use common\logic\Distribution\ProductDistribution\ProductDistributionRepository; | use common\logic\Distribution\ProductDistribution\ProductDistributionRepository; | ||||
use common\logic\Order\Order\Order; | use common\logic\Order\Order\Order; | ||||
use common\logic\Order\Order\OrderRepository; | use common\logic\Order\Order\OrderRepository; | ||||
use common\logic\Order\ProductOrder\ProductOrderBuilder; | |||||
use common\logic\PointSale\PointSale\PointSale; | use common\logic\PointSale\PointSale\PointSale; | ||||
use common\logic\Producer\Producer\Producer; | use common\logic\Producer\Producer\Producer; | ||||
use common\logic\Product\Product\Product; | use common\logic\Product\Product\Product; | ||||
use common\logic\Product\Product\ProductRepository; | use common\logic\Product\Product\ProductRepository; | ||||
use common\logic\Subscription\Subscription\Subscription; | use common\logic\Subscription\Subscription\Subscription; | ||||
use common\logic\User\UserProducer\UserProducer; | use common\logic\User\UserProducer\UserProducer; | ||||
use common\logic\User\UserProducer\UserProducerRepository; | |||||
class DistributionBuilder extends BaseService implements BuilderInterface | class DistributionBuilder extends BaseService implements BuilderInterface | ||||
{ | { | ||||
protected ProductDistributionRepository $productDistributionRepository; | protected ProductDistributionRepository $productDistributionRepository; | ||||
protected ProductDistributionBuilder $productDistributionBuilder; | protected ProductDistributionBuilder $productDistributionBuilder; | ||||
protected OrderRepository $orderRepository; | protected OrderRepository $orderRepository; | ||||
protected UserProducerRepository $userProducerRepository; | |||||
protected ProductOrderBuilder $productOrderBuilder; | |||||
public function __construct() | public function __construct() | ||||
{ | { | ||||
$this->productRepository = $this->loadService(ProductRepository::class); | $this->productRepository = $this->loadService(ProductRepository::class); | ||||
$this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class); | $this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class); | ||||
$this->orderRepository = $this->loadService(OrderRepository::class); | $this->orderRepository = $this->loadService(OrderRepository::class); | ||||
$this->userProducerRepository = $this->loadService(UserProducerRepository::class); | |||||
$this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class); | |||||
} | } | ||||
public function instanciate(Producer $producer, string $date, bool $delivery = true): Distribution | public function instanciate(Producer $producer, string $date, bool $delivery = true): Distribution | ||||
foreach ($ordersArray as $order) { | foreach ($ordersArray as $order) { | ||||
foreach ($order->productOrder as $productOrder) { | foreach ($order->productOrder as $productOrder) { | ||||
if ($productOrder->id_product == $product->id) { | if ($productOrder->id_product == $product->id) { | ||||
$productOrder->price = $product->price; | |||||
$user = false; | |||||
$userProducer = false; | |||||
$user = null; | |||||
$userProducer = null; | |||||
if (isset($order->user) && $order->user) { | if (isset($order->user) && $order->user) { | ||||
$user = $order->user; | $user = $order->user; | ||||
$userProducer = UserProducer::searchOne([ | |||||
'id_user' => $user->id, | |||||
'id_producer' => $order->distribution->id_producer | |||||
]); | |||||
$userProducer = $this->userProducerRepository->getOne($user, $distribution->producer); | |||||
} | } | ||||
$productOrder->price = $product->getPrice([ | |||||
'user' => $user, | |||||
'user_producer' => $userProducer, | |||||
'point_sale' => $order->pointSale, | |||||
'quantity' => $productOrder->quantity | |||||
]); | |||||
$productOrder->save(); | |||||
$this->productOrderBuilder->updatePrice( | |||||
$productOrder, | |||||
$user, | |||||
$userProducer, | |||||
$order->pointSale, | |||||
$productOrder->quantity | |||||
); | |||||
} | } | ||||
} | } | ||||
} | } |
]; | ]; | ||||
} | } | ||||
public function getOneById($id): ?Distribution | |||||
{ | |||||
return Distribution::searchOne([ | |||||
'id' => $id | |||||
]); | |||||
} | |||||
public function getOne(Producer $producer, string $date) | public function getOne(Producer $producer, string $date) | ||||
{ | { | ||||
$paramsDistribution = [ | $paramsDistribution = [ |
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\BuilderInterface; | use common\logic\BuilderInterface; | ||||
use common\logic\Distribution\Distribution\Distribution; | use common\logic\Distribution\Distribution\Distribution; | ||||
use common\logic\Distribution\Distribution\DistributionRepository; | |||||
use common\logic\PointSale\PointSale\PointSale; | use common\logic\PointSale\PointSale\PointSale; | ||||
use common\logic\PointSale\PointSale\PointSaleRepository; | |||||
class PointSaleDistributionBuilder extends BaseService implements BuilderInterface | class PointSaleDistributionBuilder extends BaseService implements BuilderInterface | ||||
{ | { | ||||
protected PointSaleDistributionRepository $pointSaleDistributionRepository; | protected PointSaleDistributionRepository $pointSaleDistributionRepository; | ||||
protected PointSaleRepository $pointSaleRepository; | |||||
protected DistributionRepository $distributionRepository; | |||||
public function __construct() | public function __construct() | ||||
{ | { | ||||
$this->pointSaleDistributionRepository = $this->loadService(PointSaleDistributionRepository::class); | $this->pointSaleDistributionRepository = $this->loadService(PointSaleDistributionRepository::class); | ||||
$this->pointSaleRepository = $this->loadService(PointSaleRepository::class); | |||||
$this->distributionRepository = $this->loadService(DistributionRepository::class); | |||||
} | } | ||||
/** | /** | ||||
{ | { | ||||
$pointSaleDistribution = $this->pointSaleDistributionRepository->getOne($distribution, $pointSale); | $pointSaleDistribution = $this->pointSaleDistributionRepository->getOne($distribution, $pointSale); | ||||
if(!$pointSaleDistribution) { | |||||
if (!$pointSaleDistribution) { | |||||
$pointSaleDistribution = $this->create($distribution, $pointSale); | $pointSaleDistribution = $this->create($distribution, $pointSale); | ||||
} | } | ||||
// setAll | // setAll | ||||
public function createAll(Distribution $distribution, bool $delivery): void | public function createAll(Distribution $distribution, bool $delivery): void | ||||
{ | { | ||||
$arrPointsSale = PointSale::find() | |||||
->with(['pointSaleDistribution' => function($q) use ($distribution) { | |||||
$q->where(['id_distribution' => $distribution->id]); | |||||
}]) | |||||
->where([ | |||||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||||
]) | |||||
->all(); | |||||
foreach ($arrPointsSale as $pointSale) { | |||||
if(!$pointSale->pointSaleDistribution) { | |||||
$pointSaleArray = $this->pointSaleRepository->getByDistribution($distribution); | |||||
foreach ($pointSaleArray as $pointSale) { | |||||
if (!$pointSale->pointSaleDistribution) { | |||||
$this->create($distribution, $pointSale); | $this->create($distribution, $pointSale); | ||||
} | } | ||||
} | } | ||||
$distribution = Distribution::findOne($distribution->id); | |||||
if ($distribution) { | |||||
$arrPointsSaleDistribution = PointSaleDistribution::searchAll([ | |||||
'id_distribution' => $distribution->id | |||||
]) ; | |||||
foreach ($arrPointsSaleDistribution as $pointSaleDistribution) { | |||||
$this->initDelivery($pointSaleDistribution, $delivery); | |||||
} | |||||
$pointSaleDistributionArray = $this->pointSaleDistributionRepository->getByDistribution($distribution); | |||||
foreach ($pointSaleDistributionArray as $pointSaleDistribution) { | |||||
$this->initDelivery($pointSaleDistribution, $delivery); | |||||
} | } | ||||
} | } | ||||
]); | ]); | ||||
} | } | ||||
public function getByDistribution(Distribution $distribution) | |||||
{ | |||||
return PointSaleDistribution::searchAll([ | |||||
'id_distribution' => $distribution->id | |||||
]) ; | |||||
} | |||||
public function countByDistribution(Distribution $distribution): int | public function countByDistribution(Distribution $distribution): int | ||||
{ | { | ||||
return PointSaleDistribution::searchCount([ | return PointSaleDistribution::searchCount([ |
<?php | <?php | ||||
/** | |||||
Copyright distrib (2018) | |||||
contact@opendistrib.net | |||||
Ce logiciel est un programme informatique servant à aider les producteurs | |||||
à distribuer leur production en circuits courts. | |||||
Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||||
respectant les principes de diffusion des logiciels libres. Vous pouvez | |||||
utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||||
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||||
sur le site "http://www.cecill.info". | |||||
En contrepartie de l'accessibilité au code source et des droits de copie, | |||||
de modification et de redistribution accordés par cette licence, il n'est | |||||
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||||
seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||||
titulaire des droits patrimoniaux et les concédants successifs. | |||||
A cet égard l'attention de l'utilisateur est attirée sur les risques | |||||
associés au chargement, à l'utilisation, à la modification et/ou au | |||||
développement et à la reproduction du logiciel par l'utilisateur étant | |||||
donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||||
manipuler et qui le réserve donc à des développeurs et des professionnels | |||||
avertis possédant des connaissances informatiques approfondies. Les | |||||
utilisateurs sont donc invités à charger et tester l'adéquation du | |||||
logiciel à leurs besoins dans des conditions permettant d'assurer la | |||||
sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||||
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||||
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||||
pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||||
termes. | |||||
*/ | |||||
/** | |||||
* Copyright distrib (2018) | |||||
* | |||||
* contact@opendistrib.net | |||||
* | |||||
* Ce logiciel est un programme informatique servant à aider les producteurs | |||||
* à distribuer leur production en circuits courts. | |||||
* | |||||
* Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||||
* respectant les principes de diffusion des logiciels libres. Vous pouvez | |||||
* utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||||
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||||
* sur le site "http://www.cecill.info". | |||||
* | |||||
* En contrepartie de l'accessibilité au code source et des droits de copie, | |||||
* de modification et de redistribution accordés par cette licence, il n'est | |||||
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||||
* seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||||
* titulaire des droits patrimoniaux et les concédants successifs. | |||||
* | |||||
* A cet égard l'attention de l'utilisateur est attirée sur les risques | |||||
* associés au chargement, à l'utilisation, à la modification et/ou au | |||||
* développement et à la reproduction du logiciel par l'utilisateur étant | |||||
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||||
* manipuler et qui le réserve donc à des développeurs et des professionnels | |||||
* avertis possédant des connaissances informatiques approfondies. Les | |||||
* utilisateurs sont donc invités à charger et tester l'adéquation du | |||||
* logiciel à leurs besoins dans des conditions permettant d'assurer la | |||||
* sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||||
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||||
* | |||||
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||||
* pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||||
* termes. | |||||
*/ | |||||
namespace common\logic\Document\DeliveryNote; | namespace common\logic\Document\DeliveryNote; | ||||
class DeliveryNote extends Document | class DeliveryNote extends Document | ||||
{ | { | ||||
/** | |||||
* @inheritdoc | |||||
*/ | |||||
public static function tableName() | |||||
{ | |||||
return 'delivery_note'; | |||||
} | |||||
/* | |||||
* Relations | |||||
*/ | |||||
public function getOrders() | |||||
{ | |||||
return $this->relationOrders('id_delivery_note') ; | |||||
} | |||||
public function getInvoiceId() | |||||
{ | |||||
if($this->orders && count($this->orders) > 0) { | |||||
foreach($this->orders as $order) { | |||||
if($order->id_invoice) { | |||||
return $order->id_invoice; | |||||
} | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
public function isInvoiced() | |||||
{ | |||||
return (bool) $this->getInvoiceId(); | |||||
} | |||||
public function getInvoice() | |||||
{ | |||||
$invoice = null; | |||||
$idInvoice = $this->getInvoiceId(); | |||||
if($idInvoice) { | |||||
$invoice = Invoice::searchOne([ | |||||
'id' => $idInvoice | |||||
]); | |||||
} | |||||
return $invoice; | |||||
} | |||||
/** | |||||
* @inheritdoc | |||||
*/ | |||||
public static function tableName() | |||||
{ | |||||
return 'delivery_note'; | |||||
} | |||||
/* | |||||
* Relations | |||||
*/ | |||||
public function getOrders() | |||||
{ | |||||
return $this->relationOrders('id_delivery_note'); | |||||
} | |||||
} | } |
public function getServices(): array | public function getServices(): array | ||||
{ | { | ||||
return [ | return [ | ||||
DeliveryNoteFactory::class, | |||||
DeliveryNoteBuilder::class, | |||||
DeliveryNoteSolver::class, | DeliveryNoteSolver::class, | ||||
]; | ]; | ||||
} | } | ||||
public function getFactory(): DeliveryNoteFactory | |||||
public function getFactory(): DeliveryNoteBuilder | |||||
{ | { | ||||
return new DeliveryNoteFactory(); | |||||
return new DeliveryNoteBuilder(); | |||||
} | } | ||||
public function getSolver(): DeliveryNoteSolver | public function getSolver(): DeliveryNoteSolver |
namespace common\logic\Document\DeliveryNote; | namespace common\logic\Document\DeliveryNote; | ||||
use common\helpers\GlobalParam; | use common\helpers\GlobalParam; | ||||
use common\logic\PointSale\PointSale\DeliveryNoteRepository; | |||||
use yii\data\ActiveDataProvider; | use yii\data\ActiveDataProvider; | ||||
class DeliveryNoteSearch extends DeliveryNote | class DeliveryNoteSearch extends DeliveryNote | ||||
{ | { | ||||
public $id_point_sale ; | |||||
public $date_distribution ; | |||||
public $id_point_sale; | |||||
public $date_distribution; | |||||
public function rules() | |||||
{ | |||||
return [ | |||||
[[], 'safe'], | |||||
[['comment', 'address', 'status', 'date_distribution'], 'string'], | |||||
[['id_user', 'id_point_sale'], 'integer'], | |||||
[['name', 'reference'], 'string', 'max' => 255], | |||||
]; | |||||
} | |||||
public function search($params) | |||||
{ | |||||
$optionsSearch = self::defaultOptionsSearch(); | |||||
public function rules() | |||||
{ | |||||
return [ | |||||
[[], 'safe'], | |||||
[['comment', 'address', 'status', 'date_distribution'], 'string'], | |||||
[['id_user', 'id_point_sale'], 'integer'], | |||||
[['name', 'reference'], 'string', 'max' => 255], | |||||
]; | |||||
} | |||||
$query = DeliveryNote::find() | |||||
->with($optionsSearch['with']) | |||||
->joinWith($optionsSearch['join_with']) | |||||
->where(['delivery_note.id_producer' => GlobalParam::getCurrentProducerId()]) | |||||
->orderBy('delivery_note.status ASC, delivery_note.reference DESC') | |||||
->groupBy('delivery_note.id'); | |||||
public function search($params) | |||||
{ | |||||
$deliveryNoteRepository = new DeliveryNoteRepository(); | |||||
$optionsSearch = $deliveryNoteRepository->defaultOptionsSearch(); | |||||
$dataProvider = new ActiveDataProvider([ | |||||
'query' => $query, | |||||
'sort' => ['attributes' => ['name', 'reference', 'date']], | |||||
'pagination' => [ | |||||
'pageSize' => 20, | |||||
], | |||||
]); | |||||
$query = DeliveryNote::find() | |||||
->with($optionsSearch['with']) | |||||
->joinWith($optionsSearch['join_with']) | |||||
->where(['delivery_note.id_producer' => GlobalParam::getCurrentProducerId()]) | |||||
->orderBy('delivery_note.status ASC, delivery_note.reference DESC') | |||||
->groupBy('delivery_note.id'); | |||||
$this->load($params); | |||||
if (!$this->validate()) { | |||||
return $dataProvider; | |||||
} | |||||
$dataProvider = new ActiveDataProvider([ | |||||
'query' => $query, | |||||
'sort' => ['attributes' => ['name', 'reference', 'date']], | |||||
'pagination' => [ | |||||
'pageSize' => 20, | |||||
], | |||||
]); | |||||
$query->andFilterWhere(['like', 'delivery_note.name', $this->name]); | |||||
$query->andFilterWhere(['like', 'delivery_note.reference', $this->reference]); | |||||
$query->andFilterWhere(['like', 'delivery_note.status', $this->status]); | |||||
$this->load($params); | |||||
if (!$this->validate()) { | |||||
return $dataProvider; | |||||
} | |||||
if($this->id_point_sale) { | |||||
$query->andWhere(['order.id_point_sale' => $this->id_point_sale]); | |||||
} | |||||
$query->andFilterWhere(['like', 'delivery_note.name', $this->name]); | |||||
$query->andFilterWhere(['like', 'delivery_note.reference', $this->reference]); | |||||
$query->andFilterWhere(['like', 'delivery_note.status', $this->status]); | |||||
if($this->date_distribution && strlen($this->date_distribution)) { | |||||
$query->andFilterWhere(['like', 'distribution.date', date('Y-m-d',strtotime(str_replace('/','-',$this->date_distribution)))]); | |||||
} | |||||
if ($this->id_point_sale) { | |||||
$query->andWhere(['order.id_point_sale' => $this->id_point_sale]); | |||||
} | |||||
return $dataProvider; | |||||
if ($this->date_distribution && strlen($this->date_distribution)) { | |||||
$query->andFilterWhere(['like', 'distribution.date', date('Y-m-d', strtotime(str_replace('/', '-', $this->date_distribution)))]); | |||||
} | } | ||||
return $dataProvider; | |||||
} | |||||
} | } |
namespace common\logic\Document\DeliveryNote; | namespace common\logic\Document\DeliveryNote; | ||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\Document\Invoice\Invoice; | |||||
use common\logic\SolverInterface; | use common\logic\SolverInterface; | ||||
class DeliveryNoteSolver extends BaseService implements SolverInterface | class DeliveryNoteSolver extends BaseService implements SolverInterface | ||||
{ | { | ||||
public function getInvoiceId(DeliveryNote $deliveryNote): ?int | |||||
{ | |||||
if($deliveryNote->orders && count($deliveryNote->orders) > 0) { | |||||
foreach($deliveryNote->orders as $order) { | |||||
if($order->id_invoice) { | |||||
return $order->id_invoice; | |||||
} | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
public function isInvoiced(DeliveryNote $deliveryNote): bool | |||||
{ | |||||
return (bool) $this->getInvoiceId($deliveryNote); | |||||
} | |||||
public function getInvoice(DeliveryNote $deliveryNote): ?Invoice | |||||
{ | |||||
$idInvoice = (int) $this->getInvoiceId($deliveryNote); | |||||
return Invoice::searchOne([ | |||||
'id' => $idInvoice | |||||
]); | |||||
} | |||||
} | } |
use common\components\ActiveRecordCommon; | use common\components\ActiveRecordCommon; | ||||
use common\helpers\GlobalParam; | use common\helpers\GlobalParam; | ||||
use common\logic\Order\Order\Order; | |||||
use common\logic\Order\Order\OrderRepository; | |||||
use common\logic\Producer\Producer\Producer; | use common\logic\Producer\Producer\Producer; | ||||
use common\logic\User\User\User; | |||||
use kartik\mpdf\Pdf; | use kartik\mpdf\Pdf; | ||||
use yii\base\ErrorException; | use yii\base\ErrorException; | ||||
class Document extends ActiveRecordCommon | |||||
class Document extends ActiveRecordCommon implements DocumentInterface | |||||
{ | { | ||||
const STATUS_DRAFT = 'draft'; | const STATUS_DRAFT = 'draft'; | ||||
const STATUS_VALID = 'valid'; | const STATUS_VALID = 'valid'; | ||||
public function getUser() | public function getUser() | ||||
{ | { | ||||
return $this->hasOne( User::className(), ['id' => 'id_user']); | |||||
return $this->hasOne(User::class, ['id' => 'id_user']); | |||||
} | } | ||||
public function getProducer() | public function getProducer() | ||||
public function relationOrders($fieldIdDocument) | public function relationOrders($fieldIdDocument) | ||||
{ | { | ||||
$defaultOptionsSearch = Order::defaultOptionsSearch(); | |||||
$orderRepository = new OrderRepository(); | |||||
$defaultOptionsSearch = $orderRepository->defaultOptionsSearch(); | |||||
return $this->hasMany(Order::className(), [$fieldIdDocument => 'id']) | |||||
return $this->hasMany(Order::class, [$fieldIdDocument => 'id']) | |||||
->with($defaultOptionsSearch['with']) | ->with($defaultOptionsSearch['with']) | ||||
->joinWith($defaultOptionsSearch['join_with']) | ->joinWith($defaultOptionsSearch['join_with']) | ||||
->orderBy('distribution.date ASC'); | ->orderBy('distribution.date ASC'); | ||||
* Méthodes | * Méthodes | ||||
*/ | */ | ||||
public function getAmount($type = Order::AMOUNT_TOTAL, $format = false) | |||||
{ | |||||
return $this->_getAmountGeneric($type, false, $format); | |||||
} | |||||
public function getAmountWithTax($type = Order::AMOUNT_TOTAL, $format = false) | |||||
{ | |||||
return $this->_getAmountGeneric($type, true, $format); | |||||
} | |||||
protected function _getAmountGeneric($type = Order::AMOUNT_TOTAL, $withTax = true, $format = false) | |||||
{ | |||||
$amount = 0; | |||||
$totalVat = 0; | |||||
$ordersArray = $this->orders; | |||||
// Méthode de calcul via les commandes liées | |||||
/*foreach ($ordersArray as $order) { | |||||
$order->init($this->tax_calculation_method); | |||||
$amount += $order->getAmount($type); | |||||
$totalVat += $order->getTotalVat($type); | |||||
}*/ | |||||
// Méthode de calcul via getProductOrders() | |||||
foreach($this->getProductsOrders() as $productOrderArray) { | |||||
foreach($productOrderArray as $productOrder) { | |||||
$priceLine = $productOrder->getPriceByTypeTotal($type) * $productOrder->quantity; | |||||
$amount += $priceLine; | |||||
$totalVat += Price::getVat($priceLine, $productOrder->taxRate->value, $this->tax_calculation_method); | |||||
} | |||||
} | |||||
if ($this->isTaxCalculationMethodRoundingOfTheSum()) { | |||||
$totalVat = Price::round($totalVat); | |||||
} | |||||
if ($withTax) { | |||||
$amount += $totalVat; | |||||
} | |||||
if ($format) { | |||||
return Price::format($amount); | |||||
} else { | |||||
return $amount; | |||||
} | |||||
} | |||||
public function getTotalVatArray($typeTotal) | |||||
{ | |||||
$totalVatArray = []; | |||||
// Méthode de calcul via les commandes liées | |||||
/*$ordersArray = $this->orders; | |||||
foreach ($ordersArray as $order) { | |||||
$order->init($this->tax_calculation_method); | |||||
$fieldNameVat = $order->getFieldNameAmount($typeTotal, 'vat'); | |||||
foreach ($order->$fieldNameVat as $idTaxRate => $vat) { | |||||
if (!isset($totalVatArray[$idTaxRate])) { | |||||
$totalVatArray[$idTaxRate] = 0; | |||||
} | |||||
$totalVatArray[$idTaxRate] += $vat; | |||||
} | |||||
}*/ | |||||
// Méthode de calcul via getProductOrders() | |||||
foreach($this->getProductsOrders() as $productOrderArray) { | |||||
foreach ($productOrderArray as $productOrder) { | |||||
$idTaxRate = $productOrder->taxRate->id; | |||||
if (!isset($totalVatArray[$idTaxRate])) { | |||||
$totalVatArray[$idTaxRate] = 0; | |||||
} | |||||
$totalVatArray[$idTaxRate] += Price::getVat( | |||||
$productOrder->getPriceByTypeTotal($typeTotal) * $productOrder->quantity, | |||||
$productOrder->taxRate->value, | |||||
$this->tax_calculation_method | |||||
); | |||||
} | |||||
} | |||||
return $totalVatArray; | |||||
} | |||||
public function getPointSale() | |||||
{ | |||||
if (isset($this->orders) && isset($this->orders[0])) { | |||||
return $this->orders[0]->pointSale; | |||||
} else { | |||||
return ''; | |||||
} | |||||
} | |||||
public function getDistribution() | |||||
{ | |||||
if (isset($this->orders) && isset($this->orders[0])) { | |||||
return $this->orders[0]->distribution; | |||||
} else { | |||||
return ''; | |||||
} | |||||
} | |||||
public function getClass() | |||||
{ | |||||
return str_replace('common\models\\', '', get_class($this)); | |||||
} | |||||
public function getType() | |||||
{ | |||||
$class = $this->getClass(); | |||||
if ($class == 'Invoice') { | |||||
$documentType = 'Facture'; | |||||
} elseif ($class == 'DeliveryNote') { | |||||
$documentType = 'Bon de livraison'; | |||||
} elseif ($class == 'Quotation') { | |||||
$documentType = 'Devis'; | |||||
} | |||||
if (isset($documentType)) { | |||||
return $documentType; | |||||
} | |||||
return ''; | |||||
} | |||||
public function isValidClass($typeDocument) | |||||
{ | |||||
return in_array($typeDocument, ['Invoice', 'DeliveryNote', 'Quotation']); | |||||
} | |||||
public function generateReference() | public function generateReference() | ||||
{ | { |
<?php | |||||
namespace common\logic\Document\Document; | |||||
interface DocumentInterface | |||||
{ | |||||
} |
namespace common\logic\Document\Document; | namespace common\logic\Document\Document; | ||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\Order\Order\Order; | |||||
use common\logic\SolverInterface; | use common\logic\SolverInterface; | ||||
class DocumentSolver extends BaseService implements SolverInterface | class DocumentSolver extends BaseService implements SolverInterface | ||||
{ | { | ||||
public function getAmount(DocumentInterface $document, $type = Order::AMOUNT_TOTAL, $format = false) | |||||
{ | |||||
return $this->_getAmountGeneric($document, $type, false, $format); | |||||
} | |||||
public function getAmountWithTax(DocumentInterface $document, $type = Order::AMOUNT_TOTAL, $format = false) | |||||
{ | |||||
return $this->_getAmountGeneric($document, $type, true, $format); | |||||
} | |||||
protected function _getAmountGeneric(DocumentInterface $document, $type = Order::AMOUNT_TOTAL, $withTax = true, $format = false) | |||||
{ | |||||
$amount = 0; | |||||
$totalVat = 0; | |||||
foreach($document->getProductsOrders() as $productOrderArray) { | |||||
foreach($productOrderArray as $productOrder) { | |||||
$priceLine = $productOrder->getPriceByTypeTotal($type) * $productOrder->quantity; | |||||
$amount += $priceLine; | |||||
$totalVat += Price::getVat($priceLine, $productOrder->taxRate->value, $document->tax_calculation_method); | |||||
} | |||||
} | |||||
if ($this->isTaxCalculationMethodRoundingOfTheSum()) { | |||||
$totalVat = Price::round($totalVat); | |||||
} | |||||
if ($withTax) { | |||||
$amount += $totalVat; | |||||
} | |||||
if ($format) { | |||||
return Price::format($amount); | |||||
} else { | |||||
return $amount; | |||||
} | |||||
} | |||||
public function getTotalVatArray($typeTotal) | |||||
{ | |||||
$totalVatArray = []; | |||||
// Méthode de calcul via getProductOrders() | |||||
foreach($this->getProductsOrders() as $productOrderArray) { | |||||
foreach ($productOrderArray as $productOrder) { | |||||
$idTaxRate = $productOrder->taxRate->id; | |||||
if (!isset($totalVatArray[$idTaxRate])) { | |||||
$totalVatArray[$idTaxRate] = 0; | |||||
} | |||||
$totalVatArray[$idTaxRate] += Price::getVat( | |||||
$productOrder->getPriceByTypeTotal($typeTotal) * $productOrder->quantity, | |||||
$productOrder->taxRate->value, | |||||
$this->tax_calculation_method | |||||
); | |||||
} | |||||
} | |||||
return $totalVatArray; | |||||
} | |||||
public function getPointSale() | |||||
{ | |||||
if (isset($this->orders) && isset($this->orders[0])) { | |||||
return $this->orders[0]->pointSale; | |||||
} else { | |||||
return ''; | |||||
} | |||||
} | |||||
public function getDistribution() | |||||
{ | |||||
if (isset($this->orders) && isset($this->orders[0])) { | |||||
return $this->orders[0]->distribution; | |||||
} else { | |||||
return ''; | |||||
} | |||||
} | |||||
public function getClass() | |||||
{ | |||||
return str_replace('common\models\\', '', get_class($this)); | |||||
} | |||||
public function getType() | |||||
{ | |||||
$class = $this->getClass(); | |||||
if ($class == 'Invoice') { | |||||
$documentType = 'Facture'; | |||||
} elseif ($class == 'DeliveryNote') { | |||||
$documentType = 'Bon de livraison'; | |||||
} elseif ($class == 'Quotation') { | |||||
$documentType = 'Devis'; | |||||
} | |||||
if (isset($documentType)) { | |||||
return $documentType; | |||||
} | |||||
return ''; | |||||
} | |||||
public function isValidClass($typeDocument) | |||||
{ | |||||
return in_array($typeDocument, ['Invoice', 'DeliveryNote', 'Quotation']); | |||||
} | |||||
} | } |
return $this->hasOne(DeliveryNote::className(), ['id' => 'id_delivery_note']); | return $this->hasOne(DeliveryNote::className(), ['id' => 'id_delivery_note']); | ||||
} | } | ||||
/** | |||||
* Retourne les options de base nécessaires à la fonction de recherche. | |||||
* | |||||
* @return array | |||||
*/ | |||||
public static function defaultOptionsSearch() | |||||
{ | |||||
return [ | |||||
'with' => [ | |||||
'productOrder', | |||||
'productOrder.product', | |||||
'creditHistory', | |||||
'creditHistory.userAction', | |||||
'pointSale' | |||||
], | |||||
'join_with' => ['distribution', 'user', 'user.userProducer'], | |||||
'orderby' => 'order.date ASC', | |||||
'attribute_id_producer' => 'distribution.id_producer' | |||||
]; | |||||
} | |||||
/** | /** | ||||
* Initialise le montant total, le montant déjà payé et le poids de la | * Initialise le montant total, le montant déjà payé et le poids de la | ||||
* commande. | * commande. |
class OrderRepository extends BaseService implements RepositoryInterface | class OrderRepository extends BaseService implements RepositoryInterface | ||||
{ | { | ||||
public function defaultOptionsSearch(): array | |||||
{ | |||||
return [ | |||||
'with' => [ | |||||
'productOrder', | |||||
'productOrder.product', | |||||
'creditHistory', | |||||
'creditHistory.userAction', | |||||
'pointSale' | |||||
], | |||||
'join_with' => ['distribution', 'user', 'user.userProducer'], | |||||
'orderby' => 'order.date ASC', | |||||
'attribute_id_producer' => 'distribution.id_producer' | |||||
]; | |||||
} | |||||
public function getByDistribution(Distribution $distribution, string $conditionAppend = '') | public function getByDistribution(Distribution $distribution, string $conditionAppend = '') | ||||
{ | { | ||||
return Order::searchAll([ | return Order::searchAll([ |
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\BuilderInterface; | use common\logic\BuilderInterface; | ||||
use common\logic\PointSale\PointSale\PointSale; | |||||
use common\logic\Product\Product\ProductSolver; | |||||
use common\logic\User\User\User; | |||||
use common\logic\User\UserProducer\UserProducer; | |||||
class ProductOrderBuilder extends BaseService implements BuilderInterface | class ProductOrderBuilder extends BaseService implements BuilderInterface | ||||
{ | { | ||||
protected ProductSolver $productSolver; | |||||
public function __construct() | |||||
{ | |||||
$this->productSolver = $this->loadService(ProductSolver::class); | |||||
} | |||||
public function instanciate(): ProductOrder | public function instanciate(): ProductOrder | ||||
{ | { | ||||
$productOrder = new ProductOrder(); | $productOrder = new ProductOrder(); | ||||
return $productOrder; | return $productOrder; | ||||
} | } | ||||
public function updatePrice( | |||||
ProductOrder $productOrder, | |||||
User $user = null, | |||||
UserProducer $userProducer = null, | |||||
PointSale $pointSale = null, | |||||
int $quantity = 1) | |||||
{ | |||||
$productOrder->price = $this->productSolver->getPrice( | |||||
$productOrder->product, | |||||
[ | |||||
'user' => $user, | |||||
'user_producer' => $userProducer, | |||||
'point_sale' => $pointSale, | |||||
'quantity' => $quantity | |||||
]); | |||||
$productOrder->save(); | |||||
return $productOrder; | |||||
} | |||||
} | } |
namespace common\logic\PointSale\PointSale; | namespace common\logic\PointSale\PointSale; | ||||
use common\helpers\GlobalParam; | |||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\BuilderInterface; | use common\logic\BuilderInterface; | ||||
use common\logic\Distribution\Distribution\Distribution; | |||||
use common\logic\RepositoryInterface; | use common\logic\RepositoryInterface; | ||||
class PointSaleRepository extends BaseService implements RepositoryInterface | class PointSaleRepository extends BaseService implements RepositoryInterface | ||||
{ | { | ||||
public function getByDistribution(Distribution $distribution) | |||||
{ | |||||
return PointSale::find() | |||||
->with(['pointSaleDistribution' => function($q) use ($distribution) { | |||||
$q->where(['id_distribution' => $distribution->id]); | |||||
}]) | |||||
->where([ | |||||
'id_producer' => $distribution->producer->id, | |||||
]) | |||||
->all(); | |||||
} | |||||
} | } |
return false; | return false; | ||||
} | } | ||||
public function getSpecificPricesFilterByPriorityMatch($specificPrices, $user, $pointSale) | |||||
{ | |||||
$priorityMatchSpecificPrice = ProductPrice::getPriorityMatchOfSpecificPriceArray($specificPrices, $user, $pointSale); | |||||
$specificPricesFilter = []; | |||||
foreach ($specificPrices as $keySpecificPrice => $specificPrice) { | |||||
if (($priorityMatchSpecificPrice && $specificPrice->$priorityMatchSpecificPrice($user, $pointSale)) | |||||
|| $specificPrice->matchFromQuantityOnly()) { | |||||
$specificPricesFilter[] = $specificPrice; | |||||
} | |||||
} | |||||
return $specificPricesFilter; | |||||
} | |||||
public function getPrice($params = []) | |||||
{ | |||||
$specificPrices = $this->productPrice; | |||||
$user = isset($params['user']) ? $params['user'] : false; | |||||
$userProducer = isset($params['user_producer']) ? $params['user_producer'] : false; | |||||
$pointSale = isset($params['point_sale']) ? $params['point_sale'] : false; | |||||
$quantity = (isset($params['quantity']) && $params['quantity']) ? $params['quantity'] : 1; | |||||
if ($specificPrices && ($user || $pointSale)) { | |||||
$specificPrices = $this->getSpecificPricesFilterByPriorityMatch($specificPrices, $user, $pointSale); | |||||
$bestPrice = 9999; | |||||
foreach ($specificPrices as $specificPrice) { | |||||
$fromQuantity = $specificPrice->from_quantity; | |||||
if ((($fromQuantity && $fromQuantity <= $quantity) || !$fromQuantity) | |||||
&& $specificPrice->price < $bestPrice) { | |||||
$bestPrice = $specificPrice->price; | |||||
} | |||||
} | |||||
if ($bestPrice != 9999) { | |||||
return $bestPrice; | |||||
} | |||||
} | |||||
if ($userProducer && $userProducer->product_price_percent) { | |||||
return $this->price * (1 + $userProducer->product_price_percent / 100); | |||||
} | |||||
if ($pointSale && $pointSale->product_price_percent) { | |||||
return $this->price * (1 + $pointSale->product_price_percent / 100); | |||||
} | |||||
return $this->price; | |||||
} | |||||
/** | /** | ||||
* Retourne le prix du produit avec taxe | * Retourne le prix du produit avec taxe | ||||
*/ | */ |
namespace common\logic\Product\Product; | namespace common\logic\Product\Product; | ||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\PointSale\PointSale\PointSale; | |||||
use common\logic\Product\ProductPrice\ProductPriceSolver; | |||||
use common\logic\SolverInterface; | use common\logic\SolverInterface; | ||||
use common\logic\User\User\User; | |||||
class ProductSolver extends BaseService implements SolverInterface | class ProductSolver extends BaseService implements SolverInterface | ||||
{ | { | ||||
protected ProductPriceSolver $productPriceSolver; | |||||
public function __construct() | |||||
{ | |||||
$this->productPriceSolver = $this->loadService(ProductPriceSolver::class); | |||||
} | |||||
public function getPrice(Product $product, array $params = []): float | |||||
{ | |||||
$specificPriceArray = $product->productPrice; | |||||
$user = isset($params['user']) ? $params['user'] : false; | |||||
$userProducer = isset($params['user_producer']) ? $params['user_producer'] : false; | |||||
$pointSale = isset($params['point_sale']) ? $params['point_sale'] : false; | |||||
$quantity = (isset($params['quantity']) && $params['quantity']) ? $params['quantity'] : 1; | |||||
if ($specificPriceArray && ($user || $pointSale)) { | |||||
$specificPriceArray = $this->productPriceSolver->filterByPriorityMatch( | |||||
$specificPriceArray, | |||||
$user, | |||||
$pointSale | |||||
); | |||||
$bestPrice = 9999; | |||||
foreach ($specificPriceArray as $specificPrice) { | |||||
$fromQuantity = $specificPrice->from_quantity; | |||||
if ((($fromQuantity && $fromQuantity <= $quantity) || !$fromQuantity) | |||||
&& $specificPrice->price < $bestPrice) { | |||||
$bestPrice = $specificPrice->price; | |||||
} | |||||
} | |||||
if ($bestPrice != 9999) { | |||||
return $bestPrice; | |||||
} | |||||
} | |||||
if ($userProducer && $userProducer->product_price_percent) { | |||||
return $product->price * (1 + $userProducer->product_price_percent / 100); | |||||
} | |||||
if ($pointSale && $pointSale->product_price_percent) { | |||||
return $product->price * (1 + $pointSale->product_price_percent / 100); | |||||
} | |||||
return $product->price; | |||||
} | |||||
} | } |
return $percentValues; | return $percentValues; | ||||
} | } | ||||
public static function hasMatchOfType($specificPriceArray, $typeMatch, $user, $pointSale) | |||||
{ | |||||
foreach($specificPriceArray as $specificPrice) { | |||||
if($specificPrice->$typeMatch($user, $pointSale)) { | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
public static function getPriorityMatchOfSpecificPriceArray($specificPriceArray, $user, $pointSale) | |||||
{ | |||||
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'; | |||||
} | |||||
if(self::hasMatchOfType($specificPriceArray, 'matchUserPointSale', $user, $pointSale)) { | |||||
return 'matchUserPointSale'; | |||||
} | |||||
if(self::hasMatchOfType($specificPriceArray, 'matchUserGroupPointSale', $user, $pointSale)) { | |||||
return 'matchUserGroupPointSale'; | |||||
} | |||||
return null; | |||||
} | |||||
public function matchUser($user, $pointSale) | |||||
{ | |||||
return $user | |||||
&& $this->id_user | |||||
&& !$this->id_point_sale | |||||
&& !$this->id_user_group | |||||
&& $this->id_user == $user->id; | |||||
} | |||||
public function matchUserGroup($user, $pointSale) | |||||
{ | |||||
return $user | |||||
&& $this->id_user_group | |||||
&& !$this->id_point_sale | |||||
&& !$this->id_user | |||||
&& $user->belongsToUserGroup($this->id_user_group); | |||||
} | |||||
public function matchPointSale($user, $pointSale) | |||||
{ | |||||
return $pointSale | |||||
&& $this->id_point_sale | |||||
&& !$this->id_user | |||||
&& !$this->id_user_group | |||||
&& $this->id_point_sale == $pointSale->id; | |||||
} | |||||
public function matchUserPointSale($user, $pointSale) | |||||
{ | |||||
return $pointSale && $user | |||||
&& $this->id_point_sale | |||||
&& $this->id_user | |||||
&& $this->id_point_sale == $pointSale->id | |||||
&& $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 | |||||
&& !$this->id_point_sale | |||||
&& !$this->id_user_group | |||||
&& $this->from_quantity; | |||||
} | |||||
} | } |
namespace common\logic\Product\ProductPrice; | namespace common\logic\Product\ProductPrice; | ||||
use common\logic\BaseService; | use common\logic\BaseService; | ||||
use common\logic\PointSale\PointSale\PointSale; | |||||
use common\logic\SolverInterface; | use common\logic\SolverInterface; | ||||
use common\logic\User\User\User; | |||||
class ProductPriceSolver extends BaseService implements SolverInterface | class ProductPriceSolver extends BaseService implements SolverInterface | ||||
{ | { | ||||
// getSpecificPricesFilterByPriorityMatch | |||||
public function filterByPriorityMatch( | |||||
array $specificPrices, | |||||
User $user, | |||||
PointSale $pointSale): array | |||||
{ | |||||
$priorityMatchSpecificPrice = $this->getPriorityMatch($specificPrices, $user, $pointSale); | |||||
$specificPricesFilter = []; | |||||
foreach ($specificPrices as $keySpecificPrice => $specificPrice) { | |||||
if (($priorityMatchSpecificPrice && $specificPrice->$priorityMatchSpecificPrice($user, $pointSale)) | |||||
|| $specificPrice->matchFromQuantityOnly()) { | |||||
$specificPricesFilter[] = $specificPrice; | |||||
} | |||||
} | |||||
return $specificPricesFilter; | |||||
} | |||||
// getPriorityMatchOfSpecificPriceArray | |||||
public function getPriorityMatch( | |||||
array $specificPriceArray, | |||||
User $user = null, | |||||
PointSale $pointSale = null): ?string | |||||
{ | |||||
$typeMatchArray = [ | |||||
'matchUser', | |||||
'matchUserGroup', | |||||
'matchPointSale', | |||||
'matchUserPointSale', | |||||
'matchUserGroupPointSale' | |||||
]; | |||||
foreach($typeMatchArray as $typeMatch) { | |||||
if($this->hasMatchOfType($specificPriceArray, $typeMatch, $user, $pointSale)) { | |||||
return $typeMatch; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
public function hasMatchOfType( | |||||
array $specificPriceArray, | |||||
string $typeMatch, | |||||
User $user = null, | |||||
PointSale $pointSale = null): bool | |||||
{ | |||||
foreach($specificPriceArray as $specificPrice) { | |||||
if($specificPrice->$typeMatch($user, $pointSale)) { | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
public function matchUser(ProductPrice $productPrice, User $user = null, PointSale $pointSale = null): bool | |||||
{ | |||||
return $user | |||||
&& $productPrice->id_user | |||||
&& !$productPrice->id_point_sale | |||||
&& !$productPrice->id_user_group | |||||
&& $productPrice->id_user == $user->id; | |||||
} | |||||
public function matchUserGroup(ProductPrice $productPrice, User $user = null, PointSale $pointSale = null): bool | |||||
{ | |||||
return $user | |||||
&& $productPrice->id_user_group | |||||
&& !$productPrice->id_point_sale | |||||
&& !$productPrice->id_user | |||||
&& $user->belongsToUserGroup($productPrice->id_user_group); | |||||
} | |||||
public function matchPointSale(ProductPrice $productPrice, User $user = null, PointSale $pointSale = null): bool | |||||
{ | |||||
return $pointSale | |||||
&& $productPrice->id_point_sale | |||||
&& !$productPrice->id_user | |||||
&& !$productPrice->id_user_group | |||||
&& $productPrice->id_point_sale == $pointSale->id; | |||||
} | |||||
public function matchUserPointSale(ProductPrice $productPrice, User $user = null, PointSale $pointSale = null): bool | |||||
{ | |||||
return $pointSale && $user | |||||
&& $productPrice->id_point_sale | |||||
&& $productPrice->id_user | |||||
&& $productPrice->id_point_sale == $pointSale->id | |||||
&& $productPrice->id_user == $user->id; | |||||
} | |||||
public function matchUserGroupPointSale(ProductPrice $productPrice, User $user = null, PointSale $pointSale = null): bool | |||||
{ | |||||
return $user | |||||
&& $pointSale | |||||
&& $productPrice->id_user_group | |||||
&& $productPrice->id_point_sale | |||||
&& !$productPrice->id_user | |||||
&& $user->belongsToUserGroup($productPrice->id_user_group) | |||||
&& $productPrice->id_point_sale == $pointSale->id; | |||||
} | |||||
public function matchFromQuantityOnly(ProductPrice $productPrice): bool | |||||
{ | |||||
return !$productPrice->id_user | |||||
&& !$productPrice->id_point_sale | |||||
&& !$productPrice->id_user_group | |||||
&& $productPrice->from_quantity; | |||||
} | |||||
} | } |
"yiisoft/yii2-debug": "*", | "yiisoft/yii2-debug": "*", | ||||
"yiisoft/yii2-gii": "*", | "yiisoft/yii2-gii": "*", | ||||
"yiisoft/yii2-faker": "*", | "yiisoft/yii2-faker": "*", | ||||
"codeception/codeception": "^2.3" | |||||
"codeception/codeception": "^2.3", | |||||
"phpstan/phpstan": "^1.9" | |||||
}, | }, | ||||
"config": { | "config": { | ||||
"process-timeout": 1800, | "process-timeout": 1800, |
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | ||||
"This file is @generated automatically" | "This file is @generated automatically" | ||||
], | ], | ||||
"content-hash": "78a16f604e3b8e2cb623f7204619682f", | |||||
"content-hash": "85c783330a1d88a3ed3c4674e84d10ba", | |||||
"packages": [ | "packages": [ | ||||
{ | { | ||||
"name": "2amigos/yii2-chartjs-widget", | "name": "2amigos/yii2-chartjs-widget", | ||||
}, | }, | ||||
"time": "2020-03-05T15:02:03+00:00" | "time": "2020-03-05T15:02:03+00:00" | ||||
}, | }, | ||||
{ | |||||
"name": "phpstan/phpstan", | |||||
"version": "1.9.17", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/phpstan/phpstan.git", | |||||
"reference": "204e459e7822f2c586463029f5ecec31bb45a1f2" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/204e459e7822f2c586463029f5ecec31bb45a1f2", | |||||
"reference": "204e459e7822f2c586463029f5ecec31bb45a1f2", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"php": "^7.2|^8.0" | |||||
}, | |||||
"conflict": { | |||||
"phpstan/phpstan-shim": "*" | |||||
}, | |||||
"bin": [ | |||||
"phpstan", | |||||
"phpstan.phar" | |||||
], | |||||
"type": "library", | |||||
"autoload": { | |||||
"files": [ | |||||
"bootstrap.php" | |||||
] | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"description": "PHPStan - PHP Static Analysis Tool", | |||||
"keywords": [ | |||||
"dev", | |||||
"static analysis" | |||||
], | |||||
"support": { | |||||
"issues": "https://github.com/phpstan/phpstan/issues", | |||||
"source": "https://github.com/phpstan/phpstan/tree/1.9.17" | |||||
}, | |||||
"funding": [ | |||||
{ | |||||
"url": "https://github.com/ondrejmirtes", | |||||
"type": "github" | |||||
}, | |||||
{ | |||||
"url": "https://github.com/phpstan", | |||||
"type": "github" | |||||
}, | |||||
{ | |||||
"url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", | |||||
"type": "tidelift" | |||||
} | |||||
], | |||||
"time": "2023-02-08T12:25:00+00:00" | |||||
}, | |||||
{ | { | ||||
"name": "phpunit/php-code-coverage", | "name": "phpunit/php-code-coverage", | ||||
"version": "6.1.4", | "version": "6.1.4", |