feat: API調整訂單與販賣機訂單同步強制使用warehouse_code,更新API對接文件,及優化生產與配方模組UI顯示
All checks were successful
ERP-Deploy-Demo / deploy-demo (push) Successful in 55s
All checks were successful
ERP-Deploy-Demo / deploy-demo (push) Successful in 55s
This commit is contained in:
@@ -25,6 +25,16 @@ interface RecipeDetailModalProps {
|
||||
export function RecipeDetailModal({ isOpen, onClose, recipe, isLoading }: RecipeDetailModalProps) {
|
||||
if (!isOpen) return null;
|
||||
|
||||
const getUnitCost = (product: any, unitId: string | number) => {
|
||||
if (!product || !product.cost_price) return 0;
|
||||
let cost = Number(product.cost_price);
|
||||
|
||||
if (String(unitId) === String(product.large_unit_id) || String(unitId) === String(product.purchase_unit_id)) {
|
||||
cost = cost * Number(product.conversion_rate || 1);
|
||||
}
|
||||
return cost;
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={onClose}>
|
||||
<DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto p-0 gap-0">
|
||||
@@ -92,7 +102,7 @@ export function RecipeDetailModal({ isOpen, onClose, recipe, isLoading }: Recipe
|
||||
<TableRow>
|
||||
<TableCell className="font-medium text-gray-700">標準產量</TableCell>
|
||||
<TableCell className="text-gray-900 font-medium">
|
||||
{Number(recipe.yield_quantity).toLocaleString()} {recipe.product?.base_unit?.name || '份'}
|
||||
{Number(recipe.yield_quantity).toLocaleString(undefined, { maximumFractionDigits: 4 })} {recipe.product?.base_unit?.name || '份'}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{recipe.description && (
|
||||
@@ -120,30 +130,42 @@ export function RecipeDetailModal({ isOpen, onClose, recipe, isLoading }: Recipe
|
||||
<TableHead>原物料名稱 / 料號</TableHead>
|
||||
<TableHead className="text-right">標準用量</TableHead>
|
||||
<TableHead>單位</TableHead>
|
||||
<TableHead className="text-right">預估單價</TableHead>
|
||||
<TableHead className="text-right">成本小計</TableHead>
|
||||
<TableHead>備註</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{recipe.items?.length > 0 ? (
|
||||
recipe.items.map((item: any, index: number) => (
|
||||
<TableRow key={index} className="hover:bg-gray-50/50">
|
||||
<TableCell className="font-medium">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-gray-900">{item.product?.name || 'Unknown'}</span>
|
||||
<span className="text-xs text-gray-400">{item.product?.code}</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell className="text-right font-medium text-gray-900">
|
||||
{Number(item.quantity).toLocaleString()}
|
||||
</TableCell>
|
||||
<TableCell className="text-gray-600">
|
||||
{item.unit?.name || '-'}
|
||||
</TableCell>
|
||||
<TableCell className="text-gray-500 text-sm">
|
||||
{item.remark || '-'}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
recipe.items.map((item: any, index: number) => {
|
||||
const unitCost = item.product ? getUnitCost(item.product, item.unit_id) : 0;
|
||||
const subtotal = unitCost * Number(item.quantity);
|
||||
return (
|
||||
<TableRow key={index} className="hover:bg-gray-50/50">
|
||||
<TableCell className="font-medium">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-gray-900">{item.product?.name || 'Unknown'}</span>
|
||||
<span className="text-xs text-gray-400">{item.product?.code}</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell className="text-right font-medium text-gray-900">
|
||||
{Number(item.quantity).toLocaleString(undefined, { maximumFractionDigits: 4 })}
|
||||
</TableCell>
|
||||
<TableCell className="text-gray-600">
|
||||
{item.unit?.name || '-'}
|
||||
</TableCell>
|
||||
<TableCell className="text-right text-gray-600">
|
||||
{unitCost.toLocaleString(undefined, { maximumFractionDigits: 2 })} 元
|
||||
</TableCell>
|
||||
<TableCell className="text-right font-medium text-gray-900">
|
||||
{subtotal.toLocaleString(undefined, { maximumFractionDigits: 2 })} 元
|
||||
</TableCell>
|
||||
<TableCell className="text-gray-500 text-sm">
|
||||
{item.remark || '-'}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={4} className="h-24 text-center text-gray-500">
|
||||
@@ -154,6 +176,20 @@ export function RecipeDetailModal({ isOpen, onClose, recipe, isLoading }: Recipe
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
<div className="mt-4 flex justify-end">
|
||||
<div className="bg-gray-50 p-4 rounded-lg border border-gray-200 min-w-[300px]">
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<span className="text-sm text-gray-600">配方預估總成本</span>
|
||||
<span className="text-lg font-bold text-gray-900">{(recipe.items || []).reduce((sum: number, item: any) => sum + (getUnitCost(item.product, item.unit_id) * Number(item.quantity)), 0).toLocaleString(undefined, { maximumFractionDigits: 2 })} 元</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center pt-2 border-t border-gray-200">
|
||||
<span className="text-sm font-medium text-gray-700">單位生產成本
|
||||
<span className="text-xs text-gray-500 ml-1">(共 {recipe.yield_quantity} 份)</span>
|
||||
</span>
|
||||
<span className="text-md font-bold text-primary-main">{(Number(recipe.yield_quantity) > 0 ? (recipe.items || []).reduce((sum: number, item: any) => sum + (getUnitCost(item.product, item.unit_id) * Number(item.quantity)), 0) / Number(recipe.yield_quantity) : 0).toLocaleString(undefined, { maximumFractionDigits: 2 })} 元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user