refactor: implement grouped material usage calculation across Cutting components for improved clarity and consistency in material representation
This commit is contained in:
parent
de045a4588
commit
061edbc568
@ -12,18 +12,6 @@ import {
|
|||||||
} from '@/components/ui/empty';
|
} from '@/components/ui/empty';
|
||||||
import type { CuttingListItem } from '@/types/cutting';
|
import type { CuttingListItem } from '@/types/cutting';
|
||||||
|
|
||||||
function formatTotalMaterialUsage(totalUsage: number | null | undefined): string {
|
|
||||||
if (!totalUsage) {
|
|
||||||
return '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return String(parseFloat(totalUsage.toFixed(2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTotalMaterialUsageUnit(materials: any[]): string {
|
|
||||||
return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatMaterialUsage(mat: any): string {
|
function formatMaterialUsage(mat: any): string {
|
||||||
return String(parseFloat(Number(mat.material_usage ?? 0).toFixed(2)));
|
return String(parseFloat(Number(mat.material_usage ?? 0).toFixed(2)));
|
||||||
}
|
}
|
||||||
@ -32,6 +20,28 @@ function getMaterialUnit(mat: any): string {
|
|||||||
return mat.raw_material_price?.raw_material?.unit_abbreviation ?? '';
|
return mat.raw_material_price?.raw_material?.unit_abbreviation ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MaterialUsageGroup {
|
||||||
|
total: string;
|
||||||
|
unit: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGroupedMaterialUsage(materials: any[]): MaterialUsageGroup[] {
|
||||||
|
const groups: Record<string, number> = {};
|
||||||
|
|
||||||
|
materials.forEach((mat) => {
|
||||||
|
const unit = mat.raw_material_price?.raw_material?.unit_abbreviation ?? '';
|
||||||
|
const usage = Number(mat.material_usage ?? 0);
|
||||||
|
groups[unit] = (groups[unit] ?? 0) + usage;
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.entries(groups)
|
||||||
|
.filter(([, total]) => total > 0)
|
||||||
|
.map(([unit, total]) => ({
|
||||||
|
total: String(parseFloat(total.toFixed(2))),
|
||||||
|
unit,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
cuttings: CuttingListItem[];
|
cuttings: CuttingListItem[];
|
||||||
}>();
|
}>();
|
||||||
@ -105,9 +115,13 @@ const totalCompleted = computed(() => props.cuttings.length);
|
|||||||
<span class="text-muted-foreground">Total Hasil Cutting:</span>
|
<span class="text-muted-foreground">Total Hasil Cutting:</span>
|
||||||
<span class="font-semibold tabular-nums">{{ cutting.total_result_pieces ?? 0 }} pcs</span>
|
<span class="font-semibold tabular-nums">{{ cutting.total_result_pieces ?? 0 }} pcs</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between text-[11px]">
|
<div v-if="cutting.materials.length" class="flex items-center justify-between text-[11px]">
|
||||||
<span class="text-muted-foreground">Total Pemakaian Bahan:</span>
|
<span class="text-muted-foreground">Total Pemakaian Bahan:</span>
|
||||||
<span class="font-semibold tabular-nums">{{ formatTotalMaterialUsage(cutting.total_material_usage) }} {{ getTotalMaterialUsageUnit(cutting.materials) }}</span>
|
<span class="font-semibold tabular-nums">{{ getGroupedMaterialUsage(cutting.materials).map(g => `${g.total} ${g.unit}`).join(', ') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between text-[11px]">
|
||||||
|
<span class="text-muted-foreground">Biaya Bahan:</span>
|
||||||
|
<span class="font-semibold tabular-nums">{{ cutting.total_material_cost_formatted ?? 'Rp 0' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -137,16 +137,26 @@ function getMaterialUnit(materials: any[]): string | undefined {
|
|||||||
return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation;
|
return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatTotalMaterialUsage(totalUsage: number | null | undefined): string {
|
interface MaterialUsageGroup {
|
||||||
if (!totalUsage) {
|
total: string;
|
||||||
return '0';
|
unit: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
return String(parseFloat(totalUsage.toFixed(2)));
|
function getGroupedMaterialUsage(materials: any[]): MaterialUsageGroup[] {
|
||||||
}
|
const groups: Record<string, number> = {};
|
||||||
|
|
||||||
function getTotalMaterialUsageUnit(materials: any[]): string {
|
materials.forEach((mat) => {
|
||||||
return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation ?? '';
|
const unit = mat.raw_material_price?.raw_material?.unit_abbreviation ?? '';
|
||||||
|
const usage = Number(mat.material_usage ?? 0);
|
||||||
|
groups[unit] = (groups[unit] ?? 0) + usage;
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.entries(groups)
|
||||||
|
.filter(([, total]) => total > 0)
|
||||||
|
.map(([unit, total]) => ({
|
||||||
|
total: String(parseFloat(total.toFixed(2))),
|
||||||
|
unit,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@ -185,9 +195,7 @@ function getTotalMaterialUsageUnit(materials: any[]): string {
|
|||||||
<div class="flex flex-wrap gap-x-4 gap-y-1 text-sm">
|
<div class="flex flex-wrap gap-x-4 gap-y-1 text-sm">
|
||||||
<span>Total Hasil Cutting <strong class="text-primary">{{ cutting.total_result_pieces ??
|
<span>Total Hasil Cutting <strong class="text-primary">{{ cutting.total_result_pieces ??
|
||||||
0 }} pcs</strong></span>
|
0 }} pcs</strong></span>
|
||||||
<span>Total Pemakaian Bahan <strong class="text-primary">{{
|
<span v-if="cutting.materials.length">Total Pemakaian Bahan <strong class="text-primary">{{ getGroupedMaterialUsage(cutting.materials).map(g => `${g.total} ${g.unit}`).join(', ') }}</strong></span>
|
||||||
formatTotalMaterialUsage(cutting.total_material_usage) }}
|
|
||||||
{{ getTotalMaterialUsageUnit(cutting.materials) }}</strong></span>
|
|
||||||
<span>Biaya Bahan <strong class="text-primary">{{
|
<span>Biaya Bahan <strong class="text-primary">{{
|
||||||
cutting.total_material_cost_formatted ?? 'Rp 0' }}</strong></span>
|
cutting.total_material_cost_formatted ?? 'Rp 0' }}</strong></span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,18 +3,6 @@ import { Card } from '@/components/ui/card';
|
|||||||
import type { CuttingListItem } from '@/types/cutting';
|
import type { CuttingListItem } from '@/types/cutting';
|
||||||
import DataTableActions from './data-table-actions.vue';
|
import DataTableActions from './data-table-actions.vue';
|
||||||
|
|
||||||
function formatTotalMaterialUsage(totalUsage: number | null | undefined): string {
|
|
||||||
if (!totalUsage) {
|
|
||||||
return '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return String(parseFloat(totalUsage.toFixed(2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTotalMaterialUsageUnit(materials: any[]): string {
|
|
||||||
return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatMaterialUsage(mat: any): string {
|
function formatMaterialUsage(mat: any): string {
|
||||||
return String(parseFloat(Number(mat.material_usage ?? 0).toFixed(2)));
|
return String(parseFloat(Number(mat.material_usage ?? 0).toFixed(2)));
|
||||||
}
|
}
|
||||||
@ -23,6 +11,28 @@ function getMaterialUnit(mat: any): string {
|
|||||||
return mat.raw_material_price?.raw_material?.unit_abbreviation ?? '';
|
return mat.raw_material_price?.raw_material?.unit_abbreviation ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MaterialUsageGroup {
|
||||||
|
total: string;
|
||||||
|
unit: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGroupedMaterialUsage(materials: any[]): MaterialUsageGroup[] {
|
||||||
|
const groups: Record<string, number> = {};
|
||||||
|
|
||||||
|
materials.forEach((mat) => {
|
||||||
|
const unit = mat.raw_material_price?.raw_material?.unit_abbreviation ?? '';
|
||||||
|
const usage = Number(mat.material_usage ?? 0);
|
||||||
|
groups[unit] = (groups[unit] ?? 0) + usage;
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.entries(groups)
|
||||||
|
.filter(([, total]) => total > 0)
|
||||||
|
.map(([unit, total]) => ({
|
||||||
|
total: String(parseFloat(total.toFixed(2))),
|
||||||
|
unit,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
cuttings: CuttingListItem[];
|
cuttings: CuttingListItem[];
|
||||||
}>();
|
}>();
|
||||||
@ -80,9 +90,13 @@ defineProps<{
|
|||||||
<span class="font-semibold tabular-nums">{{ cutting.total_result_pieces ?? 0 }}
|
<span class="font-semibold tabular-nums">{{ cutting.total_result_pieces ?? 0 }}
|
||||||
pcs</span>
|
pcs</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between text-[11px]">
|
<div v-if="cutting.materials.length" class="flex items-center justify-between text-[11px]">
|
||||||
<span class="text-muted-foreground">Total Pemakaian Bahan:</span>
|
<span class="text-muted-foreground">Total Pemakaian Bahan:</span>
|
||||||
<span class="font-semibold tabular-nums">{{ formatTotalMaterialUsage(cutting.total_material_usage) }} {{ getTotalMaterialUsageUnit(cutting.materials) }}</span>
|
<span class="font-semibold tabular-nums">{{ getGroupedMaterialUsage(cutting.materials).map(g => `${g.total} ${g.unit}`).join(', ') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between text-[11px]">
|
||||||
|
<span class="text-muted-foreground">Biaya Bahan:</span>
|
||||||
|
<span class="font-semibold tabular-nums">{{ cutting.total_material_cost_formatted ?? 'Rp 0' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user