Browse Source

Merge branch 'feature/specific_prices' into dev

# Conflicts:
#	backend/controllers/ProductController.php
#	backend/web/js/backend.js
#	common/models/Subscription.php
dev
Guillaume 3 years ago
parent
commit
708d230018
32 changed files with 1768 additions and 654 deletions
  1. +34
    -0
      backend/controllers/DistributionController.php
  2. +272
    -173
      backend/controllers/ProductController.php
  3. +19
    -0
      backend/controllers/UserController.php
  4. +6
    -4
      backend/views/distribution/index.php
  5. +4
    -0
      backend/views/point-sale/_form.php
  6. +89
    -128
      backend/views/product/_form.php
  7. +14
    -0
      backend/views/product/update/_nav.php
  8. +4
    -0
      backend/views/product/update/_nav_item.php
  9. +3
    -0
      backend/views/product/update/prices/_base_price.php
  10. +66
    -0
      backend/views/product/update/prices/_form.php
  11. +27
    -19
      backend/views/product/update/prices/create.php
  12. +227
    -0
      backend/views/product/update/prices/list.php
  13. +61
    -0
      backend/views/product/update/prices/update.php
  14. +62
    -0
      backend/views/product/update/update.php
  15. +4
    -0
      backend/views/user/_form.php
  16. +203
    -198
      backend/web/css/screen.css
  17. +43
    -8
      backend/web/js/backend.js
  18. +51
    -0
      backend/web/js/vuejs/distribution-index.js
  19. +0
    -8
      backend/web/sass/producer/_update.scss
  20. +18
    -0
      backend/web/sass/screen.scss
  21. +16
    -2
      common/models/PointSale.php
  22. +64
    -6
      common/models/Product.php
  23. +153
    -0
      common/models/ProductPrice.php
  24. +94
    -0
      common/models/ProductPriceSearch.php
  25. +4
    -1
      common/models/Subscription.php
  26. +39
    -3
      common/models/User.php
  27. +95
    -88
      common/models/UserProducer.php
  28. +30
    -0
      console/migrations/m201207_160043_specific_prices.php
  29. +34
    -0
      console/migrations/m201207_164410_specific_prices_percent.php
  30. +10
    -14
      producer/controllers/OrderController.php
  31. +18
    -1
      producer/controllers/SubscriptionController.php
  32. +4
    -1
      producer/web/js/vuejs/order-order.js

+ 34
- 0
backend/controllers/DistributionController.php View File

@@ -43,6 +43,7 @@ use common\helpers\GlobalParam;
use common\models\DeliveryNote;
use common\models\Distribution;
use common\models\Document;
use common\models\PointSale;
use common\models\Product;
use common\models\Producer;
use common\models\Order;
@@ -396,6 +397,39 @@ class DistributionController extends BackendController
];
}

public function actionAjaxUpdateProductOrder($idUser = false, $idPointSale = false)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

$user = User::findOne($idUser) ;
$userProducer = UserProducer::searchOne([
'id_user' => $idUser,
]) ;
$pointSale = PointSale::findOne($idPointSale) ;

$productsArray = Product::find()
->where([
'id_producer' => GlobalParam::getCurrentProducerId(),
'product.active' => 1,
])->joinWith(['productPrice'])
->all();

$productOrderArray = [];
foreach ($productsArray as $product) {
$productOrderArray[$product['id']] = [
'quantity' => 0,
'unit' => $product->unit,
'price' => $product->getPriceWithTax([
'user' => $user,
'user_producer' => $userProducer,
'point_sale' => $pointSale
]),
];
}

return $productOrderArray ;
}

/**
* Génére un PDF récapitulatif des des commandes d'un producteur pour une
* date donnée (Méthode appelable via CRON)

+ 272
- 173
backend/controllers/ProductController.php View File

@@ -1,45 +1,49 @@
<?php

/**
Copyright distrib (2018)
contact@opendistrib.net
Ce logiciel est un programme informatique servant à aider les producteurs
à distribuer leur production en circuits courts.
Ce logiciel est régi par la licence CeCILL soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info".
En contrepartie de l'accessibilité au code source et des droits de copie,
de modification et de redistribution accordés par cette licence, il n'est
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
seule une responsabilité restreinte pèse sur l'auteur du programme, le
titulaire des droits patrimoniaux et les concédants successifs.
A cet égard l'attention de l'utilisateur est attirée sur les risques
associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes.
*/
/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

namespace backend\controllers;

use common\helpers\GlobalParam;
use common\models\ProductDistribution;
use common\models\ProductPrice;
use common\models\ProductPriceSearch;
use common\models\ProductSearch;
use common\models\UserSearch;
use Yii;
use yii\filters\AccessControl;
use common\models\Product;
@@ -56,61 +60,60 @@ use common\helpers\Upload;
/**
* ProduitController implements the CRUD actions for Produit model.
*/
class ProductController extends BackendController
class ProductController extends BackendController
{
var $enableCsrfValidation = false;

public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
],
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return User::hasAccessBackend();
}
]
],
],
];
}
var $enableCsrfValidation = false;

/**
* Liste les modèles Produit.
*
* @return mixed
*/
public function actionIndex()
{
$searchModel = new ProductSearch() ;
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
],
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return User::hasAccessBackend();
}
]
],
],
];
}

/**
* Crée un modèle Produit.
* Si la création réussit, le navigateur est redirigé vers la page 'index'.
*
* @return mixed
*/
public function actionCreate()
{
$model = new Product();
/**
* Liste les modèles Produit.
*
* @return mixed
*/
public function actionIndex()
{
$searchModel = new ProductSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);

return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}

$model->active = 1;
$model->id_producer = GlobalParam::getCurrentProducerId();
/**
* Crée un modèle Produit.
* Si la création réussit, le navigateur est redirigé vers la page 'index'.
*
* @return mixed
*/
public function actionCreate()
{
$model = new Product();
$model->active = 1;
$model->id_producer = GlobalParam::getCurrentProducerId();

$model->monday = 1 ;
$model->tuesday = 1 ;
@@ -132,11 +135,11 @@ class ProductController extends BackendController

// link product / distribution
Distribution::linkProductIncomingDistributions($model) ;
Yii::$app->getSession()->setFlash('success', 'Produit <strong>'.Html::encode($model->name).'</strong> ajouté');

return $this->redirect(['index']);
}
}
else {
return $this->render('create', [
'model' => $model,
@@ -144,100 +147,196 @@ class ProductController extends BackendController
}
}

/**
* Modifie un modèle Produit existant.
* Si la modification réussit, le navigateur est redirigé vers la page 'index'.
*
* @param integer $id
* @return mixed
*/
public function actionUpdate($id)
{
$request = Yii::$app->request;
/**
* Modifie un modèle Produit existant.
* Si la modification réussit, le navigateur est redirigé vers la page 'index'.
*
* @param integer $id
* @return mixed
*/
public function actionUpdate($id)
{
$request = Yii::$app->request;

$model = $this->findModel($id);
$photoFilenameOld = $model->photo;
$model = $this->findModel($id);
$photoFilenameOld = $model->photo;

if ($model->load(Yii::$app->request->post()) && $model->save()) {
Upload::uploadFile($model, 'photo', $photoFilenameOld);
if ($model->load(Yii::$app->request->post()) && $model->save()) {

$deletePhoto = $request->post('delete_photo', 0);
if ($deletePhoto) {
$model->photo = '';
$model->save();
}
if($model->apply_distributions) {
// link product / distribution
Distribution::linkProductIncomingDistributions($model) ;
}
Yii::$app->getSession()->setFlash('success', 'Produit <strong>'.Html::encode($model->name).'</strong> modifié');
return $this->redirect(['index']);
} else {
return $this->render('update', [
'model' => $model,
]);
Upload::uploadFile($model, 'photo', $photoFilenameOld);

$deletePhoto = $request->post('delete_photo', 0);
if ($deletePhoto) {
$model->photo = '';
$model->save();
}

if ($model->apply_distributions) {
// link product / distribution
Distribution::linkProductIncomingDistributions($model);
}

Yii::$app->getSession()->setFlash('success', 'Produit <strong>' . Html::encode($model->name) . '</strong> modifié');
return $this->redirect(['index']);
}

return $this->render('update/update', [
'model' => $model,
'action' => 'update',
]);
}
}

/**
* Supprime un modèle Produit.
* Si la suppression réussit, le navigateur est redirigé vers la page
* 'index'.
*
* @param integer $id
* @return mixed
*/
public function actionDelete($id, $confirm = false)
{
$product = $this->findModel($id) ;
if($confirm) {
$product->delete();
ProductDistribution::deleteAll(['id_product' => $id]) ;
Yii::$app->getSession()->setFlash('success', 'Produit <strong>'.Html::encode($product->name).'</strong> supprimé');
}
else {
Yii::$app->getSession()->setFlash('info', 'Souhaitez-vous vraiment supprimer le produit <strong>'.Html::encode($product->name).'</strong> ? '
. Html::a('Oui',['product/delete','id' => $id, 'confirm' => 1], ['class' => 'btn btn-default']).' '.Html::a('Non', ['product/index'], ['class' => 'btn btn-default']));
public function actionPricesList($id)
{
$request = Yii::$app->request;
$model = $this->findModel($id);

$searchModel = new ProductPriceSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);

$userProducerWithProductPercent = UserProducer::searchAll([], [
'join_with' => ['user'],
'conditions' => 'user_producer.product_price_percent != 0',
]) ;

$pointSaleWithProductPercent = PointSale::searchAll([], [
'conditions' => 'point_sale.product_price_percent != 0'
]) ;

return $this->render('update/prices/list', [
'model' => $model,
'action' => 'prices-list',
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'userProducerWithProductPercent' => $userProducerWithProductPercent,
'pointSaleWithProductPercent' => $pointSaleWithProductPercent,
]);
}
return $this->redirect(['index']);
}

/**
* Modifie l'ordre des produits.
*
* @param array $array
*/
public function actionOrder()
{
$array = Yii::$app->request->post('array') ;
$orderArray = json_decode(stripslashes($array));
foreach($orderArray as $id => $order) {
$product = $this->findModel($id);
$product->order = $order;
$product->save();
public function actionPricesCreate($idProduct)
{
$model = new ProductPrice();
$model->id_product = $idProduct;
$modelProduct = $this->findModel($idProduct) ;

if ($model->load(Yii::$app->request->post())) {

$conditionsProductPriceExist = [
'id_product' => $idProduct,
'id_user' => $model->id_user ? $model->id_user : null,
'id_point_sale' => $model->id_point_sale ? $model->id_point_sale : null,
] ;

$productPriceExist = ProductPrice::findOne($conditionsProductPriceExist) ;

if($productPriceExist) {
$productPriceExist->delete() ;
Yii::$app->getSession()->setFlash('warning', 'Un prix existait déjà pour cet utilisateur / point de vente, il a été supprimé.');
}

if($model->save()) {
Yii::$app->getSession()->setFlash('success', 'Le prix a bien été ajouté.');
return $this->redirect(['product/prices-list', 'id' => $idProduct]);
}
}

return $this->render('update/prices/create', [
'model' => $model,
'modelProduct' => $modelProduct,
]);
}
}

/**
* Recherche un produit en fonction de son ID.
*
* @param integer $id
* @return Produit
* @throws NotFoundHttpException si le modèle n'est pas trouvé
*/
protected function findModel($id)
{
if (($model = Product::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
public function actionPricesUpdate($id)
{
$request = Yii::$app->request;

$model = $this->findModelProductPrice($id);
$modelProduct = $this->findModel($model->id_product) ;

if ($model->load(Yii::$app->request->post()) && $model->save()) {
Yii::$app->getSession()->setFlash('success', 'Prix modifié');
return $this->redirect(['product/prices-list', 'id' => $model->id_product]);
}

return $this->render('update/prices/update', [
'model' => $model,
'modelProduct' => $modelProduct,
'action' => 'prices-update',
]);
}

public function actionPricesDelete($id)
{
$productPrice = $this->findModelProductPrice($id);
$productPrice->delete();
Yii::$app->getSession()->setFlash('success', 'Prix supprimé');
return $this->redirect(['product/prices-list', 'id' => $productPrice->id_product]);
}

/**
* Supprime un modèle Produit.
* Si la suppression réussit, le navigateur est redirigé vers la page
* 'index'.
*
* @param integer $id
* @return mixed
*/
public function actionDelete($id, $confirm = false)
{
$product = $this->findModel($id);

if ($confirm) {
$product->delete();
ProductDistribution::deleteAll(['id_product' => $id]);
Yii::$app->getSession()->setFlash('success', 'Produit <strong>' . Html::encode($product->name) . '</strong> supprimé');
} else {
Yii::$app->getSession()->setFlash('info', 'Souhaitez-vous vraiment supprimer le produit <strong>' . Html::encode($product->name) . '</strong> ? '
. Html::a('Oui', ['product/delete', 'id' => $id, 'confirm' => 1], ['class' => 'btn btn-default']) . ' ' . Html::a('Non', ['product/index'], ['class' => 'btn btn-default']));
}

return $this->redirect(['index']);
}

/**
* Modifie l'ordre des produits.
*
* @param array $array
*/
public function actionOrder()
{
$array = Yii::$app->request->post('array');
$orderArray = json_decode(stripslashes($array));

foreach ($orderArray as $id => $order) {
$product = $this->findModel($id);
$product->order = $order;
$product->save();
}
}

/**
* Recherche un produit en fonction de son ID.
*
* @param integer $id
* @return Produit
* @throws NotFoundHttpException si le modèle n'est pas trouvé
*/
protected function findModel($id)
{
if (($model = Product::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}

protected function findModelProductPrice($id)
{
if (($model = ProductPrice::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}

}

+ 19
- 0
backend/controllers/UserController.php View File

@@ -127,6 +127,12 @@ class UserController extends BackendController
$model->points_sale[] = $userPointSaleArray->id_point_sale;
}
}

$userProducer = UserProducer::searchOne([
'id_producer' => GlobalParam::getCurrentProducerId(),
'id_user' => $model->id
]) ;
$model->product_price_percent = $userProducer->product_price_percent ;
}

// points de vente
@@ -193,6 +199,7 @@ class UserController extends BackendController

$model->sendMailWelcome($password);
$this->processLinkPointSale($model);
$this->processProductPricePercent($model) ;

Yii::$app->getSession()->setFlash('success', 'Utilisateur créé.');
$model = new User();
@@ -230,6 +237,7 @@ class UserController extends BackendController
$model->sendMailWelcome($password);
}
$this->processLinkPointSale($model);
$this->processProductPricePercent($model) ;
Yii::$app->getSession()->setFlash('success', 'Utilisateur modifié.');
}
} else {
@@ -288,6 +296,17 @@ class UserController extends BackendController
}
}

public function processProductPricePercent($model)
{
$userProducer = UserProducer::searchOne([
'id_producer' => GlobalParam::getCurrentProducerId(),
'id_user' => $model->id
]) ;
$userProducer->product_price_percent = $model->product_price_percent ;

$userProducer->save() ;
}

/**
* Désactive l'utilisateur de l'établissement.
*

+ 6
- 4
backend/views/distribution/index.php View File

@@ -231,6 +231,7 @@ $this->setPageTitle('Distributions') ;
:producer="producer"
@close="showModalFormOrderCreate = false"
@ordercreatedupdated="orderCreatedUpdated"
@updateproductorderprices="updateProductOrderPrices"
></order-form>

<div id="wrapper-nav-points-sale">
@@ -397,6 +398,7 @@ $this->setPageTitle('Distributions') ;
:producer="producer"
@close="showModalFormOrderUpdate = false"
@ordercreatedupdated="orderCreatedUpdated"
@updateproductorderprices="updateProductOrderPrices"
></order-form>

<modal v-if="showModalPayment && idOrderPayment == order.id" class="modal-payment" @close="showModalPayment = false">
@@ -547,9 +549,9 @@ $this->setPageTitle('Distributions') ;
<label class="control-label" for="select-id-user">
Utilisateur
</label>
<select class="form-control" v-model="order.id_user">
<select class="form-control" v-model="order.id_user" @change="userChange">
<option value="0">--</option>
<option v-for="user in users" :value="user.id_user" @click="userChange">
<option v-for="user in users" :value="user.id_user">
<template v-if="user.name_legal_person && user.name_legal_person.length">
Personne morale / {{ user.name_legal_person }}
</template>
@@ -562,9 +564,9 @@ $this->setPageTitle('Distributions') ;
</div>
<div class="form-group">
<label class="control-label" for="select-id-point-sale">Point de vente</label>
<select class="form-control" id="select-id-point-sale" v-model="order.id_point_sale">
<select class="form-control" id="select-id-point-sale" v-model="order.id_point_sale" @change="pointSaleChange">
<option value="0">--</option>
<option v-for="pointSale in pointsSale" v-if="pointSale.pointSaleDistribution[0].delivery == 1" :value="pointSale.id">{{ pointSale.name }}</option>
<option v-for="pointSale in pointsSale" v-if="pointSale.pointSaleDistribution[0].delivery == 1" :value="pointSale.id"">{{ pointSale.name }}</option>
</select>
</div>
<div class="form-group">

+ 4
- 0
backend/views/point-sale/_form.php View File

@@ -40,6 +40,7 @@ use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use common\models\Producer;
use common\models\ProductPrice ;

/* @var $this yii\web\View */
/* @var $model backend\models\PointVente */
@@ -92,6 +93,9 @@ use common\models\Producer;
Producer::CREDIT_FUNCTIONING_USER => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_USER],
], [])->hint(Producer::HINT_CREDIT_FUNCTIONING); ?>

<?= $form->field($model, 'product_price_percent')
->dropDownList(ProductPrice::percentValues(), [])->hint('Pourcentage appliqué aux prix de chaque produit dans ce point de vente.'); ?>


<div id="delivery-days">
<h2>Jours de livraison</h2>

+ 89
- 128
backend/views/product/_form.php View File

@@ -1,41 +1,5 @@
<?php

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use common\models\Product;
@@ -44,9 +8,6 @@ use common\models\TaxRate;
use common\models\Producer;
use common\helpers\GlobalParam;

/* @var $this yii\web\View */
/* @var $model app\models\Produit */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="product-form">
@@ -56,42 +17,42 @@ use common\helpers\GlobalParam;
'options' => ['enctype' => 'multipart/form-data']
]); ?>

<div>
<div class="col-md-8">
<?= $form->field($model, 'active')->radioList([1 => 'Oui', 0 => 'Non']) ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'description')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'recipe')->textarea()->label('Description longue') ?>
<div>
<div class="col-md-8">
<?= $form->field($model, 'active')->radioList([1 => 'Oui', 0 => 'Non']) ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'description')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'recipe')->textarea()->label('Description longue') ?>

<?= $form->field($model, 'unit')
->dropDownList(ArrayHelper::map(Product::$unitsArray, 'unit', 'wording'))
->label('Unité (pièce, poids ou volume)'); ?>
<?= $form->field($model, 'unit')
->dropDownList(ArrayHelper::map(Product::$unitsArray, 'unit', 'wording'))
->label('Unité (pièce, poids ou volume)'); ?>


<?php
<?php

//Récupère la tva par défaut du producteur courant
$producer = \common\helpers\GlobalParam::getCurrentProducer();
$taxRateDefault = $producer->taxRate;
//Récupère la tva par défaut du producteur courant
$producer = \common\helpers\GlobalParam::getCurrentProducer();
$taxRateDefault = $producer->taxRate;

$taxRateNamesArray = array_merge(array(0 => 'Tva par défaut'), ArrayHelper::map(TaxRate::find()->all(), 'id', function ($model) {
return $model->name;
}));
$taxRateValuesArray = array_merge(array(0 => $taxRateDefault->value), ArrayHelper::map(TaxRate::find()->all(), 'id', function ($model) {
return $model->value;
}));
foreach ($taxRateValuesArray as $key => $taxRateValue) {
$taxRateValuesArrayFormatted[$key] = array('data-tax-rate-value' => $taxRateValue);
}
$taxRateNamesArray = array_merge(array(0 => 'Tva par défaut'), ArrayHelper::map(TaxRate::find()->all(), 'id', function ($model) {
return $model->name;
}));
$taxRateValuesArray = array_merge(array(0 => $taxRateDefault->value), ArrayHelper::map(TaxRate::find()->all(), 'id', function ($model) {
return $model->value;
}));
foreach ($taxRateValuesArray as $key => $taxRateValue) {
$taxRateValuesArrayFormatted[$key] = array('data-tax-rate-value' => $taxRateValue);
}

?>
?>

<?php if($taxRateDefault->value != 0): ?>
<?= $form->field($model, 'id_tax_rate')->dropDownList($taxRateNamesArray, ['options' => $taxRateValuesArrayFormatted])->label('Taxe'); ?>
<?php endif; ?>
<?php if($taxRateDefault->value != 0): ?>
<?= $form->field($model, 'id_tax_rate')->dropDownList($taxRateNamesArray, ['options' => $taxRateValuesArrayFormatted])->label('Taxe'); ?>
<?php endif; ?>

<?= $form->field($model, 'price', [
'template' => '
<?= $form->field($model, 'price', [
'template' => '
<div class="row">
<div class="col-xs-6">
<label for="product-price" class="control-label without-tax"></label>
@@ -109,76 +70,76 @@ use common\helpers\GlobalParam;
</div>
',
]) ?>
<?= $form->field($model, 'step')->textInput()->hint('Définit ce qui est ajouté ou enlevé lors des changements de quantité.') ?>
]) ?>
<?= $form->field($model, 'step')->textInput()->hint('Définit ce qui est ajouté ou enlevé lors des changements de quantité.') ?>

<?= $form->field($model, 'weight')->textInput()->label('Poids (g)') ?>
<?= $form->field($model, 'weight')->textInput()->label('Poids (g)') ?>

<div class="col-md-3">
<?= $form->field($model, 'quantity_max')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_monday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_tuesday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_wednesday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_thursday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_friday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_saturday')->textInput() ?>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_monday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_tuesday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_wednesday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_thursday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_friday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_saturday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_sunday')->textInput() ?>
</div>
<div class="clr"></div>

<?php
if (!$model->isNewRecord) {
echo $form->field($model, 'apply_distributions')
->checkbox()
->hint('Sélectionnez cette option si vous souhaitez que ces modifications (actif / non actif, quantité max) soient répercutées dans les distributions à venir déjà initialisées.');
}
?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_sunday')->textInput() ?>
<div class="col-md-4">
<?= $form->field($model, 'photo')->fileInput() ?>
<?php
if (strlen($model->photo)) {
$url = Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->photo;
$url = str_replace('//uploads','/uploads', $url) ;
echo '<img class="photo-product" src="' . $url . '" width="200px" /><br />';
echo '<input type="checkbox" name="delete_photo" id="delete_photo" /> <label for="delete_photo">Supprimer la photo</label><br /><br />';
}
?>

<div id="days-production">
<h2>Jours de distribution</h2>
<?= $form->field($model, 'monday')->checkbox() ?>
<?= $form->field($model, 'tuesday')->checkbox() ?>
<?= $form->field($model, 'wednesday')->checkbox() ?>
<?= $form->field($model, 'thursday')->checkbox() ?>
<?= $form->field($model, 'friday')->checkbox() ?>
<?= $form->field($model, 'saturday')->checkbox() ?>
<?= $form->field($model, 'sunday')->checkbox() ?>
</div>
<div class="clr"></div>
</div>
<div class="clr"></div>

<?php
if (!$model->isNewRecord) {
echo $form->field($model, 'apply_distributions')
->checkbox()
->hint('Sélectionnez cette option si vous souhaitez que ces modifications (actif / non actif, quantité max) soient répercutées dans les distributions à venir déjà initialisées.');
}
?>
</div>
<div class="col-md-4">
<?= $form->field($model, 'photo')->fileInput() ?>
<?php
if (strlen($model->photo)) {
$url = Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->photo;
$url = str_replace('//uploads','/uploads', $url) ;
echo '<img class="photo-product" src="' . $url . '" width="200px" /><br />';
echo '<input type="checkbox" name="delete_photo" id="delete_photo" /> <label for="delete_photo">Supprimer la photo</label><br /><br />';
}
?>

<div id="days-production">
<h2>Jours de distribution</h2>
<?= $form->field($model, 'monday')->checkbox() ?>
<?= $form->field($model, 'tuesday')->checkbox() ?>
<?= $form->field($model, 'wednesday')->checkbox() ?>
<?= $form->field($model, 'thursday')->checkbox() ?>
<?= $form->field($model, 'friday')->checkbox() ?>
<?= $form->field($model, 'saturday')->checkbox() ?>
<?= $form->field($model, 'sunday')->checkbox() ?>
</div>
<div class="clr"></div>
</div>
<div class="clr"></div>
</div>

<?= $form->field($model, 'id_producer')->hiddenInput()->label('') ?>

<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>


+ 14
- 0
backend/views/product/update/_nav.php View File

@@ -0,0 +1,14 @@
<div id="nav-params">
<?= $this->render('_nav_item', [
'title' => 'Général',
'action' => 'update',
'currentAction' => $action,
'model' => $model,
]); ?>
<?= $this->render('_nav_item', [
'title' => 'Prix spécifiques',
'action' => 'prices-list',
'currentAction' => $action,
'model' => $model,
]); ?>
</div>

+ 4
- 0
backend/views/product/update/_nav_item.php View File

@@ -0,0 +1,4 @@
<a href="<?= Yii::$app->urlManager->createUrl(['product/'.$action, 'id' => $model->id]) ?>" class="btn <?php if($action == $currentAction): ?>btn-primary<?php else: ?>btn-default<?php endif; ?>">
<?= $title ?>
<span class="glyphicon glyphicon-triangle-bottom"></span>
</a>

+ 3
- 0
backend/views/product/update/prices/_base_price.php View File

@@ -0,0 +1,3 @@
<div class="alert alert-warning">
Prix de base : <strong><?= Price::format($model->getPrice()); ?> HT</strong> / <strong><?= Price::format($model->getPriceWithTax()); ?> TTC</strong><br />
</div>

+ 66
- 0
backend/views/product/update/prices/_form.php View File

@@ -0,0 +1,66 @@
<?php

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use common\models\Product;
use yii\helpers\ArrayHelper;
use common\models\TaxRate;
use common\models\Producer;
use common\helpers\GlobalParam;
use common\models\User ;


?>

<div class="product-form">

<?=

$this->render('_base_price', [
'model' => $modelProduct,
]) ;

?>

<?php $form = ActiveForm::begin([
'enableClientValidation' => false,
'options' => ['enctype' => 'multipart/form-data']
]); ?>

<?= $form->field($model, 'id_user')->dropDownList(User::populateDropdownList()); ?>
<?= $form->field($model, 'id_point_sale')->dropDownList(PointSale::populateDropdownList()) ?>

<?php
$producer = GlobalParam::getCurrentProducer();
$taxRateValue = $producer->taxRate->value;
if($modelProduct->taxRate) {
$taxRateValue = $modelProduct->taxRate->value ;
}
?>
<?= $form->field($model, 'price', [
'template' => '
<div class="row">
<div class="col-xs-6">
<label for="product-price" class="control-label without-tax">Prix ('.Product::strUnit($modelProduct->unit, 'wording_unit').') HT</label>
<div class="input-group">
{input} <span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span>
</div>
</div>
<div class="col-xs-6">
<label for="productprice-price-with-tax" class="control-label with-tax">Prix ('.Product::strUnit($modelProduct->unit, 'wording_unit').') TTC</label>
<div class="input-group">
<input type="text" id="productprice-price-with-tax" class="form-control" name="" value="" data-tax-rate-value="'.$taxRateValue.'">
<span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span>
</div>
</div>
</div>',
]) ?>

<div class="form-group">
<?= Html::a('Annuler', ['prices-list', 'id' => $model->id_product], ['class' => 'btn btn-default']) ?>
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>

</div>

backend/views/product/update.php → backend/views/product/update/prices/create.php View File

@@ -1,17 +1,17 @@
<?php

/**
Copyright distrib (2018)
/**
Copyright distrib (2018)

contact@opendistrib.net

Ce logiciel est un programme informatique servant à aider les producteurs
à distribuer leur production en circuits courts.
Ce logiciel est un programme informatique servant à aider les producteurs
à distribuer leur production en circuits courts.

Ce logiciel est régi par la licence CeCILL soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info".

En contrepartie de l'accessibilité au code source et des droits de copie,
@@ -22,32 +22,40 @@ titulaire des droits patrimoniaux et les concédants successifs.

A cet égard l'attention de l'utilisateur est attirée sur les risques
associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.

Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes.
*/
*/

use yii\helpers\Html;


$this->setTitle('Modifier un produit') ;
$this->setTitle('Ajouter un prix ('.Html::encode($model->product->name).')') ;
$this->addBreadcrumb(['label' => 'Produits', 'url' => ['index']]) ;
$this->addBreadcrumb(['label' => $model->name, 'url' => ['update', 'id' => $model->id]]) ;
$this->addBreadcrumb('Modifier') ;
$this->addBreadcrumb(['label' => $model->product->name, 'url' => ['update', 'id' => $model->product->id]]);
$this->addBreadcrumb(['label' => 'Prix', 'url' => ['prices-list', 'id' => $model->product->id]]) ;
$this->addBreadcrumb('Ajouter un prix') ;

?>

<?=
$this->render('../_nav', [
'model' => $modelProduct,
'action' => 'prices-list',
]) ;
?>

<div class="product-update">
<?= $this->render('_form', [
'model' => $model,
]) ?>
<div class="product-prices-create">
<?= $this->render('_form', [
'model' => $model,
'modelProduct' => $modelProduct
]) ?>
</div>

+ 227
- 0
backend/views/product/update/prices/list.php View File

@@ -0,0 +1,227 @@
<?php

use common\helpers\Price ;

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

$this->setTitle('Liste des prix ('.Html::encode($model->name).')');
$this->addBreadcrumb(['label' => 'Produits', 'url' => ['index']]);
$this->addBreadcrumb(['label' => $model->name, 'url' => ['update', 'id' => $model->id]]);
$this->addBreadcrumb('Modifier');
//$this->addButton(['label' => 'Nouveau prix <span class="glyphicon glyphicon-plus"></span>', 'url' => ['product/prices-create', 'idProduct' => $model->id ], 'class' => 'btn btn-primary']);

?>

<?=
$this->render('../_nav', [
'model' => $model,
'action' => $action,
]) ;
?>

<div class="col-md-8">

<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
Prix spécifiques à ce produit
<a href="<?= Yii::$app->urlManager->createUrl(['product/prices-create', 'idProduct' => $model->id ]) ?>" class="btn btn-default btn-xs">
Nouveau prix
<span class="glyphicon glyphicon-plus"></span>
</a>
</h3>
</div>
<div class="panel-body">
<?php

echo GridView::widget([
//'filterModel' => $searchModel,
'dataProvider' => $dataProvider,
'columns' => [
[
'attribute' => 'id_point_sale',
'format' => 'raw',
'value' => function ($model) {
if($model->pointSale) {
return $model->pointSale->name ;
}
return '<span class="label label-success">Tous</span>' ;
}
],
[
'attribute' => 'id_user',
'format' => 'raw',
'value' => function ($model) {
if($model->user) {
return $model->user->getUsername() ;
}
return '<span class="label label-success">Tous</span>' ;
}
],
[
'attribute' => 'price',
'value' => function ($productPrice) {
return Price::numberTwoDecimals($productPrice->price).' €' ;
}
],
[
'attribute' => 'price',
'header' => 'Prix (TTC)',
'value' => function ($productPrice) use ($model) {
return Price::numberTwoDecimals(Price::getPriceWithTax($productPrice->price, $model->taxRate->value)).' €' ;
}
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'update' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', ['product/prices-update', 'id' => $model->id], [
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default'
]);
},
'delete' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-trash"></span>', ['product/prices-delete', 'id' => $model->id], [
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default'
]);
}
],
],
],
]);

?>
</div>
</div>

<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Pourcentage global / Utilisateurs</h3>
</div>
<div class="panel-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Utilisateur</th>
<th>Pourcentage</th>
<th>Prix (HT)</th>
<th>Prix (TTC)</th>
</tr>
</thead>
<tbody>
<?php if($userProducerWithProductPercent && count($userProducerWithProductPercent) > 0): ?>
<?php foreach($userProducerWithProductPercent as $userProducer): ?>
<?php if($userProducer->user): ?>
<tr>
<td><?= $userProducer->user->getUsername() ?></td>
<td><?= $userProducer->product_price_percent ?> %</td>
<td><?= Price::format($model->getPrice(['user_producer' => $userProducer])) ?></td>
<td><?= Price::format($model->getPriceWithTax(['user_producer' => $userProducer])) ?></td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
<?php else: ?>
<tr><td colspan="4">Aucun résultat</td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>

<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Pourcentage global / Points de vente</h3>
</div>
<div class="panel-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Point de vente</th>
<th>Pourcentage</th>
<th>Prix (HT)</th>
<th>Prix (TTC)</th>
</tr>
</thead>
<tbody>
<?php if($pointSaleWithProductPercent && count($pointSaleWithProductPercent) > 0): ?>
<?php foreach($pointSaleWithProductPercent as $pointSale): ?>
<tr>
<td><?= Html::encode($pointSale->name) ?></td>
<td><?= $pointSale->product_price_percent ?> %</td>
<td><?= Price::format($model->getPrice(['point_sale' => $pointSale])) ?></td>
<td><?= Price::format($model->getPriceWithTax(['point_sale' => $pointSale])) ?></td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr><td colspan="4">Aucun résultat</td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>

<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Prix de base</h3>
</div>
<div class="panel-body">
<p>Prix de base : <strong><?= Price::format($model->getPrice()); ?> HT</strong> / <strong><?= Price::format($model->getPriceWithTax()); ?> TTC</strong><br /></p>
</div>
</div>
</div>

<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Priorités de résolution</h3>
</div>
<div class="panel-body">
<p>Le prix d'un produit se déduit dans un ordre précis de résolution, le voici : </p>
<ul>
<li>Les prix spécifiques définis au niveau du produit</li>
<li>Les pourcentages globaux définis au niveau des utilisateurs et points de vente</li>
<li>Le prix de base défini au niveau du produit</li>
</ul>
<p>À chaque étape de résolution, on vérifie si le contexte courant (utilisateur / point de vente) correspond à un prix.
Si c'est le cas, on l'utilise, sinon on passe à l'étape suivante jusqu'à arriver au prix de base
défini dans "Général".
</p>
</div>
</div>
</div>

+ 61
- 0
backend/views/product/update/prices/update.php View File

@@ -0,0 +1,61 @@
<?php

/**
Copyright distrib (2018)

contact@opendistrib.net

Ce logiciel est un programme informatique servant à aider les producteurs
à distribuer leur production en circuits courts.

Ce logiciel est régi par la licence CeCILL soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info".

En contrepartie de l'accessibilité au code source et des droits de copie,
de modification et de redistribution accordés par cette licence, il n'est
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
seule une responsabilité restreinte pèse sur l'auteur du programme, le
titulaire des droits patrimoniaux et les concédants successifs.

A cet égard l'attention de l'utilisateur est attirée sur les risques
associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.

Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes.
*/

use yii\helpers\Html;

$this->setTitle('Modifier un prix ('.Html::encode($model->product->name).')') ;
$this->addBreadcrumb(['label' => 'Produits', 'url' => ['index']]) ;
$this->addBreadcrumb(['label' => $model->product->name, 'url' => ['update', 'id' => $model->product->id]]);
$this->addBreadcrumb(['label' => 'Prix', 'url' => ['prices-list', 'id' => $model->product->id]]) ;
$this->addBreadcrumb('Modifier un prix') ;

?>

<?=
$this->render('../_nav', [
'model' => $modelProduct,
'action' => 'prices-list',
]) ;
?>

<div class="product-prices-update">
<?= $this->render('_form', [
'model' => $model,
'modelProduct' => $modelProduct
]) ?>
</div>

+ 62
- 0
backend/views/product/update/update.php View File

@@ -0,0 +1,62 @@
<?php

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/



/* @var $this yii\web\View */
/* @var $model app\models\Produit */
/* @var $form yii\widgets\ActiveForm */

$this->setTitle('Modifier un produit ('.Html::encode($model->name).')');
$this->addBreadcrumb(['label' => 'Produits', 'url' => ['index']]);
$this->addBreadcrumb(['label' => $model->name, 'url' => ['update', 'id' => $model->id]]);
$this->addBreadcrumb('Modifier');

?>

<?= $this->render('_nav', [
'model' => $model,
'action' => $action,
])
?>

<div class="product-update">
<?= $this->render('../_form', [
'model' => $model,
]) ?>
</div>

+ 4
- 0
backend/views/user/_form.php View File

@@ -38,6 +38,7 @@

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use common\models\ProductPrice ;

\backend\assets\VuejsUserFormAsset::register($this);

@@ -76,6 +77,9 @@ use yii\widgets\ActiveForm;
]);
?>

<?= $form->field($model, 'product_price_percent')
->dropDownList(ProductPrice::percentValues(), [])->hint('Pourcentage appliqué aux prix de chaque produit pour cet utilisateur.'); ?>

<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>

+ 203
- 198
backend/web/css/screen.css
File diff suppressed because it is too large
View File


+ 43
- 8
backend/web/js/backend.js View File

@@ -42,6 +42,7 @@ $(document).ready(function() {
opendistrib_tooltip() ;
opendistrib_ordre_produits() ;
opendistrib_products() ;
opendistrib_product_prices() ;
opendistrib_confirm_delete() ;
}) ;

@@ -87,18 +88,22 @@ function opendistrib_products_event_price_with_tax() {
if(typeof taxRateSelected == 'undefined') {
taxRateSelected = 0 ;
}
if($('#product-price').val()) {
$('#product-price-with-tax').val(getPriceWithTax($('#product-price').val(), taxRateSelected));
//formattage des prix
$('#product-price').val(parseFloat($('#product-price').val()).toFixed(3));

var price = $('#product-price').val() ;
if(price) {
$('#product-price-with-tax').val(getPriceWithTax(price, taxRateSelected));
// formattage
$('#product-price').val(parseFloat(price).toFixed(3));
}
}
function opendistrib_products_event_price(){
taxRateSelected = $('#product-id_tax_rate').find('option:selected').data('tax-rate-value');
$('#product-price').val(getPrice($('#product-price-with-tax').val(), taxRateSelected));

//formattage des prix
$('#product-price-with-tax').val(parseFloat($('#product-price-with-tax').val()).toFixed(2));
var priceWithTax = $('#product-price-with-tax').val() ;
if(priceWithTax) {
$('#product-price').val(getPrice(priceWithTax, taxRateSelected));
// formattage
$('#product-price-with-tax').val(parseFloat(priceWithTax).toFixed(2));
}
}


@@ -107,10 +112,12 @@ function opendistrib_products_event_unit(change) {
if(unit == 'piece') {
$('.field-product-step').hide() ;
$('.field-product-weight label').html('Poids (g)') ;
$('.field-product-weight').show() ;
}
else {
$('.field-product-step').show() ;
$('.field-product-weight label').html('Poids ('+$('#product-unit').val()+')') ;
$('.field-product-weight').hide() ;
}
var label_price_ttc = $('.field-product-price .control-label.with-tax') ;
@@ -147,6 +154,34 @@ function opendistrib_products_event_unit(change) {
}

function opendistrib_product_prices() {
if($('.product-prices-create').size() || $('.product-prices-update').size()) {
opendistrib_product_prices_event_price_with_tax() ;
$('#productprice-price').change(opendistrib_product_prices_event_price_with_tax);
$('#productprice-price-with-tax').change(opendistrib_product_prices_event_price);
}
}

function opendistrib_product_prices_event_price_with_tax() {
var taxRateValue = $('#productprice-price-with-tax').data('tax-rate-value');
var price = $('#productprice-price').val() ;
if(price) {
$('#productprice-price-with-tax').val(getPriceWithTax(price, taxRateValue));
// formattage
$('#productprice-price').val(parseFloat(price).toFixed(3));
}
}

function opendistrib_product_prices_event_price() {
var taxRateValue = $('#productprice-price-with-tax').data('tax-rate-value');
var priceWithTax = $('#productprice-price-with-tax').val() ;
if(priceWithTax) {
$('#productprice-price').val(getPrice(priceWithTax, taxRateValue));
// formattage
$('#productprice-price-with-tax').val(parseFloat(priceWithTax).toFixed(2));
}
}

function opendistrib_tooltip() {
$('[data-toggle="tooltip"]').tooltip({container:'body'});
}

+ 51
- 0
backend/web/js/vuejs/distribution-index.js View File

@@ -368,6 +368,7 @@ var app = new Vue({
openModalFormOrderCreate: function() {
this.showModalFormOrderCreate = true ;
this.initModalFormOrder() ;
this.updateProductOrderPrices() ;
},
initModalFormOrder: function() {
setTimeout(function() {
@@ -564,6 +565,49 @@ var app = new Vue({
appAlerts.alertResponse(response) ;
app.init(app.idActivePointSale) ;
}) ;
},

updateProductOrderPrices: function() {
var app = this ;
var order = null ;

if(app.showModalFormOrderCreate) {
order = app.orderCreate ;
}

if(app.showModalFormOrderUpdate && app.idOrderUpdate) {
for (keyOrderUpdate in app.ordersUpdate) {
if (app.ordersUpdate[keyOrderUpdate].id == app.idOrderUpdate) {
order = app.ordersUpdate[keyOrderUpdate] ;
}
}
}

if(order) {
axios.get(UrlManager.getBaseUrlAbsolute() + "distribution/ajax-update-product-order", {
params: {
idUser: order.id_user,
idPointSale: order.id_point_sale
}
})
.then(function (response) {
if (response.data) {
for (idProduct in response.data) {
if (app.showModalFormOrderCreate) {
Vue.set(app.orderCreate.productOrder[idProduct], 'price', response.data[idProduct].price);
}

if (app.showModalFormOrderUpdate && app.idOrderUpdate) {
for (keyOrderUpdate in app.ordersUpdate) {
if (order.id == app.idOrderUpdate) {
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'price', response.data[idProduct].price);
}
}
}
}
}
});
}
}
},
});
@@ -703,7 +747,14 @@ Vue.component('order-form',{
}})
.then(function(response) {
app.order.id_point_sale = response.data.id_favorite_point_sale ;
app.updateProductOrderPrices() ;
}) ;
},
pointSaleChange: function(event) {
this.updateProductOrderPrices() ;
},
updateProductOrderPrices: function() {
this.$emit('updateproductorderprices') ;
}
}
}) ;

+ 0
- 8
backend/web/sass/producer/_update.scss View File

@@ -1,12 +1,4 @@

.producer-update {
#nav-params {
margin-bottom: 30px ;
button {
margin-right: 10px ;
}
}
}

+ 18
- 0
backend/web/sass/screen.scss View File

@@ -314,6 +314,24 @@ a.btn, button.btn {
}
}

#nav-params {
margin-bottom: 30px ;

button {
margin-right: 10px ;
}
}

.panel {
.panel-heading {
.panel-title {
.btn {
float: right ;
}
}
}
}

/* modals */

.modal-mask {

+ 16
- 2
common/models/PointSale.php View File

@@ -90,7 +90,8 @@ class PointSale extends ActiveRecordCommon
['point_production', 'default', 'value' => 0],
[['id_producer', 'id_user'], 'integer'],
['id_producer', 'required'],
[['users', 'users_comment', 'code'], 'safe']
[['users', 'users_comment', 'code'], 'safe'],
[['product_price_percent'], 'double'],
];
}

@@ -124,7 +125,8 @@ class PointSale extends ActiveRecordCommon
'code' => 'Code',
'credit_functioning' => 'Utilisation du Crédit par l\'utilisateur',
'default' => 'Point de vente par défaut',
'id_user' => 'Contact'
'id_user' => 'Contact',
'product_price_percent' => 'Prix produits : pourcentage'
];
}

@@ -381,4 +383,16 @@ class PointSale extends ActiveRecordCommon
}
}
}

public static function populateDropdownList()
{
$pointSalesArrayDropdown = ['' => '--'] ;
$pointSalesArray = PointSale::find()->where('id_producer = ' . GlobalParam::getCurrentProducerId())->all() ;

foreach($pointSalesArray as $pointSale) {
$pointSalesArrayDropdown[$pointSale['id']] = $pointSale['name'] ;
}

return $pointSalesArrayDropdown ;
}
}

+ 64
- 6
common/models/Product.php View File

@@ -179,11 +179,10 @@ class Product extends ActiveRecordCommon
if($producer) {
$this->populateRelation('taxRate', $producer->taxRate);
}
//$this->populateRelation('taxRate', GlobalParam::getCurrentProducer()->taxRate);
}

$this->wording_unit = Product::strUnit($this->unit) ;
$this->price_with_tax = $this->getpriceWithTax() ;
$this->price_with_tax = $this->getPriceWithTax() ;

parent::afterFind();
}
@@ -200,10 +199,14 @@ class Product extends ActiveRecordCommon

public function getTaxRate()
{

return $this->hasOne(TaxRate::className(), ['id' => 'id_tax_rate']);
}

public function getProductPrice()
{
return $this->hasMany(ProductPrice::className(), ['id_product' => 'id']);
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
@@ -331,18 +334,73 @@ class Product extends ActiveRecordCommon
return $strUnit;
}

public function getPrice()
public function getPrice($params = [])
{
$specificPrices = $this->productPrice ;

$user = isset($params['user']) ? $params['user'] : false ;
$userProducer = isset($params['user_producer']) ? $params['user_producer'] : false ;
$pointSale = isset($params['point_sale']) ? $params['point_sale'] : false ;

if($specificPrices && ($user || $pointSale)) {

$specificPricesArray = [
'user' => false,
'pointsale' => false,
'user_pointsale' => false,
] ;

foreach($specificPrices as $specificPrice) {
if($user
&& $specificPrice->id_user && !$specificPrice->id_point_sale
&& $specificPrice->id_user == $user->id) {

$specificPricesArray['user'] = $specificPrice->price ;
}
if($pointSale
&& $specificPrice->id_point_sale && !$specificPrice->id_user
&& $specificPrice->id_point_sale == $pointSale->id) {

$specificPricesArray['pointsale'] = $specificPrice->price ;
}

if($pointSale && $user
&& $specificPrice->id_point_sale && $specificPrice->id_user
&& $specificPrice->id_point_sale == $pointSale->id && $specificPrice->id_user == $user->id) {

$specificPricesArray['user_pointsale'] = $specificPrice->price ;
}
}

if($specificPricesArray['user_pointsale']) {
return $specificPricesArray['user_pointsale'] ;
}
elseif($specificPricesArray['user']) {
return $specificPricesArray['user'] ;
}
elseif($specificPricesArray['pointsale']) {
return $specificPricesArray['pointsale'] ;
}
}

if($userProducer && $userProducer->product_price_percent) {
return $this->price * (1 + $userProducer->product_price_percent / 100) ;
}

if($pointSale && $pointSale->product_price_percent) {
return $this->price * (1 + $pointSale->product_price_percent / 100) ;
}

return $this->price ;
}

/**
* Retourne le prix du produit avec taxe
*/
public function getPriceWithTax()
public function getPriceWithTax($params = [])
{
$taxRateValue = $this->taxRate ? $this->taxRate->value : 0 ;
return Price::getPriceWithTax($this->price, $taxRateValue);
return Price::getPriceWithTax($this->getPrice($params), $taxRateValue);
}

public function getTheTaxRate()

+ 153
- 0
common/models/ProductPrice.php View File

@@ -0,0 +1,153 @@
<?php

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

namespace common\models;

use common\helpers\GlobalParam;
use Yii;
use yii\helpers\Html;
use common\models\UserPointSale;
use common\models\PointSaleDistribution;
use common\components\ActiveRecordCommon;

/**
* This is the model class for table "product_price".
*
* @property integer $id
*/
class ProductPrice extends ActiveRecordCommon
{

/**
* @inheritdoc
*/
public static function tableName()
{
return 'product_price';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
['id_user', 'required', 'when' => function($model) {
return !$model->id_point_sale ;
}, 'message' => 'Vous devez renseigner un utilisateur et/ou un point de vente'],
['id_point_sale', 'required', 'when' => function($model) {
return !$model->id_user ;
}, 'message' => 'Vous devez renseigner un utilisateur et/ou un point de vente'],
[['id_product', 'price'], 'required'],
[['id_product', 'id_user', 'id_point_sale', 'percent'], 'integer'],
[['price'], 'double'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_product' => 'Produit',
'id_user' => 'Utilisateur',
'id_point_sale' => 'Point de vente',
'price' => 'Prix (HT)',
'percent' => 'Pourcentage',
];
}

/*
* Relations
*/

public function getProduct()
{
return $this->hasOne(
Product::className(),
['id' => 'id_product']
);
}

public function getPointSale()
{
return $this->hasOne(
PointSale::className(),
['id' => 'id_point_sale']
);
}

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

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => ['user', 'pointSale'],
'join_with' => ['product'],
'orderby' => '',
'attribute_id_producer' => 'product.id_producer'
];
}

public static function percentValues()
{
$percentValues = [
'' => 'Aucun'
] ;

for($i = -50 ; $i < 51 ; $i = $i + 5) {
$percentValues[$i] = $i.' %' ;
}

return $percentValues ;
}

}

+ 94
- 0
common/models/ProductPriceSearch.php View File

@@ -0,0 +1,94 @@
<?php

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

namespace common\models;

use common\helpers\GlobalParam;
use Yii;
use yii\helpers\Html;
use common\models\UserPointSale;
use common\models\PointSaleDistribution;
use common\components\ActiveRecordCommon;

/**
* This is the model class for table "product_price".
*
* @property integer $id
*/
class ProductPriceSearch extends ProductPrice
{

public function rules()
{
return [
[['id_user', 'id_point_sale'], 'string'],
[['price'], 'double'],
];
}

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

$query = ProductPrice::find()
->with($optionsSearch['with'])
->innerJoinWith($optionsSearch['join_with'], true)
->where(['product.id_producer' => GlobalParam::getCurrentProducerId()])
->orderBy('product_price.price ASC')
;

$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort' => false,
'pagination' => [
'pageSize' => 1000,
],
]);

$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}

//$query->andFilterWhere(['like', 'user.name', $this->id_user]) ;
//$query->andFilterWhere(['like', 'point_sale.name', $this->id_point_sale]) ;

return $dataProvider;
}

}

+ 4
- 1
common/models/Subscription.php View File

@@ -247,7 +247,10 @@ class Subscription extends ActiveRecordCommon
$productOrder->id_order = $order->id;
$productOrder->id_product = $productSubscription->product->id;
$productOrder->quantity = $productSubscription->quantity;
$productOrder->price = $productSubscription->product->price;
$productOrder->price = $productSubscription->product->getPrice([
'id_user' => $this->id_user,
'id_point_sale' => $this->id_point_sale
]);
$productOrder->unit = $productSubscription->product->unit;
$productOrder->step = $productSubscription->product->step;
$productOrder->id_tax_rate = $productSubscription->product->taxRate->id;

+ 39
- 3
common/models/User.php View File

@@ -76,6 +76,7 @@ class User extends ActiveRecordCommon implements IdentityInterface
var $password_new_confirm;
var $points_sale = [];
var $one_name ;
var $product_price_percent ;

/**
* @inheritdoc
@@ -111,7 +112,7 @@ class User extends ActiveRecordCommon implements IdentityInterface
['password_old', 'verifyPasswordOld'],
['password_new', 'verifyPasswordNew'],
['password_new_confirm', 'verifyPasswordNewConfirm'],
[['date_last_connection', 'password_old', 'password_new', 'password_new_confirm', 'password_hash', 'points_sale'], 'safe'],
[['date_last_connection', 'password_old', 'password_new', 'password_new_confirm', 'password_hash', 'points_sale', 'product_price_percent'], 'safe'],
];
}

@@ -140,7 +141,8 @@ class User extends ActiveRecordCommon implements IdentityInterface
'points_sale' => 'Points de vente',
'type' => 'Type',
'name_legal_person' => 'Libellé',
'is_main_contact' => 'Contact principal'
'is_main_contact' => 'Contact principal',
'product_price_percent' => 'Prix produits : pourcentage'
];
}

@@ -693,11 +695,15 @@ class User extends ActiveRecordCommon implements IdentityInterface
return $address;
}

public function getUsername()
public function getUsername($withType = false)
{
$username = '' ;
if(isset($this->name_legal_person) && strlen($this->name_legal_person)) {
$username = $this->name_legal_person ;

if($withType) {
$username = 'Personne morale / '.$username ;
}
}
else {
$username = $this->lastname.' '.$this->name ;
@@ -706,6 +712,36 @@ class User extends ActiveRecordCommon implements IdentityInterface
return $username ;
}

public static function getUsernameFromArray($modelArray, $withType = false)
{
$username = '' ;
if(isset($modelArray['name_legal_person']) && strlen($modelArray['name_legal_person'])) {
$username = $modelArray['name_legal_person'] ;

if($withType) {
$username = 'Personne morale / '.$username ;
}
}
else {
$username = $modelArray['lastname'].' '.$modelArray['name'] ;
}

return $username ;
}

public static function populateDropdownList()
{
$usersArray = User::findBy()->all() ;
$usersArrayDropdown = ['' => '--'] ;

foreach($usersArray as $user) {
$usersArrayDropdown[$user['user_id']] = User::getUsernameFromArray($user, true) ;
}

return $usersArrayDropdown ;;
}


/**
* Retourne l'ID de l'utilisateur courant connecté.
*

+ 95
- 88
common/models/UserProducer.php View File

@@ -1,45 +1,45 @@
<?php

/**
Copyright distrib (2018)
contact@opendistrib.net
Ce logiciel est un programme informatique servant à aider les producteurs
à distribuer leur production en circuits courts.
Ce logiciel est régi par la licence CeCILL soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info".
En contrepartie de l'accessibilité au code source et des droits de copie,
de modification et de redistribution accordés par cette licence, il n'est
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
seule une responsabilité restreinte pèse sur l'auteur du programme, le
titulaire des droits patrimoniaux et les concédants successifs.
A cet égard l'attention de l'utilisateur est attirée sur les risques
associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes.
*/
/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

namespace common\models;

use Yii;
use common\components\ActiveRecordCommon ;
use common\components\ActiveRecordCommon;

/**
* This is the model class for table "user_etablissement".
@@ -49,61 +49,68 @@ use common\components\ActiveRecordCommon ;
* @property boolean $actif
* @property boolean $favoris
*/
class UserProducer extends ActiveRecordCommon
class UserProducer extends ActiveRecordCommon
{

/**
* @inheritdoc
*/
public static function tableName()
{
return 'user_producer';
}
/**
* @inheritdoc
*/
public static function tableName()
{
return 'user_producer';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_user', 'id_producer'], 'required'],
[['id_user', 'id_producer', 'product_price_percent'], 'integer'],
[['active', 'bookmark', 'credit_active'], 'boolean'],
[['credit', 'product_price_percent'], 'double'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id_user' => 'Utilisateur',
'id_producer' => 'Producteur',
'active' => 'Actif',
'bookmark' => 'Favoris',
'credit_active' => 'Crédit',
'product_price_percent' => 'Prix produits : pourcentage'
];
}

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

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_user', 'id_producer'], 'required'],
[['id_user', 'id_producer'], 'integer'],
[['active','bookmark','credit_active'], 'boolean'],
[['credit'], 'double'],
];
}
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'id_user']);
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id_user' => 'Utilisateur',
'id_producer' => 'Producteur',
'active' => 'Actif',
'bookmark' => 'Favoris',
'credit_active' => 'Crédit'
];
}
public function getProducer()
{
return $this->hasOne(Producer::className(), ['id' => 'id_producer']);
}
/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch() {
return [
'with' => [],
'join_with' => [],
'orderby' => '',
'attribute_id_producer' => 'user_producer.id_producer'
] ;
}
/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => [],
'join_with' => [],
'orderby' => '',
'attribute_id_producer' => 'user_producer.id_producer'
];
}

}

+ 30
- 0
console/migrations/m201207_160043_specific_prices.php View File

@@ -0,0 +1,30 @@
<?php

use yii\db\Migration;
use yii\db\Schema;

class m201207_160043_specific_prices extends Migration
{
public function safeUp()
{
$this->createTable('product_price', [
'id' => 'pk',
'id_product' => Schema::TYPE_INTEGER . ' NOT NULL',
'id_user' => Schema::TYPE_INTEGER,
'id_point_sale' => Schema::TYPE_INTEGER,
'price' => Schema::TYPE_FLOAT,
]);

$this->addColumn('user_producer', 'product_price_percent', Schema::TYPE_INTEGER) ;
$this->addColumn('point_sale', 'product_price_percent', Schema::TYPE_INTEGER) ;
}

public function safeDown()
{
$this->dropTable('product_price') ;
$this->dropColumn('user_producer', 'product_price_percent') ;
$this->dropColumn('point_sale', 'product_price_percent') ;

return false;
}
}

+ 34
- 0
console/migrations/m201207_164410_specific_prices_percent.php View File

@@ -0,0 +1,34 @@
<?php

use yii\db\Migration;
use yii\db\Schema;

class m201207_164410_specific_prices_percent extends Migration
{
public function safeUp()
{
$this->addColumn('product_price', 'percent', Schema::TYPE_INTEGER) ;
}

public function safeDown()
{
$this->dropColumn('product_price', 'percent') ;

return false;
}

/*
// Use up()/down() to run migration code without a transaction.
public function up()
{

}

public function down()
{
echo "m201207_164410_specific_prices_percent cannot be reverted.\n";

return false;
}
*/
}

+ 10
- 14
producer/controllers/OrderController.php View File

@@ -514,7 +514,7 @@ class OrderController extends ProducerBaseController
return 0;
}

public function actionAjaxInfos($date = '')
public function actionAjaxInfos($date = '', $pointSaleId = 0)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

@@ -523,6 +523,9 @@ class OrderController extends ProducerBaseController
$format = 'Y-m-d';
$dateObject = DateTime::createFromFormat($format, $date);

// PointSale current
$pointSaleCurrent = PointSale::findOne($pointSaleId) ;

// Producteur
$producer = Producer::searchOne([
'id' => $this->getProducer()->id
@@ -656,16 +659,6 @@ class OrderController extends ProducerBaseController
]);

// Produits
/*if (Producer::getConfig('option_allow_user_gift')) {
$productsArray = Product::find()
->orWhere(['id_producer' => $this->getProducer()->id,])
//->orWhere(['id_producer' => 0,]) // produit "Don";
;
} else {
$productsArray = Product::find()
->where(['id_producer' => $this->getProducer()->id,]);
}*/

$productsArray = Product::find()
->where([
'id_producer' => $this->getProducer()->id,
@@ -674,7 +667,7 @@ class OrderController extends ProducerBaseController

$productsArray = $productsArray->joinWith(['productDistribution' => function ($query) use ($distribution) {
$query->andOnCondition('product_distribution.id_distribution = ' . $distribution->id);
}])
}, 'productPrice'])
->orderBy('product_distribution.active DESC, order ASC')
->all();

@@ -684,12 +677,15 @@ class OrderController extends ProducerBaseController
$product = array_merge(
$product->getAttributes(),
[
'price_with_tax' => $product->getPriceWithTax(),
'price_with_tax' => $product->getPriceWithTax([
'user' => User::getCurrent(),
'user_producer' => $userProducer,
'point_sale' => $pointSaleCurrent
]),
'productDistribution' => $product['productDistribution']
]
);


$coefficient_unit = Product::$unitsArray[$product['unit']]['coefficient'];

if (is_null($product['photo'])) {

+ 18
- 1
producer/controllers/SubscriptionController.php View File

@@ -219,11 +219,24 @@ class SubscriptionController extends ProducerBaseController
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$params = [];

$user = User::getCurrent() ;
$userProducer = UserProducer::searchOne([
'id_user' => User::getCurrentId()
]) ;
$pointSale = false ;

if ($idSubscription > 0) {
$arrayProductsSubscription = ProductSubscription::searchAll([
'id_subscription' => $idSubscription
]);

$subscription = Subscription::findOne($idSubscription) ;

if($subscription) {
if($subscription->id_point_sale) {
$pointSale = PointSale::findOne($subscription->id_point_sale) ;
}
}
}

// Produits
@@ -250,7 +263,11 @@ class SubscriptionController extends ProducerBaseController
'coefficient_unit' => $coefficientUnit,
'wording_unit' => Product::strUnit($product->unit, 'wording_unit', true),
'wording_short' => Product::strUnit($product->unit, 'wording_short'),
'price_with_tax' => $product->getPriceWithTax(),
'price_with_tax' => $product->getPriceWithTax([
'user' => $user,
'user_producer' => $userProducer,
'point_sale' => $pointSale
]),
]
);
}

+ 4
- 1
producer/web/js/vuejs/order-order.js View File

@@ -107,7 +107,10 @@ var app = new Vue({
init: function() {
var app = this ;
this.loading = true ;
axios.get("ajax-infos",{params: {date : this.getDate()}})
axios.get("ajax-infos",{params: {
date : this.getDate(),
pointSaleId: this.pointSaleActive ? this.pointSaleActive.id : 0
}})
.then(function(response) {
app.producer = response.data.producer ;
app.user = response.data.user ;

Loading…
Cancel
Save