$statsType * @return array * * @phpcs:disable Generic.Metrics.CyclomaticComplexity */ public function getStats(array $statsType, CarbonInterface $start, CarbonInterface $end): array { // phpcs:enable $stats = []; foreach ($statsType as $type) { $previousPeriod = $this->getPreviousPeriod($start, $end); $previousStart = $previousPeriod->getStartDate(); $previousEnd = $previousPeriod->getIncludedEndDate(); switch ($type) { case StatsShopType::canceledRate: $previous = $this->getCanceledRate($previousStart, $previousEnd); $current = $this->getCanceledRate($start, $end); break; case StatsShopType::orderFrequency: $previous = $this->getOrderFrequency($previousStart, $previousEnd); $current = $this->getOrderFrequency($start, $end); break; case StatsShopType::purchaseFrequency: $previous = $this->getPurchaseFrequency($previousStart, $previousEnd); $current = $this->getPurchaseFrequency($start, $end); break; case StatsShopType::averageBasketHt: $previous = $this->getAverageBasketHt($previousStart, $previousEnd); $current = $this->getAverageBasketHt($start, $end); break; case StatsShopType::averageProductCountPerOrder: $previous = $this->getAverageProductCountPerOrder($previousStart, $previousEnd); $current = $this->getAverageProductCountPerOrder($start, $end); break; case StatsShopType::caHt: $previous = $this->getCaHt($previousStart, $previousEnd); $current = $this->getCaHt($start, $end); break; case StatsShopType::caTtc: $previous = $this->getCaTtc($previousStart, $previousEnd); $current = $this->getCaTtc($start, $end); break; case StatsShopType::nbCmdWith7DayDelay: $previous = $this->getNbCmdWith7DayDelay($previousStart, $previousEnd); $current = $this->getNbCmdWith7DayDelay($start, $end); break; case StatsShopType::nbCmdWith14DayDelay: $previous = $this->getNbCmdWith14DayDelay($previousStart, $previousEnd); $current = $this->getNbCmdWith14DayDelay($start, $end); break; case StatsShopType::nbActiveClients: $previous = $this->getNbActiveClients($previousStart, $previousEnd); $current = $this->getNbActiveClients($start, $end); break; case StatsShopType::nbValidateCmd: $previous = $this->getNbValidateCmd($previousStart, $previousEnd); $current = $this->getNbValidateCmd($start, $end); break; case StatsShopType::nbWaitingCmd: $previous = $this->getNbWaitingCmd($previousStart, $previousEnd); $current = $this->getNbWaitingCmd($start, $end); break; case StatsShopType::nbCanceledCmd: $previous = $this->getNbCanceledCmd($previousStart, $previousEnd); $current = $this->getNbCanceledCmd($start, $end); break; case StatsCustomerType::nbSalarie: $previous = $this->getActiveEmployeesCount($previousStart, $previousEnd); $current = $this->getActiveEmployeesCount($start, $end); break; case StatsCustomerType::nbSalarieWithAccount: $previous = $this->getActiveEmployeesCountWithAnAccount($previousStart, $previousEnd); $current = $this->getActiveEmployeesCountWithAnAccount($start, $end); break; case StatsCustomerType::membershipRate: $previous = $this->getMembershipRate($previousStart, $previousEnd); $current = $this->getMembershipRate($start, $end); break; default: throw new \InvalidArgumentException("Unknown stats type: {$type->label()}"); } $stats[$type->value] = [ 'previous' => $previous, 'current' => $current, 'diff' => $current - $previous, ]; } return $stats; } /** * Get the percentage of active registered people / people with a generated code */ public function getMembershipRate(CarbonInterface $start, CarbonInterface $end): float { $registered = $this->getActiveEmployeesCountWithAnAccount($start, $end); $employee = $this->getActiveEmployeesCount($start, $end); return $employee ? round($registered / $employee * 100, 2) : 0.0; } /** * Get the previous period of the selected date. */ public function getPreviousPeriod(CarbonInterface $start, CarbonInterface $end): CarbonPeriod { $diffDays = $start->copy()->diffInDays($end); return CarbonPeriod::create( $start->copy()->subDays($diffDays + 1), $start->copy()->subDay() ); } /** * Get the percentage of registered people / people with a generated code */ public function getMembershipPercentage(): float { $employee = $this->employeeDirectory->countActiveEmployees(); $registered = $this->employeeDirectory->countActiveRegisteredEmployees(); return $employee ? round($registered / $employee * 100, 2) : 0.0; } /** * Get the number of active employees within the date range. */ private function getActiveEmployeesCount(CarbonInterface $start, CarbonInterface $end): int { return $this->employeeDirectory->countActiveEmployeesWithin($start, $end); } /** * Get the number of active registered employees within the date range. */ private function getActiveEmployeesCountWithAnAccount(CarbonInterface $start, CarbonInterface $end): int { return $this->employeeDirectory->countActiveRegisteredEmployeesWithin($start, $end); } /** * Get all validated orders. * * @return Collection */ private function getValidatedOrders(CarbonInterface $start, CarbonInterface $end): Collection { return $this->orderDirectory->getValidatedOrders($start, $end); } /** * Get the number of validated command. */ private function getNbValidateCmd(CarbonInterface $start, CarbonInterface $end): int { return $this->getValidatedOrders($start, $end)->count(); } /** * Get the number of waiting command. */ private function getNbWaitingCmd(CarbonInterface $start, CarbonInterface $end): int { return $this->getOrdersByStatus(OrderStatus::WAITING, $start, $end)->count(); } /** * Get the number of canceled command. */ private function getNbCanceledCmd(CarbonInterface $start, CarbonInterface $end): int { return $this->getOrdersByStatus(OrderStatus::CANCELED, $start, $end)->count(); } /** * Get orders by status. * * @return Collection */ private function getOrdersByStatus(OrderStatus $statusId, CarbonInterface $start, CarbonInterface $end): Collection { return $this->orderDirectory->getOrdersByStatus($statusId, $start, $end); } /** * Get the canceled command rate. */ private function getCanceledRate(CarbonInterface $start, CarbonInterface $end): float { $nbWaitingCmd = $this->getNbWaitingCmd($start, $end); $nbCanceledCmd = $this->getNbCanceledCmd($start, $end); $nbValidateCmd = $this->getNbValidateCmd($start, $end); // Prevent division by 0. if (($nbValidateCmd + $nbWaitingCmd + $nbCanceledCmd) !== 0) { return round( (($nbWaitingCmd + $nbCanceledCmd) / ($nbValidateCmd + $nbWaitingCmd + $nbCanceledCmd)) * 100, 2 ); } return 0.0; } /** * Get the order frequency. */ private function getOrderFrequency(CarbonInterface $start, CarbonInterface $end): float { $nbValidateCmd = $this->getNbValidateCmd($start, $end); $period = new CarbonPeriod($start, $end)->count(); return round($nbValidateCmd / $period, 2); } /** * Get the order frequency. */ private function getPurchaseFrequency(CarbonInterface $start, CarbonInterface $end): float { $activeClients = $this->getNbActiveClients($start, $end); if (! $activeClients) { return 0.0; } $nbValidateCmd = $this->getNbValidateCmd($start, $end); return round($nbValidateCmd / $activeClients, 2); } /** * Get the number of active clients (ordered in the period). */ private function getNbActiveClients(CarbonInterface $start, CarbonInterface $end): int { return $this->orderDirectory->getNbActiveClients($start, $end); } /** * Get the number command where the collect day is 7 days after the order. */ private function getNbCmdWith7DayDelay(CarbonInterface $start, CarbonInterface $end): int { return $this->orderDirectory->getNbCmdWith7DayDelay($start, $end); } /** * Get the number command where the collect day is 14 days after the order. */ private function getNbCmdWith14DayDelay(CarbonInterface $start, CarbonInterface $end): int { return $this->orderDirectory->getNbCmdWith14DayDelay($start, $end); } /** * Get the CA HT. */ private function getCaHt(CarbonInterface $start, CarbonInterface $end): float { return $this->orderDirectory->getCaHt($start, $end); } /** * Get the CA TTC. */ private function getCaTtc(CarbonInterface $start, CarbonInterface $end): float { return $this->orderDirectory->getCaTtc($start, $end); } /** * Get the average basket HT. */ private function getAverageBasketHt(CarbonInterface $start, CarbonInterface $end): float { // Prevent division by 0. if ($this->getNbValidateCmd($start, $end) !== 0) { return round($this->getCaHt($start, $end) / $this->getNbValidateCmd($start, $end), 2); } return 0.0; } /** * Get the average product count per order. */ private function getAverageProductCountPerOrder(CarbonInterface $start, CarbonInterface $end): float { $nbValidateCmd = $this->getNbValidateCmd($start, $end); // Prevent division by 0. if ($nbValidateCmd !== 0) { $totalQty = $this->orderDirectory->getTotalQuantity($start, $end); return round((float) $totalQty / $nbValidateCmd, 2); } return 0.0; } }