Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

DateRangeSelect.php 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. namespace App\Filament\Forms\Components;
  3. use App\Facades\Accounting;
  4. use App\Models\Company;
  5. use Carbon\CarbonPeriod;
  6. use Filament\Forms\Components\Select;
  7. use Filament\Forms\Set;
  8. use Illuminate\Support\Carbon;
  9. class DateRangeSelect extends Select
  10. {
  11. public string $fiscalYearStartDate = '';
  12. public string $fiscalYearEndDate = '';
  13. public string $startDateField = '';
  14. public string $endDateField = '';
  15. public Company $company;
  16. protected function setUp(): void
  17. {
  18. parent::setUp();
  19. $this->company = auth()->user()->currentCompany;
  20. $this->fiscalYearStartDate = $this->company->locale->fiscalYearStartDate();
  21. $this->fiscalYearEndDate = $this->company->locale->fiscalYearEndDate();
  22. $this->options($this->getDateRangeOptions())
  23. ->live()
  24. ->afterStateUpdated(function ($state, Set $set) {
  25. $this->updateDateRange($state, $set);
  26. });
  27. }
  28. public function startDateField(string $fieldName): static
  29. {
  30. $this->startDateField = $fieldName;
  31. return $this;
  32. }
  33. public function endDateField(string $fieldName): static
  34. {
  35. $this->endDateField = $fieldName;
  36. return $this;
  37. }
  38. public function getDateRangeOptions(): array
  39. {
  40. $earliestDate = Carbon::parse(Accounting::getEarliestTransactionDate());
  41. $currentDate = now();
  42. $fiscalYearStartCurrent = Carbon::parse($this->fiscalYearStartDate);
  43. $options = [
  44. 'Fiscal Year' => [],
  45. 'Fiscal Quarter' => [],
  46. 'Calendar Year' => [],
  47. 'Calendar Quarter' => [],
  48. 'Month' => [],
  49. 'Custom' => [],
  50. ];
  51. $period = CarbonPeriod::create($earliestDate, '1 month', $currentDate);
  52. foreach ($period as $date) {
  53. $options['Fiscal Year']['FY-' . $date->year] = $date->year;
  54. $fiscalYearStart = $fiscalYearStartCurrent->copy()->subYears($currentDate->year - $date->year);
  55. for ($i = 0; $i < 4; $i++) {
  56. $quarterNumber = $i + 1;
  57. $quarterStart = $fiscalYearStart->copy()->addMonths(($quarterNumber - 1) * 3);
  58. $quarterEnd = $quarterStart->copy()->addMonths(3)->subDay();
  59. if ($quarterStart->lessThanOrEqualTo($currentDate) && $quarterEnd->greaterThanOrEqualTo($earliestDate)) {
  60. $options['Fiscal Quarter']['FQ-' . $quarterNumber . '-' . $date->year] = 'Q' . $quarterNumber . ' ' . $date->year;
  61. }
  62. }
  63. $options['Calendar Year']['Y-' . $date->year] = $date->year;
  64. $quarterKey = 'Q-' . $date->quarter . '-' . $date->year;
  65. $options['Calendar Quarter'][$quarterKey] = 'Q' . $date->quarter . ' ' . $date->year;
  66. $options['Month']['M-' . $date->format('Y-m')] = $date->format('F Y');
  67. $options['Custom']['Custom'] = 'Custom';
  68. }
  69. $options['Fiscal Year'] = array_reverse($options['Fiscal Year'], true);
  70. $options['Fiscal Quarter'] = array_reverse($options['Fiscal Quarter'], true);
  71. $options['Calendar Year'] = array_reverse($options['Calendar Year'], true);
  72. $options['Calendar Quarter'] = array_reverse($options['Calendar Quarter'], true);
  73. $options['Month'] = array_reverse($options['Month'], true);
  74. return $options;
  75. }
  76. public function updateDateRange($state, Set $set): void
  77. {
  78. if ($state === null) {
  79. $set($this->startDateField, null);
  80. $set($this->endDateField, null);
  81. return;
  82. }
  83. [$type, $param1, $param2] = explode('-', $state) + [null, null, null];
  84. $this->processDateRange($type, $param1, $param2, $set);
  85. }
  86. public function processDateRange($type, $param1, $param2, Set $set): void
  87. {
  88. match ($type) {
  89. 'FY' => $this->processFiscalYear($param1, $set),
  90. 'FQ' => $this->processFiscalQuarter($param1, $param2, $set),
  91. 'Y' => $this->processCalendarYear($param1, $set),
  92. 'Q' => $this->processCalendarQuarter($param1, $param2, $set),
  93. 'M' => $this->processMonth("{$param1}-{$param2}", $set),
  94. 'Custom' => null,
  95. };
  96. }
  97. public function processFiscalYear($year, Set $set): void
  98. {
  99. $currentYear = now()->year;
  100. $diff = $currentYear - $year;
  101. $fiscalYearStart = Carbon::parse($this->fiscalYearStartDate)->subYears($diff);
  102. $fiscalYearEnd = Carbon::parse($this->fiscalYearEndDate)->subYears($diff);
  103. $this->setDateRange($fiscalYearStart, $fiscalYearEnd, $set);
  104. }
  105. public function processFiscalQuarter($quarter, $year, Set $set): void
  106. {
  107. $currentYear = now()->year;
  108. $diff = $currentYear - $year;
  109. $fiscalYearStart = Carbon::parse($this->fiscalYearStartDate)->subYears($diff);
  110. $quarterStart = $fiscalYearStart->copy()->addMonths(($quarter - 1) * 3);
  111. $quarterEnd = $quarterStart->copy()->addMonths(3)->subDay();
  112. $this->setDateRange($quarterStart, $quarterEnd, $set);
  113. }
  114. public function processCalendarYear($year, Set $set): void
  115. {
  116. $start = Carbon::createFromDate($year)->startOfYear();
  117. $end = Carbon::createFromDate($year)->endOfYear();
  118. $this->setDateRange($start, $end, $set);
  119. }
  120. public function processCalendarQuarter($quarter, $year, Set $set): void
  121. {
  122. $month = ($quarter - 1) * 3 + 1;
  123. $start = Carbon::createFromDate($year, $month, 1);
  124. $end = Carbon::createFromDate($year, $month, 1)->endOfQuarter();
  125. $this->setDateRange($start, $end, $set);
  126. }
  127. public function processMonth($yearMonth, Set $set): void
  128. {
  129. $start = Carbon::parse($yearMonth)->startOfMonth();
  130. $end = Carbon::parse($yearMonth)->endOfMonth();
  131. $this->setDateRange($start, $end, $set);
  132. }
  133. public function setDateRange(Carbon $start, Carbon $end, Set $set): void
  134. {
  135. $set($this->startDateField, $start->startOfDay()->toDateString());
  136. $set($this->endDateField, $end->isFuture() ? now()->endOfDay()->toDateTimeString() : $end->endOfDay()->toDateTimeString());
  137. }
  138. }