@@ -0,0 +1,8 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Context ; | |||
interface DocumentUtilsInterface | |||
{ | |||
} |
@@ -8,7 +8,7 @@ use Symfony\Component\HttpFoundation\Request; | |||
use Symfony\Component\HttpFoundation\JsonResponse; | |||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | |||
class CitiesController extends AbstractController | |||
class AddressApiController extends AbstractController | |||
{ | |||
protected $utils ; | |||
@@ -17,7 +17,7 @@ class CitiesController extends AbstractController | |||
$this->utils = $utils ; | |||
} | |||
public function index(Request $request) : JsonResponse | |||
public function cities(Request $request) : JsonResponse | |||
{ | |||
$term = $request->get('term') ; | |||
$context = $request->get('context') ; | |||
@@ -58,5 +58,31 @@ class CitiesController extends AbstractController | |||
return new JsonResponse($return) ; | |||
} | |||
public function addresses(Request $request) : JsonResponse | |||
{ | |||
$return = [] ; | |||
$address = $request->get('address') ; | |||
$context = $request->get('context') ; | |||
$results = $this->utils->callAddressApi($address) ; | |||
foreach($results as $result) { | |||
if($result->getStreetNumber() && strlen($result->getStreetNumber()) > 0) { | |||
$streetNameNumber = $result->getStreetNumber().' '.$result->getStreetName() ; | |||
$return[] = [ | |||
'label' => $streetNameNumber, | |||
'value' => $streetNameNumber, | |||
'latitude' => $result->getCoordinates()->getLatitude(), | |||
'longitude' => $result->getCoordinates()->getLongitude() | |||
] ; | |||
} | |||
} | |||
if($context == 'frontend') { | |||
$return = [ | |||
'items' => $return | |||
] ; | |||
} | |||
return new JsonResponse($return) ; | |||
} | |||
} |
@@ -43,6 +43,7 @@ class AdminController extends EasyAdminController | |||
protected $orderUtils; | |||
protected $mailUtils ; | |||
protected $translator; | |||
protected $utilsProcess; | |||
protected $filtersForm = null; | |||
public function __construct(Security $security, UserManagerInterface $userManager, EntityManagerInterface $em, | |||
@@ -56,13 +57,12 @@ class AdminController extends EasyAdminController | |||
$this->merchantUtils = $utilsManager->getMerchantUtils(); | |||
$this->orderUtils = $utilsManager->getOrderUtils();; | |||
$this->mailUtils = $utilsManager->getMailUtils() ; | |||
$this->utilsProcess = $utilsManager->getUtilsProcess() ; | |||
$this->translator = $translator; | |||
} | |||
public function createCustomForm($class, $action, $parameters, $data = true) | |||
public function createCustomForm($class, $action, $parameters, $data = true, $options = array()) | |||
{ | |||
$options = array(); | |||
if ($data) $options['data'] = $parameters['entity']; | |||
$options['action'] = $this->generateUrl('easyadmin', array( | |||
'action' => $action, | |||
@@ -598,14 +598,7 @@ class AdminController extends EasyAdminController | |||
$entity= $this->em->getRepository($easyadmin['entity']['class'])->find($id); | |||
$newEntity = clone $entity ; | |||
if($newEntity instanceof ImageInterface){ | |||
$newEntity->setImage(null); | |||
} | |||
$this->em->persist($newEntity) ; | |||
$this->em->flush() ; | |||
$newEntity = $this->utilsProcess->duplicateEntity($entity); | |||
return $this->redirectToRoute('easyadmin', ['entity' => $easyadmin['entity']['name'], 'action' => 'edit', 'id' =>$newEntity->getId(), 'referer' =>$refererUrl ]) ; | |||
} | |||
@@ -622,25 +615,26 @@ class AdminController extends EasyAdminController | |||
$entity= $this->em->getRepository($easyadmin['entity']['class'])->find($id); | |||
$hub= $this->em->getRepository(MerchantInterface::class)->findOneByDevAlias($hubAlias); | |||
$newEntity = clone $entity ; | |||
$newEntity = $this->utilsProcess->duplicateEntityToOtherHub($entity,$hub); | |||
if($newEntity instanceof ImageInterface){ | |||
$newEntity->setImage(null); | |||
} | |||
$user->setMerchant($hub); | |||
$this->em->persist($user); | |||
$this->em->flush(); | |||
$redirectUrl = $this->generateUrl('easyadmin', ['entity' => $easyadmin['entity']['name'], 'action' => 'edit', 'id' =>$newEntity->getId(), 'referer' =>$refererUrl ]).'&hubredirection=true'; | |||
if ($hub) { | |||
$newEntity->setMerchant($hub); | |||
$user->setMerchant($hub); | |||
$this->em->persist($user); | |||
} | |||
$this->em->persist($newEntity) ; | |||
$this->em->flush() ; | |||
return $this->redirectToOtherHub($hub, $redirectUrl) ; | |||
} | |||
$redirectUrl = $hub->getMerchantConfig('url').substr($this->generateUrl('easyadmin', ['entity' => $easyadmin['entity']['name'], 'action' => 'edit', 'id' =>$newEntity->getId(), 'referer' =>$refererUrl ]),1).'&hubredirection=true'; | |||
public function redirectToOtherHub($hub, $url){ | |||
if(strpos($_SERVER['HTTP_HOST'], 'localhost')!==false){ | |||
return $this->redirect($url); | |||
}else{ | |||
return $this->redirect($hub->getMerchantConfig('url').substr($url,1)); | |||
} | |||
return $this->redirect($redirectUrl) ; | |||
} | |||
} | |||
@@ -10,6 +10,8 @@ use Lc\ShopBundle\Context\OrderUtilsInterface; | |||
use Lc\ShopBundle\Services\Utils; | |||
use Lc\ShopBundle\Services\UtilsManager; | |||
use Mailjet\MailjetSwiftMailer\SwiftMailer\MailjetTransport; | |||
use Symfony\Component\HttpFoundation\BinaryFileResponse; | |||
use Symfony\Component\HttpFoundation\StreamedResponse; | |||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |||
use Symfony\Component\Security\Core\Security; | |||
use Symfony\Contracts\Translation\TranslatorInterface; | |||
@@ -36,7 +38,9 @@ class DocumentController extends AdminController | |||
} | |||
if($document && $orderShop) { | |||
$this->orderUtils->generateDocumentInvoiceOrderShop($orderShop, 'download') ; | |||
return new StreamedResponse(function () use ($orderShop) { | |||
$this->orderUtils->generateDocumentInvoiceOrderShop($orderShop, 'download') ; | |||
}); | |||
} | |||
else { | |||
throw new NotFoundHttpException('Document introuvable') ; |
@@ -100,7 +100,7 @@ class MerchantController extends AdminController | |||
$em->persist($user); | |||
$em->flush(); | |||
return $this->redirect($merchant->getMerchantConfig('url').'admin/dashboard?hubredirection=true') ; | |||
return $this->redirectToOtherHub($merchant, '/admin/dashboard?hubredirection=true') ; | |||
} | |||
} | |||
@@ -418,7 +418,7 @@ class OrderController extends AdminController | |||
], | |||
]); | |||
$this->utils->addFlash('success', 'success.order.removeReductionCredit'); | |||
$this->utils->addFlash('success', 'success.order.sendPaymentLink'); | |||
} else { | |||
$this->utils->addFlash('error', $formOrderSendPaymentLink->getErrors()); | |||
} |
@@ -10,6 +10,7 @@ use Lc\ShopBundle\Context\ImageInterface; | |||
use Lc\ShopBundle\Context\OrderShopInterface; | |||
use Lc\ShopBundle\Context\ProductCategoryInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyInterface; | |||
use Lc\ShopBundle\Context\ProductInterface; | |||
use Lc\ShopBundle\Context\ReductionCatalogInterface; | |||
use Lc\ShopBundle\Context\TaxRateInterface; | |||
use Lc\ShopBundle\Form\Backend\Common\AbstractEditPositionType; | |||
@@ -34,6 +35,7 @@ class ProductFamilyController extends AdminController | |||
private $choicesTaxRateParam; | |||
private $choicesSupplierTaxRateParam; | |||
private $parameterBag ; | |||
private $productFamilyUtils ; | |||
public function __construct(Security $security, UserManagerInterface $userManager, EntityManagerInterface $em, | |||
MailjetTransport $mailjetTransport, UtilsManager $utilsManager, TranslatorInterface $translator, | |||
@@ -41,6 +43,7 @@ class ProductFamilyController extends AdminController | |||
{ | |||
parent::__construct($security, $userManager, $em, $mailjetTransport, $utilsManager, $translator); | |||
$this->parameterBag = $parameterBag ; | |||
$this->productFamilyUtils = $utilsManager->getProductFamilyUtils() ; | |||
} | |||
public function createEntityFormBuilder($entity, $view, $override = true) | |||
@@ -188,10 +191,7 @@ class ProductFamilyController extends AdminController | |||
public function updateProductFamilyEntity($entity, $editForm = false) | |||
{ | |||
if ($editForm) { | |||
$this->processReductionCatalog($entity, $editForm); | |||
$this->processCategories($entity); | |||
$this->processProducts($entity); | |||
$this->processPrice($entity); | |||
$entity = $this->productFamilyUtils->processBeforePersistProductFamily($entity, $editForm); | |||
} | |||
parent::updateEntity($entity); | |||
@@ -201,85 +201,12 @@ class ProductFamilyController extends AdminController | |||
public function persistProductFamilyEntity($entity, $newForm) | |||
{ | |||
$this->processReductionCatalog($entity, $newForm); | |||
$this->processCategories($entity); | |||
$this->processProducts($entity); | |||
$this->processPrice($entity); | |||
$entity = $this->productFamilyUtils->processBeforePersistProductFamily($entity, $newForm); | |||
$this->em->persist($entity); | |||
$this->em->flush(); | |||
} | |||
protected function processReductionCatalog($entity, $editForm) | |||
{ | |||
$reductionCatalog = $editForm->get('reductionCatalog')->getData(); | |||
if ($reductionCatalog instanceof ReductionCatalogInterface) { | |||
if ($reductionCatalog->getValue() && $reductionCatalog->getBehaviorTaxRate() && $reductionCatalog->getUnit()) { | |||
$reductionCatalog->setMerchant($entity->getMerchant()); | |||
$reductionCatalog->setStatus($editForm->get('activeReductionCatalog')->getData()); | |||
$reductionCatalog->setProductFamily($entity); | |||
$this->em->persist($reductionCatalog); | |||
} | |||
} | |||
} | |||
protected function processPrice($entity) | |||
{ | |||
if ($entity->getBehaviorPrice() == 'by-piece') { | |||
$entity->setPriceByRefUnit(null); | |||
$entity->setBuyingPriceByRefUnit(null); | |||
} else if ($entity->getBehaviorPrice() == 'by-reference-unit') { | |||
$entity->setPrice(null); | |||
$entity->setBuyingPrice(null); | |||
} | |||
} | |||
protected function processProducts($entity, $clone = false) | |||
{ | |||
//si il existe un et un seul produit pour ce product family n'ajoute rien supprime rien | |||
if (count($entity->getProducts()) == 0) { | |||
$product = new Product(); | |||
$product->setProductFamily($entity); | |||
$this->em->persist($product); | |||
$entity->addProduct($product); | |||
} else { | |||
foreach ($entity->getProducts() as $i => $product) { | |||
if ($clone) { | |||
$newProduct = clone $product; | |||
$newProduct->setProductFamily($entity); | |||
$this->em->persist($newProduct); | |||
$entity->addProduct($newProduct); | |||
} else { | |||
$product->setProductFamily($entity); | |||
$this->em->persist($product); | |||
$entity->addProduct($product); | |||
} | |||
} | |||
} | |||
} | |||
protected function processCategories(ProductFamilyInterface $entity) | |||
{ | |||
$productCategoryRepository = $this->getDoctrine()->getRepository(ProductCategoryInterface::class); | |||
$productCategories = $entity->getProductCategories(); | |||
$entity->initProductCategories(); | |||
foreach ($productCategories as $key => $bool) { | |||
if (is_bool($bool) && $bool) { | |||
if (strpos($key, 'category_children_') !== false) { | |||
$idCategory = (int)str_replace('category_children_', '', $key); | |||
} else { | |||
$idCategory = (int)str_replace('category_', '', $key); | |||
} | |||
$category = $productCategoryRepository->find($idCategory); | |||
$entity->addProductCategory($category); | |||
} | |||
} | |||
} | |||
protected function editAction() | |||
{ | |||
@@ -310,11 +237,16 @@ class ProductFamilyController extends AdminController | |||
$deleteForm = $this->createDeleteForm($this->entity['name'], $id); | |||
$sortableProductsField = array(); | |||
foreach ($editForm->get('products')->getData() as $k => $product) { | |||
$sortableProductsField[$product->getPosition()] = $k; | |||
if($product->getOriginProduct() == false) { | |||
$sortableProductsField[$product->getPosition()] = $k; | |||
}else{ | |||
$sortableProductsField[-1] = $k; | |||
} | |||
} | |||
} | |||
ksort($sortableProductsField); | |||
$editForm->handleRequest($this->request); | |||
@@ -405,40 +337,12 @@ class ProductFamilyController extends AdminController | |||
'entity' => $entity, | |||
'categories' => $categories, | |||
'sortableProductsField' => array(), | |||
'totalProductOrdered' => array() | |||
'totalProductOrdered' => array('total'=>0) | |||
]; | |||
return $this->executeDynamicMethod('render<EntityName>Template', ['new', $this->entity['templates']['new'], $parameters]); | |||
} | |||
public function duplicateAction() | |||
{ | |||
$id = $this->request->query->get('id'); | |||
$refererUrl = $this->request->query->get('referer', ''); | |||
$easyadmin = $this->request->attributes->get('easyadmin'); | |||
$entity = $this->em->getRepository($easyadmin['entity']['class'])->find($id); | |||
$newProductFamily = clone $entity; | |||
if ($easyadmin['entity']['name'] == "ProductFamily") { | |||
$this->processProducts($newProductFamily, true); | |||
} | |||
if($newProductFamily instanceof ImageInterface) { | |||
$basePath = $this->parameterBag->get('kernel.project_dir').'/public/uploads/images/' ; | |||
$imageProductFamily = 'produits/'.md5(time()).'.jpg' ; | |||
copy($basePath.$entity->getImage(), $basePath.$imageProductFamily) ; | |||
$newProductFamily->setImage($imageProductFamily); | |||
} | |||
$this->em->persist($newProductFamily); | |||
$this->em->flush(); | |||
return $this->redirectToRoute('easyadmin', ['entity' => $easyadmin['entity']['name'], 'action' => 'edit', 'id' => $newProductFamily->getId(), 'referer' => $refererUrl]); | |||
} | |||
//hack utilisé pour filter sur les catégories lors du tri des produits par sous cat | |||
//A améliorer à l'occas |
@@ -57,6 +57,7 @@ class EditEventSubscriber implements EventSubscriberInterface | |||
public function updateCommonProperty(GenericEvent $event) | |||
{ | |||
/* $this->setUpdated($entity); | |||
$this->setAddressCreatedBy($entity) ;*/ | |||
} |
@@ -48,9 +48,9 @@ class AddressType extends AbstractType | |||
]) | |||
->add('lastname', TextType::class, ['required' => false]) | |||
->add('firstname', TextType::class, ['required' => false]) | |||
->add('address', TextareaType::class) | |||
->add('zip', TextType::class) | |||
->add('city', TextType::class) | |||
->add('address', TextType::class) | |||
->add('phone', CollectionType::class, [ | |||
'allow_add'=>true, | |||
'allow_delete'=>true, |
@@ -29,6 +29,7 @@ class ProductType extends AbstractType | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
{ | |||
//dump($builder); | |||
$builder->add('title', TextType::class, array( | |||
"required" => false |
@@ -0,0 +1,54 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Form\Backend\User; | |||
use App\Entity\Supplier; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Doctrine\ORM\EntityRepository; | |||
use Lc\ShopBundle\Model\Ticket; | |||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||
use Symfony\Component\Form\AbstractType; | |||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; | |||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
use Symfony\Component\Form\FormEvent; | |||
use Symfony\Component\Form\FormEvents; | |||
use Symfony\Component\OptionsResolver\OptionsResolver; | |||
class TicketTypesNotificationType extends AbstractType | |||
{ | |||
protected $em; | |||
public function __construct(EntityManagerInterface $entityManager) | |||
{ | |||
$this->em = $entityManager; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
{ | |||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { | |||
$builder = $event->getForm()->getParent(); | |||
$builder->add('ticketTypesNotification', ChoiceType::class, [ | |||
'choices'=> array( | |||
'field.Ticket.typeOptions.'.Ticket::TYPE_GENERAL_QUESTION => Ticket::TYPE_GENERAL_QUESTION, | |||
'field.Ticket.typeOptions.'.Ticket::TYPE_PRODUCT_ERROR=> Ticket::TYPE_PRODUCT_ERROR , | |||
'field.Ticket.typeOptions.'.Ticket::TYPE_PRODUCT_UNAVAILABLE => Ticket::TYPE_PRODUCT_UNAVAILABLE, | |||
'field.Ticket.typeOptions.'.Ticket::TYPE_TECHNICAL_PROBLEM => Ticket::TYPE_TECHNICAL_PROBLEM | |||
), | |||
'required' => false, | |||
'expanded' => false, | |||
'multiple' => true, | |||
'translation_domain'=>'lcshop', | |||
]); | |||
}); | |||
} | |||
public function configureOptions(OptionsResolver $resolver) | |||
{ | |||
$resolver->setDefaults([ | |||
// 'translation_domain' => 'lcshop', | |||
]); | |||
} | |||
} |
@@ -38,7 +38,6 @@ abstract class AbstractEntity | |||
*/ | |||
protected $updatedBy; | |||
public function getCreatedAt(): ?\DateTimeInterface | |||
{ | |||
return $this->createdAt; |
@@ -73,9 +73,11 @@ abstract class Document extends AbstractDocumentEntity implements FilterMerchant | |||
/** | |||
* @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\OrderShopInterface", mappedBy="documents") | |||
* @ORM\JoinColumn(nullable=true) | |||
*/ | |||
protected $orderShops; | |||
/** | |||
* @ORM\OneToOne(targetEntity="Lc\ShopBundle\Context\OrderRefundInterface", mappedBy="document", cascade={"persist", "remove"}) | |||
*/ |
@@ -47,6 +47,10 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod | |||
*/ | |||
protected $title; | |||
/** | |||
* @ORM\Column(type="boolean", nullable=true) | |||
*/ | |||
protected $originProduct; | |||
public function __construct() | |||
{ | |||
@@ -56,13 +60,13 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod | |||
public function __toString() | |||
{ | |||
$title = $this->getProductFamily()->getTitle() ; | |||
$title = $this->getProductFamily()->getTitle(); | |||
if($this->getTitle() && strlen($this->getTitle())) { | |||
$title .= ' - '. $this->getTitle() ; | |||
if ($this->getTitle() && strlen($this->getTitle())) { | |||
$title .= ' - ' . $this->getTitle(); | |||
} | |||
return $title ; | |||
return $title; | |||
} | |||
public function getBuyingPriceInherited() | |||
@@ -133,8 +137,7 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod | |||
{ | |||
if ($this->getQuantity()) { | |||
return $this->getQuantity(); | |||
} | |||
else { | |||
} else { | |||
return $this->getProductFamily()->getQuantity(); | |||
} | |||
} | |||
@@ -199,4 +202,16 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod | |||
return $this; | |||
} | |||
public function getOriginProduct(): ?bool | |||
{ | |||
return $this->originProduct; | |||
} | |||
public function setOriginProduct(?bool $originProduct): self | |||
{ | |||
$this->originProduct = $originProduct; | |||
return $this; | |||
} | |||
} |
@@ -243,7 +243,7 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
case self::BEHAVIOR_COUNT_STOCK_BY_PRODUCT : | |||
foreach($this->getProducts() as $product) { | |||
foreach($this->getProductsOnline() as $product) { | |||
$availableQuantity += $product->getAvailableQuantityInherited() ; | |||
} | |||
break ; | |||
@@ -327,7 +327,7 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
$productsOnlineArray = new ArrayCollection() ; | |||
foreach($products as $product) { | |||
if($product->getStatus() == 1) { | |||
if($product->getStatus() == 1 && $product->getOriginProduct() !=true) { | |||
$productsOnlineArray[] = $product ; | |||
} | |||
} | |||
@@ -753,7 +753,7 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
{ | |||
if ($this->getActiveProducts()) { | |||
$arrayCountProducts = []; | |||
$products = $this->getProducts(); | |||
$products = $this->getProductsOnline(); | |||
foreach ($products as $product) { | |||
$titleProduct = $product->getTitleInherited(); | |||
@@ -777,7 +777,7 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
public function getProductsGroupByTitle() | |||
{ | |||
$arrayProductsGroupByTitle = []; | |||
$products = $this->getProducts(); | |||
$products = $this->getProductsOnline(); | |||
foreach ($products as $product) { | |||
if($product->getStatus() == 1) { | |||
@@ -791,4 +791,36 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $arrayProductsGroupByTitle; | |||
} | |||
public function getOriginProduct() | |||
{ | |||
$products = $this->getProducts() ; | |||
foreach($products as $product) { | |||
if($product->getOriginProduct()) { | |||
return $product ; | |||
} | |||
} | |||
} | |||
public function getOriginProductOnline() | |||
{ | |||
$originProduct = $this->getOriginProduct() ; | |||
if($originProduct->getStatus()==1){ | |||
return $originProduct; | |||
}else{ | |||
return false; | |||
} | |||
} | |||
public function hasOneProductOnline() | |||
{ | |||
if( ($this->getActiveProducts() && count($this->getProductsOnline()) > 0) | |||
|| (!$this->getActiveProducts() && $this->getOriginProduct())){ | |||
return true ; | |||
} | |||
return false ; | |||
} | |||
} |
@@ -17,7 +17,7 @@ trait SluggableTrait | |||
return $this->slug; | |||
} | |||
public function setSlug(string $slug): self | |||
public function setSlug(?string $slug): self | |||
{ | |||
$this->slug = $slug; | |||
@@ -102,6 +102,13 @@ abstract class User extends UserModelFOS | |||
*/ | |||
protected $updatedAt; | |||
/** | |||
* @ORM\Column(type="array", nullable=true) | |||
*/ | |||
protected $ticketTypesNotification = []; | |||
public function __construct() | |||
{ | |||
parent::__construct(); | |||
@@ -433,4 +440,17 @@ abstract class User extends UserModelFOS | |||
return $this; | |||
} | |||
public function getTicketTypesNotification(): ?array | |||
{ | |||
return $this->ticketTypesNotification; | |||
} | |||
public function setTicketTypesNotification(?array $ticketTypesNotification): self | |||
{ | |||
$this->ticketTypesNotification = $ticketTypesNotification; | |||
return $this; | |||
} | |||
} |
@@ -99,4 +99,17 @@ class BaseRepository extends EntityRepository implements ServiceEntityRepository | |||
return parent::findOneBy($criteria, $orderBy); | |||
} | |||
public function findSimilarSlug($merchant){ | |||
$qb = $this->createQueryBuilder('entity') | |||
->select('entity.id, COUNT(entity.slug) as niche') | |||
->andWhere('entity.status>=0') | |||
->andWhere('entity.merchant= :merchant') | |||
->setParameter('merchant', $merchant) | |||
->groupBy('entity.slug') | |||
->having('COUNT(entity.slug) >1'); | |||
return $qb->getQuery()->getResult(); | |||
} | |||
} |
@@ -300,6 +300,7 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt | |||
$query->select('SUM(orderProduct.quantityOrder) as quantity'); | |||
$result = $query->getQuery()->getOneOrNullResult(); | |||
return $result['quantity']; | |||
} |
@@ -32,7 +32,6 @@ class UserRepository extends BaseRepository implements DefaultRepositoryInterfac | |||
return $this->createQueryBuilder('e') | |||
->where(':newsletter MEMBER OF e.newsletters') | |||
->setParameter('newsletter', $newsletter->getId()) | |||
->andWhere('e.enabled = 1') | |||
->innerJoin('e.userMerchants', 'um') | |||
->andWhere('um.merchant = :merchant AND um.active = 1') | |||
->setParameter('merchant', $newsletter->getMerchant()) | |||
@@ -49,4 +48,15 @@ class UserRepository extends BaseRepository implements DefaultRepositoryInterfac | |||
return $qb->getQuery()->getResult(); | |||
} | |||
public function findByTicketTypesNotification($ticketType){ | |||
$qb = $this->createQueryBuilder('u') | |||
->where('u.ticketTypesNotification LIKE :ticketType') | |||
->setParameter('ticketType', '%"' . $ticketType . '"%'); | |||
return $qb->getQuery()->getResult(); | |||
} | |||
} |
@@ -8,7 +8,7 @@ Vue.component('order-product', { | |||
computed: {}, | |||
mounted: function () { | |||
this.setFields() | |||
log(this); | |||
}, | |||
methods: { | |||
setFields: function () { |
@@ -167,6 +167,7 @@ $(window).on('load', function () { | |||
title: null, | |||
position: 0, | |||
status:1, | |||
originProduct: false, | |||
fieldToUpdate: ['title', 'unit', 'quantity', 'price'], | |||
price: null, | |||
priceWithTax: null, | |||
@@ -267,7 +268,8 @@ $(window).on('load', function () { | |||
}, | |||
deleteProductForm: function () { | |||
if (confirm('Êtes-vous sur de cette action ?')) { | |||
Vue.delete(this.$parent.formProducts, this.keyForm); | |||
this.status = -1; | |||
//Vue.delete(this.$parent.formProducts, this.keyForm); | |||
this.$nextTick(function () { | |||
this.$parent.updateSortableProducts(true); | |||
}); |
@@ -1,37 +0,0 @@ | |||
// Reference array sent to dynamic staticRenderFns | |||
var staticRenderFns = []; | |||
appOrder = new Vue({ | |||
el: '#lc-supplier-edit', | |||
delimiters: ['${', '}'], | |||
data() { | |||
return Object.assign( | |||
{ | |||
addressType: null, | |||
currentSection:'general', | |||
sectionsArray: [ | |||
{ | |||
name: 'general', | |||
nameDisplay: 'Général' | |||
}, | |||
{ | |||
name: 'address', | |||
nameDisplay: 'Adresse' | |||
}, | |||
{ | |||
name: 'seo', | |||
nameDisplay: 'SEO' | |||
} | |||
] | |||
}, window.addressValues); | |||
}, | |||
mounted: function () {}, | |||
methods: { | |||
changeSection: function (section) { | |||
this.currentSection = section.name; | |||
}, | |||
}, | |||
watch: {} | |||
}); | |||
@@ -21,6 +21,8 @@ group: | |||
default: Édition | |||
Général: Général | |||
Adresse: Adresse | |||
Supplier: | |||
contact: Personne de contact | |||
Reminder: | |||
title: Pense bête | |||
list: Pense bêtes | |||
@@ -99,6 +101,7 @@ success: | |||
addReductionCredit: L'avoir a bien été généré | |||
removeReductionCredit: L'avoir a bien été généré | |||
removeReductionCart: La réduction a bien été supprimé | |||
sendPaymentLink: Le lien de paiement a bien été envoyé | |||
credit: | |||
debited: Le compte prépayé a bien été débité | |||
added: Le compte a bien été crédité | |||
@@ -264,6 +267,7 @@ field: | |||
emailFromName: "Email (From) : nom" | |||
emailSubjectPrefix: "Email : préfixe" | |||
emailContact: Email (contact) | |||
emailFromPurchaseOrder: "Email (From) : bons de commande" | |||
order: Commande | |||
subject: Sujet | |||
metaTitle: Meta title | |||
@@ -277,6 +281,11 @@ field: | |||
codeHelp: Code utilisé pour retrouver l'ambassade dans le tunnel de commande (Non sensible à la casse) | |||
Supplier: | |||
user: Utilisateur lié | |||
contactName: Personne de contact (Nom et prénom) | |||
contactPhone: Téléphone | |||
contactEmail: Email de la personne de contact | |||
displayTotalWeightInPurchaseOrder: Afficher le poids total dans les bons de commande | |||
ProductFamily: | |||
taxRateInherited: Utiliser la TVA par défaut | |||
activeProducts: Activer les déclinaisons | |||
@@ -405,7 +414,7 @@ field: | |||
quantityProduct: Quantité (en rapport à l'unité) | |||
unit: Unité | |||
redeliverySupplierShort: Erreur producteur | |||
redeliverySupplier: Erreur producteur (Aura un prix à 0€ dans le prohain bon de commande producteur - vous devez cocher à recommander) | |||
redeliverySupplierMistake: Erreur producteur (Aura un prix à 0€ dans le prohain bon de commande producteur - vous devez cocher à recommander) | |||
redeliverySupplierOrderShort: À recommander au producteur | |||
redeliverySupplierOrder: À recommander au producteur (Sera affiché dans le prohain bon de commande producteur) | |||
deliveryType: Type de livraison |
@@ -4,9 +4,12 @@ | |||
<i class="fa fa-{% block icon %}bg-info{% endblock %}"></i></span> | |||
<div class="info-box-content"> | |||
{% block infoBox %} | |||
<span class="info-box-text">{% block label %}{% endblock %}</span> | |||
<strong>{% block value %}{% endblock %}</strong> | |||
{% endblock %} | |||
<div class="float-right"> {% block button %}{% endblock %} | |||
</div> | |||
</div> | |||
</div> |
@@ -21,15 +21,15 @@ | |||
<div class="col-6"> | |||
{{ form_row(form.firstname) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.address) }} | |||
</div> | |||
<div class="col-6"> | |||
{{ form_row(form.zip) }} | |||
</div> | |||
<div class="col-6"> | |||
{{ form_row(form.city) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.address) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.phone) }} | |||
</div> | |||
@@ -57,6 +57,12 @@ | |||
<div class="col-6"> | |||
{{ form_row(form.longitude) }} | |||
</div> | |||
<div class="col-6"> | |||
{{ form_row(form.latitudeOverride) }} | |||
</div> | |||
<div class="col-6"> | |||
{{ form_row(form.longitudeOverride) }} | |||
</div> | |||
{{ form_row(form.country) }} | |||
@@ -80,7 +80,7 @@ | |||
<ul class="navbar-nav ml-auto lc-navbar"> | |||
{% set _user_name = easyadmin_read_property(app.user, easyadmin_config('user.name_property_path'))|default('user.unnamed'|trans(domain = 'EasyAdminBundle')) %} | |||
{% set _user_name = app.user.name %} | |||
{% set _logout_path = easyadmin_logout_path() %} | |||
<li class="content-top navbar-custom-menu"> | |||
{% block header_custom_menu %} |
@@ -5,16 +5,24 @@ | |||
<div class="row"> | |||
<div class="col-8"> | |||
{{ macros.card_start('Merchant.delivery','light') }} | |||
<div class="col-12"> | |||
{{ form_row(form.merchantConfigs['image-zones']) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.merchantConfigs['downtime-per-customer']) }} | |||
</div> | |||
{% if form.merchantConfigs['image-zones'] is defined %} | |||
<div class="col-12"> | |||
{{ form_row(form.merchantConfigs['image-zones']) }} | |||
</div> | |||
{% endif %} | |||
{% if form.merchantConfigs['downtime-per-customer'] is defined %} | |||
<div class="col-12"> | |||
{{ form_row(form.merchantConfigs['downtime-per-customer']) }} | |||
</div> | |||
{% endif %} | |||
<div class="col-12"> | |||
{{ form_row(form.deliveryTaxRate) }} | |||
</div> | |||
{% if form.merchantConfigs['bike-delivery-url-map'] is defined %} | |||
<div class="col-12"> | |||
{{ form_row(form.merchantConfigs['bike-delivery-url-map']) }} | |||
</div> | |||
{% endif %} | |||
{{ macros.card_end() }} | |||
</div> | |||
</div> |
@@ -18,6 +18,9 @@ | |||
<div class="col-12"> | |||
{{ form_row(form.merchantConfigs['email-contact']) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.merchantConfigs['email-from-purchase-order']) }} | |||
</div> | |||
{{ macros.card_end() }} | |||
</div> | |||
</div> |
@@ -11,13 +11,18 @@ | |||
<th colspan="2"> | |||
<span>Produits / Producteurs</span> | |||
</th> | |||
<th v-if="order.countComplementaryOrderShops > 0">Compléments</th> | |||
<th> | |||
<span v-if="order.countComplementaryOrderShops > 0">Compléments</span> | |||
</th> | |||
<th> | |||
<span>Prix HT à l'unité</span> | |||
<span>Prix achat HT </span> | |||
</th> | |||
<th> | |||
<span>Prix HT</span> | |||
</th> | |||
<th> | |||
<span>Prix TTC à l'unité </span> | |||
<span>Prix TTC </span> | |||
</th> | |||
<th> | |||
<span>Marge </span> | |||
@@ -53,33 +58,36 @@ | |||
{% macro productsTemplate(form_order_products=null) %} | |||
<tr :class=" orderProduct.isRedelivery ? 'redelivery order-product-item' : 'order-product-item'"> | |||
<td :class="editionMode ? '' : 'hidden'"> | |||
<input type="checkbox" :value="orderProduct.id" class="order-product-checkbox" /> | |||
<input type="checkbox" :value="orderProduct.id" class="order-product-checkbox"/> | |||
</td> | |||
<td colspan="2"> | |||
<a :href="orderProduct.editLink" target="_blank"> | |||
<img :src="orderProduct.image" :alt="orderProduct.title" /> | |||
{% verbatim %}{{orderProduct.title}}{% endverbatim %} | |||
<span v-show="orderProduct.hasRedelivery"> | |||
- <i class="fa fa-undo" data-toggle="tooltip" :title="orderProduct.redeliveryOrderShop" ></i> | |||
<img :src="orderProduct.image" :alt="orderProduct.title"/> | |||
{% verbatim %}{{orderProduct.title}}{% endverbatim %} | |||
<span v-show="orderProduct.hasRedelivery"> | |||
- <i class="fa fa-undo" data-toggle="tooltip" :title="orderProduct.redeliveryOrderShop"></i> | |||
</span> | |||
<span v-show="orderProduct.isRedelivery"> | |||
- <i class="fa fa-undo" data-toggle="tooltip" title="Ce produit est une relivraison" ></i> | |||
<span v-show="orderProduct.isRedelivery"> | |||
- <i class="fa fa-undo" data-toggle="tooltip" title="Ce produit est une relivraison"></i> | |||
</span> | |||
</a> | |||
</td> | |||
<td> | |||
<span v-if="orderProduct.complementaryReference"> {% verbatim %}{{orderProduct.complementaryReference}}{% endverbatim %}</span> | |||
<span v-if="orderProduct.complementaryReference"> {% verbatim %}{{orderProduct.complementaryReference}}{% endverbatim %}</span> | |||
</td> | |||
<td> | |||
{% verbatim %}{{orderProduct.buyingPrice}}{% endverbatim %} € | |||
</td> | |||
<td> | |||
{% verbatim %}{{orderProduct.price}}{% endverbatim %}€ | |||
</td> | |||
<td> | |||
{% verbatim %}{{orderProduct.priceWithTax}}{% endverbatim %}€ | |||
{% verbatim %}{{orderProduct.priceWithTax}}{% endverbatim %} € | |||
</td> | |||
<td> | |||
{% verbatim %}{{orderProduct.totalMargin}}{% endverbatim %}€ / | |||
{% verbatim %}{{orderProduct.marginPercent}}{% endverbatim %}% | |||
{% verbatim %}{{orderProduct.totalMargin}}{% endverbatim %} € / | |||
{% verbatim %}{{orderProduct.marginPercent}}{% endverbatim %} % | |||
</td> | |||
<td> | |||
{% verbatim %}{{orderProduct.availableQuantity}}{% endverbatim %} | |||
@@ -102,19 +110,22 @@ | |||
{% endif %} | |||
</td> | |||
<td> | |||
{% verbatim %}{{orderProduct.totalWithTaxAndReduction}}{% endverbatim %}€ | |||
{% verbatim %}{{orderProduct.totalWithTaxAndReduction}}{% endverbatim %} € | |||
</td> | |||
<td :class="editionMode ? '' : 'hidden'"> | |||
<div class="dropdown" :class="editionMode ? '' : 'hidden'"> | |||
<button class="btn-sm btn-info dropdown-toggle" type="button" id="dropdownMenu" data-toggle="dropdown" aria-expanded="false"> | |||
<div class="dropdown" :class="editionMode ? '' : 'hidden'"> | |||
<button class="btn-sm btn-info dropdown-toggle" type="button" id="dropdownMenu" | |||
data-toggle="dropdown" aria-expanded="false"> | |||
Actions | |||
</button> | |||
<div class="dropdown-menu" aria-labelledby="dropdownMenu"> | |||
<button v-show="modalExist('#modal-add-redelivery-order-product') && orderProduct.hasRedelivery == false" type="button" class="dropdown-item" @click="modalAddRedeliveryOrderProduct"> | |||
<button v-show="modalExist('#modal-add-redelivery-order-product') && orderProduct.hasRedelivery == false" | |||
type="button" class="dropdown-item" @click="modalAddRedeliveryOrderProduct"> | |||
Générer une relivraison | |||
</button> | |||
<button v-show="modalExist('#modal-add-reduction-credit')" type="button" class="dropdown-item" @click="modalAddReductionCredit" > | |||
<button v-show="modalExist('#modal-add-reduction-credit')" type="button" class="dropdown-item" | |||
@click="modalAddReductionCredit"> | |||
Générer un avoir | |||
</button> | |||
</div> | |||
@@ -149,7 +160,7 @@ | |||
<tbody> | |||
<tr> | |||
<th>Total produits TTC</th> | |||
<td>${order.totalOrderProductsWithTax}€</td> | |||
<td>${order.totalOrderProductsWithTax} €</td> | |||
</tr> | |||
<template v-for="(orderReductionCart, key) in order.orderReductionCarts"> | |||
<tr> | |||
@@ -161,7 +172,7 @@ | |||
<i class="fa fa-trash"></i> | |||
</button> | |||
</th> | |||
<td>${orderReductionCart.amount}€</td> | |||
<td>${orderReductionCart.amount} €</td> | |||
</tr> | |||
</template> | |||
<template v-for="(orderReductionCredit, key) in order.orderReductionCredits"> | |||
@@ -174,25 +185,25 @@ | |||
<i class="fa fa-trash"></i> | |||
</button> | |||
</th> | |||
<td>${orderReductionCredit.amount}€</td> | |||
<td>${orderReductionCredit.amount} €</td> | |||
</tr> | |||
</template> | |||
<tr> | |||
<th>Total produits après réductions TTC</th> | |||
<td>${order.totalOrderProductsWithTaxAndReductions}€</td> | |||
<td>${order.totalOrderProductsWithTaxAndReductions} €</td> | |||
</tr> | |||
<tr> | |||
<th>Total marge produits</th> | |||
<td>${order.totalMargin}€ <br /> ${order.totalMarginPercent}%</td> | |||
<td>${order.totalMargin} € <br/> ${order.totalMarginPercent} %</td> | |||
</tr> | |||
<tr> | |||
<th>Frais de livraisons TTC</th> | |||
<td>${order.deliveryPriceWithTaxAndReduction}€</td> | |||
<td>${order.deliveryPriceWithTaxAndReduction} €</td> | |||
</tr> | |||
<tr> | |||
<th>Total TTC</th> | |||
<td>${order.totalWithTax}€</td> | |||
<td>${order.totalWithTax} €</td> | |||
</tr> | |||
</tbody> | |||
@@ -217,11 +228,22 @@ | |||
{% macro box_user_info() %} | |||
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %} | |||
{% set value = ' <a v-if="order.user" :href="order.userLink" target="_blank" v-html="order.user"></a> | |||
<span v-else v-html="order.visitor"></span>' %} | |||
{{ macros.box_info('bg-info', 'user',"field.default.user"|trans({}, 'lcshop'), value) }} | |||
{% embed '@LcShop/backend/default/block/embed_box.twig' %} | |||
{% import '@LcShop/backend/order/macros.html.twig' as order_macros %} | |||
{% trans_default_domain 'lcshop' %} | |||
{% block class %}bg-info{% endblock %} | |||
{% block icon %}credit-card{% endblock %} | |||
{% block label %}{{ "field.OrderShop.reference"|trans({}, 'lcshop') }}{% endblock %} | |||
{% block value %} | |||
<span v-if="order.user" v-html="order.user"></span> | |||
<span v-else v-html="order.visitor"></span> | |||
{% endblock %} | |||
{% block button %} | |||
<a class="btn btn-sm btn-secondary" target="_blank" :href="order.userLink"> | |||
Voir la fiche | |||
</a> | |||
{% endblock %} | |||
{% endembed %} | |||
{% endmacro box_user_info %} | |||
@@ -233,16 +255,13 @@ | |||
{% trans_default_domain 'lcshop' %} | |||
{% block class %}bg-info{% endblock %} | |||
{% block icon %}credit-card{% endblock %} | |||
{% block label %}{{ "field.OrderShop.reference"|trans({}, 'lcshop')}}{% endblock %} | |||
{% block label %}{{ "field.OrderShop.reference"|trans({}, 'lcshop') }}{% endblock %} | |||
{% block value %} | |||
${order.reference}<br /> | |||
${order.reference}<br/> | |||
<span v-if="order.countComplementaryOrderShops > 0"> | |||
${order.countComplementaryOrderShops} commande(s) complémentaire(s) | |||
</span> | |||
{% endblock %} | |||
{% block button %} | |||
{{ order_macros.order_modal_button('#modal-order-delivery-address') }} | |||
{% endblock %} | |||
{% endembed %} | |||
{% endmacro %} | |||
@@ -257,9 +276,54 @@ | |||
{% macro box_total_order() %} | |||
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %} | |||
{% embed '@LcShop/backend/default/block/embed_box.twig' %} | |||
{% import '@LcShop/backend/order/macros.html.twig' as order_macros %} | |||
{% trans_default_domain 'lcshop' %} | |||
{% block class %}bg-danger{% endblock %} | |||
{% block icon %}euro-sign{% endblock %} | |||
{% block infoBox %} | |||
<table style="width: 100%"> | |||
<tr> | |||
<td> | |||
Total produits TTC :<i class="icon info" data-toggle="tooltip" title="Après reduction"></i> | |||
</td> | |||
<td> | |||
<strong class="float-right"> ${order.totalOrderProductsWithTaxAndReductions} €</strong><br/> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td> | |||
Total marge produits : | |||
</td> | |||
<td> | |||
<strong class="float-right">${order.totalMargin} € / ${order.totalMarginPercent} %</strong><br/> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td> | |||
Frais de livraisons TTC : | |||
</td> | |||
<td> | |||
<strong class="float-right">${order.deliveryPriceWithTaxAndReduction} €</strong><br/> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td> | |||
Total commandes : | |||
</td> | |||
<td> | |||
<strong class="float-right"> ${order.totalWithTax} €</strong><br/> | |||
</td> | |||
</tr> | |||
</table> | |||
{{ macros.box_info('bg-danger', 'euro-sign',"field.OrderShop.total"|trans({}, 'lcshop'), ' ${order.totalWithTax} €') }} | |||
{% endblock %} | |||
{% endembed %} | |||
{% endmacro %} | |||
@@ -290,7 +354,7 @@ | |||
{% trans_default_domain 'lcshop' %} | |||
{% block class %}bg-success{% endblock %} | |||
{% block icon %}map-marked-alt{% endblock %} | |||
{% block label %}{{ "field.default.deliveryAddress"|trans({}, 'lcshop')}}{% endblock %} | |||
{% block label %}{{ "field.default.deliveryAddress"|trans({}, 'lcshop') }}{% endblock %} | |||
{% block value %} | |||
<div v-if="order.deliveryAddress"> | |||
<address v-html="order.deliveryAddress"> | |||
@@ -352,48 +416,49 @@ | |||
</div>' %} | |||
{{ macros.card_start("OrderShop.payment", 'danger card-outline', false, tools) }} | |||
<table class="table table-striped" style="margin-bottom: 15px"> | |||
<tbody> | |||
<thead> | |||
<table class="table table-striped" style="margin-bottom: 15px"> | |||
<tbody> | |||
<thead> | |||
<tr> | |||
<th v-if="order.countComplementaryOrderShops > 0">Référence</th> | |||
<th>Mode de règlement</th> | |||
<th>Date</th> | |||
<th>Montant</th> | |||
<th>Actions</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<template v-for="(orderPayment, i) in order.orderPayments"> | |||
<tr> | |||
<th v-if="order.countComplementaryOrderShops > 0">Référence</th> | |||
<th>Mode de règlement</th> | |||
<th>Date</th> | |||
<th>Montant</th> | |||
<th>Actions</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<template v-for="(orderPayment, i) in order.orderPayments"> | |||
<tr> | |||
<td v-if="order.countComplementaryOrderShops > 0"> | |||
${orderPayment.orderReference} | |||
</td> | |||
<td>${orderPayment.meanPaymentText}</td> | |||
<td>${orderPayment.paidAtText}</td> | |||
<td>${orderPayment.amount}</td> | |||
<td v-if="order.countComplementaryOrderShops > 0"> | |||
${orderPayment.orderReference} | |||
</td> | |||
<td>${orderPayment.meanPaymentText}</td> | |||
<td>${orderPayment.paidAtText}</td> | |||
<td>${orderPayment.amount}</td> | |||
<td> | |||
<button v-show="orderPayment.editable && editionMode && modalExist('#modal-delete-order-payment')" class="btn-sm btn-info" type="button" @click="editOrderPayment(orderPayment.id)"> | |||
<i class="fa fa-pen"></i> | |||
</button> | |||
<button v-show="orderPayment.editable && editionMode && modalExist('#modal-delete-order-payment')" | |||
type="button" class="btn-sm btn-danger" | |||
@click="modalDeleteOrderPayment(orderPayment.id)"> | |||
<i class="fa fa-trash"></i> | |||
</button> | |||
</td> | |||
</tr> | |||
</template> | |||
</tbody> | |||
</table> | |||
<div class="col-11"> | |||
{{ _self.order_modal_button('#modal-order-payment', 'btn-info', "action.order.addOrderPayment") }} | |||
<td> | |||
<button v-show="orderPayment.editable && editionMode && modalExist('#modal-delete-order-payment')" | |||
class="btn-sm btn-info" type="button" @click="editOrderPayment(orderPayment.id)"> | |||
<i class="fa fa-pen"></i> | |||
</button> | |||
<button v-show="orderPayment.editable && editionMode && modalExist('#modal-delete-order-payment')" | |||
type="button" class="btn-sm btn-danger" | |||
@click="modalDeleteOrderPayment(orderPayment.id)"> | |||
<i class="fa fa-trash"></i> | |||
</button> | |||
</td> | |||
</tr> | |||
</template> | |||
</tbody> | |||
</table> | |||
<div class="col-11"> | |||
{{ _self.order_modal_button('#modal-order-payment', 'btn-info', "action.order.addOrderPayment") }} | |||
<strong class="float-right">Total règlement : ${order.totalOrderPaid} €</strong> | |||
<strong class="float-right">Total règlement : ${order.totalOrderPaid} €</strong> | |||
{#TODO: afficher si la commande est règlé et afficher une alerte si le montant des paiments est supérieur au montant total de la commande#} | |||
</div> | |||
{#TODO: afficher si la commande est règlé et afficher une alerte si le montant des paiments est supérieur au montant total de la commande#} | |||
</div> | |||
{{ macros.card_end() }} | |||
{% endmacro %} | |||
@@ -424,7 +489,8 @@ | |||
<td>Facture</td> | |||
<td>${orderDocument.reference}</td> | |||
<td> | |||
<a :href="'./?entity=Document&action=downloadInvoice&id='+orderDocument.id" class="btn-sm btn-default">Télécharger</a> | |||
<a :href="'./?entity=Document&action=downloadInvoice&id='+orderDocument.id" | |||
class="btn-sm btn-default">Télécharger</a> | |||
</td> | |||
</tr> | |||
</template> | |||
@@ -508,7 +574,7 @@ | |||
{% trans_default_domain 'lcshop' %} | |||
{% block class %}bg-success{% endblock %} | |||
{% block icon %}info{% endblock %} | |||
{% block label %}{{ "field.OrderShop.status"|trans({}, 'lcshop')}}{% endblock %} | |||
{% block label %}{{ "field.OrderShop.status"|trans({}, 'lcshop') }}{% endblock %} | |||
{% block value %} | |||
<strong> ${order.orderStatus}</strong> | |||
{% endblock %} |
@@ -11,10 +11,10 @@ | |||
{{ order_macros.box_user_info() }} | |||
</div> | |||
<div class="col-3"> | |||
{{ order_macros.box_validation_date() }} | |||
{{ order_macros.box_total_order() }} | |||
</div> | |||
<div class="col-3"> | |||
{{ order_macros.box_total_order() }} | |||
{{ order_macros.box_validation_date() }} | |||
</div> | |||
<div class="col-3"> |
@@ -11,10 +11,10 @@ | |||
{{ order_macros.box_user_info() }} | |||
</div> | |||
<div class="col-3"> | |||
{{ order_macros.box_validation_date() }} | |||
{{ order_macros.box_total_order() }} | |||
</div> | |||
<div class="col-3"> | |||
{{ order_macros.box_total_order() }} | |||
{{ order_macros.box_validation_date() }} | |||
</div> | |||
<div class="col-3"> |
@@ -14,12 +14,11 @@ | |||
{{ order_macros.box_user_info() }} | |||
</div> | |||
<div class="col-3"> | |||
{{ order_macros.box_validation_date() }} | |||
{{ order_macros.box_total_order() }} | |||
</div> | |||
<div class="col-3"> | |||
{{ order_macros.box_total_order() }} | |||
{{ order_macros.box_validation_date() }} | |||
</div> | |||
<div class="col-3"> | |||
{{ order_macros.box_status() }} | |||
</div> |
@@ -60,7 +60,7 @@ | |||
{% macro product_row(product, totalProductOrdered) %} | |||
<tr class="lc-draggable"> | |||
<tr class="lc-draggable" v-show="originProduct != true && status >= 0 "> | |||
<td> | |||
{% if product.vars.value is not null %} | |||
#{{ product.vars.value.id }} |
@@ -53,7 +53,7 @@ | |||
</th> | |||
<th colspan="3" class="price"> | |||
{# v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">#} | |||
{# v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">#} | |||
PV HT | |||
</th> | |||
<th colspan="3" class="price main-info"> | |||
@@ -137,7 +137,7 @@ | |||
</th> | |||
<th colspan="3" class="price"> | |||
{# v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">#} | |||
{# v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">#} | |||
${productFamily.price} | |||
</th> | |||
<th colspan="3" class="price main-info"> | |||
@@ -195,7 +195,9 @@ | |||
{% for keyForm,i in sortableProductsField %} | |||
{% set product = form.products[i] %} | |||
{#{% if product.vars.value.status >= 0 and (product.vars.value.originProduct is null or product.vars.value.originProduct == false) %}#} | |||
window.productForm[{{ keyForm }}] = { | |||
{% if product.vars.value.originProduct is defined %}originProduct: parseInt({{ product.vars.value.originProduct }}),{% endif %} | |||
{% if product.vars.value.status is defined %}status: parseInt({{ product.vars.value.status }}),{% endif %} | |||
{% if product.vars.value.position %}position: "{{ product.vars.value.position }}",{% endif %} | |||
{% if product.vars.value.title %}title: "{{ product.vars.value.title }}",{% endif %} | |||
@@ -211,6 +213,7 @@ | |||
{#{% if product.vars.value.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %}#} | |||
}; | |||
window.formProductTemplate[{{ keyForm }}] = '{{ product_family_macros.product_row(product, totalProductOrdered[product.vars.value.id])|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}'; | |||
{#{% endif %}#} | |||
{% endfor %} | |||
</script> |
@@ -1,13 +0,0 @@ | |||
{% extends app.request.query.get('action') == 'edit' ? '@LcShop/backend/default/edit.html.twig' : '@LcShop/backend/default/new.html.twig' %} | |||
{% block entity_form %} | |||
{% include '@LcShop/backend/supplier/form.html.twig' %} | |||
{% endblock entity_form %} | |||
{% block script_javascript %} | |||
{{ parent() }} | |||
{% include '@LcShop/backend/default/block/script-vuejs.html.twig' %} | |||
<script src="{{ asset('bundles/lcshop/js/backend/script/supplier/vuejs-supplier.js') }}"></script> | |||
{% endblock %} |
@@ -1,42 +0,0 @@ | |||
{{ form_start(form) }} | |||
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %} | |||
{% set formValues = form.vars.value %} | |||
<div id="lc-supplier-edit"> | |||
<div class="card card-light"> | |||
<div class="lc-vue-js-container card-header p-0 border-bottom-0"> | |||
<ul class="nav nav-tabs" id="nav-params"> | |||
<li class="nav-item" v-for="section in sectionsArray"> | |||
<button type="button" | |||
:class="'btn '+((currentSection == section.name) ? 'btn btn-primary' : 'btn ')" | |||
@click="changeSection(section)"> | |||
${ section.nameDisplay } | |||
<span class="glyphicon glyphicon-triangle-bottom"></span> | |||
<i class="fa fa-exclamation-circle invalid-form"></i> | |||
</button> | |||
</li> | |||
</ul> | |||
</div> | |||
</div> | |||
<div class="form "> | |||
<div v-show="currentSection == 'general'" class="panel panel-default"> | |||
{% include '@LcShop/backend/supplier/panel_general.html.twig' %} | |||
</div> | |||
<div v-show="currentSection == 'address'" class="panel panel-default"> | |||
{% include '@LcShop/backend/supplier/panel_address.html.twig' %} | |||
</div> | |||
<div v-show="currentSection == 'seo'" class="panel panel-default"> | |||
{% include '@LcShop/backend/supplier/panel_seo.html.twig' %} | |||
</div> | |||
</div> | |||
</div> | |||
{{ form_end(form) }} | |||
@@ -1,17 +0,0 @@ | |||
{% trans_default_domain 'lcshop' %} | |||
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %} | |||
<div class="row"> | |||
<div class="col-8"> | |||
{{ macros.card_start('Merchant.address','light') }} | |||
{% do form.address.civility.setRendered %} | |||
{% do form.address.firstname.setRendered %} | |||
{% do form.address.lastname.setRendered %} | |||
{% do form.address.phone.setRendered %} | |||
{% do form.address.latitude.setRendered %} | |||
{% do form.address.longitude.setRendered %} | |||
{% do form.address.deliveryInfos.setRendered %} | |||
{% include '@LcShop/backend/default/block/form_address.html.twig' with {'form' : form.address}%} | |||
{{ macros.card_end() }} | |||
</div> | |||
</div> |
@@ -1,23 +0,0 @@ | |||
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %} | |||
<div class="row"> | |||
<div class="col-8"> | |||
{{ macros.card_start('Merchant.main','light') }} | |||
<div class="col-12"> | |||
{{ form_row(form.title) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.subtitle) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.kmsHub) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.imageFile) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.description) }} | |||
</div> | |||
{{ macros.card_end() }} | |||
</div> | |||
</div> |
@@ -1,14 +0,0 @@ | |||
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %} | |||
<div class="row"> | |||
<div class="col-8"> | |||
{{ macros.card_start('Merchant.seo','light') }} | |||
<div class="col-12"> | |||
{{ form_row(form.metaTitle) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.metaDescription) }} | |||
</div> | |||
{{ macros.card_end() }} | |||
</div> | |||
</div> |
@@ -29,7 +29,7 @@ class CsvGenerator | |||
protected $convertEncoding ; | |||
protected $fromEncoding ; | |||
protected $toEncoding ; | |||
protected $delimiter ; | |||
public function __construct() | |||
{ | |||
@@ -38,6 +38,7 @@ class CsvGenerator | |||
$this->convertEncoding = false ; | |||
$this->fromEncoding = 'UTF-8' ; | |||
$this->toEncoding = 'ISO-8859-1' ; | |||
$this->delimiter = ';' ; | |||
} | |||
public function enableConvertEncoding($toEncoding, $fromEncoding = null) | |||
@@ -53,7 +54,10 @@ class CsvGenerator | |||
public function encode($value) | |||
{ | |||
if($this->convertEncoding) { | |||
return mb_convert_encoding($value, $this->toEncoding, $this->fromEncoding) ; | |||
return mb_convert_encoding( | |||
$value, | |||
$this->toEncoding, | |||
$this->fromEncoding) ; | |||
} | |||
return $value ; | |||
@@ -119,7 +123,7 @@ class CsvGenerator | |||
$handle = fopen($path, 'w+'); | |||
foreach ($this->arrayToExport as $line) { | |||
fputcsv($handle, $line, ';', ' '); | |||
fputcsv($handle, $line, $this->getDelimiter(), "\""); | |||
} | |||
fclose($handle); | |||
} | |||
@@ -143,7 +147,10 @@ class CsvGenerator | |||
} | |||
public function getDelimiter() | |||
{ | |||
return $this->delimiter ; | |||
} | |||
@@ -67,12 +67,14 @@ class DocumentUtils | |||
if(isset($params['merchant'])) { | |||
$document->setMerchant($params['merchant']) ; | |||
} | |||
else { | |||
elseif(isset($params['order_shops'])) { | |||
$document->setMerchant($params['order_shops'][0]->getMerchant()) ; | |||
} | |||
foreach($params['order_shops'] as $orderShop) { | |||
$document->addOrderShop($orderShop) ; | |||
if(isset($params['order_shops'])) { | |||
foreach ($params['order_shops'] as $orderShop) { | |||
$document->addOrderShop($orderShop); | |||
} | |||
} | |||
$document->setType($params['type']) ; |
@@ -41,7 +41,7 @@ class MailUtils | |||
$merchantCurrent = $this->merchantUtils->getMerchantCurrent(); | |||
$merchantConfigEmailFrom = $merchantCurrent->getMerchantConfig('email-from'); | |||
$emailFrom = isset($params[self::FROM_EMAIL]) ? $params[self::FROM_EMAIL] : $merchantConfigEmailFrom; | |||
$emailFrom = (isset($params[self::FROM_EMAIL]) && $params[self::FROM_EMAIL] && strlen($params[self::FROM_EMAIL])) ? $params[self::FROM_EMAIL] : $merchantConfigEmailFrom; | |||
$merchantConfigEmailFromName = $merchantCurrent->getMerchantConfig('email-from-name'); | |||
$emailFromName = isset($params[self::FROM_NAME]) ? $params[self::FROM_NAME] : $merchantConfigEmailFromName; |
@@ -338,6 +338,22 @@ class OrderUtils | |||
return false ; | |||
} | |||
public function getOrderProductsByProductFamilyInCart($productFamily) | |||
{ | |||
$arrayOrderProducts = [] ; | |||
$orderShop = $this->getCartCurrent() ; | |||
if($orderShop) { | |||
foreach($orderShop->getOrderProducts() as $orderProduct) { | |||
if($orderProduct->getProduct()->getProductFamily() == $productFamily) { | |||
$arrayOrderProducts[] = $orderProduct ; | |||
} | |||
} | |||
} | |||
return $arrayOrderProducts ; | |||
} | |||
public function groupOrderProductsByProductFamily($orderProducts) | |||
{ | |||
$orderProductsByProductFamily = []; |
@@ -0,0 +1,69 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Services ; | |||
class PointLocationUtils { | |||
var $pointOnVertex = true; // Check if the point sits exactly on one of the vertices? | |||
function pointLocation() { | |||
} | |||
function pointInPolygon($point, $polygon, $pointOnVertex = true) { | |||
$this->pointOnVertex = $pointOnVertex; | |||
// Transform string coordinates into arrays with x and y values | |||
$point = $this->pointStringToCoordinates($point); | |||
$vertices = array(); | |||
foreach ($polygon as $vertex) { | |||
$vertices[] = $this->pointStringToCoordinates($vertex); | |||
} | |||
// Check if the point sits exactly on a vertex | |||
if ($this->pointOnVertex == true and $this->pointOnVertex($point, $vertices) == true) { | |||
return "vertex"; | |||
} | |||
// Check if the point is inside the polygon or on the boundary | |||
$intersections = 0; | |||
$vertices_count = count($vertices); | |||
for ($i=1; $i < $vertices_count; $i++) { | |||
$vertex1 = $vertices[$i-1]; | |||
$vertex2 = $vertices[$i]; | |||
if ($vertex1['y'] == $vertex2['y'] and $vertex1['y'] == $point['y'] and $point['x'] > min($vertex1['x'], $vertex2['x']) and $point['x'] < max($vertex1['x'], $vertex2['x'])) { // Check if point is on an horizontal polygon boundary | |||
return "boundary"; | |||
} | |||
if ($point['y'] > min($vertex1['y'], $vertex2['y']) and $point['y'] <= max($vertex1['y'], $vertex2['y']) and $point['x'] <= max($vertex1['x'], $vertex2['x']) and $vertex1['y'] != $vertex2['y']) { | |||
$xinters = ($point['y'] - $vertex1['y']) * ($vertex2['x'] - $vertex1['x']) / ($vertex2['y'] - $vertex1['y']) + $vertex1['x']; | |||
if ($xinters == $point['x']) { // Check if point is on the polygon boundary (other than horizontal) | |||
return "boundary"; | |||
} | |||
if ($vertex1['x'] == $vertex2['x'] || $point['x'] <= $xinters) { | |||
$intersections++; | |||
} | |||
} | |||
} | |||
// If the number of edges we passed through is odd, then it's in the polygon. | |||
if ($intersections % 2 != 0) { | |||
return "inside"; | |||
} else { | |||
return "outside"; | |||
} | |||
} | |||
function pointOnVertex($point, $vertices) { | |||
foreach($vertices as $vertex) { | |||
if ($point == $vertex) { | |||
return true; | |||
} | |||
} | |||
} | |||
function pointStringToCoordinates($pointString) { | |||
$coordinates = explode(" ", $pointString); | |||
return array("x" => $coordinates[0], "y" => $coordinates[1]); | |||
} | |||
} |
@@ -13,23 +13,31 @@ use Lc\ShopBundle\Context\ReductionCatalogInterface; | |||
class OrderProductPriceUtils | |||
{ | |||
use PriceUtilsTrait ; | |||
use PriceUtilsTrait; | |||
protected $productPriceUtils ; | |||
protected $productPriceUtils; | |||
public function __construct(ProductPriceUtils $productPriceUtils) | |||
{ | |||
$this->productPriceUtils = $productPriceUtils ; | |||
$this->productPriceUtils = $productPriceUtils; | |||
} | |||
public function getPrice(OrderProductInterface $orderProduct) | |||
public function getPrice(OrderProductInterface $orderProduct, $round = false) | |||
{ | |||
return $orderProduct->getPrice(); | |||
if ($round) { | |||
return $this->round($orderProduct->getPrice()); | |||
} else { | |||
return $orderProduct->getPrice(); | |||
} | |||
} | |||
public function getBuyingPrice(OrderProductInterface $orderProduct) | |||
public function getBuyingPrice(OrderProductInterface $orderProduct, $round = false) | |||
{ | |||
return $orderProduct->getBuyingPrice(); | |||
if ($round) { | |||
return $this->round($orderProduct->getBuyingPrice()); | |||
} else { | |||
return $orderProduct->getBuyingPrice(); | |||
} | |||
} | |||
public function getPriceWithTax(OrderProductInterface $orderProduct) | |||
@@ -50,7 +58,7 @@ class OrderProductPriceUtils | |||
} | |||
public function getPriceWithReduction(OrderProductInterface $orderProduct) | |||
public function getPriceWithReduction(OrderProductInterface $orderProduct, $round = true) | |||
{ | |||
return $this->applyReductionCatalog( | |||
$orderProduct, | |||
@@ -58,7 +66,8 @@ class OrderProductPriceUtils | |||
$this->getPriceWithTax($orderProduct), | |||
1, | |||
null, | |||
false | |||
false, | |||
$round | |||
); | |||
} | |||
@@ -75,14 +84,14 @@ class OrderProductPriceUtils | |||
public function getMargin(OrderProductInterface $orderProduct) | |||
{ | |||
return $this->getPriceWithReduction($orderProduct) - $this->getBuyingPrice($orderProduct); | |||
return $this->round($this->getPriceWithReduction($orderProduct, false) - $this->getBuyingPrice($orderProduct)); | |||
} | |||
public function getMarginPercent(OrderProductInterface $orderProduct) | |||
{ | |||
if($this->getBuyingPrice($orderProduct)) { | |||
if ($this->getBuyingPrice($orderProduct)) { | |||
return $this->round(($this->getMargin($orderProduct) / $this->getPriceWithReduction($orderProduct)) * 100); | |||
}else{ | |||
} else { | |||
return 0; | |||
} | |||
} | |||
@@ -132,7 +141,8 @@ class OrderProductPriceUtils | |||
} | |||
//inclus toujours les réductions catalogues | |||
public function getTotalTaxes(OrderProductInterface $orderProduct){ | |||
public function getTotalTaxes(OrderProductInterface $orderProduct) | |||
{ | |||
return $this->getTotalWithTaxAndReduction($orderProduct) - $this->getTotalWithReduction($orderProduct); | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Services\Price ; | |||
namespace Lc\ShopBundle\Services\Price; | |||
use Lc\ShopBundle\Context\OrderProductInterface; | |||
use Lc\ShopBundle\Context\OrderShopInterface; | |||
@@ -10,59 +10,56 @@ use Lc\ShopBundle\Context\ProductPropertyInterface; | |||
class PriceUtils implements PriceUtilsInterface | |||
{ | |||
protected $productPriceUtils ; | |||
protected $orderProductPriceUtils ; | |||
protected $orderShopPriceUtils ; | |||
protected $productPriceUtils; | |||
protected $orderProductPriceUtils; | |||
protected $orderShopPriceUtils; | |||
public function __construct(ProductPriceUtils $productPriceUtils, OrderProductPriceUtils $orderProductPriceUtils, OrderShopPriceUtilsInterface $orderShopPriceUtils) | |||
{ | |||
$this->productPriceUtils = $productPriceUtils ; | |||
$this->orderProductPriceUtils = $orderProductPriceUtils ; | |||
$this->orderShopPriceUtils = $orderShopPriceUtils ; | |||
$this->productPriceUtils = $productPriceUtils; | |||
$this->orderProductPriceUtils = $orderProductPriceUtils; | |||
$this->orderShopPriceUtils = $orderShopPriceUtils; | |||
} | |||
public function __call($name, $arguments) | |||
{ | |||
$entity = $arguments[0] ; | |||
$service = '' ; | |||
if (strpos($name, 'apply') === false) { | |||
$entity = $arguments[0]; | |||
$service = ''; | |||
if($entity instanceof ProductPropertyInterface) { | |||
$service = 'productPriceUtils' ; | |||
} | |||
if($entity instanceof OrderProductInterface) { | |||
$service = 'orderProductPriceUtils' ; | |||
} | |||
if($entity instanceof OrderShopInterface || is_array($entity)) { | |||
$service = 'orderShopPriceUtils' ; | |||
} | |||
if(strlen($service) && $entity && method_exists($this->$service, $name)) { | |||
if(isset($arguments[1]) && isset($arguments[2]) && isset($arguments[3])) { | |||
return $this->$service->$name($entity, $arguments[1], $arguments[2], $arguments[3]) ; | |||
} | |||
elseif(isset($arguments[1]) && isset($arguments[2])) { | |||
return $this->$service->$name($entity, $arguments[1], $arguments[2]) ; | |||
} | |||
elseif(isset($arguments[1])) { | |||
return $this->$service->$name($entity, $arguments[1]) ; | |||
if ($entity instanceof ProductPropertyInterface) { | |||
$service = 'productPriceUtils'; | |||
} | |||
else { | |||
return $this->$service->$name($entity) ; | |||
if ($entity instanceof OrderProductInterface) { | |||
$service = 'orderProductPriceUtils'; | |||
} | |||
} | |||
else { | |||
if(!strlen($service)) { | |||
throw new \ErrorException("PriceUtils : le type d'entité n'est pas géré.") ; | |||
if ($entity instanceof OrderShopInterface || is_array($entity)) { | |||
$service = 'orderShopPriceUtils'; | |||
} | |||
else { | |||
if(!method_exists($this->$service, $name)) { | |||
throw new \ErrorException("PriceUtils : la méthode ".$name." du service ".$service." n'existe pas.") ; | |||
if (strlen($service) && $entity && method_exists($this->$service, $name)) { | |||
if (isset($arguments[1]) && isset($arguments[2]) && isset($arguments[3])) { | |||
return $this->$service->$name($entity, $arguments[1], $arguments[2], $arguments[3]); | |||
} elseif (isset($arguments[1]) && isset($arguments[2])) { | |||
return $this->$service->$name($entity, $arguments[1], $arguments[2]); | |||
} elseif (isset($arguments[1])) { | |||
return $this->$service->$name($entity, $arguments[1]); | |||
} else { | |||
return $this->$service->$name($entity); | |||
} | |||
} else { | |||
if (!strlen($service)) { | |||
throw new \ErrorException("PriceUtils : le type d'entité n'est pas géré."); | |||
} else { | |||
if (!method_exists($this->$service, $name)) { | |||
throw new \ErrorException("PriceUtils : la méthode " . $name . " du service " . $service . " n'existe pas."); | |||
} | |||
} | |||
} | |||
} | |||
return false ; | |||
return false; | |||
} | |||
} | |||
} | |||
} |
@@ -42,7 +42,7 @@ trait PriceUtilsTrait | |||
return round((($price * $percent)) / 100, 2); | |||
} | |||
public function applyReductionCatalog($entity, $price, $priceWithTax, $quantity = 1, $reductionCatalog = null, $withTax = true): ?float | |||
public function applyReductionCatalog($entity, $price, $priceWithTax, $quantity = 1, $reductionCatalog = null, $withTax = true, $round = true): ?float | |||
{ | |||
if ($reductionCatalog) { | |||
@@ -99,8 +99,13 @@ trait PriceUtilsTrait | |||
} else { | |||
$priceReturn = $this->applyPercentNegative($priceWithTax, $entity->getTaxRateInherited()->getValue()); | |||
} | |||
if($round){ | |||
return $this->round($priceReturn); | |||
}else{ | |||
return $priceReturn; | |||
} | |||
return $this->round($priceReturn); | |||
} | |||
@@ -1,368 +0,0 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Services; | |||
use Doctrine\Common\Collections\Collection; | |||
use Lc\ShopBundle\Context\OrderProductInterface; | |||
use Lc\ShopBundle\Context\OrderShopInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyInterface; | |||
use Lc\ShopBundle\Context\ProductInterface; | |||
use Lc\ShopBundle\Context\ProductPropertyInterface; | |||
use Lc\ShopBundle\Context\ReductionCatalogInterface; | |||
class PriceUtilsOld | |||
{ | |||
public function getPrice($entity) | |||
{ | |||
if ($entity instanceof ProductPropertyInterface) { | |||
if ($entity->getBehaviorPriceInherited() == 'by-piece') { | |||
return $entity->getPriceInherited(); | |||
} elseif ($entity->getBehaviorPriceInherited() == 'by-reference-unit') { | |||
if ($entity->getQuantityInherited() > 0) { | |||
return $entity->getPriceByRefUnitInherited() * ($entity->getQuantityInherited() / $entity->getUnitInherited()->getCoefficient()); | |||
} | |||
} | |||
} | |||
if ($entity instanceof OrderProductInterface) { | |||
return $entity->getPrice(); | |||
} | |||
return null; | |||
} | |||
public function getPriceWithTax($entity) | |||
{ | |||
return $this->applyTax( | |||
$this->getPrice($entity), | |||
$entity->getTaxRateInherited()->getValue() | |||
); | |||
} | |||
public function getPriceWithTaxAndReduction($entity) | |||
{ | |||
return $this->getPriceWithTaxAndReductionCatalog( | |||
$entity, | |||
$this->getPrice($entity), | |||
$this->getPriceWithTax($entity) | |||
); | |||
} | |||
public function getPriceByRefUnit($entity) | |||
{ | |||
if ($entity instanceof ProductPropertyInterface) { | |||
if ($entity->getBehaviorPriceInherited() == 'by-piece') { | |||
return ($this->getPrice($entity) * $entity->getUnitInherited()->getCoefficient()) / $entity->getQuantityInherited(); | |||
} elseif ($entity->getBehaviorPriceInherited() == 'by-reference-unit') { | |||
return $entity->getPriceByRefUnitInherited(); | |||
} | |||
} | |||
if ($entity instanceof OrderProductInterface) { | |||
return ($this->getPrice($entity) * $entity->getUnitInherited()->getCoefficient()) / $entity->getQuantityProduct(); | |||
} | |||
return null; | |||
} | |||
public function getPriceByRefUnitWithTax($entity) | |||
{ | |||
return $this->applyTax( | |||
$this->getPriceByRefUnit($entity), | |||
$entity->getTaxRateInherited()->getValue() | |||
); | |||
} | |||
public function getPriceByRefUnitWithTaxAndReduction($entity) | |||
{ | |||
return $this->getPriceWithTaxAndReductionCatalog( | |||
$entity, | |||
$this->getPriceByRefUnit($entity), | |||
$this->getPriceByRefUnitWithTax($entity) | |||
); | |||
} | |||
public function getTotal($entity) | |||
{ | |||
if ($entity instanceof OrderProductInterface) { | |||
return $entity->getQuantityOrder() * $this->getPrice($entity); | |||
} | |||
if ($entity instanceof OrderShopInterface) { | |||
$total = 0; | |||
foreach ($entity->getOrderProducts() as $orderProduct) { | |||
$total += $this->getTotal($orderProduct); | |||
} | |||
return $total; | |||
} | |||
return null; | |||
} | |||
public function getTotalWithTax($entity) | |||
{ | |||
if ($entity instanceof OrderProductInterface) { | |||
return $this->applyTax( | |||
$this->getTotal($entity), | |||
$entity->getTaxRateInherited()->getValue() | |||
); | |||
} | |||
if ($entity instanceof OrderShopInterface) { | |||
$total = 0; | |||
foreach ($entity->getOrderProducts() as $orderProduct) { | |||
$total += $this->getTotalWithTax($orderProduct); | |||
} | |||
return $total; | |||
} | |||
//C'est bizzare ce truc là | |||
//if($entity instanceof OrderShopInterface) { | |||
// return $this->getTotalOrderProducts($entity->getOrderProducts(), true) ; | |||
//} | |||
return null; | |||
} | |||
public function getTotalWithTaxAndReduction($entity) | |||
{ | |||
if ($entity instanceof OrderProductInterface) { | |||
return $this->getPriceWithTaxAndReductionCatalog( | |||
$entity, | |||
$this->getTotal($entity), | |||
$this->getTotalWithTax($entity) | |||
); | |||
} | |||
if ($entity instanceof OrderShopInterface) { | |||
return $this->getTotalOrderProductsWithTaxAndReduction($entity->getOrderProducts(), true, true); | |||
} | |||
} | |||
public function getTotalWithReduction($entity) | |||
{ | |||
if ($entity instanceof OrderProductInterface) { | |||
return $this->getPriceWithReductionCatalog( | |||
$entity, | |||
$this->getTotal($entity), | |||
$this->getTotalWithTax($entity) | |||
); | |||
} | |||
if ($entity instanceof OrderShopInterface) { | |||
return $this->getTotalOrderProductsWithReduction($entity->getOrderProducts(), true, true); | |||
} | |||
} | |||
public function getTotalOrderProductsWithReductionCart(OrderShopInterface $order) | |||
{ | |||
$this->_getTotalOrderProductsWithReductionCartGeneric($order, false); | |||
} | |||
public function getTotalOrderProductsWithTaxAndReductionCart(OrderShopInterface $order) | |||
{ | |||
$this->_getTotalOrderProductsWithReductionCartGeneric($order, true); | |||
} | |||
private function _getTotalOrderProductsWithReductionCartGeneric(OrderShopInterface $order, $withTax = true) | |||
{ | |||
if ($withTax) { | |||
$priceToReturn = $this->getTotalOrderProductsWithTaxAndReductionCatalog($order); | |||
} | |||
else { | |||
$priceToReturn = $this->getTotalOrderProductsWithReductionCatalog($order); | |||
} | |||
foreach ($order->getOrderReductionCarts() as $orderReductionCart) { | |||
if ($orderReductionCart->getUnit() == 'percent') { | |||
$priceToReturn = $this->applyReductionPercent( | |||
$priceToReturn, | |||
$orderReductionCart->getValue | |||
); | |||
} else if ($orderReductionCart->getUnit() == 'amount') { | |||
if ($orderReductionCart->getBehaviorTaxRate() == 'tax-inlcluded') { | |||
$priceToReturn = | |||
$this->applyReductionAmount( | |||
$priceToReturn, | |||
$orderReductionCart->getValue() | |||
); | |||
} | |||
} | |||
} | |||
} | |||
public function getTotalOrderProducts($entity) | |||
{ | |||
return $this->getSumOrderProductsDispatch($entity); | |||
} | |||
public function getTotalOrderProductsWithTax($entity) | |||
{ | |||
return $this->getSumOrderProductsDispatch($entity, true); | |||
} | |||
public function getTotalOrderProductsWithReduction($entity) | |||
{ | |||
return $this->getTotalOrderProductsWithReductionCatalog($entity); | |||
} | |||
public function getTotalOrderProductsWithTaxAndReduction($entity) | |||
{ | |||
return $this->getTotalOrderProductsWithTaxAndReductionCatalog($entity); | |||
} | |||
public function getTotalOrderProductsWithReductionCatalog($entity) | |||
{ | |||
return $this->getSumOrderProductsDispatch($entity, false, true); | |||
} | |||
public function getTotalOrderProductsWithTaxAndReductionCatalog($entity) | |||
{ | |||
return $this->getSumOrderProductsDispatch($entity, true, true); | |||
} | |||
public function getSumOrderProductsDispatch($entity, $withTax = false, $withReductionCatalog = false) | |||
{ | |||
if ($entity instanceof OrderShopInterface) { | |||
return $this->getSumOrderProducts($entity->getOrderProducts(), $withTax, $withReductionCatalog); | |||
} | |||
if ($entity instanceof Collection || is_array($entity)) { | |||
return $this->getSumOrderProducts($entity, $withTax, $withReductionCatalog); | |||
} | |||
} | |||
public function getSumOrderProducts($orderProducts, $withTax = false, $withReductionCatalog = false) | |||
{ | |||
$total = 0; | |||
foreach ($orderProducts as $orderProduct) { | |||
if ($withTax && $withReductionCatalog) { | |||
$total += $this->getTotalWithTaxAndReduction($orderProduct); | |||
} elseif ($withTax) { | |||
$total += $this->getTotalWithTax($orderProduct); | |||
} elseif ($withReductionCatalog) { | |||
$total += $this->getTotalWithReduction($orderProduct); | |||
} else { | |||
$total += $this->getTotal($orderProduct); | |||
} | |||
} | |||
return $total; | |||
} | |||
public function getPriceWithTaxAndReductionCatalog($entity, $price, $priceWithTax, $reductionCatalog = null) | |||
{ | |||
return $this->getPriceWithReductionCatalogGeneric($entity, $price, $priceWithTax, $reductionCatalog, true); | |||
} | |||
public function getPriceWithReductionCatalog($entity, $price, $priceWithTax, $reductionCatalog = null) | |||
{ | |||
return $this->getPriceWithReductionCatalogGeneric($entity, $price, $priceWithTax, $reductionCatalog, false); | |||
} | |||
public function getPriceWithReductionCatalogGeneric($entity, $price, $priceWithTax, $reductionCatalog = null, $withTax = true): ?float | |||
{ | |||
if ($reductionCatalog) { | |||
$reductionCatalogValue = $reductionCatalog->getValue(); | |||
$reductionCatalogUnit = $reductionCatalog->getUnit(); | |||
$reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate(); | |||
} else { | |||
if ($entity instanceof ProductPropertyInterface) { | |||
$reductionCatalog = $entity->getReductionCatalogInherited(); | |||
if ($reductionCatalog) { | |||
$reductionCatalogValue = $reductionCatalog->getValue(); | |||
$reductionCatalogUnit = $reductionCatalog->getUnit(); | |||
$reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate(); | |||
} | |||
} | |||
if ($entity instanceof OrderProductInterface) { | |||
$orderProductReductionCatalog = $entity->getOrderProductReductionCatalog(); | |||
if ($orderProductReductionCatalog) { | |||
$reductionCatalogValue = $orderProductReductionCatalog->getValue(); | |||
$reductionCatalogUnit = $orderProductReductionCatalog->getUnit(); | |||
$reductionCatalogBehaviorTaxRate = $orderProductReductionCatalog->getBehaviorTaxRate(); | |||
} | |||
} | |||
} | |||
if (isset($reductionCatalogValue) && isset($reductionCatalogUnit) && isset($reductionCatalogBehaviorTaxRate)) { | |||
if ($reductionCatalogUnit == 'percent') { | |||
$priceWithTax = $this->applyReductionPercent( | |||
$priceWithTax, | |||
$reductionCatalogValue | |||
); | |||
} elseif ($reductionCatalogUnit == 'amount') { | |||
if ($reductionCatalogBehaviorTaxRate == 'tax-excluded') { | |||
$priceWithTax = $this->applyTax( | |||
$this->applyReductionAmount( | |||
$price, | |||
$reductionCatalogValue | |||
), | |||
$entity->getTaxRateInherited()->getValue() | |||
); | |||
} elseif ($reductionCatalogBehaviorTaxRate == 'tax-included') { | |||
$priceWithTax = $this->applyReductionAmount( | |||
$priceWithTax, | |||
$reductionCatalogValue | |||
); | |||
} | |||
} | |||
} | |||
if ($withTax) { | |||
$priceReturn = $priceWithTax; | |||
} else { | |||
$priceReturn = $this->applyPercentNegative($priceWithTax, $entity->getTaxRateInherited()->getValue()); | |||
} | |||
return $this->round($priceReturn); | |||
} | |||
public function getTotalTaxes($entity) | |||
{ | |||
if ($entity instanceof OrderProductInterface) { | |||
return $this->getTotalWithReduction($entity) * ($entity->getTaxRateInherited()->getValue() / 100); | |||
} | |||
if ($entity instanceof OrderShopInterface) { | |||
$totalTaxes = 0; | |||
foreach ($entity->getOrderProducts() as $orderProduct) { | |||
$totalTaxes += $this->getTotalTaxes($orderProduct); | |||
} | |||
return $totalTaxes; | |||
} | |||
return 0; | |||
} | |||
public function applyTax($price, $taxRateValue) | |||
{ | |||
return $this->round($this->applyPercent($price, $taxRateValue)); | |||
} | |||
public function applyReductionPercent($price, $percentage) | |||
{ | |||
return $this->applyPercent($price, -$percentage); | |||
} | |||
public function applyReductionAmount($price, $amount) | |||
{ | |||
return $price - $amount; | |||
} | |||
public function applyPercent($price, $percentage) | |||
{ | |||
return $price * ($percentage / 100 + 1); | |||
} | |||
public function applyPercentNegative($price, $percentage) | |||
{ | |||
return $price / ($percentage / 100 + 1); | |||
} | |||
public function round($price) | |||
{ | |||
return round((($price * 100)) / 100, 2); | |||
} | |||
} | |||
@@ -2,16 +2,24 @@ | |||
namespace Lc\ShopBundle\Services ; | |||
use App\Entity\Product; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\ShopBundle\Context\PriceUtilsInterface; | |||
use Lc\ShopBundle\Context\ProductCategoryInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyInterface; | |||
use Lc\ShopBundle\Context\ProductInterface; | |||
use Lc\ShopBundle\Context\ReductionCatalogInterface; | |||
use Lc\ShopBundle\Model\ProductFamily; | |||
class ProductFamilyUtils | |||
{ | |||
protected $priceUtils ; | |||
protected $em ; | |||
public function __construct(PriceUtilsInterface $priceUtils) | |||
public function __construct(PriceUtilsInterface $priceUtils, EntityManagerInterface $em) | |||
{ | |||
$this->priceUtils = $priceUtils ; | |||
$this->em = $em; | |||
} | |||
public function getCheapestProduct($productFamily) | |||
@@ -40,10 +48,14 @@ class ProductFamilyUtils | |||
private function getCheapestOrMostExpensiveProduct($productFamily, $comparisonFunction, $returnSelfIfNotActiveProducts) | |||
{ | |||
$products = $productFamily->getProductsOnline()->getValues() ; | |||
if (count($products) > 0) { | |||
usort($products, $comparisonFunction); | |||
return $products[0]; | |||
if($productFamily->getActiveProducts()) { | |||
$products = $productFamily->getProductsOnline()->getValues(); | |||
if (count($products) > 0) { | |||
usort($products, $comparisonFunction); | |||
return $products[0]; | |||
} | |||
}else{ | |||
return $productFamily->getOriginProduct(); | |||
} | |||
if ($returnSelfIfNotActiveProducts) { | |||
return $productFamily; | |||
@@ -53,4 +65,110 @@ class ProductFamilyUtils | |||
} | |||
} | |||
public function processBeforePersistProductFamily($productFamily, $editForm=false, $clone =false){ | |||
if($editForm){ | |||
$this->processReductionCatalog($productFamily, $editForm); | |||
$this->processCategories($productFamily); | |||
} | |||
$this->processProducts($productFamily, $clone); | |||
$this->processPrice($productFamily); | |||
return $productFamily; | |||
} | |||
protected function processReductionCatalog($entity, $editForm) | |||
{ | |||
$reductionCatalog = $editForm->get('reductionCatalog')->getData(); | |||
if ($reductionCatalog instanceof ReductionCatalogInterface) { | |||
if ($reductionCatalog->getValue() && $reductionCatalog->getBehaviorTaxRate() && $reductionCatalog->getUnit()) { | |||
$reductionCatalog->setMerchant($entity->getMerchant()); | |||
$reductionCatalog->setStatus($editForm->get('activeReductionCatalog')->getData()); | |||
$reductionCatalog->setProductFamily($entity); | |||
$this->em->persist($reductionCatalog); | |||
} | |||
} | |||
} | |||
protected function processPrice($entity) | |||
{ | |||
if ($entity->getBehaviorPrice() == 'by-piece') { | |||
$entity->setPriceByRefUnit(null); | |||
$entity->setBuyingPriceByRefUnit(null); | |||
} else if ($entity->getBehaviorPrice() == 'by-reference-unit') { | |||
$entity->setPrice(null); | |||
$entity->setBuyingPrice(null); | |||
} | |||
} | |||
protected function processProducts($entity, $clone = false) | |||
{ | |||
if($clone) { | |||
foreach ($entity->getProducts() as $i => $product) { | |||
$newProduct = clone $product; | |||
$newProduct->setProductFamily($entity); | |||
$this->em->persist($newProduct); | |||
$entity->addProduct($newProduct); | |||
} | |||
}else { | |||
//Récupère le product origin | |||
$originProducts = $this->em->getRepository(ProductInterface::class)->findBy(array( | |||
'productFamily' => $entity->getId(), | |||
'originProduct' => true | |||
)); | |||
if (count($originProducts) > 1) { | |||
throw new \ErrorException('Plusieurs OriginProduct pour un même produit... Contacter fab'); | |||
// Case Nouveau product family | |||
} else if (count($originProducts) == 0) { | |||
$originProduct = new Product(); | |||
$originProduct->setProductFamily($entity); | |||
$originProduct->setOriginProduct(true); | |||
$entity->addProduct($originProduct); | |||
} else { | |||
$originProduct = $originProducts[0]; | |||
} | |||
if ($entity->getActiveProducts()) { | |||
$originProduct->setStatus(-1); | |||
} else { | |||
$originProduct->setStatus(1); | |||
} | |||
//Enregistrement | |||
$entity->addProduct($originProduct); | |||
foreach ($entity->getProducts() as $product) { | |||
$product->setProductFamily($entity); | |||
$this->em->persist($product); | |||
$entity->addProduct($product); | |||
} | |||
} | |||
} | |||
protected function processCategories(ProductFamilyInterface $entity) | |||
{ | |||
$productCategoryRepository = $this->em->getRepository(ProductCategoryInterface::class); | |||
$productCategories = $entity->getProductCategories(); | |||
$entity->initProductCategories(); | |||
foreach ($productCategories as $key => $bool) { | |||
if (is_bool($bool) && $bool) { | |||
if (strpos($key, 'category_children_') !== false) { | |||
$idCategory = (int)str_replace('category_children_', '', $key); | |||
} else { | |||
$idCategory = (int)str_replace('category_', '', $key); | |||
} | |||
$category = $productCategoryRepository->find($idCategory); | |||
$entity->addProductCategory($category); | |||
} | |||
} | |||
} | |||
} |
@@ -8,19 +8,23 @@ use Lc\ShopBundle\Context\MerchantUtilsInterface; | |||
use Lc\ShopBundle\Context\OrderShopInterface; | |||
use Lc\ShopBundle\Context\TicketInterface; | |||
use Lc\ShopBundle\Context\TicketMessageInterface; | |||
use Lc\ShopBundle\Context\UserInterface; | |||
use Lc\ShopBundle\Model\Ticket; | |||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; | |||
class TicketUtils | |||
{ | |||
protected $em ; | |||
protected $merchantUtils ; | |||
protected $mailUtils ; | |||
protected $authorizationChecker ; | |||
public function __construct(EntityManagerInterface $em, MerchantUtilsInterface $merchantUtils, MailUtils $mailUtils) | |||
public function __construct(EntityManagerInterface $em, MerchantUtilsInterface $merchantUtils, MailUtils $mailUtils, AuthorizationCheckerInterface $authorizationChecker) | |||
{ | |||
$this->em = $em ; | |||
$this->merchantUtils = $merchantUtils ; | |||
$this->mailUtils = $mailUtils ; | |||
$this->authorizationChecker = $authorizationChecker ; | |||
} | |||
public function createTicket($params): TicketInterface | |||
@@ -74,6 +78,9 @@ class TicketUtils | |||
], | |||
]) ; | |||
$this->notifyAdmin($ticket, $ticketMessage); | |||
return $ticket ; | |||
} | |||
@@ -114,5 +121,30 @@ class TicketUtils | |||
return $ticketMessage ; | |||
} | |||
public function notifyAdmin($ticket, $ticketMessage){ | |||
$userRepo = $this->em->getRepository(UserInterface::class); | |||
$usersToNotify = $userRepo->findByTicketTypesNotification($ticket->getType()); | |||
foreach ($usersToNotify as $userToNotify){ | |||
if($this->authorizationChecker->isGranted('ROLE_ADMIN', $userToNotify)){ | |||
// envoi email au client | |||
$this->mailUtils->send([ | |||
MailUtils::SUBJECT => 'Nouveau ticket sur placedulocal', | |||
MailUtils::TO_EMAIL => $userToNotify->getEmail(), | |||
MailUtils::CONTENT_TEMPLATE => 'mail/ticket-notification', | |||
MailUtils::CONTENT_DATA => [ | |||
'firstname' => $userToNotify->getFirstname(), | |||
'ticket' => $ticket, | |||
'ticketMessage' => $ticketMessage | |||
], | |||
]) ; | |||
} | |||
} | |||
} | |||
} | |||
@@ -105,4 +105,4 @@ class UserUtils | |||
$this->em->flush() ; | |||
} | |||
} | |||
} |
@@ -5,9 +5,16 @@ namespace Lc\ShopBundle\Services; | |||
use Cocur\Slugify\Slugify; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use EasyCorp\Bundle\EasyAdminBundle\Configuration\ConfigManager; | |||
use Geocoder\Model\Coordinates; | |||
use Geocoder\Provider\Addok\Addok; | |||
use Geocoder\Query\GeocodeQuery; | |||
use Geocoder\Query\ReverseQuery; | |||
use Lc\ShopBundle\Context\ImageInterface; | |||
use Lc\ShopBundle\Context\MerchantUtilsInterface; | |||
use Lc\ShopBundle\Context\PageInterface; | |||
use Lc\ShopBundle\Context\PointSaleInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyUtilsInterface; | |||
use Lc\ShopBundle\Context\ReminderInterface; | |||
use Lc\ShopBundle\Context\TaxRateInterface; | |||
use Lc\ShopBundle\Context\UnitInterface; | |||
@@ -15,6 +22,7 @@ use Lc\ShopBundle\Context\UserInterface; | |||
use Lc\ShopBundle\Context\UserPointSaleInterface; | |||
use Liip\ImagineBundle\Imagine\Cache\CacheManager; | |||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; | |||
use Symfony\Component\HttpClient\HttplugClient; | |||
use Symfony\Component\HttpFoundation\ParameterBag; | |||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | |||
use Symfony\Contracts\Translation\TranslatorInterface; | |||
@@ -255,6 +263,29 @@ class Utils | |||
return $result; | |||
} | |||
public function getGeocoderProvider() | |||
{ | |||
$symfonyClient = new HttplugClient(); | |||
$provider = new Addok($symfonyClient, 'https://api-adresse.data.gouv.fr') ; | |||
return $provider ; | |||
} | |||
public function callAddressApi($query) | |||
{ | |||
$provider = $this->getGeocoderProvider() ;; | |||
$query = GeocodeQuery::create($query)->withData('type', 'housenumber'); | |||
$results = $provider->geocodeQuery($query); | |||
return $results->all() ; | |||
} | |||
public function callReverseAddressApi($latitude, $longitude) | |||
{ | |||
$provider = $this->getGeocoderProvider() ;; | |||
$query = ReverseQuery::create(new Coordinates($latitude, $longitude)); | |||
$results = $provider->reverseQuery($query); | |||
return $results->all() ; | |||
} | |||
public function getZipByCity($city, $code = null) | |||
{ | |||
$zip = null; | |||
@@ -474,4 +505,7 @@ class Utils | |||
return $this->parameterBag->get('app.path.images'); | |||
} | |||
} |
@@ -3,11 +3,13 @@ | |||
namespace Lc\ShopBundle\Services ; | |||
use Lc\ShopBundle\Context\DeliveryUtilsInterface; | |||
use Lc\ShopBundle\Context\DocumentUtilsInterface; | |||
use Lc\ShopBundle\Context\MerchantUtilsInterface; | |||
use Lc\ShopBundle\Context\OrderUtilsInterface; | |||
use Lc\ShopBundle\Context\PriceUtilsInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyUtilsInterface; | |||
use Lc\ShopBundle\Context\Services\StatisticsUtilsInterface; | |||
use League\Flysystem\Util; | |||
class UtilsManager | |||
{ | |||
@@ -23,6 +25,7 @@ class UtilsManager | |||
protected $mailUtils ; | |||
protected $ticketUtils ; | |||
protected $statisticsUtils; | |||
protected $pointLocationUtils ; | |||
public function __construct( | |||
Utils $utils, | |||
@@ -33,9 +36,11 @@ class UtilsManager | |||
PriceUtilsInterface $priceUtils, | |||
DeliveryUtilsInterface $deliveryUtils, | |||
CreditUtils $creditUtils, | |||
DocumentUtils $documentUtils, | |||
DocumentUtilsInterface $documentUtils, | |||
MailUtils $mailUtils, | |||
TicketUtils $ticketUtils | |||
TicketUtils $ticketUtils, | |||
PointLocationUtils $pointLocationUtils, | |||
UtilsProcess $utilsProcess | |||
) | |||
{ | |||
$this->utils = $utils ; | |||
@@ -49,6 +54,8 @@ class UtilsManager | |||
$this->documentUtils = $documentUtils ; | |||
$this->mailUtils = $mailUtils ; | |||
$this->ticketUtils = $ticketUtils ; | |||
$this->pointLocationUtils = $pointLocationUtils ; | |||
$this->utilsProcess = $utilsProcess ; | |||
} | |||
public function getUtils(): Utils | |||
@@ -91,7 +98,7 @@ class UtilsManager | |||
return $this->creditUtils ; | |||
} | |||
public function getDocumentUtils(): DocumentUtils | |||
public function getDocumentUtils(): DocumentUtilsInterface | |||
{ | |||
return $this->documentUtils ; | |||
} | |||
@@ -106,4 +113,14 @@ class UtilsManager | |||
return $this->ticketUtils ; | |||
} | |||
public function getPointLocationUtils(): PointLocationUtils | |||
{ | |||
return $this->pointLocationUtils ; | |||
} | |||
public function getUtilsProcess(): UtilsProcess | |||
{ | |||
return $this->utilsProcess ; | |||
} | |||
} |
@@ -0,0 +1,111 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Services; | |||
use Cocur\Slugify\Slugify; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use EasyCorp\Bundle\EasyAdminBundle\Configuration\ConfigManager; | |||
use Geocoder\Model\Coordinates; | |||
use Geocoder\Provider\Addok\Addok; | |||
use Geocoder\Query\GeocodeQuery; | |||
use Geocoder\Query\ReverseQuery; | |||
use Lc\ShopBundle\Context\ImageInterface; | |||
use Lc\ShopBundle\Context\MerchantUtilsInterface; | |||
use Lc\ShopBundle\Context\PageInterface; | |||
use Lc\ShopBundle\Context\PointSaleInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyUtilsInterface; | |||
use Lc\ShopBundle\Context\ReminderInterface; | |||
use Lc\ShopBundle\Context\SluggableInterface; | |||
use Lc\ShopBundle\Context\TaxRateInterface; | |||
use Lc\ShopBundle\Context\UnitInterface; | |||
use Lc\ShopBundle\Context\UserInterface; | |||
use Lc\ShopBundle\Context\UserPointSaleInterface; | |||
use Liip\ImagineBundle\Imagine\Cache\CacheManager; | |||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; | |||
use Symfony\Component\HttpClient\HttplugClient; | |||
use Symfony\Component\HttpFoundation\ParameterBag; | |||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | |||
use Symfony\Contracts\Translation\TranslatorInterface; | |||
class UtilsProcess | |||
{ | |||
protected $em; | |||
protected $parameterBag; | |||
protected $merchantUtils; | |||
protected $productFamilyUtils; | |||
public function __construct(EntityManagerInterface $em, ParameterBagInterface $parameterBag, ProductFamilyUtilsInterface $productFamilyUtils) | |||
{ | |||
$this->em = $em; | |||
$this->parameterBag = $parameterBag; | |||
$this->productFamilyUtils = $productFamilyUtils; | |||
} | |||
public function duplicateEntity($entity, $flush = true) | |||
{ | |||
$newEntity = clone $entity; | |||
if ($newEntity instanceof ImageInterface) { | |||
$newEntity = $this->duplicateImage($newEntity); | |||
} | |||
if ($newEntity instanceof ProductFamilyInterface) { | |||
$newEntity = $this->productFamilyUtils->processBeforePersistProductFamily($newEntity, false, true); | |||
} | |||
if(method_exists($newEntity, 'getAddress') && is_object($newEntity->getAddress())){ | |||
$address = $newEntity->getAddress(); | |||
$newAddress = $this->duplicateEntity($address); | |||
$newEntity->setAddress($newAddress); | |||
$this->em->persist($newAddress); | |||
} | |||
if($newEntity instanceof SluggableInterface){ | |||
$this->em->persist($newEntity); | |||
if($flush)$this->em->flush(); | |||
$newEntity->setSlug(null); | |||
} | |||
$this->em->persist($newEntity); | |||
if($flush)$this->em->flush(); | |||
return $newEntity; | |||
} | |||
public function duplicateEntityToOtherHub($entity, $hub){ | |||
$newEntity = $this->duplicateEntity($entity); | |||
if ($hub) { | |||
$newEntity->setMerchant($hub); | |||
} | |||
$this->em->persist($newEntity) ; | |||
$this->em->flush() ; | |||
return $newEntity; | |||
} | |||
public function duplicateImage($entity, $folder = false) | |||
{ | |||
$basePath = $this->parameterBag->get('kernel.project_dir') . '/public/uploads/images/'; | |||
if ($entity->getImage() && file_exists($basePath . $entity->getImage())) { | |||
$extension = (pathinfo($basePath . $entity->getImage(), PATHINFO_EXTENSION)); | |||
if ($extension == "jpg" || $extension == "png" || $extension == "gif") { | |||
$newImage = md5(uniqid()) . '.' . $extension; | |||
if ($folder) $newImage = $folder . '/' . $newImage; | |||
copy($basePath . $entity->getImage(), $basePath . $newImage); | |||
$entity->setImage($newImage); | |||
} | |||
} else { | |||
$entity->setImage(null); | |||
} | |||
return $entity; | |||
} | |||
} |
@@ -13,6 +13,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; | |||
use Symfony\Component\Form\FormFactoryInterface; | |||
use Symfony\Component\HttpFoundation\RequestStack; | |||
use Symfony\Component\HttpKernel\KernelInterface; | |||
use Symfony\Component\Routing\RouterInterface; | |||
use Symfony\Component\Security\Core\Security; | |||
use Twig\Extension\AbstractExtension; | |||
use Twig\TwigFilter; | |||
@@ -31,9 +32,11 @@ class FrontendTwigExtension extends AbstractExtension | |||
protected $liipCacheHelper; | |||
protected $parameterBag; | |||
protected $kernel; | |||
protected $router ; | |||
public function __construct(EntityManagerInterface $em, Security $security, MerchantUtilsInterface $merchantUtils, | |||
FormFactoryInterface $formFactory, RequestStack $requestStack, ParameterBagInterface $parameterBag, KernelInterface $kernel) | |||
FormFactoryInterface $formFactory, RequestStack $requestStack, ParameterBagInterface $parameterBag, | |||
KernelInterface $kernel, RouterInterface $router) | |||
{ | |||
$this->em = $em; | |||
$this->security = $security; | |||
@@ -45,6 +48,7 @@ class FrontendTwigExtension extends AbstractExtension | |||
$this->productFamilyRepository = $this->em->getRepository($this->em->getClassMetadata(ProductFamilyInterface::class)->getName()); | |||
$this->parameterBag = $parameterBag; | |||
$this->kernel = $kernel; | |||
$this->router = $router ; | |||
} | |||
public function getFunctions() |