Project

General

Profile

Task #38 » OrderCSVDocumentation_New.md

Nghia Nguyen, 07/08/2025 01:57 AM

 

Order CSV Import/Export Documentation (New Format)

Tổng quan

Tài liệu này mô tả chi tiết về chức năng import/export CSV cho module Order với format mới sau khi thay đổi. Hệ thống hỗ trợ cả import và export với validation đầy đủ.

THAY ĐỔI QUAN TRỌNG

  • 施設ID実施場所ID: Thay đổi từ facilities.owner_facility_id sang places.owner_place_id
  • Thêm 受注企業: Field mới để phân biệt hệ thống tạo order
  • Thêm 独自実施場所ID: Field mới từ places.owner_no
  • 実施場所実施場所名: Thay đổi từ facilities.place sang places.place
  • Commodity: KHÔNG CÒN VALIDATE với commodity_relations, lưu trực tiếp trong orders.commodity
  • Database: Thêm bảng placesplace_calendar_relations để quản lý địa điểm

Database Structure

Tables được sử dụng trong Order CSV Import/Export

Import Process

  • orders - Bảng chính lưu thông tin Order
  • order_statuses - Bảng lưu trạng thái Order
  • order_date_prices - Bảng lưu giá theo ngày
  • place_calendar_relations - Bảng quan hệ calendar với places
  • places - Bảng mới lưu thông tin địa điểm
  • temporary_order_dates - Bảng tạm thời kiểm tra trùng lặp

Export Process

  • orders - Bảng chính lấy thông tin Order
  • places - Bảng tham chiếu để lấy thông tin Place
  • user_accounts - Bảng tham chiếu để lấy thông tin User
  • owner_accounts - Bảng tham chiếu để lấy thông tin Owner
  • place_calendar_relations - Bảng tham chiếu để lấy thông tin order_owner_id

1. orders (Bảng chính)

2. places (Bảng mới - thay thế facilities)

3. place_calendar_relations (Bảng mới - thay thế facility_calendar_relations)

4. order_statuses (Bảng trạng thái)

5. order_date_prices (Bảng giá theo ngày)

CSV Field Structure

Bảng chi tiết các field trong CSV (Format mới - 46 fields)

STT Field Name (Japanese) Field Name (English) Data Type Required Max Length Validation Rules Database Column Description Error Messages
1 予約ID Order ID Integer No - 1-999999 owner_order_id ID của order (để trống nếu tạo mới) Điều kiện: Nếu có thì phải tồn tại trong database
Error: 存在しない予約IDです。新規登録の場合は予約IDを空白にしてください。
2 受注企業 Order Owner Text No - - order_owner_id 999: 自社登録、100: 楽市システム登録 (Field mới, chỉ hiển thị khi export) -
3 商材 Commodity Text Yes 50 - commodity Tên hàng hóa (lưu trực tiếp trong orders.commodity) Điều kiện: Bắt buộc nhập, max 50 ký tự
Error: 商材は入力必須です。商材は50文字以内で入力してください。
4 実施場所ID Place ID Integer Yes - Must exist in Places owner_place_id ID của place (Thay đổi từ 施設ID) Điều kiện: Bắt buộc nhập, phải tồn tại trong places table
Error: 存在しない実施場所IDです。
5 独自実施場所ID Unique Place ID Text No 100 - owner_no - Điều kiện: Nếu có thì max 100 ký tự
Error: 独自実施場所IDは100文字以内で入力してください。
6 実施場所名 Place Name Text No - - places.place Tên place (lấy từ places table dựa trên 実施場所ID) -
7 施設名 Facility Name Text No - - facilities.name Tên facility (lấy từ facilities table, chỉ hiển thị) -
8 都道府県 Prefecture Text No - - facilities.prefecture - -
9 市区郡 City Text No - - facilities.city - -
10 行政区 Ward Text No - - facilities.ward - -
11 町名番地 Address Text No - - facilities.address - -
12 建物 Building Text No - - facilities.building - -
13 実施場所の広さ Area Size Text No - - places.breadth - -
14 税抜合計金額 Total Price (Ex Tax) Integer No - - orders.total_price Tổng tiền chưa thuế (tự động tính từ order_date_prices) -
15 税込合計金額 Total Price (Inc Tax) Integer No - - orders.total_tax_price Tổng tiền có thuế (tự động tính từ order_date_prices) -
16 開始日付 Start Date Date Yes - YYYY-MM-DD format orders.start_date Ngày bắt đầu Điều kiện: Bắt buộc nhập, format YYYY-MM-DD
Error: 開始日付は入力必須です。YYYY-MM-DD形式で入力してください。
17 終了日付 End Date Date Yes - YYYY-MM-DD format orders.end_date Ngày kết thúc Điều kiện: Bắt buộc nhập, format YYYY-MM-DD, >= 開始日付
Error: 終了日付は入力必須です。YYYY-MM-DD形式で入力してください。
18 商材の詳細 Commodity Detail Text No 60 - orders.commodity Chi tiết hàng hóa Điều kiện: Nếu có thì max 60 ký tự
Error: 商材の詳細は60文字以内で入力してください。
19 現場責任者 Field Manager Text No 30 - orders.field_manager_name Người phụ trách hiện trường Điều kiện: Nếu có thì max 30 ký tự
Error: 現場責任者は30文字以内で入力してください。
20 現場責任者の連絡先 Field Manager Contact Text No - Phone format orders.field_manager_tel Liên hệ người phụ trách Điều kiện: Nếu có thì phải đúng format số điện thoại Nhật
Error: 現場責任者の連絡先は正しい電話番号形式で入力してください。
21 入店者数 Number of Visitors Integer No - 0-10000 orders.number_of_visitors Số lượng người vào Điều kiện: Nếu có thì phải từ 0-10000
Error: 入店者数は0から10000の間で入力してください。
22 入店者名 Visitor Name Text No 100 - orders.visitor Tên người vào Điều kiện: Nếu có thì max 100 ký tự
Error: 入店者名は100文字以内で入力してください。
23 催事開始時刻 Event Start Time Time No - HH:MM format (15min unit) orders.start_at Thời gian bắt đầu sự kiện Điều kiện: Nếu có thì format HH:MM, 15 phút đơn vị
Error: 催事開始時刻は15分単位で入力してください。
24 催事終了時刻 Event End Time Time No - HH:MM format (15min unit) orders.end_at Thời gian kết thúc sự kiện Điều kiện: Nếu có thì format HH:MM, 15 phút đơn vị
Error: 催事終了時刻は15分単位で入力してください。
25 搬入希望日時 Carry-in Request DateTime DateTime No - YYYY-MM-DD HH:MM format orders.carry_in_time Thời gian mong muốn mang vào Điều kiện: Nếu có thì format YYYY-MM-DD HH:MM, 15 phút đơn vị
Error: 搬入希望日時はYYYY-MM-DD HH:MM形式で入力してください。
26 搬出希望日時 Carry-out Request DateTime DateTime No - YYYY-MM-DD HH:MM format orders.carry_out_time Thời gian mong muốn mang ra Điều kiện: Nếu có thì format YYYY-MM-DD HH:MM, 15 phút đơn vị
Error: 搬出希望日時はYYYY-MM-DD HH:MM形式で入力してください。
27 搬入車両有無 Carry Vehicle Integer Yes - 1-2 orders.carry_car 1: Có, 2: Không Điều kiện: Bắt buộc nhập, phải là 1 hoặc 2
Error: 搬入車両有無は1または2で入力してください。
28 搬入車両有の場合 Carry Vehicle Detail Text No 60 - orders.carry_car_remark Chi tiết xe mang vào Điều kiện: Nếu có thì max 60 ký tự
Error: 搬入車両有の場合は60文字以内で入力してください。
29 電源詳細 Power Detail Text No 1000 - orders.power_detail Chi tiết về điện Điều kiện: Nếu có thì max 1000 ký tự
Error: 電源詳細は1000文字以内で入力してください。
30 貸出希望備品 Equipment Request Text No 1000 - orders.equipment_detail Thiết bị muốn thuê Điều kiện: Nếu có thì max 1000 ký tự
Error: 貸出希望備品は1000文字以内で入力してください。
31 配布物 Handout Text No 60 - orders.handout Vật phẩm phân phát Điều kiện: Nếu có thì max 60 ký tự
Error: 配布物は60文字以内で入力してください。
32 店舗名(会社名) Shop Name (Company) Text No 80 - orders.shop_guide Tên cửa hàng (công ty) Điều kiện: Nếu có thì max 80 ký tự
Error: 店舗名(会社名)は80文字以内で入力してください。
33 店舗電話番号 Shop Phone Text No - Phone format orders.shop_guide_tel Số điện thoại cửa hàng Điều kiện: Nếu có thì phải đúng format số điện thoại Nhật
Error: 店舗電話番号は正しい電話番号形式で入力してください。
34 ユーザアカウント名 User Account Name Text No - - user_accounts.name Tên tài khoản user (lấy từ user_accounts)
35 ユーザ会社名 User Company Name Text No - - user_accounts.company_name Tên công ty user (lấy từ user_accounts)
36 ユーザ店舗名 User Shop Name Text No - - user_accounts.shop_name Tên cửa hàng user (lấy từ user_accounts)
37 ユーザのメールアドレス User Email Text Yes 100 Email format user_accounts.email Email của user (dùng để tìm user_account_id) Điều kiện: Bắt buộc nhập, format email hợp lệ, phải tồn tại trong user_accounts
Error: ユーザのメールアドレスは入力必須です。正しいメールアドレス形式で入力してください。
38 ユーザの電話番号 User Phone Text No - - user_accounts.tel Số điện thoại user (lấy từ user_accounts) -
39 担当者名 Manager Name Text Yes 60 Must exist in Owner Account owner_accounts.name Tên người phụ trách (dùng để tìm owner_account_id) Điều kiện: Bắt buộc nhập, max 60 ký tự, phải tồn tại trong owner_accounts
Error: 担当者名は入力必須です。存在しない担当者名です。
40 ステータス Status Integer Yes - 1-3 order_statuses.order_status 1: 予約受付、2: 実施確定、3: 実施不可 Điều kiện: Bắt buộc nhập, phải là 1, 2 hoặc 3
Error: ステータスは1、2、3のいずれかで入力してください。
41 回答状態 Reply Status Integer Yes - 1-2 order_statuses.reply_status 1: 未回答、2: 回答済 Điều kiện: Bắt buộc nhập, phải là 1 hoặc 2
Error: 回答状態は1または2で入力してください。
42 備考 Remark Text No 3000 - order_statuses.remark Ghi chú Điều kiện: Nếu có thì max 3000 ký tự
Error: 備考は3000文字以内で入力してください。

CSV Format Examples

CSV Header Structure (Format mới - 42 fields)

予約ID,受注企業,商材,実施場所ID,独自実施場所ID,実施場所名,施設名,都道府県,市区郡,行政区,町名番地,建物,実施場所の広さ,税抜合計金額,税込合計金額,開始日付,終了日付,商材の詳細,現場責任者,現場責任者の連絡先,入店者数,入店者名,催事開始時刻,催事終了時刻,搬入希望日時,搬出希望日時,搬入車両有無(1:有、2:無),搬入車両有の場合,電源詳細,貸出希望備品,配布物,店舗名(会社名),店舗電話番号,ユーザアカウント名,ユーザ会社名,ユーザ店舗名,ユーザのメールアドレス,ユーザの電話番号,担当者名,ステータス(1:予約受付、2:実施確定、3:実施不可),回答状態(1:未回答、 2:回答済),備考

LƯU Ý:

  • Import: Có thể bỏ qua các field tự động điền (実施場所名, 都道府県, v.v.)
  • Export: Bao gồm tất cả fields để hiển thị đầy đủ thông tin

Import CSV Sample Data (Format mới - Minimal)

,展示会,1001,PLACE001,2024-03-01,2024-03-03,展示会詳細,田中太郎,03-1234-5678,100,展示会参加者,09:00,18:00,2024-02-29 08:00,2024-03-03 19:00,1,トラック1台,電源詳細,備品あり,パンフレット,ABC商事,03-1234-5678,hanako@abc.com,佐藤次郎,1,1,備考

Export CSV Sample Data (Format mới - Full)

,自社登録,展示会,1001,PLACE001,東京コンベンションセンター,東京コンベンションセンター,メインホールA,東京都,渋谷区,神南,1-1-1,ビルA,300㎡,150000,165000,2024-03-01,2024-03-03,展示会詳細,田中太郎,03-1234-5678,100,展示会参加者,09:00,18:00,2024-02-29 08:00,2024-03-03 19:00,1,トラック1台,電源詳細,備品あり,パンフレット,ABC商事,03-1234-5678,山田花子,ABC商事,渋谷店,hanako@abc.com,03-1234-5678,佐藤次郎,1,1,備考

Configuration

CSV Import/Export Config

Environment Variables

# CSV Import Limit
CSV_IMPORT_LIMIT=3000

# Database Chunk Size
DB_CHUNK_SIZE=10000

# Storage Path
SYSTEM_STORAGE_TEMPORARY_PATH=tmp/

# File Expiration (hours)
CSV_DOWNLOAD_FILE_EXPIRED_AT=72
CSV_ERROR_FILE_EXPIRED_AT=336

Config Structure (config/web.php)

'csv' => [
    'importLimit' => env('CSV_IMPORT_LIMIT', '3000'),        // Max records per import
    'downloadFileExpiredAt' => env('CSV_DOWNLOAD_FILE_EXPIRED_AT', 72),  // Download file expiration (hours)
    'errorFileExpiredAt' => env('CSV_ERROR_FILE_EXPIRED_AT', 336)       // Error file expiration (hours)
],
'db' => [
    'chunkSize' => env('DB_CHUNK_SIZE', '10000')             // Database chunk size for processing
],

Order Owner Mapping

// Order Owner ID mapping
$orderOwnerMap = [
    999 => '自社登録',      // Own system registration
    100 => '楽市システム登録' // Rakuichi system registration
];

Validation Rules

Business Logic Validation

1. Order ID

  • Order ID: Nếu có thì phải tồn tại trong database
  • Error: "存在しない予約IDです。新規登録の場合は予約IDを空白にしてください。"

2. Place (Thay đổi từ Facility)

  • Place ID: Phải tồn tại trong Places table
  • Error: "存在しない実施場所IDです。"

3. Unique Place ID (Field mới)

  • Unique Place ID: Tùy chọn, nếu có thì phải là format hợp lệ
  • Suggested validation: Alphanumeric, max 100 characters
  • Error: "独自実施場所IDは100文字以内で入力してください。"

4. Commodity

  • Commodity: Lưu trực tiếp trong orders.commodity, KHÔNG CÒN VALIDATE với commodity_relations
  • Validation: Chỉ kiểm tra format và độ dài (max 50 characters)
  • Business Logic: Không cần kiểm tra xem commodity có tồn tại trong master data hay không
  • Error: "商材は50文字以内で入力してください。"

5. Date

  • Start Date: Phải là format YYYY-MM-DD
  • End Date: Phải là format YYYY-MM-DD và >= Start Date
  • Error: "終了日付は開始日付と同じかそれよりも後にしてください。"

6. Time

  • Event Start/End Time: Phải là 15 phút đơn vị (00, 15, 30, 45)
  • Carry-in/out Time: Phải là format "YYYY-MM-DD HH:MM" và 15 phút đơn vị
  • Error: "催事開始時刻は15分単位で入力してください。"

7. User Account

  • User Email: Phải tồn tại trong User Account
  • Error: "存在しないユーザーアカウントです。メールアドレスが正しいか確認してください。"

8. Manager

  • Manager Name: Phải tồn tại trong Owner Account
  • Error: "存在しない担当者名です。"

9. Place Calendar (Thay đổi từ Facility Calendar)

  • Date Range: Không được trùng với ngày không thể đặt trong Place Calendar
  • Error: "日程に実施場所の予約不可日が含まれています。"

10. Duplicate Check (Thay đổi từ Facility)

  • Same File: Không được trùng "Place + Date" trong cùng file
  • Error: "既にファイル内で同じ「実施場所+日付」の組み合わせが選択されています。"

Import Behavior & Field Mapping

QUAN TRỌNG: Cách thức Import các field

Fields được Import trực tiếp vào Database:

  • 予約IDorders.owner_order_id
  • 商材orders.commodity
  • 実施場所IDorders.place_id
  • 独自実施場所IDplaces.owner_no
  • 開始日付orders.start_date
  • 終了日付orders.end_date
  • 商材の詳細orders.commodity
  • 現場責任者orders.field_manager_name
  • 現場責任者の連絡先orders.field_manager_tel
  • 入店者数orders.number_of_visitors
  • 入店者名orders.visitor
  • 催事開始時刻orders.start_at
  • 催事終了時刻orders.end_at
  • 搬入希望日時orders.carry_in_time
  • 搬出希望日時orders.carry_out_time
  • 搬入車両有無orders.carry_car
  • 搬入車両有の場合orders.carry_car_remark
  • 電源詳細orders.power_detail
  • 貸出希望備品orders.equipment_detail
  • 配布物orders.handout
  • 店舗名(会社名)orders.shop_guide
  • 店舗電話番号orders.shop_guide_tel
  • ユーザのメールアドレス → Dùng để tìm user_accounts.id
  • 担当者名 → Dùng để tìm owner_accounts.id
  • ステータスorder_statuses.order_status
  • 回答状態order_statuses.reply_status
  • 備考order_statuses.remark

Fields được tính toán và lưu vào order_date_prices:

  • 開始日付 ~ 終了日付 → Tạo records trong order_date_prices cho từng ngày
  • Giá cơ bản → Lấy từ place_calendar_relations dựa trên ngày và place_id
  • Giá đặc biệt → Áp dụng nếu có trong place_calendar_relations.special_price_sell

Fields được lưu vào place_calendar_relations:

  • 受注企業order_owner_id mặc định là 999 vì đang ở owner system
  • 実施場所IDowner_place_id
  • Ngày trong khoảngregist_date (từ start_date đến end_date)

Fields được lưu vào temporary_order_dates:

  • 実施場所ID + 開始日付 + 終了日付 → Dùng để kiểm tra trùng lặp trong cùng file
  • owner_place_id → Để group theo place
  • start_date, end_date → Để kiểm tra overlap

Fields KHÔNG được Import (bị bỏ qua khi import):

  • 受注企業 → Bị bỏ qua, giá trị từ 受注企業 không có hiệu lực vì mặc định sẽ là 999
  • 実施場所名 → Bị bỏ qua, không ghi vào database
  • 施設名 → Bị bỏ qua, không ghi vào database (lấy từ facilities.name)
  • 都道府県 → Bị bỏ qua, không ghi vào database
  • 市区郡 → Bị bỏ qua, không ghi vào database
  • 行政区 → Bị bỏ qua, không ghi vào database
  • 町名番地 → Bị bỏ qua, không ghi vào database
  • 建物 → Bị bỏ qua, không ghi vào database
  • 実施場所の広さ → Bị bỏ qua, không ghi vào database
  • 税抜合計金額 → Bị bỏ qua, tự động tính từ order_date_prices
  • 税込合計金額 → Bị bỏ qua, tự động tính từ order_date_prices
  • ユーザアカウント名 → Bị bỏ qua, không ghi vào database
  • ユーザ会社名 → Bị bỏ qua, không ghi vào database
  • ユーザ店舗名 → Bị bỏ qua, không ghi vào database
  • ユーザの電話番号 → Bị bỏ qua, không ghi vào database

Fields mới (chỉ hiển thị trong Export):

  • 受注企業 → Hiển thị dựa trên place_calendar_relations.order_owner_id
    • 999 → "自社登録"
    • 100 → "楽市システム登録"

Format Import vs Export:

Import CSV Format:

  • Chỉ cần các field được import trực tiếp vào database
  • Không cần các field tự động điền (có thể để trống hoặc bỏ qua)
  • Ví dụ: Chỉ cần 予約ID,商材,実施場所ID,開始日付,終了日付,...

Export CSV Format:

  • Bao gồm tất cả 42 fields để hiển thị đầy đủ thông tin
  • Ví dụ: 予約ID,受注企業,商材,実施場所ID,独自実施場所ID,実施場所名,都道府県,...

Import Process

// Kiểm tra số lượng records
if (!ImportCsvUtility::checkRecordSize($file)) {
    throw new RuntimeException('データ数が3000件を超えています。');
}

// Kiểm tra header
ImportCsvUtility::checkCsvHeader($file, $this->createHeader(), '利用予約');

Step 2: Data Processing

// Chuyển đổi encoding
$csvRecord[] = self::convertStringCode($wk);

// Xử lý BOM
$wk = preg_replace("/^\xEF\xBB\xBF/", '', $wk);

Step 3: Record Validation

// Validate từng field
$validator->validateDigit('予約ID', $obj->ownerOrderId, false, 1, null);
$validator->validateText('商材', $obj->commodity, true, null, 50); // CHỈ validate format, KHÔNG validate với commodity_relations
$validator->validateDigit('実施場所ID', $obj->ownerPlaceId, true, 1, null);
$validator->validateText('独自実施場所ID', $obj->ownerNo, false, null, 100);
$validator->validateDate('開始日付', $obj->startDate, true);
$validator->validateDate('終了日付', $obj->endDate, true);

// Business logic validation
if (!$this->validatePlace($obj->ownerPlaceId)) {
    $validator->addErrorMessage('存在しない実施場所IDです。');
}

// LƯU Ý: Không còn validate commodity với commodity_relations

Step 4: Database Operations

// Insert/Update order
if (empty($wk->ownerOrderId)) {
    $order = $this->orderUpsertRepository->insert($wk);
} else {
    $order = $this->orderUpsertRepository->update($wk);
}

// Update order status
$this->orderStatusUpsertRepository->insert($wk);

// Update date prices
$this->orderDatePriceUpsertRepository->bulkInsert($insertData);

Export Process

Step 1: Data Retrieval

// Lấy danh sách orders
$orders = $this->orderSelectRepository->select($filterDto);

// Chunk processing
$chunks = $orders->chunk(config('web.db.chunkSize'));

Step 2: Data Formatting

// Format data cho CSV
return [
    $dbRecord->ownerOrderId,
    $this->getOrderOwnerDisplay($dbRecord->orderOwnerId), // 受注企業
    $dbRecord->commodity,
    $dbRecord->ownerPlaceId, // 実施場所ID
    $dbRecord->ownerNo, // 独自実施場所ID
    $dbRecord->placeName, // 実施場所名
    $dbRecord->place, // 実施場所名
    // ... các field khác
];

Step 3: File Generation

// Tạo CSV file
$file = CsvUtility::createCsvFile($filePath);
fputcsv($file, $this->createHeader());

// Write data
foreach ($chunks as $chunk) {
    foreach ($chunk as $order) {
        fputcsv($file, $this->formatData($order));
    }
}

Error Handling

Error File Structure

予約ID,受注企業,商材,実施場所ID,独自実施場所ID,実施場所名,実施場所名,...,Error
,自社登録,展示会,1001,PLACE001,東京コンベンションセンター,メインホールA,...,存在しない実施場所IDです。

Common Error Messages

File Validation

項目数が正しくありません。最新の利用予約CSVをダウンロードして項目数を確認してください。
項目名が正しくありません。最新の利用予約CSVをダウンロードして項目名を確認してください。
データ数が3000件を超えています。

Field Validation

商材は入力必須です。
商材は50文字以内で入力してください。
実施場所IDは入力必須です。
実施場所IDは1以上の数字で入力してください。
独自実施場所IDは100文字以内で入力してください。
開始日付はYYYY-MM-DDの形式で入力してください。
終了日付は開始日付と同じかそれよりも後にしてください。
催事開始時刻は15分単位で入力してください。
搬入車両有無は1または2で入力してください。

Business Logic

存在しない予約IDです。新規登録の場合は予約IDを空白にしてください。
存在しない実施場所IDです。
存在しないユーザーアカウントです。メールアドレスが正しいか確認してください。
存在しない担当者名です。
日程に実施場所の予約不可日が含まれています。
既にファイル内で同じ「実施場所+日付」の組み合わせが選択されています。

Performance Considerations

Chunk Processing

  • Chunk size: 100 records per chunk
  • Memory usage: Giảm memory usage bằng cách xử lý từng chunk
  • Error handling: Mỗi chunk được xử lý độc lập

Database Operations

  • Batch insert: Sử dụng chunk để insert/update
  • Transaction: Mỗi chunk được wrap trong transaction
  • Error rollback: Rollback toàn bộ chunk nếu có lỗi

Security Considerations

File Upload Security

  • File type validation: Chỉ chấp nhận .csv
  • File size limit: Giới hạn số lượng records
  • Path traversal protection: Validate file path

Data Validation

  • Input sanitization: Tự động chuyển đổi encoding
  • SQL injection protection: Sử dụng prepared statements
  • XSS protection: Validate và escape output

Access Control

  • Authentication: Yêu cầu đăng nhập
  • Authorization: Kiểm tra quyền truy cập
  • Organization isolation: Chỉ xử lý dữ liệu của organization hiện tại

Sequence Diagrams

Import Process Sequence Diagram

sequenceDiagram
    participant U as User
    participant C as Controller
    participant S as OrderCsvService
    participant V as Validator
    participant R as Repository
    participant DB as Database

    U->>C: Upload CSV File
    C->>S: processImport(file)
    
    S->>S: validateFile(file)
    Note over S: Check file size, format, encoding
    
    S->>S: parseCsv(file)
    Note over S: Convert SJIS-win to UTF-8
    
    loop For each chunk (100 records)
        S->>V: validateChunk(chunk)
        V->>V: validateFields()
        Note over V: Validate required fields, format, business rules
        
        alt Validation Error
            V->>S: return errors
            S->>S: addToErrorFile(chunk, errors)
        else Validation Success
            S->>R: insertOrders(chunk)
            R->>DB: beginTransaction()
            
            loop For each order
                R->>DB: insert/update orders
                R->>DB: insert order_statuses
                R->>DB: insert order_date_prices
                R->>DB: insert place_calendar_relations
                R->>DB: insert temporary_order_dates
            end
            
            R->>DB: commitTransaction()
        end
    end
    
    S->>C: return result
    C->>U: Show success/error message

Export Process Sequence Diagram

sequenceDiagram
    participant U as User
    participant C as Controller
    participant S as OrderCsvService
    participant R as Repository
    participant DB as Database

    U->>C: Request CSV Download
    C->>S: processExport(filters)
    
    S->>R: selectOrders(filters)
    R->>DB: query orders with joins
    DB->>R: return order data
    R->>S: return orders
    
    S->>S: formatData(orders)
    Note over S: Format all 42 fields including auto-filled data
    
    S->>S: createCsvFile()
    Note over S: Generate CSV with BOM
    
    loop For each chunk
        S->>S: writeChunkToFile(chunk)
    end
    
    S->>C: return file path
    C->>U: Download CSV file

Error Handling Sequence Diagram

sequenceDiagram
    participant U as User
    participant C as Controller
    participant S as OrderCsvService
    participant V as Validator
    participant F as FileSystem

    U->>C: Upload CSV with errors
    C->>S: processImport(file)
    
    S->>V: validateChunk(chunk)
    V->>V: validateFields()
    V->>S: return validation errors
    
    S->>S: createErrorFile()
    S->>F: write error records
    Note over F: Include original data + error messages
    
    S->>C: return error file path
    C->>U: Show error message with download link

Current System Implementation

File Processing

  • Chunk size: 100 records per chunk (configurable via config('web.db.chunkSize'))
  • Memory management: Xử lý từng chunk để tránh memory overflow
  • File storage: Temporary files lưu trong storage/app/tmp/
  • File cleanup: Tự động xóa file tạm sau khi xử lý

Error Handling

  • Error file generation: Tạo file CSV với BOM chứa records có lỗi
  • Error file format: Bao gồm header + data + error message column
  • Error file storage: Lưu trong storage/app/tmp/ với prefix Order_import_error_
  • Error file expiration: Tự động xóa sau 336 giờ (14 ngày)

Validation

  • File validation: Kiểm tra extension .csv, số lượng records (max 3000)
  • Header validation: Kiểm tra số lượng và tên cột chính xác
  • Encoding validation: Tự động chuyển đổi từ SJIS-win sang UTF-8
  • Business validation: Kiểm tra duplicate, reference data, business rules

Special Processing & Business Logic

Pre-Processing (Before Import)

  1. Date Validation: Kiểm tra 開始日付 <= 終了日付
  2. User Account Lookup: Tìm user_account_id từ ユーザのメールアドレス
  3. Owner Account Lookup: Tìm owner_account_id từ 担当者名
  4. Place Validation: Kiểm tra 実施場所ID tồn tại trong places table
  5. Order ID Validation: Nếu 予約ID được cung cấp, kiểm tra tồn tại và quyền sở hữu

Post-Processing (After Import)

  1. Total Price Calculation: Tự động tính 税抜合計金額税込合計金額 từ order_date_prices
  2. Status Update: Cập nhật order_statuses table với status mới
  3. Audit Log: Ghi log thay đổi vào batch_tasks table
  4. Notification: Gửi email thông báo cho user và owner account

Special Business Rules

  1. Commodity Handling:

    • Không validate với commodity_relations table
    • Chỉ validate format và độ dài (50 ký tự)
    • Lưu trực tiếp vào orders.commodity
  2. Order Owner Logic:

    • 受注企業 = 999: 自社登録 (tự đăng ký)
    • 受注企業 = 100: 楽市システム登録 (đăng ký qua hệ thống Rakuichi)
  3. Date Range Validation:

    • 開始日付 phải <= 終了日付
    • Không được trùng lặp với order khác cùng place trong cùng khoảng thời gian
  4. Price Calculation:

    • 税抜合計金額 = sum của tất cả order_date_prices.price
    • 税込合計金額 = sum của tất cả order_date_prices.tax_price

Special Field Processing

  1. Time Format Processing:

    • 催事開始時刻催事終了時刻: Validate 15 phút đơn vị (00, 15, 30, 45)
    • 搬入希望日時搬出希望日時: Format "YYYY-MM-DD HH:MM"
  2. Phone Number Processing:

    • 現場責任者の連絡先店舗電話番号: Validate format số điện thoại Nhật
    • Tự động format nếu cần thiết
  3. Email Processing:

    • 現場責任者メールアドレスユーザのメールアドレス: Validate email format
    • Chuyển đổi sang lowercase
  4. Address Processing:

    • Các field địa chỉ từ places table: Tự động điền từ places dựa trên 実施場所ID
    • Không được import trực tiếp, chỉ hiển thị trong export
    (1-1/1)