refactor: remove length unit handling from CuttingMaterial and related components for improved clarity and consistency in material usage representation
This commit is contained in:
parent
ec80f2145b
commit
fc234a6afd
@ -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'), ',');
|
||||
|
||||
@ -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') : [],
|
||||
];
|
||||
}
|
||||
|
||||
@ -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 ?? '',
|
||||
|
||||
@ -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() {
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<Field>
|
||||
<FieldLabel class="text-xs">
|
||||
Pemakaian ({{ item.uses_length_unit ? 'cm' : item.unit_abbreviation }})
|
||||
Pemakaian ({{ item.unit_abbreviation }})
|
||||
</FieldLabel>
|
||||
<DecimalInput
|
||||
v-model="
|
||||
@ -1022,7 +996,7 @@ function submit() {
|
||||
</Field>
|
||||
<Field>
|
||||
<FieldLabel class="text-xs">
|
||||
Sisa ({{ item.uses_length_unit ? 'cm' : item.unit_abbreviation }})
|
||||
Sisa ({{ item.unit_abbreviation }})
|
||||
</FieldLabel>
|
||||
<DecimalInput
|
||||
v-model="
|
||||
@ -1253,11 +1227,11 @@ function submit() {
|
||||
</p>
|
||||
</div>
|
||||
<span class="shrink-0 text-xs font-medium tabular-nums">
|
||||
{{ item.material_usage }} {{ item.uses_length_unit ? 'cm' : item.unit_abbreviation }}
|
||||
{{ item.material_usage }} {{ item.unit_abbreviation }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="mt-1.5 flex items-center justify-between gap-2 text-xs text-muted-foreground">
|
||||
<span>Sisa: {{ item.remaining_material }} {{ item.uses_length_unit ? 'cm' : item.unit_abbreviation }}</span>
|
||||
<span>Sisa: {{ item.remaining_material }} {{ item.unit_abbreviation }}</span>
|
||||
<span class="font-medium text-foreground">{{ formatRupiah(materialLineCost(item)) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -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);
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-[11px]">
|
||||
<span class="text-muted-foreground">Total Pemakaian Bahan:</span>
|
||||
<span class="font-semibold tabular-nums">{{ formatTotalMaterialUsage(cutting.total_material_usage, cutting.materials) }} {{ getTotalMaterialUsageUnit(cutting.materials) }}</span>
|
||||
<span class="font-semibold tabular-nums">{{ formatTotalMaterialUsage(cutting.total_material_usage) }} {{ getTotalMaterialUsageUnit(cutting.materials) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -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 {
|
||||
<span>Total Hasil Cutting <strong class="text-primary">{{ cutting.total_result_pieces ??
|
||||
0 }} pcs</strong></span>
|
||||
<span>Total Pemakaian Bahan <strong class="text-primary">{{
|
||||
formatTotalMaterialUsage(cutting.total_material_usage, cutting.materials) }}
|
||||
formatTotalMaterialUsage(cutting.total_material_usage) }}
|
||||
{{ getTotalMaterialUsageUnit(cutting.materials) }}</strong></span>
|
||||
<span>Biaya Bahan <strong class="text-primary">{{
|
||||
cutting.total_material_cost_formatted ?? 'Rp 0' }}</strong></span>
|
||||
@ -253,15 +234,9 @@ function getTotalMaterialUsageUnit(materials: any[]): string {
|
||||
</TableCell>
|
||||
<TableCell class="tabular-nums">
|
||||
{{ material.material_usage_formatted }}
|
||||
<span v-if="material.uses_length_unit" class="text-muted-foreground">
|
||||
({{ material.material_usage_cm_formatted }})
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell class="tabular-nums">
|
||||
{{ material.remaining_material_formatted }}
|
||||
<span v-if="material.uses_length_unit" class="text-muted-foreground">
|
||||
({{ material.remaining_material_cm_formatted }})
|
||||
</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</template>
|
||||
|
||||
@ -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<{
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-[11px]">
|
||||
<span class="text-muted-foreground">Total Pemakaian Bahan:</span>
|
||||
<span class="font-semibold tabular-nums">{{ formatTotalMaterialUsage(cutting.total_material_usage, cutting.materials) }} {{ getTotalMaterialUsageUnit(cutting.materials) }}</span>
|
||||
<span class="font-semibold tabular-nums">{{ formatTotalMaterialUsage(cutting.total_material_usage) }} {{ getTotalMaterialUsageUnit(cutting.materials) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user