Преглед на файлове

Refactoring services #885

refactoring
Guillaume преди 1 година
родител
ревизия
3ea70acbbb
променени са 24 файла, в които са добавени 1191 реда и са изтрити 1129 реда
  1. +2
    -2
      common/components/BusinessLogic.php
  2. +1
    -1
      common/controllers/CommonController.php
  3. +9
    -3
      common/logic/BaseService.php
  4. +51
    -23
      common/logic/Producer/Producer/ProducerBuilder.php
  5. +6
    -0
      common/logic/Producer/Producer/ProducerContainer.php
  6. +2
    -2
      common/logic/Producer/Producer/ProducerFactory.php
  7. +10
    -499
      common/logic/Producer/Producer/ProducerModel.php
  8. +169
    -0
      common/logic/Producer/Producer/ProducerRepository.php
  9. +238
    -0
      common/logic/Producer/Producer/ProducerSolver.php
  10. +0
    -15
      common/logic/Producer/ProducerPriceRange/ProducerPriceRangeModel.php
  11. +32
    -0
      common/logic/Producer/ProducerPriceRange/ProducerPriceRangeRepository.php
  12. +8
    -0
      common/logic/ResolverInterface.php
  13. +6
    -4
      common/logic/User/CreditHistory/CreditHistoryModel.php
  14. +2
    -3
      common/logic/User/CreditHistory/CreditHistorySolver.php
  15. +46
    -2
      common/logic/User/User/UserBuilder.php
  16. +1
    -508
      common/logic/User/User/UserModel.php
  17. +231
    -0
      common/logic/User/User/UserRepository.php
  18. +187
    -0
      common/logic/User/User/UserSolver.php
  19. +21
    -0
      common/logic/User/User/UserUtils.php
  20. +0
    -2
      common/logic/User/UserProducer/UserProducerContainer.php
  21. +21
    -0
      common/logic/User/UserProducer/UserProducerFactory.php
  22. +143
    -61
      common/logic/User/UserProducer/UserProducerModel.php
  23. +5
    -3
      common/logic/User/UserProducer/UserProducerRepository.php
  24. +0
    -1
      producer/views/credit/history.php

+ 2
- 2
common/components/BusinessLogic.php Целия файл

@@ -14,11 +14,11 @@ class BusinessLogic
public function getContainers()
{
return [
$this->getUserContainer(),
$this->getProducerContainer(),
$this->getCreditHistoryContainer(),
$this->getProducerPriceRangeContainer(),
$this->getUserProducerContainer(),
$this->getUserContainer(),
$this->getProducerContainer(),
];
}


+ 1
- 1
common/controllers/CommonController.php Целия файл

@@ -46,7 +46,7 @@ class CommonController extends \yii\web\Controller
public function beforeAction($event)
{
if (!Yii::$app->user->isGuest) {
Yii::$app->user->identity->updateLastConnection();
$this->getLogic()->getUserContainer()->getBuilder()->updateLastConnection(Yii::$app->user->identity);
}

return parent::beforeAction($event);

+ 9
- 3
common/logic/BaseService.php Целия файл

@@ -13,6 +13,7 @@ class BaseService
SolverInterface::class,
RepositoryInterface::class,
BuilderInterface::class,
ResolverInterface::class,
UtilsInterface::class,
];
}
@@ -28,7 +29,7 @@ class BaseService

public function respectHierarchy(string $serviceClassAsked): bool
{
$businessLogic = \Yii::$app->logic;
$domain = \Yii::$app->logic;
$serviceCurrentClass = get_class($this);
$levelHierarchyServiceAsked = $this->getServiceLevelHierarchy($serviceClassAsked);
$levelHierarchyServiceCurrent = $this->getServiceLevelHierarchy($serviceCurrentClass);
@@ -37,8 +38,8 @@ class BaseService
return true;
}
elseif($levelHierarchyServiceAsked == $levelHierarchyServiceCurrent
&& $businessLogic->getContainerLevelHierarchyByService($serviceClassAsked)
< $businessLogic->getContainerLevelHierarchyByService($serviceCurrentClass)) {
&& $domain->getContainerLevelHierarchyByService($serviceClassAsked)
< $domain->getContainerLevelHierarchyByService($serviceCurrentClass)) {

return true;
}
@@ -75,6 +76,11 @@ class BaseService
return $this->classImplementsInterface(BuilderInterface::class);
}

public function isResolver(): bool
{
return $this->classImplementsInterface(ResolverInterface::class);
}

public function isUtils(): bool
{
return $this->classImplementsInterface(UtilsInterface::class);

+ 51
- 23
common/logic/Producer/Producer/ProducerBuilder.php Целия файл

@@ -2,18 +2,28 @@

namespace common\logic\Producer\Producer;

use common\helpers\Opendistrib;
use common\logic\User\UserProducer\UserProducerFactory;
use common\helpers\Password;
use common\logic\BaseService;
use common\logic\BuilderInterface;
use common\logic\User\UserProducer\UserProducerModel;
use common\logic\User\UserProducer\UserProducerRepository;
use common\helpers\Url;

class ProducerBuilder extends BaseService implements BuilderInterface
{
protected ProducerRepository $producerRepository;
protected UserProducerRepository $userProducerRepository;
protected UserProducerFactory $userProducerFactory;
protected ProducerSolver $producerSolver;

public function __construct()
{
$this->producerRepository = $this->loadService(ProducerRepository::class);
$this->userProducerRepository = $this->loadService(UserProducerRepository::class);
$this->userProducerFactory = $this->loadService(UserProducerFactory::class);
$this->producerSolver = $this->loadService(ProducerSolver::class);
}

public function init(ProducerModel $producer): void
@@ -26,7 +36,7 @@ class ProducerBuilder extends BaseService implements BuilderInterface
{
$cptSlug = 0 ;
do {
$slug = \common\helpers\Url::slugify($producer->name) ;
$slug = Url::slugify($producer->name) ;
if($cptSlug) {
$slug .= $cptSlug ;
}
@@ -42,33 +52,51 @@ class ProducerBuilder extends BaseService implements BuilderInterface

/**
* Lie un utilisateur à un producteur.
*
* @param integer $id_user
* @param integer $id_producer
* @return UserProducerModel
*/
public static function addUser(int $idUser, int $idProducer, int $bookmark = 1)
public function addUser(int $idUser, int $idProducer, int $bookmark = 1): UserProducerModel
{
$userProducer = UserProducerModel::searchOne([
'user_producer.id_user' => $idUser,
'user_producer.id_producer' => $idProducer
]);

$userProducer = $this->userProducerRepository->getOne($idUser, $idProducer);
if (!$userProducer) {
$newUserProducer = new UserProducerModel;
$newUserProducer->id_producer = $idProducer;
$newUserProducer->id_user = $idUser;
$newUserProducer->credit = 0;
$newUserProducer->active = 1;
$newUserProducer->bookmark = (int)$bookmark;
$newUserProducer->save();
} else {
if (!$userProducer->active) {
$userProducer->active = 1;
$userProducer->save();
}
$userProducer = $this->userProducerFactory->create($idUser, $idProducer, $bookmark);
}

if (!$userProducer->getActive()) {
$userProducer->setActive(1);
}
$userProducer->save();

return $userProducer;
}

public function updateOpendistribVersion(ProducerModel $producer)
{
$versionsArray = Opendistrib::getVersions();
$producer->latest_version_opendistrib = array_values($versionsArray)[0];
$producer->save();
}

public function savePrivateKeyStripe($filename, $value)
{
if (strlen($value) > 0) {
$handle = fopen($filename, "w");
fwrite($handle, $value);
fclose($handle);
}
}

public function savePrivateKeyApiStripe(ProducerModel $producer): void
{
$this->savePrivateKeyStripe(
$this->producerSolver->getFilenamePrivateKeyApiStripe($producer),
$producer->option_stripe_private_key
);
}

public function savePrivateKeyEndpointStripe(ProducerModel $producer): bool
{
$this->savePrivateKeyStripe(
$this->producerSolver->getFilenamePrivateKeyEndpointStripe($producer),
$producer->option_stripe_endpoint_secret
);
}
}

+ 6
- 0
common/logic/Producer/Producer/ProducerContainer.php Целия файл

@@ -15,6 +15,7 @@ class ProducerContainer implements ContainerInterface
{
return [
ProducerFactory::class,
ProducerSolver::class,
ProducerRepository::class,
ProducerBuilder::class,
ProducerUtils::class
@@ -26,6 +27,11 @@ class ProducerContainer implements ContainerInterface
return new ProducerFactory();
}

public function getSolver(): ProducerSolver
{
return new ProducerSolver();
}

public function getRepository()
{
return new ProducerRepository();

+ 2
- 2
common/logic/Producer/Producer/ProducerFactory.php Целия файл

@@ -11,8 +11,8 @@ class ProducerFactory extends BaseService implements FactoryInterface
{
$producer = new ProducerModel();

$producer->order_deadline = 20;
$producer->order_delay = 1;
$producer->order_deadline = ProducerModel::ORDER_DEADLINE_DEFAULT;
$producer->order_delay = ProducerModel::ORDER_DELAY_DEFAULT;

return $producer;
}

+ 10
- 499
common/logic/Producer/Producer/ProducerModel.php Целия файл

@@ -41,31 +41,10 @@ namespace common\logic\Producer\Producer;
use common\logic\User\User\UserModel;
use common\models\TaxRate;
use common\logic\User\UserProducer\UserProducerModel;
use Yii;
use common\components\ActiveRecordCommon;
use common\helpers\Departments;
use yii\helpers\Html;

/**
* This is the model class for table "etablissement".
*
* @property integer $id
* @property string $name
* @property string $siret
* @property string $logo
* @property string $photo
* @property string $description
* @property string $postcode
* @property string $city
* @property float credit_limit_reminder
* @property boolean online_payment
* @property string mentions
* @property string gcs
* @property boolean option_allow_user_gift
* @property string credit_functioning
* @property boolean use_credit_checked_default
* @property float credit_limit
* @property string background_color_logo
* This is the model class for table "producer".
*
*/
class ProducerModel extends ActiveRecordCommon
@@ -123,6 +102,9 @@ class ProducerModel extends ActiveRecordCommon

const ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT = 25;

const ORDER_DEADLINE_DEFAULT = 20;
const ORDER_DELAY_DEFAULT = 1;

/**
* @inheritdoc
*/
@@ -430,501 +412,30 @@ class ProducerModel extends ActiveRecordCommon

public function getUser()
{
return $this->hasMany(UserModel::className(), ['id_producer' => 'id']);
return $this->hasMany(UserModel::class, ['id_producer' => 'id']);
}

public function getContact()
{
return $this->hasMany(UserModel::className(), ['id_producer' => 'id'])
return $this->hasMany(UserModel::class, ['id_producer' => 'id'])
->where(['status' => UserModel::STATUS_PRODUCER]);
}

public function getTaxRate()
{
return $this->hasOne(TaxRate::className(), ['id' => 'id_tax_rate_default']);
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => ['taxRate'],
'join_with' => [],
'orderby' => 'name ASC',
'attribute_id_producer' => 'id'
];
}

public function addUser($idUser, $idProducer)
{
$producerContainer = Yii::$app->logic->getProducerContainer();
$producerContainer->getService()->addUser($idUser, $idProducer);
}

/**
* Retourne le CA de l'établissement pour un mois donné.
*
* @param string $period
* @param boolean $format
* @return string
*/
public function getTurnover($period = '', $format = false)
{
if (!$period) {
$period = date('Y-m');
}

$connection = Yii::$app->getDb();
$command = $connection->createCommand(
'
SELECT SUM(product_order.price * product_order.quantity) AS turnover
FROM `order`, product_order, distribution, product
WHERE `order`.id = product_order.id_order
AND distribution.id_producer = :id_producer
AND `order`.id_distribution = distribution.id
AND product_order.id_product = product.id
AND distribution.date > :date_begin
AND distribution.date < :date_end',
[
':date_begin' => date('Y-m-31', strtotime("-1 month", strtotime($period))),
':date_end' => date('Y-m-01', strtotime("+1 month", strtotime($period))),
':id_producer' => $this->id
]
);

$result = $command->queryOne();
$turnover = $result['turnover'];

if ($format) {
return number_format($turnover, 2) . ' €';
} else {
return $turnover;
}
}

public function getAmountToBeBilledByTurnover($turnover, $format = false)
{
$amountToBeBilled = 0;
$producerPriceRangeArray = ProducerPriceRange::find()->all();
foreach ($producerPriceRangeArray as $priceRange) {
if ($turnover >= $priceRange->range_begin && $turnover < $priceRange->range_end) {
$amountToBeBilled = $priceRange->price;
}
}

if ($format) {
return Price::format($amountToBeBilled, 0);
} else {
return $amountToBeBilled;
}
}

public function getAmountToBeBilledByMonth($month, $format = false)
{
$turnover = $this->getTurnover($month);
return $this->getAmountToBeBilledByTurnover($turnover, $format);
}

public function getSummaryAmountsToBeBilled($label, $numberOfMonths = 1)
{
$text = '';
$numMonthCurrent = date('m');

if ($numberOfMonths == 1
|| ($numberOfMonths == 3 && (in_array($numMonthCurrent, [1, 4, 7, 10])))
|| ($numberOfMonths == 6 && (in_array($numMonthCurrent, [1, 7])))) {

for ($i = 1; $i <= $numberOfMonths; $i++) {
$month = date('Y-m', strtotime('-' . $i . ' month'));
$turnover = $this->getTurnover($month);

if ($turnover) {
$isBold = $this->isBillingTypeClassic() && !$this->option_billing_permanent_transfer;
if ($isBold) $text .= '<strong>';
$text .= $this->getAmountToBeBilledByTurnover($turnover, true);
if ($isBold) $text .= '</strong>';
$text .= ' / ' . Price::format($turnover, 0);
$text .= '<br />';
}
}

if (strlen($text)) {
$text = $label . ' : <br />' . $text;
}

}

return $text;
}

public function getAmountBilledLastMonth()
{
if ($this->isBillingTypeClassic()) {
$month = date('Y-m', strtotime('-1 month'));
return $this->getAmountToBeBilledByMonth($month);
} elseif ($this->isBillingTypeFreePrice()) {
return $this->free_price;
}

return 0;
}

/**
* Retourne le montant à facturer pour une période donnée.
*
* @param string $periode
* @param float $ca
* @param boolean $format
* @return string
*/
public function getMAmountBilled($format = false)
{
if ($format) {
return number_format($this->free_price, 2) . ' €';
} else {
return $this->free_price;
}
}

/**
* Retourne la facture d'une période donnée.
*
* @param string $periode
* @return Facture
*/
public function getInvoice($period = '')
{
if (!$period) {
$period = date('Y-m', strtotime('-1 month'));
}

$invoice = Invoice::searchOne(
['id_producer' => $this->id, 'period' => ':period'],
['params' => [':period' => $period]]
);

return $invoice;
}

/**
* Retourne la facture du mois dernier.
*
* @return Facture
*/
public function getInvoiceLastMonth()
{
return $this->getInvoice(date('Y-m', strtotime('-1 month')));
}

/**
* Retourne une configuration d'un établissement donné.
*
* @param string $config
* @param integer $id_etablissement
* @return mixed
*/
public static function getConfig($config = '', $idProducer = 0)
{
if (strlen($config)) {
if (!$idProducer) {
$idProducer = GlobalParam::getCurrentProducerId();
}

$producer = self::findOne($idProducer);
if ($producer) {
return $producer->$config;
}
}

return false;
}

/**
* Retourne le montant de l'abonnement à prix libre définit par
* le producteur.
*
* @param boolean $format
* @return mixed
*/
public function getFreePrice($format = true)
{
if (!is_null($this->free_price)) {
if ($format) {
return number_format($this->free_price, 2, ',', false) . ' €';
} else {
return $this->free_price;
}
}
}

public function getSpecificDelays()
{
$array = [];
$daysArray = [
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
'sunday'
];


foreach ($daysArray as $day) {
$fieldDelay = 'order_delay_' . $day;
$fieldDeadline = 'order_deadline_' . $day;

$delay = $this->order_delay;
$deadline = $this->order_deadline;
if ($this->$fieldDelay) {
$delay = $this->$fieldDelay;
}
if ($this->$fieldDeadline) {
$deadline = $this->$fieldDeadline;
}

$array[$day] = [
'order_delay' => $delay,
'order_deadline' => $deadline,
];
}

return $array;
}

public function hasSpecificDelays()
{
$daysArray = [
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
'sunday'
];

foreach ($daysArray as $day) {
$fieldDelay = 'order_delay_' . $day;
$fieldDeadline = 'order_deadline_' . $day;

if ($this->$fieldDelay || $this->$fieldDeadline) {
return true;
}
}

return false;
}

/**
* Retourne le chemin vers le fichier contenant la clé secrète d'API de Stripe
*
* @return string
*/
public function getFilenamePrivateKeyApiStripe()
{
return '../../common/config/stripe/api-' . $this->id . '.key';
}

public function getFilenamePrivateKeyEndpointStripe()
{
return '../../common/config/stripe/endpoint-' . $this->id . '.key';
}


public function savePrivateKeyStripe($filename, $value)
{
if (strlen($value) > 0) {
$handle = fopen($filename, "w");
fwrite($handle, $value);
fclose($handle);
}
}

public function savePrivateKeyApiStripe()
{
$this->savePrivateKeyStripe(
$this->getFilenamePrivateKeyApiStripe(),
$this->option_stripe_private_key
);
}

public function savePrivateKeyEndpointStripe()
{
$this->savePrivateKeyStripe(
$this->getFilenamePrivateKeyEndpointStripe(),
$this->option_stripe_endpoint_secret
);
}

/**
* Retourne la clé secrète d'API de Stripe.
*
* @return string
*/
public function getPrivateKeyStripe($filename)
{
if (file_exists($filename)) {
$handle = fopen($filename, "r");
$filesize = filesize($filename);
if ($handle && $filesize) {
$secretKey = fread($handle, $filesize);
fclose($handle);
return $secretKey;
}
}

return '';
}

public function getPrivateKeyApiStripe()
{
return $this->getPrivateKeyStripe($this->getFilenamePrivateKeyApiStripe());
}

public function getPrivateKeyEndpointStripe()
{
return $this->getPrivateKeyStripe($this->getFilenamePrivateKeyEndpointStripe());
}

/**
* Retourne true si le compte est un compte de démo.
*
* @return boolean
*/
public function isDemo()
{
if (strpos($this->name, 'Démo') !== false) {
return true;
}

return false;
}

public function getFullAddress($nl2br = false)
{
$address = '';
$address .= $this->name . "\n";

if (strlen($this->address)) {
$address .= $this->address . "\n";
}

if (strlen($this->postcode) || strlen($this->city)) {
$address .= $this->postcode . ' ' . $this->city;
}

if ($nl2br) {
$address = nl2br($address);
}

return $address;
}

public function getHtmlLogo()
{
$html = '';

if (strlen($this->logo)) {
$html = '<img src="' . $this->getUrlLogo() . '" class="producer-logo" />';
}

return $html;
}

public function getUrlLogo()
{
return Yii::$app->urlManagerProducer->getHostInfo() . 'ProducerModel.php/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $this->logo;
}

public function getEmailOpendistrib()
{
return $this->slug . '@opendistrib.net';
}

public function getMainContact()
{
if ($this->contact) {
foreach ($this->contact as $contact) {
if ($contact->is_main_contact) {
return $contact;
}
}
}

return false;
}

public function isOnlinePaymentActive()
{
return $this->online_payment || ($this->option_stripe_mode_test && !Yii::$app->user->isGuest && Yii::$app->user->identity->status > 10);
}

public function isOnlinePaymentActiveAndTypeOrder()
{
return $this->isOnlinePaymentActive() && $this->option_online_payment_type == 'order';
}

public static function getBillingFrequencyPopulateDropdown()
{
return self::$billingFrequencyArray;
}

public function isBillingFrequencyMonthly()
{
return $this->option_billing_frequency == self::BILLING_FREQUENCY_MONTHLY;
}

public function isBillingFrequencyQuarterly()
{
return $this->option_billing_frequency == self::BILLING_FREQUENCY_QUARTERLY;
return $this->hasOne(TaxRate::class, ['id' => 'id_tax_rate_default']);
}

public function isBillingFrequencyBiannual()
{
return $this->option_billing_frequency == self::BILLING_FREQUENCY_BIANNUAL;
}
// ---

public static function getBillingTypePopulateDropdown()
{
return self::$billingTypeArray;
}

public function isBillingTypeClassic()
{
return $this->option_billing_type == self::BILLING_TYPE_CLASSIC;
}

public function isBillingTypeFreePrice()
{
return $this->option_billing_type == self::BILLING_TYPE_FREE_PRICE;
}

public function isUpToDateWithOpendistribVersion()
{
return $this->latest_version_opendistrib == GlobalParam::getOpendistribVersion();
}

public function updateOpendistribVersion()
{
$versionsArray = Opendistrib::getVersions();
$this->latest_version_opendistrib = array_values($versionsArray)[0];
$this->save();
}

public static function getOnlinePaymentMinimumAmount()
public static function getBillingFrequencyPopulateDropdown()
{
$onlinePaymentMinimumAmount = self::getConfig('option_online_payment_minimum_amount');
if (!$onlinePaymentMinimumAmount) {
$onlinePaymentMinimumAmount = self::ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT;
}

return $onlinePaymentMinimumAmount;
return self::$billingFrequencyArray;
}
}

+ 169
- 0
common/logic/Producer/Producer/ProducerRepository.php Целия файл

@@ -3,12 +3,40 @@
namespace common\logic\Producer\Producer;

use common\helpers\Departments;
use common\helpers\GlobalParam;
use common\helpers\Price;
use common\logic\BaseService;
use common\logic\Producer\ProducerPriceRange\ProducerPriceRangeModel;
use common\logic\Producer\ProducerPriceRange\ProducerPriceRangeRepository;
use common\logic\RepositoryInterface;
use common\logic\User\User\UserModel;
use yii\helpers\Html;

class ProducerRepository extends BaseService implements RepositoryInterface
{
protected ProducerPriceRangeRepository $producerPriceRangeModel;
protected ProducerSolver $producerSolver;

public function __construct()
{
$this->producerPriceRangeRepository = $this->loadService(ProducerPriceRangeRepository::class);
$this->producerSolver = $this->loadService(ProducerSolver::class);
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
*/
public function defaultOptionsSearch(): array
{
return [
'with' => ['taxRate'],
'join_with' => [],
'orderby' => 'name ASC',
'attribute_id_producer' => 'id'
];
}

public function getOneById($id)
{
return ProducerModel::searchOne(['id' => $id]);
@@ -79,4 +107,145 @@ class ProducerRepository extends BaseService implements RepositoryInterface
'options' => $optionsProducers
];
}

/**
* Retourne le CA du producteur pour un mois donné
*/
public function getTurnover(ProducerModel $producer, string $period = '', bool $format = false)
{
if (!$period) {
$period = date('Y-m');
}

$connection = \Yii::$app->getDb();
$command = $connection->createCommand(
'
SELECT SUM(product_order.price * product_order.quantity) AS turnover
FROM `order`, product_order, distribution, product
WHERE `order`.id = product_order.id_order
AND distribution.id_producer = :id_producer
AND `order`.id_distribution = distribution.id
AND product_order.id_product = product.id
AND distribution.date > :date_begin
AND distribution.date < :date_end',
[
':date_begin' => date('Y-m-31', strtotime("-1 month", strtotime($period))),
':date_end' => date('Y-m-01', strtotime("+1 month", strtotime($period))),
':id_producer' => $producer->id
]
);

$result = $command->queryOne();
$turnover = $result['turnover'];

if ($format) {
return number_format($turnover, 2) . ' €';
} else {
return $turnover;
}
}

public function getAmountToBeBilledByMonth(ProducerModel $producer, $month, $format = false)
{
$turnover = $this->getTurnover($producer, $month);
return $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, $format);
}

public function getSummaryAmountsToBeBilled(ProducerModel $producer, $label, $numberOfMonths = 1)
{
$text = '';
$numMonthCurrent = date('m');

if ($numberOfMonths == 1
|| ($numberOfMonths == 3 && (in_array($numMonthCurrent, [1, 4, 7, 10])))
|| ($numberOfMonths == 6 && (in_array($numMonthCurrent, [1, 7])))) {

for ($i = 1; $i <= $numberOfMonths; $i++) {
$month = date('Y-m', strtotime('-' . $i . ' month'));
$turnover = $this->getTurnover($producer, $month);

if ($turnover) {
$isBold = $this->isBillingTypeClassic() && !$this->option_billing_permanent_transfer;
if ($isBold) $text .= '<strong>';
$text .= $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, true);
if ($isBold) $text .= '</strong>';
$text .= ' / ' . Price::format($turnover, 0);
$text .= '<br />';
}
}

if (strlen($text)) {
$text = $label . ' : <br />' . $text;
}

}

return $text;
}

public function getAmountBilledLastMonth(ProducerModel $producer)
{
if ($this->producerSolver->isBillingTypeClassic($producer)) {
$month = date('Y-m', strtotime('-1 month'));
return $this->getAmountToBeBilledByMonth($producer, $month);
} elseif ($this->producerSolver->isBillingTypeFreePrice($producer)) {
return $producer->free_price;
}

return 0;
}

public function getOnlinePaymentMinimumAmount(ProducerModel $producer)
{
$onlinePaymentMinimumAmount = $this->getConfig('option_online_payment_minimum_amount');
if (!$onlinePaymentMinimumAmount) {
$onlinePaymentMinimumAmount = ProducerModel::ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT;
}

return $onlinePaymentMinimumAmount;
}

/**
* Retourne une configuration d'un producteur donné
*
*/
public function getConfig($config = '', $idProducer = 0)
{
if (strlen($config)) {
if (!$idProducer) {
$idProducer = GlobalParam::getCurrentProducerId();
}

$producer = $this->getOneById($idProducer);
if ($producer) {
return $producer->$config;
}
}

return false;
}

/**
* Retourne les établissements liés à l'utilisateur.
*
* @return array
*/
public function getBookmarked(UserModel $user)
{
$producers = (new \yii\db\Query())
->select('*')
->from(['user_producer', 'producer'])
->where('user_producer.id_producer = producer.id')
->andWhere(['user_producer.id_user' => $user->id])
->andWhere(['user_producer.active' => 1])
->all();

return $producers;
}

public function getNameProducer(UserModel $user): string
{
$producer = $this->getOneById($user->id_producer);
return $producer->getName();
}
}

+ 238
- 0
common/logic/Producer/Producer/ProducerSolver.php Целия файл

@@ -0,0 +1,238 @@
<?php

namespace common\logic\Producer\Producer;

use common\helpers\GlobalParam;
use common\logic\BaseService;
use common\logic\SolverInterface;
use common\logic\User\User\UserModel;

class ProducerSolver extends BaseService implements SolverInterface
{
/**
* Retourne true si le compte est un compte de démo.
*
*/
public function isDemo(ProducerModel $producer): bool
{
if (strpos($producer->name, 'Démo') !== false) {
return true;
}

return false;
}

public function getFullAddress(ProducerModel $producer, $nl2br = false)
{
$address = '';
$address .= $producer->name . "\n";

if (strlen($producer->address)) {
$address .= $producer->address . "\n";
}

if (strlen($producer->postcode) || strlen($producer->city)) {
$address .= $producer->postcode . ' ' . $producer->city;
}

if ($nl2br) {
$address = nl2br($address);
}

return $address;
}

public function getHtmlLogo(ProducerModel $producer)
{
$html = '';

if (strlen($producer->logo)) {
$html = '<img src="' . $this->getUrlLogo($producer) . '" class="producer-logo" />';
}

return $html;
}

public function getUrlLogo(ProducerModel $producer): string
{
return \Yii::$app->urlManagerProducer->getHostInfo() . '/' . \Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $producer->logo;
}

public function getEmailOpendistrib(ProducerModel $producer): string
{
return $producer->slug . '@opendistrib.net';
}

public function getMainContact(ProducerModel $producer): ?UserModel
{
if ($producer->contact) {
foreach ($producer->contact as $contact) {
if ($contact->is_main_contact) {
return $contact;
}
}
}

return null;
}

public function isUpToDateWithOpendistribVersion(ProducerModel $producer): bool
{
return $producer->latest_version_opendistrib == GlobalParam::getOpendistribVersion();
}

public function isBillingTypeClassic(ProducerModel $producer): bool
{
return $producer->option_billing_type == ProducerModel::BILLING_TYPE_CLASSIC;
}

public function isBillingTypeFreePrice(ProducerModel $producer)
{
return $producer->option_billing_type == ProducerModel::BILLING_TYPE_FREE_PRICE;
}

/**
* Retourne le montant de l'abonnement à prix libre définit par
* le producteur.
*
*/
public function getFreePrice(ProducerModel $producer, $format = true)
{
if (!is_null($producer->free_price)) {
if ($format) {
return number_format($producer->free_price, 2, ',', false) . ' €';
} else {
return $producer->free_price;
}
}
}

public function getSpecificDelays(ProducerModel $producer): array
{
$array = [];
$daysArray = [
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
'sunday'
];

foreach ($daysArray as $day) {
$fieldDelay = 'order_delay_' . $day;
$fieldDeadline = 'order_deadline_' . $day;

$delay = $producer->order_delay;
$deadline = $producer->order_deadline;
if ($producer->$fieldDelay) {
$delay = $producer->$fieldDelay;
}
if ($producer->$fieldDeadline) {
$deadline = $producer->$fieldDeadline;
}

$array[$day] = [
'order_delay' => $delay,
'order_deadline' => $deadline,
];
}

return $array;
}

public function hasSpecificDelays(ProducerModel $producer): bool
{
$daysArray = [
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
'sunday'
];

foreach ($daysArray as $day) {
$fieldDelay = 'order_delay_' . $day;
$fieldDeadline = 'order_deadline_' . $day;

if ($producer->$fieldDelay || $producer->$fieldDeadline) {
return true;
}
}

return false;
}

public function getFilenamePrivateKeyApiStripe(ProducerModel $producer)
{
return '../../common/config/stripe/api-' . $producer->id . '.key';
}

public function getFilenamePrivateKeyEndpointStripe(ProducerModel $producer)
{
return '../../common/config/stripe/endpoint-' . $producer->id . '.key';
}

/**
* Retourne la clé secrète d'API de Stripe.
*
* @return string
*/
public function getPrivateKeyStripe($filename)
{
if (file_exists($filename)) {
$handle = fopen($filename, "r");
$filesize = filesize($filename);
if ($handle && $filesize) {
$secretKey = fread($handle, $filesize);
fclose($handle);
return $secretKey;
}
}

return '';
}

public function getPrivateKeyApiStripe(ProducerModel $producer)
{
return $this->getPrivateKeyStripe($this->getFilenamePrivateKeyApiStripe($producer));
}

public function getPrivateKeyEndpointStripe(ProducerModel $producer)
{
return $this->getPrivateKeyStripe($this->getFilenamePrivateKeyEndpointStripe($producer));
}

public function isOnlinePaymentActive(ProducerModel $producer)
{
return $producer->online_payment
|| ($producer->option_stripe_mode_test
&& !\Yii::$app->user->isGuest
&& \Yii::$app->user->identity->status > 10);
}

public function isOnlinePaymentActiveAndTypeOrder(ProducerModel $producer): bool
{
return $this->isOnlinePaymentActive($producer)
&& $producer->option_online_payment_type == 'order';
}

public function isBillingFrequencyMonthly(ProducerModel $producer): bool
{
return $producer->option_billing_frequency == ProducerModel::BILLING_FREQUENCY_MONTHLY;
}

public function isBillingFrequencyQuarterly(ProducerModel $producer): bool
{
return $producer->option_billing_frequency == ProducerModel::BILLING_FREQUENCY_QUARTERLY;
}

public function isBillingFrequencyBiannual(ProducerModel $producer): bool
{
return $producer->option_billing_frequency == ProducerModel::BILLING_FREQUENCY_BIANNUAL;
}

}

+ 0
- 15
common/logic/Producer/ProducerPriceRange/ProducerPriceRangeModel.php Целия файл

@@ -77,19 +77,4 @@ class ProducerPriceRangeModel extends ActiveRecordCommon
'price' => 'Tarif (HT)',
];
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => [],
'join_with' => [],
'orderby' => '',
'attribute_id_producer' => ''
];
}
}

+ 32
- 0
common/logic/Producer/ProducerPriceRange/ProducerPriceRangeRepository.php Целия файл

@@ -2,13 +2,45 @@

namespace common\logic\Producer\ProducerPriceRange;

use common\helpers\Price;
use common\logic\BaseService;
use common\logic\RepositoryInterface;

class ProducerPriceRangeRepository extends BaseService implements RepositoryInterface
{
/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
*/
public static function defaultOptionsSearch(): array
{
return [
'with' => [],
'join_with' => [],
'orderby' => '',
'attribute_id_producer' => ''
];
}

public function query()
{
return ProducerPriceRangeModel::find()->orderBy('range_begin ASC');
}

public function getAmountToBeBilledByTurnover(float $turnover, $format = false)
{
$amountToBeBilled = 0;
$producerPriceRangeArray = ProducerPriceRangeModel::find()->all();
foreach ($producerPriceRangeArray as $priceRange) {
if ($turnover >= $priceRange->range_begin && $turnover < $priceRange->range_end) {
$amountToBeBilled = $priceRange->price;
}
}

if ($format) {
return Price::format($amountToBeBilled, 0);
} else {
return $amountToBeBilled;
}
}
}

+ 8
- 0
common/logic/ResolverInterface.php Целия файл

@@ -0,0 +1,8 @@
<?php

namespace common\logic;

interface ResolverInterface
{

}

+ 6
- 4
common/logic/User/CreditHistory/CreditHistoryModel.php Целия файл

@@ -39,6 +39,8 @@
namespace common\logic\User\CreditHistory;

use common\components\ActiveRecordCommon;
use common\logic\User\User\UserModel;
use common\models\Order;
use yii\db\ActiveQuery;


@@ -98,20 +100,20 @@ class CreditHistoryModel extends ActiveRecordCommon

public function getUser(): ActiveQuery
{
return $this->hasOne(User::class, ['id' => 'id_user']);
return $this->hasOne(UserModel::class, ['id' => 'id_user']);
}

public function getUserObject(): ?User
public function getUserObject(): ?UserModel
{
return $this->user;
}

public function getUserAction(): ActiveQuery
{
return $this->hasOne(User::class, ['id' => 'id_user_action']);
return $this->hasOne(UserModel::class, ['id' => 'id_user_action']);
}

public function getUserActionObject(): ?User
public function getUserActionObject(): ?UserModel
{
return $this->userAction;
}

+ 2
- 3
common/logic/User/CreditHistory/CreditHistorySolver.php Целия файл

@@ -9,10 +9,9 @@ use yii\helpers\Html;

class CreditHistorySolver implements SolverInterface
{

public function isTypeDebit(CreditHistoryModel $creditHistory): bool
{
return in_array($creditHistory->type, [
return in_array($creditHistory->getType(), [
CreditHistoryModel::TYPE_DEBIT,
CreditHistoryModel::TYPE_PAYMENT,
]);
@@ -20,7 +19,7 @@ class CreditHistorySolver implements SolverInterface

public function isTypeCredit(CreditHistoryModel $creditHistory): bool
{
return in_array($creditHistory->type, [
return in_array($creditHistory->getType(), [
CreditHistoryModel::TYPE_CREDIT,
CreditHistoryModel::TYPE_INITIAL_CREDIT,
CreditHistoryModel::TYPE_REFUND

+ 46
- 2
common/logic/User/User/UserBuilder.php Целия файл

@@ -4,18 +4,62 @@ namespace common\logic\User\User;

use common\logic\BaseService;
use common\logic\BuilderInterface;
use common\logic\Producer\Producer\ProducerModel;

class UserBuilder extends BaseService implements BuilderInterface
{
public function initPassword($user, $password)
public function initPassword(UserModel $user, string $password)
{
$user->setPassword($password);
$user->generateAuthKey();
}

public function initProducer($user, $producer)
public function initProducer(UserModel $user, ProducerModel $producer)
{
$user->id_producer = $producer->id;
$user->status = UserModel::STATUS_PRODUCER;
}

/**
* Met à jour la date de dernière connexion de l'utilisateur.
*/
public function updateLastConnection(UserModel $user)
{
$user->date_last_connection = date('Y-m-d H:i:s');
$user->save();
}

/**
* Generates password hash from password and sets it to the model
*
*/
public function setPassword(UserModel $user, string $password): void
{
$user->password_hash = \Yii::$app->security->generatePasswordHash($password);
}

/**
* Generates "remember me" authentication key
*/
public function generateAuthKey(UserModel $user): void
{
$user->auth_key = \Yii::$app->security->generateRandomString();
}

/**
* Generates new password reset token
*/
public function generatePasswordResetToken(UserModel $user): void
{
$user->password_reset_token = \Yii::$app->security->generateRandomString() . '_' . time();
}

/**
* Removes password reset token
*/
public function removePasswordResetToken(UserModel $user)
{
$user->password_reset_token = null;
}

}

+ 1
- 508
common/logic/User/User/UserModel.php Целия файл

@@ -158,21 +158,6 @@ class UserModel extends ActiveRecordCommon implements IdentityInterface
];
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => [],
'join_with' => ['userProducer', 'userUserGroup'],
'orderby' => 'user.name ASC, user.lastname ASC',
'attribute_id_producer' => ''
];
}

/**
* Vérifie le mot de passe envoyé par l'utilisateur.
*
@@ -304,147 +289,6 @@ class UserModel extends ActiveRecordCommon implements IdentityInterface
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}

/**
* Finds user by username
*
* @param string $username
* @return static|null
*/
public static function findByUsername($username)
{
return static::findOne(['username' => $username]);
}

/**
* Recherche un utilisateur via son adresse email.
*
* @param string $email
* @return UserModel
*/
public static function findByEmail($email)
{
return static::findOne(['email' => $email]);
}

/**
* Finds user by password reset token
*
* @param string $token password reset token
* @return static|null
*/
public static function findByPasswordResetToken($token)
{
if (!static::isPasswordResetTokenValid($token)) {
return null;
}

return static::findOne([
'password_reset_token' => $token,
]);
}

/**
* Recherche des utilisateurs suivant les paramètres : id_etablissement,
* inactifs, id_point_vente, nom, prenom, email, telephone.
*
* @param array $params
* @return Query
*/
public static function findBy($params = [])
{
if (!isset($params['id_producer'])) {
$params['id_producer'] = GlobalParam::getCurrentProducerId();
}

$query = (new Query())
->select(['user.id AS user_id', 'user.name', 'user.lastname', 'user.phone', 'user.email', 'user.created_at', 'user.date_last_connection', 'user_producer.*', 'user.address', 'user.name_legal_person'])
->from('user');

$active = (isset($params['inactive']) && $params['inactive']) ? 0 : 1;
$query->innerJoin('user_producer', 'user.id = user_producer.id_user AND user_producer.active = ' . $active . ' AND user_producer.id_producer = :id_producer', [':id_producer' => $params['id_producer']]);

if (isset($params['id_point_sale']) && $params['id_point_sale']) {
$point_sale = PointSale::findOne(['id' => $params['id_point_sale']]);

$conditionLinkUserPointSale = 'user.id = user_point_sale.id_user AND user_point_sale.id_point_sale = :id_point_sale';

$usersPointSaleLink = false;
$usersPointSaleHasOrder = false;

if (isset($params['users_point_sale_link']) && $params['users_point_sale_link']) {
$usersPointSaleLink = true;
} elseif (isset($params['users_point_sale_has_order']) && $params['users_point_sale_has_order']) {
$usersPointSaleHasOrder = true;
} elseif ($point_sale->restricted_access) {
$usersPointSaleLink = true;
} else {
$usersPointSaleHasOrder = true;
}

if ($usersPointSaleLink) {
$query->innerJoin('user_point_sale', 'user.id = user_point_sale.id_user AND user_point_sale.id_point_sale = :id_point_sale', [':id_point_sale' => $params['id_point_sale']]);
} elseif ($usersPointSaleHasOrder) {
$query->innerJoin(
'order',
'user.id = order.id_user AND order.id_point_sale = :id_point_sale',
[':id_point_sale' => $params['id_point_sale']]
)->groupBy('user.id');
}
}

if (isset($params['subscribers']) && $params['subscribers']) {
$query->innerJoin(
'subscription',
'user.id = subscription.id_user AND subscription.id_producer = :id_producer',
[':id_producer' => GlobalParam::getCurrentProducerId()]
)->groupBy('user.id');
}

if (isset($params['inactive']) && $params['inactive']) {
$query->innerJoin(
'order',
'user.id = order.id_user'
)
->groupBy('user.id');
}

if (isset($params['name'])) {
$query->andFilterWhere(['like', 'name', $params['name']]);
}

if (isset($params['lastname'])) {
$query->andFilterWhere(['like', 'lastname', $params['lastname']]);
}

if (isset($params['email'])) {
$query->andFilterWhere(['like', 'email', $params['email']]);
}

if (isset($params['phone'])) {
$query->andFilterWhere(['like', 'phone', $params['phone']]);
}

$query->orderBy('user.type DESC, user.lastname ASC, user.name ASC');

return $query;
}

/**
* Finds out if password reset token is valid
*
* @param string $token password reset token
* @return boolean
*/
public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}
$expire = \Yii::$app->params['user.passwordResetTokenExpire'];
$parts = explode('_', $token);
$timestamp = (int)end($parts);
return $timestamp + $expire >= time();
}

/**
* @inheritdoc
@@ -472,360 +316,9 @@ class UserModel extends ActiveRecordCommon implements IdentityInterface

/**
* Validates password
*
* @param string $password password to validate
* @return boolean if password provided is valid for current user
*/
public function validatePassword($password)
public function validatePassword(string $password): bool
{
return \Yii::$app->security->validatePassword($password, $this->password_hash);
}

/**
* Generates password hash from password and sets it to the model
*
* @param string $password
*/
public function setPassword($password)
{
$this->password_hash = \Yii::$app->security->generatePasswordHash($password);
}

/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->auth_key = \Yii::$app->security->generateRandomString();
}

/**
* Generates new password reset token
*/
public function generatePasswordResetToken()
{
$this->password_reset_token = \Yii::$app->security->generateRandomString() . '_' . time();
}

/**
* Removes password reset token
*/
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}

/**
* Retourne l'utilisateur courant.
*
* @return UserModel
*/
public static function getCurrent()
{
if (!\Yii::$app->user->isGuest) {
return \Yii::$app->user->identity;
}

return false;
}

/**
* Retourne si l'utilisateur courant est connecté ou non.
*
* @return boolean
*/
public static function isCurrentConnected()
{
return !\Yii::$app->user->isGuest;
}

/**
* Retourne si l'utilisateur est un producteur ou non.
*
* @return boolean
*/
public function isProducer()
{
return ($this->status == UserModel::STATUS_ADMIN
|| $this->status == UserModel::STATUS_PRODUCER) && $this->id_producer;
}

/**
* Retourne si l'utilisateur courant est un producteur ou non.
*
* @return boolean
*/
public static function isCurrentProducer()
{
$user = UserModel::getCurrent();
if ($user) {
return $user->isProducer();
}
return false;
}

/**
* Retourne si l'utilisateur est un admin ou non.
*
* @return boolean
*/
public function isAdmin()
{
return $this->status == UserModel::STATUS_ADMIN;
}

/**
* Retourne si l'utilisateur courant est un admin ou non.
*
* @return boolean
*/
public static function isCurrentAdmin()
{
$user = UserModel::getCurrent();
if ($user) {
return $user->isAdmin();
}
return false;
}

/**
* Retourne le nom du producteur.
*
* @return string
*/
public function getNameProducer()
{
$producer = ProducerModel::findOne($this->id_producer);

return $producer->getName();
}

/**
* Retourne les établissements liés à l'utilisateur.
*
* @return array
*/
public function getBookmarkedProducers()
{
$producers = (new \yii\db\Query())
->select('*')
->from(['user_producer', 'producer'])
->where('user_producer.id_producer = producer.id')
->andWhere(['user_producer.id_user' => $this->id])
->andWhere(['user_producer.active' => 1])
->all();

return $producers;
}

/**
* Retourne le crédit de l'utilisateur pour un producteur donné.
*
* @param integer $id_etablissement
* @return float
*/
public function getCredit($idProducer)
{
$userProducer = UserProducerModel::searchOne([
'id_user' => $this->id
]);

if ($userProducer) {
return $userProducer->credit;
}

return 0;
}

/**
* Retourne le point de vente favoris d'un utilisateur : le point de vente auquel le client est lié,
* le point de vente de la dernière commande sinon.
*
* @return PointSale
*/
public function getFavoritePointSale()
{
$arrayUserPointSale = UserPointSale::find()
->innerJoinWith('pointSale', true)
->where([
'user_point_sale.id_user' => $this->id,
'point_sale.id_producer' => GlobalParam::getCurrentProducerId()
])
->all();

if (count($arrayUserPointSale) == 1) {
$pointSale = PointSale::findOne(['id' => $arrayUserPointSale[0]->id_point_sale]);
} else {
$lastOrder = Order::find()->innerJoinWith('pointSale', true)->where([
'order.id_user' => $this->id,
'point_sale.id_producer' => GlobalParam::getCurrentProducerId()
])
->orderBy('order.id DESC')
->one();

if ($lastOrder) {
$pointSale = PointSale::findOne(['id' => $lastOrder->id_point_sale]);
}
}

if (isset($pointSale)) {
return $pointSale;
}

return false;
}

/**
* Met à jour la date de dernière connexion de l'utilisateur.
*/
public function updateLastConnection()
{
$this->date_last_connection = date('Y-m-d H:i:s');
$this->save();
}

/**
* Envoie un email de bienvenue à l'utilisateur lors de son inscription
* via le backend du site.
*
* @param string $password
*/
public function sendMailWelcome($password)
{
if (strlen($this->email)) {
$producer = ProducerModel::findOne(GlobalParam::getCurrentProducerId());
\Yii::$app->mailer->compose();
$mail = \Yii::$app->mailer->compose(
['html' => 'createUserAdmin-html', 'text' => 'createUserAdmin-text'], ['user' => $this, 'producer' => $producer, 'password' => $password]
)
->setTo($this->email)
->setFrom(['contact@opendistrib.net' => 'distrib'])
->setSubject('[distrib] Inscription')
->send();
}
}

public function getFullAddress($nl2br = false)
{
$address = '';
if (isset($this->lastname) && isset($this->name) && strlen($this->lastname) && strlen($this->name)) {
$address .= $this->lastname . ' ' . $this->name . "\n";
}
if (isset($this->name_legal_person) && strlen($this->name_legal_person)) {
$address .= $this->name_legal_person . "\n";
}
$address .= $this->address;

if ($nl2br) {
$address = nl2br($address);
}

return $address;
}

public function getUsername($withType = false)
{
$username = '';
if (isset($this->name_legal_person) && strlen($this->name_legal_person)) {
$username = $this->name_legal_person;

if ($withType) {
$username = 'Personne morale / ' . $username;
}
} else {
$username = $this->lastname . ' ' . $this->name;
}

return $username;
}

public static function getUsernameFromArray($modelArray, $withType = false)
{
$username = '';
if (isset($modelArray['name_legal_person']) && strlen($modelArray['name_legal_person'])) {
$username = $modelArray['name_legal_person'];

if ($withType) {
$username = 'Personne morale / ' . $username;
}
} else {
$username = $modelArray['lastname'] . ' ' . $modelArray['name'];
}

return $username;
}

public static function populateDropdownList()
{
$usersArray = UserModel::findBy()->all();
$usersArrayDropdown = ['' => '--'];

foreach ($usersArray as $user) {
$usersArrayDropdown[$user['user_id']] = UserModel::getUsernameFromArray($user, true);
}

return $usersArrayDropdown;;
}


/**
* Retourne l'ID de l'utilisateur courant connecté.
*
* @return mixed
*/
public static function getCurrentId()
{
if (!\Yii::$app->user->isGuest) {
return \Yii::$app->user->identity->id;
}

return false;
}

/**
* Retourne le status de l'utilisateur courant connecté.
*
* @return integer|boolean
*/
public static function getCurrentStatus()
{
if (!\Yii::$app->user->isGuest) {
return \Yii::$app->user->identity->status;
}

return false;
}

public static function hasAccessBackend()
{
return UserModel::getCurrentStatus() == UserModel::STATUS_ADMIN || UserModel::getCurrentStatus() == UserModel::STATUS_PRODUCER;
}

public function belongsToUserGroup($userGroupId)
{
if (!$this->userUserGroup) {
$this->populateRelation('userUserGroup', UserUserGroup::searchAll([
'id_user' => $this->id
]));
}

if ($this->userUserGroup) {
foreach ($this->userUserGroup as $userUserGroup) {
if ($userUserGroup->id_user_group == $userGroupId) {
return true;
}
}
}

return false;
}

public static function getTypeChoicesArray()
{
return [
UserModel::TYPE_INDIVIDUAL => 'Particulier',
UserModel::TYPE_LEGAL_PERSON => 'Personne morale',
UserModel::TYPE_GUEST => 'Visiteur'
];
}
}

+ 231
- 0
common/logic/User/User/UserRepository.php Целия файл

@@ -2,14 +2,245 @@

namespace common\logic\User\User;

use common\helpers\GlobalParam;
use common\logic\BaseService;
use common\logic\Producer\Producer\ProducerModel;
use common\logic\RepositoryInterface;
use common\logic\User\UserProducer\UserProducerModel;
use common\logic\User\UserProducer\UserProducerRepository;
use common\models\Order;
use common\models\PointSale;
use common\models\UserPointSale;
use common\models\UserUserGroup;
use yii\db\Query;

class UserRepository extends BaseService implements RepositoryInterface
{
protected UserProducerRepository $userProducerRepository;
protected UserSolver $userSolver;

public function __construct()
{
$this->userProducerRepository = $this->loadService(UserProducerRepository::class);
$this->userSolver = $this->loadService(UserSolver::class);
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public function defaultOptionsSearch()
{
return [
'with' => [],
'join_with' => ['userProducer', 'userUserGroup'],
'orderby' => 'user.name ASC, user.lastname ASC',
'attribute_id_producer' => ''
];
}

public function getOneById($id)
{
return UserModel::searchOne(['id' => $id]);
}

public function belongsToUserGroup(UserModel $user, int $userGroupId): bool
{
if (!$user->userUserGroup) {
$user->populateRelation('userUserGroup', UserUserGroup::searchAll([
'id_user' => $user->id
]));
}

if ($user->userUserGroup) {
foreach ($user->userUserGroup as $userUserGroup) {
if ($userUserGroup->id_user_group == $userGroupId) {
return true;
}
}
}

return false;
}

public static function populateDropdownList()
{
$usersArray = UserModel::findBy()->all();
$usersArrayDropdown = ['' => '--'];

foreach ($usersArray as $user) {
$usersArrayDropdown[$user['user_id']] = UserModel::getUsernameFromArray($user, true);
}

return $usersArrayDropdown;;
}

/**
* Retourne le point de vente favoris d'un utilisateur : le point de vente auquel le client est lié,
* le point de vente de la dernière commande sinon.
*
*/
public function getFavoritePointSale(UserModel $user): ?PointSale
{
$arrayUserPointSale = UserPointSale::find()
->innerJoinWith('pointSale', true)
->where([
'user_point_sale.id_user' => $user->id,
'point_sale.id_producer' => GlobalParam::getCurrentProducerId()
])
->all();

if (count($arrayUserPointSale) == 1) {
$pointSale = PointSale::findOne(['id' => $arrayUserPointSale[0]->id_point_sale]);
} else {
$lastOrder = Order::find()->innerJoinWith('pointSale', true)->where([
'order.id_user' => $user->id,
'point_sale.id_producer' => GlobalParam::getCurrentProducerId()
])
->orderBy('order.id DESC')
->one();

if ($lastOrder) {
$pointSale = PointSale::findOne(['id' => $lastOrder->id_point_sale]);
}
}

if (isset($pointSale)) {
return $pointSale;
}

return null;
}

/**
* Retourne le crédit de l'utilisateur pour un producteur donné.
*
*/
public function getCredit(UserModel $user, ProducerModel $producer): float
{
$userProducer = $this->userProducerRepository->getOne($user, $producer);

if ($userProducer) {
return $userProducer->credit;
}

return 0;
}

/**
* Recherche des utilisateurs suivant les paramètres : id_etablissement,
* inactifs, id_point_vente, nom, prenom, email, telephone.
*
* @param array $params
* @return Query
*/
public static function findBy($params = [])
{
if (!isset($params['id_producer'])) {
$params['id_producer'] = GlobalParam::getCurrentProducerId();
}

$query = (new Query())
->select(['user.id AS user_id', 'user.name', 'user.lastname', 'user.phone', 'user.email', 'user.created_at', 'user.date_last_connection', 'user_producer.*', 'user.address', 'user.name_legal_person'])
->from('user');

$active = (isset($params['inactive']) && $params['inactive']) ? 0 : 1;
$query->innerJoin('user_producer', 'user.id = user_producer.id_user AND user_producer.active = ' . $active . ' AND user_producer.id_producer = :id_producer', [':id_producer' => $params['id_producer']]);

if (isset($params['id_point_sale']) && $params['id_point_sale']) {
$point_sale = PointSale::findOne(['id' => $params['id_point_sale']]);

$conditionLinkUserPointSale = 'user.id = user_point_sale.id_user AND user_point_sale.id_point_sale = :id_point_sale';

$usersPointSaleLink = false;
$usersPointSaleHasOrder = false;

if (isset($params['users_point_sale_link']) && $params['users_point_sale_link']) {
$usersPointSaleLink = true;
} elseif (isset($params['users_point_sale_has_order']) && $params['users_point_sale_has_order']) {
$usersPointSaleHasOrder = true;
} elseif ($point_sale->restricted_access) {
$usersPointSaleLink = true;
} else {
$usersPointSaleHasOrder = true;
}

if ($usersPointSaleLink) {
$query->innerJoin('user_point_sale', 'user.id = user_point_sale.id_user AND user_point_sale.id_point_sale = :id_point_sale', [':id_point_sale' => $params['id_point_sale']]);
} elseif ($usersPointSaleHasOrder) {
$query->innerJoin(
'order',
'user.id = order.id_user AND order.id_point_sale = :id_point_sale',
[':id_point_sale' => $params['id_point_sale']]
)->groupBy('user.id');
}
}

if (isset($params['subscribers']) && $params['subscribers']) {
$query->innerJoin(
'subscription',
'user.id = subscription.id_user AND subscription.id_producer = :id_producer',
[':id_producer' => GlobalParam::getCurrentProducerId()]
)->groupBy('user.id');
}

if (isset($params['inactive']) && $params['inactive']) {
$query->innerJoin(
'order',
'user.id = order.id_user'
)
->groupBy('user.id');
}

if (isset($params['name'])) {
$query->andFilterWhere(['like', 'name', $params['name']]);
}

if (isset($params['lastname'])) {
$query->andFilterWhere(['like', 'lastname', $params['lastname']]);
}

if (isset($params['email'])) {
$query->andFilterWhere(['like', 'email', $params['email']]);
}

if (isset($params['phone'])) {
$query->andFilterWhere(['like', 'phone', $params['phone']]);
}

$query->orderBy('user.type DESC, user.lastname ASC, user.name ASC');

return $query;
}

/**
* Finds user by password reset token
*
*/
public function getByPasswordResetToken(string $token)
{
if (!$this->userSolver->isPasswordResetTokenValid($token)) {
return null;
}

return UserModel::findOne([
'password_reset_token' => $token,
]);
}

/**
* Recherche un utilisateur via son adresse email.
*
*/
public static function getOneByEmail(string $email): ?UserModel
{
return UserModel::searchOne(['email' => $email]);
}

public static function getOneByUsername($username): ?UserModel
{
return UserModel::searchOne(['username' => $username]);
}

}

+ 187
- 0
common/logic/User/User/UserSolver.php Целия файл

@@ -0,0 +1,187 @@
<?php

namespace common\logic\User\User;

use common\logic\BaseService;
use common\logic\SolverInterface;

class UserSolver extends BaseService implements SolverInterface
{
public function getTypeChoicesArray(): array
{
return [
UserModel::TYPE_INDIVIDUAL => 'Particulier',
UserModel::TYPE_LEGAL_PERSON => 'Personne morale',
UserModel::TYPE_GUEST => 'Visiteur'
];
}

public function getUsernameFromArray(array $modelArray, $withType = false): string
{
$username = '';
if (isset($modelArray['name_legal_person']) && strlen($modelArray['name_legal_person'])) {
$username = $modelArray['name_legal_person'];

if ($withType) {
$username = 'Personne morale / ' . $username;
}
} else {
$username = $modelArray['lastname'] . ' ' . $modelArray['name'];
}

return $username;
}

public function getUsername(UserModel $user, $withType = false): string
{
$username = '';
if (isset($user->name_legal_person) && strlen($user->name_legal_person)) {
$username = $user->name_legal_person;

if ($withType) {
$username = 'Personne morale / ' . $username;
}
} else {
$username = $user->lastname . ' ' . $user->name;
}

return $username;
}

public function getFullAddress(UserModel $user, $nl2br = false)
{
$address = '';
if (isset($user->lastname) && isset($user->name) && strlen($user->lastname) && strlen($user->name)) {
$address .= $user->lastname . ' ' . $user->name . "\n";
}
if (isset($user->name_legal_person) && strlen($user->name_legal_person)) {
$address .= $user->name_legal_person . "\n";
}
$address .= $user->address;

if ($nl2br) {
$address = nl2br($address);
}

return $address;
}

/**
* Finds out if password reset token is valid
*
* @param string $token password reset token
* @return boolean
*/
public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}
$expire = \Yii::$app->params['user.passwordResetTokenExpire'];
$parts = explode('_', $token);
$timestamp = (int)end($parts);
return $timestamp + $expire >= time();
}

/**
* Retourne si l'utilisateur est un admin ou non.
*
*/
public function isAdmin(UserModel $user): bool
{
return $user->status == UserModel::STATUS_ADMIN;
}

/**
* Retourne si l'utilisateur est un producteur ou non.
*
*/
public function isProducer(UserModel $user): bool
{
return ($user->status == UserModel::STATUS_ADMIN
|| $user->status == UserModel::STATUS_PRODUCER) && $user->id_producer;
}

/**
* Retourne l'utilisateur courant.
*
*/
public function getCurrent(): ?UserModel
{
if (!\Yii::$app->user->isGuest) {
return \Yii::$app->user->identity;
}

return null;
}

/**
* Retourne si l'utilisateur courant est connecté ou non.
*
*/
public function isCurrentConnected(): bool
{
return !\Yii::$app->user->isGuest;
}

/**
* Retourne si l'utilisateur courant est un producteur ou non.
*
*/
public function isCurrentProducer(): bool
{
$user = $this->getCurrent();
if ($user) {
return $this->isProducer($user);
}
return false;
}

/**
* Retourne si l'utilisateur courant est un admin ou non.
*
*/
public function isCurrentAdmin(): bool
{
$user = $this->getCurrent();
if ($user) {
return $this->isAdmin($user);
}
return false;
}

/**
* Retourne l'ID de l'utilisateur courant connecté.
*
*/
public function getCurrentId()
{
if (!\Yii::$app->user->isGuest) {
return \Yii::$app->user->identity->id;
}

return false;
}

/**
* Retourne le status de l'utilisateur courant connecté.
*
*/
public function getCurrentStatus()
{
if (!\Yii::$app->user->isGuest) {
return \Yii::$app->user->identity->status;
}

return false;
}

public function hasAccessBackend(): bool
{
$userCurrentStatus = $this->getCurrentStatus();

return $userCurrentStatus == UserModel::STATUS_ADMIN
|| $userCurrentStatus == UserModel::STATUS_PRODUCER;
}

}

+ 21
- 0
common/logic/User/User/UserUtils.php Целия файл

@@ -2,6 +2,7 @@

namespace common\logic\User\User;

use common\helpers\GlobalParam;
use common\logic\BaseService;
use common\logic\Producer\Producer\ProducerModel;
use common\logic\UtilsInterface;
@@ -24,4 +25,24 @@ class UserUtils extends BaseService implements UtilsInterface
->setSubject('[Opendistrib] Inscription')
->send();
}

/**
* Envoie un email de bienvenue à l'utilisateur lors de son inscription
* via le backend du site.
*
*/
public function sendMailWelcome(UserModel $user, string $password): void
{
if (strlen($user->email)) {
$producer = ProducerModel::findOne(GlobalParam::getCurrentProducerId());
\Yii::$app->mailer->compose();
$mail = \Yii::$app->mailer->compose(
['html' => 'createUserAdmin-html', 'text' => 'createUserAdmin-text'], ['user' => $user, 'producer' => $producer, 'password' => $password]
)
->setTo($user->email)
->setFrom(['contact@opendistrib.net' => 'distrib'])
->setSubject('[Opendistrib] Inscription')
->send();
}
}
}

+ 0
- 2
common/logic/User/UserProducer/UserProducerContainer.php Целия файл

@@ -3,8 +3,6 @@
namespace common\logic\User\UserProducer;

use common\logic\ContainerInterface;
use common\logic\User\UserProducer\UserProducerModel;
use common\logic\User\UserProducer\UserProducerRepository;

class UserProducerContainer implements ContainerInterface
{

+ 21
- 0
common/logic/User/UserProducer/UserProducerFactory.php Целия файл

@@ -0,0 +1,21 @@
<?php

namespace common\logic\User\UserProducer;

use common\logic\FactoryInterface;

class UserProducerFactory implements FactoryInterface
{
public function create(int $idUser, int $idProducer, int $bookmark = 1)
{
$userProducer = new UserProducerModel();

$userProducer->setIdUser($idUser);
$userProducer->setIdProducer($idProducer);
$userProducer->setCredit(0);
$userProducer->setActive(1);
$userProducer->setBookmark($bookmark);

return $userProducer;
}
}

+ 143
- 61
common/logic/User/UserProducer/UserProducerModel.php Целия файл

@@ -45,69 +45,151 @@ use common\components\ActiveRecordCommon;

/**
* This is the model class for table "user_producer".
*
*/
class UserProducerModel extends ActiveRecordCommon
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'user_producer';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_user', 'id_producer'], 'required'],
[['id_user', 'id_producer', 'product_price_percent'], 'integer'],
[['active', 'bookmark', 'credit_active'], 'boolean'],
[['credit', 'product_price_percent'], 'double'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id_user' => 'Utilisateur',
'id_producer' => 'Producteur',
'active' => 'Actif',
'bookmark' => 'Favoris',
'credit_active' => 'Crédit',
'product_price_percent' => 'Prix produits : pourcentage'
];
}

public function getProducer()
{
return $this->hasOne(ProducerModel::class, ['id' => 'id_producer']);
}

public function getUser()
{
return $this->hasOne(UserModel::class, ['id' => 'id_user']);
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => [],
'join_with' => [],
'orderby' => '',
'attribute_id_producer' => 'user_producer.id_producer'
];
}
/**
* @inheritdoc
*/
public static function tableName()
{
return 'user_producer';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_user', 'id_producer'], 'required'],
[['id_user', 'id_producer', 'product_price_percent'], 'integer'],
[['active', 'bookmark', 'credit_active'], 'boolean'],
[['credit', 'product_price_percent'], 'double'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id_user' => 'Utilisateur',
'id_producer' => 'Producteur',
'active' => 'Actif',
'bookmark' => 'Favoris',
'credit_active' => 'Crédit',
'product_price_percent' => 'Prix produits : pourcentage'
];
}

public function getProducer()
{
return $this->hasOne(ProducerModel::class, ['id' => 'id_producer']);
}

public function getUser()
{
return $this->hasOne(UserModel::class, ['id' => 'id_user']);
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => [],
'join_with' => [],
'orderby' => '',
'attribute_id_producer' => 'user_producer.id_producer'
];
}

public function getIdUser(): int
{
return $this->id_user;
}

public function setIdUser(int $idUser): self
{
$this->id_user = $idUser;

return $this;
}

public function getIdProducer(): int
{
return $this->id_producer;
}

public function setIdProducer(int $idProducer): self
{
$this->id_producer = $idProducer;

return $this;
}

public function getActive(): ?bool
{
return $this->active;
}

public function setActive(bool $active): self
{
$this->active = $active;

return $this;
}

public function getBookmark(): ?bool
{
return $this->bookmark;
}

public function setBookmark(bool $bookmark): self
{
$this->bookmark = $bookmark;

return $this;
}

public function getCredit(): float
{
return $this->credit;
}

public function setCredit(float $credit): self
{
$this->credit = $credit;

return $this;
}

public function getCreditActive(): ?bool
{
return $this->credit_active;
}

public function setCreditActive(bool $creditActive): self
{
$this->credit_active = $creditActive;

return $this;
}

public function getProductPricePercent(): float
{
return $this->product_price_percent;
}

public function setProductPricePercent(float $productPricePercent): self
{
$this->product_price_percent = $productPricePercent;

return $this;
}
}

+ 5
- 3
common/logic/User/UserProducer/UserProducerRepository.php Целия файл

@@ -3,15 +3,17 @@
namespace common\logic\User\UserProducer;

use common\logic\BaseService;
use common\logic\Producer\Producer\ProducerModel;
use common\logic\RepositoryInterface;
use common\logic\User\User\UserModel;

class UserProducerRepository extends BaseService implements RepositoryInterface
{
public function getOne($idUser, $idProducer)
public function getOne(UserModel $user, ProducerModel $producer)
{
return UserProducerModel::searchOne([
'id_user' => $idUser,
'id_producer' => $idProducer
'id_user' => $user->id,
'id_producer' => $producer->id
]);
}


+ 0
- 1
producer/views/credit/history.php Целия файл

@@ -37,7 +37,6 @@
*/

use yii\grid\GridView;
use ruskid\stripe\StripeCheckoutCustom;

$creditHistorySolver = \Yii::$app->logic->getCreditHistoryContainer()->getSolver();
$producer = $this->context->getProducer();

Loading…
Отказ
Запис