|
- <?php
-
- namespace domain\Producer\Producer;
-
- use common\helpers\Departments;
- use common\helpers\Price;
- use domain\Document\Document\DocumentInterface;
- use domain\Document\Document\DocumentSolver;
- use domain\Order\Order\OrderRepositoryQuery;
- use domain\Order\OrderStatus\OrderStatus;
- use domain\PointSale\PointSale\PointSale;
- use domain\Producer\ProducerPriceRange\ProducerPriceRangeRepository;
- use domain\User\User\User;
- use domain\_\AbstractRepository;
- use yii\helpers\Html;
-
- class ProducerRepository extends AbstractRepository
- {
- protected ProducerRepositoryQuery $query;
- protected ProducerPriceRangeRepository $producerPriceRangeRepository;
- protected ProducerSolver $producerSolver;
- protected DocumentSolver $documentSolver;
-
- public function loadDependencies(): void
- {
- $this->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] = '<strong>' . $departments[$departmentCode] . '</strong>';
- $optionsProducers['d' . $departmentCode] = ['disabled' => true];
- }
-
- $dataProducers[$p->id] = '<span class="glyphicon glyphicon-lock"></span> ' . Html::encode(
- $p->name
- ) . ' - ' . Html::encode($p->postcode) . ' ' . Html::encode(
- $p->city
- ) . ' <span class="glyphicon glyphicon-lock"></span>';
-
- 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 .= '<strong>';
- $text .= $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, true);
- if ($isBold) $text .= '</strong>';
- $text .= ' (' . Price::format($turnover, 0) . ' CA)';
- $text .= '<br />';
-
- $sumInvoicePrice += $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, false);
- }
- }
-
- if (strlen($text)) {
- $text = '<i>' . $label . '</i>' . ' : <br />' . $text;
- }
- }
-
- if ($numberOfMonths > 1 && $sumInvoicePrice > 0) {
- $text .= '<br />Total : <strong>' . Price::format($sumInvoicePrice, 0) . '</strong>';
- }
-
- 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();
- }
- }
|