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 => [
|
self::ADMIN_TOKO => [
|
||||||
Permission::DASHBOARD_VIEW,
|
Permission::DASHBOARD_VIEW,
|
||||||
|
|
||||||
|
Permission::CUTTINGS_VERIFY,
|
||||||
|
|
||||||
Permission::ATTENDANCES_VIEW,
|
Permission::ATTENDANCES_VIEW,
|
||||||
Permission::ATTENDANCES_CREATE,
|
Permission::ATTENDANCES_CREATE,
|
||||||
Permission::ATTENDANCES_DELETE,
|
Permission::ATTENDANCES_DELETE,
|
||||||
|
|||||||
@ -98,6 +98,7 @@ public function getInProgressCuttings(User $user): Collection
|
|||||||
|
|
||||||
$cutting->setAttribute('available_actions', $actions);
|
$cutting->setAttribute('available_actions', $actions);
|
||||||
$cutting->setAttribute('is_editable', $cutting->status->isEditable());
|
$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
|
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)) {
|
if (! in_array($cutting->status, [CuttingStatus::COMPLETED, CuttingStatus::VERIFIED], true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -698,7 +702,6 @@ private function appendCostPreview(Cutting $cutting): void
|
|||||||
$cutting->setAttribute('total_production_cost_formatted', 'Rp '.number_format($totalProductionCost, 0, ',', '.'));
|
$cutting->setAttribute('total_production_cost_formatted', 'Rp '.number_format($totalProductionCost, 0, ',', '.'));
|
||||||
$cutting->setAttribute('estimated_cost_per_unit', $costPerUnit);
|
$cutting->setAttribute('estimated_cost_per_unit', $costPerUnit);
|
||||||
$cutting->setAttribute('estimated_cost_per_unit_formatted', 'Rp '.number_format($costPerUnit, 0, ',', '.'));
|
$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
|
public function calculateTotalMaterialCost(Cutting $cutting): int
|
||||||
|
|||||||
@ -93,6 +93,21 @@ const totalCompleted = computed(() => props.cuttings.length);
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</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">
|
<div class="text-[11px] text-muted-foreground pt-2 border-t flex items-center justify-between">
|
||||||
<span>Pembuat:</span>
|
<span>Pembuat:</span>
|
||||||
<span class="font-medium text-foreground">
|
<span class="font-medium text-foreground">
|
||||||
|
|||||||
@ -132,6 +132,11 @@ function getGroupedResults(results: any[]): GroupedCuttingResults[] {
|
|||||||
|
|
||||||
return Object.values(groups);
|
return Object.values(groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getMaterialUnit(materials: any[]): string | undefined {
|
||||||
|
return materials[0]?.raw_material_price?.raw_material?.unit_abbreviation;
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -165,12 +170,24 @@ function getGroupedResults(results: any[]): GroupedCuttingResults[] {
|
|||||||
<p v-if="cutting.rejection?.reason" class="text-destructive text-sm">
|
<p v-if="cutting.rejection?.reason" class="text-destructive text-sm">
|
||||||
Alasan ditolak: {{ cutting.rejection.reason }}
|
Alasan ditolak: {{ cutting.rejection.reason }}
|
||||||
</p>
|
</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>
|
</div>
|
||||||
|
|
||||||
<div class="flex shrink-0 items-center justify-end gap-2 sm:pt-0.5">
|
<div class="flex shrink-0 items-center justify-end gap-2 sm:pt-0.5">
|
||||||
<DataTableActions :cutting="cutting" />
|
<DataTableActions :cutting="cutting" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6 p-4">
|
<div class="space-y-6 p-4">
|
||||||
@ -191,11 +208,13 @@ function getGroupedResults(results: any[]): GroupedCuttingResults[] {
|
|||||||
Belum ada bahan baku
|
Belum ada bahan baku
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</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">
|
<TableRow class="bg-muted/20 hover:bg-muted/20">
|
||||||
<TableCell colspan="3" class="font-semibold text-foreground">
|
<TableCell colspan="3" class="font-semibold text-foreground">
|
||||||
{{ group.rawMaterialName }}
|
{{ 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 }}
|
{{ group.unitLabel }}
|
||||||
</Badge>
|
</Badge>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@ -241,7 +260,8 @@ function getGroupedResults(results: any[]): GroupedCuttingResults[] {
|
|||||||
Belum ada hasil produk
|
Belum ada hasil produk
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</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">
|
<TableRow class="bg-muted/20 hover:bg-muted/20">
|
||||||
<TableCell colspan="4" class="font-semibold text-foreground">
|
<TableCell colspan="4" class="font-semibold text-foreground">
|
||||||
{{ group.productName }}
|
{{ group.productName }}
|
||||||
|
|||||||
@ -93,6 +93,17 @@ const totalInProgress = computed(() => props.cuttings.length);
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</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">
|
<div class="text-[11px] text-muted-foreground pt-2 border-t flex items-center justify-between">
|
||||||
<span>Pembuat:</span>
|
<span>Pembuat:</span>
|
||||||
<span class="font-medium text-foreground">
|
<span class="font-medium text-foreground">
|
||||||
|
|||||||
@ -14,12 +14,18 @@ export type CuttingMaterialListItem = {
|
|||||||
id: number;
|
id: number;
|
||||||
material_usage_formatted: string;
|
material_usage_formatted: string;
|
||||||
remaining_material_formatted: string;
|
remaining_material_formatted: string;
|
||||||
|
uses_length_unit?: boolean;
|
||||||
|
material_usage_cm_formatted?: string;
|
||||||
|
remaining_material_cm_formatted?: string;
|
||||||
raw_material_price?: {
|
raw_material_price?: {
|
||||||
id: number;
|
id: number;
|
||||||
variant: string;
|
variant: string;
|
||||||
raw_material?: {
|
raw_material?: {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
unit?: string;
|
||||||
|
unit_label?: string;
|
||||||
|
unit_abbreviation?: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -56,6 +62,7 @@ export type CuttingListItem = {
|
|||||||
total_production_cost?: number;
|
total_production_cost?: number;
|
||||||
total_production_cost_formatted?: string;
|
total_production_cost_formatted?: string;
|
||||||
total_result_pieces?: number;
|
total_result_pieces?: number;
|
||||||
|
total_material_usage?: number;
|
||||||
estimated_cost_per_unit?: number;
|
estimated_cost_per_unit?: number;
|
||||||
estimated_cost_per_unit_formatted?: string;
|
estimated_cost_per_unit_formatted?: string;
|
||||||
created_by?: {
|
created_by?: {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user