លំហសិក្សាកម្ពុជា លំហសិក្សាកម្ពុជា V1.0
ចូល ចុះឈ្មោះ

Vehicle Inventory and Sales Management System for SMEs

អ្នកចូលរួម
គ្រូដឹកនាំ: សេក សុជាតិ
មូលសង្ខេប / Abstract

Small and Medium Enterprises (SMEs) that sell vehicles need an effective way to manage vehicle inventory and sales records. Some businesses may use manual records, spreadsheets, or separate files to manage their daily operations. This can make it difficult to track available and sold vehicles, record stock movements, manage sales, and retrieve important information. This project developed a web-based Vehicle Inventory and Sales Management System for SMEs. The system centralizes vehicle inventory, stock movements, customers, sales, and invoices in one application. It also implements Role-Based Access Control (RBAC) to restrict system functions according to user roles. The system was developed using Python and Flask with MySQL as the database. Object-Oriented Programming principles were applied through domain models, services, repositories, and routes. The resulting system provides an organized platform for managing vehicle inventory and sales operations efficiently.

ពាក្យគន្លឹះ
University of Technology & Entrepreneurship logo


Advanced Object-Oriented Programming

R&D Project Report

Vehicle Inventory and Sales Management System for SMEs (IGNITE)

Prepared by: Lay Katsrieng, Sour Chansopanha, Heang Sovanara

Lecturer: SEK SOCHEAT

Submission Date: September 25, 2026


1. Introduction

1.1 Background

Small and medium-sized vehicle-selling enterprise should implement organized software to store records about the sold vehicles, customers, sales, and invoices. Otherwise, the workers should spend a considerable amount of time retrieving information from various file formats and spreadsheets. The application was built to provide a centralized location and reduce the overall amount of time spent on processing the data. IGNITE is a web application that allows its users to manage the vehicle stock, monitor the customers, sales, and invoices in a unified interface. The software was developed with a browser-based Python framework and a relational database. The database is needed to ensure that every car is unique and not sold twice.

1.2 Problem Statement

Separate entries may become inconsistent if one employee records a sale while another inventory list still shows the vehicle as available. Adding and removing stock may also become hard to track if their histories are not tied to the vehicle. Information regarding customers, sale amounts, and invoices may involve repeated data entry, which could result in errors.

Without controlled accounts, employees may have access to features outside of their responsibilities. A manual sales summary would also need to tie together records that may not necessarily share the same format. The project addresses these problems in linking, accounting, and automating the major aspects of a sale without measuring the decreased processing time or business errors because a before-and-after evaluation was not supplied.

1.3 Objectives

The objectives of this project are to manage individual vehicle records by allowing users to create, list, search, filter, view and edit vehicle information while preserving historical records through deactivation. The system also aims to track stock-in, stock-out and adjustment activities for each vehicle and record the responsible operator. It processes sales by completing the transaction, updating vehicle availability, recording the stock-out movement and generating an invoice within a single database transaction. User access is controlled through authentication and role-based permissions. Finally, the project applies a layered object-oriented design that separates domain models, services, repositories, routes and database connection management.

1.4 Scope

The IGNITE system is designed for daily use within a single vehicle dealership. The system’s end-users are Admin, Manager, and Sales Staff, each with specific features available based on their permission level. The Manager is responsible for inventory, while Sales Staff handles customers, sales, and invoices.

The project covers vehicle records, inventory, customers, sales, invoices, and reports. The system can complete a sale, update inventory, record a stock-out movement, and generate an invoice showing the amount owed in USD. Features outside the project scope include online payments, instalments, refunds, multiple branches, and full accounting.

The system includes the following functions:

User Authentication and Role-Based Access Control

The system provides secure user login and logout functions. Access to system features is controlled using Role-Based Access Control (RBAC). The system uses three main roles:

  • Admin

  • Manager

  • Sales Staff

Users are assigned roles through the User Roles structure. Each role has a set of permissions that determines which system functions the user can access. Permissions are assigned to roles through the Role Permissions structure.

Vehicle Inventory Management

Authorized users can:

  • Add vehicle records

  • View vehicle information

  • Update vehicle information

  • Delete unused vehicles or deactivate those with transaction history

  • Search and filter vehicles

  • Check vehicle status

Vehicle status includes:

  • Available

  • Reserved

  • Sold

  • Inactive

Stock Movement Management

The system records important inventory movements, including:

  • Stock In

  • Stock Out

  • Inventory Adjustment

Each movement is linked to a vehicle and recorded with relevant details.

Customer Management

The system allows authorized users to:

  • Add customers

  • View customer information

  • Update customer records

  • Search customer records

Sales Management

Sales Staff can:

  • Select an available vehicle

  • Select or add a customer

  • Create a sales record

  • Record the sale amount

  • Complete the sale

When a sale is completed, the system updates the vehicle status and creates a stock-out record.

Invoice Management

The system:

  • Generates invoice records

  • Assigns invoice numbers

  • Displays invoice details

  • Provides a print-friendly invoice page

Reports

The system provides:

  • Available vehicle reports

  • Sold vehicle reports

  • Sales summaries

  • Stock movement history

1.5 Limitations

To keep the project manageable within one term, the first version of the system does not include:

  • Online payment gateways

  • GPS vehicle tracking

  • Mobile applications

  • Multi-branch synchronization

  • The system currently runs only on a local server and is not deployed for online access.

  • Full accounting and tax management

  • Integration with external government or vehicle registration systems

2. Technology Review

The system is built utilizing modern web and database technologies:

Python & Flask

Python supports the project’s domain records, business services, validation and tests. Flask provides routing, request handling and an explicit application object; its factory pattern supports constructing separate application instances for testing.

IGNITE implements create_app in app/init.py and keeps the local launch entry point in app.py. Jinja renders server-side HTML, while CSS and vanilla JavaScript implement the interface. This stack keeps the project runnable without a separate frontend build process. It also makes the separation between request handling and business operations visible for an Advanced OOP course.

The application uses direct MySQL queries through repositories rather than an object-relational mapper. Consequently, transaction boundaries and SQL mapping are explicit responsibilities of the project code.

MySQL

MySQL stores ten tables using InnoDB. Foreign keys connect vehicles, customers, operators, sales and invoices; junction tables implement the many-to-many access relationships. Unique constraints prevent duplicate vehicle codes and duplicate sales of the same vehicle. CHECK constraints restrict status values and monetary relationships.

A normal read is not sufficient when two requests may sell the same vehicle. MySQL locking reads using SELECT ... FOR UPDATE lock selected rows within a transaction. IGNITE combines these locks with a unique sales.vehicle_id constraint and rollback handling. The database layer uses READ COMMITTED isolation for service transactions. These mechanisms are verified by the concurrent-sale and rollback tests, rather than assumed from the interface alone.

HTML, CSS, and JavaScript

Used in the presentation layer to create the web interface that users interact with through a browser.

2.1 OOP Concepts Applied

The system relies heavily on advanced OOP concepts to separate responsibilities:

Layered Architecture

Flask routes process requests, check permissions and call the appropriate services. The service layer applies business rules, such as ensuring that only available vehicles can be sold. The repository layer retrieves and saves records through SQL queries, while the database layer manages connections, transactions and persistent storage.

Domain models—including Vehicle, Customer, Sale, Invoice, StockMovement, User, Role and Permission—support these layers by representing system records. Some read-only routes access repositories directly. During sale completion, the service saves the sale, vehicle status, stock-out movement and invoice within one transaction.

Domain Models

Classes such as Vehicle, Customer, Stock_Movement, Sale, Invoice, User, Role and Permission represent the system’s main entities. The Sale_Amounts value object handles decimal price and discount calculations.

Separation of Concerns

Service classes manage business rules and workflows, Repository classes handle SQL queries and record mapping, and the Database class manages connections and transactions. Flask routes handle web requests, while Jinja templates display the interface.

3. Analysis and Design

3.1 Requirements

IGNITE is designed to centralize vehicle inventory and sales operations for a single dealership. The system allows authorized users to manage vehicles and customers, track stock movements, complete sales, generate invoices and view reports.

Its main functional requirements are:

  • Authenticate users and control access through role-based permissions.

  • Create, view, search, filter and update vehicle records.

  • Maintain customer information and related sales history.

  • Record stock-in, stock-out and adjustment activities.

  • Sell only available vehicles and prevent duplicate sales.

  • Generate an invoice for each completed sale.

  • Provide inventory summaries and sales reports.

  • Allow administrators to manage accounts and role permissions.

The nonfunctional requirements include persistent storage, accurate monetary calculations, consistent transactions, input validation and maintainable code.

3.2 Use Cases

The system has three main user roles. Their default responsibilities are shown below.

Admin

Manage accounts and permissions, maintain records and access all operational modules.

Manager

Manage vehicles, inventory and customers; complete sales; view invoices and reports.

Sales Staff

View vehicles, manage customers, complete sales and access invoices.

One of the key use cases involves closing a car deal. The user selects a customer who is currently active and also an available car. He then verifies the price, discount and sends for the transaction to be completed. The system checks the validity of the data provided, makes the sale, updates the car's status to SOLD, creates a stock out movement and prepares an invoice.

3.3 Class Diagram and ERD

The class diagram shows the main classes Vehicle, Customer, Sale, Invoice, Stock_Movement, User, Role and Permission and their relationships. Service classes manage business rules, while repository classes handle database operations.

Figure 1: Class Diagram

Use the dark blue class diagram shown in the report before the ERD.


The Entity Relationship Diagram (ERD) shows the ten database tables and their connections through primary and foreign keys. Sales link vehicles, customers and users; invoices reference sales; and stock movements reference vehicles and users. The user_roles and role_permissions tables connect accounts to their access permission.

Figure 2: Entity Relationship Diagram (ERD)

Use the MySQL database diagram showing the 10 connected tables.

3.4 Architecture

IGNITE follows a layered architecture that separates the user interface, request handling, business rules and database operations. This structure makes the system easier to maintain, test and extend because each layer has a clear responsibility.

Presentation → Flask Routes → Services → Repositories → MySQL

The presentation layer uses Jinja HTML templates, CSS and JavaScript to show forms, vehicle listings, dashboards and invoices. Flask routes receive browser requests, validate submitted data, verify authentication and permissions, and call the appropriate service.

The service layer handles the rules and steps that the business needs. For instance, SalesService checks if a vehicle is available and works on finishing the sale. The repository layer executes SQL queries and maps database rows into records used by the application. The Database class takes care of the connections and the steps that happen when data is changed while MySQL stores all the information using tables that are connected and follow rules to keep everything correct.

Domain models like Vehicle, Customer, Sale and Invoice are the pieces of data that the system works with. When a sale is completed, the sale record, vehicle status, stock-out movement, and invoice are saved within a single transaction. Either all changes succeed or all are rolled back, keeping the database consistent.

4. Implementation

4.1 Project Structure

The IGNITE application adopts a layered architecture using a clean Flask directory layout. High-level domain logic, repository data access, web presentation, and database persistence layers are isolated without reliance on an ORM:

vehicle_sales_system/

├── app/
│ ├── init.py
│ ├── models/
│ │ ├── vehicle.py
│ │ ├── customer.py
│ │ ├── sale.py
│ │ ├── invoice.py
│ │ ├── stock_movement.py
│ │ ├── user.py
│ │ ├── role.py
│ │ ├── permission.py
│ │ └── money.py
│ ├── repositories/
│ │ ├── base.py
│ │ ├── mysql.py
│ │ ├── vehicle_repository.py
│ │ ├── customer_repository.py
│ │ ├── sale_repository.py
│ │ ├── invoice_repository.py
│ │ ├── stock_repository.py
│ │ ├── user_repository.py
│ │ ├── role_repository.py
│ │ ├── permission_repository.py
│ │ └── report_repository.py
│ ├── routes/
│ │ ├── init.py
│ │ ├── auth_routes.py
│ │ ├── dashboard_routes.py
│ │ ├── vehicle_routes.py
│ │ ├── customer_routes.py
│ │ ├── inventory_routes.py
│ │ ├── sale_routes.py
│ │ ├── invoice_routes.py
│ │ ├── report_routes.py
│ │ ├── user_routes.py
│ │ ├── role_routes.py
│ │ ├── shared_routes.py
│ │ ├── common.py
│ │ ├── form_helpers.py
│ │ └── resource_config.py
│ ├── services/
│ │ ├── auth_service.py
│ │ ├── user_service.py
│ │ ├── vehicle_service.py
│ │ ├── customer_service.py
│ │ ├── inventory_service.py
│ │ ├── sales_service.py
│ │ ├── report_service.py
│ │ └── vehicle_photo_service.py
│ ├── static/
│ ├── templates/
│ └── database.py
├── database/
└── README.md

4.2 Key Code Decisions

1. Layered Architecture

We separated the project into routes, services, repositories and models. Each layer has a clear responsibility, making the code easier to understand, test and maintain.

2. Repository-Based Database Access

SQL queries are handled by repository classes. Repositories also map database columns, such as vehicle_id, to model attributes such as id.

3. Transaction-Based Sale Processing

Completing a sale creates the sale, invoice and stock-out movement and updates vehicle availability within one transaction. If a step fails, all related changes are rolled back.

4. Duplicate-Sale Prevention

Row locking and a unique database constraint prevent the same vehicle from being sold twice, including when two users submit a sale at the same time.

5. Role-Based Access Control

Users receive roles through user_roles, and roles receive permissions through role_permissions. The server checks permissions before allowing protected actions.

6. Accurate Financial Calculations

We use Python’s Decimal type for prices, discounts and totals to avoid floating-point rounding errors. Validation rejects negative amounts and discounts greater than the selling price.

7. Secure Vehicle Photo Uploads

Uploaded photos are checked for supported formats, file size and image content. Replaced photos are removed only after the database update succeeds, helping prevent lost images.

5. Testing and Results

Authentication and permissions

Validation: Check login, inactive accounts and restricted actions.

Result: Passed

Vehicle and customer records

Validation: Validate forms, unique fields, searching and filtering.

Result: Passed

Sales and invoices

Validation: Confirm one sale creates one invoice and stock-out movement.

Result: Passed

Transaction integrity

Validation: Reject duplicate sales and roll back changes when an operation fails.

Result: Passed

Inventory

Validation: Verify stock-in, stock-out and adjustment rules.

Result: Passed

Vehicle photos

Validation: Check file formats, size limits, replacement and safe cleanup.

Result: Passed

5.1 Test Cases and Validation

The system was tested to verify that the main functions work correctly and consistently. Authentication tests checked login, inactive accounts, and restricted actions. Vehicle and customer tests verified form validation, unique fields, searching, and filtering. Inventory tests covered stock-in, stock-out, and adjustment rules.

Sales and invoice tests confirmed that a completed sale creates one invoice, records a stock-out movement, and changes the vehicle status to SOLD. Transaction tests also verified that duplicate sales are rejected and that all related changes are rolled back if an operation fails.

Vehicle photo tests checked supported file formats, file-size limits, image replacement, preview behavior, and safe file cleanup. These tests helped confirm that the main workflows and validation rules of the system operate as expected.

5.2 Bug fixes and Security Notes

Several issues were identified and corrected during development and testing. The system prevents duplicate vehicle sales using row locking and database constraints. Sale-related updates are completed within one transaction so incomplete records are not stored if part of the process fails.

An issue where an empty vehicle plate number could display as the text None was corrected so empty values remain blank. Vehicle photo preview handling was also improved so valid JPG, JPEG, PNG, and WebP files are accepted consistently while still applying file-size and image-content validation.

Security measures include password hashing, role-based permissions, CSRF protection, parameterized SQL queries, and server-side validation. Additional checks prevent invalid uploads and protect important administrative accounts. For future online deployment, the system would still require HTTPS, login rate limiting, a restricted database account, and tested backup procedures.

6. Conclusion

The web-based Vehicle Inventory and Sales Management System was successfully designed and developed. The system centralizes vehicle records, accurately tracks stock movements, and securely processes sales transactions. By implementing a layered architecture with Domain Models, Services, and Repositories, the project successfully applied advanced Object-Oriented Programming principles to create a scalable and maintainable application. Furthermore, the integration of Role-Based Access Control ensures that business data is protected and only accessible to authorized personnel.

6.1 Achievement

The IGNITE project delivered a web-based application that allows for the centralized storage of vehicle inventory, customer data, stock movements, sales, and invoices. The application uses role-based access control and provides varied user permissions for Admin, Manager, and Sales Staff. The system allows completing a sale and updating the vehicle stock, recording a stock-out movement, and generating an invoice in one transaction.

The project also involved designing the application using a layered object-oriented approach, implementing dashboards and reports, and enabling photo upload with validation. The application underwent a comprehensive automated test suite covering core workflows, validation rules, permissions, database transactions, and data accuracy.

6.2 Future Work

To keep the initial project manageable, certain advanced features were excluded from this version. Future improvements for the system could include:

  • Integrate online payment gateways.

  • Export monthly and yearly reports to Excel.

  • Implement GPS vehicle tracking.

  • Deploy the system for online access.

  • Develop a companion mobile application.

  • Add multi-branch synchronization and full accounting/tax management.

  • Apply AI-based vehicle price predictions.

Appendix

Appendix A1 SQL Access Tables


This is the SQL screenshot showing the access-related tables such as roles, permissions, role_permissions, users and user_roles.

Appendix A2 SQL Sales and Inventory


.

Appendix A3 SQL Customers and Vehicles

Appendix B User Manual

Use Python and MySQL 8.0.16 or later, then open a terminal in the project folder.

Create a virtual environment and install requirements.txt. For a fresh clone, copy .env.example to .env.

Configure the MySQL host, port, database name, username, and password through .env according to the local environment.

Then run:

python -m venv .venv

..venv\Scripts\python.exe -m pip install -r requirements.txt

..venv\Scripts\python.exe database/setup.py

..venv\Scripts\python.exe app.py

Open http://127.0.0.1:5000 in the browser and keep the terminal running. Configure the MySQL host, port, database name, username, and password through .env according to the local environment. Normal startup does not reset records.

Team Log

The team log records each member’s contribution to the IGNITE project.

Lay Katsrieng

Vehicles, inventory, sales, invoices, dashboard, reports, system testing

Code, Git commits

Sour Chansokpanha

Database design, login, users, roles and permissions ERD, SQL files, Git commits

Heang Sovannara

Prepared the final report and presentation slides

ចែករំលែក
រក្សាទុក
ការផ្សព្វផ្សាយ
ការផ្សព្វផ្សាយ
មតិយោបល់ 0
ចូលគណនី ដើម្បីបញ្ចេញមតិ