feat: add reject price handling in restock management and update related components

This commit is contained in:
Yoga Pangestu 2026-08-03 13:03:03 +07:00
parent 266abb81e7
commit 00a848747f
4 changed files with 61 additions and 20 deletions

View File

@ -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;

View File

@ -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;
}[]; }[];
}; };

View File

@ -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>

View File

@ -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>