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();
}
}