Hola a todos, en uno de los últimos proyectos en los que estoy participando, nos ha surgido la necesidad de realizar la creación de Diarios Generales y Diarios de Pagos, así como la creación de Facturas de Servicios directamente desde código X++. El código para realizar esta operación, como ya sabréis, es relativamente sencillo y funciona bastante bien. Pero, en este caso, nos surge una necesidad específica:
Cuando generamos, por ejemplo, un Diario General, sabéis que podemos marcar ciertas transacciones abiertas del cliente para que se liquiden de forma automática con las líneas del diario en cuestión (o contra la Factura de Servicios), de esta forma, vamos cerrando transacciones y disminuyendo el saldo abierto del cliente.
La forma de marcar estas transacciones para su liquidación es muy sencilla. Simplemente tenemos que indicar en la línea del diario la cuenta del cliente, y posteriormente ir a Funciones / Liquidación. Una vez abierto este nuevo formulario, únicamente tenemos que marcar las transacciones que queremos marcar y cerrarlo. Estas transacciones marcadas se liquidarán en el momento de registrar el diario (o factura).
Pues bien, la necesidad que nos surgió era realizar esta misma liquidación de forma automática por medio de programación, de forma que, al crear el diario o factura, estas transacciones se marquen en función de unos filtros realizados, para que, al ejecutar el registro del diario o factura, se vayan machacando las transacciones abiertas del cliente.
El objetivo de este artículo no es otro que compartir este pequeño fragmento de código con la comunidad, así como guardármelo para futuras ocasiones ;). Como ahora veréis, es un código tan sencillo como útil.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// jatomas.com // t: @juanan169 // Marcar transacciones abiertas de cliente - Código testado en AX 2012 R3 CU10 public void markTransaction(LedgerJouranlTrans _ledgerJournalTrans) { CustTransOpen custTransOpen; CustTrans custTrans; CustVendOpenTransManager custVendOpenTransManager; CustAccount custAccount = "Codigo_cliente"; // Seleccionamos la transacción abierta del cliente que queremos liquidar select custTransOpen index hint RefRecIdx where custTransOpen.AccountNum == custAccount join custTrans where custTrans.AccountNum == custTransOpen.AccountNum && //... // Marcar transacción custVendOpenTransManager = CustVendOpenTransManager::construct(_ledgerJournalTrans); // Si se trata de Factura de servicios // custVendOpenTransManager = CustVendOpenTransManager::construct(_custInvoiceTable); custVendOpenTransManager.updateTransMarked(custTransOpen, true); custVendOpenTransManager.updateSettleAmount(custTransOpen, _ledgerJournalTrans.amount()); // Actualizar linea de diario para indicar que está marcada // Esta parte de código exclusiva para Diarios _ledgerJournalTrans.selectForUpdate(true); _ledgerJournalTrans.SettleVoucher = SettlementType::SelectedTransact; _ledgerJournalTrans.update(); } |
Pues hasta aquí el artículo de hoy, espero que os resulte útil.
Saludos!!
Buenas
quisiera saber si me puedes ayudar, en que momento le puedo meter variables de un rango de fechas, ademas en que momento mandas a llamar al metodo este.
Perdon si es que es algo obvio, pero soy nuevo en X++
Buenas Guillermo,
La llamada a este método es necesaria antes de registrar el diario, en el momento posterior a ejecutar el insert() de la legerJournalTrans.
En cuanto a la introducción de variables para meter un rango de fechas, por favor, intenta especificar un poco más que es lo que necesitas.
Gracias!
Juanan.
gracias, te comento, en mi empresa liquidan las facturas segun un rango de fechas de una cliente, entonces lo que entendi, es que cuando se da a liquidacion, este metodo toma la cuenta del cliente que sea esta haciendo el pago y marca todas las facturas?, lo que quiero es agregarle que marque solo las facturas de un rango de fecha.
no se si me explico.
Gillermo,
En principio, esta parte de código está hecha para que la línea de diario «_ledgerJournalTrans» liquide una transacción de cliente abierta específica que se indica con una consulta:
select custTransOpen
index hint RefRecIdx
where custTransOpen.AccountNum == custAccount
join custTrans
where custTrans.AccountNum == custTransOpen.AccountNum
&& //…
Si lo que quieres que esa línea de diario vaya a liquidar una serie de transacciones concretas de un cliente, deberías recorrer esas líneas e ir marcándolas una a una antes de registrar el diario, algo como:
while select custTransOpen
where custTransOpen.AccountNum == custAccount
join custTrans
where custTrans.AccountNum == custTransOpen.AccountNum
&& custTrans.TransDate >= fechaInicio
&& custTrans.TransDate <= fechaFin { // Marcar transacción custVendOpenTransManager = CustVendOpenTransManager::construct(_ledgerJournalTrans); // Si se trata de Factura de servicios // custVendOpenTransManager = CustVendOpenTransManager::construct(_custInvoiceTable); custVendOpenTransManager.updateTransMarked(custTransOpen, true); custVendOpenTransManager.updateSettleAmount(custTransOpen, _ledgerJournalTrans.amount()); } … Espero que te sirva de ayuda! 😉
Buenas Juanan
si, lo del while select agregando las fechas me queda claro, mi consulta es debido a que soy nuevo en ax y todavia no tengo claro, si cuando le doy en Liquidacion, me abra una ventanita pidiendome el rango de fechas o como hacer para que ax me pida el rango de fechas?
perdoname si talves es algo simple
Entendido Guillermo,
En ese caso, lo que debes hacer es construir tu código utilizando el SysOperation framework, que te permite de forma sencilla generar un diálogo en el que solicitar ciertos valores a los usuarios, como pueden ser las fechas. Échale un vistazo por ejemplo al siguiente enlace:
https://community.dynamics.com/ax/b/faisalfareedaxlibrary/archive/2016/03/26/ax-2012-sysoperation-framework-implementation-example