@@ -47,6 +47,12 @@ class ActiveRecordCommon extends \yii\db\ActiveRecord | |||
const SEARCH_ONE = 'one'; | |||
const SEARCH_COUNT = 'count'; | |||
public function populateFieldObject($fieldIdentifier, $fieldObject, $object) | |||
{ | |||
$this->$fieldIdentifier = $object->id; | |||
$this->populateRelation($fieldObject, $object); | |||
} | |||
/** | |||
* Méthode générique de recherche utilisée pour tous les modèles. Elle a | |||
* pour but de construire la requête et de retourner le résultat. |
@@ -39,6 +39,7 @@ | |||
namespace common\helpers; | |||
use common\logic\Producer\Producer\Producer; | |||
use common\logic\User\User\UserSolver; | |||
use common\models\Producer; | |||
class GlobalParam | |||
@@ -83,4 +84,16 @@ class GlobalParam | |||
return false; | |||
} | |||
public static function getCurrentUser() | |||
{ | |||
$userSolver = new UserSolver(); | |||
return $userSolver->getCurrent(); | |||
} | |||
public static function getCurrentUserId() | |||
{ | |||
$userSolver = new UserSolver(); | |||
return $userSolver->getCurrentId(); | |||
} | |||
} |
@@ -36,6 +36,13 @@ class DistributionRepository extends BaseService implements RepositoryInterface | |||
return Distribution::searchOne($paramsDistribution); | |||
} | |||
public function getOneByDate(string $date) | |||
{ | |||
return Distribution::searchOne([ | |||
'distribution.date' => $date | |||
]); | |||
} | |||
/** | |||
* Récupère les distributions futures. | |||
*/ |
@@ -148,6 +148,11 @@ class Order extends ActiveRecordCommon | |||
return $this->hasOne(User::class, ['id' => 'id_user']); | |||
} | |||
public function populateUser(User $user) | |||
{ | |||
$this->populateFieldObject('id_user', 'user', $user); | |||
} | |||
public function getProductOrder() | |||
{ | |||
return $this->hasMany(ProductOrder::class, ['id_order' => 'id']) | |||
@@ -161,6 +166,11 @@ class Order extends ActiveRecordCommon | |||
->with('producer'); | |||
} | |||
public function populateDistribution(Distribution $distribution) | |||
{ | |||
$this->populateFieldObject('id_distribution', 'distribution', $distribution); | |||
} | |||
public function getPointSale() | |||
{ |
@@ -6,16 +6,26 @@ use common\helpers\GlobalParam; | |||
use common\helpers\Price; | |||
use common\logic\BaseService; | |||
use common\logic\BuilderInterface; | |||
use common\logic\Distribution\Distribution\Distribution; | |||
use common\logic\Distribution\Distribution\DistributionRepository; | |||
use common\logic\Document\Document\Document; | |||
use common\logic\Order\OrderStatusHistory\OrderStatusHistoryBuilder; | |||
use common\logic\Order\ProductOrder\ProductOrder; | |||
use common\logic\Order\ProductOrder\ProductOrderBuilder; | |||
use common\logic\PointSale\PointSale\PointSale; | |||
use common\logic\PointSale\PointSale\PointSaleBuilder; | |||
use common\logic\PointSale\PointSale\PointSaleRepository; | |||
use common\logic\PointSale\PointSale\UserPointSaleRepository; | |||
use common\logic\Producer\Producer\Producer; | |||
use common\logic\Producer\Producer\ProducerRepository; | |||
use common\logic\Subscription\Subscription\Subscription; | |||
use common\logic\Subscription\Subscription\SubscriptionBuilder; | |||
use common\logic\User\CreditHistory\CreditHistory; | |||
use common\logic\User\CreditHistory\CreditHistoryBuilder; | |||
use common\logic\User\CreditHistory\CreditHistoryRepository; | |||
use common\logic\User\User\User; | |||
use common\logic\User\User\UserSolver; | |||
use common\logic\User\UserProducer\UserProducerRepository; | |||
use yii\web\NotFoundHttpException; | |||
class OrderBuilder extends BaseService implements BuilderInterface | |||
@@ -28,6 +38,12 @@ class OrderBuilder extends BaseService implements BuilderInterface | |||
protected ProductOrderBuilder $productOrderBuilder; | |||
protected OrderStatusHistoryBuilder $orderStatusHistoryBuilder; | |||
protected OrderRepository $orderRepository; | |||
protected DistributionRepository $distributionRepository; | |||
protected SubscriptionBuilder $subscriptionBuilder; | |||
protected PointSaleRepository $pointSaleRepository; | |||
protected UserProducerRepository $userProducerRepository; | |||
protected UserPointSaleRepository $userPointSaleRepository; | |||
protected PointSaleBuilder $pointSaleBuilder; | |||
public function __construct() | |||
{ | |||
@@ -39,15 +55,149 @@ class OrderBuilder extends BaseService implements BuilderInterface | |||
$this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class); | |||
$this->orderStatusHistoryBuilder = $this->loadService(OrderStatusHistoryBuilder::class); | |||
$this->orderRepository = $this->loadService(OrderRepository::class); | |||
$this->distributionRepository = $this->loadService(DistributionRepository::class); | |||
$this->subscriptionBuilder = $this->loadService(SubscriptionBuilder::class); | |||
$this->pointSaleRepository = $this->loadService(PointSaleRepository::class); | |||
$this->userProducerRepository = $this->loadService(UserProducerRepository::class); | |||
$this->userPointSaleRepository = $this->loadService(UserPointSaleRepository::class); | |||
$this->pointSaleBuilder = $this->loadService(PointSaleBuilder::class); | |||
} | |||
public function instanciate(): Order | |||
public function instanciate(Distribution $distribution): Order | |||
{ | |||
$order = new Order(); | |||
$order->populateDistribution($distribution); | |||
$order->date = date('Y-m-d H:i:s'); | |||
$order->status = 'tmp-order'; | |||
return $order; | |||
} | |||
/** | |||
* Ajoute l'abonnement' pour une date donnée. | |||
*/ | |||
// add | |||
public function createFromSubscription(Subscription $subscription, string $date, $force = false) | |||
{ | |||
$now = date('Y-m-d'); | |||
$distributionDate = date('Y-m-d', strtotime($date)); | |||
$distribution = $this->distributionRepository->getOneByDate($distributionDate); | |||
if ($distribution | |||
&& $distribution->active | |||
&& ($distributionDate > $now || $force) | |||
&& count($subscription->productSubscription) | |||
&& $subscription->pointSale) { | |||
$order = $this->instanciate($distribution); | |||
$this->initFromSubscription($order, $subscription); | |||
$this->addUserPointSale($order); | |||
$this->initCommentPointSale($order); | |||
$this->generateReference($order); | |||
$order->save(); | |||
$productsAdd = false; | |||
$user = $subscription->user ?? null; | |||
foreach ($subscription->productSubscription as $productSubscription) { | |||
$productOrder = new ProductOrder; | |||
$productOrder->id_order = $order->id; | |||
$productOrder->id_product = $productSubscription->product->id; | |||
$productOrder->quantity = $productSubscription->quantity; | |||
$productOrder->price = $productSubscription->product->getPrice([ | |||
'user' => $user, | |||
'point_sale' => $pointSale, | |||
'quantity' => $productSubscription->quantity | |||
]); | |||
$productOrder->unit = $productSubscription->product->unit; | |||
$productOrder->step = $productSubscription->product->step; | |||
$productOrder->id_tax_rate = $productSubscription->product->taxRate->id; | |||
$productOrder->save(); | |||
$productsAdd = true; | |||
} | |||
if(!$productsAdd) { | |||
$order->delete(); | |||
} | |||
} | |||
} | |||
public function initFromSubscription(Order $order, Subscription $subscription): void | |||
{ | |||
$this->initBaseFromSubscription($order, $subscription); | |||
$this->initAutoPaymentFromSubscription($order, $subscription); | |||
} | |||
public function initBaseFromSubscription(Order $order, Subscription $subscription): void | |||
{ | |||
$order->origin = Order::ORIGIN_AUTO; | |||
$order->populatePointSale($subscription->pointSale); | |||
$order->populateSubscription($subscription); | |||
if (strlen($subscription->comment)) { | |||
$order->comment = $subscription->comment; | |||
} | |||
if (strlen($subscription->username)) { | |||
$order->username = $subscription->username; | |||
$order->id_user = 0; | |||
} else { | |||
$order->populateUser($subscription->user); | |||
} | |||
} | |||
public function initAutoPaymentFromSubscription(Order $order, Subscription $subscription): void | |||
{ | |||
$pointSale = $subscription->pointSale; | |||
if($pointSale) { | |||
$creditFunctioning = $this->producerRepository->getPointSaleCreditFunctioning($pointSale); | |||
$order->auto_payment = 0; | |||
if ($subscription->auto_payment == Subscription::AUTO_PAYMENT_DEDUCTED) { | |||
if ($order->id_user && $this->producerRepository->getConfig('credit') && $pointSale->credit) { | |||
if ($creditFunctioning == Producer::CREDIT_FUNCTIONING_OPTIONAL) { | |||
$order->auto_payment = 0; | |||
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_MANDATORY) { | |||
$order->auto_payment = 1; | |||
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_USER) { | |||
$userProducer = $this->userProducerRepository->getOne($user, $distribution->producer); | |||
if ($userProducer) { | |||
$order->auto_payment = $userProducer->credit_active; | |||
} | |||
} | |||
} | |||
} elseif ($subscription->auto_payment == Subscription::AUTO_PAYMENT_YES) { | |||
$order->auto_payment = 1; | |||
} elseif ($subscription->auto_payment == Subscription::AUTO_PAYMENT_NO) { | |||
$order->auto_payment = 0; | |||
} | |||
} | |||
$order->tiller_synchronization = $order->auto_payment; | |||
} | |||
public function addUserPointSale(Order $order) | |||
{ | |||
if($order->user) { | |||
$this->pointSaleBuilder->addUser($order->user, $order->pointSale); | |||
} | |||
} | |||
public function initCommentPointSale(Order $order): void | |||
{ | |||
if($order->user && $order->pointSale) { | |||
$userPointSale = $this->userPointSaleRepository->getOne($order->user, $order->pointSale); | |||
if ($userPointSale && strlen($userPointSale->comment)) { | |||
$order->comment_point_sale = $userPointSale->comment; | |||
} | |||
} | |||
} | |||
/** | |||
* Initialise le montant total, le montant déjà payé et le poids de la commande. | |||
*/ |
@@ -41,9 +41,7 @@ namespace common\logic\PointSale\PointSale; | |||
use common\helpers\GlobalParam; | |||
use common\logic\Distribution\PointSaleDistribution\PointSaleDistribution; | |||
use common\logic\PointSale\UserPointSale\UserPointSale; | |||
use common\logic\Producer\Producer\Producer; | |||
use common\logic\User\User\User; | |||
use yii\helpers\Html; | |||
use common\components\ActiveRecordCommon; | |||
/** | |||
@@ -160,184 +158,9 @@ class PointSale extends ActiveRecordCommon | |||
/** | |||
* Enregistre le point de vente. | |||
*/ | |||
public function save(bool $runValidation = true, array $attributeNames = NULL) | |||
public function save($runValidation = true, $attributeNames = NULL) | |||
{ | |||
$this->id_producer = GlobalParam::getCurrentProducerId(); | |||
return parent::save($runValidation, $attributeNames); | |||
} | |||
/** | |||
* Traite la mise à jour de l'attribut 'point_production'. | |||
*/ | |||
public function processPointProduction() | |||
{ | |||
if ($this->point_production) { | |||
PointSale::updateAll( | |||
['point_production' => 0], | |||
['id_producer' => $this->id_producer] | |||
); | |||
$this->point_production = 1; | |||
$this->save(); | |||
} | |||
} | |||
/** | |||
* Traite les accès restreints d'un point de vente. | |||
*/ | |||
public function processRestrictedAccess() | |||
{ | |||
UserPointSale::deleteAll(['id_point_sale' => $this->id]); | |||
if (is_array($this->users) && count($this->users)) { | |||
foreach ($this->users as $key => $val) { | |||
$user = User::findOne($val); | |||
if ($user) { | |||
$userPointSale = new UserPointSale; | |||
$userPointSale->id_user = $val; | |||
$userPointSale->id_point_sale = $this->id; | |||
if (isset($this->users_comment[$val]) && strlen($this->users_comment[$val])) { | |||
$userPointSale->comment = $this->users_comment[$val]; | |||
} | |||
$userPointSale->save(); | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* Retourne le commentaire de l'utilisateur courant lié au point de vente. | |||
* | |||
* @return string|null | |||
*/ | |||
public function getComment() | |||
{ | |||
if (isset($this->userPointSale)) { | |||
foreach ($this->userPointSale as $userPointSale) { | |||
if ($userPointSale->id_user == User::getCurrentId()) { | |||
return $userPointSale->comment; | |||
} | |||
} | |||
} | |||
return null; | |||
} | |||
/** | |||
* Retourne le nombre de points de vente pour l'établissement courant. | |||
* | |||
* @return integer | |||
*/ | |||
public static function count() | |||
{ | |||
return self::searchCount(['id_producer' => GlobalParam::getCurrentProducerId()]); | |||
} | |||
/** | |||
* Vérifie le code d'accès à un point de vente. | |||
* | |||
* @param string $code | |||
* @return boolean | |||
*/ | |||
public function validateCode($code) | |||
{ | |||
if (strlen($this->code)) { | |||
if (trim(strtolower($code)) == trim(strtolower($this->code))) { | |||
return true; | |||
} else { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
/** | |||
* Retourne les jours de livraison du point de vente sous forme d'une chaine | |||
* de caractères. | |||
* | |||
* @return string | |||
*/ | |||
public function getStrDeliveryDays() | |||
{ | |||
$str = ''; | |||
if ($this->delivery_monday) $str .= 'lundi, '; | |||
if ($this->delivery_tuesday) $str .= 'mardi, '; | |||
if ($this->delivery_wednesday) $str .= 'mercredi, '; | |||
if ($this->delivery_thursday) $str .= 'jeudi, '; | |||
if ($this->delivery_friday) $str .= 'vendredi, '; | |||
if ($this->delivery_saturday) $str .= 'samedi, '; | |||
if ($this->delivery_sunday) $str .= 'dimanche, '; | |||
if (strlen($str)) { | |||
return substr($str, 0, strlen($str) - 2); | |||
} else { | |||
return ''; | |||
} | |||
} | |||
/** | |||
* Retourne un commentaire informant l'utilisateur sur les détails de | |||
* livraison d'un point de vente et pour un jour donné. | |||
* | |||
* @param string $jour | |||
* @return string | |||
*/ | |||
public function getStrInfos($day) | |||
{ | |||
$str = ''; | |||
$field = 'infos_' . $day; | |||
if (strlen($this->$field)) { | |||
$str = nl2br(Html::encode($this->$field)); | |||
$str = preg_replace('/\[select_previous_day\](.*?)\[\/select_previous_day\]/', '<a href="javascript:void(0);" class="select-previous-day">$1</a>', $str); | |||
} | |||
return $str; | |||
} | |||
/** | |||
* Retourne le mode de fonctionnement du crédit du point de vente. | |||
* | |||
* @return string | |||
*/ | |||
public function getCreditFunctioning() | |||
{ | |||
return strlen($this->credit_functioning) > 0 ? | |||
$this->credit_functioning : | |||
Producer::getConfig('credit_functioning'); | |||
} | |||
/** | |||
* Lie un utilisateur au point de vente. | |||
* | |||
* @param integer $idUser | |||
*/ | |||
public function linkUser($idUser) | |||
{ | |||
if ($idUser) { | |||
$userPointSale = UserPointSale::find() | |||
->where([ | |||
'id_user' => $idUser, | |||
'id_point_sale' => $this->id | |||
])->one(); | |||
if (!$userPointSale) { | |||
$userPointSale = new UserPointSale; | |||
$userPointSale->id_user = $idUser; | |||
$userPointSale->id_point_sale = $this->id; | |||
$userPointSale->save(); | |||
} | |||
} | |||
} | |||
public static function populateDropdownList() | |||
{ | |||
$pointSalesArrayDropdown = ['' => '--']; | |||
$pointSalesArray = PointSale::find()->where('id_producer = ' . GlobalParam::getCurrentProducerId())->all(); | |||
foreach ($pointSalesArray as $pointSale) { | |||
$pointSalesArrayDropdown[$pointSale['id']] = $pointSale['name']; | |||
} | |||
return $pointSalesArrayDropdown; | |||
} | |||
} |
@@ -5,10 +5,26 @@ namespace common\logic\PointSale\PointSale; | |||
use common\logic\BaseService; | |||
use common\logic\BuilderInterface; | |||
use common\logic\Order\Order\Order; | |||
use common\logic\PointSale\UserPointSale\UserPointSale; | |||
use common\logic\PointSale\UserPointSale\UserPointSaleBuilder; | |||
use common\logic\Producer\Producer\Producer; | |||
use common\logic\SolverInterface; | |||
use common\logic\User\User\User; | |||
use common\logic\User\User\UserRepository; | |||
class PointSaleBuilder extends BaseService implements BuilderInterface | |||
{ | |||
protected UserPointSaleBuilder $userPointSaleBuilder; | |||
protected UserRepository $userRepository; | |||
protected UserPointSaleRepository $userPointSaleRepository; | |||
public function __construct() | |||
{ | |||
$this->userPointSaleBuilder = $this->loadService(UserPointSaleBuilder::class); | |||
$this->userRepository = $this->loadService(UserRepository::class); | |||
$this->userPointSaleRepository = $this->loadService(UserPointSaleRepository::class); | |||
} | |||
public function instanciate(): PointSale | |||
{ | |||
$pointSale = new PointSale(); | |||
@@ -38,4 +54,58 @@ class PointSaleBuilder extends BaseService implements BuilderInterface | |||
} | |||
} | |||
} | |||
public function resetPointProductions(Producer $producer): void | |||
{ | |||
PointSale::updateAll( | |||
['point_production' => 0], | |||
['id_producer' => $producer->id] | |||
); | |||
} | |||
/** | |||
* Traite la mise à jour de l'attribut 'point_production'. | |||
*/ | |||
// processPointProduction | |||
public function updatePointProduction(PointSale $pointSale): void | |||
{ | |||
if ($pointSale->point_production) { | |||
$this->resetPointProductions($pointSale->producer); | |||
$pointSale->point_production = 1; | |||
$pointSale->save(); | |||
} | |||
} | |||
/** | |||
* Traite les accès restreints d'un point de vente. | |||
*/ | |||
public function processRestrictedAccess(PointSale $pointSale): void | |||
{ | |||
$this->userPointSaleBuilder->deleteByPointSale($pointSale); | |||
if (is_array($pointSale->users) && count($pointSale->users)) { | |||
foreach ($pointSale->users as $key => $val) { | |||
$user = $this->userRepository->getOneById($val); | |||
if ($user) { | |||
$this->userPointSaleBuilder->create($user, $pointSale, $pointSale->users_comment[$val]); | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* Lie un utilisateur au point de vente. | |||
*/ | |||
// linkUser | |||
public function addUser(User $user, PointSale $pointSale) | |||
{ | |||
$userPointSale = $this->userPointSaleRepository->getOne($user, $pointSale); | |||
if (!$userPointSale) { | |||
$this->userPointSaleBuilder->create($user, $pointSale); | |||
} | |||
} | |||
} |
@@ -6,6 +6,7 @@ use common\helpers\GlobalParam; | |||
use common\logic\BaseService; | |||
use common\logic\BuilderInterface; | |||
use common\logic\Distribution\Distribution\Distribution; | |||
use common\logic\Producer\Producer\Producer; | |||
use common\logic\RepositoryInterface; | |||
class PointSaleRepository extends BaseService implements RepositoryInterface | |||
@@ -31,4 +32,31 @@ class PointSaleRepository extends BaseService implements RepositoryInterface | |||
]) | |||
->all(); | |||
} | |||
/** | |||
* Retourne le nombre de points de vente pour le producteur courant. | |||
*/ | |||
public static function count(): int | |||
{ | |||
return PointSale::searchCount(['id_producer' => GlobalParam::getCurrentProducerId()]); | |||
} | |||
public function get() | |||
{ | |||
return PointSale::find() | |||
->where('id_producer = ' . GlobalParam::getCurrentProducerId()) | |||
->all();; | |||
} | |||
public function populateDropdownList() | |||
{ | |||
$pointSalesArrayDropdown = ['' => '--']; | |||
$pointSalesArray = $this->get(); | |||
foreach ($pointSalesArray as $pointSale) { | |||
$pointSalesArrayDropdown[$pointSale['id']] = $pointSale['name']; | |||
} | |||
return $pointSalesArrayDropdown; | |||
} | |||
} |
@@ -2,10 +2,84 @@ | |||
namespace common\logic\PointSale\PointSale; | |||
use common\helpers\GlobalParam; | |||
use common\logic\BaseService; | |||
use common\logic\SolverInterface; | |||
use yii\helpers\Html; | |||
class PointSaleSolver extends BaseService implements SolverInterface | |||
{ | |||
/** | |||
* Retourne le commentaire de l'utilisateur courant lié au point de vente. | |||
*/ | |||
public function getComment(PointSale $pointSale): ?string | |||
{ | |||
if (isset($pointSale->userPointSale)) { | |||
foreach ($pointSale->userPointSale as $userPointSale) { | |||
if ($userPointSale->id_user == GlobalParam::getCurrentUserId()) { | |||
return $userPointSale->comment; | |||
} | |||
} | |||
} | |||
return null; | |||
} | |||
/** | |||
* Vérifie le code d'accès à un point de vente. | |||
*/ | |||
public function validateCode(PointSale $pointSale, string $code): bool | |||
{ | |||
if (strlen($pointSale->code)) { | |||
if (trim(strtolower($code)) == trim(strtolower($pointSale->code))) { | |||
return true; | |||
} | |||
else { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
/** | |||
* Retourne les jours de livraison du point de vente sous forme d'une chaine | |||
* de caractères. | |||
*/ | |||
public function getStrDeliveryDays(PointSale $pointSale): string | |||
{ | |||
$str = ''; | |||
if ($pointSale->delivery_monday) $str .= 'lundi, '; | |||
if ($pointSale->delivery_tuesday) $str .= 'mardi, '; | |||
if ($pointSale->delivery_wednesday) $str .= 'mercredi, '; | |||
if ($pointSale->delivery_thursday) $str .= 'jeudi, '; | |||
if ($pointSale->delivery_friday) $str .= 'vendredi, '; | |||
if ($pointSale->delivery_saturday) $str .= 'samedi, '; | |||
if ($pointSale->delivery_sunday) $str .= 'dimanche, '; | |||
if (strlen($str)) { | |||
return substr($str, 0, strlen($str) - 2); | |||
} else { | |||
return ''; | |||
} | |||
} | |||
/** | |||
* Retourne un commentaire informant l'utilisateur sur les détails de | |||
* livraison d'un point de vente et pour un jour donné. | |||
*/ | |||
public function getStrInfos(PointSale $pointSale, string $day): string | |||
{ | |||
$str = ''; | |||
$field = 'infos_' . $day; | |||
if (strlen($pointSale->$field)) { | |||
$str = nl2br(Html::encode($pointSale->$field)); | |||
$str = preg_replace('/\[select_previous_day\](.*?)\[\/select_previous_day\]/', '<a href="javascript:void(0);" class="select-previous-day">$1</a>', $str); | |||
} | |||
return $str; | |||
} | |||
} |
@@ -38,11 +38,11 @@ termes. | |||
namespace common\logic\PointSale\UserPointSale; | |||
use Yii; | |||
use common\logic\PointSale\PointSale\PointSale; | |||
use common\components\ActiveRecordCommon ; | |||
/** | |||
* This is the model class for table "point_vente_user". | |||
* This is the model class for table "user_point_sale". | |||
* | |||
*/ | |||
class UserPointSale extends ActiveRecordCommon | |||
@@ -81,20 +81,6 @@ class UserPointSale extends ActiveRecordCommon | |||
public function getPointSale() | |||
{ | |||
return $this->hasOne(PointSale::className(), ['id' => 'id_point_sale']); | |||
} | |||
/** | |||
* 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' => '' | |||
] ; | |||
return $this->hasOne(PointSale::class, ['id' => 'id_point_sale']); | |||
} | |||
} |
@@ -4,13 +4,37 @@ namespace common\logic\PointSale\UserPointSale; | |||
use common\logic\BaseService; | |||
use common\logic\BuilderInterface; | |||
use common\logic\PointSale\PointSale\PointSale; | |||
use common\logic\User\User\User; | |||
class UserPointSaleBuilder extends BaseService implements BuilderInterface | |||
{ | |||
public function instanciate(): UserPointSale | |||
public function instanciate(User $user, PointSale $pointSale, string $comment = null): UserPointSale | |||
{ | |||
$userPointSale = new UserPointSale(); | |||
$userPointSale->id_user = $user->id; | |||
$userPointSale->populateRelation('user', $user); | |||
$userPointSale->id_point_sale = $pointSale->id; | |||
$userPointSale->populateRelation('pointSale', $pointSale); | |||
if($comment) { | |||
$userPointSale->comment = $comment; | |||
} | |||
return $userPointSale; | |||
} | |||
public function create(User $user, PointSale $pointSale, string $comment = null): UserPointSale | |||
{ | |||
$userPointSale = $this->instanciate($user, $pointSale, $comment); | |||
$userPointSale->save(); | |||
return $userPointSale; | |||
} | |||
public function deleteByPointSale(PointSale $pointSale): void | |||
{ | |||
UserPointSale::deleteAll(['id_point_sale' => $pointSale->id]); | |||
} | |||
} |
@@ -4,9 +4,28 @@ namespace common\logic\PointSale\PointSale; | |||
use common\logic\BaseService; | |||
use common\logic\BuilderInterface; | |||
use common\logic\PointSale\UserPointSale\UserPointSale; | |||
use common\logic\RepositoryInterface; | |||
use common\logic\User\User\User; | |||
class UserPointSaleRepository extends BaseService implements RepositoryInterface | |||
{ | |||
public function defaultOptionsSearch(): array | |||
{ | |||
return [ | |||
'with' => [], | |||
'join_with' => [], | |||
'orderby' => '', | |||
'attribute_id_producer' => '' | |||
] ; | |||
} | |||
public function getOne(User $user, PointSale $pointSale) | |||
{ | |||
return UserPointSale::find() | |||
->where([ | |||
'id_user' => $user->id, | |||
'id_point_sale' => $pointSale->id | |||
])->one(); | |||
} | |||
} |
@@ -7,6 +7,7 @@ use common\helpers\GlobalParam; | |||
use common\helpers\Price; | |||
use common\logic\BaseService; | |||
use common\logic\Document\Document\DocumentInterface; | |||
use common\logic\PointSale\PointSale\PointSale; | |||
use common\logic\Producer\ProducerPriceRange\ProducerPriceRange; | |||
use common\logic\Producer\ProducerPriceRange\ProducerPriceRangeRepository; | |||
use common\logic\RepositoryInterface; | |||
@@ -256,4 +257,15 @@ class ProducerRepository extends BaseService implements RepositoryInterface | |||
$this->getConfig('document_display_orders_invoice') : | |||
$this->getConfig('document_display_orders_delivery_note'); | |||
} | |||
/** | |||
* Retourne le mode de fonctionnement du crédit d'un point de vente. | |||
*/ | |||
// getCreditFunctioning | |||
public function getPointSaleCreditFunctioning(PointSale $pointSale): string | |||
{ | |||
return strlen($pointSale->credit_functioning) > 0 ? | |||
$pointSale->credit_functioning : | |||
$this->getConfig('credit_functioning'); | |||
} | |||
} |
@@ -41,7 +41,13 @@ namespace common\logic\Product\Product; | |||
use common\helpers\Debug; | |||
use common\helpers\GlobalParam; | |||
use common\helpers\Price; | |||
use common\logic\Config\TaxRate\TaxRate; | |||
use common\logic\Distribution\ProductDistribution\ProductDistribution; | |||
use common\logic\Producer\Producer\Producer; | |||
use common\logic\Product\ProductCategory\ProductCategory; | |||
use common\logic\Product\ProductPointSale\ProductPointSale; | |||
use common\logic\Product\ProductPrice\ProductPrice; | |||
use common\logic\Subscription\ProductSubscription\ProductSubscription; | |||
use Yii; | |||
use common\components\ActiveRecordCommon; | |||
@@ -188,293 +194,40 @@ class Product extends ActiveRecordCommon | |||
public function getProductDistribution() | |||
{ | |||
return $this->hasMany(ProductDistributionModel::className(), ['id_product' => 'id']); | |||
return $this->hasMany(ProductDistribution::class, ['id_product' => 'id']); | |||
} | |||
public function getProductSubscription() | |||
{ | |||
return $this->hasMany( ProductSubscription::className(), ['id_product' => 'id']); | |||
return $this->hasMany(ProductSubscription::class, ['id_product' => 'id']); | |||
} | |||
public function getTaxRate() | |||
{ | |||
return $this->hasOne(TaxRate::className(), ['id' => 'id_tax_rate']); | |||
return $this->hasOne(TaxRate::class, ['id' => 'id_tax_rate']); | |||
} | |||
public function getProductPrice() | |||
{ | |||
return $this->hasMany( ProductPrice::className(), ['id_product' => 'id']); | |||
return $this->hasMany( ProductPrice::class, ['id_product' => 'id']); | |||
} | |||
public function getProductCategory() | |||
{ | |||
return $this->hasOne( ProductCategory::className(), ['id' => 'id_product_category']); | |||
return $this->hasOne( ProductCategory::class, ['id' => 'id_product_category']); | |||
} | |||
public function getProductPointSale() | |||
{ | |||
return $this->hasMany(ProductPointSale::className(), ['id_product' => 'id']); | |||
} | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
* | |||
* @return array | |||
*/ | |||
public static function defaultOptionsSearch() | |||
{ | |||
return [ | |||
'with' => ['taxRate', 'productPointSale'], | |||
'join_with' => [], | |||
'orderby' => 'order ASC', | |||
'attribute_id_producer' => 'product.id_producer' | |||
]; | |||
} | |||
public function isAvailableOnPointSale($pointSale) | |||
{ | |||
// disponible par défaut | |||
if ($this->available_on_points_sale) { | |||
foreach ($this->productPointSale as $productPointSale) { | |||
if (isset($pointSale->id) | |||
&& $productPointSale->id_point_sale | |||
&& $pointSale->id == $productPointSale->id_point_sale | |||
&& !$productPointSale->available) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} // indisponible par défaut | |||
else { | |||
foreach ($this->productPointSale as $productPointSale) { | |||
if (isset($pointSale->id) && $pointSale->id == $productPointSale->id_point_sale | |||
&& $productPointSale->available) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
} | |||
/** | |||
* Retourne la description du produit. | |||
* | |||
* @return string | |||
*/ | |||
public function getDescription() | |||
{ | |||
$description = $this->description; | |||
if (isset($this->weight) && is_numeric($this->weight) && $this->weight > 0) { | |||
if ($this->weight >= 1000) { | |||
$description .= ' (' . ($this->weight / 1000) . 'kg)'; | |||
} else { | |||
$description .= ' (' . $this->weight . 'g)'; | |||
} | |||
} | |||
return $description; | |||
} | |||
/** | |||
* Retourne le libellé (admin) du produit. | |||
* @return type | |||
*/ | |||
public function getStrWordingAdmin() | |||
{ | |||
return $this->name; | |||
return $this->hasMany(ProductPointSale::class, ['id_product' => 'id']); | |||
} | |||
/** | |||
* Enregistre le produit. | |||
* | |||
* @param boolean $runValidation | |||
* @param array $attributeNames | |||
* @return boolean | |||
*/ | |||
public function save($runValidation = true, $attributeNames = NULL) | |||
{ | |||
$this->id_producer = GlobalParam::getCurrentProducerId(); | |||
return parent::save($runValidation, $attributeNames); | |||
} | |||
/** | |||
* Retourne les produits d'une production donnée. | |||
* | |||
* @param integer $idDistribution | |||
* @return array | |||
*/ | |||
public static function searchByDistribution($idDistribution) | |||
{ | |||
return Product::find() | |||
->leftJoin('product_distribution', 'product.id = product_distribution.id_product') | |||
->where([ | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
'product_distribution.id_distribution' => $idDistribution | |||
]) | |||
->orderBy('product_distribution.active DESC, product.order ASC') | |||
->all(); | |||
} | |||
/** | |||
* Retourne le nombre de produits du producteur courant. | |||
* | |||
* @return integer | |||
*/ | |||
public static function count() | |||
{ | |||
return self::searchCount(); | |||
} | |||
/** | |||
* Retourne le produit "Don". | |||
* | |||
* @return Product | |||
*/ | |||
public static function getProductGift() | |||
{ | |||
$productGift = Product::find() | |||
->where([ | |||
'product.id_producer' => 0 | |||
]) | |||
->andFilterWhere(['like', 'product.name', 'Don']) | |||
->one(); | |||
return $productGift; | |||
} | |||
public function getRefUnit($unit) | |||
{ | |||
if (isset(self::$unitsArray[$unit]) && isset(self::$unitsArray[$unit]['ref_unit'])) { | |||
return self::$unitsArray[$unit]['ref_unit']; | |||
} | |||
return $unit; | |||
} | |||
/** | |||
* Retourne le libellé d'une unité. | |||
* | |||
* @param $format wording_unit, wording, short | |||
* @param $unitInDb Unité stockée en base de données (ex: si g > kg, si mL > L) | |||
* @return $string Libellé de l'unité | |||
*/ | |||
public static function strUnit($unit, $format = 'wording_short', $unitInDb = false) | |||
{ | |||
$strUnit = ''; | |||
if ($unitInDb) { | |||
if ($unit == 'g') { | |||
$unit = 'kg'; | |||
} | |||
if ($unit == 'mL') { | |||
$unit = 'L'; | |||
} | |||
} | |||
if (isset(self::$unitsArray[$unit]) && isset(self::$unitsArray[$unit][$format])) { | |||
$strUnit = self::$unitsArray[$unit][$format]; | |||
} | |||
return $strUnit; | |||
} | |||
public function getPriceArray($user, $pointSale) | |||
{ | |||
$priceArray = []; | |||
$userProducer = null; | |||
if ($user) { | |||
$userProducer = UserProducer::searchOne([ | |||
'id_user' => $user->id, | |||
]); | |||
} | |||
// specific prices | |||
$specificPriceArray = $this->getSpecificPricesFilterByPriorityMatch( | |||
$this->productPrice, | |||
$user, | |||
$pointSale | |||
); | |||
foreach ($specificPriceArray as $specificPrice) { | |||
$priceArray[] = [ | |||
'from_quantity' => $specificPrice->from_quantity ? $specificPrice->from_quantity : 0, | |||
'price' => number_format($this->getPrice([ | |||
'user' => $user, | |||
'user_producer' => $userProducer, | |||
'point_sale' => $pointSale, | |||
'quantity' => $specificPrice->from_quantity | |||
]), 3), | |||
'price_with_tax' => number_format($this->getPriceWithTax([ | |||
'user' => $user, | |||
'user_producer' => $userProducer, | |||
'point_sale' => $pointSale, | |||
'quantity' => $specificPrice->from_quantity | |||
]), 2), | |||
]; | |||
} | |||
if (!$this->hasPriceWithQuantityZero($priceArray)) { | |||
// base price | |||
$priceArray[] = [ | |||
'from_quantity' => 0, | |||
'price' => $this->getPrice(), | |||
'price_with_tax' => $this->getPriceWithTax(), | |||
]; | |||
} | |||
usort($priceArray, function ($a, $b) { | |||
if ($a['price'] < $b['price']) { | |||
return 1; | |||
} elseif ($a['price'] > $b['price']) { | |||
return -1; | |||
} else { | |||
return 0; | |||
} | |||
}); | |||
return $priceArray; | |||
} | |||
public function hasPriceWithQuantityZero($priceArray) | |||
{ | |||
foreach ($priceArray as $price) { | |||
if ($price['from_quantity'] == 0) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
/** | |||
* Retourne le prix du produit avec taxe | |||
*/ | |||
public function getPriceWithTax($params = []) | |||
{ | |||
$taxRateValue = $this->taxRate ? $this->taxRate->value : 0; | |||
return Price::getPriceWithTax($this->getPrice($params), $taxRateValue); | |||
} | |||
public function getTheTaxRate() | |||
{ | |||
if ($this->id_tax_rate) { | |||
return $this->id_tax_rate; | |||
} else { | |||
return GlobalParam::getCurrentProducer()->taxRate->id; | |||
} | |||
} | |||
public function getNameExport() | |||
{ | |||
$producer = GlobalParam::getCurrentProducer(); | |||
if ($producer->option_export_display_product_reference && $this->reference && strlen($this->reference) > 0) { | |||
return $this->reference; | |||
} | |||
return $this->name; | |||
} | |||
} |
@@ -2,13 +2,119 @@ | |||
namespace common\logic\Product\Product; | |||
use common\helpers\GlobalParam; | |||
use common\logic\BaseService; | |||
use common\logic\Distribution\Distribution\Distribution; | |||
use common\logic\PointSale\PointSale\PointSale; | |||
use common\logic\Product\ProductPrice\ProductPriceSolver; | |||
use common\logic\RepositoryInterface; | |||
use common\logic\User\User\User; | |||
use common\logic\User\UserProducer\UserProducerRepository; | |||
class ProductRepository extends BaseService implements RepositoryInterface | |||
{ | |||
protected ProductSolver $productSolver; | |||
protected ProductPriceSolver $productPriceSolver; | |||
protected UserProducerRepository $userProducerRepository; | |||
public function __construct() | |||
{ | |||
$this->productSolver = $this->loadService(ProductSolver::class); | |||
$this->productPriceSolver = $this->loadService(ProductPriceSolver::class); | |||
$this->userProducerRepository = $this->loadService(UserProducerRepository::class); | |||
} | |||
public function defaultOptionsSearch(): array | |||
{ | |||
return [ | |||
'with' => ['taxRate', 'productPointSale'], | |||
'join_with' => [], | |||
'orderby' => 'order ASC', | |||
'attribute_id_producer' => 'product.id_producer' | |||
]; | |||
} | |||
public function get(): array | |||
{ | |||
return Product::searchAll(); | |||
} | |||
/** | |||
* Retourne le nombre de produits du producteur courant. | |||
*/ | |||
public static function count(): int | |||
{ | |||
return Product::searchCount(); | |||
} | |||
/** | |||
* Retourne les produits d'une production donnée. | |||
*/ | |||
// searchByDistribution | |||
public function getByDistribution(Distribution $distribution) | |||
{ | |||
return Product::find() | |||
->leftJoin('product_distribution', 'product.id = product_distribution.id_product') | |||
->where([ | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
'product_distribution.id_distribution' => $distribution->id | |||
]) | |||
->orderBy('product_distribution.active DESC, product.order ASC') | |||
->all(); | |||
} | |||
public function getPriceArray(Product $product, User $user, PointSale $pointSale): array | |||
{ | |||
$priceArray = []; | |||
$userProducer = null; | |||
if ($user) { | |||
$userProducer = $this->userProducerRepository->getOne($user, GlobalParam::getCurrentProducer()); | |||
} | |||
// specific prices | |||
$specificPriceArray = $this->productPriceSolver->filterByPriorityMatch( | |||
$product->productPrice, | |||
$user, | |||
$pointSale | |||
); | |||
foreach ($specificPriceArray as $specificPrice) { | |||
$priceArray[] = [ | |||
'from_quantity' => $specificPrice->from_quantity ? $specificPrice->from_quantity : 0, | |||
'price' => number_format($this->productSolver->getPrice($product, [ | |||
'user' => $user, | |||
'user_producer' => $userProducer, | |||
'point_sale' => $pointSale, | |||
'quantity' => $specificPrice->from_quantity | |||
]), 3), | |||
'price_with_tax' => number_format($this->productSolver->getPriceWithTax($product, [ | |||
'user' => $user, | |||
'user_producer' => $userProducer, | |||
'point_sale' => $pointSale, | |||
'quantity' => $specificPrice->from_quantity | |||
]), 2), | |||
]; | |||
} | |||
if (!$this->productSolver->hasPriceWithQuantityZero($priceArray)) { | |||
// base price | |||
$priceArray[] = [ | |||
'from_quantity' => 0, | |||
'price' => $this->productSolver->getPrice($product), | |||
'price_with_tax' => $this->productSolver->getPriceWithTax($product), | |||
]; | |||
} | |||
usort($priceArray, function ($a, $b) { | |||
if ($a['price'] < $b['price']) { | |||
return 1; | |||
} elseif ($a['price'] > $b['price']) { | |||
return -1; | |||
} else { | |||
return 0; | |||
} | |||
}); | |||
return $priceArray; | |||
} | |||
} |
@@ -2,11 +2,12 @@ | |||
namespace common\logic\Product\Product; | |||
use common\helpers\GlobalParam; | |||
use common\helpers\Price; | |||
use common\logic\BaseService; | |||
use common\logic\PointSale\PointSale\PointSale; | |||
use common\logic\Product\ProductPrice\ProductPriceSolver; | |||
use common\logic\SolverInterface; | |||
use common\logic\User\User\User; | |||
class ProductSolver extends BaseService implements SolverInterface | |||
{ | |||
@@ -56,4 +57,130 @@ class ProductSolver extends BaseService implements SolverInterface | |||
return $product->price; | |||
} | |||
/** | |||
* Retourne le prix du produit avec taxe | |||
*/ | |||
public function getPriceWithTax(Product $product, $params = []) | |||
{ | |||
$taxRateValue = $product->taxRate ? $product->taxRate->value : 0; | |||
return Price::getPriceWithTax($this->getPrice($product, $params), $taxRateValue); | |||
} | |||
public function isAvailableOnPointSale(Product $product, PointSale $pointSale): bool | |||
{ | |||
// disponible par défaut | |||
if ($product->available_on_points_sale) { | |||
foreach ($product->productPointSale as $productPointSale) { | |||
if (isset($pointSale->id) | |||
&& $productPointSale->id_point_sale | |||
&& $pointSale->id == $productPointSale->id_point_sale | |||
&& !$productPointSale->available) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} // indisponible par défaut | |||
else { | |||
foreach ($product->productPointSale as $productPointSale) { | |||
if (isset($pointSale->id) && $pointSale->id == $productPointSale->id_point_sale | |||
&& $productPointSale->available) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
} | |||
/** | |||
* Retourne la description du produit. | |||
*/ | |||
public function getDescription(Product $product): string | |||
{ | |||
$description = $product->description; | |||
if (isset($product->weight) && is_numeric($product->weight) && $product->weight > 0) { | |||
if ($product->weight >= 1000) { | |||
$description .= ' (' . ($product->weight / 1000) . 'kg)'; | |||
} else { | |||
$description .= ' (' . $product->weight . 'g)'; | |||
} | |||
} | |||
return $description; | |||
} | |||
/** | |||
* Retourne le libellé (admin) du produit. | |||
*/ | |||
public function getStrWordingAdmin(Product $product): string | |||
{ | |||
return $product->name; | |||
} | |||
public function getRefUnit(string $unit): string | |||
{ | |||
if (isset(Product::$unitsArray[$unit]) && isset(Product::$unitsArray[$unit]['ref_unit'])) { | |||
return Product::$unitsArray[$unit]['ref_unit']; | |||
} | |||
return $unit; | |||
} | |||
/** | |||
* Retourne le libellé d'une unité. | |||
*/ | |||
public function strUnit(string $unit, $format = 'wording_short', $unitInDb = false): string | |||
{ | |||
$strUnit = ''; | |||
if ($unitInDb) { | |||
if ($unit == 'g') { | |||
$unit = 'kg'; | |||
} | |||
if ($unit == 'mL') { | |||
$unit = 'L'; | |||
} | |||
} | |||
if (isset(Product::$unitsArray[$unit]) && isset(Product::$unitsArray[$unit][$format])) { | |||
$strUnit = Product::$unitsArray[$unit][$format]; | |||
} | |||
return $strUnit; | |||
} | |||
public function hasPriceWithQuantityZero(array $priceArray): bool | |||
{ | |||
foreach ($priceArray as $price) { | |||
if ($price['from_quantity'] == 0) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
public function getTheTaxRate(Product $product) | |||
{ | |||
if ($product->id_tax_rate) { | |||
return $product->id_tax_rate; | |||
} else { | |||
return GlobalParam::getCurrentProducer()->taxRate->id; | |||
} | |||
} | |||
public function getNameExport(Product $product) | |||
{ | |||
$producer = GlobalParam::getCurrentProducer(); | |||
if ($producer->option_export_display_product_reference | |||
&& $product->reference | |||
&& strlen($product->reference) > 0) | |||
{ | |||
return $product->reference; | |||
} | |||
return $product->name; | |||
} | |||
} |
@@ -47,62 +47,34 @@ use common\components\ActiveRecordCommon; | |||
*/ | |||
class ProductCategory extends ActiveRecordCommon | |||
{ | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public static function tableName() | |||
{ | |||
return 'product_category'; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public static function tableName() | |||
{ | |||
return 'product_category'; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function rules() | |||
{ | |||
return [ | |||
[['name'], 'required'], | |||
[['name'], 'string'], | |||
[['position'], 'integer'], | |||
]; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function attributeLabels() | |||
{ | |||
return [ | |||
'name' => 'Nom', | |||
'position' => 'Position' | |||
]; | |||
} | |||
/** | |||
* 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' => '' | |||
]; | |||
} | |||
public static function populateDropdownList() | |||
{ | |||
$productCategoriesArrayDropdown = ['' => '--']; | |||
$productCategoriesArray = ProductCategory::find()->where('id_producer = ' . GlobalParam::getCurrentProducerId())->all(); | |||
foreach ($productCategoriesArray as $productCategory) { | |||
$productCategoriesArrayDropdown[$productCategory['id']] = $productCategory['name']; | |||
} | |||
return $productCategoriesArrayDropdown; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function rules() | |||
{ | |||
return [ | |||
[['name'], 'required'], | |||
[['name'], 'string'], | |||
[['position'], 'integer'], | |||
]; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function attributeLabels() | |||
{ | |||
return [ | |||
'name' => 'Nom', | |||
'position' => 'Position' | |||
]; | |||
} | |||
} |
@@ -2,10 +2,36 @@ | |||
namespace common\logic\Product\ProductCategory; | |||
use common\helpers\GlobalParam; | |||
use common\logic\BaseService; | |||
use common\logic\RepositoryInterface; | |||
class ProductCategoryRepository extends BaseService implements RepositoryInterface | |||
{ | |||
public function defaultOptionsSearch(): array | |||
{ | |||
return [ | |||
'with' => [], | |||
'join_with' => [], | |||
'orderby' => '', | |||
'attribute_id_producer' => '' | |||
]; | |||
} | |||
public function get() | |||
{ | |||
return ProductCategory::find()->where('id_producer = ' . GlobalParam::getCurrentProducerId())->all(); | |||
} | |||
public function populateDropdownList() | |||
{ | |||
$productCategoriesArrayDropdown = ['' => '--']; | |||
$productCategoriesArray = $this->get(); | |||
foreach ($productCategoriesArray as $productCategory) { | |||
$productCategoriesArrayDropdown[$productCategory['id']] = $productCategory['name']; | |||
} | |||
return $productCategoriesArrayDropdown; | |||
} | |||
} |
@@ -39,6 +39,8 @@ termes. | |||
namespace common\logic\Product\ProductPointSale; | |||
use common\components\ActiveRecordCommon ; | |||
use common\logic\PointSale\PointSale\PointSale; | |||
use common\logic\Product\Product\Product; | |||
/** | |||
* This is the model class for table "product_point_sale". | |||
@@ -84,25 +86,11 @@ class ProductPointSale extends ActiveRecordCommon | |||
public function getProduct() | |||
{ | |||
return $this->hasOne( Product::className(), ['id' => 'id_product']); | |||
return $this->hasOne( Product::class, ['id' => 'id_product']); | |||
} | |||
public function getPointSale() | |||
{ | |||
return $this->hasOne(PointSale::className(), ['id' => 'id_point_sale']); | |||
} | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
* | |||
* @return array | |||
*/ | |||
public static function defaultOptionsSearch() { | |||
return [ | |||
'with' => ['product', 'pointSale'], | |||
'join_with' => [], | |||
'orderby' => '', | |||
'attribute_id_producer' => '' | |||
] ; | |||
return $this->hasOne(PointSale::class, ['id' => 'id_point_sale']); | |||
} | |||
} |
@@ -7,5 +7,13 @@ use common\logic\RepositoryInterface; | |||
class ProductPointSaleRepository extends BaseService implements RepositoryInterface | |||
{ | |||
public function defaultOptionsSearch(): array | |||
{ | |||
return [ | |||
'with' => ['product', 'pointSale'], | |||
'join_with' => [], | |||
'orderby' => '', | |||
'attribute_id_producer' => '' | |||
] ; | |||
} | |||
} |
@@ -39,6 +39,10 @@ | |||
namespace common\logic\Product\ProductPrice; | |||
use common\components\ActiveRecordCommon; | |||
use common\logic\PointSale\PointSale\PointSale; | |||
use common\logic\Product\Product\Product; | |||
use common\logic\User\User\User; | |||
use common\logic\User\UserGroup\UserGroup; | |||
/** | |||
* This is the model class for table "product_price". | |||
@@ -62,41 +66,41 @@ class ProductPrice extends ActiveRecordCommon | |||
public function rules() | |||
{ | |||
return [ | |||
[ | |||
'id_user', | |||
'required', | |||
'when' => function ($model) { | |||
return !$model->id_point_sale && !$model->id_user_group && !$model->from_quantity; | |||
}, | |||
'message' => 'Vous devez renseigner au moins un utilisateur, un point de vente, un groupe d\'utilisateur ou une quantité' | |||
], | |||
[ | |||
'id_point_sale', | |||
'required', | |||
'when' => function ($model) { | |||
return !$model->id_user && !$model->id_user_group && !$model->from_quantity; | |||
}, | |||
'message' => 'Vous devez renseigner au moins un utilisateur, un point de vente, un groupe d\'utilisateur ou une quantité' | |||
], | |||
[ | |||
'id_user_group', | |||
'required', | |||
'when' => function ($model) { | |||
return !$model->id_user && !$model->id_point_sale && !$model->from_quantity; | |||
}, | |||
'message' => 'Vous devez renseigner au moins un utilisateur, un point de vente, un groupe d\'utilisateur ou une quantité' | |||
], | |||
[ | |||
'from_quantity', | |||
'required', | |||
'when' => function ($model) { | |||
return !$model->id_user && !$model->id_user_group && !$model->id_point_sale; | |||
}, | |||
'message' => 'Vous devez renseigner au moins un utilisateur, un point de vente, un groupe d\'utilisateur ou une quantité' | |||
], | |||
[['id_product', 'price'], 'required'], | |||
[['id_product', 'id_user', 'id_point_sale', 'id_user_group', 'percent'], 'integer'], | |||
[['price', 'from_quantity'], 'double'], | |||
[ | |||
'id_user', | |||
'required', | |||
'when' => function ($model) { | |||
return !$model->id_point_sale && !$model->id_user_group && !$model->from_quantity; | |||
}, | |||
'message' => 'Vous devez renseigner au moins un utilisateur, un point de vente, un groupe d\'utilisateur ou une quantité' | |||
], | |||
[ | |||
'id_point_sale', | |||
'required', | |||
'when' => function ($model) { | |||
return !$model->id_user && !$model->id_user_group && !$model->from_quantity; | |||
}, | |||
'message' => 'Vous devez renseigner au moins un utilisateur, un point de vente, un groupe d\'utilisateur ou une quantité' | |||
], | |||
[ | |||
'id_user_group', | |||
'required', | |||
'when' => function ($model) { | |||
return !$model->id_user && !$model->id_point_sale && !$model->from_quantity; | |||
}, | |||
'message' => 'Vous devez renseigner au moins un utilisateur, un point de vente, un groupe d\'utilisateur ou une quantité' | |||
], | |||
[ | |||
'from_quantity', | |||
'required', | |||
'when' => function ($model) { | |||
return !$model->id_user && !$model->id_user_group && !$model->id_point_sale; | |||
}, | |||
'message' => 'Vous devez renseigner au moins un utilisateur, un point de vente, un groupe d\'utilisateur ou une quantité' | |||
], | |||
[['id_product', 'price'], 'required'], | |||
[['id_product', 'id_user', 'id_point_sale', 'id_user_group', 'percent'], 'integer'], | |||
[['price', 'from_quantity'], 'double'], | |||
]; | |||
} | |||
@@ -106,14 +110,14 @@ class ProductPrice extends ActiveRecordCommon | |||
public function attributeLabels() | |||
{ | |||
return [ | |||
'id' => 'ID', | |||
'id_product' => 'Produit', | |||
'id_user' => 'Utilisateur', | |||
'id_point_sale' => 'Point de vente', | |||
'id_user_group' => "Groupe d'utilisateur", | |||
'price' => 'Prix (HT)', | |||
'percent' => 'Pourcentage', | |||
'from_quantity' => 'À partir de la quantité', | |||
'id' => 'ID', | |||
'id_product' => 'Produit', | |||
'id_user' => 'Utilisateur', | |||
'id_point_sale' => 'Point de vente', | |||
'id_user_group' => "Groupe d'utilisateur", | |||
'price' => 'Prix (HT)', | |||
'percent' => 'Pourcentage', | |||
'from_quantity' => 'À partir de la quantité', | |||
]; | |||
} | |||
@@ -123,61 +127,21 @@ class ProductPrice extends ActiveRecordCommon | |||
public function getProduct() | |||
{ | |||
return $this->hasOne( | |||
Product::className(), | |||
['id' => 'id_product'] | |||
); | |||
return $this->hasOne(Product::class, ['id' => 'id_product']); | |||
} | |||
public function getPointSale() | |||
{ | |||
return $this->hasOne( | |||
PointSale::className(), | |||
['id' => 'id_point_sale'] | |||
); | |||
return $this->hasOne(PointSale::class, ['id' => 'id_point_sale']); | |||
} | |||
public function getUserGroup() | |||
{ | |||
return $this->hasOne( | |||
UserGroup::className(), | |||
['id' => 'id_user_group'] | |||
); | |||
return $this->hasOne(UserGroup::class, ['id' => 'id_user_group']); | |||
} | |||
public function getUser() | |||
{ | |||
return $this->hasOne( | |||
User::className(), | |||
['id' => 'id_user'] | |||
); | |||
} | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
* | |||
* @return array | |||
*/ | |||
public static function defaultOptionsSearch() | |||
{ | |||
return [ | |||
'with' => ['user', 'pointSale'], | |||
'join_with' => ['product'], | |||
'orderby' => '', | |||
'attribute_id_producer' => 'product.id_producer' | |||
]; | |||
} | |||
public static function percentValues() | |||
{ | |||
$percentValues = [ | |||
'' => 'Aucun' | |||
]; | |||
for ($i = -50; $i < 51; $i = $i + 5) { | |||
$percentValues[$i] = $i . ' %'; | |||
} | |||
return $percentValues; | |||
return $this->hasOne(User::class, ['id' => 'id_user']); | |||
} | |||
} |
@@ -7,5 +7,16 @@ use common\logic\RepositoryInterface; | |||
class ProductPriceRepository extends BaseService implements RepositoryInterface | |||
{ | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
*/ | |||
public function defaultOptionsSearch(): array | |||
{ | |||
return [ | |||
'with' => ['user', 'pointSale'], | |||
'join_with' => ['product'], | |||
'orderby' => '', | |||
'attribute_id_producer' => 'product.id_producer' | |||
]; | |||
} | |||
} |
@@ -121,4 +121,17 @@ class ProductPriceSolver extends BaseService implements SolverInterface | |||
&& !$productPrice->id_user_group | |||
&& $productPrice->from_quantity; | |||
} | |||
public function percentValues(): array | |||
{ | |||
$percentValues = [ | |||
'' => 'Aucun' | |||
]; | |||
for ($i = -50; $i < 51; $i = $i + 5) { | |||
$percentValues[$i] = $i . ' %'; | |||
} | |||
return $percentValues; | |||
} | |||
} |
@@ -1,44 +1,45 @@ | |||
<?php | |||
/** | |||
Copyright distrib (2018) | |||
contact@opendistrib.net | |||
Ce logiciel est un programme informatique servant à aider les producteurs | |||
à distribuer leur production en circuits courts. | |||
Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||
respectant les principes de diffusion des logiciels libres. Vous pouvez | |||
utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||
sur le site "http://www.cecill.info". | |||
En contrepartie de l'accessibilité au code source et des droits de copie, | |||
de modification et de redistribution accordés par cette licence, il n'est | |||
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||
seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||
titulaire des droits patrimoniaux et les concédants successifs. | |||
A cet égard l'attention de l'utilisateur est attirée sur les risques | |||
associés au chargement, à l'utilisation, à la modification et/ou au | |||
développement et à la reproduction du logiciel par l'utilisateur étant | |||
donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||
manipuler et qui le réserve donc à des développeurs et des professionnels | |||
avertis possédant des connaissances informatiques approfondies. Les | |||
utilisateurs sont donc invités à charger et tester l'adéquation du | |||
logiciel à leurs besoins dans des conditions permettant d'assurer la | |||
sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||
pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||
termes. | |||
*/ | |||
/** | |||
* Copyright distrib (2018) | |||
* | |||
* contact@opendistrib.net | |||
* | |||
* Ce logiciel est un programme informatique servant à aider les producteurs | |||
* à distribuer leur production en circuits courts. | |||
* | |||
* Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||
* respectant les principes de diffusion des logiciels libres. Vous pouvez | |||
* utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||
* sur le site "http://www.cecill.info". | |||
* | |||
* En contrepartie de l'accessibilité au code source et des droits de copie, | |||
* de modification et de redistribution accordés par cette licence, il n'est | |||
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||
* seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||
* titulaire des droits patrimoniaux et les concédants successifs. | |||
* | |||
* A cet égard l'attention de l'utilisateur est attirée sur les risques | |||
* associés au chargement, à l'utilisation, à la modification et/ou au | |||
* développement et à la reproduction du logiciel par l'utilisateur étant | |||
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||
* manipuler et qui le réserve donc à des développeurs et des professionnels | |||
* avertis possédant des connaissances informatiques approfondies. Les | |||
* utilisateurs sont donc invités à charger et tester l'adéquation du | |||
* logiciel à leurs besoins dans des conditions permettant d'assurer la | |||
* sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||
* | |||
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||
* pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||
* termes. | |||
*/ | |||
namespace common\logic\Subscription\ProductSubscription; | |||
use common\components\ActiveRecordCommon ; | |||
use common\components\ActiveRecordCommon; | |||
use common\logic\Product\Product\Product; | |||
/** | |||
* This is the model class for table "commande_auto_produit". | |||
@@ -50,7 +51,7 @@ class ProductSubscription extends ActiveRecordCommon | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public static function tableName() | |||
public static function tableName() | |||
{ | |||
return 'product_subscription'; | |||
} | |||
@@ -58,7 +59,7 @@ class ProductSubscription extends ActiveRecordCommon | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function rules() | |||
public function rules() | |||
{ | |||
return [ | |||
[['id_subscription', 'id_product'], 'required'], | |||
@@ -70,7 +71,7 @@ class ProductSubscription extends ActiveRecordCommon | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function attributeLabels() | |||
public function attributeLabels() | |||
{ | |||
return [ | |||
'id' => 'ID', | |||
@@ -83,24 +84,9 @@ class ProductSubscription extends ActiveRecordCommon | |||
/* | |||
* Relations | |||
*/ | |||
public function getProduct() | |||
public function getProduct() | |||
{ | |||
return $this->hasOne( Product::className(), ['id' => 'id_product']); | |||
return $this->hasOne(Product::class, ['id' => 'id_product']); | |||
} | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
* | |||
* @return array | |||
*/ | |||
public static function defaultOptionsSearch() { | |||
return [ | |||
'with' => ['product'], | |||
'join_with' => [], | |||
'orderby' => '', | |||
'attribute_id_producer' => '' | |||
] ; | |||
} | |||
} |
@@ -0,0 +1,22 @@ | |||
<?php | |||
namespace common\logic\Subscription\ProductSubscription; | |||
use common\logic\BaseService; | |||
use common\logic\RepositoryInterface; | |||
class ProductSubscriptionRepository extends BaseService implements RepositoryInterface | |||
{ | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
*/ | |||
public function defaultOptionsSearch(): array | |||
{ | |||
return [ | |||
'with' => ['product'], | |||
'join_with' => [], | |||
'orderby' => '', | |||
'attribute_id_producer' => '' | |||
]; | |||
} | |||
} |
@@ -39,7 +39,9 @@ | |||
namespace common\logic\Subscription\Subscription; | |||
use common\helpers\GlobalParam; | |||
use common\logic\PointSale\PointSale\PointSale; | |||
use common\logic\Producer\Producer\Producer; | |||
use common\logic\Subscription\ProductSubscription\ProductSubscription; | |||
use common\logic\User\CreditHistory\CreditHistory; | |||
use common\logic\User\UserProducer\UserProducer; | |||
use Yii; | |||
@@ -47,8 +49,7 @@ use common\components\ActiveRecordCommon; | |||
use common\logic\User\User\User; | |||
/** | |||
* This is the model class for table "commande_auto". | |||
* | |||
* This is the model class for table "subscription". | |||
*/ | |||
class Subscription extends ActiveRecordCommon | |||
{ | |||
@@ -121,156 +122,13 @@ class Subscription extends ActiveRecordCommon | |||
public function getPointSale() | |||
{ | |||
return $this->hasOne( | |||
PointSale::class, | |||
['id' => 'id_point_sale'] | |||
); | |||
return $this->hasOne(PointSale::class, ['id' => 'id_point_sale']); | |||
} | |||
public function getProductSubscription() | |||
{ | |||
return $this->hasMany( | |||
ProductSubscription::class, | |||
['id_subscription' => 'id'] | |||
)->with('product'); | |||
} | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
* | |||
* @return array | |||
*/ | |||
public static function defaultOptionsSearch() | |||
{ | |||
return [ | |||
'with' => ['producer'], | |||
'join_with' => ['user', 'productSubscription', 'productSubscription.product', 'pointSale'], | |||
'orderby' => 'user.name ASC', | |||
'attribute_id_producer' => 'subscription.id_producer' | |||
]; | |||
} | |||
/** | |||
* Ajoute la commande pour une date donnée. | |||
* | |||
* @param string $date | |||
*/ | |||
public function add($date, $force = false) | |||
{ | |||
// distribution | |||
$now = date('Y-m-d'); | |||
$distributionDate = date('Y-m-d', strtotime($date)); | |||
$distribution = DistributionModel::searchOne([ | |||
'distribution.date' => $distributionDate | |||
]); | |||
if ($distribution | |||
&& $distribution->active | |||
&& ($distributionDate > $now || $force) | |||
&& count($this->productSubscription) | |||
&& $this->id_point_sale) { | |||
// commande | |||
$order = new Order; | |||
if (strlen($this->username)) { | |||
$order->username = $this->username; | |||
$order->id_user = 0; | |||
} else { | |||
$order->id_user = $this->id_user; | |||
} | |||
$user = false; | |||
if ($this->id_user) { | |||
$user = User::findOne($this->id_user); | |||
} | |||
$order->date = date('Y-m-d H:i:s'); | |||
$order->origin = Order::ORIGIN_AUTO; | |||
$order->id_point_sale = $this->id_point_sale; | |||
$order->id_distribution = $distribution->id; | |||
$order->id_subscription = $this->id; | |||
$order->status = 'tmp-order'; | |||
if (strlen($this->comment)) { | |||
$order->comment = $this->comment; | |||
} | |||
$pointSale = PointSale::findOne($this->id_point_sale); | |||
if ($pointSale) { | |||
$creditFunctioning = $pointSale->getCreditFunctioning(); | |||
$order->auto_payment = 0; | |||
if($this->auto_payment == self::AUTO_PAYMENT_DEDUCTED) { | |||
if ($order->id_user && Producer::getConfig('credit') && $pointSale->credit) { | |||
if ($creditFunctioning == Producer::CREDIT_FUNCTIONING_OPTIONAL) { | |||
$order->auto_payment = 0; | |||
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_MANDATORY) { | |||
$order->auto_payment = 1; | |||
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_USER) { | |||
$user = User::findOne($order->id_user); | |||
$userProducer = UserProducer::searchOne([ | |||
'id_user' => $order->id_user, | |||
'id_producer' => $distribution->id_producer | |||
]); | |||
if ($userProducer) { | |||
$order->auto_payment = $userProducer->credit_active; | |||
} | |||
} | |||
} | |||
} | |||
elseif($this->auto_payment == self::AUTO_PAYMENT_YES) { | |||
$order->auto_payment = 1; | |||
} | |||
elseif($this->auto_payment == self::AUTO_PAYMENT_NO) { | |||
$order->auto_payment = 0; | |||
} | |||
$order->tiller_synchronization = $order->auto_payment; | |||
$userPointSale = UserPointSale::searchOne([ | |||
'id_point_sale' => $this->id_point_sale, | |||
'id_user' => $this->id_user | |||
]); | |||
if ($userPointSale && strlen($userPointSale->comment)) { | |||
$order->comment_point_sale = $userPointSale->comment; | |||
} | |||
$order->save(); | |||
// liaison utilisateur / point de vente | |||
if ($order->id_user) { | |||
$pointSale = PointSale::findOne($this->id_point_sale); | |||
$pointSale->linkUser($order->id_user); | |||
} | |||
// produits | |||
$productsAdd = false; | |||
foreach ($this->productSubscription as $productSubscription) { | |||
$productOrder = new ProductOrder; | |||
$productOrder->id_order = $order->id; | |||
$productOrder->id_product = $productSubscription->product->id; | |||
$productOrder->quantity = $productSubscription->quantity; | |||
$productOrder->price = $productSubscription->product->getPrice([ | |||
'user' => $user, | |||
'point_sale' => $pointSale, | |||
'quantity' => $productSubscription->quantity | |||
]); | |||
$productOrder->unit = $productSubscription->product->unit; | |||
$productOrder->step = $productSubscription->product->step; | |||
$productOrder->id_tax_rate = $productSubscription->product->taxRate->id; | |||
$productOrder->save(); | |||
$productsAdd = true; | |||
} | |||
if (!$productsAdd) { | |||
$order->delete(); | |||
} | |||
$order->initReference(); | |||
} | |||
} | |||
return $this->hasMany(ProductSubscription::class, ['id_subscription' => 'id']) | |||
->with('product'); | |||
} | |||
/** | |||
@@ -418,7 +276,7 @@ class Subscription extends ActiveRecordCommon | |||
{ | |||
$dateStart = $this->date_begin; | |||
$comparatorDateStart = '>='; | |||
if($deleteAfterDateEnd) { | |||
if ($deleteAfterDateEnd) { | |||
$dateStart = $this->date_end; | |||
$comparatorDateStart = '>'; | |||
} | |||
@@ -443,7 +301,7 @@ class Subscription extends ActiveRecordCommon | |||
->joinWith('distribution') | |||
->where('distribution.id_producer = :id_producer') | |||
->andWhere($conditionDistributionDate) | |||
->andWhere('distribution.date '.$comparatorDateStart.' :date_start') | |||
->andWhere('distribution.date ' . $comparatorDateStart . ' :date_start') | |||
->andWhere('order.id_subscription = :id_subscription'); | |||
$orders->params($params); | |||
@@ -470,7 +328,7 @@ class Subscription extends ActiveRecordCommon | |||
$order->delete(true); | |||
$countOrdersDeleted ++; | |||
$countOrdersDeleted++; | |||
} | |||
} | |||
@@ -4,9 +4,22 @@ namespace common\logic\Subscription\Subscription; | |||
use common\logic\BaseService; | |||
use common\logic\BuilderInterface; | |||
use common\logic\Distribution\Distribution\Distribution; | |||
use common\logic\Distribution\Distribution\DistributionRepository; | |||
use common\logic\PointSale\PointSale\PointSale; | |||
use common\logic\Producer\Producer\Producer; | |||
use common\logic\User\User\User; | |||
use common\logic\User\UserProducer\UserProducer; | |||
class SubscriptionBuilder extends BaseService implements BuilderInterface | |||
{ | |||
protected DistributionRepository $distributionRepository; | |||
public function __construct() | |||
{ | |||
$this->distributionRepository = $this->loadService(DistributionRepository::class); | |||
} | |||
public function instanciate(): Subscription | |||
{ | |||
$subscription = new Subscription(); |
@@ -7,5 +7,16 @@ use common\logic\RepositoryInterface; | |||
class SubscriptionRepository extends BaseService implements RepositoryInterface | |||
{ | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
*/ | |||
public function defaultOptionsSearch(): array | |||
{ | |||
return [ | |||
'with' => ['producer'], | |||
'join_with' => ['user', 'productSubscription', 'productSubscription.product', 'pointSale'], | |||
'orderby' => 'user.name ASC', | |||
'attribute_id_producer' => 'subscription.id_producer' | |||
]; | |||
} | |||
} |