From fc234a6afdcff7480c4ee7f3d2fbcea38df8cd65 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Sun, 21 Jun 2026 12:59:11 +0700 Subject: [PATCH] refactor: remove length unit handling from CuttingMaterial and related components for improved clarity and consistency in material usage representation --- app/Models/CuttingMaterial.php | 106 ------------------ app/Services/Manage/CuttingService.php | 45 +------- .../js/pages/admin/manage/cuttings/Edit.vue | 36 ++---- .../manage/cuttings/form/CuttingPosForm.vue | 38 +------ .../table/CuttingCompletedSection.vue | 44 +------- .../cuttings/table/CuttingGroupedTable.vue | 31 +---- .../table/CuttingInProgressSection.vue | 44 +------- resources/js/types/cutting.ts | 6 - 8 files changed, 34 insertions(+), 316 deletions(-) diff --git a/app/Models/CuttingMaterial.php b/app/Models/CuttingMaterial.php index 6cc1743..cfda907 100644 --- a/app/Models/CuttingMaterial.php +++ b/app/Models/CuttingMaterial.php @@ -15,14 +15,9 @@ #[Appends([ 'material_usage_formatted', 'material_usage_input', - 'material_usage_cm_formatted', - 'material_usage_cm_input', 'remaining_material_formatted', 'remaining_material_input', - 'remaining_material_cm_formatted', - 'remaining_material_cm_input', 'unit_abbreviation', - 'uses_length_unit', ])] class CuttingMaterial extends Model { @@ -86,63 +81,6 @@ public function unitAbbreviation(): Attribute ); } - public function usesLengthUnit(): Attribute - { - return Attribute::make( - get: fn () => $this->rawMaterialPrice?->rawMaterial?->unit?->usesLengthUnit() ?? false, - ); - } - - public function materialUsageCmFormatted(): Attribute - { - return Attribute::make( - get: fn () => $this->formatCmQuantity($this->material_usage), - ); - } - - public function materialUsageCmInput(): Attribute - { - return Attribute::make( - get: fn () => $this->formatCmQuantityInput($this->material_usage), - ); - } - - public function remainingMaterialCmFormatted(): Attribute - { - return Attribute::make( - get: fn () => $this->formatCmQuantity($this->remaining_material), - ); - } - - public function remainingMaterialCmInput(): Attribute - { - return Attribute::make( - get: fn () => $this->formatCmQuantityInput($this->remaining_material), - ); - } - - public function materialUsageInCm(): ?float - { - $unit = $this->rawMaterialPrice?->rawMaterial?->unit; - - if ($unit === null) { - return null; - } - - return $unit->toCm((float) $this->material_usage); - } - - public function remainingMaterialInCm(): ?float - { - $unit = $this->rawMaterialPrice?->rawMaterial?->unit; - - if ($unit === null) { - return null; - } - - return $unit->toCm((float) $this->remaining_material); - } - public function materialCost(): int { $price = $this->rawMaterialPrice; @@ -154,50 +92,6 @@ public function materialCost(): int return (int) round((float) $this->material_usage * (int) $price->price); } - private function formatCmQuantity(float|string|null $value): ?string - { - $unit = $this->rawMaterialPrice?->rawMaterial?->unit; - - if ($unit === null) { - return null; - } - - if (! $unit->usesLengthUnit()) { - return $this->formatQuantity($value); - } - - $cm = $unit->toCm((float) $value); - - if ($cm === null) { - return null; - } - - $formatted = rtrim(rtrim(number_format($cm, 4, ',', '.'), '0'), ','); - - return "{$formatted} cm"; - } - - private function formatCmQuantityInput(float|string|null $value): ?string - { - $unit = $this->rawMaterialPrice?->rawMaterial?->unit; - - if ($unit === null) { - return null; - } - - if (! $unit->usesLengthUnit()) { - return $this->formatQuantityInput($value); - } - - $cm = $unit->toCm((float) $value); - - if ($cm === null) { - return null; - } - - return rtrim(rtrim(number_format($cm, 4, '.', ''), '0'), '.'); - } - private function formatQuantity(float|string|null $value): string { $formatted = rtrim(rtrim(number_format((float) $value, 4, ',', '.'), '0'), ','); diff --git a/app/Services/Manage/CuttingService.php b/app/Services/Manage/CuttingService.php index fc703d2..3df7f3d 100644 --- a/app/Services/Manage/CuttingService.php +++ b/app/Services/Manage/CuttingService.php @@ -281,17 +281,8 @@ public function syncDraftMaterial(array $validated, User $user): array ->with('rawMaterial') ->findOrFail($validated['raw_material_price_id']); - $unit = $price->rawMaterial?->unit; - $usageInput = round((float) $validated['material_usage'], 2); - $remainingInput = round((float) $validated['remaining_material'], 2); - - if ($unit !== null && $unit->usesLengthUnit()) { - $materialUsage = round($unit->fromCm($usageInput), 2); - $remainingMaterial = round($unit->fromCm($remainingInput), 2); - } else { - $materialUsage = $usageInput; - $remainingMaterial = $remainingInput; - } + $materialUsage = round((float) $validated['material_usage'], 2); + $remainingMaterial = round((float) $validated['remaining_material'], 2); if ($materialUsage <= 0) { throw ValidationException::withMessages([ @@ -652,17 +643,8 @@ private function buildMaterials(array $materials): array ]); } - $unit = $price->rawMaterial?->unit; - $usageInput = round((float) $itemData['material_usage'], 2); - $remainingInput = round((float) $itemData['remaining_material'], 2); - - if ($unit !== null && $unit->usesLengthUnit()) { - $materialUsage = round($unit->fromCm($usageInput), 2); - $remainingMaterial = round($unit->fromCm($remainingInput), 2); - } else { - $materialUsage = $usageInput; - $remainingMaterial = $remainingInput; - } + $materialUsage = round((float) $itemData['material_usage'], 2); + $remainingMaterial = round((float) $itemData['remaining_material'], 2); if ($materialUsage <= 0) { throw ValidationException::withMessages([ @@ -890,31 +872,16 @@ private function presentDraftMaterial(CuttingMaterial $item): array { $price = $item->rawMaterialPrice; $rawMaterial = $price?->rawMaterial; - $unit = $rawMaterial?->unit; - - $usesLengthUnit = $unit?->usesLengthUnit() ?? false; - - // Convert stored native unit back to cm for display - if ($usesLengthUnit && $unit !== null) { - $materialUsageCm = round($unit->toCm((float) $item->material_usage), 2); - $remainingMaterialCm = round($unit->toCm((float) $item->remaining_material), 2); - $materialUsageDisplay = rtrim(rtrim(number_format($materialUsageCm, 2, '.', ''), '0'), '.'); - $remainingMaterialDisplay = rtrim(rtrim(number_format($remainingMaterialCm, 2, '.', ''), '0'), '.'); - } else { - $materialUsageDisplay = $this->formatQuantityInput((float) $item->material_usage); - $remainingMaterialDisplay = $this->formatQuantityInput((float) $item->remaining_material); - } return [ 'raw_material_price_id' => $item->raw_material_price_id, 'raw_material_name' => $rawMaterial?->name ?? '', 'variant' => $price?->variant ?? '', 'unit' => $rawMaterial?->unit?->value ?? '', - 'uses_length_unit' => $usesLengthUnit, 'unit_abbreviation' => $rawMaterial?->unit?->abbreviation() ?? '', 'stock_input' => $price?->stock_input ?? '', - 'material_usage' => $materialUsageDisplay, - 'remaining_material' => $remainingMaterialDisplay, + 'material_usage' => $this->formatQuantityInput((float) $item->material_usage), + 'remaining_material' => $this->formatQuantityInput((float) $item->remaining_material), 'images' => $price ? MediaPresenter::collection($price, 'images') : [], ]; } diff --git a/resources/js/pages/admin/manage/cuttings/Edit.vue b/resources/js/pages/admin/manage/cuttings/Edit.vue index 15de0f7..3fac6af 100644 --- a/resources/js/pages/admin/manage/cuttings/Edit.vue +++ b/resources/js/pages/admin/manage/cuttings/Edit.vue @@ -17,35 +17,21 @@ const props = defineProps<{ productCatalog: CuttingProductCatalogItem[]; }>(); -function usesLengthUnit(unit?: string): boolean { - return unit === 'yard' || unit === 'meter'; -} - const initialData = computed(() => ({ description: props.cutting.description ?? '', sewing_cost: String(props.cutting.sewing_cost ?? 0), other_cost: String(props.cutting.other_cost ?? 0), - materials: props.cutting.materials.map((item) => { - const unit = item.raw_material_price?.raw_material?.unit ?? 'kilogram'; - const usesCm = usesLengthUnit(unit); - - return { - raw_material_price_id: item.raw_material_price_id, - raw_material_name: item.raw_material_price?.raw_material?.name ?? '', - variant: item.raw_material_price?.variant ?? '', - unit, - uses_length_unit: usesCm, - unit_abbreviation: item.raw_material_price?.raw_material?.unit_abbreviation ?? '', - stock_input: item.raw_material_price?.stock_input ?? '', - material_usage: usesCm - ? (item.material_usage_cm_input ?? item.material_usage_input) - : item.material_usage_input, - remaining_material: usesCm - ? (item.remaining_material_cm_input ?? item.remaining_material_input) - : item.remaining_material_input, - images: item.raw_material_price?.images ?? [], - }; - }), + materials: props.cutting.materials.map((item) => ({ + raw_material_price_id: item.raw_material_price_id, + raw_material_name: item.raw_material_price?.raw_material?.name ?? '', + variant: item.raw_material_price?.variant ?? '', + unit: item.raw_material_price?.raw_material?.unit ?? 'kilogram', + unit_abbreviation: item.raw_material_price?.raw_material?.unit_abbreviation ?? '', + stock_input: item.raw_material_price?.stock_input ?? '', + material_usage: item.material_usage_input, + remaining_material: item.remaining_material_input, + images: item.raw_material_price?.images ?? [], + })), results: props.cutting.results.map((item) => ({ product_variant_id: item.product_variant_id, product_name: item.product_variant?.product?.name ?? '', diff --git a/resources/js/pages/admin/manage/cuttings/form/CuttingPosForm.vue b/resources/js/pages/admin/manage/cuttings/form/CuttingPosForm.vue index f3d91eb..c13e280 100644 --- a/resources/js/pages/admin/manage/cuttings/form/CuttingPosForm.vue +++ b/resources/js/pages/admin/manage/cuttings/form/CuttingPosForm.vue @@ -45,10 +45,6 @@ import type { import PosCatalogCard from '../../shared/PosCatalogCard.vue'; import PosCatalogVariantThumb from '../../shared/PosCatalogVariantThumb.vue'; -function usesLengthUnit(unit: string): boolean { - return unit === 'yard' || unit === 'meter'; -} - const props = defineProps<{ rawMaterialCatalog: CuttingRawMaterialCatalogItem[]; productCatalog: CuttingProductCatalogItem[]; @@ -81,9 +77,6 @@ const form = useForm({ other_cost: '0', }); -const CM_PER_YARD = 91.44; -const CM_PER_METER = 100; - function findCatalogPrice(priceId: number) { for (const rawMaterial of props.rawMaterialCatalog) { const price = rawMaterial.prices.find((item) => item.id === priceId); @@ -99,18 +92,6 @@ function findCatalogPrice(priceId: number) { return null; } -function usageInNativeUnit(usageInput: number, unit: string): number { - if (unit === 'yard') { - return usageInput / CM_PER_YARD; - } - - if (unit === 'meter') { - return usageInput / CM_PER_METER; - } - - return usageInput; -} - const totalMaterialCost = computed(() => materialCart.value.reduce((sum, item) => { const catalogPrice = findCatalogPrice(item.raw_material_price_id); @@ -119,10 +100,7 @@ const totalMaterialCost = computed(() => return sum; } - const usage = usageInNativeUnit( - Number(item.material_usage) || 0, - catalogPrice.unit, - ); + const usage = Number(item.material_usage) || 0; return sum + Math.round(usage * catalogPrice.price); }, 0), @@ -142,10 +120,7 @@ function materialLineCost(item: CuttingMaterialCartItem): number { return 0; } - const usage = usageInNativeUnit( - Number(item.material_usage) || 0, - catalogPrice.unit, - ); + const usage = Number(item.material_usage) || 0; return Math.round(usage * catalogPrice.price); } @@ -382,7 +357,6 @@ async function addMaterial( raw_material_name: rawMaterial.name, variant: price.variant, unit: rawMaterial.unit, - uses_length_unit: usesLengthUnit(rawMaterial.unit), unit_abbreviation: rawMaterial.unit_abbreviation, stock_input: price.stock_input, material_usage: defaultUsage, @@ -1006,7 +980,7 @@ function submit() {
- Pemakaian ({{ item.uses_length_unit ? 'cm' : item.unit_abbreviation }}) + Pemakaian ({{ item.unit_abbreviation }}) - Sisa ({{ item.uses_length_unit ? 'cm' : item.unit_abbreviation }}) + Sisa ({{ item.unit_abbreviation }}) - {{ item.material_usage }} {{ item.uses_length_unit ? 'cm' : item.unit_abbreviation }} + {{ item.material_usage }} {{ item.unit_abbreviation }}
- Sisa: {{ item.remaining_material }} {{ item.uses_length_unit ? 'cm' : item.unit_abbreviation }} + Sisa: {{ item.remaining_material }} {{ item.unit_abbreviation }} {{ formatRupiah(materialLineCost(item)) }}
diff --git a/resources/js/pages/admin/manage/cuttings/table/CuttingCompletedSection.vue b/resources/js/pages/admin/manage/cuttings/table/CuttingCompletedSection.vue index 3437537..78eb85c 100644 --- a/resources/js/pages/admin/manage/cuttings/table/CuttingCompletedSection.vue +++ b/resources/js/pages/admin/manage/cuttings/table/CuttingCompletedSection.vue @@ -12,59 +12,23 @@ import { } from '@/components/ui/empty'; import type { CuttingListItem } from '@/types/cutting'; -const CM_PER_YARD = 91.44; -const CM_PER_METER = 100; - -function formatTotalMaterialUsage(totalUsage: number | null | undefined, materials: any[]): string { - if (!totalUsage || !materials.length) { +function formatTotalMaterialUsage(totalUsage: number | null | undefined): string { + if (!totalUsage) { return '0'; } - const unit = materials[0]?.raw_material_price?.raw_material?.unit; - - if (unit === 'yard') { - return (totalUsage * CM_PER_YARD).toFixed(2); - } - - if (unit === 'meter') { - return (totalUsage * CM_PER_METER).toFixed(2); - } - return totalUsage.toFixed(2); } function getTotalMaterialUsageUnit(materials: any[]): string { - const unit = materials[0]?.raw_material_price?.raw_material?.unit; - - if (unit === 'yard' || unit === 'meter') { - return 'cm'; - } - return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation ?? ''; } function formatMaterialUsage(mat: any): string { - const usage = mat.material_usage ?? 0; - const unit = mat.raw_material_price?.raw_material?.unit; - - if (unit === 'yard') { - return (usage * CM_PER_YARD).toFixed(2); - } - - if (unit === 'meter') { - return (usage * CM_PER_METER).toFixed(2); - } - - return usage.toFixed(2); + return (mat.material_usage ?? 0).toFixed(2); } function getMaterialUnit(mat: any): string { - const unit = mat.raw_material_price?.raw_material?.unit; - - if (unit === 'yard' || unit === 'meter') { - return 'cm'; - } - return mat.raw_material_price?.raw_material?.unit_abbreviation ?? ''; } @@ -143,7 +107,7 @@ const totalCompleted = computed(() => props.cuttings.length);
Total Pemakaian Bahan: - {{ formatTotalMaterialUsage(cutting.total_material_usage, cutting.materials) }} {{ getTotalMaterialUsageUnit(cutting.materials) }} + {{ formatTotalMaterialUsage(cutting.total_material_usage) }} {{ getTotalMaterialUsageUnit(cutting.materials) }}
diff --git a/resources/js/pages/admin/manage/cuttings/table/CuttingGroupedTable.vue b/resources/js/pages/admin/manage/cuttings/table/CuttingGroupedTable.vue index 203046c..e0a9898 100644 --- a/resources/js/pages/admin/manage/cuttings/table/CuttingGroupedTable.vue +++ b/resources/js/pages/admin/manage/cuttings/table/CuttingGroupedTable.vue @@ -137,34 +137,15 @@ function getMaterialUnit(materials: any[]): string | undefined { return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation; } -const CM_PER_YARD = 91.44; -const CM_PER_METER = 100; - -function formatTotalMaterialUsage(totalUsage: number | null | undefined, materials: any[]): string { - if (!totalUsage || !materials.length) { +function formatTotalMaterialUsage(totalUsage: number | null | undefined): string { + if (!totalUsage) { return '0'; } - const unit = materials[0]?.raw_material_price?.raw_material?.unit; - - if (unit === 'yard') { - return (totalUsage * CM_PER_YARD).toFixed(2); - } - - if (unit === 'meter') { - return (totalUsage * CM_PER_METER).toFixed(2); - } - return totalUsage.toFixed(2); } function getTotalMaterialUsageUnit(materials: any[]): string { - const unit = materials[0]?.raw_material_price?.raw_material?.unit; - - if (unit === 'yard' || unit === 'meter') { - return 'cm'; - } - return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation ?? ''; } @@ -205,7 +186,7 @@ function getTotalMaterialUsageUnit(materials: any[]): string { Total Hasil Cutting {{ cutting.total_result_pieces ?? 0 }} pcs Total Pemakaian Bahan {{ - formatTotalMaterialUsage(cutting.total_material_usage, cutting.materials) }} + formatTotalMaterialUsage(cutting.total_material_usage) }} {{ getTotalMaterialUsageUnit(cutting.materials) }} Biaya Bahan {{ cutting.total_material_cost_formatted ?? 'Rp 0' }} @@ -253,15 +234,9 @@ function getTotalMaterialUsageUnit(materials: any[]): string { {{ material.material_usage_formatted }} - - ({{ material.material_usage_cm_formatted }}) - {{ material.remaining_material_formatted }} - - ({{ material.remaining_material_cm_formatted }}) - diff --git a/resources/js/pages/admin/manage/cuttings/table/CuttingInProgressSection.vue b/resources/js/pages/admin/manage/cuttings/table/CuttingInProgressSection.vue index 5a329f4..180deda 100644 --- a/resources/js/pages/admin/manage/cuttings/table/CuttingInProgressSection.vue +++ b/resources/js/pages/admin/manage/cuttings/table/CuttingInProgressSection.vue @@ -3,59 +3,23 @@ import { Card } from '@/components/ui/card'; import type { CuttingListItem } from '@/types/cutting'; import DataTableActions from './data-table-actions.vue'; -const CM_PER_YARD = 91.44; -const CM_PER_METER = 100; - -function formatTotalMaterialUsage(totalUsage: number | null | undefined, materials: any[]): string { - if (!totalUsage || !materials.length) { +function formatTotalMaterialUsage(totalUsage: number | null | undefined): string { + if (!totalUsage) { return '0'; } - const unit = materials[0]?.raw_material_price?.raw_material?.unit; - - if (unit === 'yard') { - return (totalUsage * CM_PER_YARD).toFixed(2); - } - - if (unit === 'meter') { - return (totalUsage * CM_PER_METER).toFixed(2); - } - return totalUsage.toFixed(2); } function getTotalMaterialUsageUnit(materials: any[]): string { - const unit = materials[0]?.raw_material_price?.raw_material?.unit; - - if (unit === 'yard' || unit === 'meter') { - return 'cm'; - } - return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation ?? ''; } function formatMaterialUsage(mat: any): string { - const usage = mat.material_usage ?? 0; - const unit = mat.raw_material_price?.raw_material?.unit; - - if (unit === 'yard') { - return (usage * CM_PER_YARD).toFixed(2); - } - - if (unit === 'meter') { - return (usage * CM_PER_METER).toFixed(2); - } - - return usage.toFixed(2); + return (mat.material_usage ?? 0).toFixed(2); } function getMaterialUnit(mat: any): string { - const unit = mat.raw_material_price?.raw_material?.unit; - - if (unit === 'yard' || unit === 'meter') { - return 'cm'; - } - return mat.raw_material_price?.raw_material?.unit_abbreviation ?? ''; } @@ -118,7 +82,7 @@ defineProps<{
Total Pemakaian Bahan: - {{ formatTotalMaterialUsage(cutting.total_material_usage, cutting.materials) }} {{ getTotalMaterialUsageUnit(cutting.materials) }} + {{ formatTotalMaterialUsage(cutting.total_material_usage) }} {{ getTotalMaterialUsageUnit(cutting.materials) }}
diff --git a/resources/js/types/cutting.ts b/resources/js/types/cutting.ts index 266d22e..f386c0f 100644 --- a/resources/js/types/cutting.ts +++ b/resources/js/types/cutting.ts @@ -14,9 +14,6 @@ export type CuttingMaterialListItem = { id: number; material_usage_formatted: string; remaining_material_formatted: string; - uses_length_unit?: boolean; - material_usage_cm_formatted?: string; - remaining_material_cm_formatted?: string; raw_material_price?: { id: number; variant: string; @@ -88,7 +85,6 @@ export type CuttingMaterialCartItem = { raw_material_name: string; variant: string; unit: string; - uses_length_unit: boolean; unit_abbreviation: string; stock_input: string; material_usage: string; @@ -117,8 +113,6 @@ export type CuttingEditItem = { raw_material_price_id: number; material_usage_input: string; remaining_material_input: string; - material_usage_cm_input?: string | null; - remaining_material_cm_input?: string | null; raw_material_price?: { variant: string; stock_input?: string;