Compare commits
No commits in common. "8194a71c687da85360eb0fe881c32fdcb573d388" and "8c26f942bfbd3e6fd49af33716d070085d57eda2" have entirely different histories.
8194a71c68
...
8c26f942bf
@ -254,15 +254,12 @@ public function getForEdit(Cutting $cutting): array
|
|||||||
public function store(array $data): Cutting
|
public function store(array $data): Cutting
|
||||||
{
|
{
|
||||||
$cutting = DB::transaction(function () use ($data) {
|
$cutting = DB::transaction(function () use ($data) {
|
||||||
$priceIds = collect($data['materials'])->pluck('raw_material_price_id')->unique()->values();
|
|
||||||
$pricesMap = RawMaterialPrice::whereIn('id', $priceIds)->get()->keyBy('id');
|
|
||||||
|
|
||||||
foreach ($data['materials'] as $materialData) {
|
foreach ($data['materials'] as $materialData) {
|
||||||
$usage = (int) ($materialData['material_usage'] ?? 0);
|
$usage = (int) ($materialData['material_usage'] ?? 0);
|
||||||
if ($usage <= 0) {
|
if ($usage <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$price = $pricesMap[$materialData['raw_material_price_id']] ?? null;
|
$price = RawMaterialPrice::find($materialData['raw_material_price_id']);
|
||||||
if (! $price) {
|
if (! $price) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -296,10 +293,8 @@ public function store(array $data): Cutting
|
|||||||
$combinationMap[$index] = $combination->id;
|
$combinationMap[$index] = $combination->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stockDecrementMap = [];
|
|
||||||
|
|
||||||
foreach ($data['materials'] as $materialData) {
|
foreach ($data['materials'] as $materialData) {
|
||||||
$price = $pricesMap[$materialData['raw_material_price_id']] ?? null;
|
$price = RawMaterialPrice::find($materialData['raw_material_price_id']);
|
||||||
$materialCost = $price ? $price->price * ($materialData['material_usage'] ?? 0) : 0;
|
$materialCost = $price ? $price->price * ($materialData['material_usage'] ?? 0) : 0;
|
||||||
$totalMaterialCost += $materialCost;
|
$totalMaterialCost += $materialCost;
|
||||||
|
|
||||||
@ -319,16 +314,11 @@ public function store(array $data): Cutting
|
|||||||
'updated_at' => $now,
|
'updated_at' => $now,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$usage = (int) ($materialData['material_usage'] ?? 0);
|
if ($price && ($materialData['material_usage'] ?? 0) > 0) {
|
||||||
if ($price && $usage > 0) {
|
$price->decrement('stock', (int) $materialData['material_usage']);
|
||||||
$stockDecrementMap[$materialData['raw_material_price_id']] = ($stockDecrementMap[$materialData['raw_material_price_id']] ?? 0) + $usage;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($stockDecrementMap as $priceId => $totalUsage) {
|
|
||||||
RawMaterialPrice::where('id', $priceId)->decrement('stock', $totalUsage);
|
|
||||||
}
|
|
||||||
|
|
||||||
$costPerUnit = 0;
|
$costPerUnit = 0;
|
||||||
if (($data['cutting_result'] ?? 0) > 0) {
|
if (($data['cutting_result'] ?? 0) > 0) {
|
||||||
$costPerUnit = (int) ($totalMaterialCost / $data['cutting_result']);
|
$costPerUnit = (int) ($totalMaterialCost / $data['cutting_result']);
|
||||||
@ -374,29 +364,20 @@ public function store(array $data): Cutting
|
|||||||
public function update(Cutting $cutting, array $data): Cutting
|
public function update(Cutting $cutting, array $data): Cutting
|
||||||
{
|
{
|
||||||
$cutting = DB::transaction(function () use ($cutting, $data) {
|
$cutting = DB::transaction(function () use ($cutting, $data) {
|
||||||
$oldMaterialUsages = $cutting->cuttingMaterials()
|
$cutting->load(['cuttingMaterials.rawMaterialPrice']);
|
||||||
->select('raw_material_price_id', 'material_usage')
|
|
||||||
->where('material_usage', '>', 0)
|
|
||||||
->get()
|
|
||||||
->filter(fn ($m) => $m->raw_material_price_id)
|
|
||||||
->groupBy('raw_material_price_id')
|
|
||||||
->map(fn ($group) => $group->sum('material_usage'));
|
|
||||||
|
|
||||||
if ($oldMaterialUsages->isNotEmpty()) {
|
foreach ($cutting->cuttingMaterials as $oldMaterial) {
|
||||||
foreach ($oldMaterialUsages as $priceId => $totalUsage) {
|
if ($oldMaterial->material_usage > 0 && $oldMaterial->rawMaterialPrice) {
|
||||||
RawMaterialPrice::where('id', $priceId)->increment('stock', $totalUsage);
|
$oldMaterial->rawMaterialPrice->increment('stock', (int) $oldMaterial->material_usage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$priceIds = collect($data['materials'])->pluck('raw_material_price_id')->unique()->values();
|
|
||||||
$pricesMap = RawMaterialPrice::whereIn('id', $priceIds)->get()->keyBy('id');
|
|
||||||
|
|
||||||
foreach ($data['materials'] as $materialData) {
|
foreach ($data['materials'] as $materialData) {
|
||||||
$usage = (int) ($materialData['material_usage'] ?? 0);
|
$usage = (int) ($materialData['material_usage'] ?? 0);
|
||||||
if ($usage <= 0) {
|
if ($usage <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$price = $pricesMap[$materialData['raw_material_price_id']] ?? null;
|
$price = RawMaterialPrice::find($materialData['raw_material_price_id']);
|
||||||
if (! $price) {
|
if (! $price) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -407,6 +388,8 @@ public function update(Cutting $cutting, array $data): Cutting
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cutting->load(['cuttingMaterials', 'cuttingMaterialCombinations', 'cuttingResults']);
|
||||||
|
|
||||||
$cutting->cuttingResults()->delete();
|
$cutting->cuttingResults()->delete();
|
||||||
$cutting->cuttingMaterials()->delete();
|
$cutting->cuttingMaterials()->delete();
|
||||||
$cutting->cuttingMaterialCombinations()->delete();
|
$cutting->cuttingMaterialCombinations()->delete();
|
||||||
@ -428,10 +411,8 @@ public function update(Cutting $cutting, array $data): Cutting
|
|||||||
$combinationMap[$index] = $combination->id;
|
$combinationMap[$index] = $combination->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stockDecrementMap = [];
|
|
||||||
|
|
||||||
foreach ($data['materials'] as $materialData) {
|
foreach ($data['materials'] as $materialData) {
|
||||||
$price = $pricesMap[$materialData['raw_material_price_id']] ?? null;
|
$price = RawMaterialPrice::find($materialData['raw_material_price_id']);
|
||||||
$materialCost = $price ? $price->price * ($materialData['material_usage'] ?? 0) : 0;
|
$materialCost = $price ? $price->price * ($materialData['material_usage'] ?? 0) : 0;
|
||||||
$totalMaterialCost += $materialCost;
|
$totalMaterialCost += $materialCost;
|
||||||
|
|
||||||
@ -451,16 +432,11 @@ public function update(Cutting $cutting, array $data): Cutting
|
|||||||
'updated_at' => $now,
|
'updated_at' => $now,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$usage = (int) ($materialData['material_usage'] ?? 0);
|
if ($price && ($materialData['material_usage'] ?? 0) > 0) {
|
||||||
if ($price && $usage > 0) {
|
$price->decrement('stock', (int) $materialData['material_usage']);
|
||||||
$stockDecrementMap[$materialData['raw_material_price_id']] = ($stockDecrementMap[$materialData['raw_material_price_id']] ?? 0) + $usage;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($stockDecrementMap as $priceId => $totalUsage) {
|
|
||||||
RawMaterialPrice::where('id', $priceId)->decrement('stock', $totalUsage);
|
|
||||||
}
|
|
||||||
|
|
||||||
$costPerUnit = 0;
|
$costPerUnit = 0;
|
||||||
if (($data['cutting_result'] ?? 0) > 0) {
|
if (($data['cutting_result'] ?? 0) > 0) {
|
||||||
$costPerUnit = (int) ($totalMaterialCost / $data['cutting_result']);
|
$costPerUnit = (int) ($totalMaterialCost / $data['cutting_result']);
|
||||||
@ -501,15 +477,12 @@ public function update(Cutting $cutting, array $data): Cutting
|
|||||||
public function destroy(Cutting $cutting): bool
|
public function destroy(Cutting $cutting): bool
|
||||||
{
|
{
|
||||||
$result = DB::transaction(function () use ($cutting) {
|
$result = DB::transaction(function () use ($cutting) {
|
||||||
$stockRestoreMap = $cutting->cuttingMaterials()
|
$cutting->load('cuttingMaterials.rawMaterialPrice');
|
||||||
->select('raw_material_price_id', 'material_usage')
|
|
||||||
->where('material_usage', '>', 0)
|
|
||||||
->get()
|
|
||||||
->groupBy('raw_material_price_id')
|
|
||||||
->map(fn ($group) => $group->sum('material_usage'));
|
|
||||||
|
|
||||||
foreach ($stockRestoreMap as $priceId => $totalUsage) {
|
foreach ($cutting->cuttingMaterials as $material) {
|
||||||
RawMaterialPrice::where('id', $priceId)->increment('stock', $totalUsage);
|
if ($material->material_usage > 0 && $material->rawMaterialPrice) {
|
||||||
|
$material->rawMaterialPrice->increment('stock', (int) $material->material_usage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$cutting->cuttingResults()->delete();
|
$cutting->cuttingResults()->delete();
|
||||||
|
|||||||
@ -94,7 +94,15 @@ public function getForCreate(): array
|
|||||||
'rawMaterialPrices:id,raw_material_id,variant,price,stock',
|
'rawMaterialPrices:id,raw_material_id,variant,price,stock',
|
||||||
])
|
])
|
||||||
->orderBy('name')
|
->orderBy('name')
|
||||||
->get(),
|
->get()
|
||||||
|
->each(function (RawMaterial $rawMaterial) {
|
||||||
|
$rawMaterial->rawMaterialPrices->each(function (RawMaterialPrice $price) {
|
||||||
|
$media = $price->getFirstMedia('images');
|
||||||
|
$price->photo_url = $media
|
||||||
|
? $this->s3Service->getTemporaryUrl($media->getPath())
|
||||||
|
: null;
|
||||||
|
});
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,12 +226,9 @@ private function storeFromExisting(array $data): Purchase
|
|||||||
}
|
}
|
||||||
DB::table('purchase_items')->insert($itemRows);
|
DB::table('purchase_items')->insert($itemRows);
|
||||||
|
|
||||||
$stockIncrementMap = collect($data['existing_items'])
|
foreach ($data['existing_items'] as $item) {
|
||||||
->groupBy('raw_material_price_id')
|
RawMaterialPrice::whereKey($item['raw_material_price_id'])
|
||||||
->map(fn ($group) => $group->sum('quantity'));
|
->increment('stock', (int) $item['quantity']);
|
||||||
|
|
||||||
foreach ($stockIncrementMap as $priceId => $totalQty) {
|
|
||||||
RawMaterialPrice::where('id', $priceId)->increment('stock', $totalQty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! empty($data['photo_keys']) && is_array($data['photo_keys'])) {
|
if (! empty($data['photo_keys']) && is_array($data['photo_keys'])) {
|
||||||
@ -272,15 +277,12 @@ private function storeNew(array $data): Purchase
|
|||||||
|
|
||||||
DB::table('raw_material_prices')->insert($priceRows);
|
DB::table('raw_material_prices')->insert($priceRows);
|
||||||
|
|
||||||
$priceIdMap = DB::table('raw_material_prices')
|
$insertedPrices = RawMaterialPrice::where('raw_material_id', $rawMaterial->id)->get();
|
||||||
->where('raw_material_id', $rawMaterial->id)
|
$variantMap = $insertedPrices->mapWithKeys(fn ($p) => [$p->variant => $p->id]);
|
||||||
->pluck('id', 'variant')
|
|
||||||
->toArray();
|
|
||||||
|
|
||||||
foreach ($data['variants'] as $variantData) {
|
foreach ($data['variants'] as $variantData) {
|
||||||
if (! empty($variantData['photo_key'])) {
|
if (! empty($variantData['photo_key'])) {
|
||||||
$priceId = $priceIdMap[$variantData['variant']] ?? null;
|
$priceId = $variantMap[$variantData['variant']];
|
||||||
if ($priceId) {
|
|
||||||
$priceModel = RawMaterialPrice::find($priceId);
|
$priceModel = RawMaterialPrice::find($priceId);
|
||||||
$this->registerMedia(
|
$this->registerMedia(
|
||||||
model: $priceModel,
|
model: $priceModel,
|
||||||
@ -290,7 +292,6 @@ private function storeNew(array $data): Purchase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$discount = $data['discount'] ?? 0;
|
$discount = $data['discount'] ?? 0;
|
||||||
$shippingCost = $data['shipping_cost'] ?? 0;
|
$shippingCost = $data['shipping_cost'] ?? 0;
|
||||||
@ -306,20 +307,16 @@ private function storeNew(array $data): Purchase
|
|||||||
'notes' => $data['notes'] ?? null,
|
'notes' => $data['notes'] ?? null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$purchaseItems = collect($data['variants'])->map(function ($v) use ($purchase, $priceIdMap, $now) {
|
$purchaseItems = $insertedPrices->map(fn ($price) => [
|
||||||
$priceId = $priceIdMap[$v['variant']] ?? null;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'purchase_id' => $purchase->id,
|
'purchase_id' => $purchase->id,
|
||||||
'raw_material_price_id' => $priceId,
|
'raw_material_price_id' => $price->id,
|
||||||
'user_id' => auth()->id(),
|
'user_id' => auth()->id(),
|
||||||
'quantity' => $v['stock'],
|
'quantity' => $price->stock,
|
||||||
'unit_price' => $v['price'],
|
'unit_price' => $price->price,
|
||||||
'subtotal' => (int) ($v['price'] * $v['stock']),
|
'subtotal' => (int) ($price->price * $price->stock),
|
||||||
'created_at' => $now,
|
'created_at' => $now,
|
||||||
'updated_at' => $now,
|
'updated_at' => $now,
|
||||||
];
|
])->toArray();
|
||||||
})->toArray();
|
|
||||||
|
|
||||||
DB::table('purchase_items')->insert($purchaseItems);
|
DB::table('purchase_items')->insert($purchaseItems);
|
||||||
|
|
||||||
@ -345,28 +342,31 @@ private function storeNew(array $data): Purchase
|
|||||||
public function update(Purchase $purchase, array $data): Purchase
|
public function update(Purchase $purchase, array $data): Purchase
|
||||||
{
|
{
|
||||||
$purchase = DB::transaction(function () use ($purchase, $data) {
|
$purchase = DB::transaction(function () use ($purchase, $data) {
|
||||||
$oldStockMap = $purchase->purchaseItems()
|
$purchase->load('purchaseItems.rawMaterialPrice.rawMaterial');
|
||||||
->select('raw_material_price_id', 'quantity')
|
|
||||||
->get()
|
|
||||||
->groupBy('raw_material_price_id')
|
|
||||||
->map(fn ($group) => $group->sum('quantity'));
|
|
||||||
|
|
||||||
foreach ($oldStockMap as $priceId => $totalQty) {
|
$oldItems = $purchase->purchaseItems;
|
||||||
RawMaterialPrice::where('id', $priceId)->decrement('stock', $totalQty);
|
|
||||||
|
// 1. Reverse the stock increments of the old items, so prices
|
||||||
|
// get adjusted by the difference instead of being reset.
|
||||||
|
$oldItems->each(function (PurchaseItem $item) {
|
||||||
|
if ($item->rawMaterialPrice) {
|
||||||
|
$item->rawMaterialPrice->decrement('stock', (int) $item->quantity);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$oldMaterial = $purchase->purchaseItems()
|
$oldMaterial = $oldItems
|
||||||
->join('raw_material_prices', 'raw_material_prices.id', '=', 'purchase_items.raw_material_price_id')
|
->map(fn (PurchaseItem $item) => $item->rawMaterialPrice?->rawMaterial)
|
||||||
->join('raw_materials', 'raw_materials.id', '=', 'raw_material_prices.raw_material_id')
|
->filter()
|
||||||
->select('raw_materials.*')
|
->unique(fn (RawMaterial $material) => $material->id)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
$purchase->purchaseItems()->delete();
|
$oldItems->each->delete();
|
||||||
|
|
||||||
$now = now();
|
$now = now();
|
||||||
$subtotal = 0;
|
$subtotal = 0;
|
||||||
|
|
||||||
if (($data['mode'] ?? 'new') === 'existing') {
|
if (($data['mode'] ?? 'new') === 'existing') {
|
||||||
|
// 2a. Reference existing prices and add their new stock.
|
||||||
$itemRows = collect($data['existing_items'])->map(function ($item) use ($now, &$subtotal) {
|
$itemRows = collect($data['existing_items'])->map(function ($item) use ($now, &$subtotal) {
|
||||||
$itemSubtotal = (int) ($item['unit_price'] * $item['quantity']);
|
$itemSubtotal = (int) ($item['unit_price'] * $item['quantity']);
|
||||||
$subtotal += $itemSubtotal;
|
$subtotal += $itemSubtotal;
|
||||||
@ -383,14 +383,14 @@ public function update(Purchase $purchase, array $data): Purchase
|
|||||||
];
|
];
|
||||||
})->toArray();
|
})->toArray();
|
||||||
|
|
||||||
$stockIncrementMap = collect($data['existing_items'])
|
foreach ($data['existing_items'] as $item) {
|
||||||
->groupBy('raw_material_price_id')
|
RawMaterialPrice::whereKey($item['raw_material_price_id'])
|
||||||
->map(fn ($group) => $group->sum('quantity'));
|
->increment('stock', (int) $item['quantity']);
|
||||||
|
|
||||||
foreach ($stockIncrementMap as $priceId => $totalQty) {
|
|
||||||
RawMaterialPrice::where('id', $priceId)->increment('stock', $totalQty);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// 2a. Always reuse the purchase's existing material in place;
|
||||||
|
// a fresh material is only created when the purchase has
|
||||||
|
// no items yet.
|
||||||
if ($oldMaterial) {
|
if ($oldMaterial) {
|
||||||
$rawMaterial = $oldMaterial;
|
$rawMaterial = $oldMaterial;
|
||||||
$rawMaterial->update([
|
$rawMaterial->update([
|
||||||
@ -405,6 +405,8 @@ public function update(Purchase $purchase, array $data): Purchase
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2b. Adjust the stock of existing variant prices, create
|
||||||
|
// prices for new variants, but never delete variants.
|
||||||
$itemRows = collect($data['variants'])->map(function ($v) use ($purchase, $rawMaterial, $now, &$subtotal) {
|
$itemRows = collect($data['variants'])->map(function ($v) use ($purchase, $rawMaterial, $now, &$subtotal) {
|
||||||
$price = null;
|
$price = null;
|
||||||
|
|
||||||
@ -491,15 +493,14 @@ public function update(Purchase $purchase, array $data): Purchase
|
|||||||
public function destroy(Purchase $purchase): bool
|
public function destroy(Purchase $purchase): bool
|
||||||
{
|
{
|
||||||
$result = DB::transaction(function () use ($purchase) {
|
$result = DB::transaction(function () use ($purchase) {
|
||||||
$stockDecrementMap = $purchase->purchaseItems()
|
$purchase->load('purchaseItems.rawMaterialPrice');
|
||||||
->select('raw_material_price_id', 'quantity')
|
|
||||||
->get()
|
|
||||||
->groupBy('raw_material_price_id')
|
|
||||||
->map(fn ($group) => $group->sum('quantity'));
|
|
||||||
|
|
||||||
foreach ($stockDecrementMap as $priceId => $totalQty) {
|
// Remove the stock the purchase added, keep the variants.
|
||||||
RawMaterialPrice::where('id', $priceId)->decrement('stock', $totalQty);
|
$purchase->purchaseItems->each(function (PurchaseItem $item) {
|
||||||
|
if ($item->rawMaterialPrice) {
|
||||||
|
$item->rawMaterialPrice->decrement('stock', (int) $item->quantity);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$purchase->purchaseItems()->delete();
|
$purchase->purchaseItems()->delete();
|
||||||
$purchase->delete();
|
$purchase->delete();
|
||||||
|
|||||||
@ -28,6 +28,14 @@ public function getForCutting(): array
|
|||||||
->active()
|
->active()
|
||||||
->orderBy('name')
|
->orderBy('name')
|
||||||
->get()
|
->get()
|
||||||
|
->each(function (RawMaterial $rawMaterial) {
|
||||||
|
$rawMaterial->rawMaterialPrices->each(function (RawMaterialPrice $price) {
|
||||||
|
$media = $price->getFirstMedia('images');
|
||||||
|
$price->photo_url = $media
|
||||||
|
? $this->s3Service->getTemporaryUrl($media->getPath())
|
||||||
|
: null;
|
||||||
|
});
|
||||||
|
})
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -104,7 +104,7 @@ const hrItems: NavMenuItem[] = [
|
|||||||
|
|
||||||
const sistemItems: NavMenuItem[] = [
|
const sistemItems: NavMenuItem[] = [
|
||||||
{ title: 'Pengaturan', href: '/admin/settings', icon: Settings, permission: ['settings.view_system', 'settings.view_homepage', 'settings.view_social_media', 'settings.view_hr'] },
|
{ title: 'Pengaturan', href: '/admin/settings', icon: Settings, permission: ['settings.view_system', 'settings.view_homepage', 'settings.view_social_media', 'settings.view_hr'] },
|
||||||
// { title: 'Role & Permission', href: rolesIndex.url(), icon: Shield, permission: 'roles.view' },
|
{ title: 'Role & Permission', href: rolesIndex.url(), icon: Shield, permission: 'roles.view' },
|
||||||
// { title: 'Log Aktivitas', href: '#', icon: Activity, permission: 'activity_logs.view' },
|
// { title: 'Log Aktivitas', href: '#', icon: Activity, permission: 'activity_logs.view' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user