Giới thiệu dự án

Thị trường dược phẩm Việt Nam giai đoạn 2012–2015 chứng kiến tốc độ tăng trưởng kép hàng năm (CAGR) ấn tượng từ 17% đến 19%, với tổng giá trị tiền thuốc tiêu thụ toàn quốc năm 2014 ước đạt 1,395 tỷ USD. Trong đó, giá trị thuốc thành phẩm nhập khẩu chiếm ưu thế với 825 triệu USD, trong khi sản xuất nội địa đạt 570 triệu USD. Bối cảnh hội nhập sau khi gia nhập WTO và cắt giảm thuế quan đã tạo điều kiện cho các tập đoàn đa quốc gia thâm nhập sâu vào thị trường nội địa, đẩy mức độ cạnh tranh giữa hơn 1.754 doanh nghiệp kinh doanh dược phẩm lên mức gay gắt. Để tồn tại và bứt phá, năng lực tối ưu hóa chuỗi cung ứng và quản trị hệ thống phân phối trở thành yếu tố sống còn.

Công ty TNHH Thương mại Dược phẩm Đông Á (thành lập năm 1996) sở hữu quy mô nhân sự 355 người, vận hành mạng lưới gồm 116 đại lý cấp 1, 5.096 đại lý cấp 2, hơn 600 bệnh viện và trên 11.000 nhà thuốc khắp cả nước. Tuy nhiên, công ty đối mặt với các điểm nghẽn nghiêm trọng trong quản trị bán hàng: mô hình phân cấp thuần theo địa lý bộc lộ sự quá tải khi mỗi giám đốc khu vực phải bao quát hàng nghìn điểm bán; tình trạng mất cân đối mạng lưới nghiêm trọng (khu vực miền Bắc chiếm tới 45–46% doanh thu, miền Nam chiếm 36%, trong khi miền Trung chỉ đạt ~17%); mật độ điểm bán dày đặc tại các đô thị gây cạnh tranh nội bộ (cannibalization), trong khi thị trường nông thôn và miền núi bị bỏ ngỏ; đặc biệt công ty hoàn toàn chưa xây dựng được hệ thống tuyến bán hàng (Sales Route/Beat Plan) khoa học.

+-------------------------------------------------------------------------------+
|                      MÔ HÌNH CHUYỂN ĐỔI HỆ THỐNG PHÂN PHỐI                    |
+-------------------------------------------------------------------------------+
|  HIỆN TRẠNG (Mô hình Địa lý Đơn lẻ)    -->    GIẢI PHÁP MỚI (Mô hình Hỗn hợp) |
|  - 1 Giám đốc / Vùng phụ trách >5000 POS     - Ma trận: Địa lý x Khách hàng   |
|  - Thiếu Tuyến bán hàng (Route Planning)     - Chuẩn hóa Tuyến theo VRP/TSP   |
|  - Phân bổ lệch: Đô thị chồng chéo           - Mở rộng 14 tỉnh lẻ tiềm năng   |
|  - Dòng thông tin đứt gãy, thiếu DMS         - Tích hợp DMS & Giám sát KPI    |
+-------------------------------------------------------------------------------+

Đề tài đặt ra các mục tiêu giải quyết cụ thể:

  1. Tái cấu trúc mô hình tổ chức mạng lưới bán hàng từ cấu trúc địa lý đơn lẻ sang mô hình ma trận hỗn hợp (Địa lý kết hợp Phân loại Khách hàng Buôn/Lẻ và Ngành hàng Chuyên biệt).
  2. Chuẩn hóa quy hoạch hệ thống Điểm bán hàng (POS) và thiết kế Tuyến bán hàng (Route Planning), mở rộng bổ sung 14 điểm phân phối chiến lược tại các tỉnh vùng sâu, vùng xa.
  3. Xây dựng bộ tiêu chí định lượng lựa chọn thành viên kênh và thiết lập khung số hóa dòng thông tin quản trị bán hàng (DMS/ERP).

Giải pháp kỳ vọng nâng cao hiệu quả phủ sóng thị trường lên 35%, rút ngắn Lead Time giao hàng từ khoảng 1–5 ngày xuống 1–3 ngày (tỷ lệ giao hàng chuẩn xác đạt $\ge 98.5%$), giảm tỷ lệ xung đột kênh xuống dưới 5% và duy trì mức tăng trưởng doanh thu $\ge 15%$/năm. Đề tài giới hạn phạm vi nghiên cứu trên dữ liệu hoạt động kinh doanh giai đoạn 2012–2014 và triển khai mô hình ứng dụng cho toàn bộ 3 chi nhánh miền Bắc, Trung, Nam của Dược phẩm Đông Á.


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

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

Phân tích các mô hình phân phối tiêu chuẩn trong ngành dược cho thấy những ưu thế và hạn chế rõ nét khi áp dụng vào quy mô của Dược phẩm Đông Á:

Mô hình tổ chức Ưu điểm Nhược điểm Mức độ phù hợp với Đông Á
Theo Khu vực Địa lý (Hiện tại) Quản lý gọn nhẹ, tiết kiệm chi phí ban đầu, bám sát địa bàn. Quá tải quản trị khi quy mô tăng; nhân sự không chuyên sâu sản phẩm; thiếu liên kết vùng. Thấp (Đang gây nghẽn tại 3 khu vực).
Theo Sản phẩm / Ngành hàng Trình dược viên am hiểu sâu kỹ thuật, biệt dược, thiết bị y tế. Trùng lặp địa bàn di chuyển; chi phí nhân sự và vận hành tăng vọt. Trung bình (Chỉ tối ưu cho mảng thiết bị y tế).
Theo Khách hàng (OTC vs. ETC) Chăm sóc chuyên sâu từng phân khúc (Bệnh viện vs. Nhà thuốc bán lẻ). Khó khăn nếu tập khách hàng phân tán mỏng về mặt địa lý. Khá cao (Đặc thù dược phẩm đòi hỏi kênh ETC/OTC tách biệt).
Mô hình Hỗn hợp (Matrix) Tối ưu hóa chi phí di chuyển, chuyên môn hóa chính sách chiết khấu/chăm sóc. Cấu trúc quản trị đa chiều, đòi hỏi hệ thống thông tin mạnh. Rất cao (Lựa chọn tối ưu chuyển đổi).

Yêu cầu người dùng và hệ thống được chuẩn hóa theo ma trận MoSCoW:

  • Must-have (Bắt buộc): Thiết lập ranh giới tuyến bán hàng (Beat Plan) không chồng chéo; xây dựng bộ tiêu chí chấm điểm đại lý cấp 1 và cấp 2; phân luồng quy trình thanh toán và kiểm soát công nợ theo phân cấp khách hàng.
  • Should-have (Cần có): Ứng dụng hệ thống giám sát định vị đơn hàng và hành trình trình dược viên (MR); tự động hóa tính toán chiết khấu bán buôn/bán lẻ.
  • Could-have (Có thể có): Cổng thông tin Portal tự phục vụ đặt hàng dành cho đại lý cấp 1 và nhà thuốc lớn.
  • Won't-have (Chưa thực hiện): Tự động hóa hoàn toàn chuỗi cung ứng bằng AI/Machine Learning trong giai đoạn này.

Thiết kế hệ thống

Kiến trúc mạng lưới bán hàng được thiết kế lại dựa trên sự phối hợp giữa cấu trúc tổ chức ma trận và phân luồng luân chuyển dữ liệu:

graph TD
    subgraph Ban_Dieu_Hanh [Ban Giám Đốc & Phòng Kinh Doanh]
        BG[Ban Giám Đốc] --> PK[Phòng Kinh Doanh Trung Ương]
    end

    subgraph Khoi_Khu_Vuc [Quản Trị Theo Khu Vực Địa Lý]
        PK --> MB[Giám Đốc KV Miền Bắc]
        PK --> MT[Giám Đốc KV Miền Trung]
        PK --> MN[Giám Đốc KV Miền Nam]
    end

    subgraph Chuyen_Mon_Hoa_Khach_Hang [Phân Luồng Kênh Phân Phối]
        MB --> MB_BB[Quản Lý Đại Lý Bán Buôn / Cấp 1]
        MB --> MB_BL[Quản Lý Đại Lý Bán Lẻ / Cấp 2 / POS]
        
        MT --> MT_BB[Quản Lý Đại Lý Bán Buôn / Cấp 1]
        MT --> MT_BL[Quản Lý Đại Lý Bán Lẻ / Cấp 2 / POS]
        
        MN --> MN_BB[Quản Lý Đại Lý Bán Buôn / Cấp 1]
        MN --> MN_BL[Quản Lý Đại Lý Bán Lẻ / Cấp 2 / POS]
    end

    subgraph Ha_Tang_Phan_Phoi [Điểm & Tuyến Bán Hàng]
        MB_BB --> POS_Hospital[Kênh ETC: Bệnh viện >600 điểm & Trung tâm Y tế]
        MB_BL --> POS_Pharma[Kênh OTC: >11.000 Nhà thuốc & Đại lý bán lẻ]
        MT_BB --> POS_Hospital
        MT_BL --> POS_Pharma
        MN_BB --> POS_Hospital
        MN_BL --> POS_Pharma
    end

Ngăn xếp công nghệ hỗ trợ quản trị (Technology Stack)

  • Hệ thống Quản lý Phân phối (DMS Platform): Phiên bản DMS Enterprise v4.2 tích hợp GPS Tracking.
  • Cơ sở dữ liệu tập trung: PostgreSQL 15.3 kết hợp PostGIS để xử lý dữ liệu địa không gian của điểm bán.
  • Công cụ Tối ưu Lộ trình: Python 3.10 với Google OR-Tools v9.6 / NetworkX 3.1.
  • Phân tích Báo cáo BI: Microsoft Power BI Desktop v2.118 kết nối thời gian thực qua Gateway.

Thiết kế lược đồ dữ liệu quản trị mạng lưới (Database Schema)

-- Bảng quản lý Điểm Bán Hàng (Points of Sale)
CREATE TABLE pos_master (
    pos_id VARCHAR(20) PRIMARY KEY,
    pos_name VARCHAR(255) NOT NULL,
    pos_type VARCHAR(50) CHECK (pos_type IN ('WHOLESALE_L1', 'RETAIL_L2', 'HOSPITAL_ETC', 'CLINIC')),
    region_id VARCHAR(10) NOT NULL, -- NORTH, CENTRAL, SOUTH
    province VARCHAR(100) NOT NULL,
    latitude DECIMAL(9, 6),
    longitude DECIMAL(9, 6),
    credit_limit DECIMAL(15, 2) DEFAULT 0.00,
    tier_status VARCHAR(20) DEFAULT 'STANDARD',
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- Bảng quản lý Tuyến Bán Hàng (Sales Routes)
CREATE TABLE sales_routes (
    route_id VARCHAR(20) PRIMARY KEY,
    route_name VARCHAR(150) NOT NULL,
    region_id VARCHAR(10) NOT NULL,
    assigned_rep_id VARCHAR(20) NOT NULL,
    frequency VARCHAR(20) DEFAULT 'WEEKLY', -- F1, F2, F4
    total_pos_count INT DEFAULT 0,
    estimated_distance_km DECIMAL(6, 2),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- Bảng quan hệ Tuyến - Điểm bán (Thứ tự viếng thăm trong Beat Plan)
CREATE TABLE route_pos_mapping (
    mapping_id SERIAL PRIMARY KEY,
    route_id VARCHAR(20) REFERENCES sales_routes(route_id),
    pos_id VARCHAR(20) REFERENCES pos_master(pos_id),
    visit_sequence INT NOT NULL,
    visit_day_of_week INT CHECK (visit_day_of_week BETWEEN 2 AND 7), -- Thứ 2 -> Thứ 7
    CONSTRAINT unique_route_seq UNIQUE (route_id, visit_day_of_week, visit_sequence)
);

Methodology

Phương pháp tiếp cận kết hợp giữa Quy trình Quản trị Kinh doanh Theo giai đoạn (Stage-Gate)Phương pháp Tinh gọn (Lean Optimization):

  1. Khảo sát & Thu thập Dữ liệu (Tháng 1/2015): Khảo sát bằng bảng hỏi 20 nhân sự chủ chốt, phỏng vấn sâu 8 nhà quản trị cấp cao, trích xuất dữ liệu bán hàng giai đoạn 2012–2014.
  2. Thiết kế & Tái lập Mô hình (Tháng 2/2015): Định vị tọa độ toàn bộ 5.096 đại lý, mô hình hóa phân cụm địa lý theo mật độ và quy mô.
  3. Thử nghiệm & Đánh giá Tuyến mẫu (Tháng 3/2015): Triển khai thử nghiệm 15 tuyến bán hàng mẫu tại Hà Nội và TP. Hồ Chí Minh.
  4. Chuẩn hóa & Chuyển giao Toàn quốc (Tháng 4–5/2015): Ban hành bộ tiêu chuẩn đánh giá đại lý và sơ đồ tuyến mới.

Implementation và kết quả

Development process

Quá trình triển khai tái cấu trúc tập trung vào bài toán tối ưu hóa tuyến hành trình viếng thăm điểm bán (Traveling Salesperson Problem with Time Windows - TSPTW) dành cho đội ngũ hơn 200 Trình dược viên (MR).

Dưới đây là module thuật toán tối ưu hóa thứ tự viếng thăm các điểm bán hàng trong cùng một cụm tuyến bằng Python và thư viện tối ưu hóa nhằm cực tiểu hóa quãng đường và thời gian di chuyển:

import numpy as np
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp

def create_sales_route_model(distance_matrix, num_reps=1, depot_index=0):
    """Khởi tạo mô hình định tuyến bán hàng (TSP/VRP) cho Dược phẩm Đông Á."""
    data = {}
    data['distance_matrix'] = distance_matrix
    data['num_vehicles'] = num_reps
    data['depot'] = depot_index
    return data

def optimize_medical_rep_route(distance_matrix):
    """Giải bài toán tối ưu hành trình viếng thăm POS của Trình dược viên."""
    data = create_sales_route_model(distance_matrix)
    manager = pywrapcp.RoutingIndexManager(
        len(data['distance_matrix']), data['num_vehicles'], data['depot']
    )
    routing = pywrapcp.RoutingModel(manager)

    def distance_callback(from_index, to_index):
        from_node = manager.IndexToNode(from_index)
        to_node = manager.IndexToNode(to_index)
        return data['distance_matrix'][from_node][to_node]

    transit_callback_index = routing.RegisterTransitCallback(distance_callback)
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
    )

    solution = routing.SolveWithParameters(search_parameters)
    if solution:
        route = []
        index = routing.Start(0)
        while not routing.IsEnd(index):
            route.append(