@@ -2,6 +2,7 @@ | |||
namespace Lc\CaracoleBundle\Definition\Field\Order; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\Field; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField; | |||
@@ -12,6 +13,7 @@ use Lc\CaracoleBundle\Context\MerchantContextTrait; | |||
use Lc\CaracoleBundle\Definition\Field\AbstractFieldDefinition; | |||
use Lc\CaracoleBundle\Field\AssociationField; | |||
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\OrderShopOrderPaymentFilter; | |||
use Lc\CaracoleBundle\Field\Filter\Order\OrderShopOrderStatusFilter; | |||
@@ -19,6 +21,7 @@ use Lc\CaracoleBundle\Field\Filter\Order\OrderShopUserEmailFilter; | |||
use Lc\CaracoleBundle\Field\Filter\Order\OrderShopUserFirstnameFilter; | |||
use Lc\CaracoleBundle\Field\Filter\Order\OrderShopUserLastnameFilter; | |||
use Lc\CaracoleBundle\Repository\Section\SectionStore; | |||
use Lc\CaracoleBundle\Solver\Order\OrderShopSolver; | |||
use Lc\SovBundle\Translation\TranslatorAdmin; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
@@ -67,13 +70,24 @@ class OrderShopFieldDefinition extends AbstractFieldDefinition | |||
'orderShopCreatedAt' => DateTimeField::new('orderShopCreatedAt')->setSortable(true), | |||
'distribution' => AssociationField::new('distribution') | |||
->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), | |||
'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), | |||
//->setTemplatePath('@LcShop/backend/default/field/options_translatable.html.twig'), | |||
'reference' => TextField::new('reference')->setSortable(true), | |||
'complementaryOrderShops' => AssociationField::new('complementaryOrderShops') | |||
->setFormTypeOption('mapped', false) |
@@ -3,6 +3,7 @@ | |||
namespace Lc\CaracoleBundle\Definition\Field\User; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField; | |||
use Lc\CaracoleBundle\Context\MerchantContextTrait; | |||
use Lc\CaracoleBundle\Field\AssociationField; | |||
use Lc\CaracoleBundle\Repository\Newsletter\NewsletterStore; | |||
@@ -22,27 +23,46 @@ class UserFieldDefinition extends SovUserFieldDefinition | |||
protected GroupUserStore $groupUserStore; | |||
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); | |||
$this->groupUserStore = $groupUserStore; | |||
$this->newsletterStore = $newsletterStore; | |||
} | |||
public function configureIndex(): array | |||
{ | |||
return [ | |||
'id', | |||
'gender', | |||
'lastname', | |||
'firstname', | |||
'email', | |||
'groupUsers', | |||
'birthdate', | |||
'countOrder', | |||
'totalSpent', | |||
]; | |||
} | |||
public function configureForm(): array | |||
{ | |||
return [ | |||
'gender', | |||
'lastname', | |||
'firstname', | |||
'email', | |||
'phone', | |||
'birthdate', | |||
'groupUsers', | |||
'isSaleAlwaysOpen', | |||
'newsletters', | |||
'ticketTypesNotification' | |||
'gender', | |||
'lastname', | |||
'firstname', | |||
'email', | |||
'phone', | |||
'birthdate', | |||
'groupUsers', | |||
'isSaleAlwaysOpen', | |||
'newsletters', | |||
'ticketTypesNotification', | |||
]; | |||
} | |||
@@ -51,30 +71,40 @@ class UserFieldDefinition extends SovUserFieldDefinition | |||
$groupUsers = $this->groupUserStore->setMerchant($this->merchant)->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'), | |||
]); | |||
} | |||
@@ -0,0 +1,68 @@ | |||
<?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); | |||
} | |||
} | |||
} |
@@ -19,13 +19,6 @@ class OrderShopOrderDeliveryTypeFilter | |||
{ | |||
use FilterTrait; | |||
protected $translatorAdmin; | |||
public function __construct(TranslatorAdmin $translatorAdmin) | |||
{ | |||
$this->translatorAdmin = $translatorAdmin; | |||
} | |||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||
{ | |||
$builder->add( | |||
@@ -33,12 +26,7 @@ class OrderShopOrderDeliveryTypeFilter | |||
ChoiceType::class, | |||
[ | |||
'placeholder' => '--', | |||
'choices' => | |||
$this->translatorAdmin->transChoices( | |||
OrderDeliveryTypeSolver::getDeliveryTypeChoices(), | |||
'OrderShop', | |||
'deliveryType' | |||
), | |||
'choices' => $fieldDto->getCustomOption('choices'), | |||
'required' => false, | |||
'attr' => array( | |||
'class' => 'select2 input-sm', |
@@ -140,6 +140,18 @@ class OrderShopRepositoryQuery extends AbstractRepositoryQuery | |||
->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 | |||
{ | |||
return $this |
@@ -28,6 +28,7 @@ action: | |||
editProductFamily: Éditer le produit | |||
history: Historique | |||
credit: Voir l'historique de crédit | |||
switchUser: Prendre la main | |||
setting_definition: | |||
merchant: | |||
@@ -127,6 +128,9 @@ entity: | |||
fields: | |||
isSaleAlwaysOpen: Vente toujours ouverte | |||
newsletters: Newsletter | |||
countOrder: Commandes | |||
totalSpent: Ventes | |||
lastLogin: Dernière connexion | |||
CreditHistory: | |||
label: Historique de compte prépayé | |||
label_plurial: Historiques de compte prépayé |
@@ -0,0 +1 @@ | |||
{{ field.value|sov_trans_admin_choice('deliveryType', 'OrderShop') }} |
@@ -0,0 +1,11 @@ | |||
{% 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) }} |
@@ -0,0 +1,12 @@ | |||
{% 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 %} | |||
@@ -0,0 +1,8 @@ | |||
{% 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 %} |
@@ -9,8 +9,12 @@ use Lc\CaracoleBundle\Model\Config\UnitInterface; | |||
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; | |||
} | |||
} | |||
@@ -27,13 +27,20 @@ class OrderShopSolver | |||
public function __construct( | |||
EntityManagerInterface $entityManager, | |||
ProductSolver $productSolver | |||
) | |||
{ | |||
ProductSolver $productSolver | |||
) { | |||
$this->entityManager = $entityManager; | |||
$this->productSolver = $productSolver; | |||
} | |||
public function getTypeDeliveryChoices() | |||
{ | |||
return [ | |||
OrderShopModel::DELIVERY_TYPE_HOME, | |||
OrderShopModel::DELIVERY_TYPE_POINTSALE, | |||
]; | |||
} | |||
public function countQuantities(OrderShopInterface $orderShop): int | |||
{ | |||
return $this->countQuantitiesByOrderProducts($orderShop->getOrderProducts()); | |||
@@ -69,10 +76,9 @@ class OrderShopSolver | |||
// getOrderProductsByProductFamily | |||
public function getOrderProductsByProductFamily( | |||
OrderShopInterface $orderShop, | |||
OrderShopInterface $orderShop, | |||
ProductFamilyInterface $productFamily | |||
): array | |||
{ | |||
): array { | |||
$arrayOrderProducts = []; | |||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||
@@ -86,10 +92,9 @@ class OrderShopSolver | |||
public function getQuantityOrderByProduct( | |||
OrderShopInterface $orderShop, | |||
ProductInterface $product, | |||
$byWeight = false | |||
): int | |||
{ | |||
ProductInterface $product, | |||
$byWeight = false | |||
): int { | |||
$quantity = 0; | |||
$productFamily = $product->getProductFamily(); | |||
$behaviorCountStock = $productFamily->getBehaviorCountStock(); | |||
@@ -99,7 +104,8 @@ class OrderShopSolver | |||
|| (($behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY || $behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) | |||
&& $orderProduct->getProduct()->getProductFamily()->getId() == $productFamily->getId())) { | |||
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 { | |||
$quantity += $orderProduct->getQuantityOrder(); | |||
} | |||
@@ -112,12 +118,12 @@ class OrderShopSolver | |||
// isProductAvailable | |||
public function isProductAvailable( | |||
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; | |||
} | |||
@@ -254,9 +260,8 @@ class OrderShopSolver | |||
public function mergeComplentaryOrderShops( | |||
OrderShopInterface $orderShop, | |||
bool $combineProducts = true | |||
): OrderShopInterface | |||
{ | |||
bool $combineProducts = true | |||
): OrderShopInterface { | |||
$this->entityManager->refresh($orderShop); | |||
if ($this->getValidComplementaryOrderShops($orderShop)) { | |||
@@ -264,7 +269,8 @@ class OrderShopSolver | |||
foreach ($complementaryOrderShop->getOrderProducts() as $orderProductAdd) { | |||
$updated = false; | |||
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() | |||
) { | |||
$orderProduct->setUpdatedOnMergeComplementaryOrderShop(true); | |||
@@ -289,10 +295,9 @@ class OrderShopSolver | |||
} | |||
public function isReductionCreditAddedToOrder( | |||
OrderShopInterface $orderShop, | |||
OrderShopInterface $orderShop, | |||
ReductionCreditInterface $reductionCredit | |||
) | |||
{ | |||
) { | |||
foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) { | |||
if ($orderReductionCredit->getReductionCredit() == $reductionCredit) { | |||
return true; | |||
@@ -304,10 +309,9 @@ class OrderShopSolver | |||
public function hasOrderProductAlreadyInCart( | |||
OrderShopInterface $orderShop, | |||
OrderShopInterface $orderShop, | |||
OrderProductInterface $orderProductTest | |||
): ?OrderProductInterface | |||
{ | |||
): ?OrderProductInterface { | |||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||
if ($orderProduct->getProduct() == $orderProductTest->getProduct()) { | |||
return $orderProduct; | |||
@@ -351,11 +355,14 @@ class OrderShopSolver | |||
$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 |