Преглед на файлове

Merge branch 'dev'

master
Guillaume Bourgeois преди 5 години
родител
ревизия
6846785779
променени са 26 файла, в които са добавени 373 реда и са изтрити 108 реда
  1. +2
    -3
      backend/controllers/CronController.php
  2. +53
    -3
      backend/controllers/DistributionController.php
  3. +0
    -5
      backend/controllers/OrderController.php
  4. +24
    -1
      backend/controllers/UserController.php
  5. +5
    -4
      backend/views/distribution/index.php
  6. +4
    -3
      backend/views/point-sale/_form.php
  7. +19
    -5
      backend/views/producer/update.php
  8. +42
    -19
      backend/views/user/credit.php
  9. +9
    -3
      backend/views/user/index.php
  10. +5
    -0
      backend/web/css/screen.css
  11. +14
    -1
      backend/web/js/vuejs/distribution-index.js
  12. +1
    -0
      backend/web/sass/screen.scss
  13. +10
    -0
      backend/web/sass/user/_credit.scss
  14. +2
    -1
      common/models/CreditHistory.php
  15. +10
    -0
      common/models/PointSale.php
  16. +16
    -3
      common/models/Producer.php
  17. +2
    -0
      common/models/User.php
  18. +2
    -1
      common/models/UserProducer.php
  19. +17
    -0
      console/migrations/m190222_090304_ajout_champs_options_credit.php
  20. +15
    -0
      console/migrations/m190225_093245_ajout_champs_gestion_credit_utilisateur.php
  21. +52
    -22
      producer/controllers/OrderController.php
  22. +0
    -3
      producer/views/order/history.php
  23. +40
    -16
      producer/views/order/order.php
  24. +7
    -7
      producer/web/css/screen.css
  25. +18
    -6
      producer/web/js/vuejs/order-order.js
  26. +4
    -2
      producer/web/sass/order/_order.scss

+ 2
- 3
backend/controllers/CronController.php Целия файл

@@ -295,10 +295,10 @@ class CronController extends BackendController
$subject = '[distrib] Commandes du ' . date('d/m', strtotime($date));

// génération du pdf de commande
Yii::$app->runAction('order/report-cron', [
Yii::$app->runAction('distribution/report-cron', [
'date' => $date,
'save' => true,
'id_producer' => $producer['id'],
'idProducer' => $producer['id'],
'key' => '64ac0bdab7e9f5e48c4d991ec5201d57'
]);
$mail->attach(Yii::getAlias('@app/web/pdf/Orders-' . $date . '-' . $producer['id'] . '.pdf'));
@@ -313,5 +313,4 @@ class CronController extends BackendController
}
}
}

}

+ 53
- 3
backend/controllers/DistributionController.php Целия файл

@@ -50,6 +50,31 @@ use DateTime;

class DistributionController extends BackendController
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['report-cron'],
'allow' => true,
'roles' => ['?']
],
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return User::getCurrentStatus() == USER::STATUS_ADMIN
|| User::getCurrentStatus() == USER::STATUS_PRODUCER;
}
]
],
],
];
}
public function actionIndex($date = '')
{
$format = 'Y-m-d' ;
@@ -173,6 +198,15 @@ class DistributionController extends BackendController
$arrayCreditUser['credit'] = $order->user->userProducer[0]->credit ;
}
$oneProductUnactivated = false ;
foreach($order->productOrder as $productOrder) {
foreach($productsArray as $product) {
if($productOrder->id_product == $product['id'] && !$product['productDistribution'][0]['active']) {
$oneProductUnactivated = true ;
}
}
}
$order = array_merge($order->getAttributes(), [
'amount' => $order->getAmount(Order::AMOUNT_TOTAL),
'amount_paid' => $order->getAmount(Order::AMOUNT_PAID),
@@ -181,10 +215,9 @@ class DistributionController extends BackendController
'user' => (isset($order->user)) ? array_merge($order->user->getAttributes(), $arrayCreditUser) : null,
'pointSale' => ['id' => $order->pointSale->id, 'name' => $order->pointSale->name],
'productOrder' => $productOrderArray,
'creditHistory' => $creditHistoryArray
'creditHistory' => $creditHistoryArray,
'oneProductUnactivated' => $oneProductUnactivated
]) ;
}
}
@@ -265,6 +298,23 @@ class DistributionController extends BackendController
return $json ;
}
/**
* Génére un PDF récapitulatif des des commandes d'un producteur pour une
* date donnée (Méthode appelable via CRON)
*
* @param string $date
* @param boolean $save
* @param integer $idProducer
* @param string $key
* @return PDF|null
*/
public function actionReportCron($date = '', $save = false, $idProducer = 0, $key = '')
{
if($key == '64ac0bdab7e9f5e48c4d991ec5201d57') {
$this->actionReport($date, $save, $idProducer) ;
}
}
/**
* Génére un PDF récapitulatif des commandes d'un producteur pour une
* date donnée.

+ 0
- 5
backend/controllers/OrderController.php Целия файл

@@ -55,11 +55,6 @@ class OrderController extends BackendController
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['report-cron'],
'allow' => true,
'roles' => ['?']
],
[
'allow' => true,
'roles' => ['@'],

+ 24
- 1
backend/controllers/UserController.php Целия файл

@@ -42,6 +42,7 @@ use common\models\User ;
use common\models\Producer ;
use common\models\Distribution ;
use backend\models\MailForm ;
use common\models\UserProducer ;

/**
* UserController implements the CRUD actions for User model.
@@ -300,12 +301,13 @@ class UserController extends BackendController

return $this->render('credit', [
'user' => $user,
'userProducer' => $userProducer,
'creditForm' => $creditForm,
'history' => $history
]);
}
else {
throw new UserException("Vous ne pouvez pas créditer un utilisateur qui n'est pas associé à votre boulangerie.");
throw new UserException("Vous ne pouvez pas créditer un utilisateur qui n'est pas associé à votre établissement.");
}
}

@@ -328,6 +330,27 @@ class UserController extends BackendController
'user' => $user
]);
}
/**
* Modifie l'option "credit_active" d'un utilisateur pour le producteur courant.
* Redirige vers la page de crédit de l'utilisateur.
*
* @param integer $idUser
* @param boolean $state
*/
public function actionStateCredit($idUser, $state)
{
$userProducer = UserProducer::searchOne([
'id_user' => $idUser
]) ;
if($userProducer) {
$userProducer->credit_active = $state ;
$userProducer->save() ;
}
return $this->redirect(['user/credit','id' => $idUser]) ;
}

/**
* Finds the User model based on its primary key value.

+ 5
- 4
backend/views/distribution/index.php Целия файл

@@ -264,7 +264,7 @@ $this->setPageTitle('Distributions') ;
</div>
</td>
<td class="column-payment">
<div class="btn-group" v-if="order.user">
<div class="btn-group" v-if="order.user && !order.date_delete">
<button class="btn btn-xs btn-default" v-if="order.amount_paid == order.amount" @click="orderPaymentClick" :data-id-order="order.id" data-type="refund" :data-amount="order.amount">
<span class="glyphicon glyphicon-euro"></span> Rembourser
</button>
@@ -288,6 +288,7 @@ $this->setPageTitle('Distributions') ;
</div>
</td>
<td class="column-actions">
<span v-if="order.oneProductUnactivated" class="glyphicon glyphicon-warning-sign" title="Contient un produit non activé"></span>
<button class="btn btn-default" :data-id-order="order.id" @click="orderViewClick"><span :class="'glyphicon ' + ((showViewProduct && idOrderView == order.id) ? 'glyphicon-eye-close' : 'glyphicon-eye-open')"></span></button>
<button class="btn btn-default" :data-id-order="order.id" @click="updateOrderClick"><span class="glyphicon glyphicon-pencil"></span></button>
<button class="btn btn-default" :data-id-order="order.id" @click="deleteOrderClick"><span class="glyphicon glyphicon-trash"></span></button>
@@ -301,7 +302,7 @@ $this->setPageTitle('Distributions') ;
:points-sale="pointsSale"
:users="users"
:products="products"
:order="order"
:order="order.clone"
@close="showModalFormOrderUpdate = false"
@ordercreatedupdated="orderCreatedUpdated"
></order-form>
@@ -408,7 +409,7 @@ $this->setPageTitle('Distributions') ;
<strong><span class="glyphicon glyphicon-menu-right"></span> Produits</strong>
<ul>
<li v-for="product in products" v-if="order.productOrder[product.id] > 0">
{{ order.productOrder[product.id] }} x {{ product.name }}
{{ order.productOrder[product.id] }} x {{ product.name }} <span v-if="product.productDistribution[0].active == 0" class="glyphicon glyphicon-warning-sign" title="Ce produit n'est pas activé"></span>
</li>
</ul>
<div v-if="order.comment && order.comment.length > 0" class="comment">
@@ -448,7 +449,7 @@ $this->setPageTitle('Distributions') ;
<div class="form-group">
<label class="control-label" for="select-id-user">Utilisateur</label>
<select class="form-control" v-model="order.id_user">
<option v-for="user in users" :value="user.id_user">{{ user.name +' '+ user.lastname }}</option>
<option v-for="user in users" :value="user.id_user">{{ user.lastname +' '+ user.name }}</option>
</select>
<input v-model="order.username" type="text" class="form-control" placeholder="Ou saisissez ici le nom de l'utilisateur" />
</div>

+ 4
- 3
backend/views/point-sale/_form.php Целия файл

@@ -71,9 +71,10 @@ use common\models\Producer ;
<?= $form->field($model, 'credit_functioning')
->dropDownList([
'' => 'Paramètres globaux ('.Producer::$creditFunctioningArray[Producer::getConfig('credit_functioning')].')',
Producer::CREDIT_FUNCTIONING_OPTIONAL => 'Optionnelle',
Producer::CREDIT_FUNCTIONING_MANDATORY => 'Obligatoire',
], []) ; ?>
Producer::CREDIT_FUNCTIONING_OPTIONAL => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_OPTIONAL],
Producer::CREDIT_FUNCTIONING_MANDATORY => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_MANDATORY],
Producer::CREDIT_FUNCTIONING_USER => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_USER],
], [])->hint(Producer::HINT_CREDIT_FUNCTIONING) ; ?>

<div id="delivery-days">

+ 19
- 5
backend/views/producer/update.php Целия файл

@@ -173,16 +173,30 @@ $this->addBreadcrumb($this->getTitle()) ;
. 'Ils créditent leur compte en vous donnant la somme de leur choix et c\'est ensuite à vous de '.Html::a('mettre à jour', ['user/index']).' leur Crédit en ligne.<br />'
. 'Ceci fait, les clients paient leur commande directement via leur Crédit.') ; ?>

<?= $form->field($model, 'credit_functioning')
->dropDownList([
Producer::CREDIT_FUNCTIONING_OPTIONAL => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_OPTIONAL],
Producer::CREDIT_FUNCTIONING_MANDATORY => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_MANDATORY],
Producer::CREDIT_FUNCTIONING_USER => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_USER],
], [])->hint(Producer::HINT_CREDIT_FUNCTIONING) ; ?>
<?= $form->field($model, 'use_credit_checked_default')
->dropDownList([
0 => 'Non',
1 => 'Oui',
], [])->hint('Utilisation optionnelle du Crédit.') ; ?>
<?= $form->field($model, 'credit_limit_reminder',[
'template' => '{label}<div class="input-group">{input}<span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span></div>{hint}',
])
->hint("Une relance est envoyé au client dès que ce seuil est dépassé.") ; ?>
<?= $form->field($model, 'credit_functioning')
->dropDownList([
Producer::CREDIT_FUNCTIONING_OPTIONAL => 'Optionnelle',
Producer::CREDIT_FUNCTIONING_MANDATORY => 'Obligatoire',
], []) ; ?>
<?= $form->field($model, 'credit_limit',[
'template' => '{label}<div class="input-group">{input}<span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span></div>{hint}',
])->hint('Limite de crédit que l\'utilisateur ne pourra pas dépasser. Laisser vide pour permettre un crédit négatif et infini.'); ?>
</div>
</div>

+ 42
- 19
backend/views/user/credit.php Целия файл

@@ -62,29 +62,52 @@ $this->addBreadcrumb('Créditer') ;
}
?>
<div class="col-md-12">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($creditForm, 'type')->dropDownList([
CreditHistory::TYPE_CREDIT => 'Crédit',
CreditHistory::TYPE_DEBIT => 'Débit',
]) ?>
<?= $form->field($creditForm, 'amount')->textInput() ?>
<?= $form->field($creditForm, 'mean_payment')->dropDownList([
CreditHistory::MEAN_PAYMENT_MONEY => CreditHistory::getStrMeanPaymentBy(CreditHistory::MEAN_PAYMENT_MONEY),
CreditHistory::MEAN_PAYMENT_CREDIT_CARD => CreditHistory::getStrMeanPaymentBy(CreditHistory::MEAN_PAYMENT_CREDIT_CARD),
CreditHistory::MEAN_PAYMENT_CHEQUE => CreditHistory::getStrMeanPaymentBy(CreditHistory::MEAN_PAYMENT_CHEQUE),
CreditHistory::MEAN_PAYMENT_OTHER => CreditHistory::getStrMeanPaymentBy(CreditHistory::MEAN_PAYMENT_OTHER),
]) ?>
<?= $form->field($creditForm, 'comment')->textarea() ?>
<?= $form->field($creditForm, 'send_mail')->checkbox() ?>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
Crédit obligatoire
<?= Html::a($userProducer->credit_active ? 'Désactiver' : 'Activer', ['user/state-credit', 'idUser' => $user->id,'state' => !$userProducer->credit_active], ['class' => 'btn btn-default btn-xs']); ?>
</h3>
</div>
<div class="panel-body">
<?php if($userProducer->credit_active): ?>
<div class="alert alert-success">Activé</div>
<?php else: ?>
<div class="alert alert-danger">Désactivé</div>
<?php endif; ?>
</div>
</div>
<div class="form-group">
<?= Html::submitButton( 'Créditer', ['class' => 'btn btn-primary']) ?>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Crédit / débit</h3>
</div>
<div class="panel-body">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($creditForm, 'type')->dropDownList([
CreditHistory::TYPE_CREDIT => 'Crédit',
CreditHistory::TYPE_DEBIT => 'Débit',
]) ?>
<?= $form->field($creditForm, 'amount')->textInput() ?>
<?= $form->field($creditForm, 'mean_payment')->dropDownList([
CreditHistory::MEAN_PAYMENT_MONEY => CreditHistory::getStrMeanPaymentBy(CreditHistory::MEAN_PAYMENT_MONEY),
CreditHistory::MEAN_PAYMENT_CREDIT_CARD => CreditHistory::getStrMeanPaymentBy(CreditHistory::MEAN_PAYMENT_CREDIT_CARD),
CreditHistory::MEAN_PAYMENT_CHEQUE => CreditHistory::getStrMeanPaymentBy(CreditHistory::MEAN_PAYMENT_CHEQUE),
CreditHistory::MEAN_PAYMENT_OTHER => CreditHistory::getStrMeanPaymentBy(CreditHistory::MEAN_PAYMENT_OTHER),
]) ?>
<?= $form->field($creditForm, 'comment')->textarea() ?>
<?= $form->field($creditForm, 'send_mail')->checkbox() ?>

<div class="form-group">
<?= Html::submitButton( 'Créditer', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
<div class="col-md-12">
<div class="col-md-8">
<h2>Historique <span class="the-credit"><?= number_format($user->getCredit($producer->id), 2); ?> €</span></h2>
<table class="table table-bordered">
<thead>

+ 9
- 3
backend/views/user/index.php Целия файл

@@ -117,16 +117,22 @@ $this->render('_menu',[
'attribute' => 'credit',
'format' => 'raw',
'value' => function($model) use($producer) {
$user = User::findOne($model->id) ;
$userProducer = UserProducer::searchOne([
'id_user' => $model->id
]) ;
$credit = $userProducer ? $userProducer->credit : 0 ;
$classBtnCredit = $userProducer->credit_active ? 'btn-success' : 'btn-default' ;
$html = '<div class="input-group">
<input type="text" class="form-control input-credit" readonly="readonly" value="'.number_format($user->getCredit($producer->id),2).' €" placeholder="">
<input type="text" class="form-control input-credit" readonly="readonly" value="'.number_format($credit,2).' €" placeholder="">
<span class="input-group-btn">
'.Html::a(
'<span class="glyphicon glyphicon-euro"></span>',
Yii::$app->urlManager->createUrl(['user/credit','id' => $model->id]),
[
'title' => 'Crédit',
'class' => 'btn btn-default'
'class' => 'btn '.$classBtnCredit
]
).'
</span>

+ 5
- 0
backend/web/css/screen.css Целия файл

@@ -1962,6 +1962,11 @@ termes.
margin-bottom: 20px;
}

/* line 5, ../sass/user/_credit.scss */
.user-credit .panel .panel-heading .btn {
float: right;
}

/* line 4, ../sass/producer/_update.scss */
.producer-update #nav-params {
margin-bottom: 30px;

+ 14
- 1
backend/web/js/vuejs/distribution-index.js Целия файл

@@ -123,6 +123,9 @@ var app = new Vue({
app.orders = response.data.orders ;
for(i=0 ; i < app.orders.length ; i++) {
app.orders[i].clone = app.cloneOrder(app.orders[i]) ;
if(!app.orders[i].date_delete) {
app.countOrders ++ ;
}
@@ -346,6 +349,16 @@ var app = new Vue({
closeModalProducts: function() {
this.showModalProducts = false ;
this.init(this.idActivePointSale) ;
},
cloneOrder: function(order) {
var clone = Object.assign({}, order) ;
clone.productOrder = {} ;
for(var key in order.productOrder) {
clone.productOrder[key] = order.productOrder[key] ;
}
return clone ;
}
},
});
@@ -437,7 +450,7 @@ Vue.component('order-form',{
idUser: this.order.id_user,
username: ''+this.order.username,
products: JSON.stringify(this.order.productOrder),
comment: this.comment,
comment: this.order.comment,
processCredit: processCredit
}})
.then(function(response) {

+ 1
- 0
backend/web/sass/screen.scss Целия файл

@@ -1333,5 +1333,6 @@ a.btn, button.btn {
@import "stats/_products.scss" ;
@import "distribution/_index.scss" ;
@import "user/_emails.scss" ;
@import "user/_credit.scss" ;
@import "producer/_update.scss" ;
@import "point_sale/_index.scss" ;

+ 10
- 0
backend/web/sass/user/_credit.scss Целия файл

@@ -0,0 +1,10 @@

.user-credit {
.panel {
.panel-heading {
.btn {
float: right ;
}
}
}
}

+ 2
- 1
common/models/CreditHistory.php Целия файл

@@ -198,7 +198,8 @@ class CreditHistory extends ActiveRecordCommon
}
$newCredit = $userProducer->credit ;
if($oldCredit > $creditLimitReminder && $newCredit <= $creditLimitReminder) {
if(!is_null($creditLimitReminder) &&
$oldCredit > $creditLimitReminder && $newCredit <= $creditLimitReminder) {
$user = User::findOne($this->id_user) ;
$producer = Producer::findOne($this->id_producer) ;
Yii::$app->mailer->compose(

+ 10
- 0
common/models/PointSale.php Целия файл

@@ -333,4 +333,14 @@ class PointSale extends ActiveRecordCommon
}
return $str ;
}
/**
* Retourne le mode de fonctionnement du crédit du point de vente.
*
* @return string
*/
public function getCreditFunctioning()
{
return $this->credit_functioning ? $this->credit_functioning : Producer::getConfig('credit_functioning') ;
}
}

+ 16
- 3
common/models/Producer.php Целия файл

@@ -60,15 +60,26 @@ use yii\helpers\Html;
* @property string gcs
* @property boolean option_allow_user_gift
* @property string credit_functioning
* @property boolean use_credit_checked_default
* @property float credit_limit
*
*/
class Producer extends ActiveRecordCommon
{
const CREDIT_FUNCTIONING_MANDATORY = 'mandatory' ;
const CREDIT_FUNCTIONING_OPTIONAL = 'optional' ;
const CREDIT_FUNCTIONING_USER = 'user' ;
const HINT_CREDIT_FUNCTIONING = '<ul>'
. '<li>Optionnelle : l\'utilisateur choisit s\'il utilise son Crédit ou non. Les commandes peuvent être payées ou impayées.</li>'
. '<li>Obligatoire : toutes les commandes de l\'utilisateur son comptabilisées au niveau du Crédit. Toutes les commandes sont payées.</li>'
. '<li>Basée sur l\'utilisateur : Crédit obligatoire si l\'utilisateur a le crédit activé au niveau de son compte, système de Crédit non affiché sinon.</li>'
. '</ul>' ;
public static $creditFunctioningArray = [
self::CREDIT_FUNCTIONING_MANDATORY => 'Obligatoire',
self::CREDIT_FUNCTIONING_OPTIONAL => 'Optionnelle',
self::CREDIT_FUNCTIONING_USER => 'Basée sur l\'utilisateur',
];
var $secret_key_payplug ;
@@ -99,9 +110,9 @@ class Producer extends ActiveRecordCommon
}
}],
[['description','mentions','gcs','order_infos','slug','secret_key_payplug'], 'string'],
[['negative_balance', 'credit', 'active','online_payment','user_manage_subscription', 'option_allow_user_gift'], 'boolean'],
[['negative_balance', 'credit', 'active','online_payment','user_manage_subscription', 'option_allow_user_gift','use_credit_checked_default'], 'boolean'],
[['name', 'siret', 'logo', 'photo', 'postcode', 'city', 'code','type','credit_functioning'], 'string', 'max' => 255],
[['free_price', 'credit_limit_reminder'], 'double'],
[['free_price', 'credit_limit_reminder','credit_limit'], 'double'],
['free_price', 'compare', 'compareValue' => 0, 'operator' => '>=', 'type' => 'number', 'message' => 'Prix libre doit être supérieur ou égal à 0'],
];
}
@@ -137,7 +148,9 @@ class Producer extends ActiveRecordCommon
'mentions' => 'Mentions légales',
'gcs' => 'Conditions générales de vente',
'option_allow_user_gift' => 'Autoriser les utilisateurs à effectuer un don à la plateforme lors de leur commande',
'credit_functioning' => 'Utilisation du Crédit par l\'utilisateur'
'credit_functioning' => 'Utilisation du Crédit par l\'utilisateur',
'credit_limit' => 'Crédit limite',
'use_credit_checked_default' => 'Cocher par défaut l\'option "Utiliser mon crédit" lors de la commande de l\'utilisateur'
];
}


+ 2
- 0
common/models/User.php Целия файл

@@ -337,6 +337,8 @@ class User extends ActiveRecordCommon implements IdentityInterface
$query->andFilterWhere(['like', 'phone', $params['phone']]);
}
$query->orderBy('user.lastname ASC, user.name ASC') ;
return $query;
}


+ 2
- 1
common/models/UserProducer.php Целия файл

@@ -68,7 +68,7 @@ class UserProducer extends ActiveRecordCommon
return [
[['id_user', 'id_producer'], 'required'],
[['id_user', 'id_producer'], 'integer'],
[['active','bookmark'], 'boolean'],
[['active','bookmark','credit_active'], 'boolean'],
[['credit'], 'double'],
];
}
@@ -83,6 +83,7 @@ class UserProducer extends ActiveRecordCommon
'id_producer' => 'Producteur',
'active' => 'Actif',
'bookmark' => 'Favoris',
'credit_active' => 'Crédit'
];
}

+ 17
- 0
console/migrations/m190222_090304_ajout_champs_options_credit.php Целия файл

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

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

class m190222_090304_ajout_champs_options_credit extends Migration {

public function up() {
$this->addColumn('producer', 'credit_limit', Schema::TYPE_FLOAT) ;
$this->addColumn('producer', 'use_credit_checked_default', Schema::TYPE_BOOLEAN.' DEFAULT 1') ;
}

public function down() {
$this->dropColumn('producer', 'credit_limit') ;
$this->dropColumn('producer', 'use_credit_checked_default') ;
}
}

+ 15
- 0
console/migrations/m190225_093245_ajout_champs_gestion_credit_utilisateur.php Целия файл

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

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

class m190225_093245_ajout_champs_gestion_credit_utilisateur extends Migration {

public function up() {
$this->addColumn('user_producer', 'credit_active', Schema::TYPE_BOOLEAN.' DEFAULT 0') ;
}

public function down() {
$this->dropColumn('user_producer', 'credit_active') ;
}
}

+ 52
- 22
producer/controllers/OrderController.php Целия файл

@@ -42,6 +42,7 @@ use common\models\ProductDistribution ;
use common\models\User ;
use common\models\Producer ;
use common\models\Order ;
use common\models\UserPointSale ;
use DateTime;

class OrderController extends ProducerBaseController
@@ -216,8 +217,8 @@ class OrderController extends ProducerBaseController
{
$posts = Yii::$app->request->post();
$productsArray = [];

$totalQuantity = 0;
$producer = $this->getProducer() ;

foreach ($posts['products'] as $key => $quantity) {
$product = Product::find()->where(['id' => (int) $key])->one();
@@ -227,7 +228,6 @@ class OrderController extends ProducerBaseController
}
}
$producer = $this->getProducer() ;

// date
$errorDate = false;
@@ -263,18 +263,31 @@ class OrderController extends ProducerBaseController
} else {
$errorPointSale = true;
}
$userPointSale = UserPointSale::searchOne([
'id_user' => User::getCurrentId(),
'id_point_sale' => $pointSale->id
]) ;
if($pointSale->restricted_access && !$userPointSale) {
$errorPointSale = true;
}
}

$errors = [] ;
if ($order->validate() && count($productsArray) && !$errorDate && !$errorPointSale) {

$userProducer = UserProducer::searchOne([
'id_producer' => $order->distribution->id_producer,
'id_user' => User::getCurrentId()
]) ;
// gestion point de vente
$pointSale = PointSale::searchOne([
'id' => $order->id_point_sale
]) ;
$order->comment_point_sale = ($pointSale && strlen($pointSale->getComment())) ?
$pointSale->getComment() : '' ;
@@ -318,17 +331,28 @@ class OrderController extends ProducerBaseController

// credit
$credit = Producer::getConfig('credit');
$creditLimit = Producer::getConfig('credit_limit');
$creditFunctioning = $pointSale->getCreditFunctioning() ;
$creditUser = Yii::$app->user->identity->getCredit($distribution->id_producer);
$order = Order::searchOne([
'id' => $order->id
]) ;
if($credit && $pointSale->credit && ($posts['use_credit'] || $pointSale->credit_functioning == Producer::CREDIT_FUNCTIONING_MANDATORY)) {
$amountPaid = $order->getAmount(Order::AMOUNT_PAID);
$amountPaid = $order->getAmount(Order::AMOUNT_PAID);
$amountRemaining = $order->getAmount(Order::AMOUNT_REMAINING) ;
if($credit && $pointSale->credit &&
( $posts['use_credit'] ||
$pointSale->credit_functioning == Producer::CREDIT_FUNCTIONING_MANDATORY ||
($pointSale->credit_functioning == Producer::CREDIT_FUNCTIONING_USER && $userProducer->credit_active)
)) {

// à payer
if ($order->getPaymentStatus() == Order::PAYMENT_UNPAID) {
$amountRemaining = $order->getAmount(Order::AMOUNT_REMAINING) ;
$credit = Yii::$app->user->identity->getCredit($distribution->id_producer);

if(!is_null($creditLimit) && $amountRemaining > $creditUser - $creditLimit) {
$amountRemaining = $creditUser - $creditLimit ;
}
if ($amountRemaining > 0) {
$order->saveCreditHistory(
CreditHistory::TYPE_PAYMENT,
@@ -352,17 +376,18 @@ class OrderController extends ProducerBaseController
}
}
}
else {
if (!count($productsArray)) {
$errors[] = "Vous n'avez choisi aucun produit" ;
}
if ($errorDate) {
$errors[] = "Vous ne pouvez pas commander pour cette date." ;
}
if ($errorPointSale) {
$errors[] = "Point de vente invalide." ;
}
if (!count($productsArray)) {
$errors[] = "Vous n'avez choisi aucun produit" ;
}
if ($errorDate) {
$errors[] = "Vous ne pouvez pas commander pour cette date." ;
}
if ($errorPointSale) {
$errors[] = "Point de vente invalide." ;
}
return $errors ;
}

@@ -445,6 +470,8 @@ class OrderController extends ProducerBaseController
'order_infos' => $producer->order_infos,
'credit' => $producer->credit,
'credit_functioning' => $producer->credit_functioning,
'use_credit_checked_default' => $producer->use_credit_checked_default,
'credit_limit' => is_numeric($producer->credit_limit) ? $producer->credit_limit : null
] ;
// Distributions
@@ -486,7 +513,10 @@ class OrderController extends ProducerBaseController
'id_user' => User::getCurrentId()
]) ;
$json['credit'] = $userProducer->credit ;
$json['user'] = [
'credit' => $userProducer->credit,
'credit_active' => $userProducer->credit_active,
] ;
if($dateObject && $dateObject->format($format) === $date) {
@@ -506,7 +536,7 @@ class OrderController extends ProducerBaseController
// distribution
$distribution = Distribution::initDistribution($date) ;
$json['distribution'] = $distribution ;
$pointsSaleArray = PointSale::find()
->joinWith(['pointSaleDistribution' => function($query) use ($distribution) {
$query->where(['id_distribution' => $distribution->id]);
@@ -515,9 +545,9 @@ class OrderController extends ProducerBaseController
->with(['userPointSale' => function($query) {
$query->onCondition(['id_user' => User::getCurrentId()]) ;
}])
->where([
'id_producer' => $distribution->id_producer,
])
->where(['id_producer' => $distribution->id_producer])
->andWhere('restricted_access = 0 OR (restricted_access = 1 AND (SELECT COUNT(*) FROM user_point_sale WHERE point_sale.id = user_point_sale.id_point_sale AND user_point_sale.id_user = :id_user) > 0)')
->params([':id_user' => User::getCurrentId()])
->all();

$creditFunctioningProducer = Producer::getConfig('credit_functioning') ;

+ 0
- 3
producer/views/order/history.php Целия файл

@@ -118,9 +118,6 @@ GridView::widget([
if($c->date_delete) {
$html .= '<span class="label label-danger">Annulée</span><br />' ;
if($c->getState() == Order::STATE_OPEN) {
$html .= '<a href="'.Yii::$app->urlManager->createUrl(['order/order','id'=>$c->id]).'" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span> Modifier</a>' ;
}
}
else {
if($c->getState() == Order::STATE_DELIVERED) {

+ 40
- 16
producer/views/order/order.php Целия файл

@@ -232,25 +232,49 @@ $this->setTitle('Commander') ;
<label for="order-comment">Commentaire</label>
<textarea id="order-comment" v-model="comment" class="form-control"></textarea>
</div>
<div class="credit">
<div v-if="producer.credit == 1 && pointSaleActive.credit == 1">
<input type="checkbox" id="use-credit" v-model="useCredit" disabled="disabled" v-if="pointSaleActive.credit_functioning == 'mandatory'" />
<input type="checkbox" id="use-credit" v-model="useCredit" v-else /> <label for="use-credit">Utiliser mon Crédit ({{ formatPrice(credit) }})</label>
<div class="info" v-if="useCredit">
<span v-if="order == null || order.amount_paid == 0">{{ priceTotal(true) }} seront débités</span>
<span v-else-if="order != null && order.amount_paid > 0 && order.amount_paid < priceTotal()">{{ formatPrice(priceTotal() - order.amount_paid) }} seront débités</span>
<span v-else-if="order != null && order.amount_paid > priceTotal()">{{ formatPrice(order.amount_paid - priceTotal()) }} seront remboursés</span>
<template v-if="!checkCreditLimit(order) && pointSaleActive.credit_functioning == 'mandatory'">
<div class="alert alert-danger">Vous devez recharger votre crédit ou supprimer des produits. Votre producteur n'autorise pas un crédit inférieur à <strong>{{ formatPrice(creditLimit) }}</strong>.</div>
<div class="block-actions">
<a class="btn btn-primary" href="<?= Yii::$app->urlManager->createUrl(['site/index']) ?>">Retour à l'accueil</a>
</div>
</template>
<template v-else>
<div class="credit">
<div v-if="producer.credit == 1 && pointSaleActive.credit == 1 && (pointSaleActive.credit_functioning != 'user' || (pointSaleActive.credit_functioning == 'user' && user.credit_active))">
<input type="checkbox" id="use-credit" v-model="useCredit" disabled="disabled" v-if="pointSaleActive.credit_functioning == 'mandatory' || (pointSaleActive.credit_functioning == 'user' && user.credit_active)" />
<input type="checkbox" id="use-credit" v-model="useCredit" v-else /> <label for="use-credit">Utiliser mon Crédit ({{ formatPrice(user.credit) }})</label>
<div class="info" v-if="useCredit">
<template v-if="order == null || order.amount_paid == 0">
<span v-if="checkCreditLimit(order)">{{ priceTotal(true) }} seront débités</span>
<span v-else>
{{ formatPrice(user.credit) }} seront débités. (Limite de crédit à {{ formatPrice(producer.credit_limit) }})<br />
Restera {{ formatPrice(priceTotal() - credit) }} à régler.
</span>
</template>
<template v-else-if="order != null && order.amount_paid > 0 && order.amount_paid < priceTotal()">
<span v-if="checkCreditLimit(order)">{{ formatPrice(priceTotal() - order.amount_paid) }} seront débités</span>
<span v-else>
{{ formatPrice(user.credit) }} seront débités. (Limite de crédit à {{ formatPrice(producer.credit_limit) }})<br />
Restera {{ formatPrice(priceTotal() - order.amount_paid - user.credit) }} à régler.
</span>
</template>
<template v-else-if="order != null && order.amount_paid > priceTotal()">
<span>{{ formatPrice(order.amount_paid - priceTotal()) }} seront remboursés</span>
</template>
</div>
</div>
<div v-else>
<span class="glyphicon glyphicon-chevron-right"></span> La commande sera à régler sur place.
</div>
</div>
<div v-else>
<span class="glyphicon glyphicon-chevron-right"></span> La commande sera à régler sur place.
<div class="block-actions">
<button class="btn btn-primary" disabled="disabled" v-if="disableConfirmButton">Je confirme ma commande</button>
<button class="btn btn-primary" v-else @click="confirmClick">Je confirme ma commande</button>
</div>
</div>
<div class="block-actions">
<button class="btn btn-primary" disabled="disabled" v-if="disableConfirmButton">Je confirme ma commande</button>
<button class="btn btn-primary" v-else @click="confirmClick">Je confirme ma commande</button>
</div>
</template>
</div>
</transition>
</div>

+ 7
- 7
producer/web/css/screen.css Целия файл

@@ -1457,20 +1457,20 @@ termes.
.order-order #app-order-order table#products tr.total .price-total {
font-size: 23px;
}
/* line 239, ../sass/order/_order.scss */
.order-order #app-order-order #content-step-payment .credit {
margin-top: 20px;
}
/* line 242, ../sass/order/_order.scss */
/* line 240, ../sass/order/_order.scss */
.order-order #app-order-order #content-step-payment .credit .info {
margin-left: 20px;
color: gray;
}
/* line 249, ../sass/order/_order.scss */
/* line 246, ../sass/order/_order.scss */
.order-order #app-order-order #content-step-payment .comment {
margin-bottom: 20px;
}
/* line 251, ../sass/order/_order.scss */
.order-order #app-order-order #infos {
margin-top: 30px;
}
/* line 251, ../sass/order/_order.scss */
/* line 253, ../sass/order/_order.scss */
.order-order #app-order-order #infos .panel-body {
padding-top: 0px;
white-space: pre-line;

+ 18
- 6
producer/web/js/vuejs/order-order.js Целия файл

@@ -6,6 +6,7 @@ var app = new Vue({
loadingInit: true,
step: 'date',
producer: null,
user: null,
date: null,
dateFormat: null,
distributions: [],
@@ -16,7 +17,6 @@ var app = new Vue({
products: [],
comment: '',
creditCheckbox: false,
credit: 0,
useCredit: false,
errors: [],
disableConfirmButton: false,
@@ -91,10 +91,10 @@ var app = new Vue({
},
formatPrice: function(price) {
var isNumberRegExp = new RegExp(/^[-+]?[0-9]+(\.[0-9]+)*$/);
if(isNumberRegExp.test(price) && price > 0) {
if(isNumberRegExp.test(price)) {
return Number(price).toFixed(2).replace('.',',')+' €' ;
}
return '--' ;
return '0 €' ;
},
getPointSale: function(idPointSale) {
for(var key in this.pointsSale) {
@@ -109,8 +109,8 @@ var app = new Vue({
axios.get("ajax-infos",{params: {date : this.getDate()}})
.then(function(response) {
app.producer = response.data.producer ;
app.credit = response.data.credit ;
app.user = response.data.user ;
app.useCredit = response.data.producer.use_credit_checked_default ;
app.calendar.attrs = [] ;
app.calendar.availableDates = [] ;
var distributions = response.data.distributions ;
@@ -248,7 +248,12 @@ var app = new Vue({

validatePointSale: function(idPointSale) {
this.pointSaleActive = this.getPointSale(idPointSale) ;
this.useCredit = true ;
if(this.pointSaleActive.credit_functioning == 'mandatory' || (this.pointSaleActive.credit_functioning == 'user' && this.user.credit_active)) {
this.useCredit = true ;
}
else {
this.useCredit = false ;
}
this.changeStep('products') ;
},
@@ -321,6 +326,13 @@ var app = new Vue({
if(!this.oneProductOrdered()) {
this.errors.push('Veuillez sélectionner au moins un produit.') ;
}
},
checkCreditLimit: function(order) {
var total = this.priceTotal() ;
if(order != null) {
total = this.priceTotal() - order.amount_paid ;
}
return this.producer.credit_limit == null || (this.producer.credit_limit != null && (this.user.credit - total >= this.producer.credit_limit)) ;
}
}
});

+ 4
- 2
producer/web/sass/order/_order.scss Целия файл

@@ -237,13 +237,15 @@
#content-step-payment {
.credit {
margin-top: 20px ;
.info {
margin-left: 20px ;
color: gray ;
}
}
.comment {
margin-bottom: 20px ;
}
}
#infos {

Loading…
Отказ
Запис