refactor: 移除 SKU 欄位,統一使用 code 作為商品代碼
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -28,3 +28,4 @@ Thumbs.db
|
|||||||
/docs/pptx_build
|
/docs/pptx_build
|
||||||
/docs/presentation
|
/docs/presentation
|
||||||
docs/Monthly_Report_2026_01.pptx
|
docs/Monthly_Report_2026_01.pptx
|
||||||
|
docs/f6_1770350984272.xlsx
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ class ProductSyncController extends Controller
|
|||||||
'external_pos_id' => 'required|string',
|
'external_pos_id' => 'required|string',
|
||||||
'name' => 'required|string',
|
'name' => 'required|string',
|
||||||
'price' => 'nullable|numeric',
|
'price' => 'nullable|numeric',
|
||||||
'sku' => 'nullable|string',
|
|
||||||
'barcode' => 'nullable|string',
|
'barcode' => 'nullable|string',
|
||||||
'category' => 'nullable|string',
|
'category' => 'nullable|string',
|
||||||
'unit' => 'nullable|string',
|
'unit' => 'nullable|string',
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ class Product extends Model
|
|||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'code',
|
'code',
|
||||||
'barcode',
|
'barcode',
|
||||||
'sku',
|
|
||||||
'name',
|
'name',
|
||||||
'external_pos_id',
|
'external_pos_id',
|
||||||
'category_id',
|
'category_id',
|
||||||
|
|||||||
@@ -38,12 +38,11 @@ class ProductService
|
|||||||
// Map allowed fields
|
// Map allowed fields
|
||||||
$product->name = $data['name'];
|
$product->name = $data['name'];
|
||||||
$product->barcode = $data['barcode'] ?? $product->barcode;
|
$product->barcode = $data['barcode'] ?? $product->barcode;
|
||||||
$product->sku = $data['sku'] ?? $product->sku; // Maybe allow SKU update?
|
|
||||||
$product->price = $data['price'] ?? 0;
|
$product->price = $data['price'] ?? 0;
|
||||||
|
|
||||||
// Generate Code if missing (use sku or external_id)
|
// Generate Code if missing (use code or external_id)
|
||||||
if (empty($product->code)) {
|
if (empty($product->code)) {
|
||||||
$product->code = $data['code'] ?? ($product->sku ?? $product->external_pos_id);
|
$product->code = $data['code'] ?? $product->external_pos_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Category (Default: 未分類)
|
// Handle Category (Default: 未分類)
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('products', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('sku');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('products', function (Blueprint $table) {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -123,7 +123,7 @@ export default function GoodsReceiptCreate({ warehouses, pendingPurchaseOrders,
|
|||||||
product_id: item.product_id,
|
product_id: item.product_id,
|
||||||
purchase_order_item_id: item.id,
|
purchase_order_item_id: item.id,
|
||||||
product_name: item.product_name,
|
product_name: item.product_name,
|
||||||
sku: item.product_code,
|
product_code: item.product_code,
|
||||||
unit: item.unit,
|
unit: item.unit,
|
||||||
quantity_ordered: item.quantity,
|
quantity_ordered: item.quantity,
|
||||||
quantity_received_so_far: item.received_quantity,
|
quantity_received_so_far: item.received_quantity,
|
||||||
@@ -157,7 +157,7 @@ export default function GoodsReceiptCreate({ warehouses, pendingPurchaseOrders,
|
|||||||
const newItem = {
|
const newItem = {
|
||||||
product_id: product.id,
|
product_id: product.id,
|
||||||
product_name: product.name,
|
product_name: product.name,
|
||||||
sku: product.code,
|
product_code: product.code,
|
||||||
quantity_received: 0,
|
quantity_received: 0,
|
||||||
unit_price: product.price || 0,
|
unit_price: product.price || 0,
|
||||||
batch_number: '',
|
batch_number: '',
|
||||||
@@ -266,7 +266,7 @@ export default function GoodsReceiptCreate({ warehouses, pendingPurchaseOrders,
|
|||||||
// Note: fetch might not have returned yet, so seq might be default 001 until fetch updates nextSequences
|
// Note: fetch might not have returned yet, so seq might be default 001 until fetch updates nextSequences
|
||||||
|
|
||||||
const datePart = dateStr.replace(/-/g, '');
|
const datePart = dateStr.replace(/-/g, '');
|
||||||
const generatedBatch = `${item.sku}-${country}-${datePart}-${seq}`;
|
const generatedBatch = `${item.product_code}-${country}-${datePart}-${seq}`;
|
||||||
|
|
||||||
if (item.batch_number !== generatedBatch) {
|
if (item.batch_number !== generatedBatch) {
|
||||||
// Update WITHOUT triggering re-render loop
|
// Update WITHOUT triggering re-render loop
|
||||||
@@ -278,7 +278,7 @@ export default function GoodsReceiptCreate({ warehouses, pendingPurchaseOrders,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [nextSequences, JSON.stringify(data.items.map(i => ({ m: i.batchMode, c: i.originCountry, s: i.sku, p: i.product_id }))), data.received_date]);
|
}, [nextSequences, JSON.stringify(data.items.map(i => ({ m: i.batchMode, c: i.originCountry, s: i.product_code, p: i.product_id }))), data.received_date]);
|
||||||
|
|
||||||
const submit = (e: React.FormEvent) => {
|
const submit = (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -610,7 +610,7 @@ export default function GoodsReceiptCreate({ warehouses, pendingPurchaseOrders,
|
|||||||
<TableCell>
|
<TableCell>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="font-medium text-gray-900">{item.product_name}</span>
|
<span className="font-medium text-gray-900">{item.product_name}</span>
|
||||||
<span className="text-xs text-gray-500">{item.sku}</span>
|
<span className="text-xs text-gray-500">{item.product_code}</span>
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
@@ -654,7 +654,7 @@ export default function GoodsReceiptCreate({ warehouses, pendingPurchaseOrders,
|
|||||||
className="w-16 text-center px-1"
|
className="w-16 text-center px-1"
|
||||||
/>
|
/>
|
||||||
<div className="flex-1 text-sm font-mono bg-gray-50 px-3 py-2 rounded text-gray-600 truncate">
|
<div className="flex-1 text-sm font-mono bg-gray-50 px-3 py-2 rounded text-gray-600 truncate">
|
||||||
{getBatchPreview(item.product_id, item.sku, item.originCountry || 'TW', data.received_date)}
|
{getBatchPreview(item.product_id, item.product_code, item.originCountry || 'TW', data.received_date)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|||||||
Reference in New Issue
Block a user