src/Jaxon/Idempiere/Orderline.php line 272

Open in your IDE?
  1. <?php
  2. namespace App\Jaxon\Idempiere;
  3. use App\Constant;
  4. use App\Entity\Idempiere\AdOrg;
  5. use App\Entity\Idempiere\AdSequence;
  6. use App\Entity\Idempiere\AdUser;
  7. use App\Entity\Idempiere\COrder;
  8. use App\Entity\Idempiere\COrderline;
  9. use App\Entity\Idempiere\CTax;
  10. use App\Entity\Idempiere\MProduct;
  11. use App\Entity\Idempiere\MProductprice;
  12. use App\Entity\Idempiere\MWarehouse;
  13. use App\Jaxon\Base;
  14. use App\Repository\Idempiere\AdSequenceRepository;
  15. use App\Repository\Idempiere\MProductpriceRepository;
  16. use App\Repository\Idempiere\MProductRepository;
  17. use Exception;
  18. use Jaxon\Response\Response;
  19. class Orderline extends Base
  20. {
  21. /**
  22. * Habilitar campo para cambiar cantidades
  23. * de una linea en la orden
  24. *
  25. * @param int $C_Orderline_ID Identificador de la linea
  26. *
  27. * @return Response Jaxon Reponse
  28. */
  29. public function changeQty(
  30. Int $C_Orderline_ID
  31. )
  32. {
  33. $ROrderline = $this->manager->getRepository(COrderline::class);
  34. $orderline = $ROrderline->find( $C_Orderline_ID );
  35. $qty = $orderline->getQtyentered();
  36. $jxnr = new Response;
  37. $input=
  38. '<input
  39. type="number"
  40. step="0.01"
  41. value="'. number_format($qty, 2) .'"
  42. onblur="App.Jaxon.Idempiere.Orderline.setQty(\''. $C_Orderline_ID .'\', this.value)"
  43. >';
  44. return $jxnr->assign($C_Orderline_ID . '_qty', 'innerHTML', $input);
  45. }
  46. /**
  47. * Habilitar campo para cambiar precios
  48. * de una linea en la orden
  49. *
  50. * @param int $C_Orderline_ID Identificador de la linea
  51. *
  52. * @return Response Jaxon Reponse
  53. */
  54. public function changePrc(
  55. Int $C_Orderline_ID
  56. )
  57. {
  58. $ROrderline = $this->manager->getRepository(COrderline::class);
  59. $orderline = $ROrderline->find( $C_Orderline_ID );
  60. $prc = $orderline->getPriceactual();
  61. $jxnr = new Response;
  62. $input=
  63. '<input
  64. type="number"
  65. step="0.01"
  66. value="'. number_format($prc, 2) .'"
  67. onblur="App.Jaxon.Idempiere.Orderline.setPrc(\''. $C_Orderline_ID .'\', this.value)"
  68. >';
  69. return $jxnr->assign($C_Orderline_ID . '_prc', 'innerHTML', $input);
  70. }
  71. /**
  72. * Crear linea en la orden
  73. *
  74. * @param int $m_productprice_id Identificacdor del precio del producto
  75. * @param array $formData Datos de la orden
  76. *
  77. * @return Response Jaxon Reponse
  78. */
  79. # TODO: Cambiar monto de la orden
  80. public function create(
  81. Int $m_productprice_id
  82. ): Response
  83. {
  84. $jxnr = new Response;
  85. /**
  86. * Var Session
  87. */
  88. /** @var AdUser */
  89. $user = $this->session->get('user', null);
  90. /** @var COrder */
  91. $order = $this->session->get('order', null);
  92. /** @var MWarehouse */
  93. $warehouse = $this->session->get('warehouse', null);
  94. ##############################################################
  95. /**
  96. * Entity Repositorys
  97. */
  98. /** @var MProductpriceRepository */
  99. $RProductprice = $this->manager->getRepository(MProductprice::class);
  100. $productprice = $RProductprice->find($m_productprice_id);
  101. /** @var MProductRepository */
  102. $RProduct = $this->manager->getRepository(MProduct::class);
  103. $product = $RProduct->find($productprice->getMProductId());
  104. ##############################################################
  105. // Verifica si el producto tiene stock
  106. if( $RProduct->findStorage($product->getId(), $warehouse->getId()) <= 0 )
  107. return $jxnr->script( self::displayError("Producto sin Stock", "Este producto no cuenta con cantidades disponibles.") );
  108. // Verifica si el producto ya esta registrado en la orden
  109. $ROrderline = $this->manager->getRepository(COrderline::class);
  110. if( count( $ROrderline->findBy(['c_order_id' => $order->getId(), 'm_product_id' => $product->getId(), 'isactive' => 'Y']) ) > 0 )
  111. return $jxnr->script( self::displayError("Producto Repetido", "Este producto se encuentra registrado, modifique la cantidad de ser necesario.") );
  112. $orderlines = $ROrderline->findBy(['c_order_id' => $order->getId()]);
  113. /** @var AdSequenceRepository Sequence Repository */
  114. $RSequence = $this->manager->getRepository(AdSequence::class);
  115. $Orderline = new COrderline();
  116. $Orderline
  117. ->setAdClientId( $order->getAdClientId() )
  118. ->setAdOrgId( $order->getAdOrgId() )
  119. ->setCActivityId( Constant::C_Activity_ID )
  120. ->setCBpartnerId( $order->getCBpartner()->getId() )
  121. ->setCBpartnerLocationId( $order->getCBpartnerLocation()->getId() )
  122. ->setCCurrencyId( $order->getCCurrency()->getId() )
  123. ->setCOrderId( $order->getId() )
  124. ->setCOrderlineId( $RSequence->findNextSequence( $ROrderline->sequence ) )
  125. ->setCUomId( $product->getCUomId() )
  126. ->setLine( (count($orderlines) + 1) * 10 )
  127. ->setLinenetamt( $productprice->getPricelist() )
  128. ->setMProduct( $product )
  129. ->setMWarehouseId( $order->getMWarehouseId() )
  130. ->setPriceactual( $productprice->getPricelist() )
  131. ->setPriceentered( $productprice->getPricelist() )
  132. ->setPricelist( $productprice->getPricelist() )
  133. ->setQtyentered(1)
  134. ->setQtyordered(1)
  135. ->setQtyreserved(1);
  136. $date = new \DateTime("now");
  137. $Orderline
  138. ->setCreated( $date )
  139. ->setCreatedby( $user->getId() )
  140. ->setUpdated( $date )
  141. ->setUpdatedby( $user->getId() )
  142. ->setIsactive('Y')
  143. ->setDateordered( $date )
  144. ->setCOrderlineUu( $RSequence->findNextUU() );
  145. $RTax = $this->manager->getRepository(CTax::class);
  146. $tax = $RTax->findBy([
  147. 'ad_client_id' => $order->getAdClientId(),
  148. 'c_taxcategory_id' => $product->getCTaxcategoryId(),
  149. 'sopotype' => ['S', 'B'],
  150. 'isdefault' => 'Y',
  151. 'isactive' => 'Y'
  152. ]);
  153. $Orderline->setCTaxId( $tax[0]->getId() );
  154. $this->manager->persist($Orderline);
  155. $ROrder = $this->manager->getRepository(COrder::class);
  156. $order = $ROrder->find( $order->getId() );
  157. $order->setTotallines( $order->getTotallines() + $Orderline->getLinenetamt() );
  158. $order->setGrandtotal( $order->getTotallines() );
  159. $this->manager->persist($order);
  160. try {
  161. $this->manager->flush();
  162. $this->manager->clear();
  163. $html =
  164. '<tr class="text-center orderline" id="'. $Orderline->getId() .'">
  165. <td class="text-center">' . $Orderline->getLine() .'</td>
  166. <td class="text-left">' . $Orderline->getMProduct()->getName() .'</td>
  167. <td class="text-center">' . $Orderline->getMProduct()->getValue() .'</td>
  168. <td class="text-right prc" id="'. $Orderline->getId() . '_prc">
  169. <p onclick="App.Jaxon.Idempiere.Orderline.changePrc(\''. $Orderline->getId() .'\')">'. number_format($Orderline->getPriceactual(), 2) .'</p>
  170. </td>
  171. <td class="text-right qty" id="'. $Orderline->getId() . '_qty">
  172. <p onclick="App.Jaxon.Idempiere.Orderline.changeQty(\''. $Orderline->getId() .'\')">'. number_format($Orderline->getQtyordered(), 2) .'</p>
  173. </td>
  174. <td class="text-right amt" id="'. $Orderline->getId() . '_amt">
  175. '. number_format($Orderline->getLinenetamt(), 2) .'
  176. </td>
  177. <td class="btn-action">
  178. <i onclick="App.Jaxon.Base.actionConfirm(\'Orderline\', \'delete\', \''. $Orderline->getId() .'\')" class="fas fa-trash text-danger"></i>
  179. </td>
  180. </tr>';
  181. $jxnr
  182. ->prepend('tablaProductos', 'innerHTML', $html)
  183. ->assign('totallines', 'value', number_format($order->getTotallines(), 2))
  184. ->assign('grandtotal', 'value', number_format($order->getGrandtotal(), 2))
  185. ->script('$("#productModal").modal("hide")');
  186. } catch (Exception $e) {
  187. $jxnr->script(self::displayError("Oops!", "Ha fallado al crear la Linea", $e) );
  188. }
  189. return $jxnr;
  190. }
  191. /**
  192. * Borra una linea de una orden temporal
  193. *
  194. * @param int $C_Orderline_ID Identificador de la linea
  195. *
  196. * @return Response Jaxon Reponse
  197. */
  198. # TODO: Crear metodo para reordenar lineas
  199. public function delete(
  200. Int $C_Orderline_ID
  201. )
  202. {
  203. $ROrderline = $this->manager->getRepository(COrderline::class);
  204. $orderline = $ROrderline->find( $C_Orderline_ID );
  205. $oAmt = $orderline->getLinenetamt();
  206. $orderline->setIsactive('N');
  207. $this->manager->persist($orderline);
  208. $ROrder = $this->manager->getRepository(COrder::class);
  209. $order = $ROrder->find( $orderline->getCOrderId() );
  210. $order->setTotallines( $order->getTotallines() - $oAmt ); // Restar monto viejo de la linea
  211. $order->setGrandtotal( $order->getTotallines() );
  212. $this->manager->persist($order);
  213. $jxnr = new Response;
  214. try {
  215. $this->manager->flush();
  216. $this->manager->clear();
  217. $jxnr
  218. ->remove($C_Orderline_ID)
  219. ->assign('totallines', 'value', number_format($order->getTotallines(), 2))
  220. ->assign('taxamt', 'value', number_format($order->getGrandtotal() - $order->getTotallines(), 2))
  221. ->assign('grandtotal', 'value', number_format($order->getGrandtotal(), 2));
  222. } catch (Exception $e) {
  223. $jxnr->script(self::displayError("Oops!", "Ha fallado al borrar la Linea", $e) );
  224. }
  225. return $jxnr;
  226. }
  227. /**
  228. * Lista los productos coincidentes
  229. *
  230. * @param string $value Codigo o Nombre del producto
  231. * @param array $formData Datos del formulario
  232. *
  233. * @return Response Jaxon Reponse
  234. */
  235. public function getProducts(
  236. String $value = '',
  237. Array $formData
  238. ): Response
  239. {
  240. $jxnr = new Response;
  241. /**
  242. * Session
  243. */
  244. /** @var AdUser */
  245. $user = $this->session->get('user', null);
  246. /** @var AdOrg */
  247. $organization = $this->session->get('organization', null);
  248. /** @var MWarehouse */
  249. $warehouse = $this->session->get('warehouse', null);
  250. ####################################################################
  251. /**
  252. * Repositorios
  253. */
  254. /** @var MProductRepository */
  255. $RProduct = $this->manager->getRepository(MProduct::class);
  256. /** @var MProductpriceRepository */
  257. $RProductprice = $this->manager->getRepository(MProductprice::class);
  258. ####################################################################
  259. // La organizacion debe ser seleccionada para listar los productos
  260. if(!isset($organization) || $formData['organization'] == 0)
  261. return $jxnr->script('Swal.fire("Oops!", "Primero debe seleccionar una organizaci&oacute;n!", "warning")');
  262. // La lista de precio debe ser seleccionada para mostrar los precios de los articulos
  263. if(!isset($formData['pricelist']) || $formData['pricelist'] == 0)
  264. return $jxnr->script('Swal.fire("Oops!", "No has seleccionado una lista de precio!", "warning")');
  265. /** Datos */
  266. $pps = $RProductprice->findProductPrices($formData['pricelist'], $value);
  267. $html= '<table id="productTable" class="table"><thead><tr><th>Marca</th><th>Nombre</th><th>C&oacute;digo</th><th>Cantidad</th><th>Precio</th></tr></thead><tbody>';
  268. if( count($pps) > 0) {
  269. foreach ($pps as $pp) {
  270. $html .=
  271. '<tr style="font-size: 0.9rem; cursor: pointer;" onclick="App.Jaxon.Idempiere.Orderline.create(\''. $pp->getId() .'\', jaxon.getFormValues(\'order\'))">
  272. <td>'.$pp->getMProduct()->getSmMarca()->getName().'</td>
  273. <td>'.$pp->getMProduct()->getName().'</td>
  274. <td>'.$pp->getMProduct()->getValue().'</td>
  275. <td>'. number_format($RProduct->findStorage($pp->getMProductId(), $warehouse->getId()), 2) .'</td>
  276. <td>$'.$pp->getPricestd().'</td>
  277. </tr>';
  278. }
  279. } else {
  280. $html .= '<tr><td colspan="2">NO SE HA ENCONTRADO NINGUN PRODUCTO</td></tr>';
  281. }
  282. $html .= '</tbody></table>';
  283. $jxnr
  284. ->assign('products', 'innerHTML', $html)
  285. ->script('$("#productTable").dataTable({ columnDefs: [{ orderable: true, targets: 0 }], order: [[1, "asc" ]], responsive: true, lengthChange: false, autoWidth: false, dom: \'<"row"<"col-sm-12 col-md-12"f>><"row"<"col-sm-12"rt>><"row"<"col-sm-12 col-md-5"i><"col-sm-12 col-md-7"p>>\', buttons: ["copy", "csv", "excel", "pdf", "print", "colvis"] })');
  286. return $jxnr;
  287. }
  288. /**
  289. * Cambiar cantidad de un producto en una linea
  290. *
  291. * @param int $C_Orderline_ID Identificador de la linea
  292. * @param float $qty Cantidad
  293. *
  294. * @return Response Jaxon Reponse
  295. */
  296. # TODO: Verificar las cantidades disponibles
  297. public function setQty(
  298. Int $C_Orderline_ID,
  299. Float $qty
  300. )
  301. {
  302. $ROrderline = $this->manager->getRepository(COrderline::class);
  303. $orderline = $ROrderline->find( $C_Orderline_ID );
  304. $orderline->setQtyordered( $qty );
  305. $orderline->setQtyentered( $qty );
  306. $orderline->setQtyreserved( $qty );
  307. $oAmt = $orderline->getLinenetamt();
  308. $orderline->setLinenetamt( $orderline->getPriceactual() * $qty );
  309. //
  310. $this->manager->persist($orderline);
  311. //
  312. $ROrder = $this->manager->getRepository(COrder::class);
  313. $order = $ROrder->find( $orderline->getCOrderId() );
  314. $amt = $order->getTotallines() - $oAmt; // Restar monto viejo de la linea
  315. $order->setTotallines( $amt + $orderline->getLinenetamt() );
  316. $order->setGrandtotal( $order->getTotallines() );
  317. $this->manager->persist($order);
  318. $jxnr = new Response;
  319. try {
  320. $this->manager->flush();
  321. $this->manager->clear();
  322. $jxnr
  323. ->assign($C_Orderline_ID . '_qty', 'innerHTML', '<p onclick="App.Jaxon.Idempiere.Orderline.changeQty(\''. $orderline->getId() .'\')">'. number_format($qty, 2) .'</p>')
  324. ->assign($C_Orderline_ID . '_amt', 'innerHTML', number_format($orderline->getLinenetamt(), 2))
  325. ->assign('totallines', 'value', number_format($order->getTotallines(), 2))
  326. ->assign('taxamt', 'value', number_format($order->getGrandtotal() - $order->getTotallines(), 2))
  327. ->assign('grandtotal', 'value', number_format($order->getGrandtotal(), 2));
  328. } catch (Exception $e) {
  329. $jxnr->script(self::displayError("Oops!", "Ha fallado el guardado automatico de la Linea", $e) );
  330. }
  331. return $jxnr;
  332. }
  333. /**
  334. * Cambiar precio de un producto en una linea
  335. *
  336. * @param int $C_Orderline_ID Identificador de la linea
  337. * @param float $prc Precio
  338. *
  339. * @return Response Jaxon Reponse
  340. */
  341. # TODO: Verificar las cantidades disponibles
  342. public function setPrc(
  343. Int $C_Orderline_ID,
  344. Float $prc
  345. )
  346. {
  347. $ROrderline = $this->manager->getRepository(COrderline::class);
  348. $orderline = $ROrderline->find( $C_Orderline_ID );
  349. $orderline->setPriceactual($prc);
  350. $orderline->setPriceentered($prc);
  351. $orderline->setPricelist($prc);
  352. $oAmt = $orderline->getLinenetamt();
  353. $orderline->setLinenetamt( $orderline->getPriceactual() * $orderline->getQtyentered() );
  354. //
  355. $this->manager->persist($orderline);
  356. //
  357. $ROrder = $this->manager->getRepository(COrder::class);
  358. $order = $ROrder->find( $orderline->getCOrderId() );
  359. $amt = $order->getTotallines() - $oAmt; // Restar monto viejo de la linea
  360. $order->setTotallines( $amt + $orderline->getLinenetamt() );
  361. $order->setGrandtotal( $order->getTotallines() );
  362. $this->manager->persist($order);
  363. $jxnr = new Response;
  364. try {
  365. $this->manager->flush();
  366. $this->manager->clear();
  367. $jxnr
  368. ->assign($C_Orderline_ID . '_prc', 'innerHTML', '<p onclick="App.Jaxon.Idempiere.Orderline.changePrc(\''. $orderline->getId() .'\')">'. number_format($prc, 2) .'</p>')
  369. ->assign($C_Orderline_ID . '_amt', 'innerHTML', number_format($orderline->getLinenetamt(), 2))
  370. ->assign('totallines', 'value', number_format($order->getTotallines(), 2))
  371. ->assign('taxamt', 'value', number_format($order->getGrandtotal() - $order->getTotallines(), 2))
  372. ->assign('grandtotal', 'value', number_format($order->getGrandtotal(), 2));
  373. } catch (Exception $e) {
  374. $jxnr->script(self::displayError("Oops!", "Ha fallado el guardado automatico de la Linea", $e) );
  375. }
  376. return $jxnr;
  377. }
  378. }
  379. ?>