feat: enhance cutting management by adding total result pieces and material usage display in Cutting components and updating related services
This commit is contained in:
parent
3cdabfae30
commit
9df8fe1ce2
@ -92,6 +92,8 @@ public function permissions(): array
|
||||
self::ADMIN_TOKO => [
|
||||
Permission::DASHBOARD_VIEW,
|
||||
|
||||
Permission::CUTTINGS_VERIFY,
|
||||
|
||||
Permission::ATTENDANCES_VIEW,
|
||||
Permission::ATTENDANCES_CREATE,
|
||||
Permission::ATTENDANCES_DELETE,
|
||||
|
||||
@ -98,6 +98,7 @@ public function getInProgressCuttings(User $user): Collection
|
||||
|
||||
$cutting->setAttribute('available_actions', $actions);
|
||||
$cutting->setAttribute('is_editable', $cutting->status->isEditable());
|
||||
$this->appendCostPreview($cutting);
|
||||
});
|
||||
}
|
||||
|
||||
@ -678,6 +679,9 @@ private function applySorting(Builder $query, string $sort, string $direction):
|
||||
|
||||
private function appendCostPreview(Cutting $cutting): void
|
||||
{
|
||||
$cutting->setAttribute('total_result_pieces', (int) $cutting->results->sum('cutting_result'));
|
||||
$cutting->setAttribute('total_material_usage', (float) $cutting->materials->sum('material_usage'));
|
||||
|
||||
if (! in_array($cutting->status, [CuttingStatus::COMPLETED, CuttingStatus::VERIFIED], true)) {
|
||||
return;
|
||||
}
|
||||
@ -698,7 +702,6 @@ private function appendCostPreview(Cutting $cutting): void
|
||||
$cutting->setAttribute('total_production_cost_formatted', 'Rp '.number_format($totalProductionCost, 0, ',', '.'));
|
||||
$cutting->setAttribute('estimated_cost_per_unit', $costPerUnit);
|
||||
$cutting->setAttribute('estimated_cost_per_unit_formatted', 'Rp '.number_format($costPerUnit, 0, ',', '.'));
|
||||
$cutting->setAttribute('total_result_pieces', (int) $cutting->results->sum('cutting_result'));
|
||||
}
|
||||
|
||||
public function calculateTotalMaterialCost(Cutting $cutting): int
|
||||
|
||||
@ -93,6 +93,21 @@ const totalCompleted = computed(() => props.cuttings.length);
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div v-if="cutting.results.length" class="space-y-1.5 pt-2 border-t">
|
||||
<div class="flex items-center justify-between text-[11px]">
|
||||
<span class="text-muted-foreground">Total Hasil Cutting:</span>
|
||||
<span class="font-semibold tabular-nums">{{ cutting.total_result_pieces ?? 0 }} pcs</span>
|
||||
</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">{{ cutting.total_material_usage ?? 0 }}</span>
|
||||
</div>
|
||||
<div v-if="cutting.estimated_cost_per_unit_formatted" class="flex items-center justify-between text-[11px]">
|
||||
<span class="text-muted-foreground">Harga Modal:</span>
|
||||
<span class="font-semibold">{{ cutting.estimated_cost_per_unit_formatted }}/pcs</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-[11px] text-muted-foreground pt-2 border-t flex items-center justify-between">
|
||||
<span>Pembuat:</span>
|
||||
<span class="font-medium text-foreground">
|
||||
|
||||
@ -132,6 +132,11 @@ function getGroupedResults(results: any[]): GroupedCuttingResults[] {
|
||||
|
||||
return Object.values(groups);
|
||||
}
|
||||
|
||||
function getMaterialUnit(materials: any[]): string | undefined {
|
||||
return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -165,12 +170,24 @@ function getGroupedResults(results: any[]): GroupedCuttingResults[] {
|
||||
<p v-if="cutting.rejection?.reason" class="text-destructive text-sm">
|
||||
Alasan ditolak: {{ cutting.rejection.reason }}
|
||||
</p>
|
||||
<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 ??
|
||||
0 }} pcs</strong></span>
|
||||
<span>Total Pemakaian Bahan <strong class="text-primary">{{ cutting.total_material_usage
|
||||
??
|
||||
0 }} {{ getMaterialUnit(cutting.materials) }}</strong></span>
|
||||
<span>Total Biaya Produksi <strong class="text-primary">{{
|
||||
cutting.total_production_cost_formatted ?? 0 }}</strong></span>
|
||||
<span>Harga Modal <strong class="text-primary">{{
|
||||
cutting.estimated_cost_per_unit_formatted ??
|
||||
0 }}</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex shrink-0 items-center justify-end gap-2 sm:pt-0.5">
|
||||
<DataTableActions :cutting="cutting" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-6 p-4">
|
||||
@ -191,11 +208,13 @@ function getGroupedResults(results: any[]): GroupedCuttingResults[] {
|
||||
Belum ada bahan baku
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<template v-else v-for="group in getGroupedMaterials(cutting.materials)" :key="group.rawMaterialId">
|
||||
<template v-else v-for="group in getGroupedMaterials(cutting.materials)"
|
||||
:key="group.rawMaterialId">
|
||||
<TableRow class="bg-muted/20 hover:bg-muted/20">
|
||||
<TableCell colspan="3" class="font-semibold text-foreground">
|
||||
{{ group.rawMaterialName }}
|
||||
<Badge v-if="group.unitLabel" variant="secondary" class="ml-2 font-normal">
|
||||
<Badge v-if="group.unitLabel" variant="secondary"
|
||||
class="ml-2 font-normal">
|
||||
{{ group.unitLabel }}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
@ -241,7 +260,8 @@ function getGroupedResults(results: any[]): GroupedCuttingResults[] {
|
||||
Belum ada hasil produk
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<template v-else v-for="group in getGroupedResults(cutting.results)" :key="group.productId">
|
||||
<template v-else v-for="group in getGroupedResults(cutting.results)"
|
||||
:key="group.productId">
|
||||
<TableRow class="bg-muted/20 hover:bg-muted/20">
|
||||
<TableCell colspan="4" class="font-semibold text-foreground">
|
||||
{{ group.productName }}
|
||||
|
||||
@ -93,6 +93,17 @@ const totalInProgress = computed(() => props.cuttings.length);
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div v-if="cutting.results.length" class="space-y-1.5 pt-2 border-t">
|
||||
<div class="flex items-center justify-between text-[11px]">
|
||||
<span class="text-muted-foreground">Total Hasil Cutting:</span>
|
||||
<span class="font-semibold tabular-nums">{{ cutting.total_result_pieces ?? 0 }} pcs</span>
|
||||
</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">{{ cutting.total_material_usage ?? 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-[11px] text-muted-foreground pt-2 border-t flex items-center justify-between">
|
||||
<span>Pembuat:</span>
|
||||
<span class="font-medium text-foreground">
|
||||
|
||||
@ -14,12 +14,18 @@ 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;
|
||||
raw_material?: {
|
||||
id: number;
|
||||
name: string;
|
||||
unit?: string;
|
||||
unit_label?: string;
|
||||
unit_abbreviation?: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -56,6 +62,7 @@ export type CuttingListItem = {
|
||||
total_production_cost?: number;
|
||||
total_production_cost_formatted?: string;
|
||||
total_result_pieces?: number;
|
||||
total_material_usage?: number;
|
||||
estimated_cost_per_unit?: number;
|
||||
estimated_cost_per_unit_formatted?: string;
|
||||
created_by?: {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user