diff --git a/app/Services/Manage/StockService.php b/app/Services/Manage/StockService.php
index 2525593..35577f6 100644
--- a/app/Services/Manage/StockService.php
+++ b/app/Services/Manage/StockService.php
@@ -31,6 +31,7 @@ public function getPendingVerificationCuttings(User $user): Collection
'rejection.rejectedBy.profile',
'materials.rawMaterialPrice.rawMaterial:id,name,unit',
'materials.rawMaterialPrice.media',
+ 'materials.combination',
'results.productVariant.product:id,name',
'results.productVariant.media',
])
@@ -53,6 +54,7 @@ public function getPendingApprovalCuttings(User $user): Collection
'rejection.rejectedBy.profile',
'materials.rawMaterialPrice.rawMaterial:id,name,unit',
'materials.rawMaterialPrice.media',
+ 'materials.combination',
'results.productVariant.product:id,name',
'results.productVariant.media',
'resultPrices.productVariant:id,product_id,name',
@@ -236,19 +238,34 @@ private function breakMaterialCircularReference(CuttingMaterial $material): void
{
$price = $material->rawMaterialPrice;
+ // Always set these attributes regardless of price
+ $material->setAttribute('material_result', $material->material_result);
+ $material->setAttribute('material_result_input', $material->material_result);
+ $material->setAttribute('combination_id', $material->combination_id);
+ $material->setAttribute('combination_material_result', $material->combination?->material_result);
+
if ($price) {
$rawMaterial = $price->rawMaterial;
+ $material->setAttribute('variant', $price->variant);
+ $material->setAttribute('stock_input', $price->stock_input);
+ $material->setAttribute('images', $price->getAttribute('images') ?? []);
+
if ($rawMaterial) {
$unitAbbreviation = $rawMaterial->unit->abbreviation();
$price->setAttribute('unit_abbreviation', $unitAbbreviation);
$material->setAttribute('unit_abbreviation', $unitAbbreviation);
+ $material->setAttribute('unit', $rawMaterial->unit->value);
+ $material->setAttribute('raw_material_id', $rawMaterial->id);
+ $material->setAttribute('raw_material_name', $rawMaterial->name);
+ $material->setAttribute('raw_material_unit_label', $rawMaterial->unit->label());
}
$price->unsetRelation('rawMaterial');
}
$material->unsetRelation('rawMaterialPrice');
+ $material->unsetRelation('combination');
}
private function applyProductStockOnVerify(Cutting $cutting): void
diff --git a/resources/js/pages/admin/manage/cuttings/table/CuttingVerifyDialog.vue b/resources/js/pages/admin/manage/cuttings/table/CuttingVerifyDialog.vue
index 6fbeb21..f412358 100644
--- a/resources/js/pages/admin/manage/cuttings/table/CuttingVerifyDialog.vue
+++ b/resources/js/pages/admin/manage/cuttings/table/CuttingVerifyDialog.vue
@@ -3,6 +3,7 @@ import { useForm } from '@inertiajs/vue3';
import { watch } from 'vue';
import { toast } from 'vue-sonner';
import { RupiahInput } from '@/components/form/rupiah-input';
+import MediaThumbnailCell from '@/components/media/MediaThumbnailCell.vue';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
@@ -194,6 +195,27 @@ function submitVerify() {
+
+
Bahan Baku Terpakai
+
+
+
+
+
+
+
+ {{ material.raw_material_name || material.raw_material_price?.raw_material?.name }} - {{ material.variant || material.raw_material_price?.variant }}
+
+
+ Pemakaian: {{ material.material_usage_formatted }}
+ Kombinasi
+
+
+
+
+
+
diff --git a/resources/js/pages/admin/manage/stocks/table/StockPendingApprovalSection.vue b/resources/js/pages/admin/manage/stocks/table/StockPendingApprovalSection.vue
index bedb0e1..a1b3038 100644
--- a/resources/js/pages/admin/manage/stocks/table/StockPendingApprovalSection.vue
+++ b/resources/js/pages/admin/manage/stocks/table/StockPendingApprovalSection.vue
@@ -12,9 +12,73 @@ import {
} from '@/components/ui/table';
import type { CuttingListItem } from '@/types/cutting';
+interface GroupedCuttingMaterials {
+ rawMaterialId: number;
+ rawMaterialName: string;
+ unitLabel?: string;
+ items: any[];
+ isCombination?: boolean;
+}
+
defineProps<{
cuttings: CuttingListItem[];
}>();
+
+function getGroupedMaterials(materials: any[]): GroupedCuttingMaterials[] {
+ const combinationGroups: Record = {};
+ const nonCombinationItems: any[] = [];
+
+ materials.forEach((item) => {
+ if (item.combination_id) {
+ if (!combinationGroups[item.combination_id]) {
+ combinationGroups[item.combination_id] = [];
+ }
+
+ combinationGroups[item.combination_id].push(item);
+ } else {
+ nonCombinationItems.push(item);
+ }
+ });
+
+ const result: GroupedCuttingMaterials[] = [];
+
+ Object.entries(combinationGroups).forEach(([combinationId, items]) => {
+ const firstItem = items[0];
+ const rawMaterialName = firstItem.raw_material_name || 'Bahan Baku Tidak Diketahui';
+ const unitLabel = firstItem.raw_material_unit_label;
+
+ result.push({
+ rawMaterialId: Number(combinationId) * -1,
+ rawMaterialName: `Kombinasi`,
+ unitLabel,
+ items,
+ isCombination: true,
+ });
+ });
+
+ const groups: Record = {};
+
+ nonCombinationItems.forEach((item) => {
+ const rawMaterialId = item.raw_material_id ?? 0;
+ const rawMaterialName = item.raw_material_name || 'Bahan Baku Tidak Diketahui';
+ const unitLabel = item.raw_material_unit_label;
+
+ if (!groups[rawMaterialId]) {
+ groups[rawMaterialId] = {
+ rawMaterialId,
+ rawMaterialName,
+ unitLabel,
+ items: [],
+ };
+ }
+
+ groups[rawMaterialId].items.push(item);
+ });
+
+ result.push(...Object.values(groups));
+
+ return result;
+}
@@ -46,7 +110,68 @@ defineProps<{
-
+
+
+
+
Bahan Baku
+
+
+
+
+ Varian
+ Foto
+ Pemakaian
+ Hasil
+
+
+
+
+
+
+
+ {{ group.rawMaterialName }}
+
+ {{ group.items.length }} bahan
+
+
+ Hasil: {{ group.items[0].combination_material_result }} pcs
+
+
+
+ {{ group.rawMaterialName }}
+
+ {{ group.unitLabel }}
+
+
+
+
+
+
+ {{ material.variant }}
+
+
+
+
+
+ {{ material.material_usage_formatted }}
+
+
+
+ {{ material.material_result }} pcs
+
+
+ -
+
+
+
+
+
+
+
+
+
Hasil Verifikasi
diff --git a/resources/js/pages/admin/manage/stocks/table/StockPendingSection.vue b/resources/js/pages/admin/manage/stocks/table/StockPendingSection.vue
index 8b9b1d8..6ba6526 100644
--- a/resources/js/pages/admin/manage/stocks/table/StockPendingSection.vue
+++ b/resources/js/pages/admin/manage/stocks/table/StockPendingSection.vue
@@ -11,9 +11,73 @@ import {
import type { CuttingListItem } from '@/types/cutting';
import StockDataTableActions from './data-table-actions.vue';
+interface GroupedCuttingMaterials {
+ rawMaterialId: number;
+ rawMaterialName: string;
+ unitLabel?: string;
+ items: any[];
+ isCombination?: boolean;
+}
+
defineProps<{
cuttings: CuttingListItem[];
}>();
+
+function getGroupedMaterials(materials: any[]): GroupedCuttingMaterials[] {
+ const combinationGroups: Record = {};
+ const nonCombinationItems: any[] = [];
+
+ materials.forEach((item) => {
+ if (item.combination_id) {
+ if (!combinationGroups[item.combination_id]) {
+ combinationGroups[item.combination_id] = [];
+ }
+
+ combinationGroups[item.combination_id].push(item);
+ } else {
+ nonCombinationItems.push(item);
+ }
+ });
+
+ const result: GroupedCuttingMaterials[] = [];
+
+ Object.entries(combinationGroups).forEach(([combinationId, items]) => {
+ const firstItem = items[0];
+ const rawMaterialName = firstItem.raw_material_name || 'Bahan Baku Tidak Diketahui';
+ const unitLabel = firstItem.raw_material_unit_label;
+
+ result.push({
+ rawMaterialId: Number(combinationId) * -1,
+ rawMaterialName: `Kombinasi`,
+ unitLabel,
+ items,
+ isCombination: true,
+ });
+ });
+
+ const groups: Record = {};
+
+ nonCombinationItems.forEach((item) => {
+ const rawMaterialId = item.raw_material_id ?? 0;
+ const rawMaterialName = item.raw_material_name || 'Bahan Baku Tidak Diketahui';
+ const unitLabel = item.raw_material_unit_label;
+
+ if (!groups[rawMaterialId]) {
+ groups[rawMaterialId] = {
+ rawMaterialId,
+ rawMaterialName,
+ unitLabel,
+ items: [],
+ };
+ }
+
+ groups[rawMaterialId].items.push(item);
+ });
+
+ result.push(...Object.values(groups));
+
+ return result;
+}
@@ -41,7 +105,7 @@ defineProps<{
-
+
Hasil Produk
@@ -66,7 +130,8 @@ defineProps<{
{{ result.product_variant?.product?.name }} ({{ result.product_variant?.name }})
-
+
{{ result.cutting_result }} pcs
@@ -82,6 +147,69 @@ defineProps<{
+
+
+
Bahan Baku
+
+
+
+
+ Varian
+ Foto
+ Pemakaian
+ Hasil
+
+
+
+
+
+
+
+ {{ group.rawMaterialName }}
+
+ {{ group.items.length }} bahan
+
+
+ Hasil: {{ group.items[0].combination_material_result }} pcs
+
+
+
+ {{ group.rawMaterialName }}
+
+ {{ group.unitLabel }}
+
+
+
+
+
+
+ {{ material.variant }}
+
+
+
+
+
+ {{ material.material_usage_formatted }}
+
+
+
+ {{ material.material_result }} pcs
+
+
+ -
+
+
+
+
+
+
+
+
diff --git a/resources/js/pages/admin/manage/stocks/table/StockVerifyDialog.vue b/resources/js/pages/admin/manage/stocks/table/StockVerifyDialog.vue
index dc088cd..9fa4cd1 100644
--- a/resources/js/pages/admin/manage/stocks/table/StockVerifyDialog.vue
+++ b/resources/js/pages/admin/manage/stocks/table/StockVerifyDialog.vue
@@ -214,6 +214,27 @@ function submitVerify() {
+
+
Bahan Baku Terpakai
+
+
+
+
+
+
+
+ {{ material.raw_material_name || material.raw_material_price?.raw_material?.name }} - {{ material.variant || material.raw_material_price?.variant }}
+
+
+ Pemakaian: {{ material.material_usage_formatted }}
+ Kombinasi
+
+
+
+
+
+