diff --git a/app/Actions/Catalogue/Shop/Hydrators/ShopHydrateSales.php b/app/Actions/Catalogue/Shop/Hydrators/ShopHydrateSales.php index 33a72f8980..f090f15553 100644 --- a/app/Actions/Catalogue/Shop/Hydrators/ShopHydrateSales.php +++ b/app/Actions/Catalogue/Shop/Hydrators/ShopHydrateSales.php @@ -34,17 +34,17 @@ public function getJobMiddleware(): array return [(new WithoutOverlapping($this->shop->id))->dontRelease()]; } - public function handle(Shop $shop): void + public function handle(Shop $shop, ?array $intervals = null, $doPreviousIntervals = null): void { - $stats = []; + $stats = []; $queryBase = InvoiceTransaction::where('shop_id', $shop->id)->selectRaw('sum(net_amount) as sum_aggregate '); - $stats = $this->getIntervalsData($stats, $queryBase, 'sales_'); + $stats = $this->getIntervalsData($stats, $queryBase, 'sales_', $intervals, $doPreviousIntervals); $queryBase = InvoiceTransaction::where('shop_id', $shop->id)->selectRaw('sum(grp_net_amount) as sum_aggregate'); - $stats = $this->getIntervalsData($stats, $queryBase, 'sales_grp_currency_'); + $stats = $this->getIntervalsData($stats, $queryBase, 'sales_grp_currency_', $intervals, $doPreviousIntervals); $queryBase = InvoiceTransaction::where('shop_id', $shop->id)->selectRaw('sum(org_net_amount) as sum_aggregate'); - $stats = $this->getIntervalsData($stats, $queryBase, 'sales_org_currency_'); + $stats = $this->getIntervalsData($stats, $queryBase, 'sales_org_currency_', $intervals, $doPreviousIntervals); $shop->salesIntervals()->update($stats); } diff --git a/app/Actions/Helpers/Intervals/ResetDailyIntervals.php b/app/Actions/Helpers/Intervals/ResetDailyIntervals.php new file mode 100644 index 0000000000..0862896860 --- /dev/null +++ b/app/Actions/Helpers/Intervals/ResetDailyIntervals.php @@ -0,0 +1,80 @@ + + * Created: Fri, 03 Jan 2025 23:34:09 Malaysia Time, Kuala Lumpur, Malaysia + * Copyright (c) 2025, Raul A Perusquia Flores + */ + +namespace App\Actions\Helpers\Intervals; + +use App\Actions\Catalogue\Shop\Hydrators\ShopHydrateSales; +use App\Actions\SysAdmin\Group\Hydrators\GroupHydrateSales; +use App\Actions\SysAdmin\Organisation\Hydrators\OrganisationHydrateSales; +use App\Enums\DateIntervals\DateIntervalEnum; +use App\Enums\SysAdmin\Organisation\OrganisationTypeEnum; +use App\Models\Catalogue\Shop; +use App\Models\SysAdmin\Group; +use App\Models\SysAdmin\Organisation; +use Lorisleiva\Actions\Concerns\AsAction; + +class ResetDailyIntervals +{ + use AsAction; + + protected string $signature = 'intervals:reset-day'; + protected string $description = 'Reset day intervals'; + + + public function handle(): void + { + $this->resetDailyGroups(); + $this->resetDailyOrganisations(); + $this->resetDailyShops(); + } + + + protected function resetDailyGroups(): void + { + foreach (Group::all() as $group) { + GroupHydrateSales::dispatch( + group: $group, + intervals: [ + DateIntervalEnum::YESTERDAY, + DateIntervalEnum::TODAY + ], + doPreviousPeriods: [] + ); + } + } + + protected function resetDailyOrganisations(): void + { + foreach (Organisation::whereNot('type', OrganisationTypeEnum::AGENT)->get() as $organisation) { + OrganisationHydrateSales::dispatch( + organisation: $organisation, + intervals: [ + DateIntervalEnum::YESTERDAY, + DateIntervalEnum::TODAY + ], + doPreviousPeriods: [] + ); + } + } + + protected function resetDailyShops(): void + { + foreach (Shop::all() as $shop) { + ShopHydrateSales::dispatch( + shop: $shop, + intervals: [ + DateIntervalEnum::YESTERDAY, + DateIntervalEnum::TODAY + ], + doPreviousPeriods: [] + ); + } + } + + +} diff --git a/app/Actions/Helpers/Intervals/ResetMonthlyIntervals.php b/app/Actions/Helpers/Intervals/ResetMonthlyIntervals.php new file mode 100644 index 0000000000..6b4d7e7350 --- /dev/null +++ b/app/Actions/Helpers/Intervals/ResetMonthlyIntervals.php @@ -0,0 +1,82 @@ + + * Created: Sat, 04 Jan 2025 00:00:58 Malaysia Time, Kuala Lumpur, Malaysia + * Copyright (c) 2025, Raul A Perusquia Flores + */ + +namespace App\Actions\Helpers\Intervals; + +use App\Actions\Catalogue\Shop\Hydrators\ShopHydrateSales; +use App\Actions\SysAdmin\Group\Hydrators\GroupHydrateSales; +use App\Actions\SysAdmin\Organisation\Hydrators\OrganisationHydrateSales; +use App\Enums\DateIntervals\DateIntervalEnum; +use App\Enums\SysAdmin\Organisation\OrganisationTypeEnum; +use App\Models\Catalogue\Shop; +use App\Models\SysAdmin\Group; +use App\Models\SysAdmin\Organisation; +use Lorisleiva\Actions\Concerns\AsAction; + +class ResetMonthlyIntervals +{ + use AsAction; + + protected string $signature = 'intervals:reset-month'; + protected string $description = 'Reset monthly intervals'; + + + public function handle(): void + { + $this->resetMonthlyGroups(); + $this->resetMonthlyOrganisations(); + + + $this->resetMonthlyShops(); + } + + + protected function resetMonthlyGroups(): void + { + foreach (Group::all() as $group) { + GroupHydrateSales::dispatch( + group: $group, + intervals: [ + DateIntervalEnum::LAST_MONTH, + DateIntervalEnum::MONTH_TO_DAY + ], + doPreviousPeriods: [] + ); + } + } + + protected function resetMonthlyOrganisations(): void + { + foreach (Organisation::whereNot('type', OrganisationTypeEnum::AGENT)->get() as $organisation) { + OrganisationHydrateSales::dispatch( + organisation: $organisation, + intervals: [ + DateIntervalEnum::LAST_MONTH, + DateIntervalEnum::MONTH_TO_DAY + ], + doPreviousPeriods: [] + ); + } + } + + protected function resetMonthlyShops(): void + { + foreach (Shop::all() as $shop) { + ShopHydrateSales::dispatch( + shop: $shop, + intervals: [ + DateIntervalEnum::LAST_MONTH, + DateIntervalEnum::MONTH_TO_DAY + ], + doPreviousPeriods: [] + ); + } + } + + +} diff --git a/app/Actions/Helpers/Intervals/ResetQuarterlyIntervals.php b/app/Actions/Helpers/Intervals/ResetQuarterlyIntervals.php new file mode 100644 index 0000000000..9d293f52fb --- /dev/null +++ b/app/Actions/Helpers/Intervals/ResetQuarterlyIntervals.php @@ -0,0 +1,77 @@ + + * Created: Fri, 03 Jan 2025 17:46:17 Malaysia Time, Kuala Lumpur, Malaysia + * Copyright (c) 2025, Raul A Perusquia Flores + */ + +namespace App\Actions\Helpers\Intervals; + +use App\Actions\Catalogue\Shop\Hydrators\ShopHydrateSales; +use App\Actions\SysAdmin\Group\Hydrators\GroupHydrateSales; +use App\Actions\SysAdmin\Organisation\Hydrators\OrganisationHydrateSales; +use App\Enums\DateIntervals\DateIntervalEnum; +use App\Enums\SysAdmin\Organisation\OrganisationTypeEnum; +use App\Models\Catalogue\Shop; +use App\Models\SysAdmin\Group; +use App\Models\SysAdmin\Organisation; +use Lorisleiva\Actions\Concerns\AsAction; + +class ResetQuarterlyIntervals +{ + use AsAction; + + protected string $signature = 'intervals:reset-quarter'; + protected string $description = 'Reset quarter intervals'; + + + public function handle(): void + { + $this->resetQuarterlyGroups(); + $this->resetQuarterlyOrganisations(); + $this->resetQuarterlyShops(); + } + + + protected function resetQuarterlyGroups(): void + { + foreach (Group::all() as $group) { + GroupHydrateSales::dispatch( + group: $group, + intervals: [ + DateIntervalEnum::QUARTER_TO_DAY + ], + doPreviousPeriods: ['previous_quarters'] + ); + } + } + + protected function resetQuarterlyOrganisations(): void + { + foreach (Organisation::whereNot('type', OrganisationTypeEnum::AGENT)->get() as $organisation) { + OrganisationHydrateSales::dispatch( + organisation: $organisation, + intervals: [ + DateIntervalEnum::QUARTER_TO_DAY + ], + doPreviousPeriods: ['previous_quarters'] + ); + } + } + + protected function resetQuarterlyShops(): void + { + foreach (Shop::all() as $shop) { + ShopHydrateSales::dispatch( + shop: $shop, + intervals: [ + DateIntervalEnum::QUARTER_TO_DAY + ], + doPreviousPeriods: ['previous_quarters'] + ); + } + } + + +} diff --git a/app/Actions/Helpers/Intervals/ResetWeeklyIntervals.php b/app/Actions/Helpers/Intervals/ResetWeeklyIntervals.php new file mode 100644 index 0000000000..1335d9e076 --- /dev/null +++ b/app/Actions/Helpers/Intervals/ResetWeeklyIntervals.php @@ -0,0 +1,82 @@ + + * Created: Sat, 04 Jan 2025 00:45:24 Malaysia Time, Kuala Lumpur, Malaysia + * Copyright (c) 2025, Raul A Perusquia Flores + */ + +namespace App\Actions\Helpers\Intervals; + +use App\Actions\Catalogue\Shop\Hydrators\ShopHydrateSales; +use App\Actions\SysAdmin\Group\Hydrators\GroupHydrateSales; +use App\Actions\SysAdmin\Organisation\Hydrators\OrganisationHydrateSales; +use App\Enums\DateIntervals\DateIntervalEnum; +use App\Enums\SysAdmin\Organisation\OrganisationTypeEnum; +use App\Models\Catalogue\Shop; +use App\Models\SysAdmin\Group; +use App\Models\SysAdmin\Organisation; +use Lorisleiva\Actions\Concerns\AsAction; + +class ResetWeeklyIntervals +{ + use AsAction; + + protected string $signature = 'intervals:reset-week'; + protected string $description = 'Reset weekly intervals'; + + + public function handle(): void + { + $this->resetWeeklyGroups(); + $this->resetWeeklyOrganisations(); + + + $this->resetWeeklyShops(); + } + + + protected function resetWeeklyGroups(): void + { + foreach (Group::all() as $group) { + GroupHydrateSales::dispatch( + group: $group, + intervals: [ + DateIntervalEnum::LAST_WEEK, + DateIntervalEnum::WEEK_TO_DAY + ], + doPreviousPeriods: [] + ); + } + } + + protected function resetWeeklyOrganisations(): void + { + foreach (Organisation::whereNot('type', OrganisationTypeEnum::AGENT)->get() as $organisation) { + OrganisationHydrateSales::dispatch( + organisation: $organisation, + intervals: [ + DateIntervalEnum::LAST_WEEK, + DateIntervalEnum::WEEK_TO_DAY + ], + doPreviousPeriods: [] + ); + } + } + + protected function resetWeeklyShops(): void + { + foreach (Shop::all() as $shop) { + ShopHydrateSales::dispatch( + shop: $shop, + intervals: [ + DateIntervalEnum::LAST_WEEK, + DateIntervalEnum::WEEK_TO_DAY + ], + doPreviousPeriods: [] + ); + } + } + + +} diff --git a/app/Actions/Helpers/Intervals/ResetYearIntervals.php b/app/Actions/Helpers/Intervals/ResetYearIntervals.php new file mode 100644 index 0000000000..6d25bfd91d --- /dev/null +++ b/app/Actions/Helpers/Intervals/ResetYearIntervals.php @@ -0,0 +1,77 @@ + + * Created: Fri, 03 Jan 2025 17:46:17 Malaysia Time, Kuala Lumpur, Malaysia + * Copyright (c) 2025, Raul A Perusquia Flores + */ + +namespace App\Actions\Helpers\Intervals; + +use App\Actions\Catalogue\Shop\Hydrators\ShopHydrateSales; +use App\Actions\SysAdmin\Group\Hydrators\GroupHydrateSales; +use App\Actions\SysAdmin\Organisation\Hydrators\OrganisationHydrateSales; +use App\Enums\DateIntervals\DateIntervalEnum; +use App\Enums\SysAdmin\Organisation\OrganisationTypeEnum; +use App\Models\Catalogue\Shop; +use App\Models\SysAdmin\Group; +use App\Models\SysAdmin\Organisation; +use Lorisleiva\Actions\Concerns\AsAction; + +class ResetYearIntervals +{ + use AsAction; + + protected string $signature = 'intervals:reset-year'; + protected string $description = 'Reset year intervals'; + + + public function handle(): void + { + $this->resetYearlyGroups(); + $this->resetYearlyOrganisations(); + $this->resetYearlyShops(); + } + + + protected function resetYearlyGroups(): void + { + foreach (Group::all() as $group) { + GroupHydrateSales::dispatch( + group: $group, + intervals: [ + DateIntervalEnum::YEAR_TO_DAY + ], + doPreviousPeriods: ['previous_years'] + ); + } + } + + protected function resetYearlyOrganisations(): void + { + foreach (Organisation::whereNot('type', OrganisationTypeEnum::AGENT)->get() as $organisation) { + OrganisationHydrateSales::dispatch( + organisation: $organisation, + intervals: [ + DateIntervalEnum::YEAR_TO_DAY + ], + doPreviousPeriods: ['previous_years'] + ); + } + } + + protected function resetYearlyShops(): void + { + foreach (Shop::all() as $shop) { + ShopHydrateSales::dispatch( + shop: $shop, + intervals: [ + DateIntervalEnum::YEAR_TO_DAY + ], + doPreviousPeriods: ['previous_years'] + ); + } + } + + +} diff --git a/app/Actions/SysAdmin/Group/Hydrators/GroupHydrateSales.php b/app/Actions/SysAdmin/Group/Hydrators/GroupHydrateSales.php index 519b926fe2..d2df37843a 100644 --- a/app/Actions/SysAdmin/Group/Hydrators/GroupHydrateSales.php +++ b/app/Actions/SysAdmin/Group/Hydrators/GroupHydrateSales.php @@ -33,12 +33,12 @@ public function getJobMiddleware(): array return [(new WithoutOverlapping($this->group->id))->dontRelease()]; } - public function handle(Group $group): void + public function handle(Group $group, ?array $intervals = null, $doPreviousIntervals = null): void { $stats = []; - $queryBase = Invoice::where('group_id', $group->id)->selectRaw('sum(grp_net_amount) as sum_aggregate '); - $stats = $this->getIntervalsData($stats, $queryBase, 'sales_grp_currency_'); + $queryBase = Invoice::where('group_id', $group->id)->selectRaw('sum(grp_net_amount) as sum_aggregate'); + $stats = $this->getIntervalsData($stats, $queryBase, 'sales_grp_currency_', $intervals, $doPreviousIntervals); $group->salesIntervals()->update($stats); diff --git a/app/Actions/SysAdmin/Organisation/Hydrators/OrganisationHydrateSales.php b/app/Actions/SysAdmin/Organisation/Hydrators/OrganisationHydrateSales.php index 2b7cfc35c3..b1290489ae 100644 --- a/app/Actions/SysAdmin/Organisation/Hydrators/OrganisationHydrateSales.php +++ b/app/Actions/SysAdmin/Organisation/Hydrators/OrganisationHydrateSales.php @@ -9,6 +9,7 @@ namespace App\Actions\SysAdmin\Organisation\Hydrators; use App\Actions\Traits\WithIntervalsAggregators; +use App\Enums\SysAdmin\Organisation\OrganisationTypeEnum; use App\Models\Accounting\Invoice; use App\Models\SysAdmin\Organisation; use Illuminate\Queue\Middleware\WithoutOverlapping; @@ -33,15 +34,19 @@ public function getJobMiddleware(): array return [(new WithoutOverlapping($this->organisation->id))->dontRelease()]; } - public function handle(Organisation $organisation): void + public function handle(Organisation $organisation, ?array $intervals = null, $doPreviousIntervals = null): void { + if ($organisation->type == OrganisationTypeEnum::AGENT) { + return; + } + $stats = []; $queryBase = Invoice::where('organisation_id', $organisation->id)->selectRaw('sum(grp_net_amount) as sum_aggregate '); - $stats = $this->getIntervalsData($stats, $queryBase, 'sales_grp_currency_'); + $stats = $this->getIntervalsData($stats, $queryBase, 'sales_grp_currency_', $intervals, $doPreviousIntervals); $queryBase = Invoice::where('organisation_id', $organisation->id)->selectRaw(' sum(org_net_amount) as sum_aggregate '); - $stats = $this->getIntervalsData($stats, $queryBase, 'sales_org_currency_'); + $stats = $this->getIntervalsData($stats, $queryBase, 'sales_org_currency_', $intervals, $doPreviousIntervals); $organisation->salesIntervals()->update($stats); diff --git a/app/Actions/Traits/WithIntervalsAggregators.php b/app/Actions/Traits/WithIntervalsAggregators.php index 227af10efd..07460241c2 100644 --- a/app/Actions/Traits/WithIntervalsAggregators.php +++ b/app/Actions/Traits/WithIntervalsAggregators.php @@ -14,28 +14,40 @@ trait WithIntervalsAggregators { - public function getIntervalsData(array $stats, $queryBase, $statField, $dateField = 'date', $sumField = 'sum_aggregate'): array + public function getIntervalsData(array $stats, $queryBase, $statField, $dateField = 'date', $sumField = 'sum_aggregate', ?array $intervals = null, $doPreviousPeriods = null): array { - $stats = array_merge($stats, $this->getIntervalStats($queryBase, $statField, $dateField, $sumField)); - $stats = array_merge($stats, $this->getPreviousYearsIntervalStats($queryBase, $statField, $dateField, $sumField)); - $stats = array_merge($stats, $this->getPreviousQuartersIntervalStats($queryBase, $statField, $dateField, $sumField)); + $stats = array_merge($stats, $this->getIntervalStats($queryBase, $statField, $dateField, $sumField, $intervals)); + $stats = array_merge($stats, $this->getLastYearIntervalStats($queryBase, $statField, $dateField, $sumField, $intervals)); - return array_merge($stats, $this->getLastYearIntervalStats($queryBase, $statField, $dateField, $sumField)); + if ($doPreviousPeriods == null or in_array('previous_years', $doPreviousPeriods)) { + $stats = array_merge($stats, $this->getPreviousYearsIntervalStats($queryBase, $statField, $dateField, $sumField)); + } + + if ($doPreviousPeriods == null or in_array('previous_quarters', $doPreviousPeriods)) { + $stats = array_merge($stats, $this->getPreviousQuartersIntervalStats($queryBase, $statField, $dateField, $sumField)); + } + + return $stats; } public function getIntervalStats( $queryBase, string $statField, string $dateField = 'date', - string $sumField = 'sum_aggregate' + string $sumField = 'sum_aggregate', + ?array $intervals = null ): array { $stats = []; - foreach (DateIntervalEnum::cases() as $period) { + foreach (DateIntervalEnum::cases() as $interval) { + if ($intervals && !in_array($interval->value, $intervals)) { + continue; + } + $query = $queryBase->clone(); - $query = $period->wherePeriod($query, $dateField); + $query = $interval->wherePeriod($query, $dateField); - $res = $query->first(); - $stats[$statField.$period->value] = $res->{$sumField} ?? 0; + $res = $query->first(); + $stats[$statField.$interval->value] = $res->{$sumField} ?? 0; } return $stats; @@ -45,14 +57,19 @@ public function getLastYearIntervalStats( $queryBase, string $statField, string $dateField = 'date', - string $sumField = 'sum_aggregate' + string $sumField = 'sum_aggregate', + ?array $intervals = null ): array { $stats = []; - foreach (DateIntervalEnum::cases() as $period) { + foreach (DateIntervalEnum::cases() as $interval) { + if ($intervals && !in_array($interval->value, $intervals)) { + continue; + } + $query = $queryBase->clone(); - if ($query = $period->whereLastYearPeriod($query, $dateField)) { - $res = $query->first(); - $stats[$statField.$period->value.'_ly'] = $res->{$sumField} ?? 0; + if ($query = $interval->whereLastYearPeriod($query, $dateField)) { + $res = $query->first(); + $stats[$statField.$interval->value.'_ly'] = $res->{$sumField} ?? 0; } } @@ -71,9 +88,8 @@ public function getPreviousYearsIntervalStats( $query = $queryBase->clone(); $query = $period->wherePeriod($query, $dateField); - $res = $query->first(); + $res = $query->first(); $stats[$statField.$period->value] = $res->{$sumField} ?? 0; - } @@ -90,7 +106,7 @@ public function getPreviousQuartersIntervalStats( foreach (PreviousQuartersEnum::cases() as $period) { $query = $queryBase->clone(); if ($query = $period->wherePeriod($query, $dateField)) { - $res = $query->first(); + $res = $query->first(); $stats[$statField.$period->value] = $res->{$sumField} ?? 0; } } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index b4103cd275..7b94c73611 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,6 +2,11 @@ namespace App\Console; +use App\Actions\Helpers\Intervals\ResetDailyIntervals; +use App\Actions\Helpers\Intervals\ResetMonthlyIntervals; +use App\Actions\Helpers\Intervals\ResetQuarterlyIntervals; +use App\Actions\Helpers\Intervals\ResetWeeklyIntervals; +use App\Actions\Helpers\Intervals\ResetYearIntervals; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -14,6 +19,14 @@ protected function schedule(Schedule $schedule): void $schedule->command('hydrate:top_sellers')->daily(); $schedule->command('domain:check-cloudflare-status')->hourly(); $schedule->command('hydrate:fulfilment-customers-status')->daily(); + + $schedule->job(ResetYearIntervals::makeJob())->yearlyOn(1, 0, 0)->timezone('UTC'); + $schedule->job(ResetMonthlyIntervals::makeJob())->monthlyOn(1, 0)->timezone('UTC'); + $schedule->job(ResetQuarterlyIntervals::makeJob())->quarterlyOn(1, 0)->timezone('UTC'); + $schedule->job(ResetWeeklyIntervals::makeJob())->weeklyOn(1, 0)->timezone('UTC'); + $schedule->job(ResetDailyIntervals::makeJob())->dailyAt('00:00')->timezone('UTC'); + + }