Browse Source

Merge branch 'feature/fonctionnement_credit_base_sur_utilisateur' into dev

dev
Guillaume Bourgeois 5 years ago
parent
commit
519da23e21
14 changed files with 166 additions and 53 deletions
  1. +24
    -1
      backend/controllers/UserController.php
  2. +4
    -3
      backend/views/point-sale/_form.php
  3. +14
    -10
      backend/views/producer/update.php
  4. +42
    -19
      backend/views/user/credit.php
  5. +9
    -3
      backend/views/user/index.php
  6. +5
    -0
      backend/web/css/screen.css
  7. +1
    -0
      backend/web/sass/screen.scss
  8. +10
    -0
      backend/web/sass/user/_credit.scss
  9. +8
    -0
      common/models/Producer.php
  10. +2
    -1
      common/models/UserProducer.php
  11. +15
    -0
      console/migrations/m190225_093245_ajout_champs_gestion_credit_utilisateur.php
  12. +15
    -4
      producer/controllers/OrderController.php
  13. +7
    -7
      producer/views/order/order.php
  14. +10
    -5
      producer/web/js/vuejs/order-order.js

+ 24
- 1
backend/controllers/UserController.php View File

use common\models\Producer ; use common\models\Producer ;
use common\models\Distribution ; use common\models\Distribution ;
use backend\models\MailForm ; use backend\models\MailForm ;
use common\models\UserProducer ;


/** /**
* UserController implements the CRUD actions for User model. * UserController implements the CRUD actions for User model.


return $this->render('credit', [ return $this->render('credit', [
'user' => $user, 'user' => $user,
'userProducer' => $userProducer,
'creditForm' => $creditForm, 'creditForm' => $creditForm,
'history' => $history 'history' => $history
]); ]);
} }
else { 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.");
} }
} }


'user' => $user '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. * Finds the User model based on its primary key value.

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

<?= $form->field($model, 'credit_functioning') <?= $form->field($model, 'credit_functioning')
->dropDownList([ ->dropDownList([
'' => 'Paramètres globaux ('.Producer::$creditFunctioningArray[Producer::getConfig('credit_functioning')].')', '' => '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"> <div id="delivery-days">

+ 14
- 10
backend/views/producer/update.php View File

. '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 />' . '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.') ; ?> . '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',[ <?= $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}', '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é.") ; ?> ->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',[ <?= $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}', '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.'); ?> ])->hint('Limite de crédit que l\'utilisateur ne pourra pas dépasser. Laisser vide pour permettre un crédit négatif et infini.'); ?>
<?= $form->field($model, 'use_credit_checked_default')
->dropDownList([
0 => 'Non',
1 => 'Oui',
], []) ; ?>
</div> </div>
</div> </div>

+ 42
- 19
backend/views/user/credit.php View File

} }
?> ?>
<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> </div>
<?php ActiveForm::end(); ?>
</div> </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> <h2>Historique <span class="the-credit"><?= number_format($user->getCredit($producer->id), 2); ?> €</span></h2>
<table class="table table-bordered"> <table class="table table-bordered">
<thead> <thead>

+ 9
- 3
backend/views/user/index.php View File

'attribute' => 'credit', 'attribute' => 'credit',
'format' => 'raw', 'format' => 'raw',
'value' => function($model) use($producer) { '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"> $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"> <span class="input-group-btn">
'.Html::a( '.Html::a(
'<span class="glyphicon glyphicon-euro"></span>', '<span class="glyphicon glyphicon-euro"></span>',
Yii::$app->urlManager->createUrl(['user/credit','id' => $model->id]), Yii::$app->urlManager->createUrl(['user/credit','id' => $model->id]),
[ [
'title' => 'Crédit', 'title' => 'Crédit',
'class' => 'btn btn-default'
'class' => 'btn '.$classBtnCredit
] ]
).' ).'
</span> </span>

+ 5
- 0
backend/web/css/screen.css View File

margin-bottom: 20px; margin-bottom: 20px;
} }


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

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

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

@import "stats/_products.scss" ; @import "stats/_products.scss" ;
@import "distribution/_index.scss" ; @import "distribution/_index.scss" ;
@import "user/_emails.scss" ; @import "user/_emails.scss" ;
@import "user/_credit.scss" ;
@import "producer/_update.scss" ; @import "producer/_update.scss" ;
@import "point_sale/_index.scss" ; @import "point_sale/_index.scss" ;

+ 10
- 0
backend/web/sass/user/_credit.scss View File


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

+ 8
- 0
common/models/Producer.php View File

{ {
const CREDIT_FUNCTIONING_MANDATORY = 'mandatory' ; const CREDIT_FUNCTIONING_MANDATORY = 'mandatory' ;
const CREDIT_FUNCTIONING_OPTIONAL = 'optional' ; 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 = [ public static $creditFunctioningArray = [
self::CREDIT_FUNCTIONING_MANDATORY => 'Obligatoire', self::CREDIT_FUNCTIONING_MANDATORY => 'Obligatoire',
self::CREDIT_FUNCTIONING_OPTIONAL => 'Optionnelle', self::CREDIT_FUNCTIONING_OPTIONAL => 'Optionnelle',
self::CREDIT_FUNCTIONING_USER => 'Basée sur l\'utilisateur',
]; ];
var $secret_key_payplug ; var $secret_key_payplug ;

+ 2
- 1
common/models/UserProducer.php View File

return [ return [
[['id_user', 'id_producer'], 'required'], [['id_user', 'id_producer'], 'required'],
[['id_user', 'id_producer'], 'integer'], [['id_user', 'id_producer'], 'integer'],
[['active','bookmark'], 'boolean'],
[['active','bookmark','credit_active'], 'boolean'],
[['credit'], 'double'], [['credit'], 'double'],
]; ];
} }
'id_producer' => 'Producteur', 'id_producer' => 'Producteur',
'active' => 'Actif', 'active' => 'Actif',
'bookmark' => 'Favoris', 'bookmark' => 'Favoris',
'credit_active' => 'Crédit'
]; ];
} }

+ 15
- 0
console/migrations/m190225_093245_ajout_champs_gestion_credit_utilisateur.php View File

<?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') ;
}
}

+ 15
- 4
producer/controllers/OrderController.php View File

{ {
$posts = Yii::$app->request->post(); $posts = Yii::$app->request->post();
$productsArray = []; $productsArray = [];

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


foreach ($posts['products'] as $key => $quantity) { foreach ($posts['products'] as $key => $quantity) {
$product = Product::find()->where(['id' => (int) $key])->one(); $product = Product::find()->where(['id' => (int) $key])->one();
} }
} }
$producer = $this->getProducer() ;


// date // date
$errorDate = false; $errorDate = false;
if ($order->validate() && count($productsArray) && !$errorDate && !$errorPointSale) { if ($order->validate() && count($productsArray) && !$errorDate && !$errorPointSale) {


$userProducer = UserProducer::searchOne([
'id_producer' => $order->distribution->id_producer,
'id_user' => User::getCurrentId()
]) ;
// gestion point de vente // gestion point de vente
$pointSale = PointSale::searchOne([ $pointSale = PointSale::searchOne([
'id' => $order->id_point_sale 'id' => $order->id_point_sale
$amountPaid = $order->getAmount(Order::AMOUNT_PAID); $amountPaid = $order->getAmount(Order::AMOUNT_PAID);
$amountRemaining = $order->getAmount(Order::AMOUNT_REMAINING) ; $amountRemaining = $order->getAmount(Order::AMOUNT_REMAINING) ;
if($credit && $pointSale->credit && ($posts['use_credit'] || $pointSale->credit_functioning == Producer::CREDIT_FUNCTIONING_MANDATORY)) {
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 // à payer
if ($order->getPaymentStatus() == Order::PAYMENT_UNPAID) { if ($order->getPaymentStatus() == Order::PAYMENT_UNPAID) {
'id_user' => User::getCurrentId() 'id_user' => User::getCurrentId()
]) ; ]) ;
$json['credit'] = $userProducer->credit ;
$json['user'] = [
'credit' => $userProducer->credit,
'credit_active' => $userProducer->credit_active,
] ;
if($dateObject && $dateObject->format($format) === $date) { if($dateObject && $dateObject->format($format) === $date) {

+ 7
- 7
producer/views/order/order.php View File

</template> </template>
<template v-else> <template v-else>
<div class="credit"> <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 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"> <div class="info" v-if="useCredit">
<template v-if="order == null || order.amount_paid == 0"> <template v-if="order == null || order.amount_paid == 0">
<span v-if="checkCreditLimit(order)">{{ priceTotal(true) }} seront débités</span> <span v-if="checkCreditLimit(order)">{{ priceTotal(true) }} seront débités</span>
<span v-else> <span v-else>
{{ formatPrice(credit) }} seront débités. (Limite de crédit à {{ formatPrice(creditLimit) }})<br />
{{ formatPrice(user.credit) }} seront débités. (Limite de crédit à {{ formatPrice(producer.credit_limit) }})<br />
Restera {{ formatPrice(priceTotal() - credit) }} à régler. Restera {{ formatPrice(priceTotal() - credit) }} à régler.
</span> </span>
</template> </template>
<template v-else-if="order != null && order.amount_paid > 0 && order.amount_paid < priceTotal()"> <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-if="checkCreditLimit(order)">{{ formatPrice(priceTotal() - order.amount_paid) }} seront débités</span>
<span v-else> <span v-else>
{{ formatPrice(credit) }} seront débités. (Limite de crédit à {{ formatPrice(creditLimit) }})<br />
Restera {{ formatPrice(priceTotal() - order.amount_paid - credit) }} à régler.
{{ 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> </span>
</template> </template>
<template v-else-if="order != null && order.amount_paid > priceTotal()"> <template v-else-if="order != null && order.amount_paid > priceTotal()">

+ 10
- 5
producer/web/js/vuejs/order-order.js View File

loadingInit: true, loadingInit: true,
step: 'date', step: 'date',
producer: null, producer: null,
user: null,
date: null, date: null,
dateFormat: null, dateFormat: null,
distributions: [], distributions: [],
products: [], products: [],
comment: '', comment: '',
creditCheckbox: false, creditCheckbox: false,
credit: 0,
creditLimit: null,
useCredit: false, useCredit: false,
errors: [], errors: [],
disableConfirmButton: false, disableConfirmButton: false,
axios.get("ajax-infos",{params: {date : this.getDate()}}) axios.get("ajax-infos",{params: {date : this.getDate()}})
.then(function(response) { .then(function(response) {
app.producer = response.data.producer ; 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.useCredit = response.data.producer.use_credit_checked_default ;
app.creditLimit = response.data.producer.credit_limit ;
app.calendar.attrs = [] ; app.calendar.attrs = [] ;
app.calendar.availableDates = [] ; app.calendar.availableDates = [] ;
var distributions = response.data.distributions ; var distributions = response.data.distributions ;


validatePointSale: function(idPointSale) { validatePointSale: function(idPointSale) {
this.pointSaleActive = this.getPointSale(idPointSale) ; this.pointSaleActive = this.getPointSale(idPointSale) ;
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') ; this.changeStep('products') ;
}, },
productQuantityClick: function(product, quantity) { productQuantityClick: function(product, quantity) {
if(order != null) { if(order != null) {
total = this.priceTotal() - order.amount_paid ; total = this.priceTotal() - order.amount_paid ;
} }
return this.creditLimit == null || (this.creditLimit != null && (this.credit - total >= this.creditLimit)) ;
return this.producer.credit_limit == null || (this.producer.credit_limit != null && (this.user.credit - total >= this.producer.credit_limit)) ;
} }
} }
}); });

Loading…
Cancel
Save