Aquí muestro cómo crear un diario de transferir en Dynamics Ax 2009
static void ISSinventtransferjournal(Args _args)
{
InventJournalTable inventJournalTable;
InventJournalTrans inventJournalTrans;
InventJournalCheckPost inventJournalCheckPost;
NumberSeq num;
InventDim frominventDim,ToinventDim;
;
ttsbegin;
inventJournalTable.clear();
num = new NumberSeq();
num = NumberSeq::newGetNum(InventParameters::numRefTransferId());
inventJournalTable.initFromInventJournalName(InventJournalName::find(InventParameters::find().TransferJournalNameId));
inventJournalTable.Description = InventJournalName::find(InventParameters::find().TransferJournalNameId).Description;
inventJournalTable.SystemBlocked = true;
inventJournalTable.insert();
//línea 1
inventJournalTrans.clear();
inventJournalTrans.initFromInventJournalTable(inventJournalTable);
inventJournalTrans.ItemId = "AAA";
//frominventDim.wMslocationid = "";
frominventDim.inventSiteId ="CAD";
frominventdim.InventLocationId = "FABRICA";
frominventdim.inventBatchId = "1a";
//Toinventdim.wmslocationid = "";
ToinventDim.InventSiteId = "CAD";
ToinventDim.InventLocationId = "FERT";
ToinventDim.inventBatchId = "1a";
ToinventDim = InventDim::findOrCreate(ToinventDim);
frominventDim = InventDim::findOrCreate(frominventDim);
inventJournalTrans.InventDimId = frominventDim.inventDimId;
inventJournalTrans.initFromInventTable(InventTable::find("AAA"));
inventJournalTrans.Qty = 1;
inventJournalTrans.ToInventDimId = ToinventDim.inventDimId;
inventJournalTrans.TransDate = SystemDateget();
inventJournalTrans.insert();
inventJournalTable.NumOfLines = 1;
inventJournalCheckPost = InventJournalCheckPost::newJournalCheckPost(JournalCheckpostType::Post,inventJournalTable);
inventJournalCheckPost.run();
inventJournalTable.SystemBlocked = false;
inventJournalTable.update();
ttscommit;
info(strfmt("Diario: %1 creado.", inventJournalTable.JournalId));
}
Post relacionados:
Reserva de inventario por línea de venta por código x++, Dynamics Ax 2009
Dialogo para seleccionar nombre de archivo FileName
Crear una orden de producción en Dyamics Ax 2009 por código x++
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
Buscar en este blog
jueves, 23 de febrero de 2017
miércoles, 15 de febrero de 2017
Crear una orden de producción en Dyamics Ax 2009 por código x++
Ejemplo para crear una orden de producción y llevarla por los distintos estados: la estimación, la lista de selección, el inicio, reportar como terminada y el fin.
static void createProductionOrder(Args _args)
{
ProdQty qty = 2;
ItemId item = 'AAA-PT';
ProdTable prodtable;
InventTable inventTable;
InventDim inventDim;
ProdMultiCostEstimation prodMultiCostEstimation;
ProdMultiScheduling prodMultiScheduling;
ProdMultiRelease prodMultiRelease;
ProdMultiStartUp prodMultiStartUp;
ProdMultiReportFinished prodMultiReportFinished;
ProdMultiHistoricalCost prodMultiHistoricalCost;
Args args = new Args();
ProdParmStartUp prodParmStartUp;
;
// Inicializar InventTable
inventTable = inventTable::find(item);
prodtable.initValue();
prodtable.initFromInventTable(inventTable);
prodtable.ItemId = inventTable.ItemId;
prodtable.DlvDate = today();
prodtable.DlvTime = DateTimeUtil::time(DateTimeUtil::utcNow());
prodtable.QtySched = qty;
prodtable.RemainInventPhysical = qty;
// Inicializar InventDim
inventDim.initValue();
prodtable.BOMId = BOMVersion::findActive(prodtable.ItemId,
prodtable.BOMDate,
prodtable.QtySched,
inventDim).BOMId;
prodtable.RouteId = RouteVersion::findActive(prodtable.ItemId,
prodtable.BOMDate,
prodtable.QtySched,
inventDim).RouteId;
// Inicializar BOMVersion
prodtable.initBOMVersion();
// Inicializar RouteVersion
prodtable.initRouteVersion();
//Personalizar lote
inventDim = inventDim::find(prodtable.InventDimId);
inventDim.inventBatchId = "2011-302005";
inventDim = inventDim::findOrCreate(inventDim);
prodtable.InventDimId = inventDim.inventDimId;
//Dependiendo de la configuración, esto puede ser necesario o no
ProdTable.ProdGroupId = "AGR";
//Usando ProdTable para crear la orden
prodtable.type().insert();
// Indica la orden de producción que se creo
setPrefix( 'Número de orde de producción');
info(prodtable.ProdId);
// Estimation
prodMultiCostEstimation = ProdMultiCostEstimation::construct(args);
runBaseMultiParm::initParm(ProdMultiCostEstimation);
prodMultiCostEstimation.insert(prodTable, ProdMultiCostEstimation.defaultParmBuffer());
prodMultiCostEstimation.run();
// Scheduling
prodMultiScheduling = ProdMultiScheduling::construct(ProdSchedMethod::OperationScheduling);
runBaseMultiParm::initParm(prodMultiScheduling);
prodMultiScheduling.insert(prodTable, prodMultiScheduling.defaultParmBuffer());
prodMultiScheduling.run();
// Release
prodMultiRelease = ProdMultiRelease::construct(args);
runBaseMultiParm::initParm(ProdMultiRelease);
prodMultiRelease.insert(prodTable, prodMultiRelease.defaultParmBuffer());
prodMultiRelease.run();
// Start up
prodMultiStartup = ProdMultiStartUp::construct(args);
runBaseMultiParm::initParm(prodMultiStartup);
prodMultiStartup.insert(prodTable, prodMultiStartup.defaultParmBuffer());
prodMultiStartup.runISS();
// Report as Finished
prodMultiReportFinished = ProdMultiReportFinished::construct(args);
runBaseMultiParm::initParm(ProdMultiReportFinished);
prodMultiReportFinished.insert(prodTable, ProdMultiReportFinished.defaultParmBuffer());
prodMultiReportFinished.runISS();
// End the Order
prodMultiHistoricalCost = ProdMultiHistoricalCost::construct(args);
runBaseMultiParm::initParm(ProdMultiHistoricalCost);
prodMultiHistoricalCost.insert(prodTable, ProdMultiHistoricalCost.defaultParmBuffer());
prodMultiHistoricalCost.run();
}
Post relacionados:
Reserva de inventario por línea de venta por código x++, Dynamics Ax 2009
Dialogo para seleccionar nombre de archivo FileName
Crear búsquedas por nombre de producto en métodos display
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
static void createProductionOrder(Args _args)
{
ProdQty qty = 2;
ItemId item = 'AAA-PT';
ProdTable prodtable;
InventTable inventTable;
InventDim inventDim;
ProdMultiCostEstimation prodMultiCostEstimation;
ProdMultiScheduling prodMultiScheduling;
ProdMultiRelease prodMultiRelease;
ProdMultiStartUp prodMultiStartUp;
ProdMultiReportFinished prodMultiReportFinished;
ProdMultiHistoricalCost prodMultiHistoricalCost;
Args args = new Args();
ProdParmStartUp prodParmStartUp;
;
// Inicializar InventTable
inventTable = inventTable::find(item);
prodtable.initValue();
prodtable.initFromInventTable(inventTable);
prodtable.ItemId = inventTable.ItemId;
prodtable.DlvDate = today();
prodtable.DlvTime = DateTimeUtil::time(DateTimeUtil::utcNow());
prodtable.QtySched = qty;
prodtable.RemainInventPhysical = qty;
// Inicializar InventDim
inventDim.initValue();
prodtable.BOMId = BOMVersion::findActive(prodtable.ItemId,
prodtable.BOMDate,
prodtable.QtySched,
inventDim).BOMId;
prodtable.RouteId = RouteVersion::findActive(prodtable.ItemId,
prodtable.BOMDate,
prodtable.QtySched,
inventDim).RouteId;
// Inicializar BOMVersion
prodtable.initBOMVersion();
// Inicializar RouteVersion
prodtable.initRouteVersion();
//Personalizar lote
inventDim = inventDim::find(prodtable.InventDimId);
inventDim.inventBatchId = "2011-302005";
inventDim = inventDim::findOrCreate(inventDim);
prodtable.InventDimId = inventDim.inventDimId;
//Dependiendo de la configuración, esto puede ser necesario o no
ProdTable.ProdGroupId = "AGR";
//Usando ProdTable para crear la orden
prodtable.type().insert();
// Indica la orden de producción que se creo
setPrefix( 'Número de orde de producción');
info(prodtable.ProdId);
// Estimation
prodMultiCostEstimation = ProdMultiCostEstimation::construct(args);
runBaseMultiParm::initParm(ProdMultiCostEstimation);
prodMultiCostEstimation.insert(prodTable, ProdMultiCostEstimation.defaultParmBuffer());
prodMultiCostEstimation.run();
// Scheduling
prodMultiScheduling = ProdMultiScheduling::construct(ProdSchedMethod::OperationScheduling);
runBaseMultiParm::initParm(prodMultiScheduling);
prodMultiScheduling.insert(prodTable, prodMultiScheduling.defaultParmBuffer());
prodMultiScheduling.run();
// Release
prodMultiRelease = ProdMultiRelease::construct(args);
runBaseMultiParm::initParm(ProdMultiRelease);
prodMultiRelease.insert(prodTable, prodMultiRelease.defaultParmBuffer());
prodMultiRelease.run();
// Start up
prodMultiStartup = ProdMultiStartUp::construct(args);
runBaseMultiParm::initParm(prodMultiStartup);
prodMultiStartup.insert(prodTable, prodMultiStartup.defaultParmBuffer());
prodMultiStartup.runISS();
// Report as Finished
prodMultiReportFinished = ProdMultiReportFinished::construct(args);
runBaseMultiParm::initParm(ProdMultiReportFinished);
prodMultiReportFinished.insert(prodTable, ProdMultiReportFinished.defaultParmBuffer());
prodMultiReportFinished.runISS();
// End the Order
prodMultiHistoricalCost = ProdMultiHistoricalCost::construct(args);
runBaseMultiParm::initParm(ProdMultiHistoricalCost);
prodMultiHistoricalCost.insert(prodTable, ProdMultiHistoricalCost.defaultParmBuffer());
prodMultiHistoricalCost.run();
}
Post relacionados:
Reserva de inventario por línea de venta por código x++, Dynamics Ax 2009
Dialogo para seleccionar nombre de archivo FileName
Crear búsquedas por nombre de producto en métodos display
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
miércoles, 8 de febrero de 2017
Reserva de inventario por línea de venta por código x++, Dynamics Ax 2009
Este es un ejemplo para simular la reserva de productos con dimensión financiera especifica, en este caso, un número de lote y número de serie en Dynamics Ax 2009.
Nota: este ejemplo ejecutado desde un job te puede mandar un error de "El cursor no es válido para crear una instancia recordViewCache." o "The cursor is invalid for instantiating recordViewCache." esto se debe a que la clase desde donde lo ejecutes debe tener la propiedad RunOn en Server.
Nota: este ejemplo ejecutado desde un job te puede mandar un error de "El cursor no es válido para crear una instancia recordViewCache." o "The cursor is invalid for instantiating recordViewCache." esto se debe a que la clase desde donde lo ejecutes debe tener la propiedad RunOn en Server.
static void reserveInventoryForSalesLine(Args _args)
{
SalesLine salesLine;
InventUpd_Reservation reservation;
InventDim inventDimCriteria;
InventDimParm inventDimParm;
InventMovement inventMovement;
InventQty qty;
;
salesLine = salesLine::findRecId(5637148606); // RecId de la línea de venta
if (!salesLine)
{
return;
}
inventMovement = InventMovement::construct(salesLine);
inventDimCriteria = InventDim::find(salesLine.inventDimId);
inventDimCriteria.inventBatchId = '202023';//número de lote especifico de donde se quiere hacer la reserva
inventDimCriteria.inventSerialId = '1234512'; //número de serie especifico de donde se quiere hacer la reserva
inventDimParm = inventMovement.initDimParmAutoReserv(inventDimCriteria);
reservation = InventUpd_Reservation::newMovement(inventMovement, -1, false);
reservation.parmInventDimFixed(InventDimFixedClass::inventDimParm2InventDimFixed(inventDimParm));
reservation.parmInventDimCriteria(inventDimCriteria);
reservation.parmInventDimParm(inventDimParm);
reservation.updateNow();
info("termino");
}
Post relacionados:
Consultas en tablas con ValidTimeState
Crear lookup en clase dialog
Crear búsquedas por nombre de producto en métodos display
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
Post relacionados:
Consultas en tablas con ValidTimeState
Crear lookup en clase dialog
Crear búsquedas por nombre de producto en métodos display
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
miércoles, 1 de febrero de 2017
Dialogo para seleccionar nombre de archivo FileName
Este es un ejemplo de cómo hacer un job que lance un dialogo y se pueda seleccionar el nombre del archivo.
static void DialogFilePath(Args _args)
{
Dialog dialog;
Filename filename;
DialogField dialogFilename;
//Definiendo filtro de ciertos tipos de archivos
container conFilter = ["Microsoft Excel 97-2003 Worksheet (.xls)" ,"*.xlsx"];
//container conFilter = ["Comma Seperated Value .txt ", "*.csv"];
;
dialog = new dialog();
dialog.caption("Importar archivo");
dialogFilename = dialog.addField(typeId(FilenameOpen));//extendedTypeStr(FilenameOpen)); //extendedTypeStr es para 2012
//Aplicando filtro de archivos
dialog.filenameLookupFilter(conFilter);
dialog.run();
if(dialog.closedOk())
{
filename = dialogFileName.value();
info(filename);
}
}
Este es el resultado:
Post relacionados:
Crear empleado, alta y baja por código x++
Escribir XML desde Ax 2012
Listar objetos que pertenecen a un proyecto
Crear empleado, alta y baja por código x++
Escribir XML desde Ax 2012
Listar objetos que pertenecen a un proyecto
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
viernes, 26 de febrero de 2016
Cómo crear un proyecto con todos los elementos de una capa - Microsoft Dynamics Ax 2012
Cuando pasamos objetos de un ambiente a otro, es útil saber que existe la posibilidad de crear un proyecto que contenga todos los elementos de una capa, por ejemplo, si solo queremos pasar los objetos creados o modificados de la capa var de nuestro ambiente de desarrollo al ambiente de pruebas pero no queremos pasar proyecto por proyecto.
1. Crear un proyecto nuevo en el AOT. (Ctrl+P abre la lista de proyectos, eliges si lo quieres Shared o Private, y sobre alguno de esos dos, Ctrl+N para crear el nuevo proyecto).
2. Abres el nuevo proyecto con doble click y eliges el botón de filtro avanzado
3. Elige las opciones, en la ventana que se abre, debes seleccionar si quieres agregar los objetos a tu proyecto o sobreescribir los que ya hay. En este caso como es proyecto nuevo, elegimos "Anexar". También se tiene la opción de "Paquetes" que es cómo queremos que se agrupen los elementos en nuestro proyecto, si elegimos "Ninguno" agrega todos los objetos sin orden y sin agrupaciones; si elegimos "AOT", vamos a ver los objetos agrupados por tipo de una manera similar al AOT; si elegimos "Por usuario", pues eso, los agrupa por usuario que haya creado o modificado el objeto.
4. Selecciona la capa. En la misma ventana de las opciones, click en el botón "Seleccionar" para indicar la capa en el filtro "SysModelLayer"
Con esto se incluirán todos los objetos de esa capa en nuestro proyecto que creamos.
Post relacionados:
Crear empleado, alta y baja por código x++
Escribir XML desde Ax 2012
Listar objetos que pertenecen a un proyecto
Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo.
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
1. Crear un proyecto nuevo en el AOT. (Ctrl+P abre la lista de proyectos, eliges si lo quieres Shared o Private, y sobre alguno de esos dos, Ctrl+N para crear el nuevo proyecto).
2. Abres el nuevo proyecto con doble click y eliges el botón de filtro avanzado
3. Elige las opciones, en la ventana que se abre, debes seleccionar si quieres agregar los objetos a tu proyecto o sobreescribir los que ya hay. En este caso como es proyecto nuevo, elegimos "Anexar". También se tiene la opción de "Paquetes" que es cómo queremos que se agrupen los elementos en nuestro proyecto, si elegimos "Ninguno" agrega todos los objetos sin orden y sin agrupaciones; si elegimos "AOT", vamos a ver los objetos agrupados por tipo de una manera similar al AOT; si elegimos "Por usuario", pues eso, los agrupa por usuario que haya creado o modificado el objeto.
4. Selecciona la capa. En la misma ventana de las opciones, click en el botón "Seleccionar" para indicar la capa en el filtro "SysModelLayer"
Con esto se incluirán todos los objetos de esa capa en nuestro proyecto que creamos.
Post relacionados:
Crear empleado, alta y baja por código x++
Escribir XML desde Ax 2012
Listar objetos que pertenecen a un proyecto
Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo.
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
viernes, 5 de febrero de 2016
Lista de remisiones asociadas a una factura por código X++ en Dynamics Ax 2012
Este es un post rápido, solo para mostrar cómo consultar las remisiones de una orden de venta asociadas a una factura.
Nos va a mostrar por cada línea de la factura la remisión a la que pertenece, si viene de alguna remisión.
Algunos hacen esta relación mediante el InventTransId hacia la tabla InventTrans, peroooo en esa tabla no hay registros cuando se trata de servicios, entonces no sirve ese camino. Otro hacen la relación solo entre CustPackingSlipTrans (líneas de remisiones) y CustInvoiceTrans (líneas de facturas), aquí si estan los servicios, peroooooo si un mismo artículo se remisionó parcial, ya tampoco funciona ese camino porque nos mostraria todas las remisiones donde esta el artículo, se haya facturado o no. Por eso el mejor camino que he encontrado, es mediante la CustInvoicePackingSlipQuantityMatch.
Post relacionados:
Lookup para dimensiones financieras personalizadas
Consultas en tablas con ValidTimeState
Crear lookup en clase dialog
Y por cierto, acuerdate de darle click a algún anuncio si el post te sirvio de algo.
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
static void Job9(Args _args)
{
CustInvoicePackingSlipQuantityMatch custInvoicePackingSlipQuantityMatch;
CustInvoiceTrans custInvoiceTrans;
CustPackingSlipTrans custPackingSlipTrans;
CustInvoiceJour custInvoiceJour;
//Buscamos la factura por RecId en la tabla CustInvoiceJour
custInvoiceJour = custInvoiceJour::findRecId( 5637160329);
while select custPackingSlipTrans
join custInvoicePackingSlipQuantityMatch
where custInvoicePackingSlipQuantityMatch.PackingSlipSourceDocumentLine == custPackingSlipTrans.SourceDocumentLine
join custInvoiceTrans
where custInvoicePackingSlipQuantityMatch.InvoiceSourceDocumentLine == custInvoiceTrans.SourceDocumentLine &&
custInvoiceTrans.InvoiceId == custInvoiceJour.InvoiceId //aquí se indica la factura de la que se quiere conocer sus remisiones
{
info(custPackingSlipTrans.PackingSlipId);
}
}
Nos va a mostrar por cada línea de la factura la remisión a la que pertenece, si viene de alguna remisión.
Algunos hacen esta relación mediante el InventTransId hacia la tabla InventTrans, peroooo en esa tabla no hay registros cuando se trata de servicios, entonces no sirve ese camino. Otro hacen la relación solo entre CustPackingSlipTrans (líneas de remisiones) y CustInvoiceTrans (líneas de facturas), aquí si estan los servicios, peroooooo si un mismo artículo se remisionó parcial, ya tampoco funciona ese camino porque nos mostraria todas las remisiones donde esta el artículo, se haya facturado o no. Por eso el mejor camino que he encontrado, es mediante la CustInvoicePackingSlipQuantityMatch.
Post relacionados:
Lookup para dimensiones financieras personalizadas
Consultas en tablas con ValidTimeState
Crear lookup en clase dialog
Y por cierto, acuerdate de darle click a algún anuncio si el post te sirvio de algo.
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
sábado, 30 de enero de 2016
Lookup para dimensiones financieras de organización - Microsoft Dynamics Ax 2012 R2
Sabemos que existen 3 tipos de dimensiones financieras, las de sistema, de organización y las personalizadas. En un post anterior, vimos cómo hacer un lookup para las dimensiones personalizadas y en esta ocasión, les comparto el código para el lookup de las dimensiones de organización, que pueden ser centro de costo, departamento y unidad de negocio.
Por tanto, si queremos por ejemplo, mostrar en una pantalla de parámetros los valores de cada dimensione de organización para que el usuario pueda seleccionar un valor existente. Lo primero seria agregar nuestros campos a una tabla de parámetros, en este caso, voy agregar estos campos al form de parámetros de ventas y marketing, cada uno extendiendo del dato: DimValue
Posterior a esto, agregaría los campos de esta tabla al formulario de parámetros y sobreescribiria el método el lookup de cada campo.
Este método lookup, debe llamar a mi método nuevo en la tabla donde tengo mis campos creados de dimensiones, donde en este método se hace la búsqueda de los valores por cada dimension de organización. Aquí el ejemplo de los tres métodos lookup.
Centro de costo
public client static void lookupCentroCosto(FormStringControl _ctrl)
Post relacionados:
Lookup para dimensiones financieras personalizadas
Consultas en tablas con ValidTimeState
Crear lookup en clase dialog
Y por cierto, acuerdate de darle click a algún anuncio si el post te sirvio de algo.
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
Por tanto, si queremos por ejemplo, mostrar en una pantalla de parámetros los valores de cada dimensione de organización para que el usuario pueda seleccionar un valor existente. Lo primero seria agregar nuestros campos a una tabla de parámetros, en este caso, voy agregar estos campos al form de parámetros de ventas y marketing, cada uno extendiendo del dato: DimValue
Posterior a esto, agregaría los campos de esta tabla al formulario de parámetros y sobreescribiria el método el lookup de cada campo.
Este método lookup, debe llamar a mi método nuevo en la tabla donde tengo mis campos creados de dimensiones, donde en este método se hace la búsqueda de los valores por cada dimension de organización. Aquí el ejemplo de los tres métodos lookup.
Centro de costo
public client static void lookupCentroCosto(FormStringControl _ctrl)
{
Query query = new Query();
SysTableLookup sysTableLookup;
QueryBuildDataSource queryBuildDataSource;
sysTableLookup = SysTableLookup::newParameters( tableNum(OMOperatingUnit), _ctrl, true);
sysTableLookup.parmUseLookupValue( false);
sysTableLookup.addLookupfield( fieldNum(OMOperatingUnit, OMOperatingUnitNumber));
sysTableLookup.addLookupfield( fieldNum(OMOperatingUnit, Name));
queryBuildDataSource = query.addDataSource( tableNum(OMOperatingUnit));
queryBuildDataSource.addSortField( fieldnum(OMOperatingUnit, OMOperatingUnitNumber));
queryBuildDataSource.addRange( fieldNum(OMOperatingUnit, OMOperatingUnitType)).value(int2str (any2int(OMOperatingUnitType::OMCostCenter)));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}
Departamento
public client static void lookupDepartamento(FormStringControl _ctrl)
{
Query query = new Query();
SysTableLookup sysTableLookup;
QueryBuildDataSource queryBuildDataSource;
sysTableLookup = SysTableLookup::newParameters( tableNum(OMOperatingUnit), _ctrl, true);
sysTableLookup.parmUseLookupValue( false);
sysTableLookup.addLookupfield( fieldNum(OMOperatingUnit, OMOperatingUnitNumber));
sysTableLookup.addLookupfield( fieldNum(OMOperatingUnit, Name));
queryBuildDataSource = query.addDataSource( tableNum(OMOperatingUnit));
queryBuildDataSource.addSortField( fieldnum(OMOperatingUnit, OMOperatingUnitNumber));
queryBuildDataSource.addRange( fieldNum(OMOperatingUnit, OMOperatingUnitType)).value(int2str (any2int(OMOperatingUnitType::OMDepartment)));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}
Unidad de negocio o BusinessUnit
public client static void lookupBusinessUnit(FormStringControl _ctrl)
{
Query query = new Query();
SysTableLookup sysTableLookup;
QueryBuildDataSource queryBuildDataSource;
sysTableLookup = SysTableLookup::newParameters( tableNum(OMOperatingUnit), _ctrl, true);
sysTableLookup.parmUseLookupValue( false);
sysTableLookup.addLookupfield( fieldNum(OMOperatingUnit, OMOperatingUnitNumber));
sysTableLookup.addLookupfield( fieldNum(OMOperatingUnit, Name));
queryBuildDataSource = query.addDataSource( tableNum(OMOperatingUnit));
queryBuildDataSource.addSortField( fieldnum(OMOperatingUnit, OMOperatingUnitNumber));
queryBuildDataSource.addRange( fieldNum(OMOperatingUnit, OMOperatingUnitType)).value(int2str (any2int(OMOperatingUnitType::OMBusinessUnit)));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}
Post relacionados:
Lookup para dimensiones financieras personalizadas
Consultas en tablas con ValidTimeState
Crear lookup en clase dialog
Y por cierto, acuerdate de darle click a algún anuncio si el post te sirvio de algo.
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
viernes, 29 de enero de 2016
Crear búsquedas sobre nombre de producto cambiando métodos display en Dynamics Ax 2012
A veces es necesario hacer búsquedas por nombre de producto en los formularios de Ax, y nos topamos con que este campo en el formulario, es un método display, para esto, aquí un ejemplo de la modificación del formulario en una de las pantallas mas comunes, que es la de Disponible, que esta en Administración del inventario -> Consultas -> Disponible para realizar búsquedas por nombre.
Si nosotros solo agregamos la tabla EcoResProduct relacionada a InventTable y EcoResProductTranslation que es la tabla que contiene los nombres de productos relacionada a EcoResProduct en nuestro formulario, el campo de nombre de producto que agreguemos al formulario aparecerá vacío, esto se debe a que esta tabla necesita el idioma para la relación y para saber en qué idioma debe mostrar el nombre de producto.
Finalmente arrastramos el campo Name de la tabla EcoResProductTranslation a nuestro grid y abrimos el formulario. Con esto ya podemos hacer búsquedas por nombre de producto.
Post relacionados:
Reportes SQL Reporting services (SSRS) en Microsoft Dynamics Ax 2012
Multiselect de grid en Ax 2012
Crear lookup en clase dialog
Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo.
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
Si nosotros solo agregamos la tabla EcoResProduct relacionada a InventTable y EcoResProductTranslation que es la tabla que contiene los nombres de productos relacionada a EcoResProduct en nuestro formulario, el campo de nombre de producto que agreguemos al formulario aparecerá vacío, esto se debe a que esta tabla necesita el idioma para la relación y para saber en qué idioma debe mostrar el nombre de producto.
Lo que se necesita hacer es:
Tener las relaciones en las tablas EcoResProduct (a InventTable) y en EcoResProductTranslation (a EcoResProduct).
Después modificar la clase que tiene el comportamiento del formulario, en este caso es InventDimCtrl_Frm_OnHand y en el método modifyQuery agregar nuestro datasource como parámetro, en este caso nuestra tabla EcoresProductTranslation que es la tabla que necesita la relación y crear una variable de tipo QueryBuildDataSource que nos va a servir para realizar el filtro para mandar el idioma a la tabla EcoResProductTranslation.
Al final de este método es donde realizamos el filtro a nuestra tabla pasandole el lenguaje de la compañia.
if(_ecoResProductTranslation)
{
qbsInventLookup = query.dataSourceName(_ecoResProductTranslation.name());
qbr = SysQuery::findOrCreateRange(qbsInventLookup, fieldnum(EcoResProductTranslation, LanguageId));
qbr.value(queryValue(CompanyInfo::languageId()));
qbsInventLookup.addGroupByField( fieldNum(EcoResProductTranslation,Name));
}
Modificamos la llamada a este método, que es dentro del formulario, en el datasource de InventSum, en el método executeQuery
Finalmente arrastramos el campo Name de la tabla EcoResProductTranslation a nuestro grid y abrimos el formulario. Con esto ya podemos hacer búsquedas por nombre de producto.
Post relacionados:
Reportes SQL Reporting services (SSRS) en Microsoft Dynamics Ax 2012
Multiselect de grid en Ax 2012
Crear lookup en clase dialog
Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo.
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
domingo, 17 de enero de 2016
Calcular impuestos en ordenes de venta por código X++ en Dynamics Ax 2012 R3
En este post se muestra cómo calcular los impuestos de una orden de venta para los casos:
1. Para calcular impuestos de las líneas de una factura debemos buscarlos en la tabla TaxTrans, tanto para factura de productos como para facturas de servicios.
2. Cuando la orden de venta no ha sido facturada y por consiguiente, no se han registrado los impuestos en la tabla TaxTrans, podemos auxilarnos de la clase SalesTotals, el ejemplo en código seria:
3. También es posible calcular los impuestos por artículo de acuerdo al grupo de impuestos de los artículos y a las cantidades vendidas o entregadas. Un ejemplo se muestra en el código siguiente:
4. Para el caso de calcular los impuestos de una remisión, el código quedaría como sigue:
5. Calculando los impuestos de una remisión por tipo de impuesto
Finalmente también tenemos otra opción usando la clase Tax, como se muestra en el post de "Calcular los impuestos de una línea de venta o de compra por código X++ en AX 2012".
Post relacionados:
Reportes SQL Reporting services (SSRS) en Microsoft Dynamics Ax 2012
Saldo de cuenta contable por dimension
Saldo de cuenta contable
Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo.
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
- cuando ya fue facturada
- cuando no ha sido facturada
- por línea de venta con base en código de impuestos
- por remisión por código de impuestos en artículo
- por remisión por tipo de impuesto
1. Para calcular impuestos de las líneas de una factura debemos buscarlos en la tabla TaxTrans, tanto para factura de productos como para facturas de servicios.
static void impuestosEnFactura(Args _args)
{
TaxTrans taxTrans;
CustInvoiceJour custInvoiceJour;
CustInvoiceTrans custInvoiceTrans;
//RecId del diario de factura
custInvoiceJour = custInvoiceJour::findRecId( 5637149082);
//Tomando en cuenta los campos por los que se relacionan las líneas
//con el diario
while select custInvoiceTrans
where custInvoiceTrans.InvoiceId == custInvoiceJour.InvoiceId &&
custInvoiceTrans.SalesId == custInvoiceJour.SalesId &&
custInvoiceTrans.InvoiceDate == custInvoiceJour.InvoiceDate &&
custInvoiceTrans.numberSequenceGroup == custInvoiceJour.numberSequenceGroup
{
while select taxTrans
where taxTrans.InventTransId == custInvoiceTrans.InventTransId
{
//El campo TaxAmount es el importe del impuesto,
//el campo TaxValue es el porcentaje de impuesto
info( strFmt("Impuesto de línea: %1" , taxTrans.TaxAmount));
}
}
}
2. Cuando la orden de venta no ha sido facturada y por consiguiente, no se han registrado los impuestos en la tabla TaxTrans, podemos auxilarnos de la clase SalesTotals, el ejemplo en código seria:
static void impuestosPorOrdenVenta(Args _args)
{
TmpTaxWorkTrans tmpTax;
SalesTable salesTable;
SalesTotals salesTotals;
salesTable = SalesTable::find( '000735'); //Id de orden de venta
//Se usa la clase SalesTotals para calcular impuestos
//Esta clase es la que llena el formulario de Totales en una
//orden de venta
salesTotals = SalesTotals::construct(salesTable);
//Calcula el impuesto
salesTotals.calc();
//Carga la tabla tmpTaxWorkTrans con los impuestos calculador
tmpTax.setTmpData(salesTotals.tax().tmpTaxWorkTrans());
//Mostramos el monto del impuesto(TaxAmount) y el porcentaje(TaxValue)
while select tmpTax
{
info( strFmt('Porcentaje aplicado: %1, Monto: %2' , tmpTax.showTaxValue(), tmpTax.TaxAmount));
}
}
En caso de que únicamente se requiera el cálculo de impuestos por ciertas líneas de la orden de venta y con base en ciertas cantidades, como puede ser el caso de únicamente calcular los impuestos por una remisión parcial, se deben hacer los cálculos para dividir ese impuesto total por línea entre la cantidad entregada de la remisión (campo Qty).3. También es posible calcular los impuestos por artículo de acuerdo al grupo de impuestos de los artículos y a las cantidades vendidas o entregadas. Un ejemplo se muestra en el código siguiente:
static void impuestosPorTipoImpuesto(Args _args)
{
TaxOnItem taxOnItem;
TaxGroupData taxGroupData;
real taxAmount;
TaxValue taxValue;
SalesLine salesLine;
SalesTable salesTable;
salesTable = SalesTable::find( '000754');
while select salesLine
where salesLine.SalesId == salesTable.SalesId
{
if(salesLine.TaxItemGroup && salesLine.TaxGroup && salesLine.LineAmount != 0)
{
while select taxOnItem
where taxOnItem.TaxItemGroup == salesline.TaxItemGroup
{
while select taxGroupData
where taxGroupData.TaxGroup == salesline.TaxGroup
&& taxGroupData.TaxCode == taxOnItem.TaxCode
{
TaxValue = TaxData::find(taxOnItem.TaxCode, Systemdateget(), 0 ).TaxValue;
TaxAmount = (salesline.LineAmount * TaxValue) / 100;
info( strFmt('Porcentaje aplicado: %1, Monto: %2' , TaxValue, TaxAmount));
}
}
}
}
}
4. Para el caso de calcular los impuestos de una remisión, el código quedaría como sigue:
static void impuestosPorTipoImpuestoRemision(Args _args)
{
TaxOnItem taxOnItem;
TaxGroupData taxGroupData;
real taxAmount;
TaxValue taxValue;
SalesLine salesLine;
//SalesTable salesTable;
Amount montoRealDeLinea;
CustPackingSlipJour custPackingSlipJour;
CustPackingSlipTrans custPackingSlipTrans;
//RecId del diario de remisión
custPackingSlipJour = CustPackingSlipJour::findRecId( 35637161119);
//Buscando las líneas de la remisión de acuerdo a la relación física de las tablas
while select custPackingSlipTrans
where custPackingSlipTrans.PackingSlipId == custPackingSlipJour.PackingSlipId &&
custPackingSlipTrans.SalesId == custPackingSlipJour.SalesId &&
custPackingSlipTrans.DeliveryDate == custPackingSlipJour.DeliveryDate
{
salesLine = custPackingSlipTrans.salesLine();
if(salesLine.TaxItemGroup && salesLine.TaxGroup && salesLine.LineAmount != 0 && custPackingSlipTrans.Qty != 0 )
{
while select taxOnItem
where taxOnItem.TaxItemGroup == salesline.TaxItemGroup
{
while select taxGroupData
where taxGroupData.TaxGroup == salesline.TaxGroup
&& taxGroupData.TaxCode == taxOnItem.TaxCode
{
TaxValue = TaxData::find(taxOnItem.TaxCode, Systemdateget(), 0 ).TaxValue;
//Para el cálculo del impuesto por línea es necesario conocer el monto al
//que le vamos a aplicar el impuesto, en este caso es el precio unitario de
//la línea de venta por la cantidad de la remisión
montoRealDeLinea = salesline.SalesPrice * custPackingSlipTrans.Qty;
TaxAmount = (montoRealDeLinea * TaxValue) / 100;
info( strFmt('Porcentaje aplicado: %1, Monto: %2' , TaxValue, TaxAmount));
}
}
}
}
}
static void impuestosPorOrdenVentaTipoImpuesto(Args _args)
{
TmpTaxWorkTrans tmpTax;
SalesTotals salesTotals;
CustPackingSlipJour custPackingSlipJour;
CustPackingSlipTrans custPackingSlipTrans;
TaxAmount impuestoAvCast;
//RecId del diario de remisión
custPackingSlipJour = CustPackingSlipJour::findRecId( 35637161119);
salesTotals = SalesTotals::construct(custPackingSlipJour.salesTable());
salesTotals.calc();
tmpTax.setTmpData(salesTotals.tax().tmpTaxWorkTrans());
//Por cada custPackingSlipTrans calculando el ieps
while select custPackingSlipTrans
where custPackingSlipTrans.PackingSlipId == custPackingSlipJour.PackingSlipId &&
custPackingSlipTrans.SalesId == custPackingSlipJour.SalesId &&
custPackingSlipTrans.DeliveryDate == custPackingSlipJour.DeliveryDate
{
while select tmpTax
where tmpTax.InventTransId == custPackingSlipTrans.InventTransId &&
tmpTax.TaxCode == "AV_CAST"
{
//solo avcast, por línea de remisión, el resultado lo manda negativo
impuestoAvCast = tmpTax.TaxAmount/custPackingSlipTrans.Qty;
info( strFmt("ieps: %1" , impuestoAvCast));
}
}
}
Finalmente también tenemos otra opción usando la clase Tax, como se muestra en el post de "Calcular los impuestos de una línea de venta o de compra por código X++ en AX 2012".
Post relacionados:
Reportes SQL Reporting services (SSRS) en Microsoft Dynamics Ax 2012
Saldo de cuenta contable por dimension
Saldo de cuenta contable
Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo.
No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.
Suscribirse a:
Entradas (Atom)