Giới thiệu dự án

Trong bối cảnh bùng nổ thương mại điện tử và bán lẻ đa kênh (Omnichannel), các doanh nghiệp vừa và nhỏ (SMEs) cùng các chuỗi cửa hàng thời trang bán lẻ đối mặt với thách thức lớn về xử lý dữ liệu giao dịch phân mảnh. Theo các khảo sát thị trường bán lẻ, việc quản lý thủ công qua sổ sách hoặc các ứng dụng rời rạc dẫn đến tỷ lệ sai sót tồn kho lên đến 15-25% và tiêu tốn hơn 30% thời gian tác nghiệp của nhân sự.

Đề tài khóa luận tốt nghiệp "Quản lý bán hàng trên nền tảng Odoo" (Chuyên ngành Hệ thống Thông tin Kinh tế – Trường Đại học Kinh tế, Đại học Huế) được triển khai nhằm giải quyết bài toán quản trị luồng hàng hóa và đơn hàng thực tế tại cửa hàng thời trang xuất khẩu MIDDUA Shop phối hợp thực tập tại Công ty TNHH MTV Khai thác Dữ liệu số bData.

[MIDDUA Shop Retail Channels] 
 (Facebook / Instagram / Direct)
               │
               ▼
┌────────────────────────────────────────┐
│      Odoo OpenObject Framework         │
│  ┌──────────────────────────────────┐  │
│  │     Custom Sales & POS Module    │  │
│  └──────────────────────────────────┘  │
│  ┌───────────┐ ┌──────────┐ ┌────────┐ │
│  │ Inventory │ │ Invoices │ │  CRM   │ │
│  └───────────┘ └──────────┘ └────────┘ │
└───────────────────┬────────────────────┘
                    │
                    ▼
       ┌────────────────────────┐
       │   PostgreSQL Database  │
       └────────────────────────┘

Problem Statement và Mục tiêu dự án

MIDDUA Shop chuyên phân phối các dòng sản phẩm quần jean (skinny, boyfriend, short) và áo pull thời trang qua nhiều kênh (bán trực tiếp, Facebook, Instagram). Khi quy mô kinh doanh mở rộng, phương thức ghi chép đơn lẻ bộc lộ các điểm nghẽn nghiêm trọng:

  • Dữ liệu khách hàng, hóa đơn và nhà cung cấp bị phân mảnh, không đồng bộ thời gian thực.
  • Khó khăn trong việc phân quyền minh bạch giữa cấp quản lý (Chủ cửa hàng) và nhân viên bán hàng, tiềm ẩn nguy cơ thất thoát dữ liệu và sai lệch doanh thu.
  • Tốc độ tra cứu thông tin sản phẩm và lập hóa đơn thủ công chậm chạp, ảnh hưởng tiêu cực đến trải nghiệm khách hàng.

Mục tiêu nghiên cứu cụ thể:

  1. Nghiên cứu kiến trúc mã nguồn mở Odoo (OpenObject framework), hệ quản trị cơ sở dữ liệu PostgreSQL và ngôn ngữ lập trình Python.
  2. Khảo sát toàn diện quy trình nghiệp vụ bán hàng thực tế tại MIDDUA Shop và chuẩn hóa luồng xử lý thông tin.
  3. Phân tích và thiết kế hệ thống hướng đối tượng thông qua hệ thống sơ đồ UML (Use Case, Class Diagram, Sequence Diagram).
  4. Lập trình và đóng gói module quản lý bán hàng chuyên biệt trên Odoo với đầy đủ các tính năng: danh mục, sản phẩm, nhà cung cấp, khách hàng, nhân viên, hóa đơn và phân quyền tài khoản.
  5. Kiểm thử, đánh giá hiệu năng và đề xuất giải pháp mở rộng sang cổng thương mại điện tử (E-Commerce Web Portal).

Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Trước khi xây dựng module chuyên biệt, hiện trạng quản lý bán lẻ tại các cửa hàng vừa và nhỏ thường dựa vào ba phương thức chính:

Tiêu chí so sánh Ghi chép Excel / Sổ tay Phần mềm đóng gói (SaaS POS) Module Odoo tùy biến (Giải pháp đề xuất)
Chi phí bản quyền ban đầu Gần như bằng 0 Thu phí định kỳ theo tháng/năm Tối ưu chi phí nhờ Open Source Core
Khả năng mở rộng (Scalability) Rất kém, nghẽn khi dữ liệu lớn Bị giới hạn bởi nhà cung cấp dịch vụ Tùy biến linh hoạt theo OpenObject Architecture
Bảo mật & Phân quyền Thấp, dễ can thiệp công thức Cố định theo gói dịch vụ Phân quyền chi tiết tới cấp Model và Record Rule
Tính toàn vẹn dữ liệu Dễ sai lệch do thao tác thủ công Khá tốt trên đám mây Đảm bảo tuyệt đối bởi PostgreSQL quan hệ - đối tượng
Tích hợp hệ sinh thái Không có Hạn chế qua API đóng Liên kết trực tiếp kho, kế toán, website, CRM

Ưu tiên yêu cầu theo mô hình MoSCoW

  • Must have (Bắt buộc có): Đăng nhập/xác thực bảo mật; Phân quyền Quản lý - Nhân viên; Quản lý thông tin và trạng thái sản phẩm; Tạo và kết xuất hóa đơn bán hàng; Quản lý danh bạ khách hàng và nhà cung cấp.
  • Should have (Nên có): Tìm kiếm và lọc đa điều kiện (tên, mã, màu sắc, size); Điểm danh chấm công và lịch làm việc của nhân viên theo ngày (workday).
  • Could have (Có thể có): Tích hợp giao diện cổng mua sắm trực tuyến (Demo Website Store) kết nối trực tiếp cơ sở dữ liệu bán hàng.
  • Won't have (Chưa làm đợt này): Tự động hóa kết nối cổng thanh toán ngân hàng quốc tế và quản lý vận chuyển logistics bên thứ ba (3PL).

Thiết kế hệ thống

Hệ thống được thiết kế theo kiến trúc 3 tầng chuẩn của Odoo:

  1. Presentation Layer: Giao diện Web Client Single-Page Application (SPA) xây dựng bằng HTML5, CSS3, JavaScript (QWeb engine và Bootstrap).
  2. Logic / Application Layer: Odoo Server Core chạy trên nền tảng Python 3/2.7 với OpenObject Framework đóng vai trò xử lý Object-Relational Mapping (ORM) và các luồng Business Logic.
  3. Data Layer: Hệ quản trị cơ sở dữ liệu đối tượng - quan hệ PostgreSQL 10 (quản trị trực quan qua pgAdmin 4).
   ┌──────────────────────────────────────────────────────────┐
   │                    WEB CLIENT / UI                       │
   │      (XML Forms, Tree Views, JavaScript, QWeb Engine)    │
   └────────────────────────────┬─────────────────────────────┘
                                │ JSON-RPC / HTTP
                                ▼
   ┌──────────────────────────────────────────────────────────┐
   │                   ODOO APPLICATION SERVER                │
   │  ┌────────────────────────────────────────────────────┐  │
   │  │              OpenObject Modular Engine             │  │
   │  │   • Security / RBAC Rules   • ORM Engine           │  │
   │  │   • Workflow Controllers    • Business Logic       │  │
   │  └────────────────────────────────────────────────────┘  │
   └────────────────────────────┬─────────────────────────────┘
                                │ SQL (libpq / Psycopg2)
                                ▼
   ┌──────────────────────────────────────────────────────────┐
   │                  POSTGRESQL DATABASE                     │
   │      (Tables: product, invoice, customer, employee)       │
   └──────────────────────────────────────────────────────────┘

Thiết kế cơ sở dữ liệu (Database Schema)

Hệ thống xây dựng 7 bảng thực thể cốt lõi với các mối quan hệ toàn vẹn dữ liệu:

-- Cấu trúc các bảng dữ liệu chính trong module Quản lý bán hàng

CREATE TABLE res_users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    role INTEGER DEFAULT 1, -- 0: Admin/Manager, 1: Sales Staff
    created_at DATE DEFAULT CURRENT_DATE,
    update_at DATE
);

CREATE TABLE product_template (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    year DATE,
    description TEXT,
    image BYTEA,
    amount INTEGER DEFAULT 0,
    money VARCHAR(100) NOT NULL,
    color VARCHAR(50),
    size VARCHAR(20),
    material VARCHAR(100),
    state VARCHAR(50) DEFAULT 'available'
);

CREATE TABLE sale_order_invoice (
    id SERIAL PRIMARY KEY,
    created_by INTEGER REFERENCES res_users(id),
    codeorderproduct INTEGER REFERENCES product_template(id),
    customer_id INTEGER REFERENCES customer_partner(id),
    employee_id INTEGER REFERENCES hr_employee(id),
    quantity INTEGER NOT NULL,
    price INTEGER NOT NULL,
    totalcost INTEGER NOT NULL,
    time DATE DEFAULT CURRENT_DATE,
    size VARCHAR(20),
    is_archive BOOLEAN DEFAULT FALSE
);

Chi tiết mô hình liên kết bảng:

  • product_template & res_supplier: Quan hệ Nhiều - Nhiều (Many2many) thông qua bảng trung gian, một nhà cung cấp giao nhiều mặt hàng và một mặt hàng có thể nhập từ nhiều nguồn.
  • product_template & product_category: Quan hệ Nhiều - Một (Many2one) và phân cấp cấu trúc cha - con (parent_category).
  • sale_order_invoice: Liên kết Many2one với customer_partner (Khách hàng), hr_employee (Nhân viên bán), product_template (Sản phẩm) và res_users (Tài khoản người tạo).

Methodology

Dự án áp dụng mô hình phát triển phần mềm lặp (Iterative Software Development) kết hợp phương pháp luận Agile/Scrum:

  • Thời gian thực hiện: Từ ngày 16/01/2019 đến ngày 21/04/2019 (14 tuần làm việc).
  • Phân đoạn công việc (Milestones):
    • Tuần 1 - Tuần 3: Khảo sát quy trình nghiệp vụ tại MIDDUA Shop, nghiên cứu tài liệu OpenObject Framework, Python và hệ thống Odoo.
    • Tuần 4 - Tuần 7: Mô hình hóa hệ thống bằng UML (Use Case, Class, Sequence Diagrams) và thiết kế chuẩn hóa cơ sở dữ liệu trên PostgreSQL.
    • Tuần 8 - Tuần 11: Lập trình mã nguồn Module Odoo bằng Python (ORM Models) và thiết kế giao diện bằng XML/QWeb views trên IDE PyCharm.
    • Tuần 12 - Tuần 14: Kiểm thử chức năng, tích hợp thử nghiệm dữ liệu thực tế của shop, khắc phục lỗi và hoàn thiện báo cáo khóa luận.

Implementation và kết quả

Development Process & Code Structure

Dự án tuân thủ cấu trúc module chuẩn của kiến trúc Odoo, phân tách độc lập giữa Logic (Python), View/Layout (XML) và Security Access Control:

middua_sales_management/
├── __init__.py
├── __manifest__.py
├── models/
│   ├── __init__.py
│   ├── product.py
│   ├── invoice.py
│   ├── customer.py
│   └── employee.py
├── views/
│   ├── product_views.xml
│   ├── invoice_views.xml
│   └── menu_views.xml
└── security/
    └── ir.model.access.csv

Trích dẫn cài đặt Model ORM (Python Code Snippet)

Đoạn mã hiện thực hóa logic sản phẩm và hóa đơn với tính toán tự động và ràng buộc dữ liệu:

# -*- coding: utf-8 -*-
from odoo import models, fields, api

class ProductProduct(models.Model):
    _name = 'middua.product'
    _description = 'Thong tin san pham MIDDUA Shop'

    name = fields.Char(string='Tên sản phẩm', required=True)
    year = fields.Date(string='Ngày nhập hàng', default=fields.Date.today)
    description = fields.Html(string='Mô tả sản phẩm')
    image = fields.Binary(string='Ảnh sản phẩm')
    amount = fields.Integer(string='Số lượng tồn kho', default=0)
    money = fields.Float(string='Giá bán lẻ (VNĐ)', required=True)
    color = fields.Char(string='Màu sắc')
    size = fields.Selection([
        ('s', 'Size S'), ('m', 'Size M'), 
        ('l', 'Size L'), ('xl', 'Size XL'), 
        ('29', 'Size 29'), ('30', 'Size 30'), ('31', 'Size 31')
    ], string='Kích cỡ', default='m')
    material = fields.Char(string='Chất liệu', default='Jean/Cotton')
    state = fields.Selection([
        ('available', 'Còn hàng'),
        ('out_of_stock', 'Hết hàng')
    ], string='Trạng thái', default='available')
    category_id = fields.Many2one('middua.category', string='Danh mục sản phẩm')
    supplier_ids = fields.Many2many('middua.supplier', string='Nhà cung cấp')

class SaleInvoice(models.Model):
    _name = 'middua.invoice'
    _description = 'Hoa don ban hang MIDDUA Shop'

    name = fields.Char(string='Mã hóa đơn', required=True, copy=False, readonly=True, 
                       default=lambda self: self.env['ir.sequence'].next_by_code('middua.invoice'))
    customer_id = fields.Many2one('middua.customer', string='Khách hàng', required=True)
    employee_id = fields.Many2one('middua.employee', string='Nhân viên bán', required=True)
    product_id = fields.Many2one('middua.product', string='Sản phẩm', required=True)
    quantity = fields.Integer(string='Số lượng', default=1)
    price = fields.Float(string='Đơn giá', related='product_id.money', readonly=True)
    totalcost = fields.Float(string='Tổng tiền', compute='_compute_total_cost', store=True)
    time = fields.Date(string='Ngày lập hóa đơn', default=fields.Date.today)
    is_archive = fields.Boolean(string='Đã khóa sổ/Lưu trữ', default=False)

    @api.depends('quantity', 'price')
    def _compute_total_cost(self):
        for record in self:
            record.totalcost = record.quantity * record.price

Testing và Validation

Hệ thống trải qua 3 cấp độ kiểm thử toàn diện: Unit Test, Integration Test và User Acceptance Testing (UAT).

  1. Kiểm thử phân quyền (Role-based Access Control Validation):

    • Tài khoản Nhân viên: Chỉ có quyền xem thông tin sản phẩm, danh mục, nhà cung cấp; tạo mới và chỉnh sửa hóa đơn ở trạng thái bản nháp (is_archive = False). Không có quyền xóa hoặc sửa đổi cấu trúc giá.
    • Tài khoản Quản lý (Admin): Toàn quyền Thêm/Sửa/Xóa và xuất dữ liệu trên tất cả các phân hệ.
  2. Hiệu năng truy vấn & Xử lý giao dịch:

    • Tốc độ tra cứu: Thời gian phản hồi trung bình cho thao tác lọc sản phẩm theo mã và thuộc tính trên tập dữ liệu 5.000 records đạt < 180ms.
    • Tốc độ tạo đơn hàng: Rút ngắn thời gian lập và in một hóa đơn bán lẻ xuống dưới 15 giây/giao dịch (so với 60-90 giây khi lập sổ tay).
    • Tỷ lệ bao phủ kiểm thử: Đạt 100% các kịch bản luồng nghiệp vụ cơ bản từ Tiếp nhận khách hàng -> Kiểm tra tồn kho -> Lập hóa đơn -> Cập nhật trạng thái thanh toán.

Đổi mới và đóng góp

  • Chuẩn hóa kiến trúc module trên OpenObject: Thay vì lập trình một ứng dụng bán hàng độc lập (monolithic) từ đầu, tác giả đã kế thừa sức mạnh của nền tảng ERP nguồn mở Odoo để xây dựng module có tính tương thích cao, dễ dàng mở rộng và bảo trì.
  • Tự động hóa luồng bán lẻ thời trang: Thiết kế hệ thống dữ liệu đặc thù cho ngành may mặc (hỗ trợ phân loại linh hoạt theo color, size, material, ảnh đại diện sản phẩm chất lượng cao).
  • Cải thiện hiệu quả vận hành tại MIDDUA Shop:
    • Giảm 75% thời gian tìm kiếm thông tin hàng hóa và nhà cung ứng.
    • Loại bỏ 100% tình trạng trùng lặp hóa đơn và thất thoát dữ liệu khách hàng.
    • Tối ưu hóa việc theo dõi chấm công (workday) của nhân viên ngay trên cùng giao diện hệ thống.

Ứng dụng thực tế và triển khai

Hướng dẫn triển khai (Deployment Guide)

Để triển khai hệ thống quản lý bán lẻ Odoo vào môi trường vận hành thực tế:

# 1. Cài đặt hệ quản trị cơ sở dữ liệu PostgreSQL
sudo apt-get update
sudo apt-get install postgresql postgresql-contrib -y

# 2. Cài đặt Python và các thư viện phụ thuộc của Odoo
sudo apt-get install python3-pip python3-dev libxml2-dev libxslt1-dev zlib1g-dev libsasl2-dev libldap2-dev build-essential -y

# 3. Clone module bán hàng vào thư mục custom addons
cd /opt/odoo/custom_addons/
git clone https://github.com/middua-shop/middua_sales_management.git

# 4. Cấu hình file odoo.conf và kích hoạt module
# addons_path = /opt/odoo/addons,/opt/odoo/custom_addons
python3 odoo-bin -c /etc/odoo.conf -d middua_db -u middua_sales_management

Phân tích Chi phí - Lợi ích (Cost-Benefit Analysis)

  • Chi phí đầu tư: Do sử dụng phiên bản Odoo Community Edition và PostgreSQL mã nguồn mở, doanh nghiệp tiết kiệm 100% chi phí mua License hàng năm (ước tính tiết kiệm từ 15.000.000 – 30.000.000 VNĐ/năm so với các giải pháp ERP thương mại độc quyền).
  • Thời gian hoàn vốn (ROI Timeline): Ước tính trong vòng 1 - 2 tháng kể từ khi đưa vào vận hành nhờ việc cắt giảm chi phí thất thoát kho và giảm tải nhân lực kiểm kê cuối kỳ.

Hạn chế và hướng phát triển

  • Hạn chế hiện tại:

    • Hệ thống mới chỉ tập trung chủ yếu vào module bán hàng nội bộ tại quầy (Back-office POS/Sales) của shop.
    • Chưa tích hợp giao vận tự động qua API của các đơn vị chuyển phát (Giao Hàng Nhanh, Giao Hàng Tiết Kiệm, Viettel Post).
    • Chưa đồng bộ tin nhắn/đơn hàng tự động từ Fanpage Facebook qua Webhook.
  • Hướng phát triển tiếp theo:

    • Hoàn thiện cổng Web E-Commerce liên thông trực tiếp với cơ sở dữ liệu module bán hàng, cho phép khách hàng tự đặt hàng trực tuyến.
    • Tích hợp thêm phân hệ Kế toán tài chính nâng cao (Accounting) và Quản lý kho hàng chuyên sâu đa địa điểm (Warehouse Multi-location).
    • Xây dựng ứng dụng di động (Mobile App) trên nền tảng Flutter/React Native kết nối qua Odoo RESTful API để chủ cửa hàng có thể quản lý từ xa.

Đối tượng hưởng lợi

  • Doanh nghiệp bán lẻ & Shop thời trang: Sở hữu ngay một giải pháp quản lý bán hàng chuẩn quốc tế, chi phí 0 đồng tiền bản quyền, dễ dàng tùy biến theo nghiệp vụ riêng.
  • Sinh viên ngành Hệ thống Thông tin Kinh tế & CNTT: Tài liệu tham khảo thực tế và toàn diện về phương pháp luận phân tích thiết kế hệ thống (UML) kết hợp triển khai công nghệ mã nguồn mở Odoo/Python.
  • Lập trình viên Odoo: Cung cấp pattern cấu trúc thư mục, chuẩn viết ORM model, thiết lập quan hệ quan hệ dữ liệu (Many2one, Many2many) và phân quyền bảo mật trên Odoo.

Câu hỏi thường gặp

1. Yêu cầu phần cứng và môi trường để cài đặt hệ thống là gì?

Hệ thống vận hành mượt mà trên máy chủ hoặc máy tính cá nhân chạy Linux (Ubuntu 18.04/20.04 LTS) hoặc Windows 10, cấu hình tối thiểu CPU Dual-Core 2.0GHz, RAM 4GB, ổ cứng trống tối thiểu 20GB và cài đặt sẵn PostgreSQL 9.6+.

2. Dữ liệu bán hàng có bị mất khi xảy ra sự cố sập nguồn không?

PostgreSQL tuân thủ nghiêm ngặt chuẩn ACID (Atomicity, Consistency, Isolation, Durability). Mọi giao dịch hóa đơn được ghi trực tiếp vào cơ sở dữ liệu với Write-Ahead Logging (WAL), đảm bảo dữ liệu toàn vẹn tuyệt đối khi gặp sự cố phần cứng.

3. Hệ thống có thể mở rộng cho chuỗi nhiều cửa hàng không?

Hoàn toàn có thể. Nhờ kiến trúc Multi-company và Multi-warehouse tích hợp sẵn trong nhân Odoo, hệ thống có thể mở rộng từ 1 cửa hàng đơn lẻ thành chuỗi nhiều chi nhánh chỉ bằng cách kích hoạt cấu hình phân hệ mà không cần lập trình lại lõi dữ liệu.

4. Nhân viên bán hàng có thể tự ý sửa giá sản phẩm khi lập hóa đơn không?

Không. Thuộc tính đơn giá (price) trong module hóa đơn được ràng buộc readonly=True và lấy tự động từ bảng giá sản phẩm (product_template). Nhân viên không có quyền can thiệp vào giá bán trừ khi được phân quyền cấp Quản lý.

5. Chi phí bảo trì hàng năm của hệ thống là bao nhiêu?

Chi phí vận hành định kỳ chỉ bao gồm phí thuê máy chủ (VPS Hosting) khoảng 150.000 - 300.000 VNĐ/tháng đối với quy mô cửa hàng vừa và nhỏ, không phát sinh bất kỳ khoản phí duy trì phần mềm nào khác.


Kết luận

Khóa luận tốt nghiệp "Quản lý bán hàng trên nền tảng Odoo" đã hiện thực hóa thành công một giải pháp công nghệ hoàn chỉnh, giải quyết triệt để các bài toán quản lý phân mảnh tại cửa hàng thời trang MIDDUA Shop. Bằng việc kết hợp chặt chẽ giữa lý thuyết phân tích thiết kế hệ thống thông tin hướng đối tượng và công nghệ mã nguồn mở hiện đại (Odoo, Python, PostgreSQL), đề tài đã chứng minh tính khả thi, hiệu quả kinh tế cao và tiềm năng ứng dụng rộng rãi cho khối doanh nghiệp bán lẻ tại Việt Nam.