Browse Source

Refactoring services #885

refactoring
Guillaume 2 years ago
parent
commit
a601d8fbb5
28 changed files with 907 additions and 827 deletions
  1. +6
    -0
      common/components/ActiveRecordCommon.php
  2. +13
    -0
      common/helpers/GlobalParam.php
  3. +7
    -0
      common/logic/Distribution/Distribution/DistributionRepository.php
  4. +10
    -0
      common/logic/Order/Order/Order.php
  5. +151
    -1
      common/logic/Order/Order/OrderBuilder.php
  6. +1
    -178
      common/logic/PointSale/PointSale/PointSale.php
  7. +70
    -0
      common/logic/PointSale/PointSale/PointSaleBuilder.php
  8. +28
    -0
      common/logic/PointSale/PointSale/PointSaleRepository.php
  9. +74
    -0
      common/logic/PointSale/PointSale/PointSaleSolver.php
  10. +3
    -17
      common/logic/PointSale/UserPointSale/UserPointSale.php
  11. +25
    -1
      common/logic/PointSale/UserPointSale/UserPointSaleBuilder.php
  12. +19
    -0
      common/logic/PointSale/UserPointSale/UserPointSaleRepository.php
  13. +12
    -0
      common/logic/Producer/Producer/ProducerRepository.php
  14. +12
    -259
      common/logic/Product/Product/Product.php
  15. +106
    -0
      common/logic/Product/Product/ProductRepository.php
  16. +128
    -1
      common/logic/Product/Product/ProductSolver.php
  17. +28
    -56
      common/logic/Product/ProductCategory/ProductCategory.php
  18. +26
    -0
      common/logic/Product/ProductCategory/ProductCategoryRepository.php
  19. +4
    -16
      common/logic/Product/ProductPointSale/ProductPointSale.php
  20. +9
    -1
      common/logic/Product/ProductPointSale/ProductPointSaleRepository.php
  21. +51
    -87
      common/logic/Product/ProductPrice/ProductPrice.php
  22. +12
    -1
      common/logic/Product/ProductPrice/ProductPriceRepository.php
  23. +13
    -0
      common/logic/Product/ProductPrice/ProductPriceSolver.php
  24. +43
    -57
      common/logic/Subscription/ProductSubscription/ProductSubscription.php
  25. +22
    -0
      common/logic/Subscription/ProductSubscription/ProductSubscriptionRepository.php
  26. +9
    -151
      common/logic/Subscription/Subscription/Subscription.php
  27. +13
    -0
      common/logic/Subscription/Subscription/SubscriptionBuilder.php
  28. +12
    -1
      common/logic/Subscription/Subscription/SubscriptionRepository.php

+ 6
- 0
common/components/ActiveRecordCommon.php View File

const SEARCH_ONE = 'one'; const SEARCH_ONE = 'one';
const SEARCH_COUNT = 'count'; 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 * 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. * pour but de construire la requête et de retourner le résultat.

+ 13
- 0
common/helpers/GlobalParam.php View File

namespace common\helpers; namespace common\helpers;


use common\logic\Producer\Producer\Producer; use common\logic\Producer\Producer\Producer;
use common\logic\User\User\UserSolver;
use common\models\Producer; use common\models\Producer;


class GlobalParam class GlobalParam


return false; return false;
} }

public static function getCurrentUser()
{
$userSolver = new UserSolver();
return $userSolver->getCurrent();
}

public static function getCurrentUserId()
{
$userSolver = new UserSolver();
return $userSolver->getCurrentId();
}
} }

+ 7
- 0
common/logic/Distribution/Distribution/DistributionRepository.php View File

return Distribution::searchOne($paramsDistribution); return Distribution::searchOne($paramsDistribution);
} }


public function getOneByDate(string $date)
{
return Distribution::searchOne([
'distribution.date' => $date
]);
}

/** /**
* Récupère les distributions futures. * Récupère les distributions futures.
*/ */

+ 10
- 0
common/logic/Order/Order/Order.php View File

return $this->hasOne(User::class, ['id' => 'id_user']); return $this->hasOne(User::class, ['id' => 'id_user']);
} }


public function populateUser(User $user)
{
$this->populateFieldObject('id_user', 'user', $user);
}

public function getProductOrder() public function getProductOrder()
{ {
return $this->hasMany(ProductOrder::class, ['id_order' => 'id']) return $this->hasMany(ProductOrder::class, ['id_order' => 'id'])
->with('producer'); ->with('producer');
} }


public function populateDistribution(Distribution $distribution)
{
$this->populateFieldObject('id_distribution', 'distribution', $distribution);
}



public function getPointSale() public function getPointSale()
{ {

+ 151
- 1
common/logic/Order/Order/OrderBuilder.php View File

use common\helpers\Price; use common\helpers\Price;
use common\logic\BaseService; use common\logic\BaseService;
use common\logic\BuilderInterface; 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\Document\Document\Document;
use common\logic\Order\OrderStatusHistory\OrderStatusHistoryBuilder; use common\logic\Order\OrderStatusHistory\OrderStatusHistoryBuilder;
use common\logic\Order\ProductOrder\ProductOrder; use common\logic\Order\ProductOrder\ProductOrder;
use common\logic\Order\ProductOrder\ProductOrderBuilder; 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\Producer;
use common\logic\Producer\Producer\ProducerRepository; 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\CreditHistory;
use common\logic\User\CreditHistory\CreditHistoryBuilder; use common\logic\User\CreditHistory\CreditHistoryBuilder;
use common\logic\User\CreditHistory\CreditHistoryRepository; use common\logic\User\CreditHistory\CreditHistoryRepository;
use common\logic\User\User\User;
use common\logic\User\User\UserSolver; use common\logic\User\User\UserSolver;
use common\logic\User\UserProducer\UserProducerRepository;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;


class OrderBuilder extends BaseService implements BuilderInterface class OrderBuilder extends BaseService implements BuilderInterface
protected ProductOrderBuilder $productOrderBuilder; protected ProductOrderBuilder $productOrderBuilder;
protected OrderStatusHistoryBuilder $orderStatusHistoryBuilder; protected OrderStatusHistoryBuilder $orderStatusHistoryBuilder;
protected OrderRepository $orderRepository; protected OrderRepository $orderRepository;
protected DistributionRepository $distributionRepository;
protected SubscriptionBuilder $subscriptionBuilder;
protected PointSaleRepository $pointSaleRepository;
protected UserProducerRepository $userProducerRepository;
protected UserPointSaleRepository $userPointSaleRepository;
protected PointSaleBuilder $pointSaleBuilder;


public function __construct() public function __construct()
{ {
$this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class); $this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class);
$this->orderStatusHistoryBuilder = $this->loadService(OrderStatusHistoryBuilder::class); $this->orderStatusHistoryBuilder = $this->loadService(OrderStatusHistoryBuilder::class);
$this->orderRepository = $this->loadService(OrderRepository::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 = new Order();
$order->populateDistribution($distribution);
$order->date = date('Y-m-d H:i:s');
$order->status = 'tmp-order';


return $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. * Initialise le montant total, le montant déjà payé et le poids de la commande.
*/ */

+ 1
- 178
common/logic/PointSale/PointSale/PointSale.php View File

use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\logic\Distribution\PointSaleDistribution\PointSaleDistribution; use common\logic\Distribution\PointSaleDistribution\PointSaleDistribution;
use common\logic\PointSale\UserPointSale\UserPointSale; use common\logic\PointSale\UserPointSale\UserPointSale;
use common\logic\Producer\Producer\Producer;
use common\logic\User\User\User; use common\logic\User\User\User;
use yii\helpers\Html;
use common\components\ActiveRecordCommon; use common\components\ActiveRecordCommon;


/** /**
/** /**
* Enregistre le point de vente. * 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(); $this->id_producer = GlobalParam::getCurrentProducerId();
return parent::save($runValidation, $attributeNames); 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;
}
} }

+ 70
- 0
common/logic/PointSale/PointSale/PointSaleBuilder.php View File

use common\logic\BaseService; use common\logic\BaseService;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;
use common\logic\Order\Order\Order; 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\SolverInterface;
use common\logic\User\User\User;
use common\logic\User\User\UserRepository;


class PointSaleBuilder extends BaseService implements BuilderInterface 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 public function instanciate(): PointSale
{ {
$pointSale = new PointSale(); $pointSale = new PointSale();
} }
} }
} }

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



} }

+ 28
- 0
common/logic/PointSale/PointSale/PointSaleRepository.php View File

use common\logic\BaseService; use common\logic\BaseService;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;
use common\logic\Distribution\Distribution\Distribution; use common\logic\Distribution\Distribution\Distribution;
use common\logic\Producer\Producer\Producer;
use common\logic\RepositoryInterface; use common\logic\RepositoryInterface;


class PointSaleRepository extends BaseService implements RepositoryInterface class PointSaleRepository extends BaseService implements RepositoryInterface
]) ])
->all(); ->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;
}
} }

+ 74
- 0
common/logic/PointSale/PointSale/PointSaleSolver.php View File



namespace common\logic\PointSale\PointSale; namespace common\logic\PointSale\PointSale;


use common\helpers\GlobalParam;
use common\logic\BaseService; use common\logic\BaseService;
use common\logic\SolverInterface; use common\logic\SolverInterface;
use yii\helpers\Html;


class PointSaleSolver extends BaseService implements SolverInterface 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;
}



} }

+ 3
- 17
common/logic/PointSale/UserPointSale/UserPointSale.php View File



namespace common\logic\PointSale\UserPointSale; namespace common\logic\PointSale\UserPointSale;


use Yii;
use common\logic\PointSale\PointSale\PointSale;
use common\components\ActiveRecordCommon ; 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 class UserPointSale extends ActiveRecordCommon
public function getPointSale() 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']);
} }
} }

+ 25
- 1
common/logic/PointSale/UserPointSale/UserPointSaleBuilder.php View File



use common\logic\BaseService; use common\logic\BaseService;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;
use common\logic\PointSale\PointSale\PointSale;
use common\logic\User\User\User;


class UserPointSaleBuilder extends BaseService implements BuilderInterface 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 = 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; return $userPointSale;
} }

public function deleteByPointSale(PointSale $pointSale): void
{
UserPointSale::deleteAll(['id_point_sale' => $pointSale->id]);
}
} }

+ 19
- 0
common/logic/PointSale/UserPointSale/UserPointSaleRepository.php View File



use common\logic\BaseService; use common\logic\BaseService;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;
use common\logic\PointSale\UserPointSale\UserPointSale;
use common\logic\RepositoryInterface; use common\logic\RepositoryInterface;
use common\logic\User\User\User;


class UserPointSaleRepository extends BaseService implements RepositoryInterface 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();
}
} }

+ 12
- 0
common/logic/Producer/Producer/ProducerRepository.php View File

use common\helpers\Price; use common\helpers\Price;
use common\logic\BaseService; use common\logic\BaseService;
use common\logic\Document\Document\DocumentInterface; use common\logic\Document\Document\DocumentInterface;
use common\logic\PointSale\PointSale\PointSale;
use common\logic\Producer\ProducerPriceRange\ProducerPriceRange; use common\logic\Producer\ProducerPriceRange\ProducerPriceRange;
use common\logic\Producer\ProducerPriceRange\ProducerPriceRangeRepository; use common\logic\Producer\ProducerPriceRange\ProducerPriceRangeRepository;
use common\logic\RepositoryInterface; use common\logic\RepositoryInterface;
$this->getConfig('document_display_orders_invoice') : $this->getConfig('document_display_orders_invoice') :
$this->getConfig('document_display_orders_delivery_note'); $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');
}
} }

+ 12
- 259
common/logic/Product/Product/Product.php View File

use common\helpers\Debug; use common\helpers\Debug;
use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\helpers\Price; 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\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 Yii;
use common\components\ActiveRecordCommon; use common\components\ActiveRecordCommon;




public function getProductDistribution() public function getProductDistribution()
{ {
return $this->hasMany(ProductDistributionModel::className(), ['id_product' => 'id']);
return $this->hasMany(ProductDistribution::class, ['id_product' => 'id']);
} }


public function getProductSubscription() public function getProductSubscription()
{ {
return $this->hasMany( ProductSubscription::className(), ['id_product' => 'id']);
return $this->hasMany(ProductSubscription::class, ['id_product' => 'id']);
} }


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


public function getProductPrice() public function getProductPrice()
{ {
return $this->hasMany( ProductPrice::className(), ['id_product' => 'id']);
return $this->hasMany( ProductPrice::class, ['id_product' => 'id']);
} }


public function getProductCategory() public function getProductCategory()
{ {
return $this->hasOne( ProductCategory::className(), ['id' => 'id_product_category']);
return $this->hasOne( ProductCategory::class, ['id' => 'id_product_category']);
} }


public function getProductPointSale() 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. * Enregistre le produit.
*
* @param boolean $runValidation
* @param array $attributeNames
* @return boolean
*/ */
public function save($runValidation = true, $attributeNames = NULL) public function save($runValidation = true, $attributeNames = NULL)
{ {
$this->id_producer = GlobalParam::getCurrentProducerId(); $this->id_producer = GlobalParam::getCurrentProducerId();
return parent::save($runValidation, $attributeNames); 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;
}


} }

+ 106
- 0
common/logic/Product/Product/ProductRepository.php View File



namespace common\logic\Product\Product; namespace common\logic\Product\Product;


use common\helpers\GlobalParam;
use common\logic\BaseService; 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\RepositoryInterface;
use common\logic\User\User\User;
use common\logic\User\UserProducer\UserProducerRepository;


class ProductRepository extends BaseService implements RepositoryInterface 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 public function get(): array
{ {
return Product::searchAll(); 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;
}
} }

+ 128
- 1
common/logic/Product/Product/ProductSolver.php View File



namespace common\logic\Product\Product; namespace common\logic\Product\Product;


use common\helpers\GlobalParam;
use common\helpers\Price;
use common\logic\BaseService; use common\logic\BaseService;
use common\logic\PointSale\PointSale\PointSale; use common\logic\PointSale\PointSale\PointSale;
use common\logic\Product\ProductPrice\ProductPriceSolver; use common\logic\Product\ProductPrice\ProductPriceSolver;
use common\logic\SolverInterface; use common\logic\SolverInterface;
use common\logic\User\User\User;


class ProductSolver extends BaseService implements SolverInterface class ProductSolver extends BaseService implements SolverInterface
{ {


return $product->price; 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;
}
} }

+ 28
- 56
common/logic/Product/ProductCategory/ProductCategory.php View File

*/ */
class ProductCategory extends 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'
];
}
} }

+ 26
- 0
common/logic/Product/ProductCategory/ProductCategoryRepository.php View File



namespace common\logic\Product\ProductCategory; namespace common\logic\Product\ProductCategory;


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


class ProductCategoryRepository extends BaseService implements 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;
}
} }

+ 4
- 16
common/logic/Product/ProductPointSale/ProductPointSale.php View File

namespace common\logic\Product\ProductPointSale; namespace common\logic\Product\ProductPointSale;


use common\components\ActiveRecordCommon ; 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". * This is the model class for table "product_point_sale".
public function getProduct() public function getProduct()
{ {
return $this->hasOne( Product::className(), ['id' => 'id_product']);
return $this->hasOne( Product::class, ['id' => 'id_product']);
} }


public function getPointSale() 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']);
} }
} }

+ 9
- 1
common/logic/Product/ProductPointSale/ProductPointSaleRepository.php View File



class ProductPointSaleRepository extends BaseService implements RepositoryInterface class ProductPointSaleRepository extends BaseService implements RepositoryInterface
{ {

public function defaultOptionsSearch(): array
{
return [
'with' => ['product', 'pointSale'],
'join_with' => [],
'orderby' => '',
'attribute_id_producer' => ''
] ;
}
} }

+ 51
- 87
common/logic/Product/ProductPrice/ProductPrice.php View File

namespace common\logic\Product\ProductPrice; namespace common\logic\Product\ProductPrice;


use common\components\ActiveRecordCommon; 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". * This is the model class for table "product_price".
public function rules() public function rules()
{ {
return [ 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'],
]; ];
} }


public function attributeLabels() public function attributeLabels()
{ {
return [ 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é',
]; ];
} }




public function getProduct() public function getProduct()
{ {
return $this->hasOne(
Product::className(),
['id' => 'id_product']
);
return $this->hasOne(Product::class, ['id' => 'id_product']);
} }


public function getPointSale() public function getPointSale()
{ {
return $this->hasOne(
PointSale::className(),
['id' => 'id_point_sale']
);
return $this->hasOne(PointSale::class, ['id' => 'id_point_sale']);
} }


public function getUserGroup() public function getUserGroup()
{ {
return $this->hasOne(
UserGroup::className(),
['id' => 'id_user_group']
);
return $this->hasOne(UserGroup::class, ['id' => 'id_user_group']);
} }


public function getUser() 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']);
} }
} }

+ 12
- 1
common/logic/Product/ProductPrice/ProductPriceRepository.php View File



class ProductPriceRepository extends BaseService implements 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'
];
}
} }

+ 13
- 0
common/logic/Product/ProductPrice/ProductPriceSolver.php View File

&& !$productPrice->id_user_group && !$productPrice->id_user_group
&& $productPrice->from_quantity; && $productPrice->from_quantity;
} }

public function percentValues(): array
{
$percentValues = [
'' => 'Aucun'
];

for ($i = -50; $i < 51; $i = $i + 5) {
$percentValues[$i] = $i . ' %';
}

return $percentValues;
}
} }

+ 43
- 57
common/logic/Subscription/ProductSubscription/ProductSubscription.php View File

<?php <?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; 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". * This is the model class for table "commande_auto_produit".
/** /**
* @inheritdoc * @inheritdoc
*/ */
public static function tableName()
public static function tableName()
{ {
return 'product_subscription'; return 'product_subscription';
} }
/** /**
* @inheritdoc * @inheritdoc
*/ */
public function rules()
public function rules()
{ {
return [ return [
[['id_subscription', 'id_product'], 'required'], [['id_subscription', 'id_product'], 'required'],
/** /**
* @inheritdoc * @inheritdoc
*/ */
public function attributeLabels()
public function attributeLabels()
{ {
return [ return [
'id' => 'ID', 'id' => 'ID',
/* /*
* Relations * 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' => ''
] ;
}

} }

+ 22
- 0
common/logic/Subscription/ProductSubscription/ProductSubscriptionRepository.php View File

<?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' => ''
];
}
}

+ 9
- 151
common/logic/Subscription/Subscription/Subscription.php View File

namespace common\logic\Subscription\Subscription; namespace common\logic\Subscription\Subscription;


use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\logic\PointSale\PointSale\PointSale;
use common\logic\Producer\Producer\Producer; use common\logic\Producer\Producer\Producer;
use common\logic\Subscription\ProductSubscription\ProductSubscription;
use common\logic\User\CreditHistory\CreditHistory; use common\logic\User\CreditHistory\CreditHistory;
use common\logic\User\UserProducer\UserProducer; use common\logic\User\UserProducer\UserProducer;
use Yii; use Yii;
use common\logic\User\User\User; 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 class Subscription extends ActiveRecordCommon
{ {


public function getPointSale() public function getPointSale()
{ {
return $this->hasOne(
PointSale::class,
['id' => 'id_point_sale']
);
return $this->hasOne(PointSale::class, ['id' => 'id_point_sale']);
} }


public function getProductSubscription() 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');
} }


/** /**
{ {
$dateStart = $this->date_begin; $dateStart = $this->date_begin;
$comparatorDateStart = '>='; $comparatorDateStart = '>=';
if($deleteAfterDateEnd) {
if ($deleteAfterDateEnd) {
$dateStart = $this->date_end; $dateStart = $this->date_end;
$comparatorDateStart = '>'; $comparatorDateStart = '>';
} }
->joinWith('distribution') ->joinWith('distribution')
->where('distribution.id_producer = :id_producer') ->where('distribution.id_producer = :id_producer')
->andWhere($conditionDistributionDate) ->andWhere($conditionDistributionDate)
->andWhere('distribution.date '.$comparatorDateStart.' :date_start')
->andWhere('distribution.date ' . $comparatorDateStart . ' :date_start')
->andWhere('order.id_subscription = :id_subscription'); ->andWhere('order.id_subscription = :id_subscription');


$orders->params($params); $orders->params($params);


$order->delete(true); $order->delete(true);


$countOrdersDeleted ++;
$countOrdersDeleted++;
} }
} }



+ 13
- 0
common/logic/Subscription/Subscription/SubscriptionBuilder.php View File



use common\logic\BaseService; use common\logic\BaseService;
use common\logic\BuilderInterface; 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 class SubscriptionBuilder extends BaseService implements BuilderInterface
{ {
protected DistributionRepository $distributionRepository;

public function __construct()
{
$this->distributionRepository = $this->loadService(DistributionRepository::class);
}

public function instanciate(): Subscription public function instanciate(): Subscription
{ {
$subscription = new Subscription(); $subscription = new Subscription();

+ 12
- 1
common/logic/Subscription/Subscription/SubscriptionRepository.php View File



class SubscriptionRepository extends BaseService implements 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'
];
}
} }

Loading…
Cancel
Save