Browse Source

[Administration] Produits : import CSV prix spécifiques #959

refactoring
Guillaume Bourgeois 1 year ago
parent
commit
fec4e03bad
11 changed files with 275 additions and 5 deletions
  1. +121
    -0
      backend/controllers/ProductController.php
  2. +36
    -0
      backend/forms/ProductPriceUploadForm.php
  3. +1
    -0
      backend/views/layouts/left.php
  4. +63
    -0
      backend/views/product/price_import.php
  5. +1
    -1
      common/logic/Order/Order/Service/OrderSolver.php
  6. +7
    -0
      common/logic/PointSale/PointSale/Repository/PointSaleRepository.php
  7. +5
    -0
      common/logic/Product/Product/Repository/ProductRepository.php
  8. +28
    -1
      common/logic/Product/ProductPrice/Repository/ProductPriceRepository.php
  9. +1
    -0
      common/logic/Product/ProductPrice/Wrapper/ProductPriceContainer.php
  10. +5
    -0
      common/logic/User/UserGroup/Repository/UserGroupRepository.php
  11. +7
    -3
      frontend/forms/ResetPasswordForm.php

+ 121
- 0
backend/controllers/ProductController.php View File



namespace backend\controllers; namespace backend\controllers;


use backend\forms\ProductPriceUploadForm;
use common\helpers\CSV;
use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\logic\Distribution\ProductDistribution\Model\ProductDistribution; use common\logic\Distribution\ProductDistribution\Model\ProductDistribution;
use common\logic\PointSale\PointSale\Model\PointSale; use common\logic\PointSale\PointSale\Model\PointSale;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
use common\helpers\Upload; use common\helpers\Upload;
use yii\web\UploadedFile;


/** /**
* ProduitController implements the CRUD actions for Produit model. * ProduitController implements the CRUD actions for Produit model.
return ['success', 'id' => $id, 'active' => $active]; return ['success', 'id' => $id, 'active' => $active];
} }


/**
* Import des prix produits via un fichier CSV.
*
* @return mixed
*/
public function actionPriceImport()
{
$productManager = $this->getProductManager();
$productPriceManager = $this->getProductPriceManager();
$userGroupManager = $this->getUserGroupManager();
$pointSaleManager = $this->getPointSaleManager();
$userManager = $this->getUserManager();

$model = new ProductPriceUploadForm();

if (Yii::$app->request->isPost) {
$model->file = UploadedFile::getInstance($model, 'file');

if ($model->file && $model->validate()) {
$productPriceCsvArray = array_map(function($data) { return str_getcsv($data,";");}, file($model->file->tempName));
unset($productPriceCsvArray[0]);
$countUpdate = 0;
foreach($productPriceCsvArray as $productPriceCsv) {
$productName = $productPriceCsv[0];
$userArray = explode('#', $productPriceCsv[1]);
$userGroupName = $productPriceCsv[2];
$pointSaleName = $productPriceCsv[3];
$quantityFrom = (float) $productPriceCsv[4];
$price = (float) $productPriceCsv[5];

$product = $productName ? $productManager->findOneProductByName($productName) : null;
$user = (count($userArray) > 1) ? $userManager->findOneUserById((int) $userArray[1]) : null;
$userGroup = $userGroupName ? $userGroupManager->findOneUserGroupByName($userGroupName) : null;
$pointSale = $pointSaleName ? $pointSaleManager->findOnePointSaleByName($pointSaleName) : null;

if($product) {
// prix de base
if(!$user && !$userGroup && !$pointSale && !$quantityFrom) {
$product->price = $price;
$productManager->saveUpdate($product);
$countUpdate ++;
}
// prix spécifique
else {
$productPrice = $productPriceManager->findOneProductPriceBy($product, $user, $userGroup, $pointSale, $quantityFrom);
if($productPrice) {
$productPrice->price = $price;
$productPriceManager->saveUpdate($productPrice);
$countUpdate ++;
}
}
}
}

if($countUpdate) {
$this->setFlash('success', $countUpdate.' prix produits mis à jour.');
}
}
}

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

/**
* Export des prix produits au format CSV.
*
* @return mixed
*/
public function actionPriceExport()
{
$productManager = $this->getProductManager();
$productPriceManager = $this->getProductPriceManager();
$userManager = $this->getUserManager();

$data = [];

$data[] = [
"Produit",
"Utilisateur",
"Groupe d'utilisateur",
"Point de vente",
"À partir de la quantité",
"Prix HT"
];

$productArray = $productManager->findProducts();
foreach($productArray as $product) {
$data[] = [
$product->name,
'',
'',
'',
'',
$product->price
];

foreach($product->productPrice as $productPrice) {

$productPrice = $productPriceManager->findOneProductPriceById($productPrice->id);

$data[] = [
$product->name,
$productPrice->user ? $userManager->getUsername($productPrice->user).' #'.$productPrice->user->id : '',
$productPrice->userGroup ? $productPrice->userGroup->name : '',
$productPrice->pointSale ? $productPrice->pointSale->name : '',
$productPrice->from_quantity ?? '',
$productPrice->price
];
}
}

CSV::downloadSendHeaders('prix_produits.csv');
echo CSV::array2csv($data);
die();
}

/** /**
* Recherche un produit en fonction de son ID. * Recherche un produit en fonction de son ID.
*/ */

+ 36
- 0
backend/forms/ProductPriceUploadForm.php View File

<?php

namespace backend\forms;

use yii\base\Model;
use yii\web\UploadedFile;

/**
* UploadForm is the model behind the upload form.
*/
class ProductPriceUploadForm extends Model
{
/**
* @var UploadedFile file attribute
*/
public $file;

/**
* @return array the validation rules.
*/
public function rules()
{
return [
[['file'], 'file'],
];
}

public function attributeLabels()
{
return [
'file' => "Fichier d'import (CSV)"
];
}
}

?>

+ 1
- 0
backend/views/layouts/left.php View File

'items' => [ 'items' => [
['label' => 'Liste', 'icon' => 'th-list', 'url' => ['/product/index'], 'visible' => $userManager->isCurrentProducer()], ['label' => 'Liste', 'icon' => 'th-list', 'url' => ['/product/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Catégories', 'icon' => 'book', 'url' => ['/product-category/index'], 'visible' => $userManager->isCurrentProducer()], ['label' => 'Catégories', 'icon' => 'book', 'url' => ['/product-category/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Import prix', 'icon' => 'upload', 'url' => ['/product/price-import'], 'visible' => $userManager->isCurrentProducer()],
] ]
], ],
['label' => 'Points de vente', 'icon' => 'map-marker', 'url' => ['/point-sale/index'], 'visible' => $userManager->isCurrentProducer(), 'active' => Yii::$app->controller->id == 'point-sale'], ['label' => 'Points de vente', 'icon' => 'map-marker', 'url' => ['/point-sale/index'], 'visible' => $userManager->isCurrentProducer(), 'active' => Yii::$app->controller->id == 'point-sale'],

+ 63
- 0
backend/views/product/price_import.php View File

<?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\bootstrap\ActiveForm;
use yii\helpers\Html;

$productManager = $this->getProductManager();

$this->setTitle('Import prix produits');
$this->addBreadcrumb($this->getTitle());
$this->addButton(['label' => 'Exporter les prix <span class="glyphicon glyphicon-export"></span>', 'url' => 'product/price-export', 'class' => 'btn btn-primary']);

?>

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

<?= $form->field($model, 'file')->fileInput() ?>

<div class="form-group">
<?= Html::submitButton('Envoyer', ['class' => 'btn btn-primary']) ?>
</div>

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

+ 1
- 1
common/logic/Order/Order/Service/OrderSolver.php View File

/** /**
* Retourne la quantité d'un produit donné de plusieurs commandes. * Retourne la quantité d'un produit donné de plusieurs commandes.
*/ */
public function getProductQuantity(Product $product, array $orders, bool $ignoreCancel = false, string $unit = null): int
public function getProductQuantity(Product $product, array $orders, bool $ignoreCancel = false, string $unit = null): float
{ {
$quantity = 0; $quantity = 0;



+ 7
- 0
common/logic/PointSale/PointSale/Repository/PointSaleRepository.php View File

]); ]);
} }


public function findOnePointSaleByName(string $name): ?PointSale
{
return PointSale::searchOne([
'name' => $name
]);
}

public function findPointSalesByDistribution(Distribution $distribution) public function findPointSalesByDistribution(Distribution $distribution)
{ {
return PointSale::find() return PointSale::find()

+ 5
- 0
common/logic/Product/Product/Repository/ProductRepository.php View File

return Product::searchOne(['id' => $id]); return Product::searchOne(['id' => $id]);
} }


public function findOneProductByName(string $name): ?Product
{
return Product::searchOne(['name' => $name]);
}

public function findProducts(): array public function findProducts(): array
{ {
return Product::searchAll([], [ return Product::searchAll([], [

+ 28
- 1
common/logic/Product/ProductPrice/Repository/ProductPriceRepository.php View File

namespace common\logic\Product\ProductPrice\Repository; namespace common\logic\Product\ProductPrice\Repository;


use common\logic\AbstractRepository; use common\logic\AbstractRepository;
use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\Product\Product\Model\Product;
use common\logic\Product\ProductPrice\Model\ProductPrice; use common\logic\Product\ProductPrice\Model\ProductPrice;
use common\logic\User\User\Model\User;
use common\logic\User\UserGroup\Model\UserGroup;


class ProductPriceRepository extends AbstractRepository class ProductPriceRepository extends AbstractRepository
{ {
public function getDefaultOptionsSearch(): array public function getDefaultOptionsSearch(): array
{ {
return [ return [
'with' => ['user', 'pointSale'],
'with' => ['user', 'pointSale', 'userGroup'],
'join_with' => ['product'], 'join_with' => ['product'],
'orderby' => '', 'orderby' => '',
'attribute_id_producer' => 'product.id_producer' 'attribute_id_producer' => 'product.id_producer'
{ {
return ProductPrice::searchOne(['id' => $id]); return ProductPrice::searchOne(['id' => $id]);
} }

public function findOneProductPriceBy(Product $product, User $user = null, UserGroup $userGroup = null, PointSale $pointSale = null, float $fromQuantity = null)
{
$params = ['id_product' => $product->id];

if($user) {
$params['id_user'] = $user->id;
}

if($userGroup) {
$params['id_user_group'] = $userGroup->id;
}

if($pointSale) {
$params['id_point_sale'] = $pointSale->id;
}

if($fromQuantity) {
$params['from_quantity'] = $fromQuantity;
}

return ProductPrice::searchOne($params);
}
} }

+ 1
- 0
common/logic/Product/ProductPrice/Wrapper/ProductPriceContainer.php View File

{ {
return [ return [
ProductPriceSolver::class, ProductPriceSolver::class,
ProductPriceBuilder::class,
ProductPriceRepository::class ProductPriceRepository::class
]; ];
} }

+ 5
- 0
common/logic/User/UserGroup/Repository/UserGroupRepository.php View File

return UserGroup::searchOne(['id' => $id]); return UserGroup::searchOne(['id' => $id]);
} }


public function findOneUserGroupByName(string $name)
{
return UserGroup::searchOne(['name' => $name]);
}

public function findUserGroups() public function findUserGroups()
{ {
return UserGroup::find()->where('id_producer = ' . GlobalParam::getCurrentProducerId())->all(); return UserGroup::find()->where('id_producer = ' . GlobalParam::getCurrentProducerId())->all();

+ 7
- 3
frontend/forms/ResetPasswordForm.php View File



namespace frontend\forms; namespace frontend\forms;


use common\logic\User\User\Wrapper\UserManager;
use yii\base\InvalidParamException; use yii\base\InvalidParamException;
use yii\base\Model; use yii\base\Model;
use Yii; use Yii;
*/ */
public function __construct($token, $config = []) public function __construct($token, $config = [])
{ {
$userManager = UserManager::getInstance();
if (empty($token) || !is_string($token)) { if (empty($token) || !is_string($token)) {
throw new InvalidParamException('Password reset token cannot be blank.'); throw new InvalidParamException('Password reset token cannot be blank.');
} }
$this->_user = User::findByPasswordResetToken($token);
$this->_user = $userManager->findOneUserByPasswordResetToken($token);
if (!$this->_user) { if (!$this->_user) {
throw new InvalidParamException('Wrong password reset token.'); throw new InvalidParamException('Wrong password reset token.');
} }
*/ */
public function resetPassword() public function resetPassword()
{ {
$userManager = UserManager::getInstance();

$user = $this->_user; $user = $this->_user;
$user->setPassword($this->password);
$user->removePasswordResetToken();
$userManager->setPassword($user, $this->password);
$userManager->removePasswordResetToken($user);


return $user->save(); return $user->save();
} }

Loading…
Cancel
Save