public function getContainers() | public function getContainers() | ||||
{ | { | ||||
return [ | return [ | ||||
$this->getUserContainer(), | |||||
$this->getProducerContainer(), | |||||
$this->getCreditHistoryContainer(), | $this->getCreditHistoryContainer(), | ||||
$this->getProducerPriceRangeContainer(), | $this->getProducerPriceRangeContainer(), | ||||
$this->getUserProducerContainer(), | $this->getUserProducerContainer(), | ||||
$this->getUserContainer(), | |||||
$this->getProducerContainer(), | |||||
]; | ]; | ||||
} | } | ||||
public function beforeAction($event) | public function beforeAction($event) | ||||
{ | { | ||||
if (!Yii::$app->user->isGuest) { | if (!Yii::$app->user->isGuest) { | ||||
Yii::$app->user->identity->updateLastConnection(); | |||||
$this->getLogic()->getUserContainer()->getBuilder()->updateLastConnection(Yii::$app->user->identity); | |||||
} | } | ||||
return parent::beforeAction($event); | return parent::beforeAction($event); |
SolverInterface::class, | SolverInterface::class, | ||||
RepositoryInterface::class, | RepositoryInterface::class, | ||||
BuilderInterface::class, | BuilderInterface::class, | ||||
ResolverInterface::class, | |||||
UtilsInterface::class, | UtilsInterface::class, | ||||
]; | ]; | ||||
} | } | ||||
public function respectHierarchy(string $serviceClassAsked): bool | public function respectHierarchy(string $serviceClassAsked): bool | ||||
{ | { | ||||
$businessLogic = \Yii::$app->logic; | |||||
$domain = \Yii::$app->logic; | |||||
$serviceCurrentClass = get_class($this); | $serviceCurrentClass = get_class($this); | ||||
$levelHierarchyServiceAsked = $this->getServiceLevelHierarchy($serviceClassAsked); | $levelHierarchyServiceAsked = $this->getServiceLevelHierarchy($serviceClassAsked); | ||||
$levelHierarchyServiceCurrent = $this->getServiceLevelHierarchy($serviceCurrentClass); | $levelHierarchyServiceCurrent = $this->getServiceLevelHierarchy($serviceCurrentClass); | ||||
return true; | return true; | ||||
} | } | ||||
elseif($levelHierarchyServiceAsked == $levelHierarchyServiceCurrent | elseif($levelHierarchyServiceAsked == $levelHierarchyServiceCurrent | ||||
&& $businessLogic->getContainerLevelHierarchyByService($serviceClassAsked) | |||||
< $businessLogic->getContainerLevelHierarchyByService($serviceCurrentClass)) { | |||||
&& $domain->getContainerLevelHierarchyByService($serviceClassAsked) | |||||
< $domain->getContainerLevelHierarchyByService($serviceCurrentClass)) { | |||||
return true; | return true; | ||||
} | } | ||||
return $this->classImplementsInterface(BuilderInterface::class); | return $this->classImplementsInterface(BuilderInterface::class); | ||||
} | } | ||||
public function isResolver(): bool | |||||
{ | |||||
return $this->classImplementsInterface(ResolverInterface::class); | |||||
} | |||||
public function isUtils(): bool | public function isUtils(): bool | ||||
{ | { | ||||
return $this->classImplementsInterface(UtilsInterface::class); | return $this->classImplementsInterface(UtilsInterface::class); |
namespace common\logic\Producer\Producer; | namespace common\logic\Producer\Producer; | ||||
use common\helpers\Opendistrib; | |||||
use common\logic\User\UserProducer\UserProducerFactory; | |||||
use common\helpers\Password; | use common\helpers\Password; | ||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\BuilderInterface; | use common\logic\BuilderInterface; | ||||
use common\logic\User\UserProducer\UserProducerModel; | use common\logic\User\UserProducer\UserProducerModel; | ||||
use common\logic\User\UserProducer\UserProducerRepository; | |||||
use common\helpers\Url; | |||||
class ProducerBuilder extends BaseService implements BuilderInterface | class ProducerBuilder extends BaseService implements BuilderInterface | ||||
{ | { | ||||
protected ProducerRepository $producerRepository; | protected ProducerRepository $producerRepository; | ||||
protected UserProducerRepository $userProducerRepository; | |||||
protected UserProducerFactory $userProducerFactory; | |||||
protected ProducerSolver $producerSolver; | |||||
public function __construct() | public function __construct() | ||||
{ | { | ||||
$this->producerRepository = $this->loadService(ProducerRepository::class); | $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 | public function init(ProducerModel $producer): void | ||||
{ | { | ||||
$cptSlug = 0 ; | $cptSlug = 0 ; | ||||
do { | do { | ||||
$slug = \common\helpers\Url::slugify($producer->name) ; | |||||
$slug = Url::slugify($producer->name) ; | |||||
if($cptSlug) { | if($cptSlug) { | ||||
$slug .= $cptSlug ; | $slug .= $cptSlug ; | ||||
} | } | ||||
/** | /** | ||||
* Lie un utilisateur à un producteur. | * 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) { | 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; | 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 | |||||
); | |||||
} | |||||
} | } |
{ | { | ||||
return [ | return [ | ||||
ProducerFactory::class, | ProducerFactory::class, | ||||
ProducerSolver::class, | |||||
ProducerRepository::class, | ProducerRepository::class, | ||||
ProducerBuilder::class, | ProducerBuilder::class, | ||||
ProducerUtils::class | ProducerUtils::class | ||||
return new ProducerFactory(); | return new ProducerFactory(); | ||||
} | } | ||||
public function getSolver(): ProducerSolver | |||||
{ | |||||
return new ProducerSolver(); | |||||
} | |||||
public function getRepository() | public function getRepository() | ||||
{ | { | ||||
return new ProducerRepository(); | return new ProducerRepository(); |
{ | { | ||||
$producer = new ProducerModel(); | $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; | return $producer; | ||||
} | } |
use common\logic\User\User\UserModel; | use common\logic\User\User\UserModel; | ||||
use common\models\TaxRate; | use common\models\TaxRate; | ||||
use common\logic\User\UserProducer\UserProducerModel; | use common\logic\User\UserProducer\UserProducerModel; | ||||
use Yii; | |||||
use common\components\ActiveRecordCommon; | 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 | class ProducerModel extends ActiveRecordCommon | ||||
const ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT = 25; | const ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT = 25; | ||||
const ORDER_DEADLINE_DEFAULT = 20; | |||||
const ORDER_DELAY_DEFAULT = 1; | |||||
/** | /** | ||||
* @inheritdoc | * @inheritdoc | ||||
*/ | */ | ||||
public function getUser() | public function getUser() | ||||
{ | { | ||||
return $this->hasMany(UserModel::className(), ['id_producer' => 'id']); | |||||
return $this->hasMany(UserModel::class, ['id_producer' => 'id']); | |||||
} | } | ||||
public function getContact() | public function getContact() | ||||
{ | { | ||||
return $this->hasMany(UserModel::className(), ['id_producer' => 'id']) | |||||
return $this->hasMany(UserModel::class, ['id_producer' => 'id']) | |||||
->where(['status' => UserModel::STATUS_PRODUCER]); | ->where(['status' => UserModel::STATUS_PRODUCER]); | ||||
} | } | ||||
public function getTaxRate() | 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() | public static function getBillingTypePopulateDropdown() | ||||
{ | { | ||||
return self::$billingTypeArray; | 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; | |||||
} | } | ||||
} | } | ||||
namespace common\logic\Producer\Producer; | namespace common\logic\Producer\Producer; | ||||
use common\helpers\Departments; | use common\helpers\Departments; | ||||
use common\helpers\GlobalParam; | |||||
use common\helpers\Price; | |||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\Producer\ProducerPriceRange\ProducerPriceRangeModel; | |||||
use common\logic\Producer\ProducerPriceRange\ProducerPriceRangeRepository; | |||||
use common\logic\RepositoryInterface; | use common\logic\RepositoryInterface; | ||||
use common\logic\User\User\UserModel; | |||||
use yii\helpers\Html; | use yii\helpers\Html; | ||||
class ProducerRepository extends BaseService implements RepositoryInterface | 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) | public function getOneById($id) | ||||
{ | { | ||||
return ProducerModel::searchOne(['id' => $id]); | return ProducerModel::searchOne(['id' => $id]); | ||||
'options' => $optionsProducers | '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(); | |||||
} | |||||
} | } |
<?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; | |||||
} | |||||
} |
'price' => 'Tarif (HT)', | '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' => '' | |||||
]; | |||||
} | |||||
} | } |
namespace common\logic\Producer\ProducerPriceRange; | namespace common\logic\Producer\ProducerPriceRange; | ||||
use common\helpers\Price; | |||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\RepositoryInterface; | use common\logic\RepositoryInterface; | ||||
class ProducerPriceRangeRepository extends BaseService implements 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() | public function query() | ||||
{ | { | ||||
return ProducerPriceRangeModel::find()->orderBy('range_begin ASC'); | 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; | |||||
} | |||||
} | |||||
} | } |
<?php | |||||
namespace common\logic; | |||||
interface ResolverInterface | |||||
{ | |||||
} |
namespace common\logic\User\CreditHistory; | namespace common\logic\User\CreditHistory; | ||||
use common\components\ActiveRecordCommon; | use common\components\ActiveRecordCommon; | ||||
use common\logic\User\User\UserModel; | |||||
use common\models\Order; | |||||
use yii\db\ActiveQuery; | use yii\db\ActiveQuery; | ||||
public function getUser(): ActiveQuery | 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; | return $this->user; | ||||
} | } | ||||
public function getUserAction(): ActiveQuery | 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; | return $this->userAction; | ||||
} | } |
class CreditHistorySolver implements SolverInterface | class CreditHistorySolver implements SolverInterface | ||||
{ | { | ||||
public function isTypeDebit(CreditHistoryModel $creditHistory): bool | public function isTypeDebit(CreditHistoryModel $creditHistory): bool | ||||
{ | { | ||||
return in_array($creditHistory->type, [ | |||||
return in_array($creditHistory->getType(), [ | |||||
CreditHistoryModel::TYPE_DEBIT, | CreditHistoryModel::TYPE_DEBIT, | ||||
CreditHistoryModel::TYPE_PAYMENT, | CreditHistoryModel::TYPE_PAYMENT, | ||||
]); | ]); | ||||
public function isTypeCredit(CreditHistoryModel $creditHistory): bool | public function isTypeCredit(CreditHistoryModel $creditHistory): bool | ||||
{ | { | ||||
return in_array($creditHistory->type, [ | |||||
return in_array($creditHistory->getType(), [ | |||||
CreditHistoryModel::TYPE_CREDIT, | CreditHistoryModel::TYPE_CREDIT, | ||||
CreditHistoryModel::TYPE_INITIAL_CREDIT, | CreditHistoryModel::TYPE_INITIAL_CREDIT, | ||||
CreditHistoryModel::TYPE_REFUND | CreditHistoryModel::TYPE_REFUND |
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\BuilderInterface; | use common\logic\BuilderInterface; | ||||
use common\logic\Producer\Producer\ProducerModel; | |||||
class UserBuilder extends BaseService implements BuilderInterface | class UserBuilder extends BaseService implements BuilderInterface | ||||
{ | { | ||||
public function initPassword($user, $password) | |||||
public function initPassword(UserModel $user, string $password) | |||||
{ | { | ||||
$user->setPassword($password); | $user->setPassword($password); | ||||
$user->generateAuthKey(); | $user->generateAuthKey(); | ||||
} | } | ||||
public function initProducer($user, $producer) | |||||
public function initProducer(UserModel $user, ProducerModel $producer) | |||||
{ | { | ||||
$user->id_producer = $producer->id; | $user->id_producer = $producer->id; | ||||
$user->status = UserModel::STATUS_PRODUCER; | $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; | |||||
} | |||||
} | } |
]; | ]; | ||||
} | } | ||||
/** | |||||
* 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. | * Vérifie le mot de passe envoyé par l'utilisateur. | ||||
* | * | ||||
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); | 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 | * @inheritdoc | ||||
/** | /** | ||||
* Validates password | * 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); | 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' | |||||
]; | |||||
} | |||||
} | } |
namespace common\logic\User\User; | namespace common\logic\User\User; | ||||
use common\helpers\GlobalParam; | |||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\Producer\Producer\ProducerModel; | |||||
use common\logic\RepositoryInterface; | 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 | 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) | public function getOneById($id) | ||||
{ | { | ||||
return UserModel::searchOne(['id' => $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]); | |||||
} | |||||
} | } |
<?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; | |||||
} | |||||
} |
namespace common\logic\User\User; | namespace common\logic\User\User; | ||||
use common\helpers\GlobalParam; | |||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\Producer\Producer\ProducerModel; | use common\logic\Producer\Producer\ProducerModel; | ||||
use common\logic\UtilsInterface; | use common\logic\UtilsInterface; | ||||
->setSubject('[Opendistrib] Inscription') | ->setSubject('[Opendistrib] Inscription') | ||||
->send(); | ->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(); | |||||
} | |||||
} | |||||
} | } |
namespace common\logic\User\UserProducer; | namespace common\logic\User\UserProducer; | ||||
use common\logic\ContainerInterface; | use common\logic\ContainerInterface; | ||||
use common\logic\User\UserProducer\UserProducerModel; | |||||
use common\logic\User\UserProducer\UserProducerRepository; | |||||
class UserProducerContainer implements ContainerInterface | class UserProducerContainer implements ContainerInterface | ||||
{ | { |
<?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; | |||||
} | |||||
} |
/** | /** | ||||
* This is the model class for table "user_producer". | * This is the model class for table "user_producer". | ||||
* | |||||
*/ | */ | ||||
class UserProducerModel extends ActiveRecordCommon | 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; | |||||
} | |||||
} | } |
namespace common\logic\User\UserProducer; | namespace common\logic\User\UserProducer; | ||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\Producer\Producer\ProducerModel; | |||||
use common\logic\RepositoryInterface; | use common\logic\RepositoryInterface; | ||||
use common\logic\User\User\UserModel; | |||||
class UserProducerRepository extends BaseService implements RepositoryInterface | class UserProducerRepository extends BaseService implements RepositoryInterface | ||||
{ | { | ||||
public function getOne($idUser, $idProducer) | |||||
public function getOne(UserModel $user, ProducerModel $producer) | |||||
{ | { | ||||
return UserProducerModel::searchOne([ | return UserProducerModel::searchOne([ | ||||
'id_user' => $idUser, | |||||
'id_producer' => $idProducer | |||||
'id_user' => $user->id, | |||||
'id_producer' => $producer->id | |||||
]); | ]); | ||||
} | } | ||||
*/ | */ | ||||
use yii\grid\GridView; | use yii\grid\GridView; | ||||
use ruskid\stripe\StripeCheckoutCustom; | |||||
$creditHistorySolver = \Yii::$app->logic->getCreditHistoryContainer()->getSolver(); | $creditHistorySolver = \Yii::$app->logic->getCreditHistoryContainer()->getSolver(); | ||||
$producer = $this->context->getProducer(); | $producer = $this->context->getProducer(); |