feat: 實作銷售單匯入管理、貨道扣庫優化及 UI 細節調整
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Has been skipped
Koori-ERP-Deploy-System / deploy-production (push) Successful in 1m8s

This commit is contained in:
2026-02-09 14:36:47 +08:00
parent 590580e20a
commit b6fe9ad9f3
22 changed files with 1274 additions and 33 deletions

View File

@@ -0,0 +1,106 @@
<?php
namespace App\Modules\Sales\Imports;
use App\Modules\Sales\Models\SalesImportBatch;
use App\Modules\Sales\Models\SalesImportItem;
use App\Modules\Inventory\Models\Product;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithStartRow;
use Carbon\Carbon;
class SalesImportSheet implements ToCollection, WithStartRow
{
protected $batch;
protected $products;
public function __construct(SalesImportBatch $batch)
{
$this->batch = $batch;
// Pre-load all products to minimize queries (keyed by code)
$this->products = Product::pluck('id', 'code'); // assumes code is unique
}
public function startRow(): int
{
return 3;
}
public function collection(Collection $rows)
{
$totalQuantity = 0;
$totalAmount = 0;
$items = [];
foreach ($rows as $row) {
// Index mapping based on analysis:
// 0: 銷貨單號 (Serial)
// 1: 機台編號 (Machine ID)
// 4: 訂單狀態 (Original Status)
// 7: 產品代號 (Product Code)
// 9: 銷貨日期 (Transaction At)
// 11: 金額 (Amount)
// 19: 貨道 (Slot)
// Quantity default to 1
$serial = $row[0];
$machineId = $row[1];
$originalStatus = $row[4];
$productCode = $row[7];
$transactionAt = $row[9];
$amount = $row[11];
$slot = $row[19] ?? null;
// Skip empty rows
if (empty($serial) && empty($productCode)) {
continue;
}
// Parse Date
try {
// Formatting might be needed depending on Excel date format
$transactionAt = Carbon::parse($transactionAt);
} catch (\Exception $e) {
$transactionAt = now();
}
$quantity = 1; // Default
// Clean amount (remove comma etc if needed)
$amount = is_numeric($amount) ? $amount : 0;
$items[] = [
'batch_id' => $this->batch->id,
'machine_id' => $machineId,
'slot' => $slot,
'product_code' => $productCode,
'product_id' => $this->products[$productCode] ?? null,
'transaction_at' => $transactionAt,
'transaction_serial' => $serial,
'quantity' => (int)$quantity,
'amount' => $amount,
'original_status' => $originalStatus,
'created_at' => now(),
'updated_at' => now(),
];
$totalQuantity += $quantity;
$totalAmount += $amount;
}
// Bulk insert items (chunk if necessary, but assuming reasonable size)
foreach (array_chunk($items, 1000) as $chunk) {
SalesImportItem::insert($chunk);
}
// Update Batch Totals
// Increment totals instead of overwriting, in case we decide to process multiple sheets later?
// But for now, since we only process sheet 0, overwriting or incrementing is fine.
// Given we strictly return [0 => ...], only one sheet runs.
$this->batch->update([
'total_quantity' => $totalQuantity,
'total_amount' => $totalAmount,
]);
}
}