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
->first(fn ($price) => $price->type === PriceType::CAPITAL);
$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;
$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([
'created_by_id' => auth()->id(),
@ -161,7 +165,7 @@ public function update(Restock $restock, array $data): Restock
$subtotal = 0;
$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) {
$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();
$capitalPrices = ProductVariant::query()
$prices = ProductVariant::query()
->whereKey($variantIds)
->with('productPrices:id,variant_id,type,price')
->get()
->mapWithKeys(function (ProductVariant $variant) {
$capitalPrice = $variant->productPrices
->first(fn ($price) => $price->type === PriceType::CAPITAL);
->mapWithKeys(function (ProductVariant $variant) use ($priceType) {
$price = $variant->productPrices
->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'];
$unitPrice = (int) ($capitalPrices[$item['product_variant_id']] ?? 0);
$unitPrice = (int) ($prices[$item['product_variant_id']] ?? 0);
$itemSubtotal = $unitPrice * $quantity;
$subtotal += $itemSubtotal;

View File

@ -59,6 +59,7 @@ export type ProductForRestock = {
reject_stock: number;
photo_url: string | null;
capital_price: number;
reject_price: number;
}[];
};

View File

@ -122,11 +122,24 @@ export default function RestockCreate({ data }: Props) {
[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(
(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,
);
@ -160,12 +173,13 @@ export default function RestockCreate({ data }: Props) {
const variant = variantById.get(id);
if (variant) {
const unitPrice = stockType === 'reject' ? variant.reject_price : variant.capital_price;
lines.push({
key: `variant-${id}`,
photoUrl: variant.photo_url,
title: variant.name,
subtitle: `${formatCurrency(variant.capital_price)} / pcs`,
price: variant.capital_price,
subtitle: `${formatCurrency(unitPrice)} / pcs`,
price: unitPrice,
quantity,
onAdjust: (delta) => incrementQuantity(id, delta),
onSet: (value) => updateQuantity(id, value),
@ -327,7 +341,9 @@ export default function RestockCreate({ data }: Props) {
pcs
·{' '}
{formatCurrency(
variant.capital_price,
stockType === 'reject'
? variant.reject_price
: variant.capital_price,
)}
</p>
</div>

View File

@ -96,11 +96,24 @@ export default function RestockEdit({ restock, data }: Props) {
[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(
(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,
);
@ -134,12 +147,13 @@ export default function RestockEdit({ restock, data }: Props) {
const variant = variantById.get(id);
if (variant) {
const unitPrice = stockType === 'reject' ? variant.reject_price : variant.capital_price;
lines.push({
key: `variant-${id}`,
photoUrl: variant.photo_url,
title: variant.name,
subtitle: `${formatCurrency(variant.capital_price)} / pcs`,
price: variant.capital_price,
subtitle: `${formatCurrency(unitPrice)} / pcs`,
price: unitPrice,
quantity,
onAdjust: (delta) => incrementQuantity(id, delta),
onSet: (value) => updateQuantity(id, value),
@ -255,7 +269,9 @@ export default function RestockEdit({ restock, data }: Props) {
pcs
·{' '}
{formatCurrency(
variant.capital_price,
stockType === 'reject'
? variant.reject_price
: variant.capital_price,
)}
</p>
</div>