Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

DateRangeService.php 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <?php
  2. namespace App\Services;
  3. use App\Facades\Accounting;
  4. use Carbon\CarbonPeriod;
  5. use Illuminate\Support\Carbon;
  6. class DateRangeService
  7. {
  8. protected string $fiscalYearStartDate = '';
  9. protected string $fiscalYearEndDate = '';
  10. public function __construct()
  11. {
  12. $company = auth()->user()->currentCompany;
  13. $this->fiscalYearStartDate = $company->locale->fiscalYearStartDate();
  14. $this->fiscalYearEndDate = $company->locale->fiscalYearEndDate();
  15. }
  16. public function getDateRangeOptions(): array
  17. {
  18. return once(function () {
  19. return $this->generateDateRangeOptions();
  20. });
  21. }
  22. private function generateDateRangeOptions(): array
  23. {
  24. $earliestDate = Carbon::parse(Accounting::getEarliestTransactionDate());
  25. $currentDate = company_today();
  26. $currentYear = $currentDate->year;
  27. $fiscalYearStartCurrent = Carbon::parse($this->fiscalYearStartDate);
  28. $options = [
  29. 'Fiscal Year' => [],
  30. 'Fiscal Quarter' => [],
  31. 'Calendar Year' => [],
  32. 'Calendar Quarter' => [],
  33. 'Month' => [],
  34. 'Custom' => [],
  35. ];
  36. $period = CarbonPeriod::create($earliestDate, '1 month', $currentDate);
  37. foreach ($period as $date) {
  38. $options['Fiscal Year']['FY-' . $date->year] = $date->year;
  39. $fiscalYearStart = $fiscalYearStartCurrent->copy()->subYears($currentYear - $date->year);
  40. for ($i = 0; $i < 4; $i++) {
  41. $quarterNumber = $i + 1;
  42. $quarterStart = $fiscalYearStart->copy()->addMonths(($quarterNumber - 1) * 3);
  43. $quarterEnd = $quarterStart->copy()->addMonths(3)->subDay();
  44. if ($quarterStart->lessThanOrEqualTo($currentDate) && $quarterEnd->greaterThanOrEqualTo($earliestDate)) {
  45. $options['Fiscal Quarter']['FQ-' . $quarterNumber . '-' . $date->year] = 'Q' . $quarterNumber . ' ' . $date->year;
  46. }
  47. }
  48. $options['Calendar Year']['Y-' . $date->year] = $date->year;
  49. $quarterKey = 'Q-' . $date->quarter . '-' . $date->year;
  50. $options['Calendar Quarter'][$quarterKey] = 'Q' . $date->quarter . ' ' . $date->year;
  51. $options['Month']['M-' . $date->format('Y-m')] = $date->format('F Y');
  52. $options['Custom']['Custom'] = 'Custom';
  53. }
  54. $options['Fiscal Year'] = array_reverse($options['Fiscal Year'], true);
  55. $options['Fiscal Quarter'] = array_reverse($options['Fiscal Quarter'], true);
  56. $options['Calendar Year'] = array_reverse($options['Calendar Year'], true);
  57. $options['Calendar Quarter'] = array_reverse($options['Calendar Quarter'], true);
  58. $options['Month'] = array_reverse($options['Month'], true);
  59. return $options;
  60. }
  61. public function getMatchingDateRangeOption(Carbon $startDate, Carbon $endDate): string
  62. {
  63. $options = $this->getDateRangeOptions();
  64. foreach ($options as $type => $ranges) {
  65. foreach ($ranges as $key => $label) {
  66. [$expectedStart, $expectedEnd] = $this->getExpectedDateRange($type, $key);
  67. if ($expectedStart === null || $expectedEnd === null) {
  68. continue;
  69. }
  70. $expectedEnd = $expectedEnd->isFuture() ? company_today() : $expectedEnd;
  71. if ($startDate->isSameDay($expectedStart) && $endDate->isSameDay($expectedEnd)) {
  72. return $key; // Return the matching range key (e.g., "FY-2024")
  73. }
  74. }
  75. }
  76. return 'Custom'; // Return "Custom" if no matching range is found
  77. }
  78. private function getExpectedDateRange(string $type, string $key): array
  79. {
  80. $currentYear = company_today()->year;
  81. switch ($type) {
  82. case 'Fiscal Year':
  83. $year = (int) substr($key, 3);
  84. $start = Carbon::parse($this->fiscalYearStartDate)->subYears($currentYear - $year)->startOfDay();
  85. $end = Carbon::parse($this->fiscalYearEndDate)->subYears($currentYear - $year)->startOfDay();
  86. break;
  87. case 'Fiscal Quarter':
  88. [$quarter, $year] = explode('-', substr($key, 3));
  89. $start = Carbon::parse($this->fiscalYearStartDate)->subYears($currentYear - $year)->addMonths(($quarter - 1) * 3)->startOfDay();
  90. $end = $start->copy()->addMonths(3)->subDay()->startOfDay();
  91. break;
  92. case 'Calendar Year':
  93. $year = (int) substr($key, 2);
  94. $start = Carbon::createFromDate($year)->startOfYear()->startOfDay();
  95. $end = Carbon::createFromDate($year)->endOfYear()->startOfDay();
  96. break;
  97. case 'Calendar Quarter':
  98. [$quarter, $year] = explode('-', substr($key, 2));
  99. $month = ($quarter - 1) * 3 + 1;
  100. $start = Carbon::createFromDate($year, $month, 1)->startOfDay();
  101. $end = $start->copy()->endOfQuarter()->startOfDay();
  102. break;
  103. case 'Month':
  104. $yearMonth = substr($key, 2);
  105. $start = Carbon::parse($yearMonth)->startOfMonth()->startOfDay();
  106. $end = Carbon::parse($yearMonth)->endOfMonth()->startOfDay();
  107. break;
  108. default:
  109. return [null, null];
  110. }
  111. return [$start, $end];
  112. }
  113. }