You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

EditBudget.php 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <?php
  2. namespace App\Filament\Company\Resources\Accounting\BudgetResource\Pages;
  3. use App\Enums\Accounting\BudgetIntervalType;
  4. use App\Filament\Company\Resources\Accounting\BudgetResource;
  5. use App\Models\Accounting\Budget;
  6. use App\Models\Accounting\BudgetAllocation;
  7. use App\Models\Accounting\BudgetItem;
  8. use Filament\Actions;
  9. use Filament\Resources\Pages\EditRecord;
  10. use Illuminate\Database\Eloquent\Model;
  11. use Illuminate\Support\Carbon;
  12. class EditBudget extends EditRecord
  13. {
  14. protected static string $resource = BudgetResource::class;
  15. protected function getHeaderActions(): array
  16. {
  17. return [
  18. Actions\ViewAction::make(),
  19. Actions\DeleteAction::make(),
  20. ];
  21. }
  22. protected function mutateFormDataBeforeFill(array $data): array
  23. {
  24. /** @var Budget $budget */
  25. $budget = $this->record;
  26. $data['budgetItems'] = $budget->budgetItems->map(function (BudgetItem $budgetItem) {
  27. return [
  28. 'id' => $budgetItem->id,
  29. 'account_id' => $budgetItem->account_id,
  30. 'total_amount' => $budgetItem->allocations->sum('amount'), // Calculate total dynamically
  31. 'amounts' => $budgetItem->allocations->mapWithKeys(static function (BudgetAllocation $allocation) {
  32. return [$allocation->period => $allocation->amount]; // Use the correct period label
  33. })->toArray(),
  34. ];
  35. })->toArray();
  36. return $data;
  37. }
  38. protected function handleRecordUpdate(Model $record, array $data): Model
  39. {
  40. /** @var Budget $budget */
  41. $budget = $record;
  42. $budget->update([
  43. 'name' => $data['name'],
  44. 'interval_type' => $data['interval_type'],
  45. 'start_date' => $data['start_date'],
  46. 'end_date' => $data['end_date'],
  47. 'notes' => $data['notes'] ?? null,
  48. ]);
  49. $budgetItemIds = [];
  50. foreach ($data['budgetItems'] as $itemData) {
  51. /** @var BudgetItem $budgetItem */
  52. $budgetItem = $budget->budgetItems()->updateOrCreate(
  53. ['id' => $itemData['id'] ?? null],
  54. ['account_id' => $itemData['account_id']]
  55. );
  56. $budgetItemIds[] = $budgetItem->id;
  57. $budgetItem->allocations()->delete();
  58. $allocationStart = Carbon::parse($data['start_date']);
  59. foreach ($itemData['amounts'] as $periodLabel => $amount) {
  60. $allocationEnd = self::calculateEndDate($allocationStart, BudgetIntervalType::parse($data['interval_type']));
  61. // Recreate allocations
  62. $budgetItem->allocations()->create([
  63. 'period' => $periodLabel,
  64. 'interval_type' => $data['interval_type'],
  65. 'start_date' => $allocationStart->toDateString(),
  66. 'end_date' => $allocationEnd->toDateString(),
  67. 'amount' => $amount,
  68. ]);
  69. $allocationStart = $allocationEnd->addDay();
  70. }
  71. }
  72. $budget->budgetItems()->whereNotIn('id', $budgetItemIds)->delete();
  73. return $budget;
  74. }
  75. private static function calculateEndDate(Carbon $startDate, BudgetIntervalType $intervalType): Carbon
  76. {
  77. return match ($intervalType) {
  78. BudgetIntervalType::Month => $startDate->copy()->endOfMonth(),
  79. BudgetIntervalType::Quarter => $startDate->copy()->endOfQuarter(),
  80. BudgetIntervalType::Year => $startDate->copy()->endOfYear(),
  81. };
  82. }
  83. }