use domain\Feature\Feature\Feature; | use domain\Feature\Feature\Feature; | ||||
use domain\Product\Rotating\Rotating; | use domain\Product\Rotating\Rotating; | ||||
use yii\filters\AccessControl; | use yii\filters\AccessControl; | ||||
use yii\helpers\Html; | |||||
use yii\web\NotFoundHttpException; | use yii\web\NotFoundHttpException; | ||||
use yii\web\Response; | use yii\web\Response; | ||||
$rotatingModel->getDay(), | $rotatingModel->getDay(), | ||||
$rotatingModel->getSelectedProductsIds() | $rotatingModel->getSelectedProductsIds() | ||||
); | ); | ||||
$this->setFlash('success', "Produit tournant ajouté"); | |||||
$this->setFlash('success', "Produit tournant <strong>".Html::encode($rotating->getName())."</strong> ajouté"); | |||||
return $this->redirectAfterSave('rotating', $rotating->getId()); | return $this->redirectAfterSave('rotating', $rotating->getId()); | ||||
} | } | ||||
return $this->render('create', [ | return $this->render('create', [ | ||||
'rotatingModel' => $rotatingModel, | |||||
'rotating' => $this->initFormModel($rotatingModel), | 'rotating' => $this->initFormModel($rotatingModel), | ||||
'productsArray' => $this->findProducts() | 'productsArray' => $this->findProducts() | ||||
]); | ]); | ||||
{ | { | ||||
$rotating = $this->findRotating($id); | $rotating = $this->findRotating($id); | ||||
if ($rotating->load(\Yii::$app->request->post()) && $rotating->validate() && $rotating->save()) { | |||||
$this->getRotatingModule()->getManager()->manageRotatingProducts( | |||||
if ($rotating->load(\Yii::$app->request->post()) && $rotating->validate()) { | |||||
$this->getRotatingModule()->getManager()->updateRotating( | |||||
$rotating, | $rotating, | ||||
$rotating->getSelectedProductsIds() | $rotating->getSelectedProductsIds() | ||||
); | ); | ||||
$this->setFlash('success', "Produit tournant <strong>".Html::encode($rotating->getName())."</strong> modifié"); | |||||
return $this->redirectAfterSave('rotating', $rotating->getId()); | return $this->redirectAfterSave('rotating', $rotating->getId()); | ||||
} | } | ||||
return $this->render('update', [ | return $this->render('update', [ | ||||
'rotatingModel' => $rotating, | |||||
'rotating' => $this->initFormModel($rotating), | 'rotating' => $this->initFormModel($rotating), | ||||
'productsArray' => $this->findProducts() | 'productsArray' => $this->findProducts() | ||||
]); | ]); | ||||
$this->getRotatingModule()->getBuilder()->initSelectedProductsIds($rotating); | $this->getRotatingModule()->getBuilder()->initSelectedProductsIds($rotating); | ||||
return $rotating; | return $rotating; | ||||
} | } | ||||
/*public function actionCreate() | |||||
{ | |||||
$accessoryModule = $this->getAccessoryModule(); | |||||
$accessoryModel = $accessoryModule->getBuilder()->instanciateAccessory($this->getProducerCurrent()); | |||||
if ($accessoryModel->load(\Yii::$app->request->post()) && $accessoryModel->validate()) { | |||||
$accessory = $accessoryModule->getManager()->createAccessory( | |||||
$this->getProducerCurrent(), | |||||
$accessoryModel->getName(), | |||||
$accessoryModel->getQuantity() | |||||
); | |||||
$this->afterSave($accessory, $accessoryModel->getSelectedProductsIds()); | |||||
$this->setFlash('success', "Accessoire ajouté"); | |||||
return $this->redirectAfterSave('accessory', $accessory->getId()); | |||||
} | |||||
return $this->render('create', [ | |||||
'accessory' => $this->initFormModel($accessoryModel), | |||||
'productsArray' => $this->findProducts() | |||||
]); | |||||
} | |||||
public function actionUpdate(int $id) | |||||
{ | |||||
$accessory = $this->findAccessory($id); | |||||
if ($accessory->load(\Yii::$app->request->post()) && $accessory->validate() && $accessory->save()) { | |||||
$this->afterSave($accessory, $accessory->getSelectedProductsIds()); | |||||
return $this->redirectAfterSave('accessory', $accessory->getId()); | |||||
} | |||||
return $this->render('update', [ | |||||
'accessory' => $this->initFormModel($accessory), | |||||
'productsArray' => $this->findProducts() | |||||
]); | |||||
} | |||||
public function actionDelete(int $id): Response | |||||
{ | |||||
$accessory = $this->findAccessory($id); | |||||
if($accessory->delete()) { | |||||
$this->setFlash('success', "Accessoire supprimé"); | |||||
} | |||||
return $this->redirect('index'); | |||||
} | |||||
public function afterSave(Accessory $accessory, $selectedProductsIdsArray): void | |||||
{ | |||||
if(!is_array($selectedProductsIdsArray)) { | |||||
$selectedProductsIdsArray = []; | |||||
} | |||||
$this->getAccessoryModule()->getManager()->manageProducts($accessory, $selectedProductsIdsArray); | |||||
} | |||||
public function findProducts(): array | |||||
{ | |||||
return $this->getProductModule()->getRepository()->findProducts(true); | |||||
} | |||||
protected function findAccessory($id): Accessory | |||||
{ | |||||
if (($accessory = $this->getAccessoryModule()->getRepository()->findOneAccessoryById($id)) !== null) { | |||||
return $accessory; | |||||
} else { | |||||
throw new NotFoundHttpException("L'accessoire n'a pas été trouvé."); | |||||
} | |||||
} | |||||
public function initFormModel(Accessory $accessoryModel) | |||||
{ | |||||
$this->getAccessoryModule()->getBuilder()->initSelectedProductsIds($accessoryModel); | |||||
return $accessoryModel; | |||||
} | |||||
*/ | |||||
} | } |
</h3> | </h3> | ||||
</div> | </div> | ||||
<div class="panel-body"> | <div class="panel-body"> | ||||
<div class="has-error"> | |||||
<?= Html::error($rotatingModel,'selected_products_ids', ['class' => 'help-block']) ?> | |||||
</div> | |||||
<?= Html::activeCheckboxList($rotating, 'selected_products_ids', ArrayHelper::map($productsArray, 'id', function ($product, $defaultValue) { | <?= Html::activeCheckboxList($rotating, 'selected_products_ids', ArrayHelper::map($productsArray, 'id', function ($product, $defaultValue) { | ||||
return Html::encode($product->name); | return Html::encode($product->name); | ||||
}), ['encode' => false, 'class' => '']) ?> | }), ['encode' => false, 'class' => '']) ?> |
<div class="rotating-create"> | <div class="rotating-create"> | ||||
<?= $this->render('_form', [ | <?= $this->render('_form', [ | ||||
'rotatingModel' => $rotatingModel, | |||||
'rotating' => $rotating, | 'rotating' => $rotating, | ||||
'productsArray' => $productsArray | 'productsArray' => $productsArray | ||||
]) ?> | ]) ?> |
* @var View $this | * @var View $this | ||||
*/ | */ | ||||
$rotatingModule = $this->getRotatingModule(); | |||||
$this->setTitle('Produits tournans'); | $this->setTitle('Produits tournans'); | ||||
$this->addBreadcrumb($this->getTitle()); | $this->addBreadcrumb($this->getTitle()); | ||||
$this->addButton(['label' => 'Nouveau produit tournant <span class="glyphicon glyphicon-plus"></span>', 'url' => 'rotating/create', 'class' => 'btn btn-primary']); | $this->addButton(['label' => 'Nouveau produit tournant <span class="glyphicon glyphicon-plus"></span>', 'url' => 'rotating/create', 'class' => 'btn btn-primary']); | ||||
}, $rotating->getRotatingProducts())); | }, $rotating->getRotatingProducts())); | ||||
} | } | ||||
], | ], | ||||
[ | |||||
'label' => 'Distributions à venir', | |||||
'format' => 'raw', | |||||
'value' => function($rotating) use ($rotatingModule) { | |||||
return $rotatingModule->getResolver()->getRotatingProductsOfIncomingDistributionsAsHtml($rotating); | |||||
} | |||||
], | |||||
[ | [ | ||||
'class' => 'yii\grid\ActionColumn', | 'class' => 'yii\grid\ActionColumn', | ||||
'template' => '{update} {delete}', | 'template' => '{update} {delete}', |
<div class="rotating-update"> | <div class="rotating-update"> | ||||
<?= $this->render('_form', [ | <?= $this->render('_form', [ | ||||
'rotatingModel' => $rotatingModel, | |||||
'rotating' => $rotating, | 'rotating' => $rotating, | ||||
'productsArray' => $productsArray | 'productsArray' => $productsArray | ||||
]) ?> | ]) ?> |
namespace domain\Distribution\Distribution; | namespace domain\Distribution\Distribution; | ||||
use common\components\ActiveRecordCommon; | use common\components\ActiveRecordCommon; | ||||
use domain\Distribution\DistributionRotating\DistributionRotating; | |||||
use domain\Distribution\PointSaleDistribution\PointSaleDistribution; | use domain\Distribution\PointSaleDistribution\PointSaleDistribution; | ||||
use domain\Distribution\ProductDistribution\ProductDistribution; | use domain\Distribution\ProductDistribution\ProductDistribution; | ||||
use domain\Order\Order\Order; | use domain\Order\Order\Order; | ||||
return new \DateTime($this->date); | return new \DateTime($this->date); | ||||
} | } | ||||
public function getDistributionRotatings(): array | |||||
{ | |||||
return $this->distributionRotatingsRelation; | |||||
} | |||||
/* | /* | ||||
* Relations | * Relations | ||||
*/ | */ | ||||
{ | { | ||||
return $this->hasMany(PointSaleDistribution::class, ['id_distribution' => 'id']); | return $this->hasMany(PointSaleDistribution::class, ['id_distribution' => 'id']); | ||||
} | } | ||||
public function getDistributionRotatingsRelation() | |||||
{ | |||||
return $this->hasMany(DistributionRotating::class, ['id_distribution' => 'id']); | |||||
} | |||||
} | } |
namespace domain\Product\Rotating\Event; | namespace domain\Product\Rotating\Event; | ||||
use domain\Product\Rotating\Rotating; | |||||
use domain\Product\Rotating\RotatingModule; | use domain\Product\Rotating\RotatingModule; | ||||
use justcoded\yii2\eventlistener\observers\ActiveRecordObserver; | |||||
use justcoded\yii2\eventlistener\observers\Observer; | |||||
use yii\base\ErrorException; | use yii\base\ErrorException; | ||||
class RotatingObserver extends ActiveRecordObserver | |||||
class RotatingObserver extends Observer | |||||
{ | { | ||||
public function inserted(\yii\db\AfterSaveEvent $event) | |||||
public function events(): array | |||||
{ | { | ||||
//RotatingModule::getInstance()->getManager()->initializeRotatingInDistributionsIncoming($event->sender); | |||||
return [ | |||||
RotatingSaveEvent::NAME => 'onRotatingSave' | |||||
]; | |||||
} | } | ||||
/** | /** | ||||
* @throws ErrorException | * @throws ErrorException | ||||
*/ | */ | ||||
public function updated(\yii\db\AfterSaveEvent $event) | |||||
public function onRotatingSave(RotatingSaveEvent $event) | |||||
{ | { | ||||
//RotatingModule::getInstance()->getManager()->initializeRotatingInDistributionsIncoming($event->sender); | |||||
$rotatingModule = RotatingModule::getInstance(); | |||||
$rotating = $event->rotating; | |||||
// Obligé de recharger le Rotating | |||||
$rotating = $rotatingModule->getRepository()->findOneRotatingById($rotating->getId()); | |||||
$rotatingModule->getManager()->initializeRotatingInDistributionsIncoming($rotating); | |||||
} | } | ||||
} | } |
<?php | |||||
namespace domain\Product\Rotating\Event; | |||||
use yii\base\Event; | |||||
use domain\Product\Rotating\Rotating; | |||||
class RotatingSaveEvent extends Event | |||||
{ | |||||
const NAME = 'rotating.save.event'; | |||||
public Rotating $rotating; | |||||
} |
public function rules() | public function rules() | ||||
{ | { | ||||
return [ | return [ | ||||
[['id_producer', 'name', 'day'], 'required'], | |||||
[['id_producer', 'name', 'day', 'selected_products_ids'], 'required'], | |||||
[['name'], 'string', 'max' => 255], | [['name'], 'string', 'max' => 255], | ||||
[['id_producer', 'day', 'status'], 'integer'], | [['id_producer', 'day', 'status'], 'integer'], | ||||
[['selected_products_ids'], 'verifySelectedProductsIds'], | |||||
[['selected_products_ids'], 'safe'], | [['selected_products_ids'], 'safe'], | ||||
]; | ]; | ||||
} | } | ||||
'name' => 'Nom', | 'name' => 'Nom', | ||||
'day' => 'Jour', | 'day' => 'Jour', | ||||
'status' => 'Statut', | 'status' => 'Statut', | ||||
'selected_products_ids' => "Produits" | |||||
]; | ]; | ||||
} | } | ||||
public function verifySelectedProductsIds($attribute, $params) | |||||
{ | |||||
if(count($this->getSelectedProductsIds()) < 2) { | |||||
$this->addError($attribute, "Vous devez sélectionner au moins deux produits."); | |||||
} | |||||
} | |||||
/* Getters / Setters */ | /* Getters / Setters */ | ||||
public function getId(): ?int | public function getId(): ?int |
namespace domain\Product\Rotating; | namespace domain\Product\Rotating; | ||||
use common\components\Date; | |||||
use domain\_\AbstractManager; | use domain\_\AbstractManager; | ||||
use domain\Distribution\Distribution\Distribution; | use domain\Distribution\Distribution\Distribution; | ||||
use domain\Distribution\Distribution\DistributionRepository; | use domain\Distribution\Distribution\DistributionRepository; | ||||
use domain\Producer\Producer\Producer; | use domain\Producer\Producer\Producer; | ||||
use domain\Product\Product\ProductManager; | use domain\Product\Product\ProductManager; | ||||
use domain\Product\Product\ProductRepository; | use domain\Product\Product\ProductRepository; | ||||
use domain\Product\Rotating\Event\RotatingSaveEvent; | |||||
use domain\Product\RotatingProduct\RotatingProductManager; | use domain\Product\RotatingProduct\RotatingProductManager; | ||||
use yii\base\ErrorException; | use yii\base\ErrorException; | ||||
$this->productManager = $this->loadService(ProductManager::class); | $this->productManager = $this->loadService(ProductManager::class); | ||||
} | } | ||||
/** | |||||
* @throws ErrorException | |||||
*/ | |||||
public function createRotating(Producer $producer, string $name, int $day, array $productsIdsArray): Rotating | public function createRotating(Producer $producer, string $name, int $day, array $productsIdsArray): Rotating | ||||
{ | { | ||||
$rotating = $this->rotatingBuilder->instanciateRotating($producer); | $rotating = $this->rotatingBuilder->instanciateRotating($producer); | ||||
$rotating->setName($name); | $rotating->setName($name); | ||||
$rotating->setDay($day); | $rotating->setDay($day); | ||||
$rotating->save(); | $rotating->save(); | ||||
$this->afterSaveRotating($rotating, $productsIdsArray); | |||||
return $rotating; | |||||
} | |||||
public function updateRotating(Rotating $rotating, array $productsIdsArray): bool | |||||
{ | |||||
$return = $rotating->save(); | |||||
$this->afterSaveRotating($rotating, $productsIdsArray); | |||||
return $return; | |||||
} | |||||
public function afterSaveRotating(Rotating $rotating, array $productsIdsArray) | |||||
{ | |||||
$this->manageRotatingProducts($rotating, $productsIdsArray); | $this->manageRotatingProducts($rotating, $productsIdsArray); | ||||
return $rotating; | |||||
$rotating->triggerEvent(RotatingSaveEvent::class, [ | |||||
'rotating' => $rotating | |||||
]); | |||||
} | } | ||||
/** | |||||
* @throws ErrorException | |||||
*/ | |||||
public function manageRotatingProducts(Rotating $rotating, array $productsIdsArray = []): void | public function manageRotatingProducts(Rotating $rotating, array $productsIdsArray = []): void | ||||
{ | { | ||||
$this->deleteAllRotatingProducts($rotating); | $this->deleteAllRotatingProducts($rotating); | ||||
$this->rotatingProductManager->createRotatingProduct($rotating, $product); | $this->rotatingProductManager->createRotatingProduct($rotating, $product); | ||||
} | } | ||||
} | } | ||||
// Rechargement obligatoire car rotatingProductsRelation a changé juste au-dessus | |||||
// Possible de gérer ça via unset($rotating->rotatingProductsRelation) ? | |||||
$rotating = $this->rotatingRepository->findOneRotatingById($rotating->getId()); | |||||
// @TODO : gérer via événement | |||||
$this->initializeRotatingInDistributionsIncoming($rotating); | |||||
} | } | ||||
/** | /** | ||||
$distribution = $this->rotatingResolver->getNextDistribution($rotating, $date); | $distribution = $this->rotatingResolver->getNextDistribution($rotating, $date); | ||||
$dateLastDistributionIncoming = $this->distributionResolver->getDateLastDistributionIncoming(); | $dateLastDistributionIncoming = $this->distributionResolver->getDateLastDistributionIncoming(); | ||||
while($distribution && $dateLastDistributionIncoming && $date < $dateLastDistributionIncoming) { | |||||
$this->initializeRotatingInDistribution($rotating, $distribution); | |||||
$distribution = $this->rotatingResolver->getNextDistribution($rotating, $date); | |||||
if($dateLastDistributionIncoming) { | |||||
while($date < $dateLastDistributionIncoming) { | |||||
if($distribution) { | |||||
$this->initializeRotatingInDistribution($rotating, $distribution); | |||||
} | |||||
$distribution = $this->rotatingResolver->getNextDistribution($rotating, $date); | |||||
} | |||||
} | } | ||||
} | } | ||||
use domain\Product\RotatingProduct\RotatingProduct; | use domain\Product\RotatingProduct\RotatingProduct; | ||||
use domain\Product\RotatingProduct\RotatingProductRepository; | use domain\Product\RotatingProduct\RotatingProductRepository; | ||||
use yii\base\ErrorException; | use yii\base\ErrorException; | ||||
use yii\helpers\Html; | |||||
class RotatingResolver extends AbstractResolver | class RotatingResolver extends AbstractResolver | ||||
{ | { | ||||
{ | { | ||||
return (bool) $this->getRotatingOfProductInDistribution($product, $distribution); | return (bool) $this->getRotatingOfProductInDistribution($product, $distribution); | ||||
} | } | ||||
public function getRotatingProductsOfIncomingDistributionsAsHtml(Rotating $rotating): string | |||||
{ | |||||
$html = ''; | |||||
$countDistributionsDisplayed = 0; | |||||
$numberDistributionsDisplayed = count($rotating->getRotatingProducts()); | |||||
$incomingDistributionsArray = $this->distributionRepository->findDistributionsIncoming(); | |||||
foreach($incomingDistributionsArray as $distribution) { | |||||
foreach($distribution->getDistributionRotatings() as $distributionRotating) { | |||||
if($distributionRotating->getRotating()->equal($rotating)) { | |||||
$html .= $distribution->getDate()->format('d/m/Y'). ' : ' | |||||
.Html::encode($distributionRotating->getRotatingProduct()->getProduct()->name).'<br />'; | |||||
$countDistributionsDisplayed ++; | |||||
} | |||||
} | |||||
if($countDistributionsDisplayed >= $numberDistributionsDisplayed) { | |||||
break; | |||||
} | |||||
} | |||||
return $html; | |||||
} | |||||
} | } |