feat: add reject price handling in restock management and update related components
This commit is contained in:
parent
266abb81e7
commit
00a848747f
@ -82,6 +82,10 @@ public function getForCreate(): array
|
|||||||
$capitalPrice = $variant->productPrices
|
$capitalPrice = $variant->productPrices
|
||||||
->first(fn ($price) => $price->type === PriceType::CAPITAL);
|
->first(fn ($price) => $price->type === PriceType::CAPITAL);
|
||||||
$variant->capital_price = $capitalPrice?->price ?? 0;
|
$variant->capital_price = $capitalPrice?->price ?? 0;
|
||||||
|
|
||||||
|
$rejectPrice = $variant->productPrices
|
||||||
|
->first(fn ($price) => $price->type === PriceType::REJECT);
|
||||||
|
$variant->reject_price = $rejectPrice?->price ?? 0;
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
@ -117,7 +121,7 @@ public function create(array $data): Restock
|
|||||||
$subtotal = 0;
|
$subtotal = 0;
|
||||||
$stockType = $data['stock_type'] ?? ProductStockQuality::GOOD->value;
|
$stockType = $data['stock_type'] ?? ProductStockQuality::GOOD->value;
|
||||||
|
|
||||||
$itemRows = $this->buildItemRows($data['items'], $now, $subtotal);
|
$itemRows = $this->buildItemRows($data['items'], $stockType, $now, $subtotal);
|
||||||
|
|
||||||
$restock = Restock::create([
|
$restock = Restock::create([
|
||||||
'created_by_id' => auth()->id(),
|
'created_by_id' => auth()->id(),
|
||||||
@ -161,7 +165,7 @@ public function update(Restock $restock, array $data): Restock
|
|||||||
$subtotal = 0;
|
$subtotal = 0;
|
||||||
$stockType = $data['stock_type'] ?? $restock->stock_type->value;
|
$stockType = $data['stock_type'] ?? $restock->stock_type->value;
|
||||||
|
|
||||||
$itemRows = $this->buildItemRows($data['items'], $now, $subtotal);
|
$itemRows = $this->buildItemRows($data['items'], $stockType, $now, $subtotal);
|
||||||
|
|
||||||
foreach ($itemRows as &$row) {
|
foreach ($itemRows as &$row) {
|
||||||
$row['restock_id'] = $restock->id;
|
$row['restock_id'] = $restock->id;
|
||||||
@ -199,23 +203,27 @@ public function delete(Restock $restock): bool
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildItemRows(array $items, $now, int &$subtotal): array
|
private function buildItemRows(array $items, string $stockType, $now, int &$subtotal): array
|
||||||
{
|
{
|
||||||
|
$priceType = $stockType === ProductStockQuality::REJECT->value
|
||||||
|
? PriceType::REJECT
|
||||||
|
: PriceType::CAPITAL;
|
||||||
|
|
||||||
$variantIds = collect($items)->pluck('product_variant_id')->unique()->all();
|
$variantIds = collect($items)->pluck('product_variant_id')->unique()->all();
|
||||||
$capitalPrices = ProductVariant::query()
|
$prices = ProductVariant::query()
|
||||||
->whereKey($variantIds)
|
->whereKey($variantIds)
|
||||||
->with('productPrices:id,variant_id,type,price')
|
->with('productPrices:id,variant_id,type,price')
|
||||||
->get()
|
->get()
|
||||||
->mapWithKeys(function (ProductVariant $variant) {
|
->mapWithKeys(function (ProductVariant $variant) use ($priceType) {
|
||||||
$capitalPrice = $variant->productPrices
|
$price = $variant->productPrices
|
||||||
->first(fn ($price) => $price->type === PriceType::CAPITAL);
|
->first(fn ($p) => $p->type === $priceType);
|
||||||
|
|
||||||
return [$variant->id => $capitalPrice?->price ?? 0];
|
return [$variant->id => $price?->price ?? 0];
|
||||||
});
|
});
|
||||||
|
|
||||||
return collect($items)->map(function ($item) use ($now, $capitalPrices, &$subtotal) {
|
return collect($items)->map(function ($item) use ($now, $prices, &$subtotal) {
|
||||||
$quantity = (int) $item['quantity'];
|
$quantity = (int) $item['quantity'];
|
||||||
$unitPrice = (int) ($capitalPrices[$item['product_variant_id']] ?? 0);
|
$unitPrice = (int) ($prices[$item['product_variant_id']] ?? 0);
|
||||||
$itemSubtotal = $unitPrice * $quantity;
|
$itemSubtotal = $unitPrice * $quantity;
|
||||||
$subtotal += $itemSubtotal;
|
$subtotal += $itemSubtotal;
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,7 @@ export type ProductForRestock = {
|
|||||||
reject_stock: number;
|
reject_stock: number;
|
||||||
photo_url: string | null;
|
photo_url: string | null;
|
||||||
capital_price: number;
|
capital_price: number;
|
||||||
|
reject_price: number;
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -122,11 +122,24 @@ export default function RestockCreate({ data }: Props) {
|
|||||||
[products],
|
[products],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const getUnitPrice = useCallback(
|
||||||
|
(variantId: number) => {
|
||||||
|
const variant = variantById.get(variantId);
|
||||||
|
|
||||||
|
if (!variant) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stockType === 'reject' ? variant.reject_price : variant.capital_price;
|
||||||
|
},
|
||||||
|
[variantById, stockType],
|
||||||
|
);
|
||||||
|
|
||||||
const subtotal = Object.entries(quantities).reduce(
|
const subtotal = Object.entries(quantities).reduce(
|
||||||
(sum, [variantId, quantity]) => {
|
(sum, [variantId, quantity]) => {
|
||||||
const variant = variantById.get(Number(variantId));
|
const unitPrice = getUnitPrice(Number(variantId));
|
||||||
|
|
||||||
return sum + (variant ? variant.capital_price * quantity : 0);
|
return sum + unitPrice * quantity;
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
@ -160,12 +173,13 @@ export default function RestockCreate({ data }: Props) {
|
|||||||
const variant = variantById.get(id);
|
const variant = variantById.get(id);
|
||||||
|
|
||||||
if (variant) {
|
if (variant) {
|
||||||
|
const unitPrice = stockType === 'reject' ? variant.reject_price : variant.capital_price;
|
||||||
lines.push({
|
lines.push({
|
||||||
key: `variant-${id}`,
|
key: `variant-${id}`,
|
||||||
photoUrl: variant.photo_url,
|
photoUrl: variant.photo_url,
|
||||||
title: variant.name,
|
title: variant.name,
|
||||||
subtitle: `${formatCurrency(variant.capital_price)} / pcs`,
|
subtitle: `${formatCurrency(unitPrice)} / pcs`,
|
||||||
price: variant.capital_price,
|
price: unitPrice,
|
||||||
quantity,
|
quantity,
|
||||||
onAdjust: (delta) => incrementQuantity(id, delta),
|
onAdjust: (delta) => incrementQuantity(id, delta),
|
||||||
onSet: (value) => updateQuantity(id, value),
|
onSet: (value) => updateQuantity(id, value),
|
||||||
@ -327,7 +341,9 @@ export default function RestockCreate({ data }: Props) {
|
|||||||
pcs
|
pcs
|
||||||
·{' '}
|
·{' '}
|
||||||
{formatCurrency(
|
{formatCurrency(
|
||||||
variant.capital_price,
|
stockType === 'reject'
|
||||||
|
? variant.reject_price
|
||||||
|
: variant.capital_price,
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -96,11 +96,24 @@ export default function RestockEdit({ restock, data }: Props) {
|
|||||||
[products],
|
[products],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const getUnitPrice = useCallback(
|
||||||
|
(variantId: number) => {
|
||||||
|
const variant = variantById.get(variantId);
|
||||||
|
|
||||||
|
if (!variant) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stockType === 'reject' ? variant.reject_price : variant.capital_price;
|
||||||
|
},
|
||||||
|
[variantById, stockType],
|
||||||
|
);
|
||||||
|
|
||||||
const subtotal = Object.entries(quantities).reduce(
|
const subtotal = Object.entries(quantities).reduce(
|
||||||
(sum, [variantId, quantity]) => {
|
(sum, [variantId, quantity]) => {
|
||||||
const variant = variantById.get(Number(variantId));
|
const unitPrice = getUnitPrice(Number(variantId));
|
||||||
|
|
||||||
return sum + (variant ? variant.capital_price * quantity : 0);
|
return sum + unitPrice * quantity;
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
@ -134,12 +147,13 @@ export default function RestockEdit({ restock, data }: Props) {
|
|||||||
const variant = variantById.get(id);
|
const variant = variantById.get(id);
|
||||||
|
|
||||||
if (variant) {
|
if (variant) {
|
||||||
|
const unitPrice = stockType === 'reject' ? variant.reject_price : variant.capital_price;
|
||||||
lines.push({
|
lines.push({
|
||||||
key: `variant-${id}`,
|
key: `variant-${id}`,
|
||||||
photoUrl: variant.photo_url,
|
photoUrl: variant.photo_url,
|
||||||
title: variant.name,
|
title: variant.name,
|
||||||
subtitle: `${formatCurrency(variant.capital_price)} / pcs`,
|
subtitle: `${formatCurrency(unitPrice)} / pcs`,
|
||||||
price: variant.capital_price,
|
price: unitPrice,
|
||||||
quantity,
|
quantity,
|
||||||
onAdjust: (delta) => incrementQuantity(id, delta),
|
onAdjust: (delta) => incrementQuantity(id, delta),
|
||||||
onSet: (value) => updateQuantity(id, value),
|
onSet: (value) => updateQuantity(id, value),
|
||||||
@ -255,7 +269,9 @@ export default function RestockEdit({ restock, data }: Props) {
|
|||||||
pcs
|
pcs
|
||||||
·{' '}
|
·{' '}
|
||||||
{formatCurrency(
|
{formatCurrency(
|
||||||
variant.capital_price,
|
stockType === 'reject'
|
||||||
|
? variant.reject_price
|
||||||
|
: variant.capital_price,
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user