@@ -117,7 +117,6 @@ class DistributionController extends BackendController | |||
$orderManager = $this->getOrderManager(); | |||
$productManager = $this->getProductManager(); | |||
$userManager = $this->getUserManager(); | |||
$pointSaleManager = $this->getPointSaleManager(); | |||
$producer = $this->getProducerCurrent(); | |||
$format = 'Y-m-d'; | |||
@@ -133,7 +132,7 @@ class DistributionController extends BackendController | |||
$distribution = $distributionManager->createDistributionIfNotExist($date); | |||
$ordersArray = $orderManager->findOrdersByDistribution($distribution); | |||
$ordersArrayObject = $ordersArray; | |||
$productsArray = $productManager->findProductsByDistribution($distribution); | |||
$productsArray = $productManager->findProductsByDistribution($distribution, false); | |||
$json['products'] = $this->buildAjaxInfosResponseProducts($distribution, $productsArray, $ordersArray); | |||
$json['distribution'] = $this->buildAjaxInfosResponseDistribution($distribution, $ordersArrayObject, $productsArray); | |||
@@ -192,8 +191,10 @@ class DistributionController extends BackendController | |||
if (!isset($product->productDistribution[0])) { | |||
$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 { | |||
foreach($product->productDistribution as $key => $productDistribution) { | |||
@@ -201,7 +202,7 @@ class DistributionController extends BackendController | |||
} | |||
} | |||
if (!is_numeric($product->productDistribution[0]->quantity_max)) { | |||
if (!isset($product->productDistribution[0]) || !is_numeric($product->productDistribution[0]->quantity_max)) { | |||
$jsonProduct['quantity_remaining'] = null; | |||
} else { | |||
$jsonProduct['quantity_remaining'] = $product->productDistribution[0]->quantity_max - $quantityOrder; | |||
@@ -356,7 +357,7 @@ class DistributionController extends BackendController | |||
$oneProductUnactivated = false; | |||
foreach ($order->productOrder as $productOrder) { | |||
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; | |||
} | |||
} |
@@ -578,7 +578,7 @@ class DocumentController extends BackendController | |||
if ($document) { | |||
$ordersArray = []; | |||
$productsArray = $productManager->findProducts(); | |||
$productsArray = $productManager->findProducts(false); | |||
foreach ($document->orders as $order) { | |||
$orderManager->initOrder($order); |
@@ -114,7 +114,7 @@ class ProductController extends BackendController | |||
$model = $productManager->instanciateProduct(); | |||
$model->active = 1; | |||
$model->status = Product::STATUS_ONLINE; | |||
$model->id_producer = GlobalParam::getCurrentProducerId(); | |||
$model->monday = 1; | |||
$model->tuesday = 1; | |||
@@ -322,11 +322,13 @@ class ProductController extends BackendController | |||
*/ | |||
public function actionDelete(int $id, bool $confirm = false) | |||
{ | |||
$productContainer = $this->getProductContainer(); | |||
$productDistributionContainer = $this->getProductDistributionContainer(); | |||
$product = $this->findModel($id); | |||
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é'); | |||
} else { | |||
@@ -352,19 +354,19 @@ class ProductController extends BackendController | |||
} | |||
} | |||
public function actionAjaxToggleActive($id, $active) | |||
public function actionAjaxToggleStatus($id, $status) | |||
{ | |||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |||
$distributionManager = $this->getDistributionManager(); | |||
$product = $this->findModel($id); | |||
$product->active = (int) $active; | |||
$product->status = (int) $status; | |||
$product->save(); | |||
$distributionManager->addProductIncomingDistributions($product); | |||
return ['success', 'id' => $id, 'active' => $active]; | |||
return ['success', 'id' => $id, 'status' => $status]; | |||
} | |||
/** |
@@ -281,7 +281,9 @@ class SubscriptionController extends BackendController | |||
$productManager = $this->getProductManager(); | |||
$productsQuery = Product::find() | |||
->where(['id_producer' => GlobalParam::getCurrentProducerId(),]); | |||
->where(['id_producer' => GlobalParam::getCurrentProducerId()]) | |||
->andWhere('status >= :status') | |||
->addParams(['status' => Product::STATUS_OFFLINE]); | |||
if ($idSubscription) { | |||
$productsQuery->joinWith(['productSubscription' => function ($query) use ($idSubscription) { |
@@ -128,6 +128,8 @@ class MailForm extends Model | |||
->where([ | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
]) | |||
->andWhere('status >= :status') | |||
->addParams(['status' => Product::STATUS_OFFLINE]) | |||
->innerJoinWith(['productDistribution' => function($query) use($distribution) { | |||
$query->andOnCondition([ | |||
'product_distribution.id_distribution' => $distribution->id, |
@@ -128,11 +128,11 @@ $this->setPageTitle('Distributions') ; | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr v-for="product in products"> | |||
<tr v-for="product in products" v-if="getProductDistribution(product)"> | |||
<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-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> | |||
</td> | |||
<td>{{ product.name }}</td> | |||
@@ -142,7 +142,7 @@ $this->setPageTitle('Distributions') ; | |||
</td> | |||
<td class="quantity-max"> | |||
<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> | |||
</div> | |||
</td> | |||
@@ -613,8 +613,8 @@ $this->setPageTitle('Distributions') ; | |||
<td colspan="6"> | |||
<strong><span class="glyphicon glyphicon-menu-right"></span> Produits</strong> | |||
<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> | |||
</ul> | |||
<div v-if="order.comment && order.comment.length > 0" class="comment"> | |||
@@ -720,7 +720,7 @@ $this->setPageTitle('Distributions') ; | |||
</tr> | |||
</thead> | |||
<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> | |||
<span class="label label-success" v-if="loadingUpdateProductOrder || order.productOrder[product.id].active">Actif</span> | |||
<span class="label label-danger" v-else>Inactif</span> |
@@ -311,7 +311,7 @@ $documentClass = $documentManager->getClass($model); | |||
<select class="form-control" v-model="productAddId" | |||
@change="changeProductAdd"> | |||
<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 }} | |||
</option> | |||
</select> |
@@ -22,7 +22,7 @@ $taxRateManager = $this->getTaxRateManager(); | |||
<div> | |||
<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, 'reference')->textInput(['maxlength' => 255]) ?> | |||
<?= $form->field($model, 'id_product_category')->dropDownList($productCategoryManager->populateProductCategoriesDropdownList()); ?> |
@@ -135,7 +135,8 @@ $this->addButton(['label' => 'Nouveau produit <span class="glyphicon glyphicon-p | |||
} | |||
], | |||
[ | |||
'attribute' => 'active', | |||
'attribute' => 'status', | |||
'label' => 'Actif', | |||
'headerOptions' => ['class' => 'active column-hide-on-mobile'], | |||
'filterOptions' => ['class' => 'column-hide-on-mobile'], | |||
'contentOptions' => ['class' => 'center column-hide-on-mobile'], | |||
@@ -145,7 +146,7 @@ $this->addButton(['label' => 'Nouveau produit <span class="glyphicon glyphicon-p | |||
return Toggle::widget( | |||
[ | |||
'name' => 'active', | |||
'checked' => $model->active, | |||
'checked' => $model->status, | |||
'options' => [ | |||
'data-id' => $model->id, | |||
'data-on' => 'Oui', |
@@ -134,17 +134,10 @@ function opendistrib_product_index() { | |||
$('body.product-index .toggle input').change(function() { | |||
var id = $(this).data('id'); | |||
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, | |||
active: active | |||
status: checked ? 1 : 0 | |||
}); | |||
}) | |||
} | |||
@@ -260,7 +260,7 @@ var app = new Vue({ | |||
initCountActiveProducts: function () { | |||
this.countActiveProducts = 0; | |||
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++; | |||
} | |||
} | |||
@@ -324,7 +324,7 @@ var app = new Vue({ | |||
}); | |||
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; | |||
} | |||
} | |||
@@ -340,9 +340,11 @@ var app = new Vue({ | |||
return false; | |||
}, | |||
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.productDistribution[0].quantity_max; | |||
&& product.quantity_ordered > this.getProductDistribution(product).quantity_max; | |||
}, | |||
pointSaleActiveClick: function (event) { | |||
var idPointSale = event.currentTarget.getAttribute('data-id-point-sale'); | |||
@@ -923,6 +925,13 @@ var app = new Vue({ | |||
}, | |||
getUnitCoefficient: function(unit) { | |||
return this.units[unit].coefficient; | |||
}, | |||
getProductDistribution: function(product) { | |||
if(typeof product.productDistribution !== 'undefined' && product.productDistribution[0]) { | |||
return product.productDistribution[0]; | |||
} | |||
return null; | |||
} | |||
}, | |||
}); | |||
@@ -1157,7 +1166,7 @@ Vue.component('order-form', { | |||
productQuantityOrder += this.getProductQuantityProductOrder(this.order, product); | |||
} | |||
quantityRemaining = product.productDistribution[0].quantity_max - productQuantityOrder; | |||
quantityRemaining = this.getProductDistribution(product).quantity_max - productQuantityOrder; | |||
if(unit != 'piece') { | |||
quantityRemaining = quantityRemaining.toFixed(2); | |||
} | |||
@@ -1172,6 +1181,11 @@ Vue.component('order-form', { | |||
}, | |||
getUnitCoefficient: function(unit) { | |||
return this.units[unit].coefficient; | |||
}, | |||
getProductDistribution: function(product) { | |||
if(typeof product.productDistribution !== 'undefined' && product.productDistribution[0]) { | |||
return product.productDistribution[0]; | |||
} | |||
} | |||
} | |||
}); |
@@ -37,4 +37,26 @@ abstract class AbstractBuilder extends AbstractService implements BuilderInterfa | |||
{ | |||
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); | |||
} | |||
} |
@@ -26,10 +26,12 @@ abstract class AbstractRepository extends AbstractService implements RepositoryI | |||
return $this->query; | |||
} | |||
public function createDefaultQuery(): RepositoryQueryInterface | |||
public function createDefaultQuery(bool $filterStatus = true): RepositoryQueryInterface | |||
{ | |||
$this->createQuery(); | |||
if($filterStatus) { | |||
$this->defaultStatus(); | |||
} | |||
$this->defaultWith(); | |||
$this->defaultJoinWith(); | |||
$this->defaultFilterProducerContext(); | |||
@@ -38,6 +40,14 @@ abstract class AbstractRepository extends AbstractService implements RepositoryI | |||
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 | |||
{ | |||
$defaultOptions = $this->getDefaultOptionsSearch(); |
@@ -16,6 +16,11 @@ abstract class AbstractRepositoryQuery extends AbstractService implements Reposi | |||
$this->definition = $this->loadService($serviceClass); | |||
} | |||
public function getDefinition() | |||
{ | |||
return $this->definition; | |||
} | |||
public function baseQuery(): ActiveQuery | |||
{ | |||
$class = $this->definition->getEntityFqcn(); | |||
@@ -76,6 +81,24 @@ abstract class AbstractRepositoryQuery extends AbstractService implements Reposi | |||
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 | |||
{ | |||
return new ActiveDataProvider([ |
@@ -17,6 +17,7 @@ use common\logic\Order\ProductOrder\Service\ProductOrderBuilder; | |||
use common\logic\PointSale\PointSale\Model\PointSale; | |||
use common\logic\Product\Product\Model\Product; | |||
use common\logic\Product\Product\Repository\ProductRepository; | |||
use common\logic\Product\Product\Service\ProductSolver; | |||
use common\logic\User\UserProducer\Repository\UserProducerRepository; | |||
class DistributionBuilder extends AbstractBuilder | |||
@@ -31,6 +32,7 @@ class DistributionBuilder extends AbstractBuilder | |||
protected OrderRepository $orderRepository; | |||
protected UserProducerRepository $userProducerRepository; | |||
protected ProductOrderBuilder $productOrderBuilder; | |||
protected ProductSolver $productSolver; | |||
public function loadDependencies(): void | |||
{ | |||
@@ -44,6 +46,7 @@ class DistributionBuilder extends AbstractBuilder | |||
$this->orderRepository = $this->loadService(OrderRepository::class); | |||
$this->userProducerRepository = $this->loadService(UserProducerRepository::class); | |||
$this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class); | |||
$this->productSolver = $this->loadService(ProductSolver::class); | |||
} | |||
public function instanciateDistribution(string $date, bool $delivery = true): Distribution | |||
@@ -57,13 +60,10 @@ class DistributionBuilder extends AbstractBuilder | |||
return $distribution; | |||
} | |||
// initDistribution | |||
public function createDistribution(string $date, bool $delivery = true): Distribution | |||
{ | |||
$distribution = $this->instanciateDistribution($date, $delivery); | |||
$this->saveCreate($distribution); | |||
$this->create($distribution); | |||
$this->createPointSaleDistributions($distribution); | |||
$this->createProductDistributions($distribution); | |||
@@ -99,13 +99,16 @@ class DistributionBuilder extends AbstractBuilder | |||
/** | |||
* 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; | |||
} | |||
/** |
@@ -4,6 +4,7 @@ namespace common\logic\Distribution\ProductDistribution\Service; | |||
use common\logic\AbstractBuilder; | |||
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\ProductDistribution\Model\ProductDistribution; | |||
use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository; | |||
@@ -15,12 +16,14 @@ class ProductDistributionBuilder extends AbstractBuilder | |||
protected ProductDistributionRepository $productDistributionRepository; | |||
protected DistributionSolver $distributionSolver; | |||
protected ProductSolver $productSolver; | |||
protected DistributionRepository $distributionRepository; | |||
public function loadDependencies(): void | |||
{ | |||
$this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class); | |||
$this->distributionSolver = $this->loadService(DistributionSolver::class); | |||
$this->productSolver = $this->loadService(ProductSolver::class); | |||
$this->distributionRepository = $this->loadService(DistributionRepository::class); | |||
} | |||
public function instanciateProductDistribution(Distribution $distribution, Product $product): ProductDistribution | |||
@@ -96,4 +99,16 @@ class ProductDistributionBuilder extends AbstractBuilder | |||
$productDistribution->active = $active; | |||
$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 | |||
]); | |||
} | |||
} | |||
} |
@@ -5,6 +5,7 @@ namespace common\logic\PointSale\PointSale\Repository; | |||
use common\logic\AbstractRepositoryQuery; | |||
use common\logic\PointSale\PointSale\Model\PointSale; | |||
use common\logic\PointSale\PointSale\Service\PointSaleDefinition; | |||
use common\logic\StatusInterface; | |||
use yii\db\ActiveQuery; | |||
class PointSaleRepositoryQuery extends AbstractRepositoryQuery | |||
@@ -32,7 +33,7 @@ class PointSaleRepositoryQuery extends AbstractRepositoryQuery | |||
public function filterIsOnline(): self | |||
{ | |||
$this->andWhere(['status' => 1]); | |||
$this->andWhere(['status' => StatusInterface::STATUS_ONLINE]); | |||
return $this; | |||
} |
@@ -47,6 +47,7 @@ use common\logic\Product\ProductCategory\Model\ProductCategory; | |||
use common\logic\Product\ProductPointSale\Model\ProductPointSale; | |||
use common\logic\Product\ProductPrice\Model\ProductPrice; | |||
use common\components\ActiveRecordCommon; | |||
use common\logic\StatusInterface; | |||
use common\logic\Subscription\ProductSubscription\Model\ProductSubscription; | |||
use yii\web\UploadedFile; | |||
@@ -54,7 +55,7 @@ use yii\web\UploadedFile; | |||
* This is the model class for table "product". | |||
* | |||
*/ | |||
class Product extends ActiveRecordCommon | |||
class Product extends ActiveRecordCommon implements StatusInterface | |||
{ | |||
public $total = 0; | |||
public $apply_distributions = true; | |||
@@ -122,7 +123,7 @@ class Product extends ActiveRecordCommon | |||
{ | |||
return [ | |||
[['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'], | |||
[['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'], | |||
@@ -148,7 +149,6 @@ class Product extends ActiveRecordCommon | |||
'name' => 'Nom', | |||
'reference' => 'Référence', | |||
'description' => 'Description', | |||
'active' => 'Actif', | |||
'photoFile' => 'Photo', | |||
'price' => 'Prix (€) TTC', | |||
'weight' => 'Poids', | |||
@@ -175,7 +175,8 @@ class Product extends ActiveRecordCommon | |||
'step' => 'Pas', | |||
'id_tax_rate' => 'TVA', | |||
'id_product_category' => 'Catégorie', | |||
'available_on_points_sale' => 'Par défaut' | |||
'available_on_points_sale' => 'Par défaut', | |||
'status' => 'Actif', | |||
]; | |||
} | |||
@@ -47,7 +47,7 @@ class ProductSearch extends Product | |||
public function rules() | |||
{ | |||
return [ | |||
[['active', 'order', 'quantity_max', 'id_producer'], 'integer'], | |||
[['order', 'quantity_max', 'id_producer', 'status'], 'integer'], | |||
[['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable'], 'boolean'], | |||
[['price', 'weight'], 'number'], | |||
[[ 'photo'], 'file'], | |||
@@ -65,12 +65,12 @@ class ProductSearch extends Product | |||
->with($optionsSearch['with']) | |||
->innerJoinWith($optionsSearch['join_with'], true) | |||
->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([ | |||
'query' => $query, | |||
'sort' => ['attributes' => ['order', 'photo', 'name', 'description','active']], | |||
'sort' => ['attributes' => ['order', 'photo', 'name', 'description','status']], | |||
'pagination' => [ | |||
'pageSize' => 1000, | |||
], | |||
@@ -84,9 +84,9 @@ class ProductSearch extends Product | |||
$query->andFilterWhere(['like', 'product.name', $this->name]) ; | |||
$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([ | |||
'product.active' => $this->active | |||
'product.status' => $this->status | |||
]) ; | |||
} | |||
@@ -53,9 +53,9 @@ class ProductRepository extends AbstractRepository | |||
->findOne(); | |||
} | |||
public function findProducts(): array | |||
public function findProducts(bool $filterStatus = true): array | |||
{ | |||
return $this->createDefaultQuery()->find(); | |||
return $this->createDefaultQuery($filterStatus)->find(); | |||
} | |||
/** | |||
@@ -66,9 +66,9 @@ class ProductRepository extends AbstractRepository | |||
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([ | |||
'productDistribution' => function ($query) use ($distribution) { | |||
$query->andOnCondition( | |||
@@ -82,9 +82,9 @@ class ProductRepository extends AbstractRepository | |||
/** | |||
* 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); | |||
} | |||
@@ -106,14 +106,14 @@ class ProductRepository extends AbstractRepository | |||
public function queryProductsByProductCategory(ProductCategory $productCategory) | |||
{ | |||
return $this->createDefaultQuery() | |||
->filterIsActive() | |||
->filterIsStatusOnline() | |||
->filterByProductCategory($productCategory); | |||
} | |||
public function countProductsWithoutCategory(Producer $producer): int | |||
{ | |||
return $this->createDefaultQuery() | |||
->filterIsActive() | |||
->filterIsStatusOnline() | |||
->filterByProductCategory(null) | |||
->count(); | |||
} |
@@ -6,6 +6,7 @@ use common\logic\AbstractRepositoryQuery; | |||
use common\logic\Distribution\Distribution\Model\Distribution; | |||
use common\logic\Product\Product\Service\ProductDefinition; | |||
use common\logic\Product\ProductCategory\Model\ProductCategory; | |||
use common\logic\StatusInterface; | |||
class ProductRepositoryQuery extends AbstractRepositoryQuery | |||
{ | |||
@@ -28,12 +29,6 @@ class ProductRepositoryQuery extends AbstractRepositoryQuery | |||
return $this; | |||
} | |||
public function filterIsActive(): self | |||
{ | |||
$this->andWhere(['product.active' => true]); | |||
return $this; | |||
} | |||
public function filterByProductCategory(ProductCategory $productCategory = null) : self | |||
{ | |||
if($productCategory) { |
@@ -17,7 +17,7 @@ class ProductBuilder extends AbstractBuilder | |||
public function createProduct(): Product | |||
{ | |||
$product = $this->instanciateProduct(); | |||
$this->saveCreate($product); | |||
$this->create($product); | |||
return $product; | |||
} |
@@ -189,7 +189,7 @@ class ProductSolver extends AbstractService implements SolverInterface | |||
public function isProductActiveByDay(Product $product, string $day): bool | |||
{ | |||
return $product->active && $product->$day; | |||
return $product->status && $product->$day; | |||
} | |||
public function getProductFieldNameQuantityMax(string $day): string | |||
@@ -249,7 +249,7 @@ class ProductSolver extends AbstractService implements SolverInterface | |||
$potentialRevenues = 0; | |||
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']; | |||
} | |||
} | |||
@@ -262,11 +262,16 @@ class ProductSolver extends AbstractService implements SolverInterface | |||
$potentialWeight = 0; | |||
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; | |||
} | |||
} | |||
return $potentialWeight; | |||
} | |||
public function isStatusOnlineOrOffline(Product $product): bool | |||
{ | |||
return $product->status >= Product::STATUS_OFFLINE; | |||
} | |||
} |
@@ -0,0 +1,10 @@ | |||
<?php | |||
namespace common\logic; | |||
interface StatusInterface | |||
{ | |||
const STATUS_DELETED = -1; | |||
const STATUS_OFFLINE = 0; | |||
const STATUS_ONLINE = 1; | |||
} |
@@ -0,0 +1,26 @@ | |||
<?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'); | |||
} | |||
} |
@@ -890,7 +890,7 @@ class OrderController extends ProducerBaseController | |||
$productsArray = Product::find() | |||
->where([ | |||
'id_producer' => $producer->id, | |||
'product.active' => 1, | |||
'product.status' => 1, | |||
]); | |||
$productsArray = $productsArray->joinWith([ |
@@ -116,7 +116,7 @@ class SiteController extends ProducerBaseController | |||
$queryProducts = Product::find() | |||
->andWhere([ | |||
'id_producer' => $this->getProducerCurrent()->id, | |||
'active' => true, | |||
'status' => Product::STATUS_ONLINE, | |||
'id_product_category' => null, | |||
]) | |||
->with('productPointSale') |
@@ -126,7 +126,7 @@ var app = new Vue({ | |||
} | |||
}, | |||
checkProductAvailable: function (product) { | |||
var available = product.active && | |||
var available = product.status && | |||
(!this.monday || (this.monday && product.monday)) && | |||
(!this.tuesday || (this.tuesday && product.tuesday)) && | |||
(!this.wednesday || (this.wednesday && product.wednesday)) && |