Browse Source

Merge branch 'develop'

master
Guillaume 2 years ago
parent
commit
cedf51ca83
12 changed files with 246 additions and 87 deletions
  1. +18
    -4
      Definition/Field/Order/OrderShopFieldDefinition.php
  2. +66
    -36
      Definition/Field/User/UserFieldDefinition.php
  3. +68
    -0
      Field/Filter/Order/OrderShopDistributionFilter.php
  4. +1
    -13
      Field/Filter/Order/OrderShopOrderDeliveryTypeFilter.php
  5. +12
    -0
      Repository/Order/OrderShopRepositoryQuery.php
  6. +4
    -0
      Resources/translations/admin.fr.yaml
  7. +1
    -0
      Resources/views/admin/order/field/delivery_type.html.twig
  8. +11
    -0
      Resources/views/admin/order/field/distribution.html.twig
  9. +12
    -0
      Resources/views/admin/user/field/count_order.html.twig
  10. +8
    -0
      Resources/views/admin/user/field/total_spent.html.twig
  11. +6
    -2
      Solver/Config/UnitSolver.php
  12. +39
    -32
      Solver/Order/OrderShopSolver.php

+ 18
- 4
Definition/Field/Order/OrderShopFieldDefinition.php View File



namespace Lc\CaracoleBundle\Definition\Field\Order; namespace Lc\CaracoleBundle\Definition\Field\Order;


use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\Field; use EasyCorp\Bundle\EasyAdminBundle\Field\Field;
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField; use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
use Lc\CaracoleBundle\Definition\Field\AbstractFieldDefinition; use Lc\CaracoleBundle\Definition\Field\AbstractFieldDefinition;
use Lc\CaracoleBundle\Field\AssociationField; use Lc\CaracoleBundle\Field\AssociationField;
use Lc\CaracoleBundle\Field\Filter\Order\OrderShopComplementaryFilter; use Lc\CaracoleBundle\Field\Filter\Order\OrderShopComplementaryFilter;
use Lc\CaracoleBundle\Field\Filter\Order\OrderShopDistributionFilter;
use Lc\CaracoleBundle\Field\Filter\Order\OrderShopOrderDeliveryTypeFilter; use Lc\CaracoleBundle\Field\Filter\Order\OrderShopOrderDeliveryTypeFilter;
use Lc\CaracoleBundle\Field\Filter\Order\OrderShopOrderPaymentFilter; use Lc\CaracoleBundle\Field\Filter\Order\OrderShopOrderPaymentFilter;
use Lc\CaracoleBundle\Field\Filter\Order\OrderShopOrderStatusFilter; use Lc\CaracoleBundle\Field\Filter\Order\OrderShopOrderStatusFilter;
use Lc\CaracoleBundle\Field\Filter\Order\OrderShopUserFirstnameFilter; use Lc\CaracoleBundle\Field\Filter\Order\OrderShopUserFirstnameFilter;
use Lc\CaracoleBundle\Field\Filter\Order\OrderShopUserLastnameFilter; use Lc\CaracoleBundle\Field\Filter\Order\OrderShopUserLastnameFilter;
use Lc\CaracoleBundle\Repository\Section\SectionStore; use Lc\CaracoleBundle\Repository\Section\SectionStore;
use Lc\CaracoleBundle\Solver\Order\OrderShopSolver;
use Lc\SovBundle\Translation\TranslatorAdmin; use Lc\SovBundle\Translation\TranslatorAdmin;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;


'orderShopCreatedAt' => DateTimeField::new('orderShopCreatedAt')->setSortable(true), 'orderShopCreatedAt' => DateTimeField::new('orderShopCreatedAt')->setSortable(true),
'distribution' => AssociationField::new('distribution') 'distribution' => AssociationField::new('distribution')
->setSortable(true) ->setSortable(true)
->setCustomOption('filter_type', TextType::class)
->setCustomOption('filter_on', 'cycleNumber'),
->setCustomOption('filter_fqcn', OrderShopDistributionFilter::class)
->setTemplatePath('@LcCaracole/admin/order/field/distribution.html.twig'),
// ->setCustomOption('filter_type', TextType::class)
// ->setCustomOption('filter_on', 'cycleNumber'),
'cycleDeliveryId' => IntegerField::new('cycleDeliveryId')->setSortable(true), 'cycleDeliveryId' => IntegerField::new('cycleDeliveryId')->setSortable(true),
'cycleId' => IntegerField::new('cycleId')->setSortable(true), 'cycleId' => IntegerField::new('cycleId')->setSortable(true),
'deliveryType' => Field::new('deliveryType')->setSortable(true)
'deliveryType' => ChoiceField::new('deliveryType')->setSortable(true)
->autocomplete()
->setSortable(true)
->setChoices(
$this->translatorAdmin->transChoices(
OrderShopSolver::getTypeDeliveryChoices(),
'OrderShop',
'deliveryType'
)
)
->setTemplatePath('@LcCaracole/admin/order/field/delivery_type.html.twig')
->setCustomOption('filter_fqcn', OrderShopOrderDeliveryTypeFilter::class), ->setCustomOption('filter_fqcn', OrderShopOrderDeliveryTypeFilter::class),
//->setTemplatePath('@LcShop/backend/default/field/options_translatable.html.twig'),
'reference' => TextField::new('reference')->setSortable(true), 'reference' => TextField::new('reference')->setSortable(true),
'complementaryOrderShops' => AssociationField::new('complementaryOrderShops') 'complementaryOrderShops' => AssociationField::new('complementaryOrderShops')
->setFormTypeOption('mapped', false) ->setFormTypeOption('mapped', false)

+ 66
- 36
Definition/Field/User/UserFieldDefinition.php View File

namespace Lc\CaracoleBundle\Definition\Field\User; namespace Lc\CaracoleBundle\Definition\Field\User;


use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField;
use Lc\CaracoleBundle\Context\MerchantContextTrait; use Lc\CaracoleBundle\Context\MerchantContextTrait;
use Lc\CaracoleBundle\Field\AssociationField; use Lc\CaracoleBundle\Field\AssociationField;
use Lc\CaracoleBundle\Repository\Newsletter\NewsletterStore; use Lc\CaracoleBundle\Repository\Newsletter\NewsletterStore;
protected GroupUserStore $groupUserStore; protected GroupUserStore $groupUserStore;
protected NewsletterStore $newsletterStore; protected NewsletterStore $newsletterStore;


public function __construct(TranslatorAdmin $translatorAdmin, RolesDefinition $rolesDefinition, GroupUserStore $groupUserStore, NewsletterStore $newsletterStore)
{
public function __construct(
TranslatorAdmin $translatorAdmin,
RolesDefinition $rolesDefinition,
GroupUserStore $groupUserStore,
NewsletterStore $newsletterStore
) {
parent::__construct($translatorAdmin, $rolesDefinition); parent::__construct($translatorAdmin, $rolesDefinition);


$this->groupUserStore = $groupUserStore; $this->groupUserStore = $groupUserStore;
$this->newsletterStore = $newsletterStore; $this->newsletterStore = $newsletterStore;
} }


public function configureIndex(): array
{
return [
'id',
'gender',
'lastname',
'firstname',
'email',
'groupUsers',
'birthdate',
'countOrder',
'totalSpent',
];
}

public function configureForm(): array public function configureForm(): array
{ {
return [ return [
'gender',
'lastname',
'firstname',
'email',
'phone',
'birthdate',
'groupUsers',
'isSaleAlwaysOpen',
'newsletters',
'ticketTypesNotification'
'gender',
'lastname',
'firstname',
'email',
'phone',
'birthdate',
'groupUsers',
'isSaleAlwaysOpen',
'newsletters',
'ticketTypesNotification',
]; ];
} }


$groupUsers = $this->groupUserStore->setMerchant($this->merchant)->getAll(); $groupUsers = $this->groupUserStore->setMerchant($this->merchant)->getAll();
$newsletters = $this->newsletterStore->getAll(); $newsletters = $this->newsletterStore->getAll();


return array_merge(parent::configureFields(),[
'isSaleAlwaysOpen' => BooleanField::new('isSaleAlwaysOpen'),
'newsletters' => AssociationField::new('newsletters')
->setFormTypeOption('choices', $newsletters)
->setFormTypeOption('choice_label', function ($choice) {
return $choice->getTitle(). '['.$choice->getSection()->getMerchant().']';
})
->setSortable(true),
'groupUsers' => AssociationField::new('groupUsers')
->setFormTypeOption('choices', $groupUsers)
->setFormTypeOption('choice_label', function ($choice) {
return $choice->getTitle(). '['.$choice->getMerchant().']';
})
->setSortable(true),
'ticketTypesNotification' => ChoiceField::new('ticketTypesNotification')
->setSortable(true)
->setFormTypeOption('expanded', false)
->setFormTypeOption('multiple', true)
->setChoices($this->translatorAdmin->transChoices(
TicketSolver::getTypeChoices(),
'Ticket',
'type'
)),

return array_merge(parent::configureFields(), [
'isSaleAlwaysOpen' => BooleanField::new('isSaleAlwaysOpen'),
'newsletters' => AssociationField::new('newsletters')
->setFormTypeOption('choices', $newsletters)
->setFormTypeOption('choice_label', function ($choice) {
return $choice->getTitle() . '[' . $choice->getSection()->getMerchant() . ']';
})
->setSortable(true),
'groupUsers' => AssociationField::new('groupUsers')
->setFormTypeOption('choices', $groupUsers)
->setTemplatePath('@LcSov/adminlte/crud/field/association_many.html.twig')
->setFormTypeOption('choice_label', function ($choice) {
return $choice->getTitle() . '[' . $choice->getMerchant() . ']';
})
->setSortable(true),
'ticketTypesNotification' => ChoiceField::new('ticketTypesNotification')
->setSortable(true)
->setFormTypeOption('expanded', false)
->setFormTypeOption('multiple', true)
->setChoices(
$this->translatorAdmin->transChoices(
TicketSolver::getTypeChoices(),
'Ticket',
'type'
)
),
'countOrder' => NumberField::new('countOrder')
->setFormTypeOption('mapped', false)
->setCustomOption('filter', false)
->setTemplatePath('@LcCaracole/admin/user/field/count_order.html.twig'),
'totalSpent' => NumberField::new('totalSpent')
->setFormTypeOption('mapped', false)
->setCustomOption('filter', false)
->setTemplatePath('@LcCaracole/admin/user/field/total_spent.html.twig'),
]); ]);
} }



+ 68
- 0
Field/Filter/Order/OrderShopDistributionFilter.php View File

<?php

namespace Lc\CaracoleBundle\Field\Filter\Order;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto;
use Lc\SovBundle\Field\Filter\AssociationFilter;
use Lc\SovBundle\Field\Filter\FilterTrait;
use Lc\SovBundle\Repository\RepositoryQueryInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;

/**
* @author La clic ! <contact@laclic.fr>
*/
class OrderShopDistributionFilter
{
use FilterTrait;

public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array())
{
$builder->add(
$this->getFieldPropertySnake($fieldDto->getProperty()),
TextType::class,
array(
'required' => false,
'attr' => array(
'class' => ' input-sm',
'form' => 'filters-form',
),
)
);
}

public function applyFilter(RepositoryQueryInterface $repositoryQuery, FieldDto $fieldDto, $filteredValue = null)
{
if ($filteredValue !== null) {
$cycleType = "week";
$year = date("Y");

$filteredValue = strtolower($filteredValue);

if (str_contains($filteredValue, 'j')) {
$cycleType = "day";
} elseif (str_contains($filteredValue, 'm')) {
$cycleType = "month";
}
//On enleve le premier Caractere
if (preg_match('#^[a-z]#', $filteredValue)) {
$filteredValue = substr($filteredValue, 1);
}
// On sépare le cycleNumber et Year
$cycleExplode = explode("a", $filteredValue);
$cycleNumber = $cycleExplode[0];
if (isset($cycleExplode[1])) {
$year = $cycleExplode[1];
if (strlen($year) == 2) {
$year = "20" . $year;
}
}

$repositoryQuery->filterByDistributionData($cycleType, $cycleNumber, $year);
}
}

}

+ 1
- 13
Field/Filter/Order/OrderShopOrderDeliveryTypeFilter.php View File

{ {
use FilterTrait; use FilterTrait;


protected $translatorAdmin;

public function __construct(TranslatorAdmin $translatorAdmin)
{
$this->translatorAdmin = $translatorAdmin;
}

public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array())
{ {
$builder->add( $builder->add(
ChoiceType::class, ChoiceType::class,
[ [
'placeholder' => '--', 'placeholder' => '--',
'choices' =>
$this->translatorAdmin->transChoices(
OrderDeliveryTypeSolver::getDeliveryTypeChoices(),
'OrderShop',
'deliveryType'
),
'choices' => $fieldDto->getCustomOption('choices'),
'required' => false, 'required' => false,
'attr' => array( 'attr' => array(
'class' => 'select2 input-sm', 'class' => 'select2 input-sm',

+ 12
- 0
Repository/Order/OrderShopRepositoryQuery.php View File

->setParameter('alias', $status); ->setParameter('alias', $status);
} }


public function filterByDistributionData(string $cycleType, int $cycleNumber, int $year){
$this->joinDistribution();

return $this
->andWhere('distribution.cycleType LIKE :cycleType')
->andWhere('distribution.cycleNumber LIKE :cycleNumber')
->andWhere('distribution.year LIKE :year')
->setParameter('cycleType', $cycleType)
->setParameter('cycleNumber', $cycleNumber)
->setParameter('year', $year);
}

public function filterByDistributions(array $distributions): self public function filterByDistributions(array $distributions): self
{ {
return $this return $this

+ 4
- 0
Resources/translations/admin.fr.yaml View File

editProductFamily: Éditer le produit editProductFamily: Éditer le produit
history: Historique history: Historique
credit: Voir l'historique de crédit credit: Voir l'historique de crédit
switchUser: Prendre la main


setting_definition: setting_definition:
merchant: merchant:
fields: fields:
isSaleAlwaysOpen: Vente toujours ouverte isSaleAlwaysOpen: Vente toujours ouverte
newsletters: Newsletter newsletters: Newsletter
countOrder: Commandes
totalSpent: Ventes
lastLogin: Dernière connexion
CreditHistory: CreditHistory:
label: Historique de compte prépayé label: Historique de compte prépayé
label_plurial: Historiques de compte prépayé label_plurial: Historiques de compte prépayé

+ 1
- 0
Resources/views/admin/order/field/delivery_type.html.twig View File

{{ field.value|sov_trans_admin_choice('deliveryType', 'OrderShop') }}

+ 11
- 0
Resources/views/admin/order/field/distribution.html.twig View File

{% set distrubution = field.value %}
{% set cycleType = distrubution.cycleType %}
{% if cycleType == "day" %}
{% set labelCycleType = "J" %}
{% elseif cycleType == "week" %}
{% set labelCycleType = "S" %}
{% elseif cycleType == "month" %}
{% set labelCycleType = "M" %}
{% endif %}

{{ labelCycleType ~ distrubution.cycleNumber }}A{{ distrubution.year|slice(2,2) }}

+ 12
- 0
Resources/views/admin/user/field/count_order.html.twig View File

{% set order_store = order_shop_container.store.setSection(section_current()).setMerchant(merchant_current()) %}
{% set totalOrder = order_store.countValidByUserAllMerchant(entity.instance) %}
{% if totalOrder > 0 %}
<span class="badge badge-success">
{{ totalOrder }} commandes
</span>
{% else %}
<span class="badge badge-secondary">
0 commandes
</span>
{% endif %}


+ 8
- 0
Resources/views/admin/user/field/total_spent.html.twig View File

{% set order_store = order_shop_container.store.setSection(section_current()).setMerchant(merchant_current()) %}
{% set totalSpent = order_store.getTotalSpentByUser(entity.instance) %}
{# {% set totalSpent = orderUtils.getTotalSpentByUser(entity.instance) %} #}
{% if totalSpent > 0 %}
<span class="badge badge-primary"> {{ totalSpent|format_price(false) }}</span>
{% else %}
<span class="badge badge-secondary"> {{ totalSpent|format_price(false) }}</span>
{% endif %}

+ 6
- 2
Solver/Config/UnitSolver.php View File

class UnitSolver class UnitSolver
{ {


public function getWeight(UnitInterface $unit, int $quantityProduct, int $quantity){
return ($quantityProduct / $unit->getCoefficient()) * $quantity;
public function getWeight(UnitInterface $unit, int $quantityProduct, ?int $quantity){
if($quantity) {
return ($quantityProduct / $unit->getCoefficient()) * $quantity;
}else{
$quantity = 0;
}
} }





+ 39
- 32
Solver/Order/OrderShopSolver.php View File



public function __construct( public function __construct(
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
ProductSolver $productSolver
)
{
ProductSolver $productSolver
) {
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
$this->productSolver = $productSolver; $this->productSolver = $productSolver;
} }


public function getTypeDeliveryChoices()
{
return [
OrderShopModel::DELIVERY_TYPE_HOME,
OrderShopModel::DELIVERY_TYPE_POINTSALE,
];
}

public function countQuantities(OrderShopInterface $orderShop): int public function countQuantities(OrderShopInterface $orderShop): int
{ {
return $this->countQuantitiesByOrderProducts($orderShop->getOrderProducts()); return $this->countQuantitiesByOrderProducts($orderShop->getOrderProducts());


// getOrderProductsByProductFamily // getOrderProductsByProductFamily
public function getOrderProductsByProductFamily( public function getOrderProductsByProductFamily(
OrderShopInterface $orderShop,
OrderShopInterface $orderShop,
ProductFamilyInterface $productFamily ProductFamilyInterface $productFamily
): array
{
): array {
$arrayOrderProducts = []; $arrayOrderProducts = [];


foreach ($orderShop->getOrderProducts() as $orderProduct) { foreach ($orderShop->getOrderProducts() as $orderProduct) {


public function getQuantityOrderByProduct( public function getQuantityOrderByProduct(
OrderShopInterface $orderShop, OrderShopInterface $orderShop,
ProductInterface $product,
$byWeight = false
): int
{
ProductInterface $product,
$byWeight = false
): int {
$quantity = 0; $quantity = 0;
$productFamily = $product->getProductFamily(); $productFamily = $product->getProductFamily();
$behaviorCountStock = $productFamily->getBehaviorCountStock(); $behaviorCountStock = $productFamily->getBehaviorCountStock();
|| (($behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY || $behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) || (($behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY || $behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE)
&& $orderProduct->getProduct()->getProductFamily()->getId() == $productFamily->getId())) { && $orderProduct->getProduct()->getProductFamily()->getId() == $productFamily->getId())) {
if ($byWeight) { if ($byWeight) {
$quantity += $orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct() / $this->productSolver->getUnitInherited($orderProduct->getProduct())->getCoefficient());
$quantity += $orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct(
) / $this->productSolver->getUnitInherited($orderProduct->getProduct())->getCoefficient());
} else { } else {
$quantity += $orderProduct->getQuantityOrder(); $quantity += $orderProduct->getQuantityOrder();
} }
// isProductAvailable // isProductAvailable
public function isProductAvailable( public function isProductAvailable(
ProductInterface $product, ProductInterface $product,
$quantityOrder = 0,
$checkCart = false,
$orderShop
)
{
if ($product->getStatus() != 1 || $product->getProductFamily()->getStatus() != 1 || !$this->productSolver->isProductSaleStatusOn($product)) {
$quantityOrder = 0,
$checkCart = false,
$orderShop
) {
if ($product->getStatus() != 1 || $product->getProductFamily()->getStatus(
) != 1 || !$this->productSolver->isProductSaleStatusOn($product)) {
return false; return false;
} }




public function mergeComplentaryOrderShops( public function mergeComplentaryOrderShops(
OrderShopInterface $orderShop, OrderShopInterface $orderShop,
bool $combineProducts = true
): OrderShopInterface
{
bool $combineProducts = true
): OrderShopInterface {
$this->entityManager->refresh($orderShop); $this->entityManager->refresh($orderShop);


if ($this->getValidComplementaryOrderShops($orderShop)) { if ($this->getValidComplementaryOrderShops($orderShop)) {
foreach ($complementaryOrderShop->getOrderProducts() as $orderProductAdd) { foreach ($complementaryOrderShop->getOrderProducts() as $orderProductAdd) {
$updated = false; $updated = false;
foreach ($orderShop->getOrderProducts() as $orderProduct) { foreach ($orderShop->getOrderProducts() as $orderProduct) {
if ($combineProducts && $orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId()
if ($combineProducts && $orderProduct->getProduct()->getId() == $orderProductAdd->getProduct(
)->getId()
&& (string)$orderProduct->getPrice() == (string)$orderProductAdd->getPrice() && (string)$orderProduct->getPrice() == (string)$orderProductAdd->getPrice()
) { ) {
$orderProduct->setUpdatedOnMergeComplementaryOrderShop(true); $orderProduct->setUpdatedOnMergeComplementaryOrderShop(true);
} }


public function isReductionCreditAddedToOrder( public function isReductionCreditAddedToOrder(
OrderShopInterface $orderShop,
OrderShopInterface $orderShop,
ReductionCreditInterface $reductionCredit ReductionCreditInterface $reductionCredit
)
{
) {
foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) { foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
if ($orderReductionCredit->getReductionCredit() == $reductionCredit) { if ($orderReductionCredit->getReductionCredit() == $reductionCredit) {
return true; return true;




public function hasOrderProductAlreadyInCart( public function hasOrderProductAlreadyInCart(
OrderShopInterface $orderShop,
OrderShopInterface $orderShop,
OrderProductInterface $orderProductTest OrderProductInterface $orderProductTest
): ?OrderProductInterface
{
): ?OrderProductInterface {
foreach ($orderShop->getOrderProducts() as $orderProduct) { foreach ($orderShop->getOrderProducts() as $orderProduct) {
if ($orderProduct->getProduct() == $orderProductTest->getProduct()) { if ($orderProduct->getProduct() == $orderProductTest->getProduct()) {
return $orderProduct; return $orderProduct;
$byWeight = true; $byWeight = true;
} }


return max($this->productSolver->getAvailableQuantityInherited($product) - $this->getQuantityOrderByProduct(
$orderShop,
$product,
$byWeight
), 0);
return max(
$this->productSolver->getAvailableQuantityInherited($product) - $this->getQuantityOrderByProduct(
$orderShop,
$product,
$byWeight
),
0
);
} }


public function hasMakeAChoiceAboutComplementaryOrder(OrderShop $orderShop): bool public function hasMakeAChoiceAboutComplementaryOrder(OrderShop $orderShop): bool

Loading…
Cancel
Save