loadQuery(ProducerRepositoryQuery::class); $this->producerPriceRangeRepository = $this->loadService(ProducerPriceRangeRepository::class); $this->producerSolver = $this->loadService(ProducerSolver::class); $this->documentSolver = $this->loadService(DocumentSolver::class); } /** * Retourne les options de base nécessaires à la fonction de recherche. * */ public function getDefaultOptionsSearch(): array { return [ self::WITH => ['taxRate', 'contact'], self::JOIN_WITH => [], self::ORDER_BY => 'name ASC', self::ATTRIBUTE_ID_PRODUCER => 'id' ]; } public function findOneProducerById(int $id) { return $this->createQuery() ->filterById($id) ->findOne(); } public function findOneProducerBySlug(string $slug) { return $this->createQuery() ->filterBySlug($slug) ->findOne(); } public function queryProducersActive(string $orderByField = 'producer.name', string $orderByDirection = 'ASC') { return $this->createQuery() ->filterIsActive() ->orderBy($orderByField.' '.$orderByDirection); } /** * Retourne le compte producteur de démonstration. */ public function findOneProducerDemoAccount() { return $this->createQuery() ->filterIsDemoAccount() ->findOne(); } /** * Retourne la liste des établissements pour l'initialisation d'une listesélective. */ public function populateProducerDropdown(bool $excludeProducerContext = false): array { $producerContext = $this->getProducerContext(false); $producers = $this->createQuery() ->filterIsActive() ->orderBy('postcode, city ASC') ->find(); $departments = Departments::get(); $dataProducers = []; $optionsProducers = []; foreach ($producers as $p) { if($excludeProducerContext && $producerContext && $producerContext->id != $p->id || !$excludeProducerContext) { $departmentCode = substr($p->postcode, 0, 2); if (!key_exists('d' . $departmentCode, $dataProducers) && isset($departments[$departmentCode])) { $dataProducers['d' . $departmentCode] = '' . $departments[$departmentCode] . ''; $optionsProducers['d' . $departmentCode] = ['disabled' => true]; } $dataProducers[$p->id] = ' ' . Html::encode( $p->name ) . ' - ' . Html::encode($p->postcode) . ' ' . Html::encode( $p->city ) . ' '; if (strlen($p->code)) { $optionsProducers[$p->id] = ['class' => 'lock']; } } } return [ 'data' => $dataProducers, 'options' => $optionsProducers ]; } public function getTurnoverLastMonth(Producer $producer, bool $format = false) { $period = date('Y-m', strtotime('-1 month')); return $this->getTurnover($producer, $period, false, $format); } public function getYearsWithTurnover(Producer $producer): array { $year = date('Y'); $yearsArray = []; for($i = 0; $i <= 10; $i++) { if($this->hasTurnoverOverTheYear($producer, $year - $i)) { array_unshift($yearsArray, $year - $i); } } return $yearsArray; } public function hasTurnoverOverTheYear(Producer $producer, int $year): bool { for($month = 1; $month <= 12; $month++) { if($this->getTurnover($producer, $year.'-'.$month)) { return true; } } return false; } /** * Retourne le CA du producteur pour un mois donné */ public function getTurnover(Producer $producer, string $period = '', bool $withTax = false, bool $format = false) { if (!$period) { $period = date('Y-m'); } $dateStart = date('Y-m-31', strtotime("-1 month", strtotime($period))); $dateEnd = date('Y-m-01', strtotime("+1 month", strtotime($period))); return $this->getTurnoverByDateStartEnd($producer, $dateStart, $dateEnd, $withTax, $format); } public function getTurnoverByWeek(Producer $producer, int $year, int $week, bool $withTax = false, bool $format = false) { $date = new \DateTime(); $date->setISODate($year, $week); $dateStart = $date->format('Y-m-d'); $date->modify('+6 days'); $dateEnd = $date->format('Y-m-d'); return $this->getTurnoverByDateStartEnd($producer, $dateStart, $dateEnd, $withTax, $format); } public function getTurnoverByDateStartEnd(Producer $producer, string $dateStart, string $dateEnd, bool $withTax = false, bool $format = false) { $connection = \Yii::$app->getDb(); $selectSum = 'product_order.price * product_order.quantity'; if($withTax) { $selectSum .= ' * (tax_rate.value + 1)'; } $command = $connection->createCommand( ' SELECT SUM('.$selectSum.') AS turnover FROM `order`, product_order, distribution, tax_rate WHERE `order`.id = product_order.id_order AND '.OrderRepositoryQuery::getSqlFilterIsValid().' AND distribution.id_producer = :id_producer AND `order`.id_distribution = distribution.id AND distribution.date > :date_start AND distribution.date < :date_end AND product_order.id_tax_rate = tax_rate.id', [ ':date_start' => $dateStart, ':date_end' => $dateEnd, ':id_producer' => $producer->id ] ); $result = $command->queryOne(); $turnover = (float) $result['turnover']; if ($format) { return number_format($turnover, 2) . ' €'; } else { return $turnover; } } public function getTurnoverByNumberMonths(Producer $producer, $numberMonths = 1) { $totalTurnover = 0; for ($i = 1; $i <= $numberMonths; $i++) { $timeMonth = strtotime('-' . $i . ' month'); $month = date('Y-m', $timeMonth); $totalTurnover += $this->getTurnover($producer, $month); } return $totalTurnover; } public function getAmountToBeBilledByMonth(Producer $producer, $month, bool $format = false) { $turnover = $this->getTurnover($producer, $month); return $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, $format); } public function getDatasChartTurnoverStatistics(Producer $producer, int $year, string $displayBy = 'month', bool $withTax = false) { $data = []; $dataLabels = []; $start = new \DateTime($year.'-01-01'); if($year == date('Y')) { $end = new \DateTime('last day of this month'); } else { $end = new \DateTime($year.'-12-31'); } $interval = new \DateInterval(($displayBy == 'week') ? 'P1W' : 'P1M'); $period = new \DatePeriod($start, $interval, $end); if($displayBy == 'week') { foreach ($period as $date) { $week = $date->format('W'); $dataLabels[] = $week; $turnover = $this->getTurnoverByWeek($producer, $year, $date->format('W'), $withTax); $data[$week] = $turnover; } } else { foreach ($period as $date) { $month = $date->format('m/Y'); $dataLabels[] = $month; $turnover = $this->getTurnover($producer, $date->format('Y-m'), $withTax); $data[$month] = $turnover; } } // création d'un tableau sans index car chart.js n'accepte pas les index $dataNoIndex = []; foreach ($data as $key => $val) { $dataNoIndex[] = round($val, 2); } return [ 'labels' => $dataLabels, 'data' => $dataNoIndex ]; } public function getSummaryAmountsToBeBilled(Producer $producer, string $label, int $numberOfMonths = 1, $context = 'list'): string { $text = ''; $numMonthCurrent = date('m'); $sumInvoicePrice = 0; if ($numberOfMonths == 1 || ($numberOfMonths == 3 && (in_array($numMonthCurrent, [1, 4, 7, 10]))) || ($numberOfMonths == 6 && (in_array($numMonthCurrent, [1, 7]))) || $context == 'billing') { for ($i = 1; $i <= $numberOfMonths; $i++) { $timeMonth = strtotime('-' . $i . ' month'); $month = date('Y-m', $timeMonth); $turnover = $this->getTurnover($producer, $month); if ($turnover) { if ($numberOfMonths > 1) { $text .= ucfirst(strftime('%B ', $timeMonth)) . ' ' . date('Y', $timeMonth) . ' : '; } $isBold = $this->producerSolver->isBillingTypeClassic($producer) && !$producer->option_billing_permanent_transfer; if ($isBold) $text .= ''; $text .= $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, true); if ($isBold) $text .= ''; $text .= ' (' . Price::format($turnover, 0) . ' CA)'; $text .= '
'; $sumInvoicePrice += $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, false); } } if (strlen($text)) { $text = '' . $label . '' . ' :
' . $text; } } if ($numberOfMonths > 1 && $sumInvoicePrice > 0) { $text .= '
Total : ' . Price::format($sumInvoicePrice, 0) . ''; } return $text; } public function getAmountToBillCurrentMonth() { $amountToBill = 0; $producersArray = $this->findProducersActive(); foreach ($producersArray as $producer) { $amountToBill += $this->getAmountToBillCurrentMonthByProducer($producer); } return $amountToBill; } public function getAmountBilledLastMonth() { $amountBilled = 0; $producersArray = $this->findProducersActive(); foreach ($producersArray as $producer) { $amountBilled += $this->getAmountBilledLastMonthByProducer($producer); } return $amountBilled; } public function getAmountToBillCurrentMonthByProducer(Producer $producer): float { return $this->getAmountToBeBilledByMonth($producer, date('Y-m')); } public function getAmountBilledLastMonthByProducer(Producer $producer): float { return $this->getAmountToBeBilledByMonth($producer, date('Y-m', strtotime('-1 month'))); } public function getOnlinePaymentMinimumAmount(): float { $onlinePaymentMinimumAmount = $this->producerSolver->getConfig('option_online_payment_minimum_amount'); if (!$onlinePaymentMinimumAmount) { $onlinePaymentMinimumAmount = Producer::ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT; } return $onlinePaymentMinimumAmount; } public function getNameProducer(User $user): string { $producer = $this->findOneProducerById($user->id_producer); return $producer->name; } public function isDocumentDisplayOrders(DocumentInterface $document) { return ($this->documentSolver->getClass($document) == 'Invoice') ? $this->producerSolver->getConfig('document_display_orders_invoice') : $this->producerSolver->getConfig('document_display_orders_delivery_note'); } /** * Retourne le mode de fonctionnement de la cagnotte d'un point de vente. */ public function getPointSaleCreditFunctioning(PointSale $pointSale): string { return strlen($pointSale->credit_functioning) > 0 ? $pointSale->credit_functioning : $this->producerSolver->getConfig('credit_functioning'); } public function findProducersActive(string $orderByField = 'producer.name', string $orderByDirection = 'ASC') { return $this->queryProducersActive($orderByField, $orderByDirection)->find(); } public function countProducersActiveWithTurnover(): int { $count = 0; $producersArray = $this->findProducersActive(); foreach ($producersArray as $producer) { if ($this->getTurnoverByNumberMonths($producer, 3)) { $count++; } } return $count; } public function countCacheProducersActiveWithTurnover(): int { return \Yii::$app->cache->getOrSet('count_producers_active', function () { return $this->countProducersActiveWithTurnover(); }, 60 * 60 * 24); } public function findProducers() { return $this->createQuery()->find(); } public function findProducersWithTestimonials(): array { return $this->queryProducersActive() ->filterHasOptionTestimony() ->find(); } public function findProducersWithTimeSaved(): array { return $this->queryProducersActive() ->filterHasOptionTimeSaved() ->find(); } public function countProducersWithTimeSaved(): int { return count($this->findProducersWithTimeSaved()); } public function getTimeSavedByProducersAverage(): int { $producersWithTimeSavedArray = $this->findProducersWithTimeSaved(); $countProducersWithOptionTimeSaved = count($producersWithTimeSavedArray); if ($countProducersWithOptionTimeSaved) { $sumTimeSaved = 0; foreach ($producersWithTimeSavedArray as $producerWithTimeSaved) { $sumTimeSaved += $producerWithTimeSaved->option_time_saved; } return round($sumTimeSaved / $countProducersWithOptionTimeSaved); } return 0; } public function findOneProducerBySponsorshipCode(string $sponsorshipCode): ?Producer { return $this->createQuery() ->filterBySponsorshipCode($sponsorshipCode) ->findOne(); } public function findProducersSponsorshipGodsons(Producer $producer): array { return $this->createQuery() ->filterBySponsoredBy($producer) ->find(); } }