src/Controller/SalesTemplateController.php line 669

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Constant;
  4. use App\Entity\Idempiere\AdOrg;
  5. use App\Entity\Idempiere\AdRole;
  6. use App\Entity\Idempiere\AdUser;
  7. use App\Entity\Idempiere\AdWindowAccess;
  8. use App\Entity\Idempiere\CBpartner;
  9. use App\Entity\Idempiere\CBpartnerLocation;
  10. use App\Entity\Idempiere\CDoctype;
  11. use App\Entity\Idempiere\CPaymentterm;
  12. use App\Entity\Idempiere\MPricelist;
  13. use App\Entity\Idempiere\MWarehouse;
  14. use App\Entity\Idempiere\SmMarca;
  15. use App\Entity\Idempiere\SmSalestemplate;
  16. use App\Entity\Idempiere\SmSalestemplateline;
  17. use App\Form\IdempiereType\SalesTemplateLineType;
  18. use App\Form\IdempiereType\SalesTemplateType;
  19. use App\LocalSalesTemplate\Application\useCase\GetLocalSalesTemplateBySalesTemplate;
  20. use App\LocalSalesTemplate\Infrastructure\Persistence\Doctrine\Order\LocalSalesTemplateRepository;
  21. use App\Repository\Idempiere\AdOrginfoRepository;
  22. use App\Repository\Idempiere\AdOrgRepository;
  23. use App\Repository\Idempiere\AdSequenceRepository;
  24. use App\Repository\Idempiere\AdUserRepository;
  25. use App\Repository\Idempiere\CBpartnerLocationRepository;
  26. use App\Repository\Idempiere\CBpartnerRepository;
  27. use App\Repository\Idempiere\CDoctypeRepository;
  28. use App\Repository\Idempiere\CPaymenttermRepository;
  29. use App\Repository\Idempiere\MPricelistRepository;
  30. use App\Repository\Idempiere\MWarehouseRepository;
  31. use App\Repository\Idempiere\SmMarcaRepository;
  32. use App\Repository\Idempiere\SmSalestemplateRepository;
  33. use App\Service\SalesTemplateService;
  34. use App\Shared\Infraestructure\Idempiere\IdempiereRestClient;
  35. use DateTime;
  36. use Doctrine\ORM\Exception\ORMException;
  37. use Doctrine\Persistence\ManagerRegistry;
  38. use Psr\Log\LoggerInterface;
  39. use Jaxon\AjaxBundle\Jaxon;
  40. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  41. use Symfony\Component\HttpFoundation\JsonResponse;
  42. use Symfony\Component\HttpFoundation\Request;
  43. use Symfony\Component\HttpFoundation\RequestStack;
  44. use Symfony\Component\HttpFoundation\Response;
  45. use Symfony\Component\Routing\Annotation\Route;
  46. use Symfony\Component\Security\Core\Security;
  47. use Symfony\Contracts\Translation\TranslatorInterface;
  48. /**
  49. * @Route("/plantilla")
  50. */
  51. Class SalesTemplateController extends BaseController
  52. {
  53. public int $windowID = 1000174;
  54. public int $processID = 273;
  55. private SalesTemplateService $salesTemplateService;
  56. private AdWindowAccess $windowAccess;
  57. public function __construct(
  58. RequestStack $requestStack, Security $security,
  59. SalesTemplateService $salesTemplateService,
  60. ManagerRegistry $manager,
  61. private LocalSalesTemplateRepository $repo
  62. )
  63. {
  64. parent::__construct($requestStack, $security);
  65. /** @var AdRole */
  66. $role = $this->session->get('role', null);
  67. $windowAccess = $this->WindowAccess($manager, $this->windowID, $role->getId());
  68. if( is_null($windowAccess) || !$windowAccess->isActive() )
  69. return $this->redirectToRoute('app_dashboard');
  70. $this->windowAccess = $windowAccess;
  71. $this->salesTemplateService = $salesTemplateService;
  72. }
  73. /**
  74. * Ruta para eliminar una plantilla
  75. * @Route("/{id}/borrar", name="app_salestemplate_delete")
  76. *
  77. * @param SmSalestemplate $SalesTemplate Sales Template
  78. * @param ManagerRegistry $manager Doctrine Manager
  79. *
  80. * @return Response HTTP Response
  81. */
  82. public function delete(SmSalestemplate $SalesTemplate, ManagerRegistry $manager): Response
  83. {
  84. /**
  85. * Session Var
  86. */
  87. $session = $this->requestStack->getSession();
  88. /** @var AdUser */
  89. $user = $this->security->getUser();
  90. /** @var AdRole */
  91. // $role = $this->session->get('role');
  92. $role = $session->get('role');
  93. $access = $this->WindowAccess($manager, $this->windowID, $role->getId());
  94. if( is_null($access) || !$access->isActive() || !$access->isReadWrite() )
  95. return $this->redirectToRoute('app_dashboard');
  96. ######################################################################
  97. try {
  98. $SalesTemplate->setIsactive(false);
  99. $em = $manager->getManagerForClass(SmSalestemplate::class);
  100. $em->persist($SalesTemplate);
  101. $em->flush();
  102. } catch (ORMException $e) {
  103. return new JsonResponse(['status' => 'error', 'msg' => $e]);
  104. }
  105. return $this->redirectToRoute('app_salestemplate');
  106. }
  107. /**
  108. * Ruta para editar una plantilla
  109. * @Route("/{id}/editar", name="app_salestemplate_edit")
  110. *
  111. * @param SmSalestemplate $SalesTemplate Sales Template
  112. * @param Request $request HTTP Request
  113. * @param ManagerRegistry $manager Doctrine Manager
  114. * @param Jaxon $jaxon Jaxon Request Handler
  115. * @param TranslatorInterface $translator Translator
  116. *
  117. * @return Response HTTP Response
  118. */
  119. public function edit(
  120. SmSalestemplate $SalesTemplate
  121. , Request $request
  122. , ManagerRegistry $manager
  123. , Jaxon $jaxon
  124. , TranslatorInterface $translator
  125. ): Response
  126. {
  127. return $this->redirectToRoute('app_salestemplate_view', ['id' => $SalesTemplate->getId()]);
  128. /**
  129. * Session Var
  130. */
  131. // 1.-Ubicar el localsalestemplate asociado
  132. $useCase = new GetLocalSalesTemplateBySalesTemplate($this->repo);
  133. $local = $useCase->execute($SalesTemplate->getId());
  134. if (!$local) {
  135. dd(
  136. $local
  137. , "No se puede editar no viene de plantilla local"
  138. , $SalesTemplate
  139. );
  140. }
  141. // 2.-Verificar que la plantilla solo este en "NA"
  142. // 3.-Poner la plantilla en "DR" solo si esta "NA"
  143. /** @var AdUser */
  144. $user = $this->security->getUser();
  145. /** @var AdRole */
  146. $role = $this->session->get('role');
  147. $access = $this->WindowAccess($manager, $this->windowID, $role->getId());
  148. if( is_null($access) || !$access->isActive() || !$access->isReadWrite() )
  149. return $this->redirectToRoute('app_dashboard');
  150. ######################################################################
  151. $form = $this->createForm(SalesTemplateType::class, $SalesTemplate, [
  152. 'action' => $this->generateUrl('app_salestemplate_edit', ['id' => $SalesTemplate->getId()]),
  153. 'method' => 'POST'
  154. ]);
  155. //
  156. $ROrg = new AdOrgRepository($manager);
  157. $form->add('ad_org', EntityType::class, [
  158. 'class' => AdOrg::class,
  159. 'label' => 'Organization',
  160. 'choices' => $ROrg->findBy(['ad_org_id' => $SalesTemplate->getAdOrgId()]),
  161. 'choice_label' => 'name',
  162. 'row_attr' => [
  163. 'class' => 'd-none'
  164. ]
  165. ]);
  166. //
  167. $RMarca = new SmMarcaRepository($manager);
  168. $form->add('sm_marca', EntityType::class, [
  169. 'class' => SmMarca::class,
  170. 'label' => 'Brand',
  171. 'choices' => $RMarca->findBy(['sm_marca_id' => $SalesTemplate->getSmMarcaId()]),
  172. 'choice_label' => 'name',
  173. 'attr' => [
  174. 'class' => 'form-control',
  175. 'readonly' => true
  176. ]
  177. ]);
  178. //
  179. $RBPartner = new CBpartnerRepository($manager);
  180. $form->add('c_bpartner', EntityType::class, [
  181. 'class' => CBpartner::class,
  182. 'choices' => $RBPartner->findBy(['c_bpartner_id' => $SalesTemplate->getCBpartnerId()]),
  183. 'choice_label' => 'name',
  184. // HTLM Attribute
  185. 'label' => 'Customer.S',
  186. 'attr' => [
  187. 'class' => 'form-control',
  188. 'readonly' => true
  189. ]
  190. ]);
  191. //
  192. $RBPartner = new CBpartnerLocationRepository($manager);
  193. $form->add('c_bpartner_location', EntityType::class, [
  194. 'class' => CBpartnerLocation::class,
  195. 'choices' => $RBPartner->findBy(['c_bpartner_location_id' => $SalesTemplate->getCBpartnerLocationId()]),
  196. 'choice_label' => 'name',
  197. // HTLM Attribute
  198. 'label' => 'Address.S',
  199. 'attr' => [
  200. 'class' => 'form-control',
  201. 'readonly' => true
  202. ]
  203. ]);
  204. $form->add('bill_location', EntityType::class, [
  205. 'class' => CBpartnerLocation::class,
  206. 'choices' => $RBPartner->findBy(['c_bpartner_location_id' => $SalesTemplate->getBillLocationId()]),
  207. 'choice_label' => 'name',
  208. // HTML Attribute
  209. 'label' => 'Address.Invoice',
  210. 'attr' => [
  211. 'class' => 'form-control',
  212. 'readonly' => true
  213. ]
  214. ]);
  215. //
  216. $RDoctype = new CDoctypeRepository($manager);
  217. $form->add('c_doctype', EntityType::class, [
  218. 'class' => CDoctype::class,
  219. 'choices' => $RDoctype->findBy(['c_doctype_id' => $SalesTemplate->getCDoctypeId()]),
  220. 'choice_label' => 'name',
  221. // HTLM Attribute
  222. 'label' => 'DocType',
  223. 'attr' => [
  224. 'class' => 'form-control',
  225. 'readonly' => true
  226. ]
  227. ]);
  228. //
  229. $RPaymentterm = new CPaymenttermRepository($manager);
  230. $form->add('c_paymentterm', EntityType::class, [
  231. 'class' => CPaymentterm::class,
  232. 'choices' => $RPaymentterm->findBy(['c_paymentterm_id' => $SalesTemplate->getCPaymenttermId()]),
  233. 'choice_label' => 'name',
  234. // HTLM Attribute
  235. 'label' => 'Payment.Term',
  236. 'attr' => [
  237. 'class' => 'form-control',
  238. 'readonly' => true
  239. ]
  240. ]);
  241. //
  242. $RPricelist = new MPricelistRepository($manager);
  243. $form->add('m_pricelist', EntityType::class, [
  244. 'class' => MPricelist::class,
  245. 'choices' => $RPricelist->findBy(['m_pricelist_id' => $SalesTemplate->getMPricelistId()]),
  246. 'choice_label' => 'name',
  247. // HTLM Attribute
  248. 'label' => 'PriceList',
  249. 'attr' => [
  250. 'class' => 'form-control',
  251. 'readonly' => true
  252. ]
  253. ]);
  254. //
  255. $RWarehouse = new MWarehouseRepository($manager);
  256. $form->add('m_warehouse', EntityType::class, [
  257. 'class' => MWarehouse::class,
  258. 'label' => 'Warehouse',
  259. 'choices' => $RWarehouse->findBy([
  260. 'ad_org_id' => $SalesTemplate->getAdOrgId(),
  261. 'isactive' => 'Y',
  262. 'isdefault' => 'Y'
  263. ]),
  264. 'choice_label' => 'name',
  265. 'row_attr' => [
  266. 'class' => 'd-none'
  267. ]
  268. ]);
  269. //
  270. $RUser = new AdUserRepository($manager);
  271. $form->add('salesrep', EntityType::class, [
  272. 'class' => AdUser::class,
  273. 'choices' => $RUser->findBy(['ad_user_id' => $SalesTemplate->getSalesrepId()]),
  274. 'choice_label' => 'name',
  275. // HTML Attribute
  276. 'label' => 'Sales.Rep',
  277. 'attr' => [
  278. 'class' => 'form-control',
  279. 'readonly' => true
  280. ]
  281. ]);
  282. ######################################################################
  283. $form->handleRequest($request);
  284. if ( $form->isSubmitted() && $form->isValid() ) {
  285. try {
  286. $SalesTemplate
  287. ->setUpdated( new DateTime('now') )
  288. ->setUpdatedby( $user->getId() );
  289. $em = $manager->getManagerForClass(SmSalestemplate::class);
  290. $em->persist($SalesTemplate);
  291. $em->flush();
  292. } catch (ORMException $e) {
  293. return new JsonResponse(['status' => 'FAIL', 'msg' => $e]);
  294. }
  295. }
  296. ######################################################################
  297. $SalesTemplateLine = new SmSalestemplateline();
  298. $SalesTemplateLine->setParent( $SalesTemplate );
  299. $formline = $this->createForm(SalesTemplateLineType::class, $SalesTemplateLine, [
  300. 'action' => $this->generateUrl('app_salestemplateline_new'),
  301. 'method' => 'POST'
  302. ]);
  303. ######################################################################
  304. return $this->renderForm('modules/idempiere/salestemplate/editV2.html.twig', [
  305. 'title' => "{$translator->trans('Sales.Templates')} | {$SalesTemplate->getDocumentno()}",
  306. 'modulo' => $translator->trans('Sales.Templates'),
  307. 'breadcrumb' => $SalesTemplate->getDocumentno(),
  308. 'salestemplate' => $SalesTemplate,
  309. 'form' => $form,
  310. 'formline' => $formline,
  311. 'docstatus' => $this->docstatus,
  312. 'docaction' => $this->docaction,
  313. 'priorityrule' => $this->priorityrule,
  314. 'jaxonCss' => $jaxon->css(),
  315. 'jaxonJs' => $jaxon->js(),
  316. 'jaxonScript' => $jaxon->script()
  317. ]);
  318. }
  319. /**
  320. * Ruta para ver una lista con las plantillas de venta
  321. * @Route("/", name="app_salestemplate")
  322. *
  323. * @param Request $request HTTP Request
  324. * @param ManagerRegistry $manager Doctrine Manager
  325. * @param TranslatorInterface $translator Translator
  326. *
  327. * @return Response HTTP Response
  328. */
  329. public function list(Request $request, TranslatorInterface $translator, ManagerRegistry $manager): Response
  330. {
  331. /** @var AdOrg */
  332. $organization = $this->session->get('organization');
  333. $RUser = new AdUserRepository($manager);
  334. $RMarca = new SmMarcaRepository($manager);
  335. /** @var AdUser */
  336. $user = $this->security->getUser();
  337. $userPartner = $user->getCBpartner();
  338. $isSalesRep = $userPartner && $userPartner->IsSalesRep();
  339. return $this->render('modules/idempiere/salestemplate/index.html.twig', [
  340. 'title' => $translator->trans('Sales.Templates'),
  341. 'modulo' => $translator->trans('Sales.Templates'),
  342. 'docstatus' => $this->docstatus,
  343. 'salesreps' => $isSalesRep ? [$user] : $RUser->findSalesrep('', $organization->getId()),
  344. 'marcas' => $RMarca->findBy(['isactive' => 'Y'], ['name' => 'ASC']),
  345. 'access' => $this->windowAccess
  346. ]);
  347. }
  348. /**
  349. * Ruta para crear una plantilla
  350. * @Route("/nuevo", name="app_salestemplate_new")
  351. *
  352. * @param Request $request HTTP Request
  353. * @param Jaxon $jaxon Jaxon Request Handler
  354. * @param ManagerRegistry $manager Doctrine Manager
  355. * @param TranslatorInterface $translator Tranlator
  356. *
  357. * @return Response HTTP Response
  358. */
  359. public function new(Request $request, Jaxon $jaxon, ManagerRegistry $manager, TranslatorInterface $translator): Response
  360. {
  361. if (!$this->windowAccess->isReadWrite())
  362. return $this->redirectToRoute('app_dashboard');
  363. /**
  364. * Get Parameters
  365. */
  366. $BPartner = $request->query->get('bpartner', null);
  367. /** @var AdUser */
  368. $user = $this->security->getUser();
  369. $UserBP = $user->getCBpartner();
  370. $IsSalesRep = false;
  371. if ( !is_null($UserBP) )
  372. $IsSalesRep = $UserBP->IsSalesRep();
  373. ##########################################################################
  374. # TODO: Configure option to use local tables
  375. if ( true ) {
  376. $params = [];
  377. if (!is_null($BPartner))
  378. $params['bpartner'] = $BPartner;
  379. return $this->redirectToRoute('app_t_salestemplate_new', $params);
  380. }
  381. /**
  382. * Build Form
  383. */
  384. $SalesTemplate = new SmSalestemplate();
  385. $SalesTemplate->setIsactive(true);
  386. $form = $this->createForm(SalesTemplateType::class, $SalesTemplate, [
  387. 'action' => $this->generateUrl('app_salestemplate_new'),
  388. 'method' => 'POST'
  389. ]);
  390. //
  391. /** @var AdOrg */
  392. $organization = $this->session->get('organization');
  393. $ROrg = new AdOrgRepository($manager);
  394. $form->add('ad_org', EntityType::class, [
  395. 'class' => AdOrg::class,
  396. 'choices' => $ROrg->findBy(['ad_org_id' => $organization->getId()]),
  397. 'choice_label' => 'name',
  398. // HTLM Attribute
  399. 'label' => 'Organization',
  400. 'attr' => [
  401. 'class' => 'form-control'
  402. ]
  403. ]);
  404. //
  405. $RDoctype = new CDoctypeRepository($manager);
  406. $form->add('c_doctype', EntityType::class, [
  407. 'class' => CDoctype::class,
  408. 'choices' => $RDoctype->findBy(['c_doctype_id' => 1000241]),
  409. 'choice_label' => 'name',
  410. // HTLM Attribute
  411. 'label' => 'DocType',
  412. 'attr' => [
  413. 'class' => 'form-control'
  414. ]
  415. ]);
  416. //
  417. $RUser = new AdUserRepository($manager);
  418. $form->add('salesrep', EntityType::class, [
  419. 'class' => AdUser::class,
  420. 'choices' => $IsSalesRep ? $RUser->findBy(['ad_user_id' => $user->getId()]) : $RUser->findSalesrep('', $organization->getId()),
  421. 'choice_label' => 'name',
  422. // HTML Attribute
  423. 'label' => 'Sales.Rep',
  424. 'attr' => [
  425. 'class' => 'form-control',
  426. 'readonly' => $IsSalesRep
  427. ]
  428. ]);
  429. //
  430. $RPricelist = new MPricelistRepository($manager);
  431. $form->add('m_pricelist', EntityType::class, [
  432. 'class' => MPricelist::class,
  433. 'choices' =>
  434. $RPricelist
  435. ->createQueryBuilder('pl')
  436. ->where("pl.ad_org_id = :org_id AND pl.issopricelist = 'Y' AND pl.isactive = 'Y' AND pl.name NOT LIKE '%Costos Iniciales%'")
  437. ->setParameter('org_id', $organization->getId())
  438. ->getQuery()
  439. ->getResult(),
  440. 'choice_label' => 'name',
  441. // HTLM Attribute
  442. 'label' => 'PriceList',
  443. 'attr' => [
  444. 'class' => 'form-control'
  445. ]
  446. ]);
  447. //
  448. $RWarehouse = new MWarehouseRepository($manager);
  449. $form->add('m_warehouse', EntityType::class, [
  450. 'class' => MWarehouse::class,
  451. 'choices' => $RWarehouse->findBy([
  452. 'ad_org_id' => $organization->getId(),
  453. 'isactive' => 'Y'
  454. ]),
  455. 'choice_label' => 'name',
  456. // HTLM Attribute
  457. 'label' => 'Warehouse',
  458. 'attr' => [
  459. 'class' => 'form-control'
  460. ]
  461. ]);
  462. //
  463. $RPaymentterm = new CPaymenttermRepository($manager);
  464. $form->add('c_paymentterm', EntityType::class, [
  465. 'class' => CPaymentterm::class,
  466. 'choices' => $RPaymentterm->findBy([
  467. 'ad_client_id' => $organization->getAdClientId(),
  468. 'paymenttermusage'=> ['B', 'S'],
  469. 'isactive' => 'Y'
  470. ]),
  471. 'choice_label' => 'name',
  472. // HTLM Attribute
  473. 'label' => 'PaymentTerm',
  474. 'attr' => [
  475. 'class' => 'form-control'
  476. ]
  477. ]);
  478. ##########################################################################
  479. /**
  480. * Validate Form Request
  481. */
  482. $form->handleRequest($request);
  483. if ($form->isSubmitted() && $form->isValid()) {
  484. $RSalesTemplate = new SmSalestemplateRepository(($manager));
  485. $RSequence = new AdSequenceRepository($manager);
  486. $date = new \DateTime("now");
  487. $id = $RSequence->findNextSequence($RSalesTemplate->sequence);
  488. /** @var SmSalestemplate */
  489. $SalesTemplate = $form->getData();
  490. $SalesTemplate
  491. ->setAdClientId( $organization->getAdClientId() )
  492. ->setCreated( $date )
  493. ->setCreatedBy( $user->getId() );
  494. //
  495. $ROrgInfo = new AdOrginfoRepository($manager);
  496. $OrgInfo = $ROrgInfo->findOneBy(['ad_org_id' => $SalesTemplate->getAdOrg()->getId()]);
  497. $SalesTemplate->setSmMarcaId($OrgInfo->getSmMarcaId());
  498. //
  499. $SalesTemplate
  500. ->setIsquatation('Y')
  501. ->setIsapproved('N')
  502. ->setIsapproved2('N')
  503. ->setIsapproved3('N')
  504. // ->setPriorityrule('5')
  505. ->setAdUserId( $SalesTemplate->getSalesrep()->getId() );
  506. //
  507. $SalesTemplate->setDocumentno(
  508. $RSequence->findNextSequence(
  509. $SalesTemplate->getCDoctype()->getAdSequence(),
  510. $SalesTemplate
  511. )
  512. );
  513. //
  514. $RBPartner = new CBpartnerRepository($manager);
  515. $Partner = $RBPartner->find(
  516. $request->request->get('bpartner_id', Constant::C_BPartner_ID)
  517. );
  518. $SalesTemplate->setCBpartner( $Partner );
  519. //
  520. $RBPLocation = new CBpartnerLocationRepository($manager);
  521. $BPLocation = $RBPLocation->find(
  522. $request->request->get('address', Constant::C_BPartner_Location_ID)
  523. );
  524. $SalesTemplate->setCBpartnerLocation( $BPLocation );
  525. //
  526. $SalesTemplate
  527. ->setDocstatus('DR')
  528. ->setDocaction('CO')
  529. ->setSmSalestemplateId( $id )
  530. ->setSmSalestemplateUu( $RSequence->findNextUU() )
  531. ->setProcessed('N')
  532. ->setProcessing('N')
  533. ->setProcessedon(0)
  534. ->setTotallines(0)
  535. ->setUpdated( $date )
  536. ->setUpdatedBy( $user->getId() );
  537. //
  538. try {
  539. $em = $manager->getManagerForClass(SmSalestemplate::class);
  540. $em->persist($SalesTemplate);
  541. $em->flush();
  542. return $this->redirect(
  543. $this->generateUrl('app_salestemplate_edit', ['id' => $SalesTemplate->getId()])
  544. );
  545. } catch (ORMException $e) {
  546. return new JsonResponse(['status' => 'fail', 'msg' => $e]);
  547. }
  548. }
  549. ##########################################################################
  550. return $this->renderForm('modules/idempiere/salestemplate/new.html.twig', [
  551. 'title' => $translator->trans('New.Template'),
  552. 'modulo' => $translator->trans('Template'),
  553. 'breadcrumb' => 'Nuevo',
  554. 'form' => $form,
  555. 'jaxonCss' => $jaxon->css(),
  556. 'jaxonJs' => $jaxon->js(),
  557. 'jaxonScript' => $jaxon->script()
  558. ]);
  559. }
  560. /**
  561. * Ruta para previsualizar el request antes de procesar
  562. * @Route("/{id}/preview-process", name="app_salestemplate_preview_process")
  563. *
  564. * @param SmSalestemplate $SalesTemplate Plantilla de Venta
  565. *
  566. * @return JsonResponse
  567. */
  568. public function previewProcess(SmSalestemplate $SalesTemplate): JsonResponse
  569. {
  570. $baseUrl = rtrim((string)($_ENV['IDEMPIERE_BASE_URL'] ?? ''), '/');
  571. $endpoint = $baseUrl . '/api/v1/processes/processsalestemplate';
  572. $payload = ['SM_SalesTemplate_ID' => $SalesTemplate->getId()];
  573. return new JsonResponse([
  574. 'endpoint' => $endpoint,
  575. 'body' => $payload,
  576. ]);
  577. }
  578. /**
  579. * Ruta para procesar los plantilla
  580. * @Route("/{id}/procesar", name="app_salestemplate_process")
  581. *
  582. * @param SmSalestemplate $SalesTemplate Plantilla de Venta
  583. * @param IdempiereRestClient $idempiereClient iDempiere REST client
  584. *
  585. * @return JsonResponse
  586. */
  587. public function process(SmSalestemplate $SalesTemplate, IdempiereRestClient $idempiereClient, LoggerInterface $logger): JsonResponse
  588. {
  589. $res = $idempiereClient->post(
  590. '/api/v1/processes/sm_salestemplate_process',
  591. [
  592. 'record-id' => $SalesTemplate->getId(),
  593. 'table-id' => 1000391,
  594. ]
  595. );
  596. $logger->info('iDempiere process response', [
  597. 'salestemplate_id' => $SalesTemplate->getId(),
  598. 'documentno' => $SalesTemplate->getDocumentno(),
  599. 'http_status' => $res['status'],
  600. 'raw' => $res['body'],
  601. ]);
  602. $decoded = json_decode((string)($res['body'] ?? ''), true);
  603. $rpr = is_array($decoded['RunProcessResponse'] ?? null) ? $decoded['RunProcessResponse'] : null;
  604. if ($rpr !== null) {
  605. $isError = filter_var($rpr['@IsError'] ?? false, FILTER_VALIDATE_BOOLEAN);
  606. $errorMsg = (string)($rpr['Summary'] ?? $rpr['summary'] ?? $rpr['Error'] ?? 'Error procesando plantilla.');
  607. } else {
  608. $isError = (bool)($decoded['isError'] ?? $decoded['IsError'] ?? ($res['status'] >= 400));
  609. $errorMsg = (string)($decoded['summary'] ?? $decoded['detail'] ?? $decoded['Error'] ?? 'Error procesando plantilla.');
  610. }
  611. if ($isError) {
  612. $response = [
  613. 'status' => 'error',
  614. 'msg' => $errorMsg,
  615. ];
  616. } else {
  617. $response = [
  618. 'status' => 'success',
  619. 'url' => $this->generateUrl('app_salestemplate_view', ['id' => $SalesTemplate->getId()]),
  620. 'documentno' => $SalesTemplate->getDocumentno(),
  621. 'msg' => $rpr !== null ? (string)($rpr['Summary'] ?? $rpr['summary'] ?? '') : (string)($decoded['summary'] ?? ''),
  622. ];
  623. }
  624. return new JsonResponse($response);
  625. }
  626. /**
  627. * Ruta para ver un plantilla
  628. * @Route("/{id}", name="app_salestemplate_view")
  629. *
  630. * @param SmSalestemplate $SalesTemplate Sales Template
  631. * @param Jaxon $jaxon Jaxon Request Handler
  632. * @param TranslatorInterface $translator Translator
  633. *
  634. * @return Response HTTP Response
  635. */
  636. public function view(SmSalestemplate $SalesTemplate, Jaxon $jaxon, TranslatorInterface $translator): Response
  637. {
  638. $useCase = new GetLocalSalesTemplateBySalesTemplate($this->repo);
  639. $local = $useCase->execute($SalesTemplate->getId());
  640. if($local) {
  641. $local = $this->repo->get($local->id);
  642. }
  643. $edit = false;
  644. if($local) {
  645. $edit = $local->getId();
  646. }
  647. return $this->render('modules/idempiere/salestemplate/view.html.twig', [
  648. 'title' => "{$translator->trans('Sales.Templates')} | {$SalesTemplate->getDocumentno()}",
  649. 'modulo' => $translator->trans('Sales.Templates'),
  650. 'breadcrumb' => $SalesTemplate->getDocumentno(),
  651. 'salestemplate' => $SalesTemplate,
  652. 'docstatus' => $this->docstatus,
  653. 'priorityrule' => $this->priorityrule,
  654. 'jaxonCss' => $jaxon->css(),
  655. 'jaxonJs' => $jaxon->js(),
  656. 'jaxonScript' => $jaxon->script(),
  657. 'edit' => $edit
  658. ]);
  659. }
  660. }
  661. ?>