<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="getProductDistribution(product).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">{{ labelUnitReference(product.unit) }}</span> | |||||
</div> | </div> | ||||
<div class="limit-quantity-accessories" v-if="getProductDistribution(product).quantity_max != product.quantity_max && product.quantity_max"> | |||||
<div class="limit-quantity-accessories" v-if="!showLoading && product.quantity_max && (getProductDistribution(product).quantity_max > product.quantity_max || !getProductDistribution(product).quantity_max)"> | |||||
<span class="glyphicon glyphicon-warning-sign"></span> Limitation accessoires : | <span class="glyphicon glyphicon-warning-sign"></span> Limitation accessoires : | ||||
<strong>{{ product.quantity_max }} {{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</strong> | |||||
<strong>{{ product.quantity_max }} {{ labelUnitReference(product.unit) }}</strong> | |||||
</div> | </div> | ||||
</td> | </td> | ||||
</tr> | </tr> | ||||
<td class="quantity-remaining"> | <td class="quantity-remaining"> | ||||
<span class="infinite" v-if="(getProductQuantityRemaining(order, product) === null) || order.productOrder[product.id].unit != product.unit">∞</span> | <span class="infinite" v-if="(getProductQuantityRemaining(order, product) === null) || order.productOrder[product.id].unit != product.unit">∞</span> | ||||
<span class="negative" v-else-if="getProductQuantityRemaining(order, product) <= 0"> | <span class="negative" v-else-if="getProductQuantityRemaining(order, product) <= 0"> | ||||
{{ getProductQuantityRemaining(order, product) }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }} | |||||
{{ getProductQuantityRemaining(order, product) }} {{ labelUnitReference(order.productOrder[product.id].unit) }} | |||||
<span class="glyphicon glyphicon-alert" v-if="getProductQuantityRemaining(order, product) < 0"></span> | <span class="glyphicon glyphicon-alert" v-if="getProductQuantityRemaining(order, product) < 0"></span> | ||||
</span> | </span> | ||||
<span class="has-quantity" v-else>{{ getProductQuantityRemaining(order, product) }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</span> | |||||
<span class="has-quantity" v-else>{{ getProductQuantityRemaining(order, product) }} {{ labelUnitReference(order.productOrder[product.id].unit) }}</span> | |||||
</td> | </td> | ||||
</tr> | </tr> | ||||
</tbody> | </tbody> |
opendistrib_sponsorship(); | opendistrib_sponsorship(); | ||||
}); | }); | ||||
function label_unit_reference(unit) { | |||||
if(unit == 'piece') { | |||||
return 'p.'; | |||||
} | |||||
else if(unit == 'g' || unit == 'kg') { | |||||
return 'kg'; | |||||
} | |||||
else { | |||||
return 'litre(s)'; | |||||
} | |||||
} | |||||
function opendistrib_sponsorship() { | function opendistrib_sponsorship() { | ||||
$('#sponsorship-link-copy').click(function() { | $('#sponsorship-link-copy').click(function() { | ||||
navigator.clipboard.writeText($(this).attr('href')); | navigator.clipboard.writeText($(this).attr('href')); |
} | } | ||||
}); | }); | ||||
}, | }, | ||||
labelUnitReference: function(unit) { | |||||
return label_unit_reference(unit); | |||||
}, | |||||
getProductQuantityRemainingGlobal: function(product) { | getProductQuantityRemainingGlobal: function(product) { | ||||
var app = this; | var app = this; | ||||
this.init(); | this.init(); | ||||
}, | }, | ||||
productQuantityMaxChange: function (event) { | productQuantityMaxChange: function (event) { | ||||
var app = this; | |||||
var quantityMax = event.currentTarget.value; | var quantityMax = event.currentTarget.value; | ||||
axios.get("ajax-process-product-quantity-max", { | axios.get("ajax-process-product-quantity-max", { | ||||
params: { | params: { | ||||
} | } | ||||
}) | }) | ||||
.then(function (response) { | .then(function (response) { | ||||
app.init(app.idActivePointSale); | |||||
}); | }); | ||||
}, | }, | ||||
productActiveClick: function (event) { | productActiveClick: function (event) { | ||||
} | } | ||||
}, | }, | ||||
methods: { | methods: { | ||||
labelUnitReference: function(unit) { | |||||
return label_unit_reference(unit); | |||||
}, | |||||
checkForm: function () { | checkForm: function () { | ||||
this.errors = []; | this.errors = []; | ||||
} | } | ||||
$productQuantity = $this->orderSolver->getProductQuantity($product, $ordersArray); | $productQuantity = $this->orderSolver->getProductQuantity($product, $ordersArray); | ||||
if($inNumberOfPieces) { | if($inNumberOfPieces) { | ||||
$productQuantity = $this->productSolver->getNumberOfPieces($productQuantity, $product); | $productQuantity = $this->productSolver->getNumberOfPieces($productQuantity, $product); | ||||
} | } |
{ | { | ||||
// Poids total | // Poids total | ||||
if($product->unit != 'piece') { | if($product->unit != 'piece') { | ||||
$quantity = ($quantity * $product->weight) / $this->getUnitCoefficient($product); | |||||
$quantity = ($quantity * $product->weight) / 1000; | |||||
} | } | ||||
return $quantity; | return $quantity; | ||||
public function getNumberOfPieces(float $quantity, Product $product): int | public function getNumberOfPieces(float $quantity, Product $product): int | ||||
{ | { | ||||
if($product->unit != 'piece') { | if($product->unit != 'piece') { | ||||
$quantity = ($quantity * $this->getUnitCoefficient($product)) / $product->weight; | |||||
$quantity = $quantity / ($product->weight / 1000); | |||||
} | } | ||||
return $quantity; | return $quantity; |
<div class="panel panel-default"> | <div class="panel panel-default"> | ||||
<div class="panel-heading"> | <div class="panel-heading"> | ||||
<h3 class="panel-title"> | |||||
<h3 class="panel-title" id="modules"> | |||||
<i class="bi bi-boxes"></i> | <i class="bi bi-boxes"></i> | ||||
Modules | Modules | ||||
</h3> | </h3> | ||||
</div> | </div> | ||||
<div class="panel-body"> | <div class="panel-body"> | ||||
<div class="alert alert-dark" role="alert"> | <div class="alert alert-dark" role="alert"> | ||||
Retrouvez ici les modules payants de Souke correspondant aux développements qui n'ont pas encore | |||||
été totalement financés et aux fonctionnalités nécessitant une configuration spécifique. Contactez-moi | |||||
pour demander l'activation d'un module. | |||||
Retrouvez ici les modules payants de Souke correspondant à des fonctionnalités en lien avec des | |||||
plateformes externes ou à des développements répondant à des besoins spécifiques. N'hésitez pas à | |||||
<a href="<?= Yii::$app->urlManager->createUrl(['site/contact']) ?>">me contacter</a> pour en savoir plus ou pour demander l'activation d'un module. | |||||
</div> | </div> | ||||
<table class="table table-striped table-bordered"> | <table class="table table-striped table-bordered"> | ||||
<thead> | <thead> |
</div> | </div> | ||||
<div class="row"> | <div class="row"> | ||||
<?= block_feature("calendar3", "Planification des jours de distributions"); ?> | <?= block_feature("calendar3", "Planification des jours de distributions"); ?> | ||||
<?= block_feature("download", "Récapitulatif des commandes par jour de distribution (PDF et CSV), génération d'étiquettes (PDF)"); ?> | |||||
<?= block_feature("download", "Récapitulatif des commandes par jour de distribution (PDF et CSV)<br />Génération d'étiquettes simple (PDF)<br />Génération d'étiquettes avec format spécifique (PDF) *"); ?> | |||||
</div> | </div> | ||||
<div class="row"> | <div class="row"> | ||||
<?= block_feature("basket", "Gestion des produits, catégories et prix spécifiques"); ?> | |||||
<?= block_feature("basket", "Gestion des produits, catégories et prix spécifiques<br />Gestion des accessoires produits *"); ?> | |||||
<?php $featureSharedPointSaleDescription = ''; | <?php $featureSharedPointSaleDescription = ''; | ||||
if($featureChecker->isEnabled(Feature::ALIAS_SHARED_POINT_SALE)): | if($featureChecker->isEnabled(Feature::ALIAS_SHARED_POINT_SALE)): | ||||
$featureSharedPointSaleDescription .= "<br />Partage de points de vente entre plusieurs producteurs pour des distributions communes"; | $featureSharedPointSaleDescription .= "<br />Partage de points de vente entre plusieurs producteurs pour des distributions communes"; | ||||
</div> | </div> | ||||
<div class="row"> | <div class="row"> | ||||
<?= block_feature("piggy-bank", "Système de cagnotte permettant la comptabilisation des paiements"); ?> | <?= block_feature("piggy-bank", "Système de cagnotte permettant la comptabilisation des paiements"); ?> | ||||
<?= block_feature("credit-card", "Paiement en ligne possible via la plateforme <strong>Stripe</strong> pour que les clients puissent alimenter leur cagnotte de manière autonome"); ?> | |||||
<?= block_feature("credit-card", "Paiement en ligne via la plateforme <strong>Stripe</strong> pour le paiement des commandes ou l'alimentation des cagnottes *"); ?> | |||||
</div> | </div> | ||||
<div class="row"> | <div class="row"> | ||||
<?= block_feature("megaphone", "Communication facilitée avec les clients via l'envoi d'emails en masse"); ?> | <?= block_feature("megaphone", "Communication facilitée avec les clients via l'envoi d'emails en masse"); ?> | ||||
</div> | </div> | ||||
<div class="row"> | <div class="row"> | ||||
<?= block_feature("graph-up", "Statistiques et rapports de vente"); ?> | <?= block_feature("graph-up", "Statistiques et rapports de vente"); ?> | ||||
<?= block_feature("cloud-arrow-up", "Exports vers les logiciels <strong>Evoliz</strong> (comptabilité) et <strong>SumUp</strong> (caisse)"); ?> | |||||
<?= block_feature("cloud-arrow-up", "Exports vers les logiciels <strong>Evoliz</strong> (comptabilité) et <strong>SumUp</strong> (caisse) *"); ?> | |||||
</div> | </div> | ||||
<p> | |||||
* <a href="#modules">Modules payants</a> | |||||
</p> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
) && isset($unitsArray[$product->id])) ? $unitsArray[$product->id] : $product->unit; | ) && isset($unitsArray[$product->id])) ? $unitsArray[$product->id] : $product->unit; | ||||
$coefficient = Product::$unitsArray[$unit]['coefficient']; | $coefficient = Product::$unitsArray[$unit]['coefficient']; | ||||
$quantity = ((float)$posts['products'][$product->id]) / $coefficient; | $quantity = ((float)$posts['products'][$product->id]) / $coefficient; | ||||
if ($availableProducts[$product->id]['quantity_max'] && $quantity > $availableProducts[$product->id]['quantity_remaining']) { | |||||
$quantity = $availableProducts[$product->id]['quantity_remaining']; | |||||
$quantityRemaining = $orderModule->getResolver()->getProductQuantityRemaining($product, $order->distribution); | |||||
if(!is_null($quantityRemaining) && $quantity > $quantityRemaining) { | |||||
$quantity = $quantityRemaining; | |||||
} | } | ||||
$productOrder->quantity = $quantity; | $productOrder->quantity = $quantity; | ||||
$productOrder->price = $productModule->getPrice($product, [ | $productOrder->price = $productModule->getPrice($product, [ |