ソースを参照

Refactoring services #885

refactoring
Guillaume Bourgeois 1年前
コミット
82c110eaf0
73個のファイルの変更547行の追加372行の削除
  1. +3
    -3
      common/components/ActiveRecordCommon.php
  2. +9
    -4
      common/logic/BaseBuilder.php
  3. +1
    -1
      common/logic/Config/TaxRate/TaxRateBuilder.php
  4. +1
    -1
      common/logic/Config/TaxRate/TaxRateRepository.php
  5. +1
    -1
      common/logic/Development/Development/Development.php
  6. +1
    -1
      common/logic/Development/DevelopmentPriority/DevelopmentPriority.php
  7. +12
    -0
      common/logic/Distribution/Distribution/Distribution.php
  8. +9
    -8
      common/logic/Distribution/Distribution/DistributionBuilder.php
  9. +43
    -1
      common/logic/Distribution/Distribution/DistributionRepository.php
  10. +7
    -8
      common/logic/Distribution/PointSaleDistribution/PointSaleDistributionBuilder.php
  11. +1
    -1
      common/logic/Distribution/PointSaleDistribution/PointSaleDistributionRepository.php
  12. +1
    -1
      common/logic/Distribution/ProductDistribution/ProductDistributionBuilder.php
  13. +1
    -1
      common/logic/Distribution/ProductDistribution/ProductDistributionRepository.php
  14. +1
    -1
      common/logic/Document/DeliveryNote/DeliveryNoteRepository.php
  15. +1
    -1
      common/logic/Document/DeliveryNote/DeliveryNoteSearch.php
  16. +3
    -3
      common/logic/Document/Document/Document.php
  17. +3
    -2
      common/logic/Document/Document/DocumentBuilder.php
  18. +1
    -1
      common/logic/Document/Document/DocumentSolver.php
  19. +1
    -1
      common/logic/Document/Invoice/InvoiceRepository.php
  20. +1
    -1
      common/logic/Document/Invoice/InvoiceSearch.php
  21. +1
    -1
      common/logic/Document/Quotation/QuotationRepository.php
  22. +1
    -1
      common/logic/Document/Quotation/QuotationSearch.php
  23. +11
    -46
      common/logic/Order/Order/OrderBuilder.php
  24. +10
    -8
      common/logic/Order/Order/OrderRepository.php
  25. +1
    -1
      common/logic/Order/Order/OrderSearch.php
  26. +6
    -9
      common/logic/Order/OrderStatusHistory/OrderStatusHistoryBuilder.php
  27. +1
    -1
      common/logic/Order/OrderStatusHistory/OrderStatusHistoryRepository.php
  28. +9
    -8
      common/logic/Order/ProductOrder/ProductOrderBuilder.php
  29. +2
    -2
      common/logic/Order/ProductOrder/ProductOrderRepository.php
  30. +21
    -16
      common/logic/PointSale/PointSale/PointSaleBuilder.php
  31. +2
    -2
      common/logic/PointSale/PointSale/PointSaleRepository.php
  32. +1
    -1
      common/logic/PointSale/PointSale/PointSaleSearch.php
  33. +11
    -0
      common/logic/PointSale/UserPointSale/UserPointSale.php
  34. +19
    -9
      common/logic/PointSale/UserPointSale/UserPointSaleBuilder.php
  35. +2
    -2
      common/logic/PointSale/UserPointSale/UserPointSaleRepository.php
  36. +12
    -10
      common/logic/Producer/Producer/ProducerBuilder.php
  37. +15
    -14
      common/logic/Producer/Producer/ProducerRepository.php
  38. +23
    -0
      common/logic/Producer/ProducerPriceRange/ProducerPriceRangeBuilder.php
  39. +1
    -0
      common/logic/Producer/ProducerPriceRange/ProducerPriceRangeManager.php
  40. +8
    -3
      common/logic/Producer/ProducerPriceRange/ProducerPriceRangeRepository.php
  41. +11
    -3
      common/logic/Product/Product/ProductBuilder.php
  42. +34
    -32
      common/logic/Product/Product/ProductRepository.php
  43. +1
    -1
      common/logic/Product/Product/ProductSearch.php
  44. +11
    -2
      common/logic/Product/ProductCategory/ProductCategoryBuilder.php
  45. +5
    -5
      common/logic/Product/ProductCategory/ProductCategoryRepository.php
  46. +1
    -1
      common/logic/Product/ProductCategory/ProductCategorySearch.php
  47. +11
    -3
      common/logic/Product/ProductPointSale/ProductPointSaleBuilder.php
  48. +1
    -1
      common/logic/Product/ProductPointSale/ProductPointSaleRepository.php
  49. +11
    -3
      common/logic/Product/ProductPrice/ProductPriceBuilder.php
  50. +1
    -1
      common/logic/Product/ProductPrice/ProductPriceRepository.php
  51. +1
    -1
      common/logic/Product/ProductPrice/ProductPriceSearch.php
  52. +11
    -3
      common/logic/Subscription/ProductSubscription/ProductSubscriptionBuilder.php
  53. +1
    -1
      common/logic/Subscription/ProductSubscription/ProductSubscriptionRepository.php
  54. +14
    -11
      common/logic/Subscription/Subscription/SubscriptionBuilder.php
  55. +19
    -0
      common/logic/Subscription/Subscription/SubscriptionEventSubscriber.php
  56. +9
    -46
      common/logic/Subscription/Subscription/SubscriptionRepository.php
  57. +1
    -1
      common/logic/Subscription/Subscription/SubscriptionSearch.php
  58. +1
    -1
      common/logic/Subscription/Subscription/SubscriptionSolver.php
  59. +24
    -0
      common/logic/User/CreditHistory/CreditHistory.php
  60. +13
    -21
      common/logic/User/CreditHistory/CreditHistoryBuilder.php
  61. +1
    -1
      common/logic/User/CreditHistory/CreditHistoryRepository.php
  62. +1
    -1
      common/logic/User/CreditHistory/CreditHistorySearch.php
  63. +4
    -4
      common/logic/User/User/UserBuilder.php
  64. +28
    -20
      common/logic/User/User/UserRepository.php
  65. +1
    -1
      common/logic/User/User/UserSearch.php
  66. +11
    -3
      common/logic/User/UserGroup/UserGroupBuilder.php
  67. +8
    -3
      common/logic/User/UserGroup/UserGroupRepository.php
  68. +1
    -1
      common/logic/User/UserGroup/UserGroupSearch.php
  69. +25
    -20
      common/logic/User/UserProducer/UserProducerBuilder.php
  70. +12
    -0
      common/logic/User/UserProducer/UserProducerEventSubscriber.php
  71. +3
    -3
      common/logic/User/UserProducer/UserProducerRepository.php
  72. +12
    -2
      common/logic/User/UserUserGroup/UserUserGroupBuilder.php
  73. +1
    -1
      common/logic/User/UserUserGroup/UserUserGroupRepository.php

+ 3
- 3
common/components/ActiveRecordCommon.php ファイルの表示

$class = get_called_class(); $class = get_called_class();
$repositoryClass = $class.'Repository'; $repositoryClass = $class.'Repository';


if (is_callable([$repositoryClass, 'defaultOptionsSearch'])) {
if (is_callable([$repositoryClass, 'getDefaultOptionsSearch'])) {
$repository = new $repositoryClass; $repository = new $repositoryClass;
$default_options = $repository->defaultOptionsSearch();
$default_options = $repository->getDefaultOptionsSearch();
} else { } else {
throw new \ErrorException('La méthode "defaultOptionsSearch" n\'est '
throw new \ErrorException('La méthode "getDefaultOptionsSearch" n\'est '
. 'pas définie dans la classe "' . $class . '"'); . 'pas définie dans la classe "' . $class . '"');
} }



+ 9
- 4
common/logic/BaseBuilder.php ファイルの表示



class BaseBuilder extends BaseService class BaseBuilder extends BaseService
{ {
public function create(ActiveRecord $model): void
public function saveCreate(ActiveRecord $model): bool
{ {
$model->save();
return $model->save();
} }


public function update(ActiveRecord $model): void
public function saveUpdate(ActiveRecord $model): bool
{ {
$model->save();
return $model->save();
}

public function delete(ActiveRecord $model): bool
{
$model->delete();
} }
} }

+ 1
- 1
common/logic/Config/TaxRate/TaxRateBuilder.php ファイルの表示

{ {
$taxRate = $this->instanciateTaxRate(); $taxRate = $this->instanciateTaxRate();


$this->create($taxRate);
$this->saveCreate($taxRate);


return $taxRate; return $taxRate;
} }

+ 1
- 1
common/logic/Config/TaxRate/TaxRateRepository.php ファイルの表示



class TaxRateRepository extends BaseService implements RepositoryInterface class TaxRateRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],

+ 1
- 1
common/logic/Development/Development/Development.php ファイルの表示

* *
* @return array * @return array
*/ */
public static function defaultOptionsSearch() {
public static function getDefaultOptionsSearch() {
return [ return [
'with' => ['developmentPriority', 'developmentPriorityCurrentProducer'], 'with' => ['developmentPriority', 'developmentPriorityCurrentProducer'],
'join_with' => [], 'join_with' => [],

+ 1
- 1
common/logic/Development/DevelopmentPriority/DevelopmentPriority.php ファイルの表示

* *
* @return array * @return array
*/ */
public static function defaultOptionsSearch() {
public static function getDefaultOptionsSearch() {
return [ return [
'with' => [], 'with' => [],
'join_with' => [], 'join_with' => [],

+ 12
- 0
common/logic/Distribution/Distribution/Distribution.php ファイルの表示

use common\logic\Order\Order\Order; use common\logic\Order\Order\Order;
use common\logic\Producer\Producer\Producer; use common\logic\Producer\Producer\Producer;
use common\components\ActiveRecordCommon; use common\components\ActiveRecordCommon;
use common\logic\Subscription\Subscription\SubscriptionEventSubscriber;


class Distribution extends ActiveRecordCommon class Distribution extends ActiveRecordCommon
{ {
const EVENT_ACTIVE = 'distribution.active';

/** /**
* @inheritdoc * @inheritdoc
*/ */
]; ];
} }


public function init()
{
$this->on(Distribution::EVENT_ACTIVE, function($event) {
SubscriptionEventSubscriber::onActiveDistribution($event->distribution);
});

parent::init();
}

/* /*
* Relations * Relations
*/ */

+ 9
- 8
common/logic/Distribution/Distribution/DistributionBuilder.php ファイルの表示

use common\logic\Product\Product\Product; use common\logic\Product\Product\Product;
use common\logic\Product\Product\ProductRepository; use common\logic\Product\Product\ProductRepository;
use common\logic\User\UserProducer\UserProducerRepository; use common\logic\User\UserProducer\UserProducerRepository;
use yii\base\Event;


class DistributionBuilder extends BaseBuilder implements BuilderInterface class DistributionBuilder extends BaseBuilder implements BuilderInterface
{ {
{ {
$distribution = $this->instanciateDistribution($producer, $date, $delivery); $distribution = $this->instanciateDistribution($producer, $date, $delivery);


$this->create($distribution);
$this->saveCreate($distribution);


$this->createPointSaleDistributions($distribution); $this->createPointSaleDistributions($distribution);
$this->createProductDistributions($distribution); $this->createProductDistributions($distribution);
$pointSaleDistribution->delivery = 1; $pointSaleDistribution->delivery = 1;
} }


$this->update($pointSaleDistribution);
$this->saveUpdate($pointSaleDistribution);


return $pointSaleDistribution; return $pointSaleDistribution;
} }
*/ */
public function addPointSaleIncomingDistributions(PointSale $pointSale): void public function addPointSaleIncomingDistributions(PointSale $pointSale): void
{ {
$distributionArray = $this->distributionRepository->getIncoming();
$distributionArray = $this->distributionRepository->findDistributionsIncoming();
foreach ($distributionArray as $distribution) { foreach ($distributionArray as $distribution) {
$this->addPointSale($distribution, $pointSale); $this->addPointSale($distribution, $pointSale);
} }


public function updateOrderProductPrices(Distribution $distribution, Product $product): void public function updateOrderProductPrices(Distribution $distribution, Product $product): void
{ {
$ordersArray = $this->orderRepository->getByDistribution($distribution, 'AND origin != "user"');
$ordersArray = $this->orderRepository->findOrdersByDistribution($distribution, 'AND origin != "user"');


if ($ordersArray) { if ($ordersArray) {
foreach ($ordersArray as $order) { foreach ($ordersArray as $order) {
/** /**
* Active ou désactive la distribution. * Active ou désactive la distribution.
*/ */
public function updateActive(Distribution $distribution, bool $active = true): void
// active
public function activeDistribution(Distribution $distribution, bool $active = true): void
{ {
$this->pointSaleDistributionBuilder->createAllPointSaleDistributions($distribution, true); $this->pointSaleDistributionBuilder->createAllPointSaleDistributions($distribution, true);


$distribution->active = (int) $active; $distribution->active = (int) $active;


$this->update($distribution);
$this->saveUpdate($distribution);


if ($active) { if ($active) {
// @TODO : gérer avec les événements
//Subscription::addAll($distribution->date);
$distribution->trigger(Distribution::EVENT_ACTIVE, new Event(['distribution' => $distribution]));
} }
} }
} }

+ 43
- 1
common/logic/Distribution/Distribution/DistributionRepository.php ファイルの表示

use common\logic\BaseService; use common\logic\BaseService;
use common\logic\Producer\Producer\Producer; use common\logic\Producer\Producer\Producer;
use common\logic\RepositoryInterface; use common\logic\RepositoryInterface;
use common\logic\Subscription\Subscription\Subscription;
use common\logic\Subscription\Subscription\SubscriptionSolver;


class DistributionRepository extends BaseService implements RepositoryInterface class DistributionRepository extends BaseService implements RepositoryInterface
{ {
protected DistributionSolver $distributionSolver; protected DistributionSolver $distributionSolver;
protected SubscriptionSolver $subscriptionSolver;


public function __construct() public function __construct()
{ {
$this->distributionSolver = $this->loadService(DistributionSolver::class); $this->distributionSolver = $this->loadService(DistributionSolver::class);
$this->subscriptionSolver = $this->loadService(SubscriptionSolver::class);
} }


public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],
return $distributionsArray; return $distributionsArray;
} }


/**
* Recherche les distributions futures où l'abonnement peut s'appliquer.
*/
// searchMatchedIncomingDistributions
public function findDistributionsIncomingMatchWithSubscrtiption(Subscription $subscription): array
{
$params = [
':date_earliest_order' => date('Y-m-d'),
':date_begin' => date('Y-m-d', strtotime($subscription->date_begin)),
':id_producer' => GlobalParam::getCurrentProducerId()
];

$incomingDistributions = Distribution::find()
->where('id_producer = :id_producer')
->andWhere('date >= :date_begin')
->andWhere('date > :date_earliest_order');

if ($subscription->date_end) {
$incomingDistributions->andWhere('date <= :date_end');
$params[':date_end'] = date('Y-m-d', strtotime($subscription->date_end));
}

$incomingDistributions->orderBy('date ASC');

$incomingDistributions->params($params);
$incomingDistributionsArray = $incomingDistributions->all();
$this->subscriptionSolver->filterDistributionsByDateDelay($incomingDistributionsArray);

$matchedIncomingDistributionsArray = [];
foreach ($incomingDistributionsArray as $incomingDistribution) {
if ($this->subscriptionSolver->matchWith($subscription, $incomingDistribution->date)) {
$matchedIncomingDistributionsArray[] = $incomingDistribution;
}
}

return $matchedIncomingDistributionsArray;
}

// isDateAvailable // isDateAvailable
public function isDistributionDateAvailable(Producer $producer, string $date = null): bool public function isDistributionDateAvailable(Producer $producer, string $date = null): bool
{ {

+ 7
- 8
common/logic/Distribution/PointSaleDistribution/PointSaleDistributionBuilder.php ファイルの表示

public function instanciatePointSaleDistribution(Distribution $distribution, PointSale $pointSale): PointSaleDistribution public function instanciatePointSaleDistribution(Distribution $distribution, PointSale $pointSale): PointSaleDistribution
{ {
$pointSaleDistribution = new PointSaleDistribution(); $pointSaleDistribution = new PointSaleDistribution();

$pointSaleDistribution->id_distribution = $distribution->id;
$pointSaleDistribution->id_point_sale = $pointSale->id;
$pointSaleDistribution->populateFieldObject('id_distribution', 'distribution', $distribution);
$pointSaleDistribution->populateFieldObject('id_point_sale', 'pointSale', $pointSale);


return $pointSaleDistribution; return $pointSaleDistribution;
} }
{ {
$pointSaleDistribution = $this->instanciatePointSaleDistribution($distribution, $pointSale); $pointSaleDistribution = $this->instanciatePointSaleDistribution($distribution, $pointSale);


$this->create($pointSaleDistribution);
$this->saveCreate($pointSaleDistribution);


return $pointSaleDistribution; return $pointSaleDistribution;
} }
} }
} }


$pointSaleDistributionArray = $this->pointSaleDistributionRepository->getByDistribution($distribution);
$pointSaleDistributionArray = $this->pointSaleDistributionRepository->findPointSaleDistributionsByDistribution($distribution);
foreach ($pointSaleDistributionArray as $pointSaleDistribution) { foreach ($pointSaleDistributionArray as $pointSaleDistribution) {
$this->initDelivery($pointSaleDistribution, $delivery);
$this->updateDelivery($pointSaleDistribution, $delivery);
} }
} }


public function initDelivery(PointSaleDistribution $pointSaleDistribution, bool $delivery): void
public function updateDelivery(PointSaleDistribution $pointSaleDistribution, bool $delivery): void
{ {
$day = date('N', strtotime($pointSaleDistribution->distribution->date)); $day = date('N', strtotime($pointSaleDistribution->distribution->date));
$pointSale = $pointSaleDistribution->pointSale; $pointSale = $pointSaleDistribution->pointSale;
$pointSaleDistribution->delivery = 0; $pointSaleDistribution->delivery = 0;
} }


$this->update($pointSaleDistribution);
$this->saveUpdate($pointSaleDistribution);
} }
} }

+ 1
- 1
common/logic/Distribution/PointSaleDistribution/PointSaleDistributionRepository.php ファイルの表示



class PointSaleDistributionRepository extends BaseService implements RepositoryInterface class PointSaleDistributionRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => ['distribution', 'pointSale'], 'with' => ['distribution', 'pointSale'],

+ 1
- 1
common/logic/Distribution/ProductDistribution/ProductDistributionBuilder.php ファイルの表示

->initActive($productDistribution) ->initActive($productDistribution)
->initQuantityMax($productDistribution); ->initQuantityMax($productDistribution);


$this->create($productDistribution);
$this->saveCreate($productDistribution);


return $productDistribution; return $productDistribution;
} }

+ 1
- 1
common/logic/Distribution/ProductDistribution/ProductDistributionRepository.php ファイルの表示



class ProductDistributionRepository extends BaseService implements RepositoryInterface class ProductDistributionRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => ['product','distribution'], 'with' => ['product','distribution'],

+ 1
- 1
common/logic/Document/DeliveryNote/DeliveryNoteRepository.php ファイルの表示



class DeliveryNoteRepository extends BaseService implements RepositoryInterface class DeliveryNoteRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],

+ 1
- 1
common/logic/Document/DeliveryNote/DeliveryNoteSearch.php ファイルの表示

public function search($params) public function search($params)
{ {
$deliveryNoteRepository = new DeliveryNoteRepository(); $deliveryNoteRepository = new DeliveryNoteRepository();
$optionsSearch = $deliveryNoteRepository->defaultOptionsSearch();
$optionsSearch = $deliveryNoteRepository->getDefaultOptionsSearch();


$query = DeliveryNote::find() $query = DeliveryNote::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])

+ 3
- 3
common/logic/Document/Document/Document.php ファイルの表示

public function relationOrders($fieldIdDocument) public function relationOrders($fieldIdDocument)
{ {
$orderRepository = new OrderRepository(); $orderRepository = new OrderRepository();
$defaultOptionsSearch = $orderRepository->defaultOptionsSearch();
$getDefaultOptionsSearch = $orderRepository->getDefaultOptionsSearch();


return $this->hasMany(Order::class, [$fieldIdDocument => 'id']) return $this->hasMany(Order::class, [$fieldIdDocument => 'id'])
->with($defaultOptionsSearch['with'])
->joinWith($defaultOptionsSearch['join_with'])
->with($getDefaultOptionsSearch['with'])
->joinWith($getDefaultOptionsSearch['join_with'])
->orderBy('distribution.date ASC'); ->orderBy('distribution.date ASC');
} }
} }

+ 3
- 2
common/logic/Document/Document/DocumentBuilder.php ファイルの表示



public function generateReference(DocumentInterface $document): void public function generateReference(DocumentInterface $document): void
{ {
$class = $document->getClass();
$class = $this->documentSolver->getClass($document);
$classLower = strtolower($class); $classLower = strtolower($class);
if ($classLower == 'deliverynote') { if ($classLower == 'deliverynote') {
$classLower = 'delivery_note'; $classLower = 'delivery_note';


public function changeStatus(DocumentInterface $document, string $status): void public function changeStatus(DocumentInterface $document, string $status): void
{ {
$document->status = $status;

if ($status == Document::STATUS_VALID) { if ($status == Document::STATUS_VALID) {
$document->status = $status;
$this->generateReference($document); $this->generateReference($document);
} }
} }

+ 1
- 1
common/logic/Document/Document/DocumentSolver.php ファイルの表示



namespace common\logic\Document\Document; namespace common\logic\Document\Document;


use common\helpers\Price;
use common\logic\BaseService; use common\logic\BaseService;
use common\logic\Order\Order\Order; use common\logic\Order\Order\Order;
use common\logic\PointSale\PointSale\PointSale; use common\logic\PointSale\PointSale\PointSale;
use common\logic\Producer\Producer\Producer;
use common\logic\SolverInterface; use common\logic\SolverInterface;


class DocumentSolver extends BaseService implements SolverInterface class DocumentSolver extends BaseService implements SolverInterface

+ 1
- 1
common/logic/Document/Invoice/InvoiceRepository.php ファイルの表示



class InvoiceRepository extends BaseService implements RepositoryInterface class InvoiceRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],

+ 1
- 1
common/logic/Document/Invoice/InvoiceSearch.php ファイルの表示



public function search($params) public function search($params)
{ {
$optionsSearch = self::defaultOptionsSearch();
$optionsSearch = self::getDefaultOptionsSearch();


$query = Invoice::find() $query = Invoice::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])

+ 1
- 1
common/logic/Document/Quotation/QuotationRepository.php ファイルの表示



class QuotationRepository extends BaseService implements RepositoryInterface class QuotationRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],

+ 1
- 1
common/logic/Document/Quotation/QuotationSearch.php ファイルの表示



public function search($params) public function search($params)
{ {
$optionsSearch = self::defaultOptionsSearch();
$optionsSearch = self::getDefaultOptionsSearch();


$query = Quotation::find() $query = Quotation::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])

+ 11
- 46
common/logic/Order/Order/OrderBuilder.php ファイルの表示

use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\helpers\MeanPayment; use common\helpers\MeanPayment;
use common\helpers\Price; use common\helpers\Price;
use common\logic\BaseBuilder;
use common\logic\BaseService; use common\logic\BaseService;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;
use common\logic\Config\TaxRate\TaxRate; use common\logic\Config\TaxRate\TaxRate;
use common\logic\User\UserProducer\UserProducerRepository; use common\logic\User\UserProducer\UserProducerRepository;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;


class OrderBuilder extends BaseService implements BuilderInterface
class OrderBuilder extends BaseBuilder implements BuilderInterface
{ {
protected UserSolver $userSolver; protected UserSolver $userSolver;
protected OrderSolver $orderSolver; protected OrderSolver $orderSolver;
{ {
$order = $this->instanciateOrder($distribution); $order = $this->instanciateOrder($distribution);


$this->addUserPointSale($order);
$this->createUserPointSale($order);
$this->initOrderCommentPointSale($order); $this->initOrderCommentPointSale($order);
$this->generateOrderReference($order); $this->generateOrderReference($order);




if (isset($order->productOrder)) { if (isset($order->productOrder)) {
foreach ($order->productOrder as $productOrder) { foreach ($order->productOrder as $productOrder) {
$this->addAmount($order, Order::AMOUNT_TOTAL, $productOrder, $taxCalculationMethod);
$this->addAmount($order, Order::INVOICE_AMOUNT_TOTAL, $productOrder, $taxCalculationMethod);
$this->addWeight($order, $productOrder);
$this->addProductOrderAmount($order, Order::AMOUNT_TOTAL, $productOrder, $taxCalculationMethod);
$this->addProductOrderAmount($order, Order::INVOICE_AMOUNT_TOTAL, $productOrder, $taxCalculationMethod);
$this->addProductOrderWeight($order, $productOrder);
} }
} }
} }
// remboursement si l'utilisateur a payé pour cette commande // remboursement si l'utilisateur a payé pour cette commande
$amountPaid = $this->orderSolver->getAmount($order, Order::AMOUNT_PAID); $amountPaid = $this->orderSolver->getAmount($order, Order::AMOUNT_PAID);


if ($amountPaid > 0.01) {
if ($amountPaid >= 0.01) {
$this->creditHistoryBuilder->create( $this->creditHistoryBuilder->create(
CreditHistory::TYPE_REFUND, CreditHistory::TYPE_REFUND,
$amountPaid, $amountPaid,


$this->productOrderBuilder->deleteByOrder($order); $this->productOrderBuilder->deleteByOrder($order);


return $order->delete();
return $this->delete($order);
} }
// status 'delete' // status 'delete'
elseif ($this->producerRepository->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS) { elseif ($this->producerRepository->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS) {
$order->date_delete = date('Y-m-d H:i:s'); $order->date_delete = date('Y-m-d H:i:s');


return $order->save();
return $this->saveUpdate($order);
} }


return false; return false;
$order->tiller_synchronization = 0; $order->tiller_synchronization = 0;
} }


$order->save();
$this->saveUpdate($order);
} }


/** /**
$order->save(); $order->save();
break; break;
case 'waiting-paiement-on-delivery': case 'waiting-paiement-on-delivery':
if (in_array($newStatus, $orderStatusArray[$order->status]['nextStatusAllow'])) {
$this->orderStatusHistoryBuilder->create($order, $userCurrent, $newStatus, $origin);
$order->status = $newStatus;
$order->save();
}
break;
case 'waiting-paiement-by-credit': case 'waiting-paiement-by-credit':
if (in_array($newStatus, $orderStatusArray[$order->status]['nextStatusAllow'])) {
$this->orderStatusHistoryBuilder->create($order, $userCurrent, $newStatus, $origin);
$order->status = $newStatus;
$order->save();
}
break;
case 'paid-by-credit': case 'paid-by-credit':
if (in_array($newStatus, $orderStatusArray[$order->status]['nextStatusAllow'])) {
$this->orderStatusHistoryBuilder->create($order, $userCurrent, $newStatus, $origin);
$order->status = $newStatus;
$order->save();
}
break;
case 'waiting-delevery' : case 'waiting-delevery' :
if (in_array($newStatus, $orderStatusArray[$order->status]['nextStatusAllow'])) {
$this->orderStatusHistoryBuilder->create($order, $userCurrent, $newStatus, $origin);
$order->status = $newStatus;
$order->save();
}
break;
case 'delivered': case 'delivered':
if (in_array($newStatus, $orderStatusArray[$order->status]['nextStatusAllow'])) {
$this->orderStatusHistoryBuilder->create($order, $userCurrent, $newStatus, $origin);
$order->status = $newStatus;
$order->save();
}
break;
case 'refunded': case 'refunded':
if (in_array($newStatus, $orderStatusArray[$order->status]['nextStatusAllow'])) {
$this->orderStatusHistoryBuilder->create($order, $userCurrent, $newStatus, $origin);
$order->status = $newStatus;
$order->save();
}
break;
case 'cancel': case 'cancel':
if (in_array($newStatus, $orderStatusArray[$order->status]['nextStatusAllow'])) { if (in_array($newStatus, $orderStatusArray[$order->status]['nextStatusAllow'])) {
$this->orderStatusHistoryBuilder->create($order, $userCurrent, $newStatus, $origin); $this->orderStatusHistoryBuilder->create($order, $userCurrent, $newStatus, $origin);
$order->reference = 'A' . date('y') . 'C0001'; $order->reference = 'A' . date('y') . 'C0001';
} }


$order->save();
$this->saveUpdate($order);
} }
} }



+ 10
- 8
common/logic/Order/Order/OrderRepository.php ファイルの表示

$this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class); $this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class);
} }


public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [ 'with' => [
]; ];
} }


public function findOneById(int $id)
public function findOneOrderById(int $id)
{ {
return Order::searchOne(['order.id' => $id]);; return Order::searchOne(['order.id' => $id]);;
} }
* Recherche et initialise des commandes. * Recherche et initialise des commandes.
*/ */
// searchBy // searchBy
public function findBy(array $params = [], array $options = []): array
// findBy
public function findOrdersBy(array $params = [], array $options = []): mixed
{ {
$orders = Order::searchBy($params, $options); $orders = Order::searchBy($params, $options);


'conditions' => 'date_delete IS NULL ' . $conditionAppend 'conditions' => 'date_delete IS NULL ' . $conditionAppend
]); ]);
} }
public function queryHistory(Producer $producer, User $user, string $type = 'incoming')

// queryHistory
public function queryOrdersHistory(Producer $producer, User $user)
{ {
$query = Order::find() $query = Order::find()
->with('productOrder', 'pointSale', 'creditHistory') ->with('productOrder', 'pointSale', 'creditHistory')
return Order::STATE_PREPARATION; return Order::STATE_PREPARATION;
} }


public function findOneLastOfYear(Producer $producer)
public function findOneOrderLastOfYear(Producer $producer)
{ {
return Order::find()->innerJoinWith('distribution', true) return Order::find()->innerJoinWith('distribution', true)
->where(['>=', 'distribution.date', date('Y') . '-01-01']) ->where(['>=', 'distribution.date', date('Y') . '-01-01'])
public function findProductDistributionsByDistribution(Distribution $distribution): array public function findProductDistributionsByDistribution(Distribution $distribution): array
{ {
$orderArray = $this->findOrdersByDistribution($distribution); $orderArray = $this->findOrdersByDistribution($distribution);
$productDistributionArray = $this->productDistributionRepository->findProductDistributionsByDistribution();
$productDistributionArray = $this->productDistributionRepository->findProductDistributionsByDistribution($distribution);


foreach ($productDistributionArray as $productDistribution) { foreach ($productDistributionArray as $productDistribution) {
if (isset($productDistribution->product)) { if (isset($productDistribution->product)) {
'unavailable' => (int) $productDistribution->product->unavailable, 'unavailable' => (int) $productDistribution->product->unavailable,
'quantity_max' => $productDistribution->quantity_max, 'quantity_max' => $productDistribution->quantity_max,
'quantity_order' => $this->orderSolver->getProductQuantity($productDistribution->product, $orderArray), 'quantity_order' => $this->orderSolver->getProductQuantity($productDistribution->product, $orderArray),
'quantity_remaining' => $productDistribution->quantity_max - $this->orderSolver->getProductQuantity($productDistribution->product, $orders)
'quantity_remaining' => $productDistribution->quantity_max - $this->orderSolver->getProductQuantity($productDistribution->product, $orderArray)
]; ];
} }
} }

+ 1
- 1
common/logic/Order/Order/OrderSearch.php ファイルの表示

{ {
public function search($params) public function search($params)
{ {
$optionsSearch = self::defaultOptionsSearch() ;
$optionsSearch = self::getDefaultOptionsSearch() ;


$paramsSearch = []; $paramsSearch = [];
if(isset($params['id_user'])) { if(isset($params['id_user'])) {

+ 6
- 9
common/logic/Order/OrderStatusHistory/OrderStatusHistoryBuilder.php ファイルの表示



namespace common\logic\Order\OrderStatusHistory; namespace common\logic\Order\OrderStatusHistory;


use common\logic\BaseService;
use common\logic\BaseBuilder;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;
use common\logic\Order\Order\Order; use common\logic\Order\Order\Order;
use common\logic\User\User\User; use common\logic\User\User\User;
use common\logic\User\User\UserSolver; use common\logic\User\User\UserSolver;


class OrderStatusHistoryBuilder extends BaseService implements BuilderInterface
class OrderStatusHistoryBuilder extends BaseBuilder implements BuilderInterface
{ {
protected UserSolver $userSolver; protected UserSolver $userSolver;


public function instanciateOrderStatusHistory(Order $order, User $user, string $status, string $origin): OrderStatusHistory public function instanciateOrderStatusHistory(Order $order, User $user, string $status, string $origin): OrderStatusHistory
{ {
$orderStatusHistory = new OrderStatusHistory(); $orderStatusHistory = new OrderStatusHistory();

$orderStatusHistory->id_order = $order->id;
$orderStatusHistory->populateRelation('order', $order);
$orderStatusHistory->id_user = $user->id;
$orderStatusHistory->populateRelation('user', $user);
$orderStatusHistory->populateOrder($order);
$orderStatusHistory->populateUser($user);
$orderStatusHistory->status = $status; $orderStatusHistory->status = $status;
$orderStatusHistory->origin = $origin; $orderStatusHistory->origin = $origin;
$orderStatusHistory->date = date('Y-m-d H:i:s'); $orderStatusHistory->date = date('Y-m-d H:i:s');
public function createOrderStatusHistory(Order $order, User $user, string $status, string $origin): OrderStatusHistory public function createOrderStatusHistory(Order $order, User $user, string $status, string $origin): OrderStatusHistory
{ {
$orderStatusHistory = $this->instanciateOrderStatusHistory($order, $user, $status, $origin); $orderStatusHistory = $this->instanciateOrderStatusHistory($order, $user, $status, $origin);
$orderStatusHistory->save();
$this->saveCreate($orderStatusHistory);


return $orderStatusHistory
return $orderStatusHistory;
} }
} }

+ 1
- 1
common/logic/Order/OrderStatusHistory/OrderStatusHistoryRepository.php ファイルの表示



class OrderStatusHistoryRepository extends BaseService implements RepositoryInterface class OrderStatusHistoryRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],

+ 9
- 8
common/logic/Order/ProductOrder/ProductOrderBuilder.php ファイルの表示



namespace common\logic\Order\ProductOrder; namespace common\logic\Order\ProductOrder;


use common\logic\BaseBuilder;
use common\logic\BaseService; use common\logic\BaseService;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;
use common\logic\Config\TaxRate\TaxRate; use common\logic\Config\TaxRate\TaxRate;
use common\logic\User\User\User; use common\logic\User\User\User;
use common\logic\User\UserProducer\UserProducer; use common\logic\User\UserProducer\UserProducer;


class ProductOrderBuilder extends BaseService implements BuilderInterface
class ProductOrderBuilder extends BaseBuilder implements BuilderInterface
{ {
protected ProductSolver $productSolver; protected ProductSolver $productSolver;


public function instanciateProductOrder(Order $order, Product $product, float $quantity, float $price): ProductOrder public function instanciateProductOrder(Order $order, Product $product, float $quantity, float $price): ProductOrder
{ {
$productOrder = new ProductOrder(); $productOrder = new ProductOrder();

$productOrder->populateOrder($order); $productOrder->populateOrder($order);
$productOrder->populateProduct($product); $productOrder->populateProduct($product);
$productOrder->populateTaxRate($product->taxRate); $productOrder->populateTaxRate($product->taxRate);
public function createProductOrder(Order $order, Product $product, float $quantity, float $price): ProductOrder public function createProductOrder(Order $order, Product $product, float $quantity, float $price): ProductOrder
{ {
$productOrder = $this->instanciateProductOrder($order, $product, $quantity, $price); $productOrder = $this->instanciateProductOrder($order, $product, $quantity, $price);
$productOrder->save();
$this->saveCreate($productOrder);

return $productOrder; return $productOrder;
} }


public function updatePrice(
public function updateProductOrderPrice(
ProductOrder $productOrder, ProductOrder $productOrder,
User $user = null, User $user = null,
UserProducer $userProducer = null, UserProducer $userProducer = null,
'quantity' => $quantity 'quantity' => $quantity
]); ]);


$productOrder->save();
$this->saveUpdate($productOrder);


return $productOrder; return $productOrder;
} }


public function updateInvoicePrice(ProductOrder $productOrder, array $params = []): void
public function updateProductOrderInvoicePrice(ProductOrder $productOrder, array $params = []): void
{ {
$productOrder->invoice_price = $this->productSolver->getPrice($productOrder->product, [ $productOrder->invoice_price = $this->productSolver->getPrice($productOrder->product, [
'user' => isset($params['user']) ?? null, 'user' => isset($params['user']) ?? null,
'point_sale' => isset($params['point_sale']) ?? null, 'point_sale' => isset($params['point_sale']) ?? null,
'quantity' => $productOrder->quantity 'quantity' => $productOrder->quantity
]); ]);
$productOrder->save();
$this->saveUpdate($productOrder);
} }


public function deleteByOrder(Order $order): void
public function deleteProductOrdersByOrder(Order $order): void
{ {
ProductOrder::deleteAll(['id_order' => $order->id]); ProductOrder::deleteAll(['id_order' => $order->id]);
} }

+ 2
- 2
common/logic/Order/ProductOrder/ProductOrderRepository.php ファイルの表示



class ProductOrderRepository extends BaseService implements RepositoryInterface class ProductOrderRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => ['taxRate'], 'with' => ['taxRate'],
]; ];
} }


public function getByOrder(Order $order)
public function findProductOrdersByOrder(Order $order): array
{ {
return ProductOrder::find()->where(['id_order' => $order->id])->all(); return ProductOrder::find()->where(['id_order' => $order->id])->all();
} }

+ 21
- 16
common/logic/PointSale/PointSale/PointSaleBuilder.php ファイルの表示



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


use common\logic\BaseBuilder;
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\PointSale\UserPointSale\UserPointSale;
use common\logic\User\User\User; use common\logic\User\User\User;
use common\logic\User\User\UserRepository; use common\logic\User\User\UserRepository;


class PointSaleBuilder extends BaseService implements BuilderInterface
class PointSaleBuilder extends BaseBuilder implements BuilderInterface
{ {
protected UserPointSaleBuilder $userPointSaleBuilder; protected UserPointSaleBuilder $userPointSaleBuilder;
protected UserRepository $userRepository; protected UserRepository $userRepository;
return $pointSale; return $pointSale;
} }


public function createPointSale(): PointSale
{
$pointSale = $this->instanciatePointSale();
$this->saveCreate($pointSale);

return $pointSale;
}

/** /**
* Initialise les commandes liées au point de vente. * Initialise les commandes liées au point de vente.
*/ */
public function initOrders(PointSale $pointSale, array $ordersArray): void
public function initPointSaleOrders(PointSale $pointSale, array $ordersArray): void
{ {
$pointSale->orders = []; $pointSale->orders = [];
$pointSale->revenues = 0; $pointSale->revenues = 0;
} }
} }


public function resetPointProductions(Producer $producer): void
// resetPointProductions
public function resetPointSalePointProductions(Producer $producer): void
{ {
PointSale::updateAll( PointSale::updateAll(
['point_production' => 0], ['point_production' => 0],
* Traite la mise à jour de l'attribut 'point_production'. * Traite la mise à jour de l'attribut 'point_production'.
*/ */
// processPointProduction // processPointProduction
public function updatePointProduction(PointSale $pointSale): void
// updatePointProduction
public function updatePointSalePointProduction(PointSale $pointSale): void
{ {
if ($pointSale->point_production) { if ($pointSale->point_production) {
$this->resetPointProductions($pointSale->producer);
$this->resetPointSalePointProductions($pointSale->producer);
$pointSale->point_production = 1; $pointSale->point_production = 1;
$pointSale->save();
$this->saveUpdate($pointSale);
} }
} }


*/ */
public function processRestrictedAccess(PointSale $pointSale): void public function processRestrictedAccess(PointSale $pointSale): void
{ {
$this->userPointSaleBuilder->deleteByPointSale($pointSale);
$this->userPointSaleBuilder->deleteUserPointSaleByPointSale($pointSale);


if (is_array($pointSale->users) && count($pointSale->users)) { if (is_array($pointSale->users) && count($pointSale->users)) {
foreach ($pointSale->users as $key => $val) { foreach ($pointSale->users as $key => $val) {
$user = $this->userRepository->getOneById($val);
$user = $this->userRepository->findOneUserById($val);
if ($user) { if ($user) {
$this->userPointSaleBuilder->create($user, $pointSale, $pointSale->users_comment[$val]);
$this->userPointSaleBuilder->createUserPointSale($user, $pointSale, $pointSale->users_comment[$val]);
} }
} }
} }
// linkUser // linkUser
public function addUser(User $user, PointSale $pointSale): UserPointSale public function addUser(User $user, PointSale $pointSale): UserPointSale
{ {
$userPointSale = $this->userPointSaleRepository->getOne($user, $pointSale);

if (!$userPointSale) {
$userPointSale = $this->userPointSaleBuilder->create($user, $pointSale);
}

return $userPointSale;
return $this->userPointSaleBuilder->createUserPointSaleIfNotExist($user, $pointSale);
} }
} }

+ 2
- 2
common/logic/PointSale/PointSale/PointSaleRepository.php ファイルの表示



class PointSaleRepository extends BaseService implements RepositoryInterface class PointSaleRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],
); );
} }


public function populateDropdownList(): array
public function populatePointSaleDropdownList(): array
{ {
$pointSalesArrayDropdown = ['' => '--']; $pointSalesArrayDropdown = ['' => '--'];
$pointSalesArray = $this->get(); $pointSalesArray = $this->get();

+ 1
- 1
common/logic/PointSale/PointSale/PointSaleSearch.php ファイルの表示

public function search($params) public function search($params)
{ {
$optionsSearch = self::defaultOptionsSearch() ;
$optionsSearch = self::getDefaultOptionsSearch() ;
$query = PointSale::find() $query = PointSale::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])

+ 11
- 0
common/logic/PointSale/UserPointSale/UserPointSale.php ファイルの表示



use common\logic\PointSale\PointSale\PointSale; use common\logic\PointSale\PointSale\PointSale;
use common\components\ActiveRecordCommon ; use common\components\ActiveRecordCommon ;
use common\logic\User\User\User;


/** /**
* This is the model class for table "user_point_sale". * This is the model class for table "user_point_sale".
{ {
$this->populateFieldObject('id_point_sale', 'pointSale', $pointSale); $this->populateFieldObject('id_point_sale', 'pointSale', $pointSale);
} }

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

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

+ 19
- 9
common/logic/PointSale/UserPointSale/UserPointSaleBuilder.php ファイルの表示



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


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


class UserPointSaleBuilder extends BaseService implements BuilderInterface
class UserPointSaleBuilder extends BaseBuilder implements BuilderInterface
{ {
protected UserPointSaleRepository $userPointSaleRepository;

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

public function instanciateUserPointSale(User $user, PointSale $pointSale, string $comment = null): UserPointSale public function instanciateUserPointSale(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);
$userPointSale->populatePointSale($pointSale);
$userPointSale->populateUser($user);


if($comment) { if($comment) {
$userPointSale->comment = $comment; $userPointSale->comment = $comment;
public function createUserPointSale(User $user, PointSale $pointSale, string $comment = null): UserPointSale public function createUserPointSale(User $user, PointSale $pointSale, string $comment = null): UserPointSale
{ {
$userPointSale = $this->instanciateUserPointSale($user, $pointSale, $comment); $userPointSale = $this->instanciateUserPointSale($user, $pointSale, $comment);
$userPointSale->save();
$this->saveCreate($userPointSale);


return $userPointSale; return $userPointSale;
} }


public function deleteByPointSale(PointSale $pointSale): void
public function createUserPointSaleIfNotExist(User $user, PointSale $pointSale, string $comment = null): UserPointSale
{
return $this->userPointSaleRepository->findOneUserPointSale($user, $pointSale)
?? $this->createUserPointSale($user, $pointSale);
}

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

+ 2
- 2
common/logic/PointSale/UserPointSale/UserPointSaleRepository.php ファイルの表示



class UserPointSaleRepository extends BaseService implements RepositoryInterface class UserPointSaleRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],
] ; ] ;
} }


public function getOne(User $user, PointSale $pointSale)
public function findOneUserPointSale(User $user, PointSale $pointSale)
{ {
return UserPointSale::find() return UserPointSale::find()
->where([ ->where([

+ 12
- 10
common/logic/Producer/Producer/ProducerBuilder.php ファイルの表示



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


class ProducerBuilder extends BaseService implements BuilderInterface
class ProducerBuilder extends BaseBuilder implements BuilderInterface
{ {
protected ProducerRepository $producerRepository; protected ProducerRepository $producerRepository;
protected UserProducerRepository $userProducerRepository; protected UserProducerRepository $userProducerRepository;
public function instanciateProducer(): Producer public function instanciateProducer(): Producer
{ {
$producer = new Producer(); $producer = new Producer();

$producer->order_deadline = Producer::ORDER_DEADLINE_DEFAULT; $producer->order_deadline = Producer::ORDER_DEADLINE_DEFAULT;
$producer->order_delay = Producer::ORDER_DELAY_DEFAULT; $producer->order_delay = Producer::ORDER_DELAY_DEFAULT;


return $producer; return $producer;
} }


public function init(Producer $producer): void
public function initProducer(Producer $producer): void
{ {
$this->initSlug($producer);
$this->initCode($producer);
$this->initProducerSlug($producer);
$this->initProducerCode($producer);
} }


public function initSlug(Producer $producer): void
public function initProducerSlug(Producer $producer): void
{ {
$cptSlug = 0 ; $cptSlug = 0 ;
do { do {
} while($this->producerRepository->getOneBySlug($producer->slug)) ; } while($this->producerRepository->getOneBySlug($producer->slug)) ;
} }


public function initCode(Producer $producer): void
public function initProducerCode(Producer $producer): void
{ {
$producer->code = Password::generate(); $producer->code = Password::generate();
} }
*/ */
public function addUser(User $user, Producer $producer, int $bookmark = 1): UserProducer public function addUser(User $user, Producer $producer, int $bookmark = 1): UserProducer
{ {
$userProducer = $this->userProducerBuilder->createIfNotExist($user, $producer, $bookmark);
$userProducer = $this->userProducerBuilder->createUserProducerIfNotExist($user, $producer, $bookmark);


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

$this->saveUpdate($userProducer);


return $userProducer; return $userProducer;
} }
{ {
$versionsArray = Opendistrib::getVersions(); $versionsArray = Opendistrib::getVersions();
$producer->latest_version_opendistrib = array_values($versionsArray)[0]; $producer->latest_version_opendistrib = array_values($versionsArray)[0];
$producer->save();

$this->saveUpdate($producer);
} }


public function savePrivateKeyStripe($filename, $value) public function savePrivateKeyStripe($filename, $value)

+ 15
- 14
common/logic/Producer/Producer/ProducerRepository.php ファイルの表示

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\Document\Document\DocumentSolver;
use common\logic\PointSale\PointSale\PointSale; 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;
{ {
protected ProducerPriceRangeRepository $producerPriceRangeRepository; protected ProducerPriceRangeRepository $producerPriceRangeRepository;
protected ProducerSolver $producerSolver; protected ProducerSolver $producerSolver;
protected DocumentSolver $documentSolver;


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


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


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


public function getOneBySlug(string $slug)
public function findOneProducerBySlug(string $slug)
{ {
return Producer::searchOne(['slug' => $slug]); return Producer::searchOne(['slug' => $slug]);
} }


public function queryActive()
public function queryProducerActive()
{ {
return Producer::find() return Producer::find()
->where([ ->where([
* Retourne le compte producteur de démonstration. * Retourne le compte producteur de démonstration.
* *
*/ */
public function getOneDemoAccount()
public function findOneProducerDemoAccount()
{ {
return Producer::find()->where('name LIKE \'Démo\'')->one(); return Producer::find()->where('name LIKE \'Démo\'')->one();
} }


/** /**
* Retourne la liste des établissements pour l'initialisation d'une liste
* sélective.
*
* @return array
* Retourne la liste des établissements pour l'initialisation d'une listesélective.
*/ */
public static function getPopulateDropdown(): array public static function getPopulateDropdown(): array
{ {
$turnover = $this->getTurnover($producer, $month); $turnover = $this->getTurnover($producer, $month);


if ($turnover) { if ($turnover) {
$isBold = $this->isBillingTypeClassic() && !$this->option_billing_permanent_transfer;
$isBold = $this->producerSolver->isBillingTypeClassic($producer) && !$producer->option_billing_permanent_transfer;
if ($isBold) $text .= '<strong>'; if ($isBold) $text .= '<strong>';
$text .= $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, true); $text .= $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, true);
if ($isBold) $text .= '</strong>'; if ($isBold) $text .= '</strong>';
$idProducer = GlobalParam::getCurrentProducerId(); $idProducer = GlobalParam::getCurrentProducerId();
} }


$producer = $this->getOneById($idProducer);
$producer = $this->findOneProducerById($idProducer);
if ($producer) { if ($producer) {
return $producer->$config; return $producer->$config;
} }
/** /**
* Retourne les établissements liés à l'utilisateur. * Retourne les établissements liés à l'utilisateur.
*/ */
public function getBookmarked(User $user): array
// getBookmarked
public function findProducersBookmarked(User $user): array
{ {
$producers = (new \yii\db\Query()) $producers = (new \yii\db\Query())
->select('*') ->select('*')


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


public function isDocumentDisplayOrders(DocumentInterface $document): bool public function isDocumentDisplayOrders(DocumentInterface $document): bool
{ {
return ($document->getClass() == 'Invoice') ?
return ($this->documentSolver->getClass($document) == 'Invoice') ?
$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');
} }

+ 23
- 0
common/logic/Producer/ProducerPriceRange/ProducerPriceRangeBuilder.php ファイルの表示

<?php

namespace common\logic\Producer\ProducerPriceRange;

use common\logic\BaseBuilder;

class ProducerPriceRangeBuilder extends BaseBuilder
{
public function instanciateProducerPriceRange(): ProducerPriceRange
{
$producerPriceRange = new ProducerPriceRange();

return $producerPriceRange;
}

public function createProducerPriceRange(): ProducerPriceRange
{
$producerPriceRange = $this->instanciateProducerPriceRange();
$this->saveCreate($producerPriceRange);

return $producerPriceRange;
}
}

+ 1
- 0
common/logic/Producer/ProducerPriceRange/ProducerPriceRangeManager.php ファイルの表示



/** /**
* @mixin ProducerPriceRangeRepository * @mixin ProducerPriceRangeRepository
* @mixin ProducerPriceRangeBuilder
*/ */
class ProducerPriceRangeManager extends BaseManager class ProducerPriceRangeManager extends BaseManager
{ {

+ 8
- 3
common/logic/Producer/ProducerPriceRange/ProducerPriceRangeRepository.php ファイルの表示

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


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


public function findProducerPriceRanges()
{
return $this->queryProducerPriceRanges()->all();
}

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

+ 11
- 3
common/logic/Product/Product/ProductBuilder.php ファイルの表示



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


use common\logic\BaseService;
use common\logic\BaseBuilder;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;


class ProductBuilder extends BaseService implements BuilderInterface
class ProductBuilder extends BaseBuilder implements BuilderInterface
{ {
public function instanciate(): Product
public function instanciateProduct(): Product
{ {
$product = new Product(); $product = new Product();


return $product; return $product;
} }

public function createProduct(): Product
{
$product = $this->instanciateProduct();
$this->saveCreate($product);

return $product;
}
} }

+ 34
- 32
common/logic/Product/Product/ProductRepository.php ファイルの表示

$this->userProducerRepository = $this->loadService(UserProducerRepository::class); $this->userProducerRepository = $this->loadService(UserProducerRepository::class);
} }


public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => ['taxRate', 'productPointSale'], 'with' => ['taxRate', 'productPointSale'],
]; ];
} }


public function get(): array
public function findProducts(): array
{ {
return Product::searchAll(); return Product::searchAll();
} }
/** /**
* Retourne le nombre de produits du producteur courant. * Retourne le nombre de produits du producteur courant.
*/ */
public static function count(): int
public static function countProducts(): int
{ {
return Product::searchCount(); return Product::searchCount();
} }
* Retourne les produits d'une production donnée. * Retourne les produits d'une production donnée.
*/ */
// searchByDistribution // searchByDistribution
public function getByDistribution(Distribution $distribution)
// getByDistribution
public function findProductsByDistribution(Distribution $distribution)
{ {
return Product::find() return Product::find()
->leftJoin('product_distribution', 'product.id = product_distribution.id_product') ->leftJoin('product_distribution', 'product.id = product_distribution.id_product')
->all(); ->all();
} }


// queryByProductCategory
public function queryProductsByProductCategory(ProductCategory $productCategory)
{
return Product::find()
->andWhere([
'id_producer' => $productCategory->id_producer,
'active' => true,
])
->andWhere(
'product.id_product_category = :id_product_category'
)
->params(
[':id_product_category' => $productCategory->id]
)
->orderBy(
'order ASC'
);
}

public function countProductsWithoutCategory(Producer $producer): int
{
return Product::searchCount([
'id_producer' => $producer->id,
'product.active' => 1,
'product.id_product_category' => null
]);
}

public function getPriceArray(Product $product, User $user, PointSale $pointSale): array public function getPriceArray(Product $product, User $user, PointSale $pointSale): array
{ {
$priceArray = []; $priceArray = [];
$userProducer = null; $userProducer = null;
if ($user) { if ($user) {
$userProducer = $this->userProducerRepository->getOne($user, GlobalParam::getCurrentProducer());
$userProducer = $this->userProducerRepository->findOneUserProducer($user, GlobalParam::getCurrentProducer());
} }


// specific prices // specific prices


return $priceArray; return $priceArray;
} }

public function queryByProductCategory(ProductCategory $productCategory)
{
return Product::find()
->andWhere([
'id_producer' => $productCategory->id_producer,
'active' => true,
])
->andWhere(
'product.id_product_category = :id_product_category'
)
->params(
[':id_product_category' => $productCategory->id]
)
->orderBy(
'order ASC'
);
}

public function countProductsWithoutCategory(Producer $producer): int
{
return Product::searchCount([
'id_producer' => $producer->id,
'product.active' => 1,
'product.id_product_category' => null
]);
}
} }

+ 1
- 1
common/logic/Product/Product/ProductSearch.php ファイルの表示

public function search($params) public function search($params)
{ {
$optionsSearch = self::defaultOptionsSearch() ;
$optionsSearch = self::getDefaultOptionsSearch() ;
$query = Product::find() $query = Product::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])

+ 11
- 2
common/logic/Product/ProductCategory/ProductCategoryBuilder.php ファイルの表示



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


use common\logic\BaseBuilder;
use common\logic\BaseService; use common\logic\BaseService;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;


class ProductCategoryBuilder extends BaseService implements BuilderInterface
class ProductCategoryBuilder extends BaseBuilder implements BuilderInterface
{ {
public function instanciate(): ProductCategory
public function instanciateProductCategory(): ProductCategory
{ {
$productCategory = new ProductCategory(); $productCategory = new ProductCategory();


return $productCategory; return $productCategory;
} }

public function createProductCategory(): ProductCategory
{
$productCategory = $this->instanciateProductCategory();
$this->saveCreate($productCategory);

return $productCategory;
}
} }

+ 5
- 5
common/logic/Product/ProductCategory/ProductCategoryRepository.php ファイルの表示



class ProductCategoryRepository extends BaseService implements RepositoryInterface class ProductCategoryRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],
]; ];
} }


public function get()
public function findProductCategories()
{ {
return ProductCategory::searchAll([], ['orderby' => 'product_category.position ASC']); return ProductCategory::searchAll([], ['orderby' => 'product_category.position ASC']);
} }


public function getAsArray()
public function findProductCategoriesAsArray()
{ {
return ProductCategory::searchAll( return ProductCategory::searchAll(
[], [],
); );
} }


public function populateDropdownList()
public function populateProductCategoriesDropdownList()
{ {
$productCategoriesArrayDropdown = ['' => '--']; $productCategoriesArrayDropdown = ['' => '--'];
$productCategoriesArray = $this->get();
$productCategoriesArray = $this->findProductCategories();


foreach ($productCategoriesArray as $productCategory) { foreach ($productCategoriesArray as $productCategory) {
$productCategoriesArrayDropdown[$productCategory['id']] = $productCategory['name']; $productCategoriesArrayDropdown[$productCategory['id']] = $productCategory['name'];

+ 1
- 1
common/logic/Product/ProductCategory/ProductCategorySearch.php ファイルの表示

public function search($params) public function search($params)
{ {
$optionsSearch = self::defaultOptionsSearch() ;
$optionsSearch = self::getDefaultOptionsSearch() ;
$query = ProductCategory::find() $query = ProductCategory::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])

+ 11
- 3
common/logic/Product/ProductPointSale/ProductPointSaleBuilder.php ファイルの表示



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


use common\logic\BaseService;
use common\logic\BaseBuilder;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;


class ProductPointSaleBuilder extends BaseService implements BuilderInterface
class ProductPointSaleBuilder extends BaseBuilder implements BuilderInterface
{ {
public function instanciate(): ProductPointSale
public function instanciateProductPointSale(): ProductPointSale
{ {
$productPointSale = new ProductPointSale(); $productPointSale = new ProductPointSale();


return $productPointSale; return $productPointSale;
} }

public function createProductPointSale(): ProductPointSale
{
$productPointSale = $this->instanciateProductPointSale();
$this->saveCreate($productPointSale);

return $productPointSale;
}
} }

+ 1
- 1
common/logic/Product/ProductPointSale/ProductPointSaleRepository.php ファイルの表示



class ProductPointSaleRepository extends BaseService implements RepositoryInterface class ProductPointSaleRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => ['product', 'pointSale'], 'with' => ['product', 'pointSale'],

+ 11
- 3
common/logic/Product/ProductPrice/ProductPriceBuilder.php ファイルの表示



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


use common\logic\BaseService;
use common\logic\BaseBuilder;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;


class ProductPriceBuilder extends BaseService implements BuilderInterface
class ProductPriceBuilder extends BaseBuilder implements BuilderInterface
{ {
public function instanciate(): ProductPrice
public function instanciateProductPrice(): ProductPrice
{ {
$productPrice = new ProductPrice(); $productPrice = new ProductPrice();


return $productPrice; return $productPrice;
} }

public function createProductPrice(): ProductPrice
{
$productPrice = $this->instanciateProductPrice();
$this->saveCreate($productPrice);

return $productPrice;
}
} }

+ 1
- 1
common/logic/Product/ProductPrice/ProductPriceRepository.php ファイルの表示

/** /**
* Retourne les options de base nécessaires à la fonction de recherche. * Retourne les options de base nécessaires à la fonction de recherche.
*/ */
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => ['user', 'pointSale'], 'with' => ['user', 'pointSale'],

+ 1
- 1
common/logic/Product/ProductPrice/ProductPriceSearch.php ファイルの表示



public function search($params) public function search($params)
{ {
$optionsSearch = self::defaultOptionsSearch() ;
$optionsSearch = self::getDefaultOptionsSearch() ;


$query = ProductPrice::find() $query = ProductPrice::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])

+ 11
- 3
common/logic/Subscription/ProductSubscription/ProductSubscriptionBuilder.php ファイルの表示



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


use common\logic\BaseService;
use common\logic\BaseBuilder;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;


class ProductSubscriptionBuilder extends BaseService implements BuilderInterface
class ProductSubscriptionBuilder extends BaseBuilder implements BuilderInterface
{ {
public function instanciate(): ProductSubscription
public function instanciateProductSubscription(): ProductSubscription
{ {
$productSubscription = new ProductSubscription(); $productSubscription = new ProductSubscription();


return $productSubscription; return $productSubscription;
} }

public function createProductSubscription(): ProductSubscription
{
$productSubscription = $this->instanciateProductSubscription();
$this->saveCreate($productSubscription);

return $productSubscription;
}
} }

+ 1
- 1
common/logic/Subscription/ProductSubscription/ProductSubscriptionRepository.php ファイルの表示

/** /**
* Retourne les options de base nécessaires à la fonction de recherche. * Retourne les options de base nécessaires à la fonction de recherche.
*/ */
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => ['product'], 'with' => ['product'],

+ 14
- 11
common/logic/Subscription/Subscription/SubscriptionBuilder.php ファイルの表示



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


use common\logic\BaseService;
use common\logic\BaseBuilder;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;
use common\logic\Distribution\Distribution\Distribution;
use common\logic\Distribution\Distribution\DistributionRepository; use common\logic\Distribution\Distribution\DistributionRepository;
use common\logic\PointSale\PointSale\PointSale;
use common\logic\Producer\Producer\Producer;
use common\logic\Subscription\ProductSubscription\ProductSubscription; use common\logic\Subscription\ProductSubscription\ProductSubscription;
use common\logic\User\User\User;
use common\logic\User\UserProducer\UserProducer;


class SubscriptionBuilder extends BaseService implements BuilderInterface
class SubscriptionBuilder extends BaseBuilder implements BuilderInterface
{ {
protected DistributionRepository $distributionRepository; protected DistributionRepository $distributionRepository;


$this->distributionRepository = $this->loadService(DistributionRepository::class); $this->distributionRepository = $this->loadService(DistributionRepository::class);
} }


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


return $subscription; return $subscription;
} }


public function delete(Subscription $subscription): void
public function createSubscription(): Subscription
{ {
ProductSubscription::deleteAll(['id_subscription' => $id]);
$subscription->delete();
$subscription = $this->instanciateSubscription();
$this->saveCreate($subscription);

return $subscription;
}

public function deleteSubscription(Subscription $subscription): void
{
ProductSubscription::deleteAll(['id_subscription' => $subscription->id]);
$this->delete($subscription);
} }
} }

+ 19
- 0
common/logic/Subscription/Subscription/SubscriptionEventSubscriber.php ファイルの表示

<?php

namespace common\logic\Subscription\Subscription;

use common\logic\Distribution\Distribution\Distribution;
use common\logic\Order\Order\OrderManager;

class SubscriptionEventSubscriber
{
/**
* @param Distribution $distribution
* @return void
*/
public static function onActiveDistribution(Distribution $distribution): void
{
$orderManager = new OrderManager();
$orderManager->createAllOrdersFromSubscriptions($distribution->date);
}
}

+ 9
- 46
common/logic/Subscription/Subscription/SubscriptionRepository.php ファイルの表示

$this->subscriptionSolver = $this->loadService(SubscriptionSolver::class); $this->subscriptionSolver = $this->loadService(SubscriptionSolver::class);
} }


public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => ['producer'], 'with' => ['producer'],
]; ];
} }


public function getOneById(int $id): ?Subscription
public function findOneSubscriptionById(int $id): ?Subscription
{ {
return Subscription::searchOne(['id' => $id]); return Subscription::searchOne(['id' => $id]);
} }


public function get()
public function findSubscriptions()
{ {
return Subscription::searchAll(); return Subscription::searchAll();
} }
/** /**
* Retourne les abonnements pour une date donnée. * Retourne les abonnements pour une date donnée.
*/ */
// searchByDate
public function getByDate(string $date)
// searchByDate, getByDate
public function findSubscriptionsByDate(string $date)
{ {
$date = date('Y-m-d', strtotime($date)); $date = date('Y-m-d', strtotime($date));
$subscriptionArray = $this->get();
$subscriptionArray = $this->findSubscriptions();
$subscriptionReturnArray = []; $subscriptionReturnArray = [];


foreach ($subscriptionArray as $subscription) { foreach ($subscriptionArray as $subscription) {
if ($date >= $subscription->date_begin && if ($date >= $subscription->date_begin &&
(!$subscription->date_end || $date <= $subscription->date_end) &&
$subscription->matchWith($date)) {
(!$subscription->date_end || $date <= $subscription->date_end)
&& $this->subscriptionSolver->isSubscriptionMatchWith($subscription, $date)) {
$subscriptionReturnArray[] = $subscription; $subscriptionReturnArray[] = $subscription;
} }
} }
return $subscriptionReturnArray; return $subscriptionReturnArray;
} }


/**
* Recherche les distributions futures où l'abonnement peut s'appliquer.
*/
public function searchMatchedIncomingDistributions(Subscription $subscription): array
{
$params = [
':date_earliest_order' => date('Y-m-d'),
':date_begin' => date('Y-m-d', strtotime($subscription->date_begin)),
':id_producer' => GlobalParam::getCurrentProducerId()
];

$incomingDistributions = Distribution::find()
->where('id_producer = :id_producer')
->andWhere('date >= :date_begin')
->andWhere('date > :date_earliest_order');

if ($subscription->date_end) {
$incomingDistributions->andWhere('date <= :date_end');
$params[':date_end'] = date('Y-m-d', strtotime($subscription->date_end));
}

$incomingDistributions->orderBy('date ASC');

$incomingDistributions->params($params);
$incomingDistributionsArray = $incomingDistributions->all();
$this->subscriptionSolver->filterDistributionsByDateDelay($incomingDistributionsArray);

$matchedIncomingDistributionsArray = [];
foreach ($incomingDistributionsArray as $incomingDistribution) {
if ($this->subscriptionSolver->matchWith($subscription, $incomingDistribution->date)) {
$matchedIncomingDistributionsArray[] = $incomingDistribution;
}
}

return $matchedIncomingDistributionsArray;
}

public function count(User $user, Producer $producer)
public function countSubscriptionsByUser(User $user, Producer $producer)
{ {
return Subscription::find() return Subscription::find()
->where([ ->where([

+ 1
- 1
common/logic/Subscription/Subscription/SubscriptionSearch.php ファイルの表示

public function search($params) { public function search($params) {
$optionsSearch = self::defaultOptionsSearch() ;
$optionsSearch = self::getDefaultOptionsSearch() ;
$query = Subscription::find() $query = Subscription::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])

+ 1
- 1
common/logic/Subscription/Subscription/SubscriptionSolver.php ファイルの表示

/** /**
* Valide le fait qu'un abonnement est bien compatible avec une date donnée. * Valide le fait qu'un abonnement est bien compatible avec une date donnée.
*/ */
public function matchWith(Subscription $subscription, string $date): bool
public function isSubscriptionMatchWith(Subscription $subscription, string $date): bool
{ {
$arrayDays = [ $arrayDays = [
1 => 'monday', 1 => 'monday',

+ 24
- 0
common/logic/User/CreditHistory/CreditHistory.php ファイルの表示

namespace common\logic\User\CreditHistory; namespace common\logic\User\CreditHistory;


use common\components\ActiveRecordCommon; use common\components\ActiveRecordCommon;
use common\logic\Producer\Producer\Producer;
use common\logic\User\User\User; use common\logic\User\User\User;
use common\logic\Order\Order\Order; use common\logic\Order\Order\Order;
use common\logic\User\UserProducer\UserProducerEventSubscriber;
use yii\db\ActiveQuery; use yii\db\ActiveQuery;
use yii\db\ActiveRecord;




class CreditHistory extends ActiveRecordCommon class CreditHistory extends ActiveRecordCommon
{ {
const EVENT_CREATE = 'creditHistory.create';

const TYPE_INITIAL_CREDIT = 'initial-credit'; const TYPE_INITIAL_CREDIT = 'initial-credit';
const TYPE_CREDIT = 'credit'; const TYPE_CREDIT = 'credit';
const TYPE_PAYMENT = 'payment'; const TYPE_PAYMENT = 'payment';
]; ];
} }


public function init()
{
$this->on(CreditHistory::EVENT_CREATE, function($event) {
UserProducerEventSubscriber::onCreateCreditHistory($event->creditHistory);
});

parent::init();
}

/* /*
* Relations * Relations
*/ */


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

public function populateProducer(Producer $producer): void
{
$this->populateFieldObject('id_producer', 'producer', $producer);
}

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

+ 13
- 21
common/logic/User/CreditHistory/CreditHistoryBuilder.php ファイルの表示



namespace common\logic\User\CreditHistory; namespace common\logic\User\CreditHistory;


use common\logic\BaseService;
use common\logic\BaseBuilder;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;
use common\logic\Order\Order\Order; use common\logic\Order\Order\Order;
use common\logic\Producer\Producer\Producer; use common\logic\Producer\Producer\Producer;
use common\logic\User\User\User; use common\logic\User\User\User;
use common\logic\User\UserProducer\UserProducerBuilder;
use yii\base\Event;
use yii\db\ActiveRecord;


class CreditHistoryBuilder extends BaseService implements BuilderInterface
class CreditHistoryBuilder extends BaseBuilder implements BuilderInterface
{ {
protected CreditHistorySolver $creditHistorySolver; protected CreditHistorySolver $creditHistorySolver;


$this->creditHistorySolver = $this->loadService(CreditHistorySolver::class); $this->creditHistorySolver = $this->loadService(CreditHistorySolver::class);
} }


public function instanciate(
public function instanciateCreditHistory(
string $type, string $type,
float $amount, float $amount,
Producer $producer, Producer $producer,


$creditHistory->type = $type; $creditHistory->type = $type;
$creditHistory->amount = round($amount, 2); $creditHistory->amount = round($amount, 2);
$creditHistory->id_producer = $producer->id;
$creditHistory->populateRelation('producer', $producer);
$creditHistory->id_user = $user->id;
$creditHistory->populateRelation('user', $user);
$creditHistory->id_user_action = $userAction->id;
$creditHistory->populateRelation('userAction', $userAction);
$creditHistory->populateProducer($producer);
$creditHistory->populateUser($user);
$creditHistory->populateUserAction($userAction);


if($order) { if($order) {
$creditHistory->id_order = $order->id;
$creditHistory->populateRelation('order', $order);
$creditHistory->populateOrder($order);
} }


if($meanPayment) { if($meanPayment) {
} }


// saveCreditHistory // saveCreditHistory
public function create(
public function createCreditHistory(
string $type, string $type,
float $amount, float $amount,
Producer $producer, Producer $producer,
return null; return null;
} }


$creditHistory = $this->instanciate($type, $amount, $producer, $user, $userAction, $meanPayment, $order);

// Initialisation du commentaire avant sauvegarde
$creditHistory = $this->instanciateCreditHistory($type, $amount, $producer, $user, $userAction, $meanPayment, $order);
$creditHistory->setComment($creditHistory->getComment() . $this->creditHistorySolver->getStrComment($creditHistory)); $creditHistory->setComment($creditHistory->getComment() . $this->creditHistorySolver->getStrComment($creditHistory));
$this->saveCreate($creditHistory);


$creditHistory->save();

// Mise à jour du crédit au niveau de UserProducer
// @TODO : à gérer avec les événements
//$this->userProducerBuilder->updateCredit($creditHistory);
$creditHistory->trigger(CreditHistory::EVENT_CREATE, new Event(['creditHistory' => $creditHistory]));


return $creditHistory; return $creditHistory;
} }

+ 1
- 1
common/logic/User/CreditHistory/CreditHistoryRepository.php ファイルの表示



class CreditHistoryRepository extends BaseService implements RepositoryInterface class CreditHistoryRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],

+ 1
- 1
common/logic/User/CreditHistory/CreditHistorySearch.php ファイルの表示

public function search($params) public function search($params)
{ {
$optionsSearch = CreditHistoryRepository::defaultOptionsSearch() ;
$optionsSearch = CreditHistoryRepository::getDefaultOptionsSearch() ;
$query = CreditHistory::find() $query = CreditHistory::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])

+ 4
- 4
common/logic/User/User/UserBuilder.php ファイルの表示



namespace common\logic\User\User; namespace common\logic\User\User;


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


class UserBuilder extends BaseService implements BuilderInterface
class UserBuilder extends BaseBuilder implements BuilderInterface
{ {
public function instanciate(): User
public function instanciateUser(): User
{ {
$user = new User(); $user = new User();


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


/** /**
* Generates password hash from password and sets it to the model * Generates password hash from password and sets it to the model
*
*/ */
public function setPassword(User $user, string $password): void public function setPassword(User $user, string $password): void
{ {

+ 28
- 20
common/logic/User/User/UserRepository.php ファイルの表示



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


class UserRepository extends BaseService implements RepositoryInterface class UserRepository extends BaseService implements RepositoryInterface
* *
* @return array * @return array
*/ */
public function defaultOptionsSearch()
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],
]; ];
} }


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


public function belongsToUserGroup(User $user, int $userGroupId): bool
// belongsToUserGroup
public function isUserbelongsToUserGroup(User $user, UserGroup $userGroup): bool
{ {
if (!$user->userUserGroup) { if (!$user->userUserGroup) {
$user->populateRelation('userUserGroup', UserUserGroup::searchAll([ $user->populateRelation('userUserGroup', UserUserGroup::searchAll([


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


public static function populateDropdownList()
public function findUsers(): array
{ {
$usersArray = User::findBy()->all();
return $this->queryUsersBy()->all();
}

public static function populateUserDropdownList()
{
$usersArray =
$usersArrayDropdown = ['' => '--']; $usersArrayDropdown = ['' => '--'];


foreach ($usersArray as $user) { foreach ($usersArray as $user) {
* le point de vente de la dernière commande sinon. * le point de vente de la dernière commande sinon.
* *
*/ */
public function getFavoritePointSale(User $user): ?PointSale
public function getUserFavoritePointSale(User $user): ?PointSale
{ {
$arrayUserPointSale = UserPointSale::find() $arrayUserPointSale = UserPointSale::find()
->innerJoinWith('pointSale', true) ->innerJoinWith('pointSale', true)
*/ */
public function getCredit(User $user, Producer $producer): float public function getCredit(User $user, Producer $producer): float
{ {
$userProducer = $this->userProducerRepository->getOne($user, $producer);

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

return 0;
$userProducer = $this->userProducerRepository->findOneUserProducer($user, $producer);
return $userProducer ? $userProducer->credit : 0;
} }


/** /**
* @param array $params * @param array $params
* @return Query * @return Query
*/ */
public static function findBy($params = [])
// findBy
public function queryUsersBy(array $params = [])
{ {
if (!isset($params['id_producer'])) { if (!isset($params['id_producer'])) {
$params['id_producer'] = GlobalParam::getCurrentProducerId(); $params['id_producer'] = GlobalParam::getCurrentProducerId();


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


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


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

+ 1
- 1
common/logic/User/User/UserSearch.php ファイルの表示



public function search($params = []) public function search($params = [])
{ {
$optionsSearch = self::defaultOptionsSearch();
$optionsSearch = self::getDefaultOptionsSearch();


$query = User::find() $query = User::find()
->select( ->select(

+ 11
- 3
common/logic/User/UserGroup/UserGroupBuilder.php ファイルの表示



namespace common\logic\User\UserGroup; namespace common\logic\User\UserGroup;


use common\logic\BaseService;
use common\logic\BaseBuilder;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;


class UserGroupBuilder extends BaseService implements BuilderInterface
class UserGroupBuilder extends BaseBuilder implements BuilderInterface
{ {
public function instanciate(): UserGroup
public function instanciateUserGroup(): UserGroup
{ {
$userGroup = new UserGroup(); $userGroup = new UserGroup();


return $userGroup; return $userGroup;
} }

public function createUserGroup(): UserGroup
{
$userGroup = $this->instanciateUserGroup();
$this->saveCreate($userGroup);

return $userGroup;
}
} }

+ 8
- 3
common/logic/User/UserGroup/UserGroupRepository.php ファイルの表示



class UserGroupRepository extends BaseService implements RepositoryInterface class UserGroupRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch()
public function getDefaultOptionsSearch()
{ {
return [ return [
'with' => [], 'with' => [],
]; ];
} }


public function populateDropdownList(): array
public function findUserGroups()
{
return UserGroup::find()->where('id_producer = ' . GlobalParam::getCurrentProducerId())->all();
}

public function populateUserGroupDropdownList(): array
{ {
$userGroupsArrayDropdown = ['' => '--']; $userGroupsArrayDropdown = ['' => '--'];
$userGroupsArray = UserGroup::find()->where('id_producer = ' . GlobalParam::getCurrentProducerId())->all();
$userGroupsArray = $this->findUserGroups();


foreach ($userGroupsArray as $userGroup) { foreach ($userGroupsArray as $userGroup) {
$userGroupsArrayDropdown[$userGroup['id']] = $userGroup['name']; $userGroupsArrayDropdown[$userGroup['id']] = $userGroup['name'];

+ 1
- 1
common/logic/User/UserGroup/UserGroupSearch.php ファイルの表示

public function search($params) public function search($params)
{ {
$optionsSearch = self::defaultOptionsSearch() ;
$optionsSearch = self::getDefaultOptionsSearch() ;
$query = UserGroup::find() $query = UserGroup::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])

+ 25
- 20
common/logic/User/UserProducer/UserProducerBuilder.php ファイルの表示

namespace common\logic\User\UserProducer; namespace common\logic\User\UserProducer;


use common\helpers\MeanPayment; use common\helpers\MeanPayment;
use common\logic\BaseBuilder;
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\Order\Order\OrderRepository;
use common\logic\Producer\Producer\Producer; use common\logic\Producer\Producer\Producer;
use common\logic\Producer\Producer\ProducerRepository;
use common\logic\User\CreditHistory\CreditHistory; use common\logic\User\CreditHistory\CreditHistory;
use common\logic\User\CreditHistory\CreditHistorySolver; use common\logic\User\CreditHistory\CreditHistorySolver;
use common\logic\User\User\User; use common\logic\User\User\User;


class UserProducerBuilder extends BaseService implements BuilderInterface
class UserProducerBuilder extends BaseBuilder implements BuilderInterface
{ {
protected CreditHistorySolver $creditHistorySolver; protected CreditHistorySolver $creditHistorySolver;
protected UserProducerRepository $userProducerRepository; protected UserProducerRepository $userProducerRepository;
protected OrderRepository $orderRepository;
protected ProducerRepository $producerRepository;


public function __construct() public function __construct()
{ {
$this->creditHistorySolver = $this->loadService(CreditHistorySolver::class); $this->creditHistorySolver = $this->loadService(CreditHistorySolver::class);
$this->userProducerRepository = $this->loadService(UserProducerRepository::class); $this->userProducerRepository = $this->loadService(UserProducerRepository::class);
$this->orderRepository = $this->loadService(OrderRepository::class);
$this->producerRepository = $this->loadService(ProducerRepository::class);
} }


public function instanciate(User $user, Producer $producer, int $bookmark = 1)
public function instanciateUserProducer(User $user, Producer $producer, int $bookmark = 1)
{ {
$userProducer = new UserProducer(); $userProducer = new UserProducer();


return $userProducer; return $userProducer;
} }


public function create(User $user, Producer $producer, int $bookmark = 1): UserProducer
public function createUserProducer(User $user, Producer $producer, int $bookmark = 1): UserProducer
{ {
$userProducer = $this->instanciate($user, $producer, $bookmark);
$userProducer->save();
$userProducer = $this->instanciateUserProducer($user, $producer, $bookmark);
$this->saveCreate($userProducer);
return $userProducer; return $userProducer;
} }


public function createIfNotExist(User $user, Producer $producer, int $bookmark = 1): UserProducer
public function createUserProducerIfNotExist(User $user, Producer $producer, int $bookmark = 1): UserProducer
{ {
$userProducer = $this->userProducerRepository->getOne($user, $producer);
if (!$userProducer) {
$userProducer = $this->create($user, $producer, $bookmark);
}

return $userProducer;
return $this->userProducerRepository->findOneUserProducer($user, $producer)
?? $this->createUserProducer($user, $producer, $bookmark);
} }


public function updateCredit(CreditHistory $creditHistory): void public function updateCredit(CreditHistory $creditHistory): void
{ {
$userProducer = $this->userProducerRepository->getOne($creditHistory->getIdUser(), $creditHistory->getIdProducer());
$userProducer = $this->userProducerRepository->findOneUserProducer($creditHistory->user, $creditHistory->producer);


if ($userProducer) { if ($userProducer) {
$oldCredit = $userProducer->getCredit(); $oldCredit = $userProducer->getCredit();
$userProducer->setCredit($userProducer->getCredit() - $creditHistory->getAmount()); $userProducer->setCredit($userProducer->getCredit() - $creditHistory->getAmount());
} }


$userProducer->save();
$this->saveUpdate($userProducer);
} }


public function initMeanPaymentOrder($creditHistory) public function initMeanPaymentOrder($creditHistory)
{ {
// set mean payment
if ($creditHistory->id_order && $creditHistory->id_order > 0) { if ($creditHistory->id_order && $creditHistory->id_order > 0) {
$order = Order::searchOne(['id' => (int)$creditHistory->id_order]);
$order = $this->orderRepository->findOneOrderById((int) $creditHistory->id_order);


if ($order) { if ($order) {
$paymentStatus = $order->getPaymentStatus(); $paymentStatus = $order->getPaymentStatus();
|| $paymentStatus == Order::PAYMENT_SURPLUS) { || $paymentStatus == Order::PAYMENT_SURPLUS) {


$order->mean_payment = MeanPayment::CREDIT; $order->mean_payment = MeanPayment::CREDIT;
$order->save();

$this->saveUpdate($order);
} }
} }
} }


public function isCreditLimitCrossed($oldCredit, $newCredit) public function isCreditLimitCrossed($oldCredit, $newCredit)
{ {
$creditLimitReminder = Producer::getConfig('credit_limit_reminder');
$creditLimitReminder = $this->producerRepository->getConfig('credit_limit_reminder');


return !is_null($creditLimitReminder) && return !is_null($creditLimitReminder) &&
$oldCredit > $creditLimitReminder $oldCredit > $creditLimitReminder


public function updateActive(User $user, Producer $producer, bool $active): void public function updateActive(User $user, Producer $producer, bool $active): void
{ {
$userProducer = $this->getUserProducerContainer()->getRepository()->getOne(
$userProducer = $this->createUserProducerIfNotExist(
$user, $user,
$producer $producer
); );

$userProducer->active = $active; $userProducer->active = $active;
$userProducer->save();

$this->saveUpdate($userProducer);
} }
} }

+ 12
- 0
common/logic/User/UserProducer/UserProducerEventSubscriber.php ファイルの表示

<?php

namespace common\logic\User\UserProducer;

class UserProducerEventSubscriber
{
public static function onCreateCreditHistory($event)
{
$userProducerManager = new UserProducerManager();
$userProducerManager->updateCredit($event->creditHistory);
}
}

+ 3
- 3
common/logic/User/UserProducer/UserProducerRepository.php ファイルの表示



class UserProducerRepository extends BaseService implements RepositoryInterface class UserProducerRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],
]; ];
} }


public function getOne(User $user, Producer $producer)
public function findOneUserProducer(User $user, Producer $producer)
{ {
return UserProducer::searchOne([ return UserProducer::searchOne([
'id_user' => $user->id, 'id_user' => $user->id,
]); ]);
} }


public function getBy(User $user, $active = 1, $bookmark = 1)
public function findUserProducersByUser(User $user, bool $active = true, bool $bookmark = true)
{ {
return UserProducer::find() return UserProducer::find()
->with(['producer']) ->with(['producer'])

+ 12
- 2
common/logic/User/UserUserGroup/UserUserGroupBuilder.php ファイルの表示



namespace common\logic\User\UserGroup; namespace common\logic\User\UserGroup;


use common\logic\BaseBuilder;
use common\logic\BaseService; use common\logic\BaseService;
use common\logic\BuilderInterface; use common\logic\BuilderInterface;
use common\logic\User\UserUserGroup\UserUserGroup;


class UserUserGroupBuilder extends BaseService implements BuilderInterface
class UserUserGroupBuilder extends BaseBuilder implements BuilderInterface
{ {
public function instanciate(): UserUserGroup
public function instanciateUserUserGroup(): UserUserGroup
{ {
$userUserGroup = new UserUserGroup(); $userUserGroup = new UserUserGroup();


return $userUserGroup; return $userUserGroup;
} }

public function createUserUserGroup(): UserUserGroup
{
$userUserGroup = $this->instanciateUserUserGroup();
$this->saveCreate($userUserGroup);

return $userUserGroup;
}
} }

+ 1
- 1
common/logic/User/UserUserGroup/UserUserGroupRepository.php ファイルの表示



class UserUserGroupRepository extends BaseService implements RepositoryInterface class UserUserGroupRepository extends BaseService implements RepositoryInterface
{ {
public function defaultOptionsSearch(): array
public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => [], 'with' => [],

読み込み中…
キャンセル
保存