feat: add submittedBy relationship to Cutting model and enhance notification system for cutting updates and deletions
This commit is contained in:
parent
9170e5fd1e
commit
4cbd296c0c
@ -39,6 +39,11 @@ public function createdBy(): BelongsTo
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
}
|
||||
|
||||
public function submittedBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'submitted_by_id');
|
||||
}
|
||||
|
||||
public function materials(): HasMany
|
||||
{
|
||||
return $this->hasMany(CuttingMaterial::class);
|
||||
|
||||
@ -106,11 +106,28 @@ public function update(EmployeeAdvance $employeeAdvance, array $validated, User
|
||||
$employeeAdvance->due_date = $validated['due_date'];
|
||||
$employeeAdvance->save();
|
||||
});
|
||||
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
'✏️ Kasbon Diperbarui',
|
||||
"Kasbon sebesar {$employeeAdvance->amount_formatted} telah diperbarui oleh {$user->profile?->full_name}.",
|
||||
['owner', 'developer'],
|
||||
'/admin/finance/employee-advances',
|
||||
);
|
||||
}
|
||||
|
||||
public function delete(EmployeeAdvance $employeeAdvance, User $user): void
|
||||
{
|
||||
$amount = $employeeAdvance->amount_formatted;
|
||||
$description = $employeeAdvance->description;
|
||||
|
||||
$employeeAdvance->delete();
|
||||
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
'🗑️ Kasbon Dihapus',
|
||||
"Kasbon sebesar {$amount} dengan keterangan {$description} telah dihapus.",
|
||||
['owner', 'developer'],
|
||||
'/admin/finance/employee-advances',
|
||||
);
|
||||
}
|
||||
|
||||
public function approve(EmployeeAdvance $employeeAdvance, User $user): void
|
||||
|
||||
@ -269,6 +269,15 @@ public function deleteAdjustment(PayrollAdjustment $adjustment): void
|
||||
$payroll->recalculateAmounts();
|
||||
$payroll->save();
|
||||
});
|
||||
|
||||
if ($payroll->employee?->user_id) {
|
||||
$this->pushNotificationService->sendToUser(
|
||||
'📊 Penyesuaian Gaji Dihapus',
|
||||
"Penyesuaian gaji Anda untuk periode {$payroll->payrollPeriod->period_label} telah dihapus.",
|
||||
$payroll->employee->user_id,
|
||||
'/admin/finance/payrolls',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function pay(Payroll $payroll, User $user): void
|
||||
|
||||
@ -160,8 +160,19 @@ public function checkOut(array $validated, User $user): void
|
||||
|
||||
public function delete(Attendance $attendance): void
|
||||
{
|
||||
$attendance->loadMissing('employee.user.profile');
|
||||
$employeeName = $attendance->employee?->user?->profile?->full_name;
|
||||
$date = $attendance->attendance_date;
|
||||
|
||||
$attendance->clearMediaCollection('checkin');
|
||||
$attendance->clearMediaCollection('checkout');
|
||||
$attendance->delete();
|
||||
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
'🗑️ Presensi Dihapus',
|
||||
"Data presensi {$employeeName} tanggal {$date} telah dihapus.",
|
||||
['owner', 'developer'],
|
||||
'/admin/hr/attendances',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,11 +101,28 @@ public function update(LeaveRequest $leaveRequest, array $validated, User $user)
|
||||
$leaveRequest->end_date = $endDate;
|
||||
$leaveRequest->total_days = $this->calculateTotalDays($startDate, $endDate);
|
||||
$leaveRequest->save();
|
||||
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
'✏️ Pengajuan Cuti Diperbarui',
|
||||
"Pengajuan cuti oleh {$user->profile?->full_name} telah diperbarui.",
|
||||
['owner', 'developer'],
|
||||
'/admin/hr/leave-requests',
|
||||
);
|
||||
}
|
||||
|
||||
public function delete(LeaveRequest $leaveRequest): void
|
||||
{
|
||||
$totalDays = $leaveRequest->total_days;
|
||||
$employeeName = $leaveRequest->employee?->user?->profile?->full_name;
|
||||
|
||||
$leaveRequest->delete();
|
||||
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
'🗑️ Pengajuan Cuti Dihapus',
|
||||
"Pengajuan cuti {$totalDays} hari oleh {$employeeName} telah dihapus.",
|
||||
['owner', 'developer'],
|
||||
'/admin/hr/leave-requests',
|
||||
);
|
||||
}
|
||||
|
||||
public function approve(LeaveRequest $leaveRequest, User $user): void
|
||||
|
||||
@ -506,6 +506,14 @@ public function update(Cutting $cutting, array $validated): void
|
||||
$this->deductMaterialStock($cutting);
|
||||
}
|
||||
});
|
||||
|
||||
$description = $cutting->description ?? '-';
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
'✏️ Proses Cutting Diperbarui',
|
||||
"Proses cutting dengan deskripsi '{$description}' telah diperbarui.",
|
||||
['owner', 'developer'],
|
||||
'/admin/manage/cuttings',
|
||||
);
|
||||
}
|
||||
|
||||
public function delete(Cutting $cutting): void
|
||||
@ -615,10 +623,14 @@ public function transitionStatus(
|
||||
default => '✂️ Proses Cutting Diperbarui',
|
||||
};
|
||||
|
||||
$roles = $status === CuttingStatus::COMPLETED
|
||||
? ['owner', 'developer', 'admin-toko']
|
||||
: ['owner', 'developer'];
|
||||
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
$title,
|
||||
$message,
|
||||
['owner', 'developer'],
|
||||
$roles,
|
||||
'/admin/manage/cuttings',
|
||||
);
|
||||
}
|
||||
|
||||
@ -109,6 +109,7 @@ public function submitVerification(
|
||||
]);
|
||||
}
|
||||
|
||||
$cutting->submitted_by_id = $user->id;
|
||||
$cutting->status = CuttingStatus::PENDING_VERIFICATION;
|
||||
$cutting->save();
|
||||
});
|
||||
@ -195,6 +196,15 @@ public function rejectVerification(
|
||||
['owner', 'developer'],
|
||||
'/admin/manage/owner-verifications',
|
||||
);
|
||||
|
||||
if ($cutting->submitted_by_id) {
|
||||
$this->pushNotificationService->sendToUser(
|
||||
'📦 Verifikasi Cutting Ditolak Owner',
|
||||
"Cutting dengan deskripsi '{$description}' yang Anda verifikasi ditolak oleh owner dengan alasan: '{$reason}'.",
|
||||
$cutting->submitted_by_id,
|
||||
'/admin/manage/owner-verifications',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function applyProductStockOnVerify(Cutting $cutting): void
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('cuttings', function (Blueprint $table) {
|
||||
$table->foreignId('submitted_by_id')
|
||||
->nullable()
|
||||
->after('created_by_id')
|
||||
->constrained('users')
|
||||
->nullOnDelete();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('cuttings', function (Blueprint $table) {
|
||||
$table->dropConstrainedForeignId('submitted_by_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -15,30 +15,30 @@ public function run(): void
|
||||
RolePermissionSeeder::class,
|
||||
UserSeeder::class,
|
||||
SystemConfigurationSeeder::class,
|
||||
CategorySeeder::class,
|
||||
ProductSeeder::class,
|
||||
ProductVariantSeeder::class,
|
||||
RawMaterialSeeder::class,
|
||||
RawMaterialPriceSeeder::class,
|
||||
SupplierSeeder::class,
|
||||
CustomerSeeder::class,
|
||||
// CategorySeeder::class,
|
||||
// ProductSeeder::class,
|
||||
// ProductVariantSeeder::class,
|
||||
// RawMaterialSeeder::class,
|
||||
// RawMaterialPriceSeeder::class,
|
||||
// SupplierSeeder::class,
|
||||
// CustomerSeeder::class,
|
||||
CashAccountSeeder::class,
|
||||
CashTransactionSeeder::class,
|
||||
ExpenseSeeder::class,
|
||||
PayrollPeriodSeeder::class,
|
||||
PayrollSeeder::class,
|
||||
PayrollAdjustmentSeeder::class,
|
||||
AttendanceSeeder::class,
|
||||
LeaveRequestSeeder::class,
|
||||
EmployeeAdvanceSeeder::class,
|
||||
RejectionSeeder::class,
|
||||
PurchaseSeeder::class,
|
||||
PurchaseItemSeeder::class,
|
||||
OrderSeeder::class,
|
||||
OrderItemSeeder::class,
|
||||
CuttingSeeder::class,
|
||||
CuttingMaterialSeeder::class,
|
||||
CuttingResultSeeder::class,
|
||||
// CashTransactionSeeder::class,
|
||||
// ExpenseSeeder::class,
|
||||
// PayrollPeriodSeeder::class,
|
||||
// PayrollSeeder::class,
|
||||
// PayrollAdjustmentSeeder::class,
|
||||
// AttendanceSeeder::class,
|
||||
// LeaveRequestSeeder::class,
|
||||
// EmployeeAdvanceSeeder::class,
|
||||
// RejectionSeeder::class,
|
||||
// PurchaseSeeder::class,
|
||||
// PurchaseItemSeeder::class,
|
||||
// OrderSeeder::class,
|
||||
// OrderItemSeeder::class,
|
||||
// CuttingSeeder::class,
|
||||
// CuttingMaterialSeeder::class,
|
||||
// CuttingResultSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user