@@ -0,0 +1,11 @@ | |||
# Change Log | |||
Tous les ajouts, modifications et correctifs de ce projet sont listés dans ce fichier. | |||
## [22.10.A] - 25/10/2022 | |||
### Ajouts | |||
- [Producer] Ajout d'un captcha sur le formulaire de contact #228 | |||
### Modifications | |||
### Correctifs |
@@ -79,7 +79,39 @@ class DevelopmentController extends Controller | |||
* | |||
* @return mixed | |||
*/ | |||
public function actionIndex($status = Development::STATUS_OPEN) | |||
public function actionIndex() | |||
{ | |||
$versionsArray = []; | |||
$pathVersions = Yii::getAlias('@common/versions'); | |||
if(is_dir($pathVersions)) | |||
{ | |||
$directory = opendir($pathVersions); | |||
while( $child = readdir($directory) ){ | |||
if($child != '.' && $child != '..'){ | |||
$version = str_replace('.php', '', $child); | |||
$versionsArray[$version] = [ | |||
'version' => str_replace('.php', '', $child), | |||
'content' => $this->renderFile('@common/versions/'.$child) | |||
]; | |||
} | |||
} | |||
} | |||
krsort($versionsArray); | |||
// Producer : set latest version d'Opendistrib | |||
$producer = GlobalParam::getCurrentProducer(); | |||
$producer->latest_version_opendistrib = array_values($versionsArray)[0]['version']; | |||
$producer->save(); | |||
return $this->render('index', [ | |||
'versionsArray' => $versionsArray | |||
]); | |||
} | |||
public function actionDevelopment($status = Development::STATUS_OPEN) | |||
{ | |||
$dataProvider = new ActiveDataProvider([ | |||
'query' => Development::find() | |||
@@ -88,10 +120,10 @@ class DevelopmentController extends Controller | |||
->orderBy('date DESC'), | |||
]); | |||
return $this->render('index', [ | |||
return $this->render('development', [ | |||
'dataProvider' => $dataProvider, | |||
'status' => $status | |||
]); | |||
]); | |||
} | |||
/** |
@@ -82,7 +82,7 @@ class DistributionController extends BackendController | |||
]; | |||
} | |||
public function actionIndex($date = '') | |||
public function actionIndex($date = '', $idOrderUpdate = 0) | |||
{ | |||
$this->checkProductsPointsSale(); | |||
@@ -94,8 +94,14 @@ class DistributionController extends BackendController | |||
$theDate = $date; | |||
} | |||
$orderUpdate = null; | |||
if($idOrderUpdate) { | |||
$orderUpdate = Order::searchOne(['id' => $idOrderUpdate]); | |||
} | |||
return $this->render('index', [ | |||
'date' => $theDate | |||
'date' => $theDate, | |||
'orderUpdate' => $orderUpdate | |||
]); | |||
} | |||
@@ -176,20 +182,19 @@ class DistributionController extends BackendController | |||
$json['distribution']['weight'] = number_format($weight, 2); | |||
// products | |||
$productsArray = Product::find() | |||
->orWhere(['id_producer' => GlobalParam::getCurrentProducerId(),]) | |||
->joinWith([ | |||
'taxRate', | |||
'productDistribution' => function ($query) use ($distribution) { | |||
$query->andOnCondition( | |||
'product_distribution.id_distribution = ' . $distribution->id | |||
); | |||
} | |||
]) | |||
->orderBy('product_distribution.active DESC, order ASC') | |||
->asArray() | |||
->all(); | |||
$productsQuery = Product::find() | |||
->orWhere(['id_producer' => GlobalParam::getCurrentProducerId(),]) | |||
->joinWith([ | |||
'taxRate', | |||
'productDistribution' => function ($query) use ($distribution) { | |||
$query->andOnCondition( | |||
'product_distribution.id_distribution = ' . $distribution->id | |||
); | |||
} | |||
]) | |||
->orderBy('product_distribution.active DESC, order ASC'); | |||
$productsArray = $productsQuery->asArray()->all(); | |||
$potentialRevenues = 0; | |||
$potentialWeight = 0; | |||
@@ -229,12 +234,14 @@ class DistributionController extends BackendController | |||
$ordersArrayObject = $ordersArray; | |||
if ($ordersArray) { | |||
foreach ($ordersArray as &$order) { | |||
$productOrderArray = []; | |||
foreach ($order->productOrder as $productOrder) { | |||
$productOrderArray[$productOrder->id_product] = [ | |||
'quantity' => $productOrder->quantity * Product::$unitsArray[$productOrder->unit]['coefficient'], | |||
'unit' => $productOrder->unit, | |||
'price' => Price::getPriceWithTax($productOrder->price, $productOrder->taxRate->value) | |||
'price' => number_format($productOrder->price, 3), | |||
'price_with_tax' => Price::getPriceWithTax($productOrder->price, $productOrder->taxRate->value), | |||
]; | |||
} | |||
@@ -243,7 +250,8 @@ class DistributionController extends BackendController | |||
$productOrderArray[$product['id']] = [ | |||
'quantity' => 0, | |||
'unit' => $product['unit'], | |||
'price' => Price::getPriceWithTax($product['price'], $product['taxRate']['value']), | |||
'price' => number_format($product['price'], 3), | |||
'price_with_tax' => Price::getPriceWithTax($product['price'], $product['taxRate']['value']), | |||
]; | |||
} | |||
} | |||
@@ -253,6 +261,7 @@ class DistributionController extends BackendController | |||
foreach ($order->creditHistory as $creditHistory) { | |||
$creditHistoryArray[] = [ | |||
'date' => date('d/m/Y H:i:s', strtotime($creditHistory->date)), | |||
'user' => $creditHistory->user->getUsername(), | |||
'user_action' => $creditHistory->strUserAction(), | |||
'wording' => $creditHistory->getStrWording(), | |||
'debit' => ($creditHistory->isTypeDebit() ? '- ' . $creditHistory->getAmount( | |||
@@ -282,6 +291,7 @@ class DistributionController extends BackendController | |||
$order = array_merge($order->getAttributes(), [ | |||
'selected' => false, | |||
'weight' => $order->weight, | |||
'amount' => Price::numberTwoDecimals($order->getAmountWithTax(Order::AMOUNT_TOTAL)), | |||
'amount_paid' => Price::numberTwoDecimals($order->getAmount(Order::AMOUNT_PAID)), | |||
'amount_remaining' => Price::numberTwoDecimals($order->getAmount(Order::AMOUNT_REMAINING)), | |||
@@ -446,7 +456,6 @@ class DistributionController extends BackendController | |||
$productsArray = Product::find() | |||
->where([ | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
'product.active' => 1, | |||
])->joinWith([ | |||
'productPrice', | |||
'productDistribution' => function ($q) use ($distribution) { | |||
@@ -1459,6 +1468,7 @@ class DistributionController extends BackendController | |||
if ($order && $order->distribution->id_producer == GlobalParam::getCurrentProducerId( | |||
) && $order->id_user) { | |||
$deliveryNote = null; | |||
$idDeliveryNote = $order->id_delivery_note; | |||
if ($idDeliveryNote) { | |||
@@ -1491,6 +1501,20 @@ class DistributionController extends BackendController | |||
if ($deliveryNote) { | |||
$order->id_delivery_note = $deliveryNote->id; | |||
$order->save(); | |||
// init invoice prices | |||
$user = User::searchOne([ | |||
'id' => $deliveryNote->id_user | |||
]); | |||
$userProducer = UserProducer::searchOne([ | |||
'id_user' => $deliveryNote->id_user, | |||
'id_producer' => GlobalParam::getCurrentProducerId() | |||
]); | |||
$order->initInvoicePrices([ | |||
'user' => $user, | |||
'user_producer' => $userProducer, | |||
'point_sale' => $order->pointSale | |||
]); | |||
} | |||
} | |||
} |
@@ -320,6 +320,10 @@ class DocumentController extends BackendController | |||
{ | |||
$document = $this->findModel($id); | |||
if ($document->send()) { | |||
$document->is_sent = true; | |||
$document->save(); | |||
Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('send', $document)); | |||
} else { | |||
Yii::$app->getSession()->setFlash('danger', $this->getFlashMessage('send', $document)); |
@@ -62,75 +62,75 @@ use common\helpers\Upload; | |||
*/ | |||
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; | |||
public function behaviors() | |||
{ | |||
return [ | |||
'verbs' => [ | |||
'class' => VerbFilter::className(), | |||
'actions' => [ | |||
], | |||
], | |||
'access' => [ | |||
'class' => AccessControl::className(), | |||
'rules' => [ | |||
[ | |||
'allow' => true, | |||
'roles' => ['@'], | |||
'matchCallback' => function ($rule, $action) { | |||
return User::hasAccessBackend(); | |||
} | |||
] | |||
], | |||
], | |||
]; | |||
} | |||
/** | |||
* 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, | |||
]); | |||
} | |||
/** | |||
* 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, | |||
]); | |||
} | |||
/** | |||
* 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 ; | |||
$model->wednesday = 1 ; | |||
$model->thursday = 1 ; | |||
$model->friday = 1 ; | |||
$model->saturday = 1 ; | |||
$model->sunday = 1 ; | |||
$model->available_on_points_sale = 1 ; | |||
/** | |||
* 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; | |||
$model->wednesday = 1; | |||
$model->thursday = 1; | |||
$model->friday = 1; | |||
$model->saturday = 1; | |||
$model->sunday = 1; | |||
$model->available_on_points_sale = 1; | |||
if ($model->load(Yii::$app->request->post()) && $model->save()) { | |||
$lastProductOrder = Product::find()->where('id_producer = :id_producer')->params([':id_producer' => GlobalParam::getCurrentProducerId()])->orderBy('order DESC')->one() ; | |||
if($lastProductOrder) { | |||
$model->order = ++ $lastProductOrder->order ; | |||
$lastProductOrder = Product::find()->where('id_producer = :id_producer')->params([':id_producer' => GlobalParam::getCurrentProducerId()])->orderBy('order DESC')->one(); | |||
if ($lastProductOrder) { | |||
$model->order = ++$lastProductOrder->order; | |||
} | |||
Upload::uploadFile($model, 'photo'); | |||
$model->save(); | |||
@@ -138,244 +138,254 @@ class ProductController extends BackendController | |||
$this->processAvailabilityPointsSale($model); | |||
// link product / distribution | |||
Distribution::linkProductIncomingDistributions($model) ; | |||
Distribution::linkProductIncomingDistributions($model); | |||
Yii::$app->getSession()->setFlash('success', 'Produit <strong>'.Html::encode($model->name).'</strong> ajouté'); | |||
Yii::$app->getSession()->setFlash('success', 'Produit <strong>' . Html::encode($model->name) . '</strong> ajouté'); | |||
return $this->redirect(['index']); | |||
} | |||
else { | |||
} else { | |||
return $this->render('create', [ | |||
'model' => $model, | |||
]); | |||
} | |||
} | |||
/** | |||
* 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); | |||
foreach ($model->productPointSale as $productPointSale) { | |||
$model->pointsSale[] = $productPointSale->id_point_sale; | |||
} | |||
$photoFilenameOld = $model->photo; | |||
/** | |||
* 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); | |||
foreach ($model->productPointSale as $productPointSale) { | |||
$model->pointsSale[] = $productPointSale->id_point_sale; | |||
} | |||
if ($model->load(Yii::$app->request->post()) && $model->save()) { | |||
$photoFilenameOld = $model->photo; | |||
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(); | |||
} | |||
Upload::uploadFile($model, 'photo', $photoFilenameOld); | |||
// availability on points sale | |||
$this->processAvailabilityPointsSale($model); | |||
$deletePhoto = $request->post('delete_photo', 0); | |||
if ($deletePhoto) { | |||
$model->photo = ''; | |||
$model->save(); | |||
} | |||
if ($model->apply_distributions) { | |||
// link product / distribution | |||
Distribution::linkProductIncomingDistributions($model); | |||
} | |||
// availability on points sale | |||
$this->processAvailabilityPointsSale($model); | |||
Yii::$app->getSession()->setFlash('success', 'Produit <strong>' . Html::encode($model->name) . '</strong> modifié'); | |||
return $this->redirect(['index']); | |||
} | |||
if ($model->apply_distributions) { | |||
// link product / distribution | |||
Distribution::linkProductIncomingDistributions($model); | |||
} | |||
return $this->render('update/update', [ | |||
'model' => $model, | |||
'action' => 'update', | |||
]); | |||
Yii::$app->getSession()->setFlash('success', 'Produit <strong>' . Html::encode($model->name) . '</strong> modifié'); | |||
return $this->redirect(['index']); | |||
} | |||
/** | |||
* Traite les accès restreints d'un point de vente. | |||
*/ | |||
public function processAvailabilityPointsSale($model) | |||
{ | |||
ProductPointSale::deleteAll(['id_product' => $model->id]); | |||
if (is_array($model->pointsSale) && count($model->pointsSale)) { | |||
foreach ($model->pointsSale as $key => $val) { | |||
$pointSale = PointSale::findOne($val); | |||
if ($pointSale) { | |||
$productPointSale = new ProductPointSale; | |||
$productPointSale->id_product = $model->id; | |||
$productPointSale->id_point_sale = $pointSale->id; | |||
$productPointSale->available = ($model->available_on_points_sale) ? 0 : 1; | |||
$productPointSale->save(); | |||
} | |||
return $this->render('update/update', [ | |||
'model' => $model, | |||
'action' => 'update', | |||
]); | |||
} | |||
/** | |||
* Traite les accès restreints d'un point de vente. | |||
*/ | |||
public function processAvailabilityPointsSale($model) | |||
{ | |||
ProductPointSale::deleteAll(['id_product' => $model->id]); | |||
if (is_array($model->pointsSale) && count($model->pointsSale)) { | |||
foreach ($model->pointsSale as $key => $val) { | |||
$pointSale = PointSale::findOne($val); | |||
if ($pointSale) { | |||
$productPointSale = new ProductPointSale; | |||
$productPointSale->id_product = $model->id; | |||
$productPointSale->id_point_sale = $pointSale->id; | |||
$productPointSale->available = ($model->available_on_points_sale) ? 0 : 1; | |||
$productPointSale->save(); | |||
} | |||
} | |||
} | |||
} | |||
public function actionPricesList($id) | |||
{ | |||
$request = Yii::$app->request; | |||
$model = $this->findModel($id); | |||
$searchModel = new ProductPriceSearch(); | |||
$searchModel->id_product = $id ; | |||
$dataProvider = $searchModel->search(array_merge(Yii::$app->request->queryParams, [ | |||
'id_product' => $id | |||
])); | |||
$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, | |||
]); | |||
} | |||
public function actionPricesCreate($idProduct) | |||
{ | |||
$model = new ProductPrice(); | |||
$model->id_product = $idProduct; | |||
$modelProduct = $this->findModel($idProduct) ; | |||
public function actionPricesList($id) | |||
{ | |||
$request = Yii::$app->request; | |||
$model = $this->findModel($id); | |||
$searchModel = new ProductPriceSearch(); | |||
$searchModel->id_product = $id; | |||
$dataProvider = $searchModel->search(array_merge(Yii::$app->request->queryParams, [ | |||
'id_product' => $id | |||
])); | |||
$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, | |||
]); | |||
} | |||
if ($model->load(Yii::$app->request->post())) { | |||
public function actionPricesCreate($idProduct) | |||
{ | |||
$model = new ProductPrice(); | |||
$model->id_product = $idProduct; | |||
$modelProduct = $this->findModel($idProduct); | |||
$conditionsProductPriceExist = [ | |||
'id_product' => $idProduct, | |||
'id_user' => $model->id_user ? $model->id_user : null, | |||
'id_user_group' => $model->id_user_group ? $model->id_user_group : null, | |||
'id_point_sale' => $model->id_point_sale ? $model->id_point_sale : null, | |||
'from_quantity' => $model->from_quantity ? $model->from_quantity : null, | |||
] ; | |||
if ($model->load(Yii::$app->request->post())) { | |||
$productPriceExist = ProductPrice::findOne($conditionsProductPriceExist) ; | |||
$conditionsProductPriceExist = [ | |||
'id_product' => $idProduct, | |||
'id_user' => $model->id_user ? $model->id_user : null, | |||
'id_user_group' => $model->id_user_group ? $model->id_user_group : null, | |||
'id_point_sale' => $model->id_point_sale ? $model->id_point_sale : null, | |||
'from_quantity' => $model->from_quantity ? $model->from_quantity : null, | |||
]; | |||
if($productPriceExist) { | |||
$productPriceExist->delete() ; | |||
Yii::$app->getSession()->setFlash('warning', 'Un prix existait déjà pour cet utilisateur / point de vente, il a été supprimé.'); | |||
} | |||
$productPriceExist = ProductPrice::findOne($conditionsProductPriceExist); | |||
if($model->save()) { | |||
Yii::$app->getSession()->setFlash('success', 'Le prix a bien été ajouté.'); | |||
return $this->redirect(['product/prices-list', 'id' => $idProduct]); | |||
} | |||
} | |||
if ($productPriceExist) { | |||
$productPriceExist->delete(); | |||
Yii::$app->getSession()->setFlash('warning', 'Un prix existait déjà pour cet utilisateur / point de vente, il a été supprimé.'); | |||
} | |||
return $this->render('update/prices/create', [ | |||
'model' => $model, | |||
'modelProduct' => $modelProduct, | |||
]); | |||
if ($model->save()) { | |||
Yii::$app->getSession()->setFlash('success', 'Le prix a bien été ajouté.'); | |||
return $this->redirect(['product/prices-list', 'id' => $idProduct]); | |||
} | |||
} | |||
public function actionPricesUpdate($id) | |||
{ | |||
$request = Yii::$app->request; | |||
return $this->render('update/prices/create', [ | |||
'model' => $model, | |||
'modelProduct' => $modelProduct, | |||
]); | |||
} | |||
$model = $this->findModelProductPrice($id); | |||
$modelProduct = $this->findModel($model->id_product) ; | |||
public function actionPricesUpdate($id) | |||
{ | |||
$request = Yii::$app->request; | |||
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]); | |||
} | |||
$model = $this->findModelProductPrice($id); | |||
$modelProduct = $this->findModel($model->id_product); | |||
return $this->render('update/prices/update', [ | |||
'model' => $model, | |||
'modelProduct' => $modelProduct, | |||
'action' => 'prices-update', | |||
]); | |||
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]); | |||
} | |||
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]); | |||
} | |||
return $this->render('update/prices/update', [ | |||
'model' => $model, | |||
'modelProduct' => $modelProduct, | |||
'action' => 'prices-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 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]); | |||
} | |||
return $this->redirect(['index']); | |||
/** | |||
* 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'])); | |||
} | |||
/** | |||
* 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(); | |||
} | |||
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.'); | |||
} | |||
public function actionAjaxToggleActive($id, $active) | |||
{ | |||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |||
$product = $this->findModel($id); | |||
$product->active = (int) $active; | |||
Distribution::linkProductIncomingDistributions($product); | |||
return ['success', 'id' => $id, 'active' => $active]; | |||
} | |||
/** | |||
* 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.'); | |||
} | |||
protected function findModelProductPrice($id) | |||
{ | |||
if (($model = ProductPrice::findOne($id)) !== null) { | |||
return $model; | |||
} else { | |||
throw new NotFoundHttpException('The requested page does not exist.'); | |||
} | |||
} | |||
} |
@@ -117,6 +117,7 @@ class SiteController extends BackendController | |||
*/ | |||
public function actionIndex() | |||
{ | |||
// commandes | |||
$optionDashboardNumberDistributions = Producer::getConfig('option_dashboard_number_distributions') ; | |||
$dashboardNumberDistributions = $optionDashboardNumberDistributions ? $optionDashboardNumberDistributions : 3 ; | |||
@@ -175,8 +176,6 @@ class SiteController extends BackendController | |||
]); | |||
// clients | |||
$nbUsers = User::searchCount(); | |||
$usersArray = User::findBy() | |||
->orderBy('created_at DESC') | |||
->limit(5) | |||
@@ -196,7 +195,6 @@ class SiteController extends BackendController | |||
'distributionsArray' => $distributionsArray, | |||
'ordersArray' => $ordersArray, | |||
'usersArray' => $usersArray, | |||
'nbUsers' => $nbUsers, | |||
'usersNegativeCredit' => $usersNegativeCredit, | |||
'producer' => $producer, | |||
'productsCount' => $productsCount, |
@@ -73,7 +73,8 @@ class CreditForm extends Model | |||
[['id_user', 'id_user_action', 'id_producer'], 'integer'], | |||
[['date','send_mail'], 'safe'], | |||
[['amount'], 'double'], | |||
[['type', 'mean_payment', 'comment'], 'string', 'max' => 255], | |||
[['type', 'mean_payment'], 'string', 'max' => 255], | |||
[['comment'], 'string', 'max' => 2048], | |||
]; | |||
} | |||
@@ -0,0 +1,194 @@ | |||
<?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\grid\GridView; | |||
use common\models\Development; | |||
use common\models\DevelopmentPriority; | |||
use common\models\User; | |||
use common\helpers\Url; | |||
use common\helpers\GlobalParam; | |||
$this->setTitle('Développement'); | |||
$this->addButton(['label' => 'Nouveau développement <span class="glyphicon glyphicon-plus"></span>', 'url' => ['development/create'], 'class' => 'btn btn-primary']); | |||
$this->addBreadcrumb($this->getTitle()); | |||
?> | |||
<div class="development-index"> | |||
<div class="well"> | |||
Cette page liste les besoins recencés auprès des producteurs utilisant la plateforme. N'hésitez pas à me <a | |||
href="<?= Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/contact']); ?>">contacter</a> pour la | |||
faire évoluer. Les remontées de bugs sont également bienvenues.<br/> | |||
Afin d'orienter de manière pertinente le développement de la plateforme, je vous invite à définir la priorité | |||
des évolutions qui vous intéressent. | |||
</div> | |||
<ul id="tab-status-developments" class="nav nav-tabs" role="tablist"> | |||
<li role="presentation" class="<?php if ($status == Development::STATUS_OPEN): ?>active<?php endif; ?>"><a | |||
href="<?= Yii::$app->urlManager->createUrl(['development/index', 'status' => Development::STATUS_OPEN]); ?>" | |||
id="" aria-controls="" role="tab">Ouvert</a></li> | |||
<li role="presentation" class="<?php if ($status == Development::STATUS_CLOSED): ?>active<?php endif; ?>"><a | |||
href="<?= Yii::$app->urlManager->createUrl(['development/index', 'status' => Development::STATUS_CLOSED]); ?>" | |||
id="" aria-controls="" role="tab">Fermé</a></li> | |||
</ul> | |||
<?php | |||
$columns = [ | |||
[ | |||
'header' => '#', | |||
'value' => function ($model) { | |||
return '#' . $model->id; | |||
} | |||
], | |||
[ | |||
'attribute' => 'type', | |||
'header' => 'Type', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
if ($model->type == Development::TYPE_EVOLUTION) { | |||
return '<span class="label label-success">Évolution</span>'; | |||
} else { | |||
return '<span class="label label-danger">Anomalie</span>'; | |||
} | |||
} | |||
], | |||
['attribute' => 'sujet', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
$html = '<strong>' . Html::encode($model->subject) . '</strong>'; | |||
if (strlen($model->description)) | |||
$html .= '<br />' . nl2br(Html::encode($model->description)); | |||
return $html; | |||
}], | |||
['attribute' => 'estimation_temps', | |||
'header' => 'Estimation', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
return intval($model->time_estimate) . ' h'; | |||
}], | |||
['attribute' => 'avancement', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
if ($model->progress) | |||
return '<div class="progress"> | |||
<div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="' . intval($model->progress) . '" aria-valuemin="0" aria-valuemax="100" style="width: ' . intval($model->progress) . '%;"> | |||
<span class="sr-only">' . intval($model->progress) . '% effectué</span> | |||
</div> | |||
</div> '; | |||
else | |||
return ''; | |||
}], | |||
['attribute' => 'date_delivery', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
if (strlen($model->date_delivery)) | |||
return date('d/m/Y', strtotime($model->date_delivery)); | |||
else | |||
return ''; | |||
}], | |||
]; | |||
if (User::hasAccessBackend()) { | |||
$columns[] = [ | |||
'header' => 'Priorité', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
$currentPriority = (isset($model->developmentPrioritYCurrentProducer)) ? $model->developmentPriorityCurrentProducer->getStrPriority() : 'Non'; | |||
$styleButton = (isset($model->developmentPriorityCurrentProducer)) ? $model->developmentPriorityCurrentProducer->getClassCssStyleButton() : 'default'; | |||
$html = '<div class="btn-group btn-group-priorite"> | |||
<button type="button" class="btn btn-priorite btn-sm btn-' . $styleButton . ' dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |||
' . $currentPriority . ' <span class="caret"></span> | |||
</button> | |||
<ul class="dropdown-menu"> | |||
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id]) . '">Non</a></li> | |||
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_LOW]) . '">Basse</a></li> | |||
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_NORMAL]) . '">Normale</a></li> | |||
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_HIGH]) . '">Haute</a></li> | |||
</ul> | |||
</div><br />'; | |||
if (isset($model->developmentPriority) && count($model->developmentPriority)) { | |||
foreach ($model->developmentPriority as $developmentPriority) { | |||
if ($developmentPriority->id_producer != GlobalParam::getCurrentProducerId()) | |||
$html .= '<div class="label label-priorite label-sm label-' . $developmentPriority->getClassCssStyleButton() . '">' . Html::encode($developmentPriority->producer->name) . '</div> '; | |||
} | |||
} | |||
return $html; | |||
} | |||
]; | |||
} | |||
if (User::getCurrentStatus() == USER::STATUS_ADMIN) { | |||
$columns[] = [ | |||
'class' => 'yii\grid\ActionColumn', | |||
'template' => '{update}', | |||
'headerOptions' => ['class' => 'actions'], | |||
'buttons' => [ | |||
'update' => function ($url, $model) { | |||
return '<div class="btn-group"> | |||
<a href="' . $url . '" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span> Modifier</a> | |||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |||
<span class="caret"></span> | |||
<span class="sr-only">Toggle Dropdown</span> | |||
</button> | |||
<ul class="dropdown-menu"> | |||
<li><a href="' . Yii::$app->urlManager->createUrl(['development/delete', 'id' => $model->id]) . '" class=""><span class="glyphicon glyphicon-trash"></span> Supprimer</a></li> | |||
</ul> | |||
</div>'; | |||
}, | |||
], | |||
]; | |||
} | |||
?> | |||
<?= | |||
GridView::widget([ | |||
'id' => 'tab-developments', | |||
'dataProvider' => $dataProvider, | |||
'columns' => $columns | |||
]); | |||
?> | |||
</div> |
@@ -45,150 +45,27 @@ use common\helpers\Url; | |||
use common\helpers\GlobalParam; | |||
$this->setTitle('Développement'); | |||
$this->addButton(['label' => 'Nouveau développement <span class="glyphicon glyphicon-plus"></span>', 'url' => ['development/create'], 'class' => 'btn btn-primary']); | |||
$this->addBreadcrumb($this->getTitle()); | |||
?> | |||
<div class="development-index"> | |||
<div class="well"> | |||
Cette page liste les besoins recencés auprès des producteurs utilisant la plateforme. N'hésitez pas à me <a | |||
href="<?= Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/contact']); ?>">contacter</a> pour la | |||
faire évoluer. Les remontées de bugs sont également bienvenues.<br/> | |||
Afin d'orienter de manière pertinente le développement de la plateforme, je vous invite à définir la priorité | |||
des évolutions qui vous intéressent. | |||
<div class="alert alert-info"> | |||
Cette page liste les dernières versions du logiciel Opendistrib. Me | |||
<a href="mailto:contact@opendistrib.net">contacter</a> pour soumettre | |||
vos suggestions d'évolutions ou remontées de bug. | |||
</div> | |||
<ul id="tab-status-developments" class="nav nav-tabs" role="tablist"> | |||
<li role="presentation" class="<?php if ($status == Development::STATUS_OPEN): ?>active<?php endif; ?>"><a | |||
href="<?= Yii::$app->urlManager->createUrl(['development/index', 'status' => Development::STATUS_OPEN]); ?>" | |||
id="" aria-controls="" role="tab">Ouvert</a></li> | |||
<li role="presentation" class="<?php if ($status == Development::STATUS_CLOSED): ?>active<?php endif; ?>"><a | |||
href="<?= Yii::$app->urlManager->createUrl(['development/index', 'status' => Development::STATUS_CLOSED]); ?>" | |||
id="" aria-controls="" role="tab">Fermé</a></li> | |||
</ul> | |||
<?php | |||
$columns = [ | |||
[ | |||
'header' => '#', | |||
'value' => function ($model) { | |||
return '#' . $model->id; | |||
} | |||
], | |||
[ | |||
'attribute' => 'type', | |||
'header' => 'Type', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
if ($model->type == Development::TYPE_EVOLUTION) { | |||
return '<span class="label label-success">Évolution</span>'; | |||
} else { | |||
return '<span class="label label-danger">Anomalie</span>'; | |||
} | |||
} | |||
], | |||
['attribute' => 'sujet', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
$html = '<strong>' . Html::encode($model->subject) . '</strong>'; | |||
if (strlen($model->description)) | |||
$html .= '<br />' . nl2br(Html::encode($model->description)); | |||
return $html; | |||
}], | |||
['attribute' => 'estimation_temps', | |||
'header' => 'Estimation', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
return intval($model->time_estimate) . ' h'; | |||
}], | |||
['attribute' => 'avancement', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
if ($model->progress) | |||
return '<div class="progress"> | |||
<div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="' . intval($model->progress) . '" aria-valuemin="0" aria-valuemax="100" style="width: ' . intval($model->progress) . '%;"> | |||
<span class="sr-only">' . intval($model->progress) . '% effectué</span> | |||
</div> | |||
</div> '; | |||
else | |||
return ''; | |||
}], | |||
['attribute' => 'date_delivery', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
if (strlen($model->date_delivery)) | |||
return date('d/m/Y', strtotime($model->date_delivery)); | |||
else | |||
return ''; | |||
}], | |||
]; | |||
if (User::hasAccessBackend()) { | |||
$columns[] = [ | |||
'header' => 'Priorité', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
$currentPriority = (isset($model->developmentPrioritYCurrentProducer)) ? $model->developmentPriorityCurrentProducer->getStrPriority() : 'Non'; | |||
$styleButton = (isset($model->developmentPriorityCurrentProducer)) ? $model->developmentPriorityCurrentProducer->getClassCssStyleButton() : 'default'; | |||
$html = '<div class="btn-group btn-group-priorite"> | |||
<button type="button" class="btn btn-priorite btn-sm btn-' . $styleButton . ' dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |||
' . $currentPriority . ' <span class="caret"></span> | |||
</button> | |||
<ul class="dropdown-menu"> | |||
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id]) . '">Non</a></li> | |||
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_LOW]) . '">Basse</a></li> | |||
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_NORMAL]) . '">Normale</a></li> | |||
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_HIGH]) . '">Haute</a></li> | |||
</ul> | |||
</div><br />'; | |||
if (isset($model->developmentPriority) && count($model->developmentPriority)) { | |||
foreach ($model->developmentPriority as $developmentPriority) { | |||
if ($developmentPriority->id_producer != GlobalParam::getCurrentProducerId()) | |||
$html .= '<div class="label label-priorite label-sm label-' . $developmentPriority->getClassCssStyleButton() . '">' . Html::encode($developmentPriority->producer->name) . '</div> '; | |||
} | |||
} | |||
return $html; | |||
} | |||
]; | |||
} | |||
if (User::getCurrentStatus() == USER::STATUS_ADMIN) { | |||
$columns[] = [ | |||
'class' => 'yii\grid\ActionColumn', | |||
'template' => '{update}', | |||
'headerOptions' => ['class' => 'actions'], | |||
'buttons' => [ | |||
'update' => function ($url, $model) { | |||
return '<div class="btn-group"> | |||
<a href="' . $url . '" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span> Modifier</a> | |||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |||
<span class="caret"></span> | |||
<span class="sr-only">Toggle Dropdown</span> | |||
</button> | |||
<ul class="dropdown-menu"> | |||
<li><a href="' . Yii::$app->urlManager->createUrl(['development/delete', 'id' => $model->id]) . '" class=""><span class="glyphicon glyphicon-trash"></span> Supprimer</a></li> | |||
</ul> | |||
</div>'; | |||
}, | |||
], | |||
]; | |||
} | |||
?> | |||
<?= | |||
GridView::widget([ | |||
'id' => 'tab-developments', | |||
'dataProvider' => $dataProvider, | |||
'columns' => $columns | |||
]); | |||
?> | |||
<?php foreach($versionsArray as $version): ?> | |||
<div class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title"> | |||
<?= $version['version'] ?> | |||
</h3> | |||
</div> | |||
<div class="panel-body"> | |||
<?= $version['content'] ?> | |||
</div> | |||
</div> | |||
<?php endforeach; ?> | |||
</div> |
@@ -43,6 +43,20 @@ $this->setTitle('Distributions') ; | |||
$this->setPageTitle('Distributions') ; | |||
?> | |||
<?php if($orderUpdate): | |||
$orderUpdateDistributionTimestamp = strtotime($orderUpdate->distribution->date); | |||
?> | |||
<script> | |||
window.vueValues = { | |||
date: new Date(<?= date('Y', $orderUpdateDistributionTimestamp) ?>, <?= date('m', $orderUpdateDistributionTimestamp) - 1 ?>, <?= date('d', $orderUpdateDistributionTimestamp) ?>), | |||
dateFormat: '<?= date('d/m/Y', $orderUpdateDistributionTimestamp) ?>', | |||
showModalFormOrderUpdate: true, | |||
idOrderUpdate: <?= $orderUpdate->id ?> | |||
}; | |||
</script> | |||
<?php endif; ?> | |||
<div id="app-distribution-index" class="app-vuejs"> | |||
<?php if(strlen($date)): ?> | |||
<span id="distribution-date"><?= $date; ?></span> | |||
@@ -225,6 +239,7 @@ $this->setPageTitle('Distributions') ; | |||
:date="date" | |||
:order="orderCreate" | |||
:points-sale="pointsSale" | |||
:id-active-point-sale="idActivePointSale" | |||
:means-payment="meansPayment" | |||
:users="users" | |||
:products="products" | |||
@@ -287,6 +302,11 @@ $this->setPageTitle('Distributions') ; | |||
Attention, ce jour de distribution n'est pas activé et vous avez quand même des commandes enregistrées. | |||
</div> | |||
<div v-if="idActivePointSale > 0 && (totalActivePointSale() > 0 || weightActivePointSale() > 0)" class="point-sale-totals"> | |||
<span class="title">Totaux</span> | |||
CA TTC : <strong>{{ totalActivePointSale() }} €</strong> / Poids : <strong>{{ weightActivePointSale() }} kg</strong> | |||
</div> | |||
<table class="table table-condensed table-bordered table-hover" v-if="countOrdersByPointSale[idActivePointSale] > 0 || (idActivePointSale == 0 && orders.length > 0)"> | |||
<thead> | |||
<tr> | |||
@@ -397,8 +417,9 @@ $this->setPageTitle('Distributions') ; | |||
<order-form | |||
v-if="showModalFormOrderUpdate && idOrderUpdate == order.id" | |||
:date="date" | |||
:id-point-sale="idActivePointSale" | |||
:date-format="dateFormat" | |||
:points-sale="pointsSale" | |||
:id-active-point-sale="idActivePointSale" | |||
:means-payment="meansPayment" | |||
:users="users" | |||
:products="products" | |||
@@ -486,6 +507,7 @@ $this->setPageTitle('Distributions') ; | |||
<td>Date</td> | |||
<td>Utilisateur</td> | |||
<td>Action</td> | |||
<td>Origine action</td> | |||
<td>- Débit</td> | |||
<td>+ Crédit</td> | |||
</tr> | |||
@@ -493,8 +515,9 @@ $this->setPageTitle('Distributions') ; | |||
<tbody> | |||
<tr v-for="creditHistory in order.creditHistory"> | |||
<td>{{ creditHistory.date }}</td> | |||
<td>{{ creditHistory.user_action }}</td> | |||
<td>{{ creditHistory.user }}</td> | |||
<td v-html="creditHistory.wording"></td> | |||
<td>{{ creditHistory.user_action }}</td> | |||
<td v-html="creditHistory.debit"></td> | |||
<td v-html="creditHistory.credit"></td> | |||
</tr> | |||
@@ -532,11 +555,11 @@ $this->setPageTitle('Distributions') ; | |||
</td> | |||
</tr> | |||
</template> | |||
<tr v-if="idActivePointSale > 0"> | |||
<!--<tr v-if="idActivePointSale > 0"> | |||
<td colspan="4"><strong>Total (TTC)</strong></td> | |||
<td><strong>{{ totalActivePointSale() }}</strong></td> | |||
<td colspan="3"></td> | |||
</tr> | |||
</tr>--> | |||
</tbody> | |||
</table> | |||
<div class="alert alert-warning" v-else> | |||
@@ -550,7 +573,11 @@ $this->setPageTitle('Distributions') ; | |||
<!-- template for the order-form component --> | |||
<script type="text/x-template" id="order-form-template"> | |||
<modal class="modal-form-order" @close="$emit('close')"> | |||
<h3 slot="header">Ajouter une commande</h3> | |||
<h3 v-if="order.id" slot="header"> | |||
<template v-if="order.id">Modifier</template> | |||
<template v-else>Ajouter</template> | |||
une commande - {{ dateFormat }} | |||
</h3> | |||
<div slot="body"> | |||
<div class="callout callout-warning" v-if="errors.length"> | |||
<ul> | |||
@@ -608,15 +635,19 @@ $this->setPageTitle('Distributions') ; | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr v-for="product in products" :class="(order.productOrder[product.id] > 0) ? 'product-ordered' : ''"> | |||
<tr v-for="product in products" :class="(order.productOrder[product.id].quantity > 0) ? 'product-ordered' : ''"> | |||
<td> | |||
<span class="label label-success" v-if="loadingUpdateProductOrder || order.productOrder[product.id].active">Actif</span> | |||
<span class="label label-danger" v-else>Inactif</span> | |||
</td> | |||
<td>{{ product.name }}</td> | |||
<td class="price"> | |||
<div v-show="vatMode == 'all'" class="input-group"> | |||
<input type="text" v-model="order.productOrder[product.id].price" class="form-control input-sm" @change="productPriceChange" :data-with-tax="false" :data-id-product="product.id" /> | |||
<span class="input-group-addon" id="basic-addon2">€ HT </span> | |||
</div> | |||
<div class="input-group"> | |||
<input type="text" v-model="order.productOrder[product.id].price" class="form-control" @change="productPriceChange" :data-id-product="product.id" /> | |||
<input type="text" v-model="order.productOrder[product.id].price_with_tax" class="form-control input-sm" @change="productPriceChange" :data-with-tax="true" :data-id-product="product.id" /> | |||
<span class="input-group-addon" id="basic-addon2">€ TTC</span> | |||
</div> | |||
</td> | |||
@@ -625,7 +656,7 @@ $this->setPageTitle('Distributions') ; | |||
<span class="input-group-btn"> | |||
<button class="btn btn-default btn-moins" type="button" @click="productQuantityClick(product.id, order.productOrder[product.id].unit == 'piece' ? -1 : -parseFloat(product.step))"><span class="glyphicon glyphicon-minus"></span></button> | |||
</span> | |||
<input type="text" v-model="order.productOrder[product.id].quantity" class="form-control" /> | |||
<input type="text" v-model="order.productOrder[product.id].quantity" class="form-control input-quantity" /> | |||
<span class="input-group-addon">{{ order.productOrder[product.id].unit == 'piece' ? 'p.' : order.productOrder[product.id].unit }}</span> | |||
<span class="input-group-btn"> | |||
<button class="btn btn-default btn-plus" type="button" @click="productQuantityClick(product.id, order.productOrder[product.id].unit == 'piece' ? 1 : parseFloat(product.step))"><span class="glyphicon glyphicon-plus"></span></button> | |||
@@ -633,8 +664,8 @@ $this->setPageTitle('Distributions') ; | |||
</div> | |||
</td> | |||
<td class="quantity-remaining infinite" v-if="product.quantity_remaining === null || order.productOrder[product.id].unit != product.unit">∞</td> | |||
<td class="quantity-remaining negative" v-else-if="product.quantity_remaining <= 0">{{ product.quantity_remaining }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</td> | |||
<td class="quantity-remaining has-quantity" v-else>{{ product.quantity_remaining }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</td> | |||
<td class="quantity-remaining negative" v-else-if="product.quantity_remaining <= 0">{{ product.quantity_remaining }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</td> | |||
<td class="quantity-remaining has-quantity" v-else>{{ product.quantity_remaining }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
@@ -648,7 +679,16 @@ $this->setPageTitle('Distributions') ; | |||
<button class="modal-default-button btn btn-primary" @click="submitFormUpdate" v-if="order.id">Modifier</button> | |||
<button class="modal-default-button btn btn-primary" @click="submitFormCreate" v-else>Créer</button> | |||
<button class="modal-default-button btn btn-default" @click="$emit('close')">Annuler</button> | |||
<button class="modal-default-button btn btn-danger" @click="$emit('close')">Annuler</button> | |||
<div class="right"> | |||
<button class="modal-default-button btn btn-info" @click="updateProductOrderPrices(true)">Recharger les prix</button> | |||
<button class="modal-default-button btn btn-info" @click="toggleVatMode()"> | |||
<template v-if="vatMode == 'all'">Cacher</template> | |||
<template v-else>Afficher</template> | |||
les prix HT | |||
</button> | |||
</div> | |||
</div> | |||
</div> | |||
</modal> |
@@ -20,7 +20,7 @@ | |||
<?php if($displayPrices): ?> | |||
<td class="align-center"> | |||
<?= Price::format($price) ?> | |||
<?= Price::format($price) ?> | |||
</td> | |||
<?php endif; ?> | |||
<td class="align-center"> | |||
@@ -28,7 +28,7 @@ | |||
</td> | |||
<td class="align-center"><?= Product::strUnit($productOrder->unit, 'wording') ?></td> | |||
<?php if($displayPrices): ?> | |||
<?php if(GlobalParam::getCurrentProducer()->taxRate->value != 0): ?> | |||
<?php if($producer->taxRate->value != 0): ?> | |||
<td class="align-center"><?= $productOrder->taxRate->value * 100 ?> %</td> | |||
<?php endif; ?> | |||
<td class="align-center"> |
@@ -50,272 +50,283 @@ use common\models\Producer; | |||
<div class="document-form" id="app-document-form" data-class-document="<?= $model->getClass() ?>" | |||
data-id-document="<?= ($model->id > 0) ? $model->id : $model->id ?>"> | |||
<div class="<?= ($action == 'update') ? 'col-md-6' : '' ?>"> | |||
<div class="panel panel-default"> | |||
<div class="panel-heading"> | |||
Général | |||
</div> | |||
<div class="panel-body"> | |||
<?php $form = ActiveForm::begin(); ?> | |||
<?= Html::hiddenInput('classDocument',$model->getClass(), ['id' => 'class-document']) ?> | |||
<?= Html::hiddenInput('typeAction',$action, ['id' => 'type-action']) ?> | |||
<?php if ($action == 'update'): ?> | |||
<?= Html::hiddenInput('idDocument',$model->id, ['id' => 'id-document']) ?> | |||
<?php endif; ?> | |||
<?= $form->field($model, 'name')->label('Nom du document') ?> | |||
<div class="<?= ($action == 'update') ? 'col-md-6' : '' ?>"> | |||
<div class="panel panel-default"> | |||
<div class="panel-heading"> | |||
Général | |||
</div> | |||
<div class="panel-body"> | |||
<?php $form = ActiveForm::begin(); ?> | |||
<?= Html::hiddenInput('classDocument', $model->getClass(), ['id' => 'class-document']) ?> | |||
<?= Html::hiddenInput('typeAction', $action, ['id' => 'type-action']) ?> | |||
<?php if ($action == 'update'): ?> | |||
<?= Html::hiddenInput('idDocument', $model->id, ['id' => 'id-document']) ?> | |||
<?php endif; ?> | |||
<?= $form->field($model, 'name')->label('Nom du document') ?> | |||
<?php if($action == 'update'): ?> | |||
<?= $form->field($model, 'id_user', [ | |||
'template' => '{label} <div>{input}</div>'.$model->user->getUsername(), | |||
])->hiddenInput(); ?> | |||
<?php else: ?> | |||
<?php | |||
$usersArray = User::findBy()->orderBy('type DESC')->all(); | |||
?> | |||
<?= $form->field($model, 'id_user', [ | |||
'template' => '{label} <a href="' . Yii::$app->urlManager->createUrl(['user/create']) . '" class="btn btn-xs btn-default">Nouvel utilisateur <span class="glyphicon glyphicon-plus"></span></a><div>{input}</div>{hint}', | |||
]) | |||
->dropDownList( | |||
ArrayHelper::map($usersArray, 'user_id', function ($model) { | |||
if(isset($model['name_legal_person']) && strlen($model['name_legal_person'])) { | |||
return 'Personne morale / '.$model['name_legal_person'] ; | |||
} | |||
else { | |||
return $model['lastname'] . ' ' . $model['name']; | |||
} | |||
}), | |||
[ | |||
'@change' => 'changeUser', | |||
'prompt' => '--', | |||
'v-model' => 'idUser', | |||
] | |||
); ?> | |||
<?php endif; ?> | |||
<?php if ($action == 'update'): ?> | |||
<?= $form->field($model, 'id_user', [ | |||
'template' => '{label} <div>{input}</div>' . $model->user->getUsername(), | |||
])->hiddenInput(); ?> | |||
<?php else: ?> | |||
<?php | |||
$usersArray = User::findBy()->orderBy('type DESC, name_legal_person ASC, lastname ASC, name ASC')->all(); | |||
?> | |||
<?= $form->field($model, 'id_user', [ | |||
'template' => '{label} <a href="' . Yii::$app->urlManager->createUrl(['user/create']) . '" class="btn btn-xs btn-default">Nouvel utilisateur <span class="glyphicon glyphicon-plus"></span></a><div>{input}</div>{hint}', | |||
]) | |||
->dropDownList( | |||
ArrayHelper::map($usersArray, 'user_id', function ($model) { | |||
if (isset($model['name_legal_person']) && strlen($model['name_legal_person'])) { | |||
return 'Personne morale / ' . $model['name_legal_person']; | |||
} else { | |||
return $model['lastname'] . ' ' . $model['name']; | |||
} | |||
}), | |||
[ | |||
'@change' => 'changeUser', | |||
'prompt' => '--', | |||
'v-model' => 'idUser', | |||
] | |||
); ?> | |||
<?php endif; ?> | |||
<?= $form->field($model, 'address')->textarea(['rows' => 2, 'v-model' => 'document.address']) ?> | |||
<?php if ($action == 'update'): ?> | |||
<?= $form->field($model, 'comment')->textarea(['rows' => 2])->hint('Affiché en bas de la facture') ?> | |||
<?php endif; ?> | |||
<?= $form->field($model, 'address')->textarea(['rows' => 2, 'v-model' => 'document.address']) ?> | |||
<?php if ($action == 'update'): ?> | |||
<?= $form->field($model, 'comment')->textarea(['rows' => 2])->hint('Affiché en bas de la facture') ?> | |||
<?php endif; ?> | |||
<?php if($model->getClass() == 'Invoice'): ?> | |||
<template v-if="idUser > 0"> | |||
<strong>Bons de livraison</strong> | |||
<table v-if="deliveryNotes && deliveryNotes.length > 0" class="table table-bordered"> | |||
<thead> | |||
<tr> | |||
<?php if($action == 'create'): ?><th></th><?php endif; ?> | |||
<th>Libellé</th> | |||
<th v-if="taxRateProducer != 0">Montant (TTC)</th> | |||
<th v-else>Montant</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr v-for="deliveryNote in deliveryNotes"> | |||
<?php if($action == 'create'): ?> | |||
<td><input type="checkbox" name="Invoice[deliveryNotes][]" :value="deliveryNote.id" /></td> | |||
<?php endif; ?> | |||
<td>{{ deliveryNote.name }}</td> | |||
<td>{{ formatPrice(deliveryNote.total) }}</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
<div v-else class="alert alert-warning">Aucun bon de livraison pour cet utilisateur.</div> | |||
</template> | |||
<?php if ($model->getClass() == 'Invoice'): ?> | |||
<template v-if="idUser > 0"> | |||
<strong>Bons de livraison</strong> | |||
<table v-if="deliveryNotes && deliveryNotes.length > 0" class="table table-bordered"> | |||
<thead> | |||
<tr> | |||
<?php if ($action == 'create'): ?> | |||
<th></th><?php endif; ?> | |||
<th>Libellé</th> | |||
<th v-if="taxRateProducer != 0">Montant (TTC)</th> | |||
<th v-else>Montant</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr v-for="deliveryNote in deliveryNotes"> | |||
<?php if ($action == 'create'): ?> | |||
<td><input type="checkbox" name="Invoice[deliveryNotes][]" | |||
:value="deliveryNote.id"/></td> | |||
<?php endif; ?> | |||
<td>{{ deliveryNote.name }}</td> | |||
<td>{{ formatPrice(deliveryNote.total) }}</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
<div v-else class="alert alert-warning">Aucun bon de livraison pour cet utilisateur.</div> | |||
</template> | |||
<?php endif; ?> | |||
<div class="form-group"> | |||
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => 'btn btn-primary']) ?> | |||
</div> | |||
<?php ActiveForm::end(); ?> | |||
</div> | |||
<div class="form-group"> | |||
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => 'btn btn-primary']) ?> | |||
</div> | |||
<?php ActiveForm::end(); ?> | |||
</div> | |||
</div> | |||
</div> | |||
<?php if ($action == 'update'): ?> | |||
<?php if ($action == 'update'): ?> | |||
<div class="col-md-6"> | |||
<div id="" class="info-box"> | |||
<span class="info-box-icon bg-green"><i class="fa fa-sticky-note-o"></i></span> | |||
<div class="info-box-content"> | |||
<span class="info-box-text"><?= $typeDocument ?> <span v-html="document.html_label"></span></span> | |||
<span class="info-box-number">{{ document.reference }}</span> | |||
<span class="info-box-text">Date</span> | |||
<span class="info-box-number">{{ document.date }}</span> | |||
</div> | |||
</div> | |||
<div id="" class="info-box"> | |||
<span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span> | |||
<div class="info-box-content"> | |||
<span class="info-box-text">Total<span v-if="taxRateProducer != 0"> (TTC)</span></span> | |||
<span class="info-box-number">{{ formatPrice(total_with_tax) }}</span> | |||
</div> | |||
</div> | |||
<div id="" class="info-box"> | |||
<span class="info-box-icon bg-blue"><i class="fa fa-download"></i></span> | |||
<div class="info-box-content"> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl().'/download', 'id' => $model->id]) ?>" class="btn btn-default"><span class="glyphicon glyphicon-download-alt"></span> Télécharger (PDF)</a> | |||
<?php if($model->getClass() == 'Invoice' && Producer::getConfig('option_export_evoliz')): ?> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl().'/export-csv-evoliz', 'id' => $model->id]) ?>" class="btn btn-default"><span class="glyphicon glyphicon-save-file"></span> Export Evoliz (CSV)</a> | |||
<?php endif; ?> | |||
</div> | |||
</div> | |||
<div v-if="document.status == 'draft'" id="" class="info-box"> | |||
<span class="info-box-icon bg-red"><i class="fa fa-flash"></i></span> | |||
<div class="info-box-content"> | |||
<form action="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl().'/validate']) ?>"> | |||
<?= Html::hiddenInput('id', $model->id); ?> | |||
<button class="btn btn-default"><span class="glyphicon glyphicon-ok"></span> Valider le document</button> | |||
</form> | |||
<?php if(isset($model->user) && strlen($model->user->email) > 0): ?> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl().'/send', 'id' => $model->id]) ?>" class="btn btn-default"><span class="glyphicon glyphicon-send"></span> Envoyer le document</a> | |||
<?php endif; ?> | |||
</div> | |||
</div> | |||
<div class="col-md-6"> | |||
<div id="" class="info-box"> | |||
<span class="info-box-icon bg-green"><i class="fa fa-sticky-note-o"></i></span> | |||
<div class="info-box-content"> | |||
<span class="info-box-text"><?= $typeDocument ?> <span v-html="document.html_label"></span></span> | |||
<span class="info-box-number">{{ document.reference }}</span> | |||
<span class="info-box-text">Date</span> | |||
<span class="info-box-number">{{ document.date }}</span> | |||
</div> | |||
</div> | |||
<div id="" class="info-box"> | |||
<span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span> | |||
<div class="info-box-content"> | |||
<span class="info-box-text">Total<span v-if="taxRateProducer != 0"> (TTC)</span></span> | |||
<span class="info-box-number">{{ formatPrice(total_with_tax) }}</span> | |||
</div> | |||
</div> | |||
<div id="" class="info-box"> | |||
<span class="info-box-icon bg-blue"><i class="fa fa-download"></i></span> | |||
<div class="info-box-content"> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/download', 'id' => $model->id]) ?>" | |||
class="btn btn-default"><span class="glyphicon glyphicon-download-alt"></span> Télécharger (PDF)</a> | |||
<?php if ($model->getClass() == 'Invoice' && Producer::getConfig('option_export_evoliz')): ?> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/export-csv-evoliz', 'id' => $model->id]) ?>" | |||
class="btn btn-default"><span class="glyphicon glyphicon-save-file"></span> Export Evoliz | |||
(CSV)</a> | |||
<?php endif; ?> | |||
</div> | |||
<div class="clr"></div> | |||
</div> | |||
<div v-if="document.status == 'draft'" id="" class="info-box"> | |||
<span class="info-box-icon bg-red"><i class="fa fa-flash"></i></span> | |||
<div class="info-box-content"> | |||
<form action="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/validate']) ?>"> | |||
<?= Html::hiddenInput('id', $model->id); ?> | |||
<button class="btn btn-default"><span class="glyphicon glyphicon-ok"></span> Valider le document | |||
</button> | |||
</form> | |||
<?php if (isset($model->user) && strlen($model->user->email) > 0): ?> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/send', 'id' => $model->id]) ?>" | |||
class="btn btn-default"><span class="glyphicon glyphicon-send"></span> Envoyer le | |||
document</a> | |||
<?php endif; ?> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="clr"></div> | |||
<div class=""> | |||
<div class="panel panel-default" id="block-add-product"> | |||
<div class="panel-heading"> | |||
Ajouter un produit | |||
</div> | |||
<div class="panel-body"> | |||
<div class="col-md-6"> | |||
<strong>Produit</strong> | |||
<select class="form-control" v-model="productAddId" | |||
@change="changeProductAdd"> | |||
<option value="0" selected="selected">--</option> | |||
<option v-for="product in productsArray" :value="product.id"> | |||
{{ product.name }} | |||
</option> | |||
</select> | |||
</div> | |||
<template v-if="productAddId > 0"> | |||
<div class="col-md-3"> | |||
<strong>Prix unitaire</strong> | |||
<div class="input-group"> | |||
<input type="text" class="form-control input-price" | |||
v-model="productAddPrice" @change="formatProductAddPrice"/> | |||
<span class="input-group-addon"><span | |||
class="glyphicon glyphicon-euro"></span> <span v-if="taxRateProducer != 0">HT</span></span> | |||
</div> | |||
</div> | |||
<div class="col-md-3 total"> | |||
<strong>Quantité</strong> | |||
<div class="input-group input-group-quantity"> | |||
<div class=""> | |||
<div class="panel panel-default" id="block-add-product"> | |||
<div class="panel-heading"> | |||
Ajouter un produit | |||
</div> | |||
<div class="panel-body"> | |||
<div class="col-md-6"> | |||
<strong>Produit</strong> | |||
<select class="form-control" v-model="productAddId" | |||
@change="changeProductAdd"> | |||
<option value="0" selected="selected">--</option> | |||
<option v-for="product in productsArray" :value="product.id"> | |||
{{ product.name }} | |||
</option> | |||
</select> | |||
</div> | |||
<template v-if="productAddId > 0"> | |||
<div class="col-md-3"> | |||
<strong>Prix unitaire</strong> | |||
<div class="input-group"> | |||
<input type="text" class="form-control input-price" | |||
v-model="productAddPrice" @change="formatProductAddPrice"/> | |||
<span class="input-group-addon"><span | |||
class="glyphicon glyphicon-euro"></span> <span v-if="taxRateProducer != 0">HT</span></span> | |||
</div> | |||
</div> | |||
<div class="col-md-3 total"> | |||
<strong>Quantité</strong> | |||
<div class="input-group input-group-quantity"> | |||
<span class="input-group-btn"> | |||
<button class="btn btn-default" type="button" | |||
@click="changeQuantityProductAdd(-1)">-</button> | |||
</span> | |||
<input type="text" class="form-control input-quantity" | |||
v-model="productAddQuantity" @change="formatProductAddQuantity"/> | |||
<span class="input-group-addon">{{ getProductById(productAddId).wording_unit }}</span> | |||
<span class="input-group-btn"> | |||
<input type="text" class="form-control input-quantity" | |||
v-model="productAddQuantity" @change="formatProductAddQuantity"/> | |||
<span class="input-group-addon">{{ getProductById(productAddId).wording_unit }}</span> | |||
<span class="input-group-btn"> | |||
<button class="btn btn-default" | |||
type="button" | |||
@click="changeQuantityProductAdd(1)">+</button> | |||
</span> | |||
</div> | |||
<button class="btn btn-primary" value="Ajouter" | |||
@click="submitProductAdd">Ajouter | |||
</button> | |||
<div class="clr"></div> | |||
</div> | |||
<!--<div class="col-md-3 total"> | |||
<strong>Total</strong> | |||
<div class="input-group"> | |||
<input type="text" class="form-control input-price" readonly | |||
:value="formatPrice(productAddPrice * productAddQuantity)"/> | |||
<span class="input-group-addon"><span | |||
class="glyphicon glyphicon-euro"></span> <span v-if="taxRateProducer != 0">HT</span></span> | |||
</div> | |||
</div>--> | |||
</template> | |||
<div class="clr"></div> | |||
</div> | |||
</div> | |||
<button class="btn btn-primary" value="Ajouter" | |||
@click="submitProductAdd">Ajouter | |||
</button> | |||
<div class="clr"></div> | |||
</div> | |||
<div class="panel panel-default"> | |||
<div class="panel-heading"> | |||
Produits | |||
<!--<div class="col-md-3 total"> | |||
<strong>Total</strong> | |||
<div class="input-group"> | |||
<input type="text" class="form-control input-price" readonly | |||
:value="formatPrice(productAddPrice * productAddQuantity)"/> | |||
<span class="input-group-addon"><span | |||
class="glyphicon glyphicon-euro"></span> <span v-if="taxRateProducer != 0">HT</span></span> | |||
</div> | |||
<div class="panel-body"> | |||
<div id="block-list-products"> | |||
<table class="table table-bordered" v-if="total > 0"> | |||
<thead> | |||
<tr> | |||
<th>Nom</th> | |||
<th>Prix (unité)</th> | |||
<th>Quantité</th> | |||
<th v-if="taxRateProducer != 0">TVA</th> | |||
<th v-if="taxRateProducer != 0">Total HT</th> | |||
<th v-else>Total</th> | |||
<th>Supprimer</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<template v-for="order in ordersArray"> | |||
<tr v-for="productOrder in order.productOrder"> | |||
<td class="col-md-4"> | |||
<div class="product-name">{{ getProductById(productOrder.id_product).name }}</div> | |||
<ul class="product-order-meta"> | |||
<li>{{ order.username }}</li> | |||
<li v-if="order.distribution_date">{{ order.distribution_date }}</li> | |||
<li v-if="order.point_sale_name">{{ order.point_sale_name }}</li> | |||
</ul> | |||
</td> | |||
<td class="col-md-2"> | |||
{{ formatPrice(getProductOrderPrice(productOrder)) }} | |||
</td> | |||
<td class="col-md-2">{{ productOrder.quantity }}</td> | |||
<td class="col-md-1" v-if="taxRateProducer != 0"> | |||
{{ getProductById(productOrder.id_product).tax_rate * 100 }} % | |||
</td> | |||
<td class="col-md-2"> | |||
{{ formatPrice(productOrder.quantity * getProductOrderPrice(productOrder)) }} | |||
</td> | |||
<td class="col-md-1"> | |||
<a class="btn btn-default" @click="deleteProductOrder(productOrder.id)"> | |||
<span class="glyphicon glyphicon-trash"></span> | |||
</a> | |||
</td> | |||
</tr> | |||
</template> | |||
<template v-if="taxRateProducer != 0"> | |||
<tr> | |||
<td colspan="4"><strong>Total HT</strong></td> | |||
<td><strong>{{ formatPrice(total) }} HT</strong></td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td colspan="4"><strong>Montant TVA</strong></td> | |||
<td><strong>{{ formatPrice(total_with_tax - total) }}</strong></td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td colspan="4"><strong>Total TTC</strong></td> | |||
<td><strong>{{ formatPrice(total_with_tax) }} TTC</strong></td> | |||
<td></td> | |||
</tr> | |||
</template> | |||
<template v-else> | |||
<tr> | |||
<td colspan="3"><strong>Total</strong></td> | |||
<td><strong>{{ formatPrice(total) }}</strong></td> | |||
<td></td> | |||
</tr> | |||
</template> | |||
</tbody> | |||
</table> | |||
<div v-else class="alert alert-info"> | |||
Aucun produit. | |||
</div> | |||
</div>--> | |||
</template> | |||
<div class="clr"></div> | |||
</div> | |||
</div> | |||
<div class="panel panel-default"> | |||
<div class="panel-heading"> | |||
Produits | |||
</div> | |||
<div class="panel-body"> | |||
<div id="block-list-products"> | |||
<table class="table table-bordered" v-if="total > 0"> | |||
<thead> | |||
<tr> | |||
<th>Nom</th> | |||
<th>Prix (unité)</th> | |||
<th>Quantité</th> | |||
<th v-if="taxRateProducer != 0">TVA</th> | |||
<th v-if="taxRateProducer != 0">Total HT</th> | |||
<th v-else>Total</th> | |||
<th>Supprimer</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<template v-for="order in ordersArray"> | |||
<tr v-for="productOrder in order.productOrder"> | |||
<td class="col-md-4"> | |||
<div class="product-name">{{ getProductById(productOrder.id_product).name }} | |||
</div> | |||
</div> | |||
<ul class="product-order-meta"> | |||
<li>{{ order.username }}</li> | |||
<li v-if="order.distribution_date">{{ order.distribution_date }}</li> | |||
<li v-if="order.point_sale_name">{{ order.point_sale_name }}</li> | |||
</ul> | |||
</td> | |||
<td class="col-md-2"> | |||
{{ formatPrice(getProductOrderPrice(productOrder)) }} | |||
<template v-if="document.status == 'draft' && getProductOrderPrice(productOrder) != getBestProductPrice(productOrder.id_product, productOrder.quantity)"> | |||
<i class="fa fa-exclamation-triangle" title="Prix différent de celui défini au niveau du produit"></i> | |||
</template> | |||
</td> | |||
<td class="col-md-2">{{ productOrder.quantity }}</td> | |||
<td class="col-md-1" v-if="taxRateProducer != 0"> | |||
{{ getProductById(productOrder.id_product).tax_rate * 100 }} % | |||
</td> | |||
<td class="col-md-2"> | |||
{{ formatPrice(productOrder.quantity * getProductOrderPrice(productOrder)) }} | |||
</td> | |||
<td class="col-md-1"> | |||
<a class="btn btn-default" @click="deleteProductOrder(productOrder.id)"> | |||
<span class="glyphicon glyphicon-trash"></span> | |||
</a> | |||
</td> | |||
</tr> | |||
</template> | |||
<template v-if="taxRateProducer != 0"> | |||
<tr> | |||
<td colspan="4"><strong>Total HT</strong></td> | |||
<td><strong>{{ formatPrice(total) }} HT</strong></td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td colspan="4"><strong>Montant TVA</strong></td> | |||
<td><strong>{{ formatPrice(total_with_tax - total) }}</strong></td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td colspan="4"><strong>Total TTC</strong></td> | |||
<td><strong>{{ formatPrice(total_with_tax) }} TTC</strong></td> | |||
<td></td> | |||
</tr> | |||
</template> | |||
<template v-else> | |||
<tr> | |||
<td colspan="3"><strong>Total</strong></td> | |||
<td><strong>{{ formatPrice(total) }}</strong></td> | |||
<td></td> | |||
</tr> | |||
</template> | |||
</tbody> | |||
</table> | |||
<div v-else class="alert alert-info"> | |||
Aucun produit. | |||
</div> | |||
</div> | |||
</div> | |||
<?php endif; ?> | |||
</div> | |||
</div> | |||
<?php endif; ?> | |||
</div> |
@@ -1,182 +1,186 @@ | |||
<?php | |||
$displayPrices = Yii::$app->controller->getClass() != 'DeliveryNote' || (Yii::$app->controller->getClass() == 'DeliveryNote' && Producer::getConfig('document_display_prices_delivery_note')) ; | |||
$displayPrices = Yii::$app->controller->getClass() != 'DeliveryNote' || (Yii::$app->controller->getClass() == 'DeliveryNote' && Producer::getConfig('document_display_prices_delivery_note')); | |||
$displayProductDescription = Producer::getConfig('document_display_product_description'); | |||
?> | |||
<div class="document-download"> | |||
<div id="block-addresses"> | |||
<div class="producer"> | |||
<?php if(strlen($producer->logo)) : ?> | |||
<div class="logo"> | |||
<img style="max-height: 80px;" src="<?= $producer->getUrlLogo() ?>" /> | |||
</div> | |||
<?php endif; ?> | |||
<div class="address"><?= $producer->getFullAddress(true) ; ?></div> | |||
</div> | |||
<div class="user"> | |||
<?php if($document->address && strlen($document->address) > 0): ?> | |||
<?= nl2br($document->address) ?> | |||
<?php else: ?> | |||
<?= $document->user->getFullAddress(true) ; ?> | |||
<?php endif; ?> | |||
<div id="block-addresses"> | |||
<div class="producer"> | |||
<?php if (strlen($producer->logo)) : ?> | |||
<div class="logo"> | |||
<img style="max-height: 80px;" src="<?= $producer->getUrlLogo() ?>"/> | |||
</div> | |||
<?php endif; ?> | |||
<div class="address"><?= $producer->getFullAddress(true); ?></div> | |||
</div> | |||
<div id="block-infos-document"> | |||
<div class="date"> | |||
Le <?= strftime('%d %B %Y', strtotime($document->date)) ?> | |||
</div> | |||
<div class="reference"> | |||
<?php if(strlen($document->reference)) : ?> | |||
<?= $document->getType(); ?> N°<?= $document->reference ; ?> | |||
<?php else: ?> | |||
<div class="block-is-draft"><?= $document->getType(); ?> non validé<?= ($document->getType() == 'Facture') ? 'e' : '' ?></div> | |||
<?php endif; ?> | |||
</div> | |||
<div class="name"> | |||
<strong>Libellé : </strong><?= $document->name ; ?> | |||
</div> | |||
<div class="user"> | |||
<?php if ($document->address && strlen($document->address) > 0): ?> | |||
<?= nl2br($document->address) ?> | |||
<?php else: ?> | |||
<?= $document->user->getFullAddress(true); ?> | |||
<?php endif; ?> | |||
</div> | |||
</div> | |||
<?php if(strlen($document->comment)): ?> | |||
<div class="block-infos"> | |||
<strong>Commentaire</strong><br /> | |||
<?= Html::encode($document->comment) ?> | |||
</div> | |||
<?php endif; ?> | |||
<div id="block-products"> | |||
<?php if(count($document->orders) > 0) : ?> | |||
<table class="table table-bordered"> | |||
<thead> | |||
<tr> | |||
<th class="align-left">Produit</th> | |||
<?php if($displayPrices): ?> | |||
<?php if(GlobalParam::getCurrentProducer()->taxRate->value == 0): ?> | |||
<th>Prix unitaire</th> | |||
<?php else: ?> | |||
<th>Prix unitaire HT</th> | |||
<?php endif; ?> | |||
<?php endif; ?> | |||
<th>Quantité</th> | |||
<th>Unité</th> | |||
<?php if($displayPrices): ?> | |||
<?php if(GlobalParam::getCurrentProducer()->taxRate->value == 0): ?> | |||
<th>Prix</th> | |||
<?php else: ?> | |||
<th>TVA</th> | |||
<th>Prix HT</th> | |||
<?php endif; ?> | |||
<?php endif; ?> | |||
<div id="block-infos-document"> | |||
<div class="date"> | |||
Le <?= strftime('%d %B %Y', strtotime($document->date)) ?> | |||
</div> | |||
<div class="reference"> | |||
<?php if (strlen($document->reference)) : ?> | |||
<?= $document->getType(); ?> N°<?= $document->reference; ?> | |||
<?php else: ?> | |||
<div class="block-is-draft"><?= $document->getType(); ?> non | |||
validé<?= ($document->getType() == 'Facture') ? 'e' : '' ?></div> | |||
<?php endif; ?> | |||
</div> | |||
<div class="name"> | |||
<strong>Libellé : </strong><?= $document->name; ?> | |||
</div> | |||
</div> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<?php if (strlen($document->comment)): ?> | |||
<div class="block-infos"> | |||
<strong>Commentaire</strong><br/> | |||
<?= Html::encode($document->comment) ?> | |||
</div> | |||
<?php endif; ?> | |||
<?php if($document->isDisplayOrders()): ?> | |||
<?php foreach($document->orders as $order): ?> | |||
<tr> | |||
<td> | |||
<strong><?= Html::encode($order->getUsername()) ; ?></strong> | |||
<?php if($order->distribution): ?> | |||
le <?= date('d/m/Y', strtotime($order->distribution->date)) ?> | |||
<?php endif; ?> | |||
</td> | |||
<?php if($displayPrices): ?> | |||
<td class="align-center"></td> | |||
<?php endif; ?> | |||
<td></td> | |||
<td></td> | |||
<?php if($displayPrices): ?> | |||
<?php if(GlobalParam::getCurrentProducer()->taxRate->value != 0): ?> | |||
<td class="align-center"></td> | |||
<?php endif; ?> | |||
<td class="align-center"></td> | |||
<?php endif; ?> | |||
</tr> | |||
<?php foreach($order->productOrder as $productOrder): ?> | |||
<?= $this->render('_download_product_line', [ | |||
'document' => $document, | |||
'productOrder' => $productOrder, | |||
'displayOrders' => true, | |||
'displayPrices' => $displayPrices, | |||
'displayProductDescription' => $displayProductDescription | |||
]) ?> | |||
<?php endforeach; ?> | |||
<?php endforeach; ?> | |||
<div id="block-products"> | |||
<?php if (count($document->orders) > 0) : ?> | |||
<table class="table table-bordered"> | |||
<thead> | |||
<tr> | |||
<th class="align-left">Produit</th> | |||
<?php if ($displayPrices): ?> | |||
<?php if ($producer->taxRate->value == 0): ?> | |||
<th>Prix unitaire</th> | |||
<?php else: ?> | |||
<?php foreach($document->getProductsOrders() as $product): ?> | |||
<?php foreach($product as $productOrder): ?> | |||
<?= $this->render('_download_product_line', [ | |||
'document' => $document, | |||
'productOrder' => $productOrder, | |||
'displayPrices' => $displayPrices, | |||
'displayProductDescription' => $displayProductDescription | |||
]) ?> | |||
<?php endforeach; ?> | |||
<?php endforeach; ?> | |||
<th>Prix unitaire HT</th> | |||
<?php endif; ?> | |||
<?php if($displayPrices): ?> | |||
<?php $typeAmount = $document->isInvoicePrice() ? Order::INVOICE_AMOUNT_TOTAL : Order::AMOUNT_TOTAL ; ?> | |||
<?php endif; ?> | |||
<th>Quantité</th> | |||
<th>Unité</th> | |||
<?php if ($displayPrices): ?> | |||
<?php if ($producer->taxRate->value == 0): ?> | |||
<th>Prix</th> | |||
<?php else: ?> | |||
<th>TVA</th> | |||
<th>Prix HT</th> | |||
<?php endif; ?> | |||
<?php endif; ?> | |||
<?php if(GlobalParam::getCurrentProducer()->taxRate->value != 0): ?> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr> | |||
<td class="align-right" colspan="5"><strong>Total HT</strong></td> | |||
<td class="align-center"> | |||
<?= Price::format($document->getAmount($typeAmount)); ?> | |||
</td> | |||
</tr> | |||
<?php if ($document->isDisplayOrders()): ?> | |||
<?php foreach ($document->orders as $order): ?> | |||
<tr> | |||
<td> | |||
<strong><?= Html::encode($order->getUsername()); ?></strong> | |||
<?php if ($order->distribution): ?> | |||
le <?= date('d/m/Y', strtotime($order->distribution->date)) ?> | |||
<?php endif; ?> | |||
</td> | |||
<?php if ($displayPrices): ?> | |||
<td class="align-center"></td> | |||
<?php endif; ?> | |||
<td></td> | |||
<td></td> | |||
<?php if ($displayPrices): ?> | |||
<?php if ($producer->taxRate->value != 0): ?> | |||
<td class="align-center"></td> | |||
<?php endif; ?> | |||
<td class="align-center"></td> | |||
<?php endif; ?> | |||
</tr> | |||
<?php foreach ($order->productOrder as $productOrder): ?> | |||
<?= $this->render('_download_product_line', [ | |||
'producer' => $producer, | |||
'document' => $document, | |||
'productOrder' => $productOrder, | |||
'displayOrders' => true, | |||
'displayPrices' => $displayPrices, | |||
'displayProductDescription' => $displayProductDescription | |||
]) ?> | |||
<?php endforeach; ?> | |||
<?php endforeach; ?> | |||
<?php else: ?> | |||
<?php foreach ($document->getProductsOrders() as $product): ?> | |||
<?php foreach ($product as $productOrder): ?> | |||
<?= $this->render('_download_product_line', [ | |||
'producer' => $producer, | |||
'document' => $document, | |||
'productOrder' => $productOrder, | |||
'displayPrices' => $displayPrices, | |||
'displayProductDescription' => $displayProductDescription | |||
]) ?> | |||
<?php endforeach; ?> | |||
<?php endforeach; ?> | |||
<?php endif; ?> | |||
<?php if ($displayPrices): ?> | |||
<?php $typeAmount = $document->isInvoicePrice() ? Order::INVOICE_AMOUNT_TOTAL : Order::AMOUNT_TOTAL; ?> | |||
<?php | |||
$taxRateArray = TaxRate::getTaxRateArray(); | |||
foreach($document->getTotalVatArray($typeAmount) as $idTaxRate => $totalVat): ?> | |||
<tr> | |||
<td class="align-right" colspan="5"><strong>TVA <?= $taxRateArray[$idTaxRate]->value * 100 ?> %</strong></td> | |||
<td class="align-center"> | |||
<?= Price::format($totalVat); ?> | |||
</td> | |||
</tr> | |||
<?php endforeach; ?> | |||
<?php if ($producer->taxRate->value != 0): ?> | |||
<!--<tr> | |||
<tr> | |||
<td class="align-right" colspan="5"><strong>Total HT</strong></td> | |||
<td class="align-center"> | |||
<?= Price::format($document->getAmount($typeAmount)); ?> | |||
</td> | |||
</tr> | |||
<?php | |||
$taxRateArray = TaxRate::getTaxRateArray(); | |||
foreach ($document->getTotalVatArray($typeAmount) as $idTaxRate => $totalVat): ?> | |||
<tr> | |||
<td class="align-right" colspan="5"> | |||
<strong>TVA <?= $taxRateArray[$idTaxRate]->value * 100 ?> %</strong></td> | |||
<td class="align-center"> | |||
<?= Price::format($totalVat); ?> | |||
</td> | |||
</tr> | |||
<?php endforeach; ?> | |||
<!--<tr> | |||
<td class="align-right" colspan="5"><strong>TVA</strong></td> | |||
<td class="align-center"> | |||
<?= Price::format($document->getAmountWithTax($typeAmount) - $document->getAmount($typeAmount)) ?> | |||
</td> | |||
</tr>--> | |||
<tr> | |||
<td class="align-right" colspan="5"><strong>Total TTC</strong></td> | |||
<td class="align-center"><?= Price::format($document->getAmountWithTax($typeAmount)) ?></td> | |||
</tr> | |||
<?php else: ?> | |||
<tr> | |||
<td class="align-right" colspan="4"> | |||
<strong>Total</strong><br /> | |||
TVA non applicable | |||
</td> | |||
<td class="align-center"><?= Price::format($document->getAmount($typeAmount)) ?></td> | |||
</tr> | |||
<?php endif; ?> | |||
<?php endif; ?> | |||
</tbody> | |||
</table> | |||
<?php else : ?> | |||
<div id="block-no-product"> | |||
<strong>Aucun produit</strong> | |||
</div> | |||
<tr> | |||
<td class="align-right" colspan="5"><strong>Total TTC</strong></td> | |||
<td class="align-center"><?= Price::format($document->getAmountWithTax($typeAmount)) ?></td> | |||
</tr> | |||
<?php else: ?> | |||
<tr> | |||
<td class="align-right" colspan="4"> | |||
<strong>Total</strong><br/> | |||
TVA non applicable | |||
</td> | |||
<td class="align-center"><?= Price::format($document->getAmount($typeAmount)) ?></td> | |||
</tr> | |||
<?php endif; ?> | |||
<?php endif; ?> | |||
</div> | |||
</tbody> | |||
</table> | |||
<?php else : ?> | |||
<div id="block-no-product"> | |||
<strong>Aucun produit</strong> | |||
</div> | |||
<?php endif; ?> | |||
</div> | |||
<?php | |||
$fieldProducerDocumentInfo = 'document_infos_'.str_replace('deliverynote','delivery_note',strtolower($document->getClass())) ; ?> | |||
<?php if(strlen($producer->$fieldProducerDocumentInfo)): ?> | |||
<?php | |||
$fieldProducerDocumentInfo = 'document_infos_' . str_replace('deliverynote', 'delivery_note', strtolower($document->getClass())); ?> | |||
<?php if (strlen($producer->$fieldProducerDocumentInfo)): ?> | |||
<div class="block-infos"> | |||
<strong>Informations</strong><br /> | |||
<?= nl2br(Html::encode($producer->$fieldProducerDocumentInfo)) ?> | |||
<strong>Informations</strong><br/> | |||
<?= nl2br(Html::encode($producer->$fieldProducerDocumentInfo)) ?> | |||
</div> | |||
<?php endif; ?> | |||
<?php endif; ?> | |||
</div> |
@@ -79,7 +79,7 @@ $this->addButton(['label' => 'Nouvelle facture <span class="glyphicon glyphicon- | |||
], | |||
'name', | |||
[ | |||
'attribute' => 'id_user', | |||
'attribute' => 'username', | |||
'header' => 'Utilisateur', | |||
'value' => function($model) { | |||
return $model->user->getUsername() ; | |||
@@ -99,6 +99,19 @@ $this->addButton(['label' => 'Nouvelle facture <span class="glyphicon glyphicon- | |||
return $invoice->getAmountWithTax(Order::INVOICE_AMOUNT_TOTAL, true) ; | |||
} | |||
], | |||
[ | |||
'attribute' => 'is_sent', | |||
'header' => 'Envoyé', | |||
'format' => 'raw', | |||
'value' => function($model) { | |||
if($model->is_sent) { | |||
return '<span class="label label-success">Oui</span>'; | |||
} | |||
else { | |||
return '<span class="label label-danger">Non</span>'; | |||
} | |||
} | |||
], | |||
[ | |||
'class' => 'yii\grid\ActionColumn', | |||
'template' => '{validate} {update} {delete} {send} {download} {export-csv-evoliz}', |
@@ -83,10 +83,14 @@ use dmstr\widgets\Alert; | |||
<footer class="main-footer"> | |||
<div class="pull-right hidden-xs"> | |||
<strong>Version</strong> <?= GlobalParam::getOpendistribVersion(); ?> | |||
</div> | |||
<br /> | |||
<!--<div class="pull-right hidden-xs"> | |||
<b>Version</b> 2.0 | |||
</div> | |||
<strong>Copyright © 2014-2015 <a href="http://almsaeedstudio.com">Almsaeed Studio</a>.</strong> All rights | |||
reserved. | |||
reserved.--> | |||
</footer> | |||
<!-- Control Sidebar --> |
@@ -198,7 +198,7 @@ $producer = GlobalParam::getCurrentProducer(); | |||
<?php foreach ($usersNegativeCreditArray as $user): ?> | |||
<li> | |||
<a href="<?= Yii::$app->urlManagerBackend->createUrl(['user/credit', 'id' => $user['user_id']]); ?>"> | |||
<h5><?= Html::encode($user['name'] . ' ' . $user['lastname']); ?> | |||
<h5><?= User::getUsernameFromArray($user); ?> | |||
<small> | |||
<i class="fa fa-euro"></i> <?= Price::format($user['credit']); ?> | |||
</small> |
@@ -1,40 +1,40 @@ | |||
<?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. | |||
*/ | |||
?> | |||
@@ -42,65 +42,80 @@ termes. | |||
<section class="sidebar"> | |||
<?php | |||
$producer = GlobalParam::getCurrentProducer(); | |||
$newVersionOpendistribTemplate = ''; | |||
if($producer->latest_version_opendistrib != GlobalParam::getOpendistribVersion()) { | |||
$newVersionOpendistribTemplate = '<span class="pull-right-container"><small class="label pull-right bg-orange"> </small></span>'; | |||
} | |||
?> | |||
<?= dmstr\widgets\Menu::widget( | |||
[ | |||
'options' => ['class' => 'sidebar-menu tree', 'data-widget'=> 'tree'], | |||
'options' => ['class' => 'sidebar-menu tree', 'data-widget' => 'tree'], | |||
'items' => [ | |||
['label' => 'Tableau de bord','icon' => 'dashboard','url' => ['/site/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Distributions','icon' => 'calendar','url' => ['/distribution/index'], 'visible' => User::isCurrentProducer()], | |||
[ | |||
'label' => 'Produits', | |||
'icon' => 'clone', | |||
'url' => '#', | |||
'visible' => User::isCurrentProducer(), | |||
'active' => Yii::$app->controller->id == 'product', | |||
'items' => [ | |||
['label' => 'Liste','icon' => 'th-list','url' => ['/product/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Catégories','icon' => 'book','url' => ['/product-category/index'], 'visible' => User::isCurrentProducer()], | |||
] | |||
], | |||
['label' => 'Points de vente','icon' => 'map-marker','url' => ['/point-sale/index'], 'visible' => User::isCurrentProducer(), 'active' => Yii::$app->controller->id == 'point-sale'], | |||
['label' => 'Tableau de bord', 'icon' => 'dashboard', 'url' => ['/site/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Distributions', 'icon' => 'calendar', 'url' => ['/distribution/index'], 'visible' => User::isCurrentProducer()], | |||
[ | |||
'label' => 'Utilisateurs', | |||
'icon' => 'users', | |||
'url' => '#', | |||
'items' => [ | |||
['label' => 'Liste','icon' => 'th-list','url' => ['/user/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Groupes','icon' => 'users','url' => ['/user-group/index'], 'visible' => User::isCurrentProducer()], | |||
], | |||
'label' => 'Produits', | |||
'icon' => 'clone', | |||
'url' => ['/product/index'], | |||
'visible' => User::isCurrentProducer(), | |||
'active' => Yii::$app->controller->id == 'product', | |||
'items' => [ | |||
['label' => 'Liste', 'icon' => 'th-list', 'url' => ['/product/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Catégories', 'icon' => 'book', 'url' => ['/product-category/index'], 'visible' => User::isCurrentProducer()], | |||
] | |||
], | |||
['label' => 'Abonnements','icon' => 'repeat','url' => ['/subscription/index'], 'visible' => User::isCurrentProducer(), 'active' => Yii::$app->controller->id == 'subscription'], | |||
['label' => 'Paramètres','icon' => 'cog','url' => ['/producer/update'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Communiquer','icon' => 'bullhorn','url' => ['/communicate/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Points de vente', 'icon' => 'map-marker', 'url' => ['/point-sale/index'], 'visible' => User::isCurrentProducer(), 'active' => Yii::$app->controller->id == 'point-sale'], | |||
[ | |||
'label' => 'Statistiques', | |||
'icon' => 'line-chart', | |||
'url' => '#', | |||
'label' => 'Utilisateurs', | |||
'icon' => 'users', | |||
'url' => ['/user/index'], | |||
'items' => [ | |||
['label' => 'Rapports','icon' => 'pencil-square-o','url' => ['/report/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Chiffre d\'affaire','icon' => 'line-chart','url' => ['/stats/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Produits','icon' => 'table','url' => ['/stats/products'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Liste', 'icon' => 'th-list', 'url' => ['/user/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Groupes', 'icon' => 'users', 'url' => ['/user-group/index'], 'visible' => User::isCurrentProducer()], | |||
], | |||
], | |||
['label' => 'Abonnements', 'icon' => 'repeat', 'url' => ['/subscription/index'], 'visible' => User::isCurrentProducer(), 'active' => Yii::$app->controller->id == 'subscription'], | |||
['label' => 'Communiquer', 'icon' => 'bullhorn', 'url' => ['/communicate/index'], 'visible' => User::isCurrentProducer()], | |||
[ | |||
'label' => 'Documents', | |||
'icon' => 'clone', | |||
'url' => '#', | |||
'url' => ['/delivery-note/index'], | |||
'items' => [ | |||
['label' => 'Devis','icon' => 'sticky-note-o','url' => ['/quotation/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Bons de livraison','icon' => 'sticky-note-o','url' => ['/delivery-note/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Factures','icon' => 'sticky-note-o','url' => ['/invoice/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Bons de livraison', 'icon' => 'sticky-note-o', 'url' => ['/delivery-note/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Factures', 'icon' => 'sticky-note-o', 'url' => ['/invoice/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Devis', 'icon' => 'sticky-note-o', 'url' => ['/quotation/index'], 'visible' => User::isCurrentProducer()], | |||
], | |||
], | |||
['label' => 'Développement','icon' => 'wrench','url' => ['/development/index'], 'visible' => User::isCurrentProducer(), 'active' => Yii::$app->controller->id == 'development'], | |||
['label' => 'Tarifs','icon' => 'euro','url' => ['/producer/billing'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Accès','icon' => 'lock','url' => ['/access/index'], 'visible' => User::isCurrentProducer()], | |||
[ | |||
'label' => 'Statistiques', | |||
'icon' => 'line-chart', | |||
'url' => ['/stats/index'], | |||
'items' => [ | |||
['label' => 'Chiffre d\'affaire', 'icon' => 'line-chart', 'url' => ['/stats/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Rapports', 'icon' => 'pencil-square-o', 'url' => ['/report/index'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Produits', 'icon' => 'table', 'url' => ['/stats/products'], 'visible' => User::isCurrentProducer()], | |||
], | |||
], | |||
['label' => 'Paramètres', 'icon' => 'cog', 'url' => ['/producer/update'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Accès', 'icon' => 'lock', 'url' => ['/access/index'], 'visible' => User::isCurrentProducer()], | |||
[ | |||
'label' => 'Développement', | |||
'icon' => 'code', | |||
'url' => ['/development/index'], | |||
'visible' => User::isCurrentProducer(), | |||
'active' => Yii::$app->controller->id == 'development', | |||
'template'=>'<a href="{url}">{icon} {label}'.$newVersionOpendistribTemplate.'</a>' | |||
], | |||
['label' => 'Tarifs', 'icon' => 'euro', 'url' => ['/producer/billing'], 'visible' => User::isCurrentProducer()], | |||
['label' => 'Administration', 'options' => ['class' => 'header'], 'visible' => User::isCurrentAdmin()], | |||
['label' => 'Producteurs','icon' => 'th-list','url' => ['/producer-admin/index'], 'visible' => User::isCurrentAdmin()], | |||
['label' => 'Tranches de prix','icon' => 'eur','url' => ['/producer-price-range-admin/index'], 'visible' => User::isCurrentAdmin()], | |||
['label' => 'Taxes','icon' => 'eur','url' => ['/tax-rate-admin/index'], 'visible' => User::isCurrentAdmin()], | |||
['label' => 'Communiquer','icon' => 'bullhorn','url' => ['/communicate-admin/index'], 'visible' => User::isCurrentAdmin()], | |||
['label' => 'Producteurs', 'icon' => 'th-list', 'url' => ['/producer-admin/index'], 'visible' => User::isCurrentAdmin()], | |||
['label' => 'Tranches de prix', 'icon' => 'eur', 'url' => ['/producer-price-range-admin/index'], 'visible' => User::isCurrentAdmin()], | |||
['label' => 'Taxes', 'icon' => 'eur', 'url' => ['/tax-rate-admin/index'], 'visible' => User::isCurrentAdmin()], | |||
['label' => 'Communiquer', 'icon' => 'bullhorn', 'url' => ['/communicate-admin/index'], 'visible' => User::isCurrentAdmin()], | |||
['label' => 'Outils', 'options' => ['class' => 'header'], 'visible' => User::isCurrentAdmin()], | |||
['label' => 'Gii', 'icon' => 'file-code-o', 'url' => ['/gii'], 'visible' => User::isCurrentAdmin()], |
@@ -69,7 +69,7 @@ if (Yii::$app->controller->action->id === 'login') { | |||
<meta name="baseurl" content="<?= Yii::$app->urlManagerBackend->baseUrl ; ?>"> | |||
<meta name="baseurl-absolute" content="<?= Yii::$app->urlManagerBackend->getHostInfo().Yii::$app->urlManagerBackend->baseUrl; ?>"> | |||
<?= Html::csrfMetaTags() ?> | |||
<title><?= Html::encode($this->title) ?> | distrib</title> | |||
<title><?= Html::encode($this->page_title) ?> | Opendistrib</title> | |||
<link rel="icon" type="image/png" href="<?php echo Yii::$app->urlManagerBackend->getBaseUrl(); ?>/img/favicon-distrib.png" /> | |||
<?php $this->head() ?> | |||
</head> |
@@ -1,340 +1,332 @@ | |||
<?php | |||
/** | |||
Copyright La boîte à pain (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 La boîte à pain (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\widgets\ActiveForm; | |||
use common\helpers\Url ; | |||
use common\models\Producer ; | |||
use common\helpers\Url; | |||
use common\models\Producer; | |||
\backend\assets\VuejsProducerUpdateAsset::register($this); | |||
$this->setTitle('Paramètres') ; | |||
$this->addBreadcrumb($this->getTitle()) ; | |||
$this->setTitle('Paramètres'); | |||
$this->addBreadcrumb($this->getTitle()); | |||
?> | |||
<script> | |||
var appInitValues = { | |||
isAdmin: <?= (int) User::isCurrentAdmin() ?> | |||
isAdmin: <?= (int)User::isCurrentAdmin() ?> | |||
}; | |||
</script> | |||
<div class="user-update" id="app-producer-update"> | |||
<div id="nav-params"> | |||
<button v-for="section in sectionsArray" v-if="!section.isAdminSection || (section.isAdminSection && isAdmin)" :class="'btn '+((currentSection == section.name) ? 'btn-primary' : 'btn-default')" @click="changeSection(section)"> | |||
<button v-for="section in sectionsArray" v-if="!section.isAdminSection || (section.isAdminSection && isAdmin)" | |||
:class="'btn '+((currentSection == section.name) ? 'btn-primary' : 'btn-default')" | |||
@click="changeSection(section)"> | |||
{{ section.nameDisplay }} | |||
<span class="glyphicon glyphicon-triangle-bottom"></span> | |||
</button> | |||
</div> | |||
<div class="user-form"> | |||
<?php $form = ActiveForm::begin([ | |||
'enableClientValidation' => false, | |||
]); ?> | |||
<div> | |||
<div v-show="currentSection == 'general'" class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title">Général</h3> | |||
</div> | |||
<div class="panel-body"> | |||
<h4>Accès</h4> | |||
<?= $form->field($model, 'active') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []) | |||
->label('En ligne') | |||
->hint('Activez cette option pour rendre votre établissement visible à vos clients.') ; ?> | |||
->hint('Activez cette option pour rendre votre espace visible à vos clients.'); ?> | |||
<?= $form->field($model, 'code')->hint("Saisissez ce champs si vous souhaitez protéger l'accès à votre espace par un code, sinon laissez-le vide.<br />" | |||
. "Ce code est à communiquer à vos clients pour qu'ils puissent ajouter votre espace à leurs favoris.<br />" | |||
. "<a href=\"" . Yii::$app->urlManager->createUrl(['communicate/index']) . "\">Cliquez ici</a> pour télécharger un mode d'emploi comprenant ce code à distribuer à vos clients.") ?> | |||
<h4>Général</h4> | |||
<?= $form->field($model, 'name') ?> | |||
<?= $form->field($model, 'type') ?> | |||
<?= $form->field($model, 'description') | |||
->textarea(['rows' => 4]) | |||
->hint('Affiché sur la page d\'accueil') ?> | |||
->textarea(['rows' => 4]) | |||
->hint('Affiché sur la page d\'accueil') ?> | |||
<?= $form->field($model, 'address') | |||
->textarea(['rows' => 4]) ?> | |||
->textarea(['rows' => 4]) ?> | |||
<?= $form->field($model, 'postcode') ?> | |||
<?= $form->field($model, 'city') ?> | |||
<?= $form->field($model, 'code')->hint("Saisissez ce champs si vous souhaitez protéger l'accès à votre boutique par un code, sinon laissez-le vide.<br />" | |||
. "Ce code est à communiquer à vos client pour qu'ils puissent ajouter votre établissement à leur tableau de bord.<br />" | |||
. "<a href=\"".Yii::$app->urlManager->createUrl(['communicate/index'])."\">Cliquez ici</a> pour télécharger un mode d'emploi comprenant ce code à distribuer à vos clients.") ?> | |||
<h4>Apparence</h4> | |||
<?= $form->field($model, 'background_color_logo') ?> | |||
<?= $form->field($model, 'logo')->fileInput() ?> | |||
<?php | |||
if (strlen($model->logo)) { | |||
echo '<img src="'.Yii::$app->urlManagerProducer->getHostInfo().'/'.Yii::$app->urlManagerProducer->baseUrl.'/uploads/' . $model->logo . '" width="200px" /><br />'; | |||
echo '<img src="' . Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->logo . '" width="200px" /><br />'; | |||
echo '<input type="checkbox" name="delete_logo" id="delete_logo" /> <label for="delete_logo">Supprimer le logo</label><br /><br />'; | |||
} | |||
?> | |||
<?= $form->field($model, 'photo')->fileInput()->hint('Format idéal : 900 x 150 px') ?> | |||
<?php | |||
if (strlen($model->photo)) { | |||
echo '<img src="'.Yii::$app->urlManagerProducer->getHostInfo().'/'.Yii::$app->urlManagerProducer->baseUrl.'/uploads/' . $model->photo . '" width="400px" /><br />'; | |||
echo '<img src="' . Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->photo . '" width="400px" /><br />'; | |||
echo '<input type="checkbox" name="delete_photo" id="delete_photo" /> <label for="delete_photo">Supprimer la photo</label><br /><br />'; | |||
} | |||
?> | |||
<?= $form->field($model, 'behavior_home_point_sale_day_list') | |||
->dropDownList([ | |||
Producer::BEHAVIOR_HOME_POINT_SALE_DAY_LIST_WEEK => 'Jours de la semaine', | |||
Producer::BEHAVIOR_HOME_POINT_SALE_DAY_LIST_INCOMING_DISTRIBUTIONS => 'Distributions à venir', | |||
]); ?> | |||
->dropDownList([ | |||
Producer::BEHAVIOR_HOME_POINT_SALE_DAY_LIST_WEEK => 'Jours de la semaine', | |||
Producer::BEHAVIOR_HOME_POINT_SALE_DAY_LIST_INCOMING_DISTRIBUTIONS => 'Distributions à venir', | |||
]); ?> | |||
</div> | |||
</div> | |||
<div v-show="currentSection == 'tableau-bord'" class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title">Tableau de bord</h3> | |||
</div> | |||
<div class="panel-body"> | |||
<?= $form->field($model, 'option_dashboard_number_distributions') | |||
->dropDownList([ | |||
3 => '3', | |||
6 => '6', | |||
9 => '9', | |||
12 => '12', | |||
15 => '15', | |||
18 => '18', | |||
21 => '21', | |||
24 => '24', | |||
27 => '27', | |||
30 => '30', | |||
], []); ?> | |||
<?= $form->field($model, 'option_dashboard_date_start')->textInput([ | |||
'class' => 'datepicker form-control' | |||
]) ; ?> | |||
<?= $form->field($model, 'option_dashboard_date_end')->textInput([ | |||
'class' => 'datepicker form-control' | |||
]) ; ?> | |||
<h4>Tableau de bord administration</h4> | |||
<?= $form->field($model, 'option_dashboard_number_distributions') | |||
->dropDownList([ | |||
3 => '3', | |||
6 => '6', | |||
9 => '9', | |||
12 => '12', | |||
15 => '15', | |||
18 => '18', | |||
21 => '21', | |||
24 => '24', | |||
27 => '27', | |||
30 => '30', | |||
], []); ?> | |||
<?= $form->field($model, 'option_dashboard_date_start')->textInput([ | |||
'class' => 'datepicker form-control' | |||
]); ?> | |||
<?= $form->field($model, 'option_dashboard_date_end')->textInput([ | |||
'class' => 'datepicker form-control' | |||
]); ?> | |||
</div> | |||
</div> | |||
<div v-show="currentSection == 'prise-commande'" class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title">Prise de commande</h3> | |||
</div> | |||
<div v-show="currentSection == 'prise-commande'" class="panel panel-default"> | |||
<div class="panel-body"> | |||
<h4>Horaires</h4> | |||
<?php | |||
$delaysArray = [ | |||
1 => '1 jour', | |||
2 => '2 jours', | |||
3 => '3 jours', | |||
4 => '4 jours', | |||
5 => '5 jours', | |||
6 => '6 jours', | |||
7 => '7 jours', | |||
]; | |||
$deadlinesArray = [ | |||
24 => 'Minuit', | |||
23 => '23h', | |||
22 => '22h', | |||
21 => '21h', | |||
20 => '20h', | |||
19 => '19h', | |||
18 => '18h', | |||
17 => '17h', | |||
16 => '16h', | |||
15 => '15h', | |||
14 => '14h', | |||
13 => '13h', | |||
12 => '12h', | |||
11 => '11h', | |||
10 => '10h', | |||
9 => '9h', | |||
8 => '8h', | |||
]; | |||
$daysArray = [ | |||
'monday' => 'Lundi', | |||
'tuesday' => 'Mardi', | |||
'wednesday' => 'Mercredi', | |||
'thursday' => 'Jeudi', | |||
'friday' => 'Vendredi', | |||
'saturday' => 'Samedi', | |||
'sunday' => 'Dimanche' | |||
]; | |||
?> | |||
<?php | |||
$delaysArray = [ | |||
1 => '1 jour', | |||
2 => '2 jours', | |||
3 => '3 jours', | |||
4 => '4 jours', | |||
5 => '5 jours', | |||
6 => '6 jours', | |||
7 => '7 jours', | |||
] ; | |||
$deadlinesArray = [ | |||
24 => 'Minuit', | |||
23 => '23h', | |||
22 => '22h', | |||
21 => '21h', | |||
20 => '20h', | |||
19 => '19h', | |||
18 => '18h', | |||
17 => '17h', | |||
16 => '16h', | |||
15 => '15h', | |||
14 => '14h', | |||
13 => '13h', | |||
12 => '12h', | |||
11 => '11h', | |||
10 => '10h', | |||
9 => '9h', | |||
8 => '8h', | |||
] ; | |||
$daysArray = [ | |||
'monday' => 'Lundi', | |||
'tuesday' => 'Mardi', | |||
'wednesday' => 'Mercredi', | |||
'thursday' => 'Jeudi', | |||
'friday' => 'Vendredi', | |||
'saturday' => 'Samedi', | |||
'sunday' => 'Dimanche' | |||
] ; | |||
?> | |||
<div class="row"> | |||
<div class="col-md-2"> | |||
<strong>Par défaut</strong> | |||
</div> | |||
<div class="col-md-5"> | |||
<?= $form->field($model, 'order_delay') | |||
->dropDownList($delaysArray, ['prompt' => '--']) | |||
->hint('Si <strong>1 jour</strong> est sélectionné, le client pourra commander jusqu\'à la veille de la production.<br />' | |||
. 'Si <strong>2 jours</strong> est sélectionné, le client pourra commander jusqu\'à l\'avant-veille de la production, etc.') ; ?> | |||
</div> | |||
<div class="col-md-5"> | |||
<?= $form->field($model, 'order_deadline') | |||
->dropDownList($deadlinesArray, ['prompt' => '--']) | |||
->hint('Heure limite jusqu\'à laquelle les clients peuvent commander pour satisfaire le délai de commande.<br />' | |||
. 'Par exemple, si <strong>2 jours</strong> est sélectionné dans le délai de commande, le client devra commander l\'avant-veille de la production avant l\'heure précisée ici.') ; ?> | |||
</div> | |||
<div class="row"> | |||
<div class="col-md-2"> | |||
<strong>Par défaut</strong> | |||
</div> | |||
<div class="col-md-5"> | |||
<?= $form->field($model, 'order_delay') | |||
->dropDownList($delaysArray, ['prompt' => '--']) | |||
->hint('Si <strong>1 jour</strong> est sélectionné, le client pourra commander jusqu\'à la veille de la production.<br />' | |||
. 'Si <strong>2 jours</strong> est sélectionné, le client pourra commander jusqu\'à l\'avant-veille de la production, etc.'); ?> | |||
</div> | |||
<div class="col-md-5"> | |||
<?= $form->field($model, 'order_deadline') | |||
->dropDownList($deadlinesArray, ['prompt' => '--']) | |||
->hint('Heure limite jusqu\'à laquelle les clients peuvent commander pour satisfaire le délai de commande.<br />' | |||
. 'Par exemple, si <strong>2 jours</strong> est sélectionné dans le délai de commande, le client devra commander l\'avant-veille de la production avant l\'heure précisée ici.'); ?> | |||
</div> | |||
<?php foreach($daysArray as $day => $labelDay): ?> | |||
</div> | |||
<?php foreach ($daysArray as $day => $labelDay): ?> | |||
<div class="row"> | |||
<div class="col-md-2"> | |||
<strong><?= $labelDay ?></strong> | |||
</div> | |||
<div class="col-md-5"> | |||
<?= $form->field($model, 'order_delay_'.$day, [ | |||
'template' => '{input}', | |||
])->dropDownList($delaysArray, ['prompt' => '--'])->label(''); ?> | |||
</div> | |||
<div class="col-md-5"> | |||
<?= $form->field($model, 'order_deadline_'.$day, [ | |||
'template' => '{input}', | |||
])->dropDownList($deadlinesArray, ['prompt' => '--'])->label(''); ?> | |||
</div> | |||
<div class="col-md-2"> | |||
<strong><?= $labelDay ?></strong> | |||
</div> | |||
<div class="col-md-5"> | |||
<?= $form->field($model, 'order_delay_' . $day, [ | |||
'template' => '{input}', | |||
])->dropDownList($delaysArray, ['prompt' => '--'])->label(''); ?> | |||
</div> | |||
<div class="col-md-5"> | |||
<?= $form->field($model, 'order_deadline_' . $day, [ | |||
'template' => '{input}', | |||
])->dropDownList($deadlinesArray, ['prompt' => '--'])->label(''); ?> | |||
</div> | |||
</div> | |||
<?php endforeach; ?> | |||
<?php endforeach; ?> | |||
<h4>Informations</h4> | |||
<?= $form->field($model, 'order_infos') | |||
->textarea(['rows' => 6]) | |||
->hint('Affichées au client lors de sa commande')?> | |||
->hint('Affichées au client lors de sa commande') ?> | |||
<?= $form->field($model, 'option_payment_info') | |||
->textarea(['rows' => 6]) | |||
->hint('Affichées au client à la fin de la prise de commande') ?> | |||
<h4>Tunnel de commande</h4> | |||
<?= $form->field($model, 'option_order_entry_point') | |||
->dropDownList([ | |||
Producer::ORDER_ENTRY_POINT_DATE => 'Date', | |||
Producer::ORDER_ENTRY_POINT_POINT_SALE => 'Point de vente', | |||
], []); ?> | |||
<?= $form->field($model, 'behavior_order_select_distribution') | |||
->dropDownList([ | |||
Producer::BEHAVIOR_ORDER_SELECT_DISTRIBUTION_CALENDAR => 'Calendrier', | |||
Producer::BEHAVIOR_ORDER_SELECT_DISTRIBUTION_LIST => 'Liste', | |||
]); ?> | |||
<?= $form->field($model, 'option_delivery') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?php echo $form->field($model, 'option_allow_order_guest') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<h4>Notifications</h4> | |||
<?= $form->field($model, 'option_notify_producer_order_summary') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui', | |||
], []) ; ?> | |||
<?= $form->field($model, 'option_behavior_cancel_order') | |||
->dropDownList([ | |||
Producer::BEHAVIOR_DELETE_ORDER_DELETE => 'Suppression de la commande', | |||
Producer::BEHAVIOR_DELETE_ORDER_STATUS => 'Passage de la commande en statut "supprimé"', | |||
], []) ; ?> | |||
], []); ?> | |||
<?= $form->field($model, 'option_email_confirm') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_email_confirm_producer') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'behavior_order_select_distribution') | |||
<h4>Exports</h4> | |||
<?= $form->field($model, 'option_csv_export_all_products') | |||
->dropDownList([ | |||
Producer::BEHAVIOR_ORDER_SELECT_DISTRIBUTION_CALENDAR => 'Calendrier', | |||
Producer::BEHAVIOR_ORDER_SELECT_DISTRIBUTION_LIST => 'Liste', | |||
]); ?> | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_csv_export_by_piece') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_display_export_grid') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_export_display_product_reference') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_payment_info') | |||
->textarea(['rows' => 6]) | |||
->hint('Affiché au client à la fin de la prise de commande')?> | |||
<?= $form->field($model, 'option_email_confirm') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_email_confirm_producer') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_csv_export_all_products') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_csv_export_by_piece') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_display_export_grid') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_order_reference_type') | |||
->dropDownList([ | |||
Producer::ORDER_REFERENCE_TYPE_NONE => '--', | |||
Producer::ORDER_REFERENCE_TYPE_YEARLY => 'Annuelle', | |||
], []) ; ?> | |||
<?= $form->field($model, 'option_export_display_product_reference') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?php echo $form->field($model, 'option_allow_order_guest') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_order_entry_point') | |||
->dropDownList([ | |||
Producer::ORDER_ENTRY_POINT_DATE => 'Date', | |||
Producer::ORDER_ENTRY_POINT_POINT_SALE => 'Point de vente', | |||
], []); ?> | |||
<?= $form->field($model, 'option_delivery') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<h4>Divers</h4> | |||
<?= $form->field($model, 'option_order_reference_type') | |||
->dropDownList([ | |||
Producer::ORDER_REFERENCE_TYPE_NONE => '--', | |||
Producer::ORDER_REFERENCE_TYPE_YEARLY => 'Annuelle', | |||
], []); ?> | |||
<?= $form->field($model, 'option_behavior_cancel_order') | |||
->dropDownList([ | |||
Producer::BEHAVIOR_DELETE_ORDER_DELETE => 'Suppression de la commande', | |||
Producer::BEHAVIOR_DELETE_ORDER_STATUS => 'Passage de la commande en statut "supprimé"', | |||
], []); ?> | |||
</div> | |||
</div> | |||
</div> | |||
<div v-show="currentSection == 'abonnements'" class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title">Abonnements</h3> | |||
</div> | |||
<div class="panel-body"> | |||
<h4>Abonnements</h4> | |||
<?= $form->field($model, 'user_manage_subscription') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui', | |||
], []) ; ?> | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui', | |||
], []); ?> | |||
</div> | |||
</div> | |||
<div v-show="currentSection == 'credit-payment'" class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title">Crédit</h3> | |||
</div> | |||
<div class="panel-body"> | |||
<h4>Crédit</h4> | |||
<?= $form->field($model, 'credit') | |||
->dropDownList([ | |||
0 => 'Non', | |||
@@ -342,142 +334,135 @@ $this->addBreadcrumb($this->getTitle()) ; | |||
], []) | |||
->label('Activer le système de Crédit') | |||
->hint('Le système de Crédit permet à vos clients d\'avoir un compte prépayé sur le site <em>distrib</em>.<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.') ; ?> | |||
. '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) ; ?> | |||
->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_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.'); ?> | |||
<br /> | |||
<h3>Paiement en ligne</h3> | |||
->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_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.'); ?> | |||
<h4>Paiement en ligne</h4> | |||
<?= $form->field($model, 'online_payment') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui', | |||
], []); ?> | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui', | |||
], []); ?> | |||
<?= $form->field($model, 'option_stripe_mode_test')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []); ?> | |||
<?= $form->field($model, 'option_online_payment_type') | |||
->dropDownList([ | |||
'credit' => 'Alimentation du crédit', | |||
'order' => 'Paiement à la commande', | |||
], []); ?> | |||
->dropDownList([ | |||
'credit' => 'Alimentation du crédit', | |||
'order' => 'Paiement à la commande', | |||
], []); ?> | |||
<?= $form->field($model, 'option_stripe_public_key')->textInput(); ?> | |||
<?= $form->field($model, 'option_stripe_private_key')->textInput(); ?> | |||
<?= $form->field($model, 'option_stripe_endpoint_secret')->textInput(); ?> | |||
</div> | |||
</div> | |||
<div v-show="currentSection == 'infos'" class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title">Informations légales</h3> | |||
</div> | |||
<div class="panel-body"> | |||
<h4>Informations légales</h4> | |||
<?= $form->field($model, 'mentions') | |||
->textarea(['rows' => 15]) | |||
->hint('') ?> | |||
->textarea(['rows' => 15]) | |||
->hint('') ?> | |||
<?= $form->field($model, 'gcs') | |||
->textarea(['rows' => 15]) | |||
->hint('') ?> | |||
->textarea(['rows' => 15]) | |||
->hint('') ?> | |||
</div> | |||
</div> | |||
<div v-show="currentSection == 'logiciels-caisse'" class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title">Logiciels de caisse</h3> | |||
</div> | |||
<div class="panel-body"> | |||
<h4>Tiller</h4> | |||
<?= $form->field($model, 'tiller') | |||
->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
], []) | |||
->label('Synchroniser avec Tiller'); ?> | |||
<?= $form->field($model, 'tiller_provider_token') ; ?> | |||
<?= $form->field($model, 'tiller_restaurant_token') ; ?> | |||
<?= $form->field($model, 'tiller_provider_token'); ?> | |||
<?= $form->field($model, 'tiller_restaurant_token'); ?> | |||
</div> | |||
</div> | |||
<div v-show="currentSection == 'facturation'" class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title">Facturation</h3> | |||
</div> | |||
<div class="panel-body"> | |||
<?= $form->field($model, 'id_tax_rate_default') | |||
->dropDownList(ArrayHelper::map(TaxRate::find()->all(), 'id', function($model) { return $model->name; })) | |||
->label('TVA à appliquer par défaut'); ?> | |||
<?= $form->field($model, 'option_tax_calculation_method') | |||
->dropDownList(Document::$taxCalculationMethodArray); ?> | |||
<?= $form->field($model, 'option_export_evoliz')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
]) ; ?> | |||
<?= $form->field($model, 'document_quotation_prefix') ; ?> | |||
<?= $form->field($model, 'document_quotation_first_reference') ; ?> | |||
<?= $form->field($model, 'document_quotation_duration') ; ?> | |||
<?= $form->field($model, 'document_invoice_prefix') ; ?> | |||
<?= $form->field($model, 'document_invoice_first_reference') ; ?> | |||
<?= $form->field($model, 'document_delivery_note_prefix') ; ?> | |||
<?= $form->field($model, 'document_delivery_note_first_reference') ; ?> | |||
<?= $form->field($model, 'document_display_orders_invoice')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
]) ; ?> | |||
<?= $form->field($model, 'document_display_orders_delivery_note')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
]) ; ?> | |||
<?= $form->field($model, 'document_display_prices_delivery_note')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
]) ; ?> | |||
<?= $form->field($model, 'document_display_product_description')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
]) ; ?> | |||
<?= $form->field($model, 'document_infos_bottom') | |||
->textarea(['rows' => 15]) ?> | |||
<?= $form->field($model, 'document_infos_quotation') | |||
->textarea(['rows' => 15]) ?> | |||
<?= $form->field($model, 'document_infos_invoice') | |||
->textarea(['rows' => 15]) ?> | |||
<?= $form->field($model, 'document_infos_delivery_note') | |||
->textarea(['rows' => 15]) ?> | |||
<h4>Facturation</h4> | |||
<?= $form->field($model, 'id_tax_rate_default') | |||
->dropDownList(ArrayHelper::map(TaxRate::find()->all(), 'id', function ($model) { | |||
return $model->name; | |||
})) | |||
->label('TVA à appliquer par défaut'); ?> | |||
<?= $form->field($model, 'option_tax_calculation_method') | |||
->dropDownList(Document::$taxCalculationMethodArray); ?> | |||
<?= $form->field($model, 'option_export_evoliz')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
]); ?> | |||
<?= $form->field($model, 'document_quotation_prefix'); ?> | |||
<?= $form->field($model, 'document_quotation_first_reference'); ?> | |||
<?= $form->field($model, 'document_quotation_duration'); ?> | |||
<?= $form->field($model, 'document_invoice_prefix'); ?> | |||
<?= $form->field($model, 'document_invoice_first_reference'); ?> | |||
<?= $form->field($model, 'document_delivery_note_prefix'); ?> | |||
<?= $form->field($model, 'document_delivery_note_first_reference'); ?> | |||
<?= $form->field($model, 'document_display_orders_invoice')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
]); ?> | |||
<?= $form->field($model, 'document_display_orders_delivery_note')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
]); ?> | |||
<?= $form->field($model, 'document_display_prices_delivery_note')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
]); ?> | |||
<?= $form->field($model, 'document_display_product_description')->dropDownList([ | |||
0 => 'Non', | |||
1 => 'Oui' | |||
]); ?> | |||
<?= $form->field($model, 'document_infos_bottom') | |||
->textarea(['rows' => 15]) ?> | |||
<?= $form->field($model, 'document_infos_quotation') | |||
->textarea(['rows' => 15]) ?> | |||
<?= $form->field($model, 'document_infos_invoice') | |||
->textarea(['rows' => 15]) ?> | |||
<?= $form->field($model, 'document_infos_delivery_note') | |||
->textarea(['rows' => 15]) ?> | |||
</div> | |||
</div> | |||
<?php if(User::isCurrentAdmin()): ?> | |||
<?php if (User::isCurrentAdmin()): ?> | |||
<div v-show="currentSection == 'administration'" class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title">Administration</h3> | |||
</div> | |||
<div class="panel-body"> | |||
<h4>Administration</h4> | |||
<?= $form->field($model, 'option_billing_type') | |||
->dropDownList(Producer::getBillingTypePopulateDropdown()); ?> | |||
<?= $form->field($model, 'option_billing_frequency') | |||
@@ -490,7 +475,7 @@ $this->addBreadcrumb($this->getTitle()) ; | |||
</div> | |||
</div> | |||
<?php endif; ?> | |||
<div class="form-group"> | |||
<?= Html::submitButton('Mettre à jour', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> | |||
</div> |
@@ -43,6 +43,7 @@ use common\models\Product; | |||
use common\models\TaxRate; | |||
use common\models\Producer; | |||
use common\helpers\GlobalParam; | |||
use \lo\widgets\Toggle; | |||
$this->setTitle('Produits'); | |||
$this->addBreadcrumb($this->getTitle()); | |||
@@ -53,107 +54,112 @@ $this->addButton(['label' => 'Nouveau produit <span class="glyphicon glyphicon-p | |||
<span style="display: none;" id="page-size"><?= $dataProvider->pagination->pageSize; ?></span> | |||
<div class="product-index"> | |||
<?= GridView::widget([ | |||
'filterModel' => $searchModel, | |||
'dataProvider' => $dataProvider, | |||
'columns' => [ | |||
[ | |||
'attribute' => 'order', | |||
'headerOptions' => ['class' => 'order'], | |||
'format' => 'raw', | |||
'filter' => '', | |||
'value' => function ($model) { | |||
return '<a class="btn-order btn btn-default" href="javascript:void(0);"><span class="glyphicon glyphicon-resize-vertical"></span></a>'; | |||
} | |||
], | |||
[ | |||
'attribute' => 'photo', | |||
'format' => 'raw', | |||
'headerOptions' => ['class' => 'td-photo'], | |||
'filter' => '', | |||
'value' => function ($model) { | |||
if (strlen($model->photo)) { | |||
$url = Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/'.$model->photo ; | |||
$url = str_replace('//uploads','/uploads', $url) ; | |||
return '<img class="photo-product" src="' . $url . '" />'; | |||
} | |||
return ''; | |||
} | |||
], | |||
'name', | |||
'description', | |||
[ | |||
'attribute' => 'id_product_category', | |||
'format' => 'raw', | |||
'headerOptions' => ['class' => 'td-product-category'], | |||
'filter' => '', | |||
'value' => function ($model) { | |||
if ($model->productCategory) { | |||
return $model->productCategory->name ; | |||
} | |||
return ''; | |||
} | |||
], | |||
[ | |||
'attribute' => 'id_tax_rate', | |||
'value' => function ($model) { | |||
if ($model->id_tax_rate == 0 || $model->id_tax_rate == null) { | |||
<?= GridView::widget([ | |||
'filterModel' => $searchModel, | |||
'dataProvider' => $dataProvider, | |||
'columns' => [ | |||
[ | |||
'attribute' => 'order', | |||
'headerOptions' => ['class' => 'order'], | |||
'format' => 'raw', | |||
'filter' => '', | |||
'value' => function ($model) { | |||
return '<a class="btn-order btn btn-default" href="javascript:void(0);"><span class="glyphicon glyphicon-resize-vertical"></span></a>'; | |||
} | |||
], | |||
[ | |||
'attribute' => 'photo', | |||
'format' => 'raw', | |||
'headerOptions' => ['class' => 'td-photo'], | |||
'filter' => '', | |||
'value' => function ($model) { | |||
if (strlen($model->photo)) { | |||
$url = Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->photo; | |||
$url = str_replace('//uploads', '/uploads', $url); | |||
return '<img class="photo-product" src="' . $url . '" />'; | |||
} | |||
return ''; | |||
} | |||
], | |||
'name', | |||
'description', | |||
[ | |||
'attribute' => 'id_product_category', | |||
'format' => 'raw', | |||
'headerOptions' => ['class' => 'td-product-category'], | |||
'filter' => '', | |||
'value' => function ($model) { | |||
if ($model->productCategory) { | |||
return $model->productCategory->name; | |||
} | |||
return ''; | |||
} | |||
], | |||
[ | |||
'attribute' => 'id_tax_rate', | |||
'value' => function ($model) { | |||
if ($model->id_tax_rate == 0 || $model->id_tax_rate == null) { | |||
//Récupère la tva par défaut du producteur courant | |||
$taxRateDefault = GlobalParam::getCurrentProducer()->taxRate; | |||
//Récupère la tva par défaut du producteur courant | |||
$taxRateDefault = GlobalParam::getCurrentProducer()->taxRate; | |||
$return = $taxRateDefault->name; | |||
} else { | |||
$return = $taxRateDefault->name; | |||
} else { | |||
$return = $model->taxRate->name; | |||
} | |||
return $return; | |||
} | |||
], | |||
[ | |||
'attribute' => 'price', | |||
'value' => function ($model) { | |||
$return = ''; | |||
if ($model->price) { | |||
$return = Price::format($model->getPriceWithTax()) . ' (' . Product::strUnit($model->unit, 'wording_unit', true) . ')'; | |||
} | |||
return $return; | |||
} | |||
], | |||
[ | |||
'attribute' => 'active', | |||
'headerOptions' => ['class' => 'active'], | |||
'contentOptions' => ['class' => 'center'], | |||
'format' => 'raw', | |||
'filter' => [0 => 'Non', 1 => 'Oui'], | |||
'value' => function ($model) { | |||
if ($model->active) { | |||
return '<span class="label label-success">oui</span>'; | |||
} else { | |||
return '<span class="label label-danger">non</span>'; | |||
} | |||
} | |||
], | |||
$return = $model->taxRate->name; | |||
} | |||
return $return; | |||
} | |||
], | |||
[ | |||
'attribute' => 'price', | |||
'value' => function ($model) { | |||
$return = ''; | |||
if ($model->price) { | |||
$return = Price::format($model->getPriceWithTax()) . ' (' . Product::strUnit($model->unit, 'wording_unit', true) . ')'; | |||
} | |||
return $return; | |||
} | |||
], | |||
[ | |||
'attribute' => 'active', | |||
'headerOptions' => ['class' => 'active'], | |||
'contentOptions' => ['class' => 'center'], | |||
'format' => 'raw', | |||
'filter' => [0 => 'Non', 1 => 'Oui'], | |||
'value' => function ($model) { | |||
return Toggle::widget( | |||
[ | |||
'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>', $url, [ | |||
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default' | |||
]); | |||
}, | |||
'delete' => function ($url, $model) { | |||
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [ | |||
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default' | |||
]); | |||
} | |||
], | |||
], | |||
'name' => 'active', | |||
'checked' => $model->active, | |||
'options' => [ | |||
'data-id' => $model->id, | |||
'data-on' => 'Oui', | |||
'data-off' => 'Non', | |||
], | |||
] | |||
); | |||
} | |||
], | |||
[ | |||
'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>', $url, [ | |||
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default' | |||
]); | |||
}, | |||
'delete' => function ($url, $model) { | |||
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [ | |||
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default' | |||
]); | |||
} | |||
], | |||
]); ?> | |||
], | |||
], | |||
]); ?> | |||
</div> |
@@ -38,7 +38,7 @@ termes. | |||
use yii\helpers\Html ; | |||
$this->title = 'Tableau de bord'; | |||
$this->setTitle('Tableau de bord'); | |||
?> | |||
<div class="site-index"> |
@@ -67,11 +67,7 @@ $this->render('_menu', [ | |||
'attribute' => 'username', | |||
'label' => 'Nom', | |||
'value' => function ($model) { | |||
if (isset($model['name_legal_person']) && strlen($model['name_legal_person'])) { | |||
return $model['name_legal_person']; | |||
} else { | |||
return $model['lastname'] . ' ' . $model['name']; | |||
} | |||
return User::getUsernameFromArray($model); | |||
} | |||
], | |||
[ | |||
@@ -112,7 +108,7 @@ $this->render('_menu', [ | |||
'orders' => function ($url, $model) { | |||
$url = Yii::$app->urlManager->createUrl(['user/orders', 'id' => $model['id']]); | |||
$countOrders = Order::searchCount([ | |||
'id_user' => $model['id'] | |||
'id_user' => $model['id'], | |||
], ['conditions' => 'date_delete IS NULL']); | |||
$html = ''; |
@@ -1,79 +1,105 @@ | |||
<?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 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. | |||
*/ | |||
contact@opendistrib.net | |||
use yii\grid\GridView; | |||
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\widgets\ActiveForm; | |||
use common\models\CreditHistory; | |||
use common\models\Producer; | |||
use common\models\Order; | |||
$this->setTitle('Commandes <small>'.Html::encode($user->lastname.' '.$user->name).'</small>', 'Commandes de '.Html::encode($user->lastname.' '.$user->name)) ; | |||
$this->addBreadcrumb(['label' => 'Utilisateurs', 'url' => ['index']]) ; | |||
$this->addBreadcrumb(['label' => Html::encode($user->lastname.' '.$user->name)]) ; | |||
$this->addBreadcrumb('Commandes') ; | |||
$this->setTitle('Commandes <small>' . Html::encode($user->getUsername()) . '</small>', 'Commandes de ' . Html::encode($user->getUsername())); | |||
$this->addBreadcrumb(['label' => 'Utilisateurs', 'url' => ['index']]); | |||
$this->addBreadcrumb(['label' => Html::encode($user->lastname . ' ' . $user->name)]); | |||
$this->addBreadcrumb('Commandes'); | |||
?> | |||
<div class="user-orders"> | |||
<?php if(count($ordersArray)): ?> | |||
<table id="historique-commandes" class="table table-striped table-bordered"> | |||
<thead> | |||
<tr> | |||
<th>Date livraison</th> | |||
<th>Historique</th> | |||
<th>Résumé</th> | |||
<th>Point de vente</th> | |||
<th class="montant">Montant</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<?php foreach($ordersArray as $order): ?> | |||
<tr class="<?= $order->getClassHistory() ; ?>"> | |||
<td><?php echo date('d/m/Y',strtotime($order->distribution->date)); ?></td> | |||
<td class="historique"><?= $order->getStrHistory() ; ?></td> | |||
<td class="resume"><?= $order->getCartSummary() ; ?></td> | |||
<td><?= $order->getPointSaleSummary(); ?></td> | |||
<td class="montant"><?= $order->getAmountSummary(); ?></td> | |||
</tr> | |||
<?php endforeach; ?> | |||
</tbody> | |||
</table> | |||
<?php else: ?> | |||
<div class="alert alert-warning">Aucune commande passée par ce client.</div> | |||
<?php endif; ?> | |||
<?= GridView::widget([ | |||
'filterModel' => $searchModel, | |||
'dataProvider' => $dataProvider, | |||
'columns' => [ | |||
[ | |||
'attribute' => 'distribution.date', | |||
'label' => 'Date de livraison', | |||
'value' => function ($model) { | |||
return date('d/m/Y',strtotime($model->distribution->date)); | |||
} | |||
], | |||
[ | |||
'label' => 'Historique', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
return $model->getStrHistory(); | |||
} | |||
], | |||
[ | |||
'label' => 'Résumé', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
return $model->getCartSummary(); | |||
} | |||
], | |||
[ | |||
'label' => 'Point de vente', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
return $model->getPointSaleSummary(); | |||
} | |||
], | |||
[ | |||
'label' => 'Montant', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
$model->init(); | |||
return $model->getAmountSummary(); | |||
} | |||
], | |||
[ | |||
'class' => 'yii\grid\ActionColumn', | |||
'template' => '{update}', | |||
'headerOptions' => ['class' => 'column-actions'], | |||
'contentOptions' => ['class' => 'column-actions'], | |||
'buttons' => [ | |||
'update' => function ($url, $model) { | |||
$url = Yii::$app->urlManager->createUrl(['distribution/index', 'idOrderUpdate' => $model->id]); | |||
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [ | |||
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default' | |||
]); | |||
}, | |||
], | |||
] | |||
], | |||
]); ?> | |||
</div> |
@@ -1720,22 +1720,23 @@ body.login-page .login-box .login-box-body a:hover { | |||
right: 15px; | |||
width: 300px; | |||
height: auto; | |||
z-index: 9999; | |||
} | |||
/* line 9, ../sass/_alerts.scss */ | |||
/* line 10, ../sass/_alerts.scss */ | |||
#app-alerts .slide-fade-enter-active { | |||
-moz-transition: all 0.3s ease; | |||
-o-transition: all 0.3s ease; | |||
-webkit-transition: all 0.3s ease; | |||
transition: all 0.3s ease; | |||
} | |||
/* line 12, ../sass/_alerts.scss */ | |||
/* line 13, ../sass/_alerts.scss */ | |||
#app-alerts .slide-fade-leave-active { | |||
-moz-transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); | |||
-o-transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); | |||
-webkit-transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); | |||
transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); | |||
} | |||
/* line 15, ../sass/_alerts.scss */ | |||
/* line 16, ../sass/_alerts.scss */ | |||
#app-alerts .slide-fade-enter, #app-alerts .slide-fade-leave-to { | |||
-moz-transform: translateX(10px); | |||
-ms-transform: translateX(10px); | |||
@@ -2075,11 +2076,28 @@ termes. | |||
.distribution-index #orders #buttons-top-orders .dropdown { | |||
display: inline-block; | |||
} | |||
/* line 242, ../sass/distribution/_index.scss */ | |||
/* line 240, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders .point-sale-totals { | |||
background-color: white; | |||
padding: 10px 20px; | |||
border: solid 1px #e0e0e0; | |||
-moz-border-radius: 5px; | |||
-webkit-border-radius: 5px; | |||
border-radius: 5px; | |||
margin-bottom: 20px; | |||
} | |||
/* line 247, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders .point-sale-totals .title { | |||
color: gray; | |||
font-size: 13px; | |||
margin-right: 13px; | |||
text-transform: uppercase; | |||
} | |||
/* line 257, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.tiller { | |||
width: 60px; | |||
} | |||
/* line 245, ../sass/distribution/_index.scss */ | |||
/* line 260, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.tiller label { | |||
font-size: 12px; | |||
cursor: pointer; | |||
@@ -2087,68 +2105,68 @@ termes. | |||
top: -2px; | |||
font-weight: normal; | |||
} | |||
/* line 254, ../sass/distribution/_index.scss */ | |||
/* line 269, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions { | |||
position: relative; | |||
text-align: right; | |||
} | |||
/* line 258, ../sass/distribution/_index.scss */ | |||
/* line 273, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions .dropdown-menu { | |||
top: 0px; | |||
right: 0px; | |||
} | |||
/* line 263, ../sass/distribution/_index.scss */ | |||
/* line 278, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions .modal-form-order, | |||
.distribution-index #orders table td.column-actions .modal-payment { | |||
text-align: left; | |||
} | |||
/* line 268, ../sass/distribution/_index.scss */ | |||
/* line 283, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions .add-subscription { | |||
position: relative; | |||
} | |||
/* line 271, ../sass/distribution/_index.scss */ | |||
/* line 286, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-actions .add-subscription .glyphicon-plus { | |||
position: absolute; | |||
top: 4px; | |||
right: 4px; | |||
font-size: 7px; | |||
} | |||
/* line 280, ../sass/distribution/_index.scss */ | |||
/* line 295, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-state-payment { | |||
width: 120px; | |||
} | |||
/* line 285, ../sass/distribution/_index.scss */ | |||
/* line 300, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table td.column-payment div.btn-group { | |||
width: 125px; | |||
} | |||
/* line 291, ../sass/distribution/_index.scss */ | |||
/* line 306, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table tr.view ul { | |||
list-style-type: none; | |||
margin-left: 0px; | |||
padding-left: 15px; | |||
} | |||
/* line 301, ../sass/distribution/_index.scss */ | |||
/* line 316, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table tr.view .comment { | |||
margin-top: 20px; | |||
} | |||
/* line 305, ../sass/distribution/_index.scss */ | |||
/* line 320, ../sass/distribution/_index.scss */ | |||
.distribution-index #orders table tr.view .delivery { | |||
margin-top: 20px; | |||
} | |||
/* line 314, ../sass/distribution/_index.scss */ | |||
/* line 329, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container { | |||
width: 100%; | |||
padding: 0px; | |||
} | |||
/* line 318, ../sass/distribution/_index.scss */ | |||
/* line 333, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container .modal-body { | |||
padding-right: 15px; | |||
} | |||
/* line 320, ../sass/distribution/_index.scss */ | |||
/* line 336, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container .modal-body table { | |||
margin-bottom: 150px; | |||
} | |||
/* line 325, ../sass/distribution/_index.scss */ | |||
/* line 341, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container .modal-footer { | |||
border-top-color: #f4f4f4; | |||
position: fixed; | |||
@@ -2160,46 +2178,54 @@ termes. | |||
text-align: center; | |||
border-top: solid 1px #e0e0e0; | |||
} | |||
/* line 337, ../sass/distribution/_index.scss */ | |||
/* line 353, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container .modal-footer .actions-form button { | |||
float: none; | |||
} | |||
/* line 344, ../sass/distribution/_index.scss */ | |||
/* line 357, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .modal-container .modal-footer .actions-form div.right { | |||
float: right; | |||
} | |||
/* line 364, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .btn-credit { | |||
float: right; | |||
} | |||
/* line 350, ../sass/distribution/_index.scss */ | |||
/* line 370, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products .product-ordered td { | |||
background-color: #e9e9e9; | |||
} | |||
/* line 354, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products .product-ordered input { | |||
/* line 374, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products .product-ordered input.input-quantity { | |||
font-size: 16px; | |||
font-weight: bold; | |||
} | |||
/* line 360, ../sass/distribution/_index.scss */ | |||
/* line 380, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.price { | |||
width: 150px; | |||
} | |||
/* line 362, ../sass/distribution/_index.scss */ | |||
/* line 383, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.price input { | |||
text-align: center; | |||
} | |||
/* line 367, ../sass/distribution/_index.scss */ | |||
/* line 387, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.price .input-group-addon { | |||
background-color: #eee; | |||
} | |||
/* line 392, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity { | |||
width: 165px; | |||
} | |||
/* line 370, ../sass/distribution/_index.scss */ | |||
/* line 395, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity input { | |||
text-align: center; | |||
color: black; | |||
} | |||
/* line 375, ../sass/distribution/_index.scss */ | |||
/* line 400, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity .form-control { | |||
border-right: 0px none; | |||
padding-right: 4px; | |||
} | |||
/* line 380, ../sass/distribution/_index.scss */ | |||
/* line 405, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity .input-group-addon { | |||
padding: 5px; | |||
padding-left: 0px; | |||
@@ -2207,35 +2233,35 @@ termes. | |||
border-left: 0px none; | |||
border-right: 0px none; | |||
} | |||
/* line 389, ../sass/distribution/_index.scss */ | |||
/* line 414, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity-remaining { | |||
text-align: right; | |||
} | |||
/* line 392, ../sass/distribution/_index.scss */ | |||
/* line 417, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity-remaining.quantity-remaining, .distribution-index .modal-form-order table.table-products td.quantity-remaining.infinite { | |||
color: #00A65A; | |||
} | |||
/* line 396, ../sass/distribution/_index.scss */ | |||
/* line 421, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity-remaining.negative { | |||
color: #DD4B39; | |||
} | |||
/* line 400, ../sass/distribution/_index.scss */ | |||
/* line 425, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products td.quantity-remaining.infinite, .distribution-index .modal-form-order table.table-products td.quantity-remaining.empty { | |||
font-size: 18px; | |||
} | |||
/* line 407, ../sass/distribution/_index.scss */ | |||
/* line 432, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order .actions-form button { | |||
margin-left: 15px; | |||
} | |||
/* line 415, ../sass/distribution/_index.scss */ | |||
/* line 440, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-payment .info-box .info-box-icon { | |||
width: 50px; | |||
} | |||
/* line 418, ../sass/distribution/_index.scss */ | |||
/* line 443, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-payment .info-box .info-box-icon i { | |||
font-size: 30px; | |||
} | |||
/* line 423, ../sass/distribution/_index.scss */ | |||
/* line 448, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-payment .info-box .info-box-content { | |||
margin-left: 50px; | |||
} | |||
@@ -2272,6 +2298,18 @@ termes. | |||
margin-left: 15px; | |||
} | |||
/* line 4, ../sass/producer/_update.scss */ | |||
.producer-update .panel h4 { | |||
font-size: 23px; | |||
margin-bottom: 20px; | |||
text-transform: uppercase; | |||
border-bottom: solid 1px gray; | |||
} | |||
/* line 10, ../sass/producer/_update.scss */ | |||
.producer-update .panel h4:not(:first-child) { | |||
margin-top: 45px; | |||
} | |||
/* line 4, ../sass/point_sale/_index.scss */ | |||
.point-sale-index table .td-default { | |||
text-align: center; |
@@ -1,68 +1,104 @@ | |||
/** | |||
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. | |||
*/ | |||
$(document).ready(function() { | |||
opendistrib_datepicker() ; | |||
$('button[data-toggle=popover]').popover() ; | |||
opendistrib_commandeauto() ; | |||
opendistrib_points_vente_acces() ; | |||
opendistrib_tooltip() ; | |||
opendistrib_ordre_produits() ; | |||
opendistrib_ordre_categories() ; | |||
opendistrib_products() ; | |||
opendistrib_product_prices() ; | |||
opendistrib_confirm_delete() ; | |||
opendistrib_product_availability_points_sale(); | |||
}) ; | |||
/** | |||
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. | |||
*/ | |||
$(document).ready(function () { | |||
opendistrib_datepicker(); | |||
$('button[data-toggle=popover]').popover(); | |||
opendistrib_commandeauto(); | |||
opendistrib_points_vente_acces(); | |||
opendistrib_tooltip(); | |||
opendistrib_ordre_produits(); | |||
opendistrib_ordre_categories(); | |||
opendistrib_products(); | |||
opendistrib_product_prices(); | |||
opendistrib_product_index(); | |||
opendistrib_confirm_delete(); | |||
opendistrib_product_availability_points_sale(); | |||
opendistrib_user_index(); | |||
opendistrib_menu_treeview(); | |||
}); | |||
var UrlManager = { | |||
getBaseUrl: function() { | |||
return $('meta[name=baseurl]').attr('content')+'/' ; | |||
getBaseUrl: function () { | |||
return $('meta[name=baseurl]').attr('content') + '/'; | |||
}, | |||
getBaseUrlAbsolute: function() { | |||
return $('meta[name=baseurl-absolute]').attr('content')+'/' ; | |||
getBaseUrlAbsolute: function () { | |||
return $('meta[name=baseurl-absolute]').attr('content') + '/'; | |||
} | |||
}; | |||
function opendistrib_user_index() { | |||
if ($('body').hasClass('user-index')) { | |||
$('#w0-filters input:first').focus(); | |||
} | |||
} | |||
function opendistrib_menu_treeview() { | |||
$('li.treeview a').unbind('click').click(function () { | |||
var href = $(this).attr('href'); | |||
if (href != '#') { | |||
$(location).attr('href', href); | |||
} | |||
}); | |||
} | |||
function opendistrib_product_index() { | |||
$('body.product-index .toggle input').change(function() { | |||
var id = $(this).data('id'); | |||
var checked = $(this).prop('checked'); | |||
var active = 0; | |||
if(checked) { | |||
active = 1; | |||
} | |||
$.get(UrlManager.getBaseUrl() + 'product/ajax-toggle-active', { | |||
id: id, | |||
active: active | |||
}); | |||
}) | |||
} | |||
function opendistrib_product_availability_points_sale() { | |||
$('input[name="Product[available_on_points_sale]"]').change(function() { | |||
$('input[name="Product[available_on_points_sale]"]').change(function () { | |||
var available = parseInt($(this).val()); | |||
var label = 'disponible'; | |||
if(available == 1) { | |||
if (available == 1) { | |||
label = 'indisponible'; | |||
} | |||
@@ -71,24 +107,24 @@ function opendistrib_product_availability_points_sale() { | |||
} | |||
function opendistrib_confirm_delete() { | |||
$('.btn-confirm-delete').click(function(event) { | |||
if(!confirm('Souhaitez-vous vraiment supprimer cette entrée ?')) { | |||
event.stopPropagation() ; | |||
return false ; | |||
$('.btn-confirm-delete').click(function (event) { | |||
if (!confirm('Souhaitez-vous vraiment supprimer cette entrée ?')) { | |||
event.stopPropagation(); | |||
return false; | |||
} | |||
}) ; | |||
}); | |||
} | |||
function opendistrib_products() { | |||
if($('.product-create').size() || $('.product-update').size()) { | |||
opendistrib_products_event_unit(false) ; | |||
if ($('.product-create').size() || $('.product-update').size()) { | |||
opendistrib_products_event_unit(false); | |||
$('#product-unit').change(function() { | |||
opendistrib_products_event_unit(true) ; | |||
}) ; | |||
$('#product-unit').change(function () { | |||
opendistrib_products_event_unit(true); | |||
}); | |||
opendistrib_products_event_price_with_tax() ; | |||
opendistrib_products_event_price_with_tax(); | |||
$('#product-price').change(opendistrib_products_event_price_with_tax); | |||
$('#product-price-with-tax').change(opendistrib_products_event_price); | |||
@@ -99,21 +135,22 @@ function opendistrib_products() { | |||
function opendistrib_products_event_price_with_tax() { | |||
taxRateSelected = $('#product-id_tax_rate').find('option:selected').data('tax-rate-value'); | |||
if(typeof taxRateSelected == 'undefined') { | |||
taxRateSelected = 0 ; | |||
if (typeof taxRateSelected == 'undefined') { | |||
taxRateSelected = 0; | |||
} | |||
var price = $('#product-price').val() ; | |||
if(price) { | |||
var price = $('#product-price').val().replace(',', '.'); | |||
if (price) { | |||
$('#product-price-with-tax').val(getPriceWithTax(price, taxRateSelected)); | |||
// formattage | |||
$('#product-price').val(parseFloat(price).toFixed(3)); | |||
} | |||
} | |||
function opendistrib_products_event_price(){ | |||
function opendistrib_products_event_price() { | |||
taxRateSelected = $('#product-id_tax_rate').find('option:selected').data('tax-rate-value'); | |||
var priceWithTax = $('#product-price-with-tax').val() ; | |||
if(priceWithTax) { | |||
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)); | |||
@@ -122,55 +159,51 @@ function opendistrib_products_event_price(){ | |||
function opendistrib_products_event_unit(change) { | |||
var unit = $('#product-unit').val() ; | |||
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') ; | |||
var label_price_ht = $('.field-product-price .control-label.without-tax') ; | |||
var label_step = $('.field-product-step .control-label') ; | |||
var label_quantity_max = $('.field-product-quantity_max .control-label') ; | |||
if(unit == 'piece') { | |||
label_price_ttc.html('Prix (la pièce) TTC') ; | |||
label_price_ht.html('Prix (la pièce) HT') ; | |||
label_quantity_max.html('Quantité max par défaut (pièces)') ; | |||
var unit = $('#product-unit').val(); | |||
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(); | |||
} | |||
else if(unit == 'g' || unit == 'kg') { | |||
label_price_ttc.html('Prix (au kg) TTC') ; | |||
label_price_ht.html('Prix (au kg) HT') ; | |||
label_quantity_max.html('Quantité max par défaut (kg)') ; | |||
label_step.html('Pas ('+unit+')') ; | |||
} | |||
else if(unit == 'mL' || unit == 'L') { | |||
label_price_ttc.html('Prix (au litre) TTC') ; | |||
label_price_ht.html('Prix (au litre) HT') ; | |||
label_quantity_max.html('Quantité max par défaut (litres)') ; | |||
label_step.html('Pas ('+unit+')') ; | |||
var label_price_ttc = $('.field-product-price .control-label.with-tax'); | |||
var label_price_ht = $('.field-product-price .control-label.without-tax'); | |||
var label_step = $('.field-product-step .control-label'); | |||
var label_quantity_max = $('.field-product-quantity_max .control-label'); | |||
if (unit == 'piece') { | |||
label_price_ttc.html('Prix (la pièce) TTC'); | |||
label_price_ht.html('Prix (la pièce) HT'); | |||
label_quantity_max.html('Quantité max par défaut (pièces)'); | |||
} else if (unit == 'g' || unit == 'kg') { | |||
label_price_ttc.html('Prix (au kg) TTC'); | |||
label_price_ht.html('Prix (au kg) HT'); | |||
label_quantity_max.html('Quantité max par défaut (kg)'); | |||
label_step.html('Pas (' + unit + ')'); | |||
} else if (unit == 'mL' || unit == 'L') { | |||
label_price_ttc.html('Prix (au litre) TTC'); | |||
label_price_ht.html('Prix (au litre) HT'); | |||
label_quantity_max.html('Quantité max par défaut (litres)'); | |||
label_step.html('Pas (' + unit + ')'); | |||
} | |||
if(change) { | |||
if(unit == 'piece') { | |||
$('#product-step').val(1) ; | |||
} | |||
else { | |||
$('#product-step').val('') ; | |||
if (change) { | |||
if (unit == 'piece') { | |||
$('#product-step').val(1); | |||
} else { | |||
$('#product-step').val(''); | |||
} | |||
} | |||
} | |||
function opendistrib_product_prices() { | |||
if($('.product-prices-create').size() || $('.product-prices-update').size()) { | |||
opendistrib_product_prices_event_price_with_tax() ; | |||
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); | |||
} | |||
@@ -178,8 +211,8 @@ function opendistrib_product_prices() { | |||
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) { | |||
var price = $('#productprice-price').val().replace(',', '.'); | |||
if (price) { | |||
$('#productprice-price-with-tax').val(getPriceWithTax(price, taxRateValue)); | |||
// formattage | |||
$('#productprice-price').val(parseFloat(price).toFixed(3)); | |||
@@ -188,8 +221,8 @@ function opendistrib_product_prices_event_price_with_tax() { | |||
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) { | |||
var priceWithTax = $('#productprice-price-with-tax').val().replace(',', '.'); | |||
if (priceWithTax) { | |||
$('#productprice-price').val(getPrice(priceWithTax, taxRateValue)); | |||
// formattage | |||
$('#productprice-price-with-tax').val(parseFloat(priceWithTax).toFixed(2)); | |||
@@ -197,87 +230,85 @@ function opendistrib_product_prices_event_price() { | |||
} | |||
function opendistrib_tooltip() { | |||
$('[data-toggle="tooltip"]').tooltip({container:'body'}); | |||
$('[data-toggle="tooltip"]').tooltip({container: 'body'}); | |||
} | |||
function opendistrib_nl2br(str, is_xhtml) { | |||
var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>'; | |||
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2'); | |||
function opendistrib_nl2br(str, is_xhtml) { | |||
var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>'; | |||
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2'); | |||
} | |||
function opendistrib_points_vente_acces() { | |||
// affichage du bloc acces restreint | |||
$('#pointsale-restricted_access').change(function() { | |||
opendistrib_points_vente_acces_event() ; | |||
}) ; | |||
opendistrib_points_vente_acces_event() ; | |||
$('#pointsale-restricted_access').change(function () { | |||
opendistrib_points_vente_acces_event(); | |||
}); | |||
opendistrib_points_vente_acces_event(); | |||
// affichage du champs commentaire | |||
$('#pointsale-users input[type=checkbox]').change(function() { | |||
opendistrib_points_vente_commentaire_event() ; | |||
}) ; | |||
opendistrib_points_vente_commentaire_event() ; | |||
$('#pointsale-users input[type=checkbox]').change(function () { | |||
opendistrib_points_vente_commentaire_event(); | |||
}); | |||
opendistrib_points_vente_commentaire_event(); | |||
} | |||
function opendistrib_points_vente_commentaire_event() { | |||
$('#pointsale-users input[type=checkbox]').each(function() { | |||
if($(this).prop('checked')) { | |||
$(this).parent().find('.commentaire').fadeIn() ; | |||
} | |||
else { | |||
$(this).parent().find('.commentaire').hide() ; | |||
$('#pointsale-users input[type=checkbox]').each(function () { | |||
if ($(this).prop('checked')) { | |||
$(this).parent().find('.commentaire').fadeIn(); | |||
} else { | |||
$(this).parent().find('.commentaire').hide(); | |||
} | |||
}) ; | |||
}); | |||
} | |||
function opendistrib_points_vente_acces_event() { | |||
if($('#pointsale-restricted_access').prop('checked')) { | |||
$('#pointsale-users').fadeIn() ; | |||
} | |||
else { | |||
$('#pointsale-users').hide() ; | |||
if ($('#pointsale-restricted_access').prop('checked')) { | |||
$('#pointsale-users').fadeIn(); | |||
} else { | |||
$('#pointsale-users').hide(); | |||
} | |||
} | |||
function opendistrib_commandeauto() { | |||
$('#subscriptionform-date_begin, #subscriptionform-date_end').datepicker() ; | |||
$('#subscriptionform-date_begin, #subscriptionform-date_end').datepicker(); | |||
} | |||
function opendistrib_sortable_list(element_selector, button_selector, route_ajax) { | |||
var fixHelper = function(e, ui) { | |||
ui.children().each(function() { | |||
var fixHelper = function (e, ui) { | |||
ui.children().each(function () { | |||
$(this).width($(this).width()); | |||
}); | |||
return ui; | |||
}; | |||
$(element_selector+" table tbody").sortable({ | |||
$(element_selector + " table tbody").sortable({ | |||
items: "> tr", | |||
appendTo: "parent", | |||
cursor: "move", | |||
placeholder: "ui-state-highlight", | |||
handle: button_selector, | |||
helper: fixHelper, | |||
stop: function(event, ui) { | |||
var tab_ordre = {} ; | |||
var ordre = 1 ; | |||
if($('ul.pagination').size()) { | |||
var page = parseInt($('ul.pagination li.active a').html()) ; | |||
var nb_items_by_page = parseInt($('#page-size').html()) ; | |||
if(page != 1) { | |||
ordre = (page - 1) * nb_items_by_page ; | |||
stop: function (event, ui) { | |||
var tab_ordre = {}; | |||
var ordre = 1; | |||
if ($('ul.pagination').size()) { | |||
var page = parseInt($('ul.pagination li.active a').html()); | |||
var nb_items_by_page = parseInt($('#page-size').html()); | |||
if (page != 1) { | |||
ordre = (page - 1) * nb_items_by_page; | |||
} | |||
} | |||
$(element_selector+" table tbody tr").each(function() { | |||
tab_ordre[$(this).attr('data-key')] = ordre ; | |||
ordre++ ; | |||
}) ; | |||
$(element_selector + " table tbody tr").each(function () { | |||
tab_ordre[$(this).attr('data-key')] = ordre; | |||
ordre++; | |||
}); | |||
$.post(UrlManager.getBaseUrl() + route_ajax,{ | |||
$.post(UrlManager.getBaseUrl() + route_ajax, { | |||
array: JSON.stringify(tab_ordre) | |||
}) ; | |||
}); | |||
} | |||
}).disableSelection(); | |||
} | |||
@@ -287,7 +318,7 @@ function opendistrib_ordre_categories() { | |||
'.product-category-index', | |||
'.btn-position', | |||
'product-category/position' | |||
) ; | |||
); | |||
} | |||
function opendistrib_ordre_produits() { | |||
@@ -296,7 +327,7 @@ function opendistrib_ordre_produits() { | |||
'.product-index', | |||
'.btn-order', | |||
'product/order' | |||
) ; | |||
); | |||
/*var fixHelper = function(e, ui) { | |||
ui.children().each(function() { | |||
@@ -338,45 +369,46 @@ function opendistrib_ordre_produits() { | |||
} | |||
function opendistrib_datepicker() { | |||
$('input.datepicker').datepicker({dateFormat:'dd/mm/yy'}) ; | |||
$('input.datepicker').datepicker({dateFormat: 'dd/mm/yy'}); | |||
} | |||
/* French initialisation for the jQuery UI date picker plugin. */ | |||
/* Written by Keith Wood (kbwood{at}iinet.com.au), | |||
Stéphane Nahmani (sholby@sholby.net), | |||
Stéphane Raimbault <stephane.raimbault@gmail.com> */ | |||
(function( factory ) { | |||
if ( typeof define === "function" && define.amd ) { | |||
// AMD. Register as an anonymous module. | |||
define([ "../jquery.ui.datepicker" ], factory ); | |||
} else { | |||
// Browser globals | |||
factory( jQuery.datepicker ); | |||
} | |||
}(function( datepicker ) { | |||
datepicker.regional['fr'] = { | |||
closeText: 'Fermer', | |||
prevText: 'Précédent', | |||
nextText: 'Suivant', | |||
currentText: 'Aujourd\'hui', | |||
monthNames: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', | |||
'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], | |||
monthNamesShort: ['janv.', 'févr.', 'mars', 'avril', 'mai', 'juin', | |||
'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'], | |||
dayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'], | |||
dayNamesShort: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'], | |||
dayNamesMin: ['D','L','M','M','J','V','S'], | |||
weekHeader: 'Sem.', | |||
dateFormat: 'dd/mm/yy', | |||
firstDay: 1, | |||
isRTL: false, | |||
showMonthAfterYear: false, | |||
yearSuffix: ''}; | |||
datepicker.setDefaults(datepicker.regional['fr']); | |||
return datepicker.regional['fr']; | |||
(function (factory) { | |||
if (typeof define === "function" && define.amd) { | |||
// AMD. Register as an anonymous module. | |||
define(["../jquery.ui.datepicker"], factory); | |||
} else { | |||
// Browser globals | |||
factory(jQuery.datepicker); | |||
} | |||
}(function (datepicker) { | |||
datepicker.regional['fr'] = { | |||
closeText: 'Fermer', | |||
prevText: 'Précédent', | |||
nextText: 'Suivant', | |||
currentText: 'Aujourd\'hui', | |||
monthNames: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', | |||
'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], | |||
monthNamesShort: ['janv.', 'févr.', 'mars', 'avril', 'mai', 'juin', | |||
'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'], | |||
dayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'], | |||
dayNamesShort: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'], | |||
dayNamesMin: ['D', 'L', 'M', 'M', 'J', 'V', 'S'], | |||
weekHeader: 'Sem.', | |||
dateFormat: 'dd/mm/yy', | |||
firstDay: 1, | |||
isRTL: false, | |||
showMonthAfterYear: false, | |||
yearSuffix: '' | |||
}; | |||
datepicker.setDefaults(datepicker.regional['fr']); | |||
return datepicker.regional['fr']; | |||
})); | |||
@@ -37,90 +37,95 @@ termes. | |||
var app = new Vue({ | |||
el: '#app-distribution-index', | |||
data: { | |||
UrlManager: UrlManager, | |||
baseUrl: $('meta[name=baseurl]').attr('content'), | |||
date: null, | |||
dateFormat: null, | |||
loading: true, | |||
distribution: { | |||
active: false, | |||
}, | |||
producer: null, | |||
oneDistributionWeekActive: false, | |||
products: [], | |||
countActiveProducts: 0, | |||
pointsSale: [], | |||
meansPayment: [], | |||
idActivePointSale: 0, | |||
idDefaultPointSale: 0, | |||
countActivePointsSale: 0, | |||
countOrdersByPointSale: [], | |||
orders: [], | |||
ordersUpdate: [], | |||
countOrders: 0, | |||
users: [], | |||
deliveryNotes: [], | |||
showModalProducts: false, | |||
showModalPointsSale: false, | |||
showModalFormOrderCreate: false, | |||
orderCreate: null, | |||
showModalFormOrderUpdate: false, | |||
idOrderUpdate: 0, | |||
showViewProduct: false, | |||
idOrderView: 0, | |||
showModalPayment: false, | |||
idOrderPayment: 0, | |||
showLoading: false, | |||
tillerIsSynchro: false, | |||
checkboxSelectAllOrders: false, | |||
messageGenerateDeliveryNoteDisplayed: false, | |||
missingSubscriptions: false, | |||
loadingUpdateProductOrder: false, | |||
calendar: { | |||
mode: 'single', | |||
attrs: [], | |||
themeStyles: { | |||
wrapper: { | |||
background: '#F7F7F7', | |||
color: '#333', | |||
border: 'solid 1px #e0e0e0' | |||
}, | |||
header: { | |||
padding: '10px 10px', | |||
}, | |||
headerHorizontalDivider: { | |||
borderTop: 'solid rgba(255, 255, 255, 0.2) 1px', | |||
width: '80%', | |||
}, | |||
weekdays: { | |||
color: '#e0e0e0', | |||
fontWeight: '600', | |||
padding: '10px 10px', | |||
fontSize: '2rem' | |||
}, | |||
weeks: { | |||
padding: '0 15px 15px 15px', | |||
data() { | |||
return Object.assign( | |||
{ | |||
UrlManager: UrlManager, | |||
baseUrl: $('meta[name=baseurl]').attr('content'), | |||
date: null, | |||
dateFormat: null, | |||
loading: true, | |||
distribution: { | |||
active: false, | |||
}, | |||
dayContent: function(object) { | |||
var style = { | |||
fontSize: '2rem', | |||
padding: '16px', | |||
}; | |||
if(object.isHovered || object.isFocus) { | |||
style.backgroundColor = '#F39C12' ; | |||
producer: null, | |||
oneDistributionWeekActive: false, | |||
products: [], | |||
countActiveProducts: 0, | |||
pointsSale: [], | |||
meansPayment: [], | |||
idActivePointSale: 0, | |||
idDefaultPointSale: 0, | |||
countActivePointsSale: 0, | |||
countOrdersByPointSale: [], | |||
orders: [], | |||
ordersUpdate: [], | |||
countOrders: 0, | |||
users: [], | |||
deliveryNotes: [], | |||
showModalProducts: false, | |||
showModalPointsSale: false, | |||
showModalFormOrderCreate: false, | |||
orderCreate: null, | |||
showModalFormOrderUpdate: false, | |||
idOrderUpdate: 0, | |||
showViewProduct: false, | |||
idOrderView: 0, | |||
showModalPayment: false, | |||
idOrderPayment: 0, | |||
showLoading: false, | |||
tillerIsSynchro: false, | |||
checkboxSelectAllOrders: false, | |||
messageGenerateDeliveryNoteDisplayed: false, | |||
missingSubscriptions: false, | |||
loadingUpdateProductOrder: false, | |||
calendar: { | |||
mode: 'single', | |||
attrs: [], | |||
themeStyles: { | |||
wrapper: { | |||
background: '#F7F7F7', | |||
color: '#333', | |||
border: 'solid 1px #e0e0e0' | |||
}, | |||
header: { | |||
padding: '10px 10px', | |||
}, | |||
headerHorizontalDivider: { | |||
borderTop: 'solid rgba(255, 255, 255, 0.2) 1px', | |||
width: '80%', | |||
}, | |||
weekdays: { | |||
color: '#e0e0e0', | |||
fontWeight: '600', | |||
padding: '10px 10px', | |||
fontSize: '2rem' | |||
}, | |||
weeks: { | |||
padding: '0 15px 15px 15px', | |||
}, | |||
dayContent: function(object) { | |||
var style = { | |||
fontSize: '2rem', | |||
padding: '16px', | |||
}; | |||
if(object.isHovered || object.isFocus) { | |||
style.backgroundColor = '#F39C12' ; | |||
} | |||
return style ; | |||
}, | |||
}, | |||
formats: { | |||
dayPopover: 'DD/MM/YYYY' | |||
} | |||
return style ; | |||
}, | |||
}, | |||
formats: { | |||
dayPopover: 'DD/MM/YYYY' | |||
} | |||
}, | |||
, window.vueValues); | |||
}, | |||
mounted: function() { | |||
if($('#distribution-date').size()) { | |||
this.date = new Date($('#distribution-date').html()) ; | |||
@@ -128,7 +133,6 @@ var app = new Vue({ | |||
+ ('0' + (this.date.getMonth() +1)).slice(-2) + '/' | |||
+ this.date.getFullYear() ; | |||
} | |||
this.init() ; | |||
this.loading = false ; | |||
}, | |||
@@ -220,6 +224,10 @@ var app = new Vue({ | |||
appAlerts.alert('info','Pour générer un bon de livraison, sélectionnez tout d\'abord un jour et un lieu de distribution.', 6000) ; | |||
app.messageGenerateDeliveryNoteDisplayed = true ; | |||
} | |||
if(app.idOrderUpdate) { | |||
app.updateOrderFromUrl(); | |||
} | |||
}) ; | |||
}, | |||
initCountActiveProducts: function() { | |||
@@ -360,6 +368,10 @@ var app = new Vue({ | |||
app.init(app.idActivePointSale) ; | |||
}) ; | |||
}, | |||
updateOrderFromUrl: function() { | |||
this.initModalFormOrder() ; | |||
this.updateProductOrderPrices(false); | |||
}, | |||
updateOrderClick: function(event) { | |||
var idOrder = event.currentTarget.getAttribute('data-id-order') ; | |||
this.idOrderUpdate = idOrder ; | |||
@@ -446,10 +458,19 @@ var app = new Vue({ | |||
var total = 0 ; | |||
for(var i = 0; i < this.orders.length ; i++) { | |||
if(this.orders[i].id_point_sale == this.idActivePointSale) { | |||
total += this.orders[i].amount ; | |||
total += parseFloat(this.orders[i].amount) ; | |||
} | |||
} | |||
return total.toFixed(2); | |||
}, | |||
weightActivePointSale: function() { | |||
var weight = 0 ; | |||
for(var i = 0; i < this.orders.length ; i++) { | |||
if(this.orders[i].id_point_sale == this.idActivePointSale) { | |||
weight += parseFloat(this.orders[i].weight) ; | |||
} | |||
} | |||
return formatPrice(total) ; | |||
return weight.toFixed(2) ; | |||
}, | |||
changeSynchroTiller: function(event) { | |||
var app = this ; | |||
@@ -598,11 +619,13 @@ var app = new Vue({ | |||
.then(function (response) { | |||
if (response.data) { | |||
for (idProduct in response.data) { | |||
if (app.showModalFormOrderCreate) { | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'prices', response.data[idProduct].prices); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'active', response.data[idProduct].active); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'unit_coefficient', response.data[idProduct].unit_coefficient); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'price', app.getBestProductPrice(app.orderCreate, idProduct, app.orderCreate.productOrder[idProduct].quantity)); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'price', app.getBestProductPrice(app.orderCreate, idProduct, app.orderCreate.productOrder[idProduct].quantity, false)); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'price_with_tax', app.getBestProductPrice(app.orderCreate, idProduct, app.orderCreate.productOrder[idProduct].quantity, true)); | |||
} | |||
if (app.showModalFormOrderUpdate && app.idOrderUpdate) { | |||
@@ -611,48 +634,80 @@ var app = new Vue({ | |||
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'prices', response.data[idProduct].prices); | |||
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'active', response.data[idProduct].active); | |||
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'unit_coefficient', response.data[idProduct].unit_coefficient); | |||
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'prices', response.data[idProduct].prices); | |||
if(updatePricesOnUpdateOrder) { | |||
console.log('new price : '); | |||
Vue.set( | |||
app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], | |||
'price', | |||
app.getBestProductPrice(app.ordersUpdate[keyOrderUpdate], idProduct, app.ordersUpdate[keyOrderUpdate].productOrder[idProduct].quantity)); | |||
app.getBestProductPrice(app.ordersUpdate[keyOrderUpdate], idProduct, app.ordersUpdate[keyOrderUpdate].productOrder[idProduct].quantity, false)); | |||
Vue.set( | |||
app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], | |||
'price_with_tax', | |||
app.getBestProductPrice(app.ordersUpdate[keyOrderUpdate], idProduct, app.ordersUpdate[keyOrderUpdate].productOrder[idProduct].quantity, true)); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
if(updatePricesOnUpdateOrder) { | |||
appAlerts.alert('info','Prix rechargés') ; | |||
} | |||
} | |||
app.loadingUpdateProductOrder = false; | |||
}); | |||
} | |||
}, | |||
getBestProductPrice: function(order, idProduct, theQuantity) { | |||
var thePriceWithTax = 9999; | |||
getBestProductPrice: function(order, idProduct, theQuantity, withTax) { | |||
var thePrice = 9999; | |||
var pricesArray = order.productOrder[idProduct].prices; | |||
var unitCoefficient = order.productOrder[idProduct].unit_coefficient; | |||
if(theQuantity) { | |||
theQuantity = theQuantity / unitCoefficient; | |||
} | |||
for(var i = 0; i < pricesArray.length ; i++) { | |||
var priceWithTax = pricesArray[i].price_with_tax; | |||
var fromQuantity = pricesArray[i].from_quantity; | |||
if(pricesArray) { | |||
for(var i = 0; i < pricesArray.length ; i++) { | |||
var price = pricesArray[i].price; | |||
if(withTax) { | |||
price = pricesArray[i].price_with_tax | |||
} | |||
var fromQuantity = pricesArray[i].from_quantity; | |||
if(priceWithTax < thePriceWithTax && fromQuantity <= theQuantity) { | |||
thePriceWithTax = priceWithTax; | |||
if(price < thePrice && fromQuantity <= theQuantity) { | |||
thePrice = price; | |||
} | |||
} | |||
} | |||
else { | |||
var product = this.getProduct(idProduct); | |||
if(withTax) { | |||
thePrice = getPriceWithTax(product.price, product.taxRate.value); | |||
} | |||
else { | |||
thePrice = product.price; | |||
} | |||
} | |||
if(thePriceWithTax == 9999) { | |||
if(thePrice == 9999) { | |||
return 0; | |||
} | |||
else { | |||
return thePriceWithTax; | |||
return thePrice; | |||
} | |||
}, | |||
getProduct: function(idProduct) { | |||
for(var i= 0; i < this.products.length; i++) { | |||
if(this.products[i].id == idProduct) { | |||
return this.products[i]; | |||
} | |||
} | |||
return false; | |||
}, | |||
}, | |||
}); | |||
@@ -661,16 +716,17 @@ Vue.component('modal', { | |||
}) | |||
Vue.component('order-form',{ | |||
props: ['date', 'pointsSale','meansPayment', 'users', 'products', 'order', 'producer', 'loadingUpdateProductOrder'], | |||
props: ['date', 'dateFormat', 'pointsSale', 'idActivePointSale', 'meansPayment', 'users', 'products', 'order', 'producer', 'loadingUpdateProductOrder'], | |||
emits: ['updateProductPrice'], | |||
data: function() { | |||
return { | |||
errors: [], | |||
idPointSale: 0, | |||
idPointSale: 0, | |||
idUser: 0, | |||
username : '', | |||
comment: '', | |||
baseUrl: $('meta[name=baseurl]').attr('content'), | |||
vatMode: 'with_tax' | |||
} ; | |||
}, | |||
template: '#order-form-template', | |||
@@ -771,21 +827,55 @@ Vue.component('order-form',{ | |||
} | |||
Vue.set(this.order.productOrder[id_product], 'quantity', theQuantity); | |||
Vue.set(this.order.productOrder[id_product], 'price', app.getBestProductPrice(this.order, id_product, theQuantity)); | |||
Vue.set(this.order.productOrder[id_product], 'price', app.getBestProductPrice(this.order, id_product, theQuantity, false)); | |||
Vue.set(this.order.productOrder[id_product], 'price_with_tax', app.getBestProductPrice(this.order, id_product, theQuantity, true)); | |||
} | |||
}, | |||
productPriceChange: function(event) { | |||
var idProduct = event.currentTarget.getAttribute('data-id-product') ; | |||
var price = parseFloat(event.currentTarget.value) ; | |||
if(isNaN(price)) { | |||
price = 0 ; | |||
getProduct: function(idProduct) { | |||
for(var i= 0; i < this.products.length; i++) { | |||
if(this.products[i].id == idProduct) { | |||
return this.products[i]; | |||
} | |||
} | |||
Vue.set(this.order.productOrder, idProduct, { | |||
quantity: this.order.productOrder[idProduct].quantity, | |||
unit: this.order.productOrder[idProduct].unit, | |||
price: price | |||
}); | |||
return false; | |||
}, | |||
productPriceChange: function(event) { | |||
var idProduct = event.currentTarget.getAttribute('data-id-product'); | |||
var product = this.getProduct(idProduct); | |||
if(product) { | |||
var taxRateValue = parseFloat(product.taxRate.value); | |||
var withTax = event.currentTarget.getAttribute('data-with-tax'); | |||
var price = 0; | |||
var priceWithTax = 0; | |||
var priceValue = parseFloat(event.currentTarget.value.replace(',', '.')); | |||
if(withTax) { | |||
priceWithTax = priceValue.toFixed(2); | |||
price = getPrice(priceWithTax, taxRateValue); | |||
} | |||
else { | |||
price = priceValue.toFixed(3); | |||
priceWithTax = getPriceWithTax(price, taxRateValue); | |||
} | |||
if(isNaN(price)) { | |||
price = 0 ; | |||
} | |||
if(isNaN(priceWithTax)) { | |||
priceWithTax = 0 ; | |||
} | |||
Vue.set(this.order.productOrder, idProduct, { | |||
active: this.order.productOrder[idProduct].active, | |||
quantity: this.order.productOrder[idProduct].quantity, | |||
unit: this.order.productOrder[idProduct].unit, | |||
price: price, | |||
price_with_tax: priceWithTax | |||
}); | |||
} | |||
}, | |||
userChange: function(event) { | |||
var app = this ; | |||
@@ -793,7 +883,9 @@ Vue.component('order-form',{ | |||
idUser: app.order.id_user, | |||
}}) | |||
.then(function(response) { | |||
app.order.id_point_sale = response.data.id_favorite_point_sale ; | |||
if(app.idActivePointSale == 0) { | |||
app.order.id_point_sale = response.data.id_favorite_point_sale ; | |||
} | |||
app.updateProductOrderPrices(true) ; | |||
}) ; | |||
}, | |||
@@ -802,6 +894,14 @@ Vue.component('order-form',{ | |||
}, | |||
updateProductOrderPrices: function(updateProductOrderPrices) { | |||
this.$emit('updateproductorderprices', updateProductOrderPrices) ; | |||
}, | |||
toggleVatMode: function() { | |||
if(this.vatMode == 'all') { | |||
this.vatMode = 'with_tax'; | |||
} | |||
else { | |||
this.vatMode = 'all'; | |||
} | |||
} | |||
} | |||
}) ; |
@@ -47,13 +47,18 @@ var app = new Vue({ | |||
isAdminSection: 0 | |||
}, | |||
{ | |||
name: 'tableau-bord', | |||
nameDisplay: 'Tableau de bord', | |||
name: 'prise-commande', | |||
nameDisplay: 'Commandes', | |||
isAdminSection: 0 | |||
}, | |||
{ | |||
name: 'prise-commande', | |||
nameDisplay: 'Prise de commande', | |||
name: 'credit-payment', | |||
nameDisplay: 'Crédit', | |||
isAdminSection: 0 | |||
}, | |||
{ | |||
name: 'facturation', | |||
nameDisplay: 'Facturation', | |||
isAdminSection: 0 | |||
}, | |||
{ | |||
@@ -62,8 +67,8 @@ var app = new Vue({ | |||
isAdminSection: 0 | |||
}, | |||
{ | |||
name: 'credit-payment', | |||
nameDisplay: 'Crédit', | |||
name: 'tableau-bord', | |||
nameDisplay: 'Tableau de bord', | |||
isAdminSection: 0 | |||
}, | |||
{ | |||
@@ -76,11 +81,6 @@ var app = new Vue({ | |||
nameDisplay: 'Logiciels de caisse', | |||
isAdminSection: 0 | |||
}, | |||
{ | |||
name: 'facturation', | |||
nameDisplay: 'Facturation', | |||
isAdminSection: 0 | |||
}, | |||
{ | |||
name: 'administration', | |||
nameDisplay: 'Administration', |
@@ -5,6 +5,7 @@ | |||
right: 15px ; | |||
width: 300px ; | |||
height: auto ; | |||
z-index: 9999; | |||
.slide-fade-enter-active { | |||
@include transition(all .3s ease); |
@@ -36,394 +36,419 @@ termes. | |||
.distribution-index { | |||
.content-header { | |||
.date { | |||
font-weight: bold; | |||
} | |||
.content-header { | |||
.date { | |||
font-weight: bold; | |||
} | |||
} | |||
#wrapper-app-distribution-index { | |||
display: none; | |||
&.loaded { | |||
display: block; | |||
} | |||
} | |||
#app-distribution-index { | |||
position: relative; | |||
} | |||
#distribution-date { | |||
display: none; | |||
} | |||
#calendar { | |||
margin-bottom: 15px; | |||
.c-header .c-title-layout .c-title-popover .c-title-anchor .c-title[data-v-2083cb72] { | |||
font-size: 2rem; | |||
} | |||
.c-day-background { | |||
//background-color: #F39C12; | |||
//background-color: white ; | |||
padding: 16px; | |||
//border: solid 1px black !important ; | |||
//opacity: 1 ; | |||
} | |||
.c-day-popover-content { | |||
font-size: 1.3rem; | |||
} | |||
.c-title { | |||
text-transform: uppercase; | |||
font-family: 'capsuularegular'; | |||
} | |||
} | |||
#products { | |||
td.quantities { | |||
width: 100px; | |||
text-align: right; | |||
} | |||
input.quantity-max { | |||
width: 50px; | |||
text-align: center; | |||
display: inline; | |||
} | |||
} | |||
#infos-top { | |||
.col-md-4 { | |||
padding: 0px; | |||
} | |||
$height-info-box: 96px ; | |||
.info-box { | |||
min-height: $height-info-box; | |||
height: $height-info-box; | |||
.info-box-icon { | |||
height: $height-info-box; | |||
width: 50px; | |||
line-height: $height-info-box; | |||
i.fa { | |||
font-size: 30px; | |||
} | |||
} | |||
#wrapper-app-distribution-index { | |||
display: none; | |||
.info-box-content { | |||
margin-left: 55px; | |||
.info-box-text { | |||
font-size: 12px; | |||
.btn { | |||
font-size: 12px; | |||
text-transform: uppercase; | |||
} | |||
} | |||
.info-box-number { | |||
font-size: 14px; | |||
} | |||
} | |||
} | |||
#info-box-distribution { | |||
.btn-active-week { | |||
float: right; | |||
} | |||
} | |||
#summary-ca-weight { | |||
.normal { | |||
font-weight: normal; | |||
} | |||
} | |||
} | |||
#modal-products { | |||
table.table { | |||
thead { | |||
tr { | |||
td { | |||
font-weight: bold; | |||
} | |||
} | |||
} | |||
td.quantity-ordered, | |||
td.quantity-max { | |||
text-align: center; | |||
} | |||
td.quantity-ordered { | |||
width: 50px; | |||
} | |||
td.quantity-max { | |||
width: 120px; | |||
input { | |||
text-align: center; | |||
min-width: 50px; | |||
} | |||
} | |||
} | |||
} | |||
#orders { | |||
position: relative; | |||
.panel-heading { | |||
.buttons { | |||
.btn { | |||
position: relative; | |||
top: -19px; | |||
float: right; | |||
margin-left: 10px; | |||
} | |||
} | |||
} | |||
#wrapper-nav-points-sale { | |||
margin-bottom: 10px; | |||
ul#nav-points-sale { | |||
margin: 0px; | |||
padding: 0px; | |||
list-style-type: none; | |||
li { | |||
float: left; | |||
margin-right: 10px; | |||
margin-bottom: 10px; | |||
a { | |||
.label { | |||
background-color: white; | |||
border: solid 1px #e0e0e0; | |||
@include border-radius(10px) ; | |||
} | |||
} | |||
&.loaded { | |||
display: block; | |||
} | |||
} | |||
} | |||
} | |||
#buttons-top-orders { | |||
background-color: #F5F5F5; | |||
padding: 10px 20px; | |||
border: solid 1px #e0e0e0; | |||
@include border-radius(5px) ; | |||
margin-bottom: 20px; | |||
.left { | |||
} | |||
.right { | |||
float: right; | |||
} | |||
.dropdown { | |||
display: inline-block; | |||
} | |||
} | |||
.point-sale-totals { | |||
background-color: white; | |||
padding: 10px 20px; | |||
border: solid 1px #e0e0e0; | |||
@include border-radius(5px) ; | |||
margin-bottom: 20px; | |||
.title { | |||
color: gray; | |||
font-size: 13px; | |||
margin-right: 13px; | |||
text-transform: uppercase; | |||
} | |||
} | |||
table { | |||
td.tiller { | |||
width: 60px; | |||
label { | |||
font-size: 12px; | |||
cursor: pointer; | |||
position: relative; | |||
top: -2px; | |||
font-weight: normal; | |||
} | |||
} | |||
td.column-actions { | |||
position: relative; | |||
text-align: right; | |||
#app-distribution-index { | |||
position: relative; | |||
.dropdown-menu { | |||
top: 0px; | |||
right: 0px; | |||
} | |||
#distribution-date { | |||
display: none; | |||
.modal-form-order, | |||
.modal-payment { | |||
text-align: left; | |||
} | |||
#calendar { | |||
margin-bottom: 15px; | |||
.c-header .c-title-layout .c-title-popover .c-title-anchor .c-title[data-v-2083cb72] { | |||
font-size: 2rem; | |||
} | |||
.c-day-background { | |||
//background-color: #F39C12; | |||
//background-color: white ; | |||
padding: 16px; | |||
//border: solid 1px black !important ; | |||
//opacity: 1 ; | |||
} | |||
.c-day-popover-content { | |||
font-size: 1.3rem; | |||
} | |||
.c-title { | |||
text-transform: uppercase; | |||
font-family: 'capsuularegular'; | |||
} | |||
.add-subscription { | |||
position: relative; | |||
.glyphicon-plus { | |||
position: absolute; | |||
top: 4px; | |||
right: 4px; | |||
font-size: 7px; | |||
} | |||
} | |||
} | |||
td.column-state-payment { | |||
width: 120px; | |||
} | |||
#products { | |||
td.quantities { | |||
width: 100px; | |||
text-align: right; | |||
} | |||
input.quantity-max { | |||
width: 50px; | |||
text-align: center; | |||
display: inline; | |||
} | |||
td.column-payment { | |||
div.btn-group { | |||
width: 125px; | |||
} | |||
} | |||
tr.view { | |||
ul { | |||
list-style-type: none; | |||
margin-left: 0px; | |||
padding-left: 15px; | |||
#infos-top { | |||
.col-md-4 { | |||
padding: 0px; | |||
} | |||
$height-info-box: 96px ; | |||
.info-box { | |||
min-height: $height-info-box; | |||
height: $height-info-box; | |||
.info-box-icon { | |||
height: $height-info-box; | |||
width: 50px; | |||
line-height: $height-info-box; | |||
i.fa { | |||
font-size: 30px; | |||
} | |||
} | |||
.info-box-content { | |||
margin-left: 55px; | |||
.info-box-text { | |||
font-size: 12px; | |||
.btn { | |||
font-size: 12px; | |||
text-transform: uppercase; | |||
} | |||
} | |||
.info-box-number { | |||
font-size: 14px; | |||
} | |||
} | |||
} | |||
#info-box-distribution { | |||
.btn-active-week { | |||
float: right; | |||
} | |||
} | |||
#summary-ca-weight { | |||
.normal { | |||
font-weight: normal; | |||
} | |||
} | |||
li { | |||
} | |||
} | |||
#modal-products { | |||
table.table { | |||
thead { | |||
tr { | |||
td { | |||
font-weight: bold; | |||
} | |||
} | |||
} | |||
td.quantity-ordered, | |||
td.quantity-max { | |||
text-align: center; | |||
} | |||
td.quantity-ordered { | |||
width: 50px; | |||
} | |||
td.quantity-max { | |||
width: 120px; | |||
input { | |||
text-align: center; | |||
min-width: 50px; | |||
} | |||
} | |||
} | |||
.comment { | |||
margin-top: 20px; | |||
} | |||
#orders { | |||
position: relative; | |||
.panel-heading { | |||
.buttons { | |||
.btn { | |||
position: relative; | |||
top: -19px; | |||
float: right; | |||
margin-left: 10px; | |||
} | |||
} | |||
} | |||
#wrapper-nav-points-sale { | |||
margin-bottom: 10px; | |||
ul#nav-points-sale { | |||
margin: 0px; | |||
padding: 0px; | |||
list-style-type: none; | |||
li { | |||
float: left; | |||
margin-right: 10px; | |||
margin-bottom: 10px; | |||
a { | |||
.label { | |||
background-color: white; | |||
border: solid 1px #e0e0e0; | |||
@include border-radius(10px) ; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
#buttons-top-orders { | |||
background-color: #F5F5F5; | |||
padding: 10px 20px; | |||
border: solid 1px #e0e0e0; | |||
@include border-radius(5px) ; | |||
margin-bottom: 20px; | |||
.left { | |||
} | |||
.right { | |||
float: right; | |||
} | |||
.dropdown { | |||
display: inline-block ; | |||
} | |||
} | |||
table { | |||
td.tiller { | |||
width: 60px; | |||
label { | |||
font-size: 12px; | |||
cursor: pointer; | |||
position: relative; | |||
top: -2px; | |||
font-weight: normal; | |||
} | |||
} | |||
td.column-actions { | |||
position: relative; | |||
text-align: right; | |||
.dropdown-menu { | |||
top: 0px; | |||
right: 0px; | |||
} | |||
.modal-form-order, | |||
.modal-payment { | |||
text-align: left; | |||
} | |||
.add-subscription { | |||
position: relative; | |||
.glyphicon-plus { | |||
position: absolute; | |||
top: 4px; | |||
right: 4px; | |||
font-size: 7px; | |||
} | |||
} | |||
} | |||
td.column-state-payment { | |||
width: 120px; | |||
} | |||
td.column-payment { | |||
div.btn-group { | |||
width: 125px; | |||
} | |||
} | |||
tr.view { | |||
ul { | |||
list-style-type: none; | |||
margin-left: 0px; | |||
padding-left: 15px; | |||
li { | |||
} | |||
} | |||
.comment { | |||
margin-top: 20px; | |||
} | |||
.delivery { | |||
margin-top: 20px; | |||
} | |||
} | |||
} | |||
.delivery { | |||
margin-top: 20px; | |||
} | |||
} | |||
} | |||
} | |||
.modal-form-order { | |||
.modal-container { | |||
width: 100%; | |||
padding: 0px; | |||
.modal-form-order { | |||
.modal-container { | |||
width: 100%; | |||
padding: 0px; | |||
.modal-body { | |||
padding-right: 15px; | |||
table { | |||
margin-bottom: 150px; | |||
} | |||
} | |||
.modal-footer { | |||
border-top-color: #f4f4f4; | |||
position: fixed; | |||
bottom: 0; | |||
right: 0; | |||
z-index: 99999; | |||
background-color: white; | |||
width: 100%; | |||
text-align: center; | |||
border-top: solid 1px #e0e0e0; | |||
.actions-form { | |||
button { | |||
float: none; | |||
} | |||
} | |||
} | |||
} | |||
.btn-credit { | |||
float: right; | |||
} | |||
table.table-products { | |||
.product-ordered { | |||
td { | |||
background-color: #e9e9e9; | |||
} | |||
input { | |||
font-size: 16px; | |||
font-weight: bold; | |||
} | |||
} | |||
td.price { | |||
width: 150px ; | |||
input { | |||
text-align: center ; | |||
} | |||
} | |||
td.quantity { | |||
width: 165px; | |||
input { | |||
text-align: center; | |||
color: black; | |||
} | |||
.form-control { | |||
border-right: 0px none; | |||
padding-right: 4px; | |||
} | |||
.input-group-addon { | |||
padding: 5px; | |||
padding-left: 0px; | |||
margin: 0px; | |||
border-left: 0px none; | |||
border-right: 0px none; | |||
} | |||
} | |||
td.quantity-remaining { | |||
text-align: right; | |||
&.quantity-remaining, &.infinite { | |||
color: #00A65A; | |||
} | |||
&.negative { | |||
color: #DD4B39; | |||
} | |||
&.infinite, &.empty { | |||
font-size: 18px; | |||
} | |||
} | |||
} | |||
.actions-form { | |||
button { | |||
margin-left: 15px; | |||
} | |||
} | |||
.modal-body { | |||
padding-right: 15px; | |||
table { | |||
margin-bottom: 150px; | |||
} | |||
} | |||
.modal-footer { | |||
border-top-color: #f4f4f4; | |||
position: fixed; | |||
bottom: 0; | |||
right: 0; | |||
z-index: 99999; | |||
background-color: white; | |||
width: 100%; | |||
text-align: center; | |||
border-top: solid 1px #e0e0e0; | |||
.actions-form { | |||
button { | |||
float: none; | |||
} | |||
div.right { | |||
float: right; | |||
} | |||
} | |||
} | |||
} | |||
.modal-payment { | |||
.info-box { | |||
.info-box-icon { | |||
width: 50px; | |||
i { | |||
font-size: 30px; | |||
} | |||
} | |||
.info-box-content { | |||
margin-left: 50px; | |||
} | |||
} | |||
.btn-credit { | |||
float: right; | |||
} | |||
table.table-products { | |||
.product-ordered { | |||
td { | |||
background-color: #e9e9e9; | |||
} | |||
input.input-quantity { | |||
font-size: 16px; | |||
font-weight: bold; | |||
} | |||
} | |||
td.price { | |||
width: 150px; | |||
input { | |||
text-align: center; | |||
} | |||
.input-group-addon { | |||
background-color: #eee; | |||
} | |||
} | |||
td.quantity { | |||
width: 165px; | |||
input { | |||
text-align: center; | |||
color: black; | |||
} | |||
.form-control { | |||
border-right: 0px none; | |||
padding-right: 4px; | |||
} | |||
.input-group-addon { | |||
padding: 5px; | |||
padding-left: 0px; | |||
margin: 0px; | |||
border-left: 0px none; | |||
border-right: 0px none; | |||
} | |||
} | |||
td.quantity-remaining { | |||
text-align: right; | |||
&.quantity-remaining, &.infinite { | |||
color: #00A65A; | |||
} | |||
&.negative { | |||
color: #DD4B39; | |||
} | |||
&.infinite, &.empty { | |||
font-size: 18px; | |||
} | |||
} | |||
} | |||
.actions-form { | |||
button { | |||
margin-left: 15px; | |||
} | |||
} | |||
} | |||
.modal-payment { | |||
.info-box { | |||
.info-box-icon { | |||
width: 50px; | |||
i { | |||
font-size: 30px; | |||
} | |||
} | |||
.info-box-content { | |||
margin-left: 50px; | |||
} | |||
} | |||
} | |||
} | |||
@@ -1,4 +1,14 @@ | |||
.producer-update { | |||
.panel { | |||
h4 { | |||
font-size: 23px; | |||
margin-bottom: 20px; | |||
text-transform: uppercase; | |||
border-bottom: solid 1px gray; | |||
} | |||
h4:not(:first-child) { | |||
margin-top: 45px; | |||
} | |||
} | |||
} |
@@ -42,168 +42,189 @@ use common\helpers\GlobalParam; | |||
class ActiveRecordCommon extends \yii\db\ActiveRecord | |||
{ | |||
const SEARCH_ALL = 'all'; | |||
const SEARCH_ONE = 'one'; | |||
const SEARCH_COUNT = 'count'; | |||
/** | |||
* Méthode générique de recherche utilisée pour tous les modèles. Elle a | |||
* pour but de construire la requête et de retourner le résultat. | |||
* | |||
* @param array $params | |||
* @param array $options | |||
* @return mixed | |||
* @throws NotFoundHttpException | |||
*/ | |||
public static function searchBy($params = [], $options = []) | |||
{ | |||
$class = get_called_class(); | |||
if (is_callable([$class, 'defaultOptionsSearch'])) { | |||
$default_options = $class::defaultOptionsSearch(); | |||
} else { | |||
throw new \ErrorException('La méthode "defaultOptionsSearch" n\'est ' | |||
. 'pas définie dans la classe "' . $class . '"'); | |||
} | |||
$options = array_merge($default_options, $options); | |||
$pk = $class::primaryKey(); | |||
$pk = $class::tableName() . '.' . $pk[0]; | |||
const SEARCH_QUERY = 'query'; | |||
const SEARCH_ALL = 'all'; | |||
const SEARCH_ONE = 'one'; | |||
const SEARCH_COUNT = 'count'; | |||
/** | |||
* Méthode générique de recherche utilisée pour tous les modèles. Elle a | |||
* pour but de construire la requête et de retourner le résultat. | |||
* | |||
* @param array $params | |||
* @param array $options | |||
* @return mixed | |||
* @throws NotFoundHttpException | |||
*/ | |||
public static function searchBy($params = [], $options = []) | |||
{ | |||
$class = get_called_class(); | |||
if (is_callable([$class, 'defaultOptionsSearch'])) { | |||
$default_options = $class::defaultOptionsSearch(); | |||
} else { | |||
throw new \ErrorException('La méthode "defaultOptionsSearch" n\'est ' | |||
. 'pas définie dans la classe "' . $class . '"'); | |||
} | |||
if (isset($options['attribute_id_producer']) && strlen($options['attribute_id_producer']) | |||
&& !isset($params[$options['attribute_id_producer']]) && !Yii::$app->user->isGuest) { | |||
$params[$options['attribute_id_producer']] = GlobalParam::getCurrentProducerId(); | |||
} | |||
$options = array_merge($default_options, $options); | |||
if (!isset($options['type_search'])) { | |||
$options['type_search'] = self::SEARCH_ALL; | |||
} | |||
$pk = $class::primaryKey(); | |||
$pk = $class::tableName() . '.' . $pk[0]; | |||
$records = $class::find(); | |||
if (isset($options['attribute_id_producer']) && strlen($options['attribute_id_producer']) | |||
&& !isset($params[$options['attribute_id_producer']]) && !Yii::$app->user->isGuest) { | |||
$params[$options['attribute_id_producer']] = GlobalParam::getCurrentProducerId(); | |||
} | |||
// With | |||
if (is_array($options['with']) && count($options['with'])) { | |||
$records = $records->with($options['with']); | |||
} | |||
if (!isset($options['type_search'])) { | |||
$options['type_search'] = self::SEARCH_ALL; | |||
} | |||
// Join with | |||
if (is_array($options['join_with']) && count($options['join_with'])) { | |||
$records = $records->joinWith($options['join_with']); | |||
} | |||
$records = $class::find(); | |||
// Conditions | |||
if (isset($options['conditions'])) { | |||
if (is_array($options['conditions'])) { | |||
if (count($options['conditions'])) { | |||
foreach ($options['conditions'] as $condition) { | |||
$records = $records->andWhere($condition); | |||
} | |||
} | |||
} else { | |||
if (strlen($options['conditions'])) { | |||
$records = $records->andWhere($options['conditions']); | |||
} | |||
} | |||
} | |||
// With | |||
if (is_array($options['with']) && count($options['with'])) { | |||
$records = $records->with($options['with']); | |||
} | |||
// Params | |||
if (isset($options['params']) && is_array($options['params']) && count($options['params'])) { | |||
$records = $records->params($options['params']); | |||
} | |||
// Join with | |||
if (is_array($options['join_with']) && count($options['join_with'])) { | |||
$records = $records->joinWith($options['join_with']); | |||
} | |||
// Paramètres | |||
if (is_array($params) && count($params)) { | |||
foreach ($params as $key => $val) { | |||
if (strpos($key, '.') === false) { | |||
unset($params[$key]); | |||
$key = $class::tableName() . '.' . $key; | |||
$params[$key] = $val; | |||
} | |||
$records = $records->andWhere([$key => $val]); | |||
} | |||
// Conditions | |||
if (isset($options['conditions'])) { | |||
if (is_array($options['conditions'])) { | |||
if (count($options['conditions'])) { | |||
foreach ($options['conditions'] as $condition) { | |||
$records = $records->andWhere($condition); | |||
} | |||
} | |||
if (!isset($params[$pk])) { | |||
// Orderby | |||
if (isset($options['orderby']) && strlen($options['orderby'])) { | |||
$records = $records->orderBy($options['orderby']); | |||
} | |||
// Limit | |||
if (isset($options['limit']) && is_numeric($options['limit']) | |||
&& $options['limit'] > 0) { | |||
$records = $records->limit($options['limit']); | |||
} | |||
} else { | |||
if (strlen($options['conditions'])) { | |||
$records = $records->andWhere($options['conditions']); | |||
} | |||
} | |||
} | |||
if (isset($options['as_array'])) { | |||
$records = $records->asArray(); | |||
} | |||
// Params | |||
if (isset($options['params']) && is_array($options['params']) && count($options['params'])) { | |||
$records = $records->params($options['params']); | |||
} | |||
if ($options['type_search'] == self::SEARCH_ALL) { | |||
return $records->all(); | |||
} elseif ($options['type_search'] == self::SEARCH_ONE) { | |||
$record = $records->one(); | |||
if ($record) { | |||
return $record; | |||
} | |||
} elseif ($options['type_search'] == self::SEARCH_COUNT) { | |||
return $records->count(); | |||
// Paramètres | |||
if (is_array($params) && count($params)) { | |||
foreach ($params as $key => $val) { | |||
if (strpos($key, '.') === false) { | |||
unset($params[$key]); | |||
$key = $class::tableName() . '.' . $key; | |||
$params[$key] = $val; | |||
} | |||
return false; | |||
$records = $records->andWhere([$key => $val]); | |||
} | |||
} | |||
/** | |||
* Recherche un enregistrement. | |||
* | |||
* @param array $params | |||
* @param array $options | |||
* @return mixed | |||
*/ | |||
public static function searchOne($params = [], $options = []) | |||
{ | |||
$options['type_search'] = self::SEARCH_ONE; | |||
return self::searchDispatch($params, $options); | |||
if (!isset($params[$pk])) { | |||
// Orderby | |||
if (isset($options['orderby']) && strlen($options['orderby'])) { | |||
$records = $records->orderBy($options['orderby']); | |||
} | |||
// Limit | |||
if (isset($options['limit']) && is_numeric($options['limit']) | |||
&& $options['limit'] > 0) { | |||
$records = $records->limit($options['limit']); | |||
} | |||
} | |||
/** | |||
* Recherche tous les enregistrements. | |||
* | |||
* @param array $params | |||
* @param array $options | |||
* @return mixed | |||
*/ | |||
public static function searchAll($params = [], $options = []) | |||
{ | |||
$options['type_search'] = self::SEARCH_ALL; | |||
return self::searchDispatch($params, $options); | |||
if (isset($options['groupby'])) { | |||
$records = $records->groupBy($options['groupby']); | |||
} | |||
/** | |||
* Recherche et compte le nombre de résultats. | |||
* | |||
* @param array $params | |||
* @param array $options | |||
* @return integer | |||
*/ | |||
public static function searchCount($params = [], $options = []) | |||
{ | |||
$options['type_search'] = self::SEARCH_COUNT; | |||
return self::searchDispatch($params, $options); | |||
if (isset($options['as_array'])) { | |||
$records = $records->asArray(); | |||
} | |||
/** | |||
* Appelle la méthode 'search' de la classe appellante. | |||
* | |||
* @param array $params | |||
* @param array $options | |||
* @return mixed | |||
*/ | |||
public static function searchDispatch($params = [], $options = []) | |||
{ | |||
$class = get_called_class(); | |||
return $class::searchBy($params, $options); | |||
if ($options['type_search'] == self::SEARCH_QUERY) { | |||
self::groupByPrimaryKey($class, $records); | |||
return $records; | |||
} elseif ($options['type_search'] == self::SEARCH_ALL) { | |||
return $records->all(); | |||
} elseif ($options['type_search'] == self::SEARCH_ONE) { | |||
$record = $records->one(); | |||
if ($record) { | |||
return $record; | |||
} | |||
} elseif ($options['type_search'] == self::SEARCH_COUNT) { | |||
self::groupByPrimaryKey($class, $records); | |||
return $records->count(); | |||
} | |||
return false; | |||
} | |||
public static function groupByPrimaryKey($class, $records) | |||
{ | |||
$primaryKey = static::primaryKey(); | |||
$records = $records->groupBy($class::tableName() . '.' . $primaryKey[0]); | |||
} | |||
public static function searchQuery($params = [], $options = []) | |||
{ | |||
$options['type_search'] = self::SEARCH_QUERY; | |||
return self::searchDispatch($params, $options); | |||
} | |||
/** | |||
* Recherche un enregistrement. | |||
* | |||
* @param array $params | |||
* @param array $options | |||
* @return mixed | |||
*/ | |||
public static function searchOne($params = [], $options = []) | |||
{ | |||
$options['type_search'] = self::SEARCH_ONE; | |||
return self::searchDispatch($params, $options); | |||
} | |||
/** | |||
* Recherche tous les enregistrements. | |||
* | |||
* @param array $params | |||
* @param array $options | |||
* @return mixed | |||
*/ | |||
public static function searchAll($params = [], $options = []) | |||
{ | |||
$options['type_search'] = self::SEARCH_ALL; | |||
return self::searchDispatch($params, $options); | |||
} | |||
/** | |||
* Recherche et compte le nombre de résultats. | |||
* | |||
* @param array $params | |||
* @param array $options | |||
* @return integer | |||
*/ | |||
public static function searchCount($params = [], $options = []) | |||
{ | |||
$options['type_search'] = self::SEARCH_COUNT; | |||
return self::searchDispatch($params, $options); | |||
} | |||
/** | |||
* Appelle la méthode 'search' de la classe appellante. | |||
* | |||
* @param array $params | |||
* @param array $options | |||
* @return mixed | |||
*/ | |||
public static function searchDispatch($params = [], $options = []) | |||
{ | |||
$class = get_called_class(); | |||
return $class::searchBy($params, $options); | |||
} | |||
} |
@@ -37,6 +37,7 @@ | |||
*/ | |||
return [ | |||
'version' => '22.10.A', | |||
'adminEmail' => 'contact@opendistrib.net', | |||
'supportEmail' => 'contact@opendistrib.net', | |||
'user.passwordResetTokenExpire' => 3600, |
@@ -42,43 +42,44 @@ use common\models\Producer; | |||
class GlobalParam | |||
{ | |||
public static function get($key) | |||
{ | |||
if ($key == 'producer') { | |||
return $this->getCurrentProducer(); | |||
} else { | |||
public function get($key) | |||
{ | |||
if($key == 'producer'){ | |||
return $this->getCurrentProducer(); | |||
}else{ | |||
return \Yii::$app->params[$key]; | |||
} | |||
} | |||
public static function getCurrentProducer() | |||
{ | |||
if(\Yii::$app->params['producer'] == false){ | |||
\Yii::$app->params['producer'] = Producer::searchOne(); | |||
} | |||
return \Yii::$app->params['producer']; | |||
return \Yii::$app->params[$key]; | |||
} | |||
} | |||
/** | |||
* Retourne l'ID du producteur courant. | |||
* | |||
* @return integer|boolean | |||
*/ | |||
public static function getCurrentProducerId() | |||
{ | |||
if(\Yii::$app->controller->module->id == 'app-backend') { | |||
if(!\Yii::$app->user->isGuest) { | |||
return Yii::$app->user->identity->id_producer ; | |||
} | |||
} | |||
else { | |||
return \Yii::$app->controller->getProducer()->id; | |||
} | |||
public static function getOpendistribVersion() | |||
{ | |||
return self::get('version'); | |||
} | |||
return false ; | |||
public static function getCurrentProducer() | |||
{ | |||
if (\Yii::$app->params['producer'] == false) { | |||
\Yii::$app->params['producer'] = Producer::searchOne(); | |||
} | |||
return \Yii::$app->params['producer']; | |||
} | |||
/** | |||
* Retourne l'ID du producteur courant. | |||
* | |||
* @return integer|boolean | |||
*/ | |||
public static function getCurrentProducerId() | |||
{ | |||
if (\Yii::$app->controller->module->id == 'app-backend') { | |||
if (!\Yii::$app->user->isGuest) { | |||
return Yii::$app->user->identity->id_producer; | |||
} | |||
} else { | |||
return \Yii::$app->controller->getProducer()->id; | |||
} | |||
return false; | |||
} | |||
} |
@@ -85,7 +85,8 @@ class CreditHistory extends ActiveRecordCommon | |||
[['id_user', 'id_user_action', 'id_order', 'id_producer'], 'integer'], | |||
[['date'], 'safe'], | |||
[['amount'], 'double'], | |||
[['type', 'mean_payment', 'comment'], 'string', 'max' => 255], | |||
[['type', 'mean_payment'], 'string', 'max' => 255], | |||
[['comment'], 'string', 'max' => 2048], | |||
]; | |||
} | |||
@@ -336,6 +336,24 @@ class Distribution extends ActiveRecordCommon | |||
foreach($order->productOrder as $productOrder) { | |||
if($productOrder->id_product == $product->id) { | |||
$productOrder->price = $product->price ; | |||
$user = false; | |||
$userProducer = false; | |||
if(isset($order->user) && $order->user) { | |||
$user = $order->user; | |||
$userProducer = UserProducer::searchOne([ | |||
'id_user' => $user->id, | |||
'id_producer' => $order->distribution->id_producer | |||
]) ; | |||
} | |||
$productOrder->price = $product->getPrice([ | |||
'user' => $user, | |||
'user_producer' => $userProducer, | |||
'point_sale' => $order->pointSale, | |||
'quantity' => $productOrder->quantity | |||
]); | |||
$productOrder->save() ; | |||
} | |||
} |
@@ -67,6 +67,7 @@ class Document extends ActiveRecordCommon | |||
[['date'], 'safe'], | |||
[['comment', 'address', 'tax_calculation_method'], 'string'], | |||
[['id_user', 'id_producer'], 'integer'], | |||
['is_sent', 'boolean'], | |||
[['name', 'reference', 'status'], 'string', 'max' => 255], | |||
[['deliveryNotes'], 'safe'] | |||
]; | |||
@@ -87,7 +88,8 @@ class Document extends ActiveRecordCommon | |||
'address' => 'Adresse', | |||
'id_producer' => 'Producteur', | |||
'status' => 'Statut', | |||
'tax_calculation_method' => 'Méthode de calcul de la TVA' | |||
'tax_calculation_method' => 'Méthode de calcul de la TVA', | |||
'is_sent' => 'Envoyé' | |||
]; | |||
} | |||
@@ -285,10 +287,9 @@ class Document extends ActiveRecordCommon | |||
{ | |||
$filenameComplete = $this->getFilenameComplete(); | |||
/*if (!file_exists($filenameComplete)) { | |||
if (!file_exists($filenameComplete)) { | |||
$this->generatePdf(Pdf::DEST_FILE); | |||
}*/ | |||
$this->generatePdf(Pdf::DEST_FILE); | |||
} | |||
if (file_exists($filenameComplete)) { | |||
return Yii::$app->response->sendFile($filenameComplete, $this->getFilename(), ['inline' => true]); | |||
@@ -299,7 +300,7 @@ class Document extends ActiveRecordCommon | |||
public function generatePdf($destination) | |||
{ | |||
$producer = GlobalParam::getCurrentProducer(); | |||
$producer = $this->producer; | |||
$content = Yii::$app->controller->renderPartial('/document/download', [ | |||
'producer' => $producer, | |||
'document' => $this | |||
@@ -433,9 +434,8 @@ class Document extends ActiveRecordCommon | |||
$productOrderMatch = false; | |||
foreach ($productsOrdersArray[$indexProductOrder] as &$theProductOrder) { | |||
if ($theProductOrder->unit == $productOrder->unit | |||
&& ((!$this->isInvoicePrice() && $theProductOrder->price == $productOrder->price) | |||
|| ($this->isInvoicePrice() && $theProductOrder->invoice_price == $productOrder->invoice_price) | |||
)) { | |||
&& $theProductOrder->price == $productOrder->price | |||
&& $theProductOrder->invoice_price == $productOrder->invoice_price) { | |||
$theProductOrder->quantity += $productOrder->quantity; | |||
$productOrderMatch = true; |
@@ -44,44 +44,52 @@ use common\models\Invoice; | |||
class InvoiceSearch extends Invoice | |||
{ | |||
public function rules() | |||
{ | |||
return [ | |||
[[], 'safe'], | |||
[['comment', 'address', 'status'], 'string'], | |||
[['id_user'], 'integer'], | |||
[['name', 'reference'], 'string', 'max' => 255], | |||
]; | |||
} | |||
public function search($params) | |||
{ | |||
$optionsSearch = self::defaultOptionsSearch(); | |||
var $username; | |||
$query = Invoice::find() | |||
->with($optionsSearch['with']) | |||
->joinWith($optionsSearch['join_with']) | |||
->where(['invoice.id_producer' => GlobalParam::getCurrentProducerId()]) | |||
->orderBy('invoice.status ASC, invoice.reference DESC') | |||
->groupBy('invoice.id'); | |||
public function rules() | |||
{ | |||
return [ | |||
[[], 'safe'], | |||
[['comment', 'address', 'status', 'username'], 'string'], | |||
[['name', 'reference'], 'string', 'max' => 255], | |||
]; | |||
} | |||
$dataProvider = new ActiveDataProvider([ | |||
'query' => $query, | |||
'sort' => ['attributes' => ['name', 'reference', 'date']], | |||
'pagination' => [ | |||
'pageSize' => 20, | |||
], | |||
]); | |||
public function search($params) | |||
{ | |||
$optionsSearch = self::defaultOptionsSearch(); | |||
$this->load($params); | |||
if (!$this->validate()) { | |||
return $dataProvider; | |||
} | |||
$query = Invoice::find() | |||
->with($optionsSearch['with']) | |||
->joinWith($optionsSearch['join_with']) | |||
->where(['invoice.id_producer' => GlobalParam::getCurrentProducerId()]) | |||
->orderBy('invoice.status ASC, invoice.reference DESC') | |||
->groupBy('invoice.id'); | |||
$query->andFilterWhere(['like', 'invoice.name', $this->name]); | |||
$query->andFilterWhere(['like', 'invoice.reference', $this->reference]); | |||
$query->andFilterWhere(['like', 'invoice.status', $this->status]); | |||
$dataProvider = new ActiveDataProvider([ | |||
'query' => $query, | |||
'sort' => ['attributes' => ['name', 'reference', 'date']], | |||
'pagination' => [ | |||
'pageSize' => 20, | |||
], | |||
]); | |||
return $dataProvider; | |||
$this->load($params); | |||
if (!$this->validate()) { | |||
return $dataProvider; | |||
} | |||
$query->andFilterWhere(['like', 'invoice.name', $this->name]); | |||
$query->andFilterWhere(['like', 'invoice.reference', $this->reference]); | |||
$query->andFilterWhere(['like', 'invoice.status', $this->status]); | |||
$query->andFilterWhere([ | |||
'or', | |||
['like', 'user.lastname', $this->username], | |||
['like', 'user.name', $this->username], | |||
['like', 'user.name_legal_person', $this->username], | |||
]); | |||
return $dataProvider; | |||
} | |||
} |
@@ -121,7 +121,13 @@ class LoginForm extends Model | |||
public function getUser() | |||
{ | |||
if ($this->_user === false) { | |||
$this->_user = User::findOne(['email' => $this->email, 'type' => User::TYPE_INDIVIDUAL]); | |||
$this->_user = User::searchOne( | |||
['email' => $this->email], | |||
[ | |||
'conditions' => 'type LIKE :type_individual OR type LIKE :type_legal_person', | |||
'params' => [':type_individual' => User::TYPE_INDIVIDUAL, ':type_legal_person' => User::TYPE_LEGAL_PERSON] | |||
] | |||
); | |||
} | |||
return $this->_user; |
@@ -552,7 +552,7 @@ class Order extends ActiveRecordCommon | |||
public function saveCreditHistory($type, $amount, $idProducer, $idUser, $idUserAction) | |||
{ | |||
$creditHistory = new CreditHistory; | |||
$creditHistory->id_user = $this->id_user; | |||
$creditHistory->id_user = $idUser; | |||
$creditHistory->id_order = $this->id; | |||
$creditHistory->amount = $amount; | |||
$creditHistory->type = $type; | |||
@@ -573,6 +573,8 @@ class Order extends ActiveRecordCommon | |||
if ($this->id_user) { | |||
$paymentStatus = $this->getPaymentStatus(); | |||
echo $paymentStatus; | |||
if ($paymentStatus == self::PAYMENT_PAID) { | |||
return true; | |||
} elseif ($paymentStatus == self::PAYMENT_SURPLUS) { |
@@ -0,0 +1,74 @@ | |||
<?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 common\models\Product ; | |||
class OrderSearch extends Order | |||
{ | |||
public function search($params) | |||
{ | |||
$optionsSearch = self::defaultOptionsSearch() ; | |||
$paramsSearch = []; | |||
if(isset($params['id_user'])) { | |||
$paramsSearch['id_user'] = $params['id_user']; | |||
} | |||
$query = Order::searchQuery($paramsSearch, [ | |||
'orderby' => 'distribution.date DESC' | |||
]); | |||
$dataProvider = new ActiveDataProvider([ | |||
'query' => $query, | |||
'sort' => ['attributes' => []], | |||
'pagination' => [ | |||
'pageSize' => 20, | |||
], | |||
]); | |||
$this->load($params); | |||
if (!$this->validate()) { | |||
return $dataProvider; | |||
} | |||
return $dataProvider; | |||
} | |||
} |
@@ -224,7 +224,8 @@ class Producer extends ActiveRecordCommon | |||
'option_stripe_private_key', | |||
'option_stripe_endpoint_secret', | |||
'option_online_payment_type', | |||
'option_tax_calculation_method' | |||
'option_tax_calculation_method', | |||
'latest_version_opendistrib' | |||
], | |||
'string' | |||
], | |||
@@ -308,7 +309,7 @@ class Producer extends ActiveRecordCommon | |||
'description' => 'Description', | |||
'postcode' => 'Code postal', | |||
'city' => 'Ville', | |||
'code' => 'Code', | |||
'code' => "Code d'accès", | |||
'order_delay' => 'Délai de commande', | |||
'order_deadline' => 'Heure limite de commande', | |||
'order_delay_monday' => 'Délai de commande (lundi)', | |||
@@ -390,7 +391,8 @@ class Producer extends ActiveRecordCommon | |||
'option_billing_frequency' => 'Fréquence de facturation', | |||
'option_billing_reduction' => 'Réduction appliquée au moment de la facturation', | |||
'option_tax_calculation_method' => 'Méthode de calcul de la TVA', | |||
'option_export_evoliz' => 'Activer l\'export vers Evoliz' | |||
'option_export_evoliz' => 'Activer l\'export vers Evoliz', | |||
'latest_version_opendistrib' => 'Dernière version d\'Opendistrib', | |||
]; | |||
} | |||
@@ -202,9 +202,11 @@ class ProductPrice extends ActiveRecordCommon | |||
if(self::hasMatchOfType($specificPriceArray, 'matchUser', $user, $pointSale)) { | |||
return 'matchUser'; | |||
} | |||
if(self::hasMatchOfType($specificPriceArray, 'matchUserGroup', $user, $pointSale)) { | |||
return 'matchUserGroup'; | |||
} | |||
if(self::hasMatchOfType($specificPriceArray, 'matchPointSale', $user, $pointSale)) { | |||
return 'matchPointSale'; | |||
} | |||
@@ -213,6 +215,10 @@ class ProductPrice extends ActiveRecordCommon | |||
return 'matchUserPointSale'; | |||
} | |||
if(self::hasMatchOfType($specificPriceArray, 'matchUserGroupPointSale', $user, $pointSale)) { | |||
return 'matchUserGroupPointSale'; | |||
} | |||
return null; | |||
} | |||
@@ -252,6 +258,17 @@ class ProductPrice extends ActiveRecordCommon | |||
&& $this->id_user == $user->id; | |||
} | |||
public function matchUserGroupPointSale($user, $pointSale) | |||
{ | |||
return $user | |||
&& $pointSale | |||
&& $this->id_user_group | |||
&& $this->id_point_sale | |||
&& !$this->id_user | |||
&& $user->belongsToUserGroup($this->id_user_group) | |||
&& $this->id_point_sale == $pointSale->id; | |||
} | |||
public function matchFromQuantityOnly() | |||
{ | |||
return !$this->id_user |
@@ -71,428 +71,434 @@ use common\models\ProductOrder; | |||
*/ | |||
class Subscription extends ActiveRecordCommon | |||
{ | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public static function tableName() | |||
{ | |||
return 'subscription'; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function rules() | |||
{ | |||
return [ | |||
[['id_producer', 'id_point_sale'], 'required'], | |||
[['id_user', 'id_producer', 'id_point_sale', 'monday', 'tuesday', | |||
'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'week_frequency'], 'integer'], | |||
[['auto_payment'], 'boolean'], | |||
[['date_begin', 'date_end', 'username', 'comment'], 'safe'], | |||
]; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function attributeLabels() | |||
{ | |||
return [ | |||
'id' => 'ID', | |||
'id_user' => 'Utilisateur', | |||
'id_producer' => 'Etablissement', | |||
'id_point_sale' => 'Point de vente', | |||
'date_begin' => 'Date de début', | |||
'date_end' => 'Date de fin', | |||
'monday' => 'Lundi', | |||
'tuesday' => 'Mardi', | |||
'wednesday' => 'Mercredi', | |||
'thursday' => 'Jeudi', | |||
'friday' => 'Vendredi', | |||
'saturday' => 'Samedi', | |||
'sunday' => 'Dimanche', | |||
'week_frequency' => 'Périodicité', | |||
'auto_payment' => 'Paiement automatique', | |||
'comment' => 'Commentaire' | |||
]; | |||
} | |||
/* | |||
* Relations | |||
*/ | |||
public function getUser() | |||
{ | |||
return $this->hasOne(User::className(), ['id' => 'id_user']); | |||
} | |||
public function getProducer() | |||
{ | |||
return $this->hasOne( | |||
Producer::className(), | |||
['id' => 'id_producer'] | |||
); | |||
} | |||
public function getPointSale() | |||
{ | |||
return $this->hasOne( | |||
PointSale::className(), | |||
['id' => 'id_point_sale'] | |||
); | |||
} | |||
public function getProductSubscription() | |||
{ | |||
return $this->hasMany( | |||
ProductSubscription::className(), | |||
['id_subscription' => 'id'] | |||
)->with('product'); | |||
} | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
* | |||
* @return array | |||
*/ | |||
public static function defaultOptionsSearch() | |||
{ | |||
return [ | |||
'with' => ['producer'], | |||
'join_with' => ['user', 'productSubscription', 'productSubscription.product', 'pointSale'], | |||
'orderby' => 'user.name ASC', | |||
'attribute_id_producer' => 'subscription.id_producer' | |||
]; | |||
} | |||
/** | |||
* Ajoute la commande pour une date donnée. | |||
* | |||
* @param string $date | |||
*/ | |||
public function add($date) | |||
{ | |||
// distribution | |||
$distribution = Distribution::searchOne([ | |||
'distribution.date' => date('Y-m-d', strtotime($date)) | |||
]); | |||
if ($distribution && $distribution->active && count($this->productSubscription) && $this->id_point_sale) { | |||
// commande | |||
$order = new Order; | |||
if (strlen($this->username)) { | |||
$order->username = $this->username; | |||
$order->id_user = 0; | |||
} else { | |||
$order->id_user = $this->id_user; | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public static function tableName() | |||
{ | |||
return 'subscription'; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function rules() | |||
{ | |||
return [ | |||
[['id_producer', 'id_point_sale'], 'required'], | |||
[['id_user', 'id_producer', 'id_point_sale', 'monday', 'tuesday', | |||
'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'week_frequency'], 'integer'], | |||
[['auto_payment'], 'boolean'], | |||
[['date_begin', 'date_end', 'username', 'comment'], 'safe'], | |||
]; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function attributeLabels() | |||
{ | |||
return [ | |||
'id' => 'ID', | |||
'id_user' => 'Utilisateur', | |||
'id_producer' => 'Etablissement', | |||
'id_point_sale' => 'Point de vente', | |||
'date_begin' => 'Date de début', | |||
'date_end' => 'Date de fin', | |||
'monday' => 'Lundi', | |||
'tuesday' => 'Mardi', | |||
'wednesday' => 'Mercredi', | |||
'thursday' => 'Jeudi', | |||
'friday' => 'Vendredi', | |||
'saturday' => 'Samedi', | |||
'sunday' => 'Dimanche', | |||
'week_frequency' => 'Périodicité', | |||
'auto_payment' => 'Paiement automatique', | |||
'comment' => 'Commentaire' | |||
]; | |||
} | |||
/* | |||
* Relations | |||
*/ | |||
public function getUser() | |||
{ | |||
return $this->hasOne(User::className(), ['id' => 'id_user']); | |||
} | |||
public function getProducer() | |||
{ | |||
return $this->hasOne( | |||
Producer::className(), | |||
['id' => 'id_producer'] | |||
); | |||
} | |||
public function getPointSale() | |||
{ | |||
return $this->hasOne( | |||
PointSale::className(), | |||
['id' => 'id_point_sale'] | |||
); | |||
} | |||
public function getProductSubscription() | |||
{ | |||
return $this->hasMany( | |||
ProductSubscription::className(), | |||
['id_subscription' => 'id'] | |||
)->with('product'); | |||
} | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
* | |||
* @return array | |||
*/ | |||
public static function defaultOptionsSearch() | |||
{ | |||
return [ | |||
'with' => ['producer'], | |||
'join_with' => ['user', 'productSubscription', 'productSubscription.product', 'pointSale'], | |||
'orderby' => 'user.name ASC', | |||
'attribute_id_producer' => 'subscription.id_producer' | |||
]; | |||
} | |||
/** | |||
* Ajoute la commande pour une date donnée. | |||
* | |||
* @param string $date | |||
*/ | |||
public function add($date, $force = false) | |||
{ | |||
// distribution | |||
$now = date('Y-m-d'); | |||
$distributionDate = date('Y-m-d', strtotime($date)); | |||
$distribution = Distribution::searchOne([ | |||
'distribution.date' => $distributionDate | |||
]); | |||
if ($distribution | |||
&& $distribution->active | |||
&& ($distributionDate > $now || $force) | |||
&& count($this->productSubscription) | |||
&& $this->id_point_sale) { | |||
// commande | |||
$order = new Order; | |||
if (strlen($this->username)) { | |||
$order->username = $this->username; | |||
$order->id_user = 0; | |||
} else { | |||
$order->id_user = $this->id_user; | |||
} | |||
$user = false; | |||
if ($this->id_user) { | |||
$user = User::findOne($this->id_user); | |||
} | |||
$order->date = date('Y-m-d H:i:s'); | |||
$order->origin = Order::ORIGIN_AUTO; | |||
$order->id_point_sale = $this->id_point_sale; | |||
$order->id_distribution = $distribution->id; | |||
$order->id_subscription = $this->id; | |||
$order->status = 'tmp-order'; | |||
if (strlen($this->comment)) { | |||
$order->comment = $this->comment; | |||
} | |||
$pointSale = PointSale::findOne($this->id_point_sale); | |||
if ($pointSale) { | |||
$creditFunctioning = $pointSale->getCreditFunctioning(); | |||
$order->auto_payment = 0; | |||
if ($order->id_user && Producer::getConfig('credit') && $pointSale->credit) { | |||
if ($creditFunctioning == Producer::CREDIT_FUNCTIONING_OPTIONAL) { | |||
$order->auto_payment = $this->auto_payment; | |||
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_MANDATORY) { | |||
$order->auto_payment = 1; | |||
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_USER) { | |||
$user = User::findOne($order->id_user); | |||
$userProducer = UserProducer::searchOne([ | |||
'id_user' => $order->id_user, | |||
'id_producer' => $distribution->id_producer | |||
]); | |||
if ($userProducer) { | |||
$order->auto_payment = $userProducer->credit_active; | |||
} | |||
} | |||
} | |||
$user = false; | |||
if($this->id_user) { | |||
$user = User::findOne($this->id_user); | |||
} | |||
$order->tiller_synchronization = $order->auto_payment; | |||
$order->date = date('Y-m-d H:i:s'); | |||
$order->origin = Order::ORIGIN_AUTO; | |||
$order->id_point_sale = $this->id_point_sale; | |||
$order->id_distribution = $distribution->id; | |||
$order->id_subscription = $this->id; | |||
$order->status = 'tmp-order' ; | |||
if (strlen($this->comment)) { | |||
$order->comment = $this->comment; | |||
} | |||
$userPointSale = UserPointSale::searchOne([ | |||
'id_point_sale' => $this->id_point_sale, | |||
'id_user' => $this->id_user | |||
]); | |||
$pointSale = PointSale::findOne($this->id_point_sale); | |||
if($pointSale) { | |||
$creditFunctioning = $pointSale->getCreditFunctioning(); | |||
$order->auto_payment = 0; | |||
if ($order->id_user && Producer::getConfig('credit') && $pointSale->credit) { | |||
if ($creditFunctioning == Producer::CREDIT_FUNCTIONING_OPTIONAL) { | |||
$order->auto_payment = $this->auto_payment; | |||
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_MANDATORY) { | |||
$order->auto_payment = 1; | |||
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_USER) { | |||
$user = User::findOne($order->id_user); | |||
$userProducer = UserProducer::searchOne([ | |||
'id_user' => $order->id_user, | |||
'id_producer' => $distribution->id_producer | |||
]); | |||
if ($userProducer) { | |||
$order->auto_payment = $userProducer->credit_active; | |||
} | |||
} | |||
} | |||
$order->tiller_synchronization = $order->auto_payment ; | |||
$userPointSale = UserPointSale::searchOne([ | |||
'id_point_sale' => $this->id_point_sale, | |||
'id_user' => $this->id_user | |||
]); | |||
if ($userPointSale && strlen($userPointSale->comment)) { | |||
$order->comment_point_sale = $userPointSale->comment; | |||
} | |||
$order->save(); | |||
// liaison utilisateur / point de vente | |||
if ($order->id_user) { | |||
$pointSale = PointSale::findOne($this->id_point_sale); | |||
$pointSale->linkUser($order->id_user); | |||
} | |||
// produits | |||
$amountTotal = 0; | |||
$productsAdd = false; | |||
foreach ($this->productSubscription as $productSubscription) { | |||
$productOrder = new ProductOrder; | |||
$productOrder->id_order = $order->id; | |||
$productOrder->id_product = $productSubscription->product->id; | |||
$productOrder->quantity = $productSubscription->quantity; | |||
$productOrder->price = $productSubscription->product->getPrice([ | |||
'user' => $user, | |||
'point_sale' => $pointSale, | |||
'quantity' => $productSubscription->quantity | |||
]); | |||
$productOrder->unit = $productSubscription->product->unit; | |||
$productOrder->step = $productSubscription->product->step; | |||
$productOrder->id_tax_rate = $productSubscription->product->taxRate->id; | |||
$productOrder->save(); | |||
$productsAdd = true; | |||
} | |||
if (!$productsAdd) { | |||
$order->delete(); | |||
} | |||
$order->initReference() ; | |||
} | |||
if ($userPointSale && strlen($userPointSale->comment)) { | |||
$order->comment_point_sale = $userPointSale->comment; | |||
} | |||
} | |||
/** | |||
* Ajoute les commandes pour une date donnée à partir des abonnements. | |||
* | |||
* @param string $date | |||
* @param boolean $force | |||
*/ | |||
public static function addAll($date, $force = false) | |||
{ | |||
$distribution = Distribution::searchOne([ | |||
'date' => date('Y-m-d', strtotime($date)), | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
]); | |||
$order->save(); | |||
if ($distribution) { | |||
$arrayOrdersDistribution = Order::searchAll([ | |||
Order::tableName() . '.id_distribution' => $distribution->id | |||
]); | |||
$arraySubscriptions = self::searchByDate($date); | |||
foreach ($arraySubscriptions as $subscription) { | |||
if (!$subscription->hasOrderAlreadyExist($arrayOrdersDistribution)) { | |||
$subscription->add($date); | |||
} | |||
} | |||
// liaison utilisateur / point de vente | |||
if ($order->id_user) { | |||
$pointSale = PointSale::findOne($this->id_point_sale); | |||
$pointSale->linkUser($order->id_user); | |||
} | |||
// produits | |||
$amountTotal = 0; | |||
$productsAdd = false; | |||
foreach ($this->productSubscription as $productSubscription) { | |||
$productOrder = new ProductOrder; | |||
$productOrder->id_order = $order->id; | |||
$productOrder->id_product = $productSubscription->product->id; | |||
$productOrder->quantity = $productSubscription->quantity; | |||
$productOrder->price = $productSubscription->product->getPrice([ | |||
'user' => $user, | |||
'point_sale' => $pointSale, | |||
'quantity' => $productSubscription->quantity | |||
]); | |||
$productOrder->unit = $productSubscription->product->unit; | |||
$productOrder->step = $productSubscription->product->step; | |||
$productOrder->id_tax_rate = $productSubscription->product->taxRate->id; | |||
$productOrder->save(); | |||
$productsAdd = true; | |||
} | |||
} | |||
/** | |||
* Informe s'il existe une commande correspond à l'abonnement courant. | |||
* | |||
* @param array $arrayOrders | |||
* @return boolean | |||
*/ | |||
public function hasOrderAlreadyExist($arrayOrders) | |||
{ | |||
if (is_array($arrayOrders) && count($arrayOrders) > 0) { | |||
foreach ($arrayOrders as $order) { | |||
if ((($order->id_user > 0 && $order->id_user == $this->id_user) || | |||
(!$order->id_user && $order->username == $this->username)) && | |||
$order->id_point_sale == $this->id_point_sale) { | |||
return true; | |||
} | |||
} | |||
if (!$productsAdd) { | |||
$order->delete(); | |||
} | |||
return false; | |||
$order->initReference(); | |||
} | |||
} | |||
/** | |||
* Retourne les abonnements pour une date donnée. | |||
* | |||
* @param string $date | |||
* @return array | |||
*/ | |||
public static function searchByDate($date) | |||
{ | |||
$date = date('Y-m-d', strtotime($date)); | |||
$subscriptions = Subscription::searchAll(); | |||
$arrSubscriptions = []; | |||
foreach ($subscriptions as $s) { | |||
if ($date >= $s->date_begin && | |||
(!$s->date_end || $date <= $s->date_end) && | |||
$s->matchWith($date)) { | |||
$arrSubscriptions[] = $s; | |||
} | |||
} | |||
/** | |||
* Ajoute les commandes pour une date donnée à partir des abonnements. | |||
* | |||
* @param string $date | |||
* @param boolean $force | |||
*/ | |||
public static function addAll($date, $force = false) | |||
{ | |||
$distribution = Distribution::searchOne([ | |||
'date' => date('Y-m-d', strtotime($date)), | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
]); | |||
if ($distribution) { | |||
$arrayOrdersDistribution = Order::searchAll([ | |||
Order::tableName() . '.id_distribution' => $distribution->id | |||
]); | |||
$arraySubscriptions = self::searchByDate($date); | |||
foreach ($arraySubscriptions as $subscription) { | |||
if (!$subscription->hasOrderAlreadyExist($arrayOrdersDistribution)) { | |||
$subscription->add($date, $force); | |||
} | |||
return $arrSubscriptions; | |||
} | |||
} | |||
/** | |||
* Valide le fait qu'un abonnement est bien compatible avec une date donnée. | |||
* | |||
* @param string $date | |||
* @return boolean | |||
*/ | |||
public function matchWith($date) | |||
{ | |||
$arrayDays = [ | |||
1 => 'monday', | |||
2 => 'tuesday', | |||
3 => 'wednesday', | |||
4 => 'thursday', | |||
5 => 'friday', | |||
6 => 'saturday', | |||
7 => 'sunday' | |||
]; | |||
$nbDays = (strtotime($date) - strtotime($this->date_begin)) / (24 * 60 * 60); | |||
if (round($nbDays) % ($this->week_frequency * 7) < 7) { | |||
$numDay = date('N', strtotime($date)); | |||
$day = $arrayDays[$numDay]; | |||
if ($this->$day) { | |||
return true; | |||
} | |||
} | |||
/** | |||
* Informe s'il existe une commande correspond à l'abonnement courant. | |||
* | |||
* @param array $arrayOrders | |||
* @return boolean | |||
*/ | |||
public function hasOrderAlreadyExist($arrayOrders) | |||
{ | |||
if (is_array($arrayOrders) && count($arrayOrders) > 0) { | |||
foreach ($arrayOrders as $order) { | |||
if ((($order->id_user > 0 && $order->id_user == $this->id_user) || | |||
(!$order->id_user && $order->username == $this->username)) && | |||
$order->id_point_sale == $this->id_point_sale) { | |||
return true; | |||
} | |||
} | |||
} | |||
return false; | |||
return false; | |||
} | |||
/** | |||
* Retourne les abonnements pour une date donnée. | |||
* | |||
* @param string $date | |||
* @return array | |||
*/ | |||
public static function searchByDate($date) | |||
{ | |||
$date = date('Y-m-d', strtotime($date)); | |||
$subscriptions = Subscription::searchAll(); | |||
$arrSubscriptions = []; | |||
foreach ($subscriptions as $s) { | |||
if ($date >= $s->date_begin && | |||
(!$s->date_end || $date <= $s->date_end) && | |||
$s->matchWith($date)) { | |||
$arrSubscriptions[] = $s; | |||
} | |||
} | |||
/** | |||
* Recherche les distributions futures où l'abonnement peut s'appliquer. | |||
* | |||
* @return array | |||
*/ | |||
public function searchMatchedIncomingDistributions() | |||
{ | |||
$producer = GlobalParam::getCurrentProducer(); | |||
$params = [ | |||
':date_earliest_order' => date('Y-m-d'), | |||
':date_begin' => date('Y-m-d', strtotime($this->date_begin)), | |||
':id_producer' => GlobalParam::getCurrentProducerId() | |||
]; | |||
$incomingDistributions = Distribution::find() | |||
->where('id_producer = :id_producer') | |||
->andWhere('date >= :date_begin') | |||
->andWhere('date >= :date_earliest_order'); | |||
if ($this->date_end) { | |||
$incomingDistributions->andWhere('date < :date_end'); | |||
$params[':date_end'] = date('Y-m-d', strtotime($this->date_end)); | |||
} | |||
return $arrSubscriptions; | |||
} | |||
/** | |||
* Valide le fait qu'un abonnement est bien compatible avec une date donnée. | |||
* | |||
* @param string $date | |||
* @return boolean | |||
*/ | |||
public function matchWith($date) | |||
{ | |||
$arrayDays = [ | |||
1 => 'monday', | |||
2 => 'tuesday', | |||
3 => 'wednesday', | |||
4 => 'thursday', | |||
5 => 'friday', | |||
6 => 'saturday', | |||
7 => 'sunday' | |||
]; | |||
$nbDays = (strtotime($date) - strtotime($this->date_begin)) / (24 * 60 * 60); | |||
if (round($nbDays) % ($this->week_frequency * 7) < 7) { | |||
$numDay = date('N', strtotime($date)); | |||
$day = $arrayDays[$numDay]; | |||
if ($this->$day) { | |||
return true; | |||
} | |||
} | |||
$incomingDistributions->orderBy('date ASC'); | |||
return false; | |||
} | |||
/** | |||
* Recherche les distributions futures où l'abonnement peut s'appliquer. | |||
* | |||
* @return array | |||
*/ | |||
public function searchMatchedIncomingDistributions() | |||
{ | |||
$producer = GlobalParam::getCurrentProducer(); | |||
$params = [ | |||
':date_earliest_order' => date('Y-m-d'), | |||
':date_begin' => date('Y-m-d', strtotime($this->date_begin)), | |||
':id_producer' => GlobalParam::getCurrentProducerId() | |||
]; | |||
$incomingDistributions = Distribution::find() | |||
->where('id_producer = :id_producer') | |||
->andWhere('date >= :date_begin') | |||
->andWhere('date > :date_earliest_order'); | |||
if ($this->date_end) { | |||
$incomingDistributions->andWhere('date < :date_end'); | |||
$params[':date_end'] = date('Y-m-d', strtotime($this->date_end)); | |||
} | |||
$incomingDistributions->params($params); | |||
$incomingDistributionsArray = $incomingDistributions->all(); | |||
$incomingDistributions->orderBy('date ASC'); | |||
$incomingDistributions = Distribution::filterDistributionsByDateDelay($incomingDistributionsArray) ; | |||
$incomingDistributions->params($params); | |||
$incomingDistributionsArray = $incomingDistributions->all(); | |||
$matchedIncomingDistributionsArray = []; | |||
foreach ($incomingDistributionsArray as $incomingDistribution) { | |||
if ($this->matchWith($incomingDistribution->date)) { | |||
$matchedIncomingDistributionsArray[] = $incomingDistribution; | |||
} | |||
} | |||
$incomingDistributions = Distribution::filterDistributionsByDateDelay($incomingDistributionsArray); | |||
return $matchedIncomingDistributionsArray; | |||
$matchedIncomingDistributionsArray = []; | |||
foreach ($incomingDistributionsArray as $incomingDistribution) { | |||
if ($this->matchWith($incomingDistribution->date)) { | |||
$matchedIncomingDistributionsArray[] = $incomingDistribution; | |||
} | |||
} | |||
public function deleteOrdersIncomingDistributions() | |||
{ | |||
$params = [ | |||
':id_producer' => GlobalParam::getCurrentProducerId(), | |||
':date_today' => date('Y-m-d'), | |||
':date_begin' => $this->date_begin, | |||
':id_subscription' => $this->id | |||
]; | |||
return $matchedIncomingDistributionsArray; | |||
} | |||
public function deleteOrdersIncomingDistributions() | |||
{ | |||
$params = [ | |||
':id_producer' => GlobalParam::getCurrentProducerId(), | |||
':date_today' => date('Y-m-d'), | |||
':date_begin' => $this->date_begin, | |||
':id_subscription' => $this->id | |||
]; | |||
$orderDeadline = Producer::getConfig('order_deadline'); | |||
$hour = date('G'); | |||
if ($hour >= $orderDeadline) { | |||
$conditionDistributionDate = 'distribution.date > :date_today'; | |||
} else { | |||
$conditionDistributionDate = 'distribution.date >= :date_today'; | |||
} | |||
$orderDeadline = Producer::getConfig('order_deadline'); | |||
$hour = date('G'); | |||
$orders = Order::find() | |||
->joinWith('distribution') | |||
->where('distribution.id_producer = :id_producer') | |||
->andWhere($conditionDistributionDate) | |||
->andWhere('distribution.date >= :date_begin') | |||
->andWhere('order.id_subscription = :id_subscription'); | |||
if ($hour >= $orderDeadline) { | |||
$conditionDistributionDate = 'distribution.date > :date_today'; | |||
} else { | |||
$conditionDistributionDate = 'distribution.date >= :date_today'; | |||
} | |||
$orders->params($params); | |||
$orders = Order::find() | |||
->joinWith('distribution') | |||
->where('distribution.id_producer = :id_producer') | |||
->andWhere($conditionDistributionDate) | |||
->andWhere('distribution.date >= :date_begin') | |||
->andWhere('order.id_subscription = :id_subscription'); | |||
$ordersArray = $orders->all(); | |||
$configCredit = Producer::getConfig('credit'); | |||
$orders->params($params); | |||
if ($ordersArray && count($ordersArray)) { | |||
foreach ($ordersArray as $order) { | |||
$ordersArray = $orders->all(); | |||
$configCredit = Producer::getConfig('credit'); | |||
$theOrder = Order::searchOne(['id' => $order->id]); | |||
if ($ordersArray && count($ordersArray)) { | |||
foreach ($ordersArray as $order) { | |||
// remboursement de la commande | |||
if ($theOrder->id_user && $theOrder->getAmount(Order::AMOUNT_PAID) && $configCredit) { | |||
$theOrder->saveCreditHistory( | |||
CreditHistory::TYPE_REFUND, | |||
$theOrder->getAmount(Order::AMOUNT_PAID), | |||
$theOrder->distribution->id_producer, | |||
$theOrder->id_user, | |||
User::getCurrentId() | |||
); | |||
} | |||
$theOrder = Order::searchOne(['id' => $order->id]); | |||
$order->delete(); | |||
} | |||
// remboursement de la commande | |||
if ($theOrder->id_user && $theOrder->getAmount(Order::AMOUNT_PAID) && $configCredit) { | |||
$theOrder->saveCreditHistory( | |||
CreditHistory::TYPE_REFUND, | |||
$theOrder->getAmount(Order::AMOUNT_PAID), | |||
$theOrder->distribution->id_producer, | |||
$theOrder->id_user, | |||
User::getCurrentId() | |||
); | |||
} | |||
$order->delete(); | |||
} | |||
} | |||
} | |||
public function updateIncomingDistributions($update = false) | |||
{ | |||
$matchedDistributionsArray = $this->searchMatchedIncomingDistributions(); | |||
public function updateIncomingDistributions($update = false) | |||
{ | |||
$matchedDistributionsArray = $this->searchMatchedIncomingDistributions(); | |||
if ($update) { | |||
$this->deleteOrdersIncomingDistributions(); | |||
} | |||
if (count($matchedDistributionsArray)) { | |||
foreach ($matchedDistributionsArray as $distribution) { | |||
$this->add($distribution->date); | |||
} | |||
} | |||
if ($update) { | |||
$this->deleteOrdersIncomingDistributions(); | |||
} | |||
public function getUsername() | |||
{ | |||
if($this->user) { | |||
return $this->user->getUsername() ; | |||
} | |||
if (count($matchedDistributionsArray)) { | |||
foreach ($matchedDistributionsArray as $distribution) { | |||
$this->add($distribution->date); | |||
} | |||
} | |||
} | |||
return $this->username ; | |||
public function getUsername() | |||
{ | |||
if ($this->user) { | |||
return $this->user->getUsername(); | |||
} | |||
return $this->username; | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>25/10/2022</li> | |||
</ul> | |||
<h4>Évolutions</h4> | |||
<ul> | |||
<li>[Administration] Distributions > commandes : ajout ligne avec montant total et poids par point de vente</li> | |||
<li>[Administration] Distributions > formulaire commande : ajout champs prix HT</li> | |||
<li>[Administration] Produits, Utilisateurs, Statistiques et Documents : accès rapide en un clic</li> | |||
<li>[Administration] Produits > liste : possibilité de modifier directement le champs "actif"</li> | |||
<li>[Administration] Utilisateurs > commandes : ajout lien vers modification</li> | |||
<li> | |||
[Administration] Documents > modification : mise en évidence des prix incohérents par rapport à ceux définis au | |||
niveau des produits | |||
</li> | |||
<li>[Administration] Documents > liste : ajout champs "Envoyé"</li> | |||
<li>[Administration] Documents > factures > liste : filtre par utilisateur</li> | |||
<li>[Administration] Paramètres : tri et réagencement</li> | |||
<li>[Administration] Développement : page de suivi des versions du logiciel (liste des évolutions et correctifs)</li> | |||
<li>[Espace producteur] Formulaire de contact avec protection par captcha</li> | |||
</ul> | |||
<h4>Correctifs</h4> | |||
<ul> | |||
<li> | |||
[Administration] Produits > modification : prise en compte des prix spécifiques lors de la mise à jour automatique | |||
des commandes des distributions futures | |||
</li> | |||
<li> | |||
[Administration] Produits > prix spécifiques : prise en compte des prix par groupe d'utilisateur et point de vente | |||
</li> | |||
<li>[Administration] Utilisateurs > crédit : correctif champs "Commentaire" trop long</li> | |||
<li>[Administration] Utilisateurs > liste : correctif nombre de commandes</li> | |||
<li>[Administration] Distributions > modification commande : correctif modification prix</li> | |||
<li> | |||
[Administration] Distributions > modification commande : adaptation changement du point de vente lors de la | |||
sélection d'un utilisateur | |||
</li> | |||
<li>[Administration] Haut de page : utilisateurs vides dans le bloc "Utilisateurs au crédit négatif"</li> | |||
<li>[Administration] Abonnements : ne pas générer de commandes pour le jour même</li> | |||
<li>[Backend] Facture > créer : tri des utilisateurs par ordre alphabétique</li> | |||
<li>Correctif connexion personnes morales</li> | |||
</ul> |
@@ -30,7 +30,8 @@ | |||
"yiisoft/yii2-jui": "^2.0", | |||
"bower-asset/jquery": "^3.6", | |||
"yidas/yii2-bower-asset": "2.0.13.1", | |||
"stripe/stripe-php": "^7.95" | |||
"stripe/stripe-php": "^7.95", | |||
"loveorigami/yii2-bootstrap-toggle": "*" | |||
}, | |||
"require-dev": { | |||
"yiisoft/yii2-codeception": "*", |
@@ -4,7 +4,7 @@ | |||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | |||
"This file is @generated automatically" | |||
], | |||
"content-hash": "bbfd502bb99ed522c5f181c9e809790f", | |||
"content-hash": "96d4dfea93de951d74c4d1d099ed27ed", | |||
"packages": [ | |||
{ | |||
"name": "2amigos/yii2-chartjs-widget", | |||
@@ -178,6 +178,24 @@ | |||
}, | |||
"time": "2019-08-29T08:20:20+00:00" | |||
}, | |||
{ | |||
"name": "bower-asset/bootstrap-toggle", | |||
"version": "2.2.2", | |||
"source": { | |||
"type": "git", | |||
"url": "git@github.com:minhur/bootstrap-toggle.git", | |||
"reference": "187e332b7431afe3d0c07eeef92782ce59a77d66" | |||
}, | |||
"dist": { | |||
"type": "zip", | |||
"url": "https://api.github.com/repos/minhur/bootstrap-toggle/zipball/187e332b7431afe3d0c07eeef92782ce59a77d66", | |||
"reference": "187e332b7431afe3d0c07eeef92782ce59a77d66" | |||
}, | |||
"type": "bower-asset", | |||
"license": [ | |||
"MIT" | |||
] | |||
}, | |||
{ | |||
"name": "bower-asset/chartjs", | |||
"version": "v2.1.6", | |||
@@ -1011,6 +1029,56 @@ | |||
}, | |||
"time": "2020-05-03T11:44:34+00:00" | |||
}, | |||
{ | |||
"name": "loveorigami/yii2-bootstrap-toggle", | |||
"version": "1.1", | |||
"source": { | |||
"type": "git", | |||
"url": "https://github.com/loveorigami/yii2-bootstrap-toggle.git", | |||
"reference": "27ee6469f784b9163c03ee760e34c7ef751be148" | |||
}, | |||
"dist": { | |||
"type": "zip", | |||
"url": "https://api.github.com/repos/loveorigami/yii2-bootstrap-toggle/zipball/27ee6469f784b9163c03ee760e34c7ef751be148", | |||
"reference": "27ee6469f784b9163c03ee760e34c7ef751be148", | |||
"shasum": "" | |||
}, | |||
"require": { | |||
"bower-asset/bootstrap-toggle": "*", | |||
"yiisoft/yii2": "2.0.*" | |||
}, | |||
"require-dev": { | |||
"yiisoft/yii2-debug": "2.0.*" | |||
}, | |||
"type": "yii2-extension", | |||
"autoload": { | |||
"psr-4": { | |||
"lo\\widgets\\": "" | |||
} | |||
}, | |||
"notification-url": "https://packagist.org/downloads/", | |||
"license": [ | |||
"GPL-3.0+" | |||
], | |||
"authors": [ | |||
{ | |||
"name": "Andrey Lukyanov", | |||
"email": "loveorigami@mail.ru" | |||
} | |||
], | |||
"description": "Yii2 bootstrap-toggle widget", | |||
"keywords": [ | |||
"bootstrap", | |||
"toggle", | |||
"widget", | |||
"yii2" | |||
], | |||
"support": { | |||
"issues": "https://github.com/loveorigami/yii2-bootstrap-toggle/issues", | |||
"source": "https://github.com/loveorigami/yii2-bootstrap-toggle/tree/master" | |||
}, | |||
"time": "2016-05-12T15:57:40+00:00" | |||
}, | |||
{ | |||
"name": "mailjet/mailjet-apiv3-php", | |||
"version": "v1.5.1", | |||
@@ -6048,5 +6116,5 @@ | |||
"php": ">=5.4.0" | |||
}, | |||
"platform-dev": [], | |||
"plugin-api-version": "2.0.0" | |||
"plugin-api-version": "2.3.0" | |||
} |
@@ -0,0 +1,30 @@ | |||
<?php | |||
use yii\db\Migration; | |||
use yii\db\Schema; | |||
/** | |||
* Class m221010_124540_document_is_sent | |||
*/ | |||
class m221010_124540_document_is_sent extends Migration | |||
{ | |||
/** | |||
* {@inheritdoc} | |||
*/ | |||
public function safeUp() | |||
{ | |||
$this->addColumn('quotation', 'is_sent', Schema::TYPE_BOOLEAN); | |||
$this->addColumn('delivery_note', 'is_sent', Schema::TYPE_BOOLEAN); | |||
$this->addColumn('invoice', 'is_sent', Schema::TYPE_BOOLEAN); | |||
} | |||
/** | |||
* {@inheritdoc} | |||
*/ | |||
public function safeDown() | |||
{ | |||
$this->dropColumn('quotation', 'is_sent'); | |||
$this->dropColumn('delivery_note', 'is_sent'); | |||
$this->dropColumn('invoice', 'is_sent'); | |||
} | |||
} |
@@ -0,0 +1,26 @@ | |||
<?php | |||
use yii\db\Migration; | |||
use yii\db\Schema; | |||
/** | |||
* Class m221013_085349_producer_add_field_latest_version | |||
*/ | |||
class m221013_085349_producer_add_field_latest_version extends Migration | |||
{ | |||
/** | |||
* {@inheritdoc} | |||
*/ | |||
public function safeUp() | |||
{ | |||
$this->addColumn('producer', 'latest_version_opendistrib', Schema::TYPE_STRING); | |||
} | |||
/** | |||
* {@inheritdoc} | |||
*/ | |||
public function safeDown() | |||
{ | |||
$this->dropColumn('producer', 'latest_version_opendistrib'); | |||
} | |||
} |
@@ -56,18 +56,11 @@ $this->params['breadcrumbs'][] = $this->title; | |||
<div class="row"> | |||
<div class="col-lg-5"> | |||
<!--<h2>par téléphone</h2> | |||
<p id="contact-phone"> | |||
Guillaume Bourgeois<br /> | |||
<span class="glyphicon glyphicon-phone"></span> 06 84 59 71 79 | |||
<br /><br /> | |||
Fabien Normand<br /> | |||
<span class="glyphicon glyphicon-phone"></span> 07 81 99 97 01 | |||
</p>--> | |||
<h2>Par email</h2> | |||
<div class="alert alert-info"> | |||
Ce formulaire de contact vous permet de joindre le développeur de la plateforme Opendistrib. | |||
Si vous souhaitez joindre un producteur, merci de le faire directement depuis son espace producteur. | |||
</div> | |||
<?php $form = ActiveForm::begin(['id' => 'contact-form']); ?> | |||
<?= $form->field($model, 'name') ?> | |||
<?= $form->field($model, 'email') ?> |
@@ -1 +0,0 @@ | |||
<?php phpinfo(); ?> |
@@ -188,8 +188,6 @@ class SiteController extends ProducerBaseController | |||
*/ | |||
public function actionContact() | |||
{ | |||
return $this->redirect(['site/index']); | |||
$model = new ContactForm(); | |||
$producer = $this->getProducer(); | |||
@@ -202,6 +200,7 @@ class SiteController extends ProducerBaseController | |||
$email = $contact->email; | |||
} | |||
$email = 'guillaume@laclic.fr'; | |||
if (strlen($email) && $model->sendEmail($email)) { | |||
$isSent = true; | |||
} |
@@ -209,11 +209,11 @@ if (!Yii::$app->user->isGuest) { | |||
'visible' => !Yii::$app->user->isGuest && $producer->credit, | |||
'active' => $this->getControllerAction() == 'credit/history', | |||
], | |||
/*[ | |||
[ | |||
'label' => '<span class="glyphicon glyphicon-envelope"></span> Contact', | |||
'url' => Yii::$app->urlManager->createUrl(['site/contact']), | |||
'active' => $this->getControllerAction() == 'site/contact', | |||
],*/ | |||
], | |||
[ | |||
'label' => '<span class="glyphicon glyphicon-cog"></span> Administration', | |||
'url' => Yii::$app->urlManagerBackend->createAbsoluteUrl(['site/index']), |
@@ -263,7 +263,7 @@ var app = new Vue({ | |||
} | |||
if (!this.monday && !this.tuesday && !this.wednesday && !this.thursday && | |||
!this.friday && !this.saturday) { | |||
!this.friday && !this.saturday && !this.sunday) { | |||
this.errors.push('Veuillez sélectionner un jour de distribution'); | |||
} | |||