$orderManager = $this->getOrderManager(); | $orderManager = $this->getOrderManager(); | ||||
$productManager = $this->getProductManager(); | $productManager = $this->getProductManager(); | ||||
$userManager = $this->getUserManager(); | $userManager = $this->getUserManager(); | ||||
$pointSaleManager = $this->getPointSaleManager(); | |||||
$producer = $this->getProducerCurrent(); | $producer = $this->getProducerCurrent(); | ||||
$format = 'Y-m-d'; | $format = 'Y-m-d'; | ||||
$distribution = $distributionManager->createDistributionIfNotExist($date); | $distribution = $distributionManager->createDistributionIfNotExist($date); | ||||
$ordersArray = $orderManager->findOrdersByDistribution($distribution); | $ordersArray = $orderManager->findOrdersByDistribution($distribution); | ||||
$ordersArrayObject = $ordersArray; | $ordersArrayObject = $ordersArray; | ||||
$productsArray = $productManager->findProductsByDistribution($distribution); | |||||
$productsArray = $productManager->findProductsByDistribution($distribution, false); | |||||
$json['products'] = $this->buildAjaxInfosResponseProducts($distribution, $productsArray, $ordersArray); | $json['products'] = $this->buildAjaxInfosResponseProducts($distribution, $productsArray, $ordersArray); | ||||
$json['distribution'] = $this->buildAjaxInfosResponseDistribution($distribution, $ordersArrayObject, $productsArray); | $json['distribution'] = $this->buildAjaxInfosResponseDistribution($distribution, $ordersArrayObject, $productsArray); | ||||
if (!isset($product->productDistribution[0])) { | if (!isset($product->productDistribution[0])) { | ||||
$productDistributionAdd = $distributionManager->addProduct($distribution, $product); | $productDistributionAdd = $distributionManager->addProduct($distribution, $product); | ||||
$jsonProduct['productDistribution'][0] = $productDistributionAdd->getAttributes(); | |||||
$product->populateRelation('productDistribution', [$productDistributionAdd]); | |||||
if($productDistributionAdd) { | |||||
$jsonProduct['productDistribution'][0] = $productDistributionAdd->getAttributes(); | |||||
$product->populateRelation('productDistribution', [$productDistributionAdd]); | |||||
} | |||||
} | } | ||||
else { | else { | ||||
foreach($product->productDistribution as $key => $productDistribution) { | foreach($product->productDistribution as $key => $productDistribution) { | ||||
} | } | ||||
} | } | ||||
if (!is_numeric($product->productDistribution[0]->quantity_max)) { | |||||
if (!isset($product->productDistribution[0]) || !is_numeric($product->productDistribution[0]->quantity_max)) { | |||||
$jsonProduct['quantity_remaining'] = null; | $jsonProduct['quantity_remaining'] = null; | ||||
} else { | } else { | ||||
$jsonProduct['quantity_remaining'] = $product->productDistribution[0]->quantity_max - $quantityOrder; | $jsonProduct['quantity_remaining'] = $product->productDistribution[0]->quantity_max - $quantityOrder; | ||||
$oneProductUnactivated = false; | $oneProductUnactivated = false; | ||||
foreach ($order->productOrder as $productOrder) { | foreach ($order->productOrder as $productOrder) { | ||||
foreach ($productsArray as $product) { | foreach ($productsArray as $product) { | ||||
if ($productOrder->id_product == $product['id'] && !$product['productDistribution'][0]['active']) { | |||||
if ($productOrder->id_product == $product['id'] && isset($product['productDistribution'][0]) && !$product['productDistribution'][0]['active']) { | |||||
$oneProductUnactivated = true; | $oneProductUnactivated = true; | ||||
} | } | ||||
} | } |
if ($document) { | if ($document) { | ||||
$ordersArray = []; | $ordersArray = []; | ||||
$productsArray = $productManager->findProducts(); | |||||
$productsArray = $productManager->findProducts(false); | |||||
foreach ($document->orders as $order) { | foreach ($document->orders as $order) { | ||||
$orderManager->initOrder($order); | $orderManager->initOrder($order); |
$model = $productManager->instanciateProduct(); | $model = $productManager->instanciateProduct(); | ||||
$model->active = 1; | |||||
$model->status = Product::STATUS_ONLINE; | |||||
$model->id_producer = GlobalParam::getCurrentProducerId(); | $model->id_producer = GlobalParam::getCurrentProducerId(); | ||||
$model->monday = 1; | $model->monday = 1; | ||||
$model->tuesday = 1; | $model->tuesday = 1; | ||||
*/ | */ | ||||
public function actionDelete(int $id, bool $confirm = false) | public function actionDelete(int $id, bool $confirm = false) | ||||
{ | { | ||||
$productContainer = $this->getProductContainer(); | |||||
$productDistributionContainer = $this->getProductDistributionContainer(); | |||||
$product = $this->findModel($id); | $product = $this->findModel($id); | ||||
if ($confirm) { | if ($confirm) { | ||||
$product->delete(); | |||||
ProductDistribution::deleteAll(['id_product' => $id]); | |||||
$productContainer->getBuilder()->updateStatusDeleted($product); | |||||
$productDistributionContainer->getBuilder()->disableProductDistributionsIncomingByProduct($product); | |||||
$this->setFlash('success', 'Produit <strong>' . Html::encode($product->name) . '</strong> supprimé'); | $this->setFlash('success', 'Produit <strong>' . Html::encode($product->name) . '</strong> supprimé'); | ||||
} else { | } else { | ||||
} | } | ||||
} | } | ||||
public function actionAjaxToggleActive($id, $active) | |||||
public function actionAjaxToggleStatus($id, $status) | |||||
{ | { | ||||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | ||||
$distributionManager = $this->getDistributionManager(); | $distributionManager = $this->getDistributionManager(); | ||||
$product = $this->findModel($id); | $product = $this->findModel($id); | ||||
$product->active = (int) $active; | |||||
$product->status = (int) $status; | |||||
$product->save(); | $product->save(); | ||||
$distributionManager->addProductIncomingDistributions($product); | $distributionManager->addProductIncomingDistributions($product); | ||||
return ['success', 'id' => $id, 'active' => $active]; | |||||
return ['success', 'id' => $id, 'status' => $status]; | |||||
} | } | ||||
/** | /** |
$productManager = $this->getProductManager(); | $productManager = $this->getProductManager(); | ||||
$productsQuery = Product::find() | $productsQuery = Product::find() | ||||
->where(['id_producer' => GlobalParam::getCurrentProducerId(),]); | |||||
->where(['id_producer' => GlobalParam::getCurrentProducerId()]) | |||||
->andWhere('status >= :status') | |||||
->addParams(['status' => Product::STATUS_OFFLINE]); | |||||
if ($idSubscription) { | if ($idSubscription) { | ||||
$productsQuery->joinWith(['productSubscription' => function ($query) use ($idSubscription) { | $productsQuery->joinWith(['productSubscription' => function ($query) use ($idSubscription) { |
->where([ | ->where([ | ||||
'id_producer' => GlobalParam::getCurrentProducerId(), | 'id_producer' => GlobalParam::getCurrentProducerId(), | ||||
]) | ]) | ||||
->andWhere('status >= :status') | |||||
->addParams(['status' => Product::STATUS_OFFLINE]) | |||||
->innerJoinWith(['productDistribution' => function($query) use($distribution) { | ->innerJoinWith(['productDistribution' => function($query) use($distribution) { | ||||
$query->andOnCondition([ | $query->andOnCondition([ | ||||
'product_distribution.id_distribution' => $distribution->id, | 'product_distribution.id_distribution' => $distribution->id, |
</tr> | </tr> | ||||
</thead> | </thead> | ||||
<tbody> | <tbody> | ||||
<tr v-for="product in products"> | |||||
<tr v-for="product in products" v-if="getProductDistribution(product)"> | |||||
<td> | <td> | ||||
<button class="btn btn-success" v-if="product.productDistribution[0].active == 1"><span class="glyphicon glyphicon-ok"></span></button> | |||||
<button class="btn btn-success" v-if="getProductDistribution(product).active == 1"><span class="glyphicon glyphicon-ok"></span></button> | |||||
<button class="btn btn-default" v-else data-active-product="1" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-ok"></span></button> | <button class="btn btn-default" v-else data-active-product="1" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-ok"></span></button> | ||||
<button class="btn btn-danger" v-if="product.productDistribution[0].active == 0"><span class="glyphicon glyphicon-remove"></span></button> | |||||
<button class="btn btn-danger" v-if="getProductDistribution(product).active == 0"><span class="glyphicon glyphicon-remove"></span></button> | |||||
<button class="btn btn-default" v-else data-active-product="0" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-remove"></span></button> | <button class="btn btn-default" v-else data-active-product="0" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-remove"></span></button> | ||||
</td> | </td> | ||||
<td>{{ product.name }}</td> | <td>{{ product.name }}</td> | ||||
</td> | </td> | ||||
<td class="quantity-max"> | <td class="quantity-max"> | ||||
<div class="input-group"> | <div class="input-group"> | ||||
<input type="text" class="form-control quantity-max" placeholder="∞" :data-id-product="product.id" v-model="product.productDistribution[0].quantity_max" @keyup="productQuantityMaxChange" /> | |||||
<input type="text" class="form-control quantity-max" placeholder="∞" :data-id-product="product.id" v-model="getProductDistribution(product).quantity_max" @keyup="productQuantityMaxChange" /> | |||||
<span class="input-group-addon">{{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</span> | <span class="input-group-addon">{{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</span> | ||||
</div> | </div> | ||||
</td> | </td> | ||||
<td colspan="6"> | <td colspan="6"> | ||||
<strong><span class="glyphicon glyphicon-menu-right"></span> Produits</strong> | <strong><span class="glyphicon glyphicon-menu-right"></span> Produits</strong> | ||||
<ul> | <ul> | ||||
<li v-for="product in products" v-if="order.productOrder[product.id].quantity > 0"> | |||||
{{ product.name }} : {{ order.productOrder[product.id].quantity }} {{ order.productOrder[product.id].unit == 'piece' ? ' pièce(s)' : ' '+order.productOrder[product.id].unit }} <span v-if="product.productDistribution[0].active == 0" class="glyphicon glyphicon-warning-sign" title="Ce produit n'est pas activé"></span> | |||||
<li v-for="product in products" v-if="getProductDistribution(product) && order.productOrder[product.id].quantity > 0"> | |||||
{{ product.name }} : {{ order.productOrder[product.id].quantity }} {{ order.productOrder[product.id].unit == 'piece' ? ' pièce(s)' : ' '+order.productOrder[product.id].unit }} <span v-if="getProductDistribution(product).active == 0" class="glyphicon glyphicon-warning-sign" title="Ce produit n'est pas activé"></span> | |||||
</li> | </li> | ||||
</ul> | </ul> | ||||
<div v-if="order.comment && order.comment.length > 0" class="comment"> | <div v-if="order.comment && order.comment.length > 0" class="comment"> | ||||
</tr> | </tr> | ||||
</thead> | </thead> | ||||
<tbody> | <tbody> | ||||
<tr v-for="product in products" :class="(order.productOrder[product.id].quantity > 0) ? 'product-ordered' : ''"> | |||||
<tr v-for="product in products" v-if="product.status >= 0 || order.productOrder[product.id].quantity > 0" :class="(order.productOrder[product.id].quantity > 0) ? 'product-ordered' : ''"> | |||||
<td> | <td> | ||||
<span class="label label-success" v-if="loadingUpdateProductOrder || order.productOrder[product.id].active">Actif</span> | <span class="label label-success" v-if="loadingUpdateProductOrder || order.productOrder[product.id].active">Actif</span> | ||||
<span class="label label-danger" v-else>Inactif</span> | <span class="label label-danger" v-else>Inactif</span> |
<select class="form-control" v-model="productAddId" | <select class="form-control" v-model="productAddId" | ||||
@change="changeProductAdd"> | @change="changeProductAdd"> | ||||
<option value="0" selected="selected">--</option> | <option value="0" selected="selected">--</option> | ||||
<option v-for="product in productsArray" :value="product.id"> | |||||
<option v-for="product in productsArray" v-if="product.status >= 0" :value="product.id"> | |||||
{{ product.name }} | {{ product.name }} | ||||
</option> | </option> | ||||
</select> | </select> |
<div> | <div> | ||||
<div class="col-md-8"> | <div class="col-md-8"> | ||||
<?= $form->field($model, 'active')->radioList([1 => 'Oui', 0 => 'Non']) ?> | |||||
<?= $form->field($model, 'status')->radioList([1 => 'Oui', 0 => 'Non']) ?> | |||||
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?> | <?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?> | ||||
<?= $form->field($model, 'reference')->textInput(['maxlength' => 255]) ?> | <?= $form->field($model, 'reference')->textInput(['maxlength' => 255]) ?> | ||||
<?= $form->field($model, 'id_product_category')->dropDownList($productCategoryManager->populateProductCategoriesDropdownList()); ?> | <?= $form->field($model, 'id_product_category')->dropDownList($productCategoryManager->populateProductCategoriesDropdownList()); ?> |
} | } | ||||
], | ], | ||||
[ | [ | ||||
'attribute' => 'active', | |||||
'attribute' => 'status', | |||||
'label' => 'Actif', | |||||
'headerOptions' => ['class' => 'active column-hide-on-mobile'], | 'headerOptions' => ['class' => 'active column-hide-on-mobile'], | ||||
'filterOptions' => ['class' => 'column-hide-on-mobile'], | 'filterOptions' => ['class' => 'column-hide-on-mobile'], | ||||
'contentOptions' => ['class' => 'center column-hide-on-mobile'], | 'contentOptions' => ['class' => 'center column-hide-on-mobile'], | ||||
return Toggle::widget( | return Toggle::widget( | ||||
[ | [ | ||||
'name' => 'active', | 'name' => 'active', | ||||
'checked' => $model->active, | |||||
'checked' => $model->status, | |||||
'options' => [ | 'options' => [ | ||||
'data-id' => $model->id, | 'data-id' => $model->id, | ||||
'data-on' => 'Oui', | 'data-on' => 'Oui', |
$('body.product-index .toggle input').change(function() { | $('body.product-index .toggle input').change(function() { | ||||
var id = $(this).data('id'); | var id = $(this).data('id'); | ||||
var checked = $(this).prop('checked'); | var checked = $(this).prop('checked'); | ||||
var active = 0; | |||||
if(checked) { | |||||
active = 1; | |||||
} | |||||
$.get(UrlManager.getBaseUrl() + 'product/ajax-toggle-active', { | |||||
$.get(UrlManager.getBaseUrl() + 'product/ajax-toggle-status', { | |||||
id: id, | id: id, | ||||
active: active | |||||
status: checked ? 1 : 0 | |||||
}); | }); | ||||
}) | }) | ||||
} | } | ||||
initCountActiveProducts: function () { | initCountActiveProducts: function () { | ||||
this.countActiveProducts = 0; | this.countActiveProducts = 0; | ||||
for (var i = 0; i < this.products.length; i++) { | for (var i = 0; i < this.products.length; i++) { | ||||
if (this.products[i].productDistribution[0].active == 1) { | |||||
if (this.products[i].productDistribution && this.products[i].productDistribution[0].active == 1) { | |||||
this.countActiveProducts++; | this.countActiveProducts++; | ||||
} | } | ||||
} | } | ||||
}); | }); | ||||
for (i = 0; i < this.products.length; i++) { | for (i = 0; i < this.products.length; i++) { | ||||
if (this.products[i].id == idProduct) { | |||||
if (this.products[i].productDistribution && this.products[i].id == idProduct) { | |||||
this.products[i].productDistribution[0].active = activeProduct; | this.products[i].productDistribution[0].active = activeProduct; | ||||
} | } | ||||
} | } | ||||
return false; | return false; | ||||
}, | }, | ||||
isProductMaximumQuantityExceeded: function (product) { | isProductMaximumQuantityExceeded: function (product) { | ||||
return product.productDistribution[0].quantity_max | |||||
return | |||||
this.getProductDistribution(product) | |||||
&& this.getProductDistribution(product).quantity_max | |||||
&& product.quantity_ordered | && product.quantity_ordered | ||||
&& product.quantity_ordered > product.productDistribution[0].quantity_max; | |||||
&& product.quantity_ordered > this.getProductDistribution(product).quantity_max; | |||||
}, | }, | ||||
pointSaleActiveClick: function (event) { | pointSaleActiveClick: function (event) { | ||||
var idPointSale = event.currentTarget.getAttribute('data-id-point-sale'); | var idPointSale = event.currentTarget.getAttribute('data-id-point-sale'); | ||||
}, | }, | ||||
getUnitCoefficient: function(unit) { | getUnitCoefficient: function(unit) { | ||||
return this.units[unit].coefficient; | return this.units[unit].coefficient; | ||||
}, | |||||
getProductDistribution: function(product) { | |||||
if(typeof product.productDistribution !== 'undefined' && product.productDistribution[0]) { | |||||
return product.productDistribution[0]; | |||||
} | |||||
return null; | |||||
} | } | ||||
}, | }, | ||||
}); | }); | ||||
productQuantityOrder += this.getProductQuantityProductOrder(this.order, product); | productQuantityOrder += this.getProductQuantityProductOrder(this.order, product); | ||||
} | } | ||||
quantityRemaining = product.productDistribution[0].quantity_max - productQuantityOrder; | |||||
quantityRemaining = this.getProductDistribution(product).quantity_max - productQuantityOrder; | |||||
if(unit != 'piece') { | if(unit != 'piece') { | ||||
quantityRemaining = quantityRemaining.toFixed(2); | quantityRemaining = quantityRemaining.toFixed(2); | ||||
} | } | ||||
}, | }, | ||||
getUnitCoefficient: function(unit) { | getUnitCoefficient: function(unit) { | ||||
return this.units[unit].coefficient; | return this.units[unit].coefficient; | ||||
}, | |||||
getProductDistribution: function(product) { | |||||
if(typeof product.productDistribution !== 'undefined' && product.productDistribution[0]) { | |||||
return product.productDistribution[0]; | |||||
} | |||||
} | } | ||||
} | } | ||||
}); | }); |
{ | { | ||||
return $model->save(); | return $model->save(); | ||||
} | } | ||||
} | |||||
/** | |||||
* Status | |||||
*/ | |||||
public function updateStatusOnline(Model $model) | |||||
{ | |||||
$model->status = StatusInterface::STATUS_ONLINE; | |||||
$this->update($model); | |||||
} | |||||
public function updateStatusOffline(Model $model) | |||||
{ | |||||
$model->status = StatusInterface::STATUS_OFFLINE; | |||||
$this->update($model); | |||||
} | |||||
public function updateStatusDeleted(Model $model) | |||||
{ | |||||
$model->status = StatusInterface::STATUS_DELETED; | |||||
$this->update($model); | |||||
} | |||||
} |
return $this->query; | return $this->query; | ||||
} | } | ||||
public function createDefaultQuery(): RepositoryQueryInterface | |||||
public function createDefaultQuery(bool $filterStatus = true): RepositoryQueryInterface | |||||
{ | { | ||||
$this->createQuery(); | $this->createQuery(); | ||||
if($filterStatus) { | |||||
$this->defaultStatus(); | |||||
} | |||||
$this->defaultWith(); | $this->defaultWith(); | ||||
$this->defaultJoinWith(); | $this->defaultJoinWith(); | ||||
$this->defaultFilterProducerContext(); | $this->defaultFilterProducerContext(); | ||||
return $this->query; | return $this->query; | ||||
} | } | ||||
public function defaultStatus(): void | |||||
{ | |||||
$class = new \ReflectionClass($this->query->getDefinition()->getEntityFqcn()); | |||||
if($class->implementsInterface('common\logic\StatusInterface')) { | |||||
$this->query->filterIsStatusOnlineAndOffline(); | |||||
} | |||||
} | |||||
public function defaultWith(): void | public function defaultWith(): void | ||||
{ | { | ||||
$defaultOptions = $this->getDefaultOptionsSearch(); | $defaultOptions = $this->getDefaultOptionsSearch(); |
$this->definition = $this->loadService($serviceClass); | $this->definition = $this->loadService($serviceClass); | ||||
} | } | ||||
public function getDefinition() | |||||
{ | |||||
return $this->definition; | |||||
} | |||||
public function baseQuery(): ActiveQuery | public function baseQuery(): ActiveQuery | ||||
{ | { | ||||
$class = $this->definition->getEntityFqcn(); | $class = $this->definition->getEntityFqcn(); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function filterIsStatusOnline() | |||||
{ | |||||
$this->andWhere(['status' => StatusInterface::STATUS_ONLINE]); | |||||
return $this; | |||||
} | |||||
public function filterIsStatusOnlineAndOffline() | |||||
{ | |||||
$this->andWhere('status >= :status')->addParams(['status' => StatusInterface::STATUS_OFFLINE]); | |||||
return $this; | |||||
} | |||||
public function filterIsStatusDeleted() | |||||
{ | |||||
$this->andWhere(['status' => StatusInterface::STATUS_DELETED]); | |||||
return $this; | |||||
} | |||||
public function getDataProvider(int $pageSize): ActiveDataProvider | public function getDataProvider(int $pageSize): ActiveDataProvider | ||||
{ | { | ||||
return new ActiveDataProvider([ | return new ActiveDataProvider([ |
use common\logic\PointSale\PointSale\Model\PointSale; | use common\logic\PointSale\PointSale\Model\PointSale; | ||||
use common\logic\Product\Product\Model\Product; | use common\logic\Product\Product\Model\Product; | ||||
use common\logic\Product\Product\Repository\ProductRepository; | use common\logic\Product\Product\Repository\ProductRepository; | ||||
use common\logic\Product\Product\Service\ProductSolver; | |||||
use common\logic\User\UserProducer\Repository\UserProducerRepository; | use common\logic\User\UserProducer\Repository\UserProducerRepository; | ||||
class DistributionBuilder extends AbstractBuilder | class DistributionBuilder extends AbstractBuilder | ||||
protected OrderRepository $orderRepository; | protected OrderRepository $orderRepository; | ||||
protected UserProducerRepository $userProducerRepository; | protected UserProducerRepository $userProducerRepository; | ||||
protected ProductOrderBuilder $productOrderBuilder; | protected ProductOrderBuilder $productOrderBuilder; | ||||
protected ProductSolver $productSolver; | |||||
public function loadDependencies(): void | public function loadDependencies(): void | ||||
{ | { | ||||
$this->orderRepository = $this->loadService(OrderRepository::class); | $this->orderRepository = $this->loadService(OrderRepository::class); | ||||
$this->userProducerRepository = $this->loadService(UserProducerRepository::class); | $this->userProducerRepository = $this->loadService(UserProducerRepository::class); | ||||
$this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class); | $this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class); | ||||
$this->productSolver = $this->loadService(ProductSolver::class); | |||||
} | } | ||||
public function instanciateDistribution(string $date, bool $delivery = true): Distribution | public function instanciateDistribution(string $date, bool $delivery = true): Distribution | ||||
return $distribution; | return $distribution; | ||||
} | } | ||||
// initDistribution | |||||
public function createDistribution(string $date, bool $delivery = true): Distribution | public function createDistribution(string $date, bool $delivery = true): Distribution | ||||
{ | { | ||||
$distribution = $this->instanciateDistribution($date, $delivery); | $distribution = $this->instanciateDistribution($date, $delivery); | ||||
$this->saveCreate($distribution); | |||||
$this->create($distribution); | |||||
$this->createPointSaleDistributions($distribution); | $this->createPointSaleDistributions($distribution); | ||||
$this->createProductDistributions($distribution); | $this->createProductDistributions($distribution); | ||||
/** | /** | ||||
* Ajoute un produit à une distribution. | * Ajoute un produit à une distribution. | ||||
*/ | */ | ||||
public function addProduct(Distribution $distribution, Product $product): ProductDistribution | |||||
public function addProduct(Distribution $distribution, Product $product): ?ProductDistribution | |||||
{ | { | ||||
$productDistribution = $this->productDistributionBuilder->createProductDistributionIfNotExist($distribution, $product); | |||||
$this->productDistributionBuilder->updateProductDistribution($productDistribution); | |||||
$this->updateOrderProductPrices($distribution, $product); | |||||
if($this->productSolver->isStatusOnlineOrOffline($product)) { | |||||
$productDistribution = $this->productDistributionBuilder->createProductDistributionIfNotExist($distribution, $product); | |||||
$this->productDistributionBuilder->updateProductDistribution($productDistribution); | |||||
$this->updateOrderProductPrices($distribution, $product); | |||||
return $productDistribution; | |||||
} | |||||
return $productDistribution; | |||||
return null; | |||||
} | } | ||||
/** | /** |
use common\logic\AbstractBuilder; | use common\logic\AbstractBuilder; | ||||
use common\logic\Distribution\Distribution\Model\Distribution; | use common\logic\Distribution\Distribution\Model\Distribution; | ||||
use common\logic\Distribution\Distribution\Repository\DistributionRepository; | |||||
use common\logic\Distribution\Distribution\Service\DistributionSolver; | use common\logic\Distribution\Distribution\Service\DistributionSolver; | ||||
use common\logic\Distribution\ProductDistribution\Model\ProductDistribution; | use common\logic\Distribution\ProductDistribution\Model\ProductDistribution; | ||||
use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository; | use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository; | ||||
protected ProductDistributionRepository $productDistributionRepository; | protected ProductDistributionRepository $productDistributionRepository; | ||||
protected DistributionSolver $distributionSolver; | protected DistributionSolver $distributionSolver; | ||||
protected ProductSolver $productSolver; | protected ProductSolver $productSolver; | ||||
protected DistributionRepository $distributionRepository; | |||||
public function loadDependencies(): void | public function loadDependencies(): void | ||||
{ | { | ||||
$this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class); | $this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class); | ||||
$this->distributionSolver = $this->loadService(DistributionSolver::class); | $this->distributionSolver = $this->loadService(DistributionSolver::class); | ||||
$this->productSolver = $this->loadService(ProductSolver::class); | $this->productSolver = $this->loadService(ProductSolver::class); | ||||
$this->distributionRepository = $this->loadService(DistributionRepository::class); | |||||
} | } | ||||
public function instanciateProductDistribution(Distribution $distribution, Product $product): ProductDistribution | public function instanciateProductDistribution(Distribution $distribution, Product $product): ProductDistribution | ||||
$productDistribution->active = $active; | $productDistribution->active = $active; | ||||
$this->update($productDistribution); | $this->update($productDistribution); | ||||
} | } | ||||
public function disableProductDistributionsIncomingByProduct(Product $product) | |||||
{ | |||||
$distributionsIncomingArray = $this->distributionRepository->findDistributionsIncoming(true); | |||||
foreach($distributionsIncomingArray as $distribution) { | |||||
ProductDistribution::updateAll([ | |||||
'id_product' => $product->id, | |||||
'id_distribution' => $distribution->id, | |||||
'active' => false | |||||
]); | |||||
} | |||||
} | |||||
} | } |
use common\logic\AbstractRepositoryQuery; | use common\logic\AbstractRepositoryQuery; | ||||
use common\logic\PointSale\PointSale\Model\PointSale; | use common\logic\PointSale\PointSale\Model\PointSale; | ||||
use common\logic\PointSale\PointSale\Service\PointSaleDefinition; | use common\logic\PointSale\PointSale\Service\PointSaleDefinition; | ||||
use common\logic\StatusInterface; | |||||
use yii\db\ActiveQuery; | use yii\db\ActiveQuery; | ||||
class PointSaleRepositoryQuery extends AbstractRepositoryQuery | class PointSaleRepositoryQuery extends AbstractRepositoryQuery | ||||
public function filterIsOnline(): self | public function filterIsOnline(): self | ||||
{ | { | ||||
$this->andWhere(['status' => 1]); | |||||
$this->andWhere(['status' => StatusInterface::STATUS_ONLINE]); | |||||
return $this; | return $this; | ||||
} | } |
use common\logic\Product\ProductPointSale\Model\ProductPointSale; | use common\logic\Product\ProductPointSale\Model\ProductPointSale; | ||||
use common\logic\Product\ProductPrice\Model\ProductPrice; | use common\logic\Product\ProductPrice\Model\ProductPrice; | ||||
use common\components\ActiveRecordCommon; | use common\components\ActiveRecordCommon; | ||||
use common\logic\StatusInterface; | |||||
use common\logic\Subscription\ProductSubscription\Model\ProductSubscription; | use common\logic\Subscription\ProductSubscription\Model\ProductSubscription; | ||||
use yii\web\UploadedFile; | use yii\web\UploadedFile; | ||||
* This is the model class for table "product". | * This is the model class for table "product". | ||||
* | * | ||||
*/ | */ | ||||
class Product extends ActiveRecordCommon | |||||
class Product extends ActiveRecordCommon implements StatusInterface | |||||
{ | { | ||||
public $total = 0; | public $total = 0; | ||||
public $apply_distributions = true; | public $apply_distributions = true; | ||||
{ | { | ||||
return [ | return [ | ||||
[['name', 'id_producer'], 'required'], | [['name', 'id_producer'], 'required'], | ||||
[['active', 'order', 'id_producer', 'id_tax_rate', 'id_product_category'], 'integer'], | |||||
[['order', 'id_producer', 'id_tax_rate', 'id_product_category', 'status'], 'integer'], | |||||
[['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable', 'apply_distributions', 'available_on_points_sale'], 'boolean'], | [['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable', 'apply_distributions', 'available_on_points_sale'], 'boolean'], | ||||
[['price', 'weight', 'step', 'quantity_max', 'quantity_max_monday', 'quantity_max_tuesday', 'quantity_max_wednesday', 'quantity_max_thursday', 'quantity_max_friday', 'quantity_max_saturday', 'quantity_max_sunday'], 'number'], | [['price', 'weight', 'step', 'quantity_max', 'quantity_max_monday', 'quantity_max_tuesday', 'quantity_max_wednesday', 'quantity_max_thursday', 'quantity_max_friday', 'quantity_max_saturday', 'quantity_max_sunday'], 'number'], | ||||
[['photoFile'], 'file', 'extensions' => 'png, jpg, jpeg', 'mimeTypes' => 'image/png, image/jpeg'], | [['photoFile'], 'file', 'extensions' => 'png, jpg, jpeg', 'mimeTypes' => 'image/png, image/jpeg'], | ||||
'name' => 'Nom', | 'name' => 'Nom', | ||||
'reference' => 'Référence', | 'reference' => 'Référence', | ||||
'description' => 'Description', | 'description' => 'Description', | ||||
'active' => 'Actif', | |||||
'photoFile' => 'Photo', | 'photoFile' => 'Photo', | ||||
'price' => 'Prix (€) TTC', | 'price' => 'Prix (€) TTC', | ||||
'weight' => 'Poids', | 'weight' => 'Poids', | ||||
'step' => 'Pas', | 'step' => 'Pas', | ||||
'id_tax_rate' => 'TVA', | 'id_tax_rate' => 'TVA', | ||||
'id_product_category' => 'Catégorie', | 'id_product_category' => 'Catégorie', | ||||
'available_on_points_sale' => 'Par défaut' | |||||
'available_on_points_sale' => 'Par défaut', | |||||
'status' => 'Actif', | |||||
]; | ]; | ||||
} | } | ||||
public function rules() | public function rules() | ||||
{ | { | ||||
return [ | return [ | ||||
[['active', 'order', 'quantity_max', 'id_producer'], 'integer'], | |||||
[['order', 'quantity_max', 'id_producer', 'status'], 'integer'], | |||||
[['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable'], 'boolean'], | [['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable'], 'boolean'], | ||||
[['price', 'weight'], 'number'], | [['price', 'weight'], 'number'], | ||||
[[ 'photo'], 'file'], | [[ 'photo'], 'file'], | ||||
->with($optionsSearch['with']) | ->with($optionsSearch['with']) | ||||
->innerJoinWith($optionsSearch['join_with'], true) | ->innerJoinWith($optionsSearch['join_with'], true) | ||||
->where(['product.id_producer' => GlobalParam::getCurrentProducerId()]) | ->where(['product.id_producer' => GlobalParam::getCurrentProducerId()]) | ||||
->orderBy('product.order ASC') | |||||
; | |||||
->andWhere('status >= :status')->addParams(['status' => Product::STATUS_OFFLINE]) | |||||
->orderBy('product.order ASC'); | |||||
$dataProvider = new ActiveDataProvider([ | $dataProvider = new ActiveDataProvider([ | ||||
'query' => $query, | 'query' => $query, | ||||
'sort' => ['attributes' => ['order', 'photo', 'name', 'description','active']], | |||||
'sort' => ['attributes' => ['order', 'photo', 'name', 'description','status']], | |||||
'pagination' => [ | 'pagination' => [ | ||||
'pageSize' => 1000, | 'pageSize' => 1000, | ||||
], | ], | ||||
$query->andFilterWhere(['like', 'product.name', $this->name]) ; | $query->andFilterWhere(['like', 'product.name', $this->name]) ; | ||||
$query->andFilterWhere(['like', 'product.description', $this->description]) ; | $query->andFilterWhere(['like', 'product.description', $this->description]) ; | ||||
if(isset($this->active) && is_numeric($this->active)) { | |||||
if(isset($this->status) && is_numeric($this->status)) { | |||||
$query->andWhere([ | $query->andWhere([ | ||||
'product.active' => $this->active | |||||
'product.status' => $this->status | |||||
]) ; | ]) ; | ||||
} | } | ||||
->findOne(); | ->findOne(); | ||||
} | } | ||||
public function findProducts(): array | |||||
public function findProducts(bool $filterStatus = true): array | |||||
{ | { | ||||
return $this->createDefaultQuery()->find(); | |||||
return $this->createDefaultQuery($filterStatus)->find(); | |||||
} | } | ||||
/** | /** | ||||
return $this->createDefaultQuery()->count(); | return $this->createDefaultQuery()->count(); | ||||
} | } | ||||
public function queryProductsByDistribution(Distribution $distribution) | |||||
public function queryProductsByDistribution(Distribution $distribution, bool $filterStatus = true) | |||||
{ | { | ||||
return $this->createDefaultQuery() | |||||
return $this->createDefaultQuery($filterStatus) | |||||
->joinWith([ | ->joinWith([ | ||||
'productDistribution' => function ($query) use ($distribution) { | 'productDistribution' => function ($query) use ($distribution) { | ||||
$query->andOnCondition( | $query->andOnCondition( | ||||
/** | /** | ||||
* Retourne les produits d'une production donnée. | * Retourne les produits d'une production donnée. | ||||
*/ | */ | ||||
public function findProductsByDistribution(Distribution $distribution) | |||||
public function findProductsByDistribution(Distribution $distribution, bool $filterStatus = true) | |||||
{ | { | ||||
$productArray = $this->queryProductsByDistribution($distribution)->find(); | |||||
$productArray = $this->queryProductsByDistribution($distribution, $filterStatus)->find(); | |||||
return $this->buildProductsArrayById($productArray); | return $this->buildProductsArrayById($productArray); | ||||
} | } | ||||
public function queryProductsByProductCategory(ProductCategory $productCategory) | public function queryProductsByProductCategory(ProductCategory $productCategory) | ||||
{ | { | ||||
return $this->createDefaultQuery() | return $this->createDefaultQuery() | ||||
->filterIsActive() | |||||
->filterIsStatusOnline() | |||||
->filterByProductCategory($productCategory); | ->filterByProductCategory($productCategory); | ||||
} | } | ||||
public function countProductsWithoutCategory(Producer $producer): int | public function countProductsWithoutCategory(Producer $producer): int | ||||
{ | { | ||||
return $this->createDefaultQuery() | return $this->createDefaultQuery() | ||||
->filterIsActive() | |||||
->filterIsStatusOnline() | |||||
->filterByProductCategory(null) | ->filterByProductCategory(null) | ||||
->count(); | ->count(); | ||||
} | } |
use common\logic\Distribution\Distribution\Model\Distribution; | use common\logic\Distribution\Distribution\Model\Distribution; | ||||
use common\logic\Product\Product\Service\ProductDefinition; | use common\logic\Product\Product\Service\ProductDefinition; | ||||
use common\logic\Product\ProductCategory\Model\ProductCategory; | use common\logic\Product\ProductCategory\Model\ProductCategory; | ||||
use common\logic\StatusInterface; | |||||
class ProductRepositoryQuery extends AbstractRepositoryQuery | class ProductRepositoryQuery extends AbstractRepositoryQuery | ||||
{ | { | ||||
return $this; | return $this; | ||||
} | } | ||||
public function filterIsActive(): self | |||||
{ | |||||
$this->andWhere(['product.active' => true]); | |||||
return $this; | |||||
} | |||||
public function filterByProductCategory(ProductCategory $productCategory = null) : self | public function filterByProductCategory(ProductCategory $productCategory = null) : self | ||||
{ | { | ||||
if($productCategory) { | if($productCategory) { |
public function createProduct(): Product | public function createProduct(): Product | ||||
{ | { | ||||
$product = $this->instanciateProduct(); | $product = $this->instanciateProduct(); | ||||
$this->saveCreate($product); | |||||
$this->create($product); | |||||
return $product; | return $product; | ||||
} | } |
public function isProductActiveByDay(Product $product, string $day): bool | public function isProductActiveByDay(Product $product, string $day): bool | ||||
{ | { | ||||
return $product->active && $product->$day; | |||||
return $product->status && $product->$day; | |||||
} | } | ||||
public function getProductFieldNameQuantityMax(string $day): string | public function getProductFieldNameQuantityMax(string $day): string | ||||
$potentialRevenues = 0; | $potentialRevenues = 0; | ||||
foreach($productsArray as $product) { | foreach($productsArray as $product) { | ||||
if ($product['productDistribution'][0]['active'] && $product['productDistribution'][0]['quantity_max']) { | |||||
if (isset($product['productDistribution'][0]) && $product['productDistribution'][0]['active'] && $product['productDistribution'][0]['quantity_max']) { | |||||
$potentialRevenues += $product['productDistribution'][0]['quantity_max'] * $product['price']; | $potentialRevenues += $product['productDistribution'][0]['quantity_max'] * $product['price']; | ||||
} | } | ||||
} | } | ||||
$potentialWeight = 0; | $potentialWeight = 0; | ||||
foreach($productsArray as $product) { | foreach($productsArray as $product) { | ||||
if ($product['productDistribution'][0]['active'] && $product['productDistribution'][0]['quantity_max']) { | |||||
if (isset($product['productDistribution'][0]) && $product['productDistribution'][0]['active'] && $product['productDistribution'][0]['quantity_max']) { | |||||
$potentialWeight += $product['productDistribution'][0]['quantity_max'] * $product['weight'] / 1000; | $potentialWeight += $product['productDistribution'][0]['quantity_max'] * $product['weight'] / 1000; | ||||
} | } | ||||
} | } | ||||
return $potentialWeight; | return $potentialWeight; | ||||
} | } | ||||
public function isStatusOnlineOrOffline(Product $product): bool | |||||
{ | |||||
return $product->status >= Product::STATUS_OFFLINE; | |||||
} | |||||
} | } |
<?php | |||||
namespace common\logic; | |||||
interface StatusInterface | |||||
{ | |||||
const STATUS_DELETED = -1; | |||||
const STATUS_OFFLINE = 0; | |||||
const STATUS_ONLINE = 1; | |||||
} |
<?php | |||||
use yii\db\Migration; | |||||
use yii\db\Schema; | |||||
/** | |||||
* Class m230929_065700_rename_column_product_active_status | |||||
*/ | |||||
class m230929_065700_rename_column_product_active_status extends Migration | |||||
{ | |||||
/** | |||||
* {@inheritdoc} | |||||
*/ | |||||
public function safeUp() | |||||
{ | |||||
$this->renameColumn('product', 'active', 'status'); | |||||
} | |||||
/** | |||||
* {@inheritdoc} | |||||
*/ | |||||
public function safeDown() | |||||
{ | |||||
$this->renameColumn('product', 'status', 'active'); | |||||
} | |||||
} |
$productsArray = Product::find() | $productsArray = Product::find() | ||||
->where([ | ->where([ | ||||
'id_producer' => $producer->id, | 'id_producer' => $producer->id, | ||||
'product.active' => 1, | |||||
'product.status' => 1, | |||||
]); | ]); | ||||
$productsArray = $productsArray->joinWith([ | $productsArray = $productsArray->joinWith([ |
$queryProducts = Product::find() | $queryProducts = Product::find() | ||||
->andWhere([ | ->andWhere([ | ||||
'id_producer' => $this->getProducerCurrent()->id, | 'id_producer' => $this->getProducerCurrent()->id, | ||||
'active' => true, | |||||
'status' => Product::STATUS_ONLINE, | |||||
'id_product_category' => null, | 'id_product_category' => null, | ||||
]) | ]) | ||||
->with('productPointSale') | ->with('productPointSale') |
} | } | ||||
}, | }, | ||||
checkProductAvailable: function (product) { | checkProductAvailable: function (product) { | ||||
var available = product.active && | |||||
var available = product.status && | |||||
(!this.monday || (this.monday && product.monday)) && | (!this.monday || (this.monday && product.monday)) && | ||||
(!this.tuesday || (this.tuesday && product.tuesday)) && | (!this.tuesday || (this.tuesday && product.tuesday)) && | ||||
(!this.wednesday || (this.wednesday && product.wednesday)) && | (!this.wednesday || (this.wednesday && product.wednesday)) && |