public void setRanges(Query _query)
{
QueryBuildDataSource qbds;
InventJournalTable inventJournalTable;
FormDataSource fds;
qbds = _query.dataSourceTable(tablenum(InventJournalTable));
while (qbds.findRange(fieldNum(InventJournalTable, JournalId)))
{
qbds.clearRange(fieldNum(InventJournalTable, JournalId));
}
if (this.parmArgs())
{
switch (this.parmArgs().dataset())
{
case tableNum(InventJournalTable):
inventJournalTable = this.parmArgs().record();
fds = inventJournalTable.dataSource();
if (inventJournalTable.isFormDataSource() && inventJournalTable.dataSource() && fds.anyMarked())
{
for (inventJournalTable = fds.getFirst(fds.anyMarked()); inventJournalTable; inventJournalTable = fds.getNext())
{
qbds.addRange(fieldNum(InventJournalTable, JournalId)).value(inventJournalTable.JournalId);
}
}
else
{
//nessun record selezionato, prendi il record corrente
qbds.addRange(fieldNum(InventJournalTable, JournalId)).value(inventJournalTable.JournalId);
}
break;
default:
throw error(strFmt("@SYS19306",funcName()));
}
}
}
mercoledì 6 marzo 2019
AX 2012 - Impostare il filtro di una query di un report in base ai record selezionati su una grid
Molto spesso capita di dover lanciare un report filtrandolo per i record selezionati su un grid. In questo esempio vogliamo stampare il report del giornale/i inventariale selezionati. Nel metodo prePromptModifyContract() della nostra controller possiamo creare un metodo set range che costruisce il range in base ai record selezionati dall'utente sul grid:
mercoledì 20 febbraio 2019
AX2009 - Picking - Packing in one shot!
Process:
1.
Generate a sales order: create
a sales order accessing the following path Accounts receivable --> Common
--> Sales order. Create a sales order header defining the customer, address
and contact information. Define if the item on hand allocation should be
performed automatically or manually for the sales order lines in the sales
order header. Performing the reservation in an automatic way the system will
apply directly the FIFO rule, in order to do it there is an enum value in the
setup tab of the sales order header named Reservation (setting it to automatic
the reservation will be automatically driven). Create all the sales lines
related to the specific sales order header according to the items we want to
ship, define also the requested delivery dates for each line. In case we decide
to modify or to apply the automatic reservation of sales order lines in a
second moment we can access the release sales order line for picking at the
path: Inventory management --> Periodic --> Release sales order picking.
At this point we can choose which items to reserve / release for picking. In
order to reserve lines we can click on the button Activation and choose for the
selected lines between three options:
o
All orders that can be fully
delivered
o
All the orders that are
physical reserved
o
All the orders that not
require manual allocation of the stock
Perfoming the allocation the system will try to physical reserve all the
lines selected according to FIFO rule of stock keeping.
Once we have activated all the lines we can release for picking all the
activated lines clicking on the button Release for pick, at this point the
system will create a picking list and a shipment in status registered.
2.
Check of possible shortages in
the shipment: once we have created the shipment we can always check if there is
a lack of items into the warehouse for performing the shipment clicking the
shipment form (inventory management --> common --> shipments) on the
button functions --> possible shortage, in case we need to reserve something
we can perform the reservation manually for each shipment line or automatically
clicking on the button functions --> reserve now
3.
Activation of the shipment: in
order to activate the shipment it's needed to have all the stock available for
the shipment lines. For doing it we have to click on the button Functions
--> Activate.
4.
Picking route generation --
rules: at the activation of the shipment the system will generate the picking
routes, the system has to generate a picking route for each full pallet needed to
pick. And a generic picking route for all the lines remaining or considered as
mixed pallet. In order to understand if a line is full pallet we need to
consider if the picking quantity is a multiple of the pallet quantity defined
in the item master. In case not we have to define the maximum mutiple
applicable and the rest of the line will be considered as part of the picking
route for mixed pallets generation. Consider to create a picking list for each
full pallet to be picked in the warehouse.
5.
Picking route closing and
definition of the palletid: at the closure of the picking route we can close directly each picking line defining the pallet in which we will put each wmsordertrans.
6. Packing slip generation: Once we have closed all the picking lines we can create the packing slip, after declaring the shipment as sent clicking on the button Functions --> Send.
Demonstration in AX2009 In Order to replicate the Subprocess 4. we manage an already generated picking route as reported above, we should access the following path Inventory management --> Common --> Picking Routes.
In this form it is possible to create a picking pallet clicking (after selecting the proper picking route) on the button Create picking pallet.
Then it is possible to assign a WMSOrdertrans line to the pallet picking.
This operation should be performed line by line, it is then possible after clicking on approval details to approve line by line the picking and the pallet picking.
In the same form it is possible to split lines and assign per each line a different pick palletid.
At the end of this procedure the system will ask to deliver items to the final location.
Then entering in the shipment form we should perform the shipment staging as reported below.
We can ship items starting from the shipment form as reported below.
venerdì 8 febbraio 2019
AX 2012 - Cross reference update batch job
In AX i riferimenti incrociati (cross reference) non possono essere messi in batch. Questo job crea in automatico la ricorrenza nel batch job per schedulare giornalmente l'aggiornamento
static void LIL_UpdateCrossRefBatch(Args _args)
{
xRefUpdate::truncateXrefTables();
xRefUpdateIL::updateAllXref(true, false, true);
info("Done, cross reference update batch job created.");
}
martedì 5 febbraio 2019
D365FO - Gestione articoli in conto deposito
Gli
items di proprietà del fornitore sono gestiti con una dimensione
inventariale specifica “owner”.
Ogni valore della dimensione inventariale viene associata ad uno specifico fornitore.
Ogni valore della dimensione inventariale viene associata ad uno specifico fornitore.
La merce
viene ricevuta in un magazzino D365 impiegando una tipologia di transazione
chiamata “consignment replenishment order”.
In fase
di ricezione merce viene automaticamente assegnata la
dimensione owner referenziata al codice fornitore, tale merce non ha
valore di magazzino finchè non avviene il cambio di proprietà della
merce stessa.
Prima di impiegare la merce in produzione / vendita occorre
cambiare la dimensione owner da valore fornitore a valore
interno usando la transazione
“inventory ownership change journal”.
Al cambio di ownership della merce un ordine di acquisto viene generato
automaticamente con riferimento a vendor/items coinvolti e nasce in stato
“Ricevuto”, tale transazione sarà usata per la registrazione della fattura di
acquisto.
É possibile effettuare il conteggio della merce di proprietà del
fornitore anche usando un comune giornale di counting.
martedì 2 ottobre 2018
AX 2012 - Codifica/Decodifica base64 di un file
Con questo job possiamo codificare / decodificare un file in Base64:
static void LIL_EncodeDecode(Args _args)
{
#File
Set permissionSet;
InteropPermission interopPerm;
FileIOPermission fileIOPerm;
boolean fileExists;
str path,
base64Encode,
base64ext;
bindata bindata;
int pos;
container data;
permissionSet = new Set(Types::Class);
path = @"C:\Images\test.png";
fileIOPerm = new FileIOPermission(path,#io_read);
permissionSet.add(fileIOPerm);
interopPerm = new InteropPermission(InteropKind::ClrInterop);
permissionSet.add(interopPerm);
CodeAccessPermission::assertMultiple(permissionSet);
fileExists = System.IO.File::Exists(path);
if(fileExists)
{
bindata = new bindata();
bindata.loadFile(path);
base64Encode = bindata.base64Encode();
}
info(base64Encode);//stringa codificata
//decodifica...
if(base64Encode)
{
pos = strFind(base64Encode, ';', 1, 60);
if(pos)
{
base64ext = subStr(base64Encode, 1, pos-1);
}
pos = strFind(base64Encode, ',', 1, 60);
base64Encode = strDel(base64Encode, 1, pos);
bindata = new bindata();
data = BinData::loadFromBase64(base64Encode);
bindata.setData(data);
bindata.saveFile(@"C:\Images\test2.png");
}
info("Terminato!");
}
martedì 7 agosto 2018
D-365 for Finance and Operations - Come modificare il valore di una variabile di tipo Date durante il debug
Utilizzando il debugger di VS-2015 durante una sessione di analisi sul flusso di un programma, per capire dove intervenire con le modifiche, mi sono imbattuto nella necessità di dove variare il valore di una variabile definita come TransDate.
Sebbene risulti particolarmente semplice variare il valore di campi stringa, numerici e booleani, mi sono accorto subito che non risulta altrettanto semplice e lineare eseguire la variazione nel caso di date.
Se proviamo a variare il valore direttamente dalla finestra di watch, otteniamo un errore di errata immissione.
Dalla mia esperienza con il debugger su applicazioni in C#, ho provato ad eseguire l'assegnazione passando per la finestra immediate, assegnando alla variabile in questione un nuovo valore tramite il costruttore dell'oggetto System.Date di .Net Framework, visto che il codice X++ su D365 alla fine gestisce oggetti di framework.
Ma anche in questo caso si ottiene un errore di errata assegnazione, però in questo il messaggio riporta che è errato il cast.
Alla fine ne consegue che è necessario eseguire il cast dell'oggetto System.Date in "Microsoft.Dynamics.Ax.Xpp.AxShared.Date" per ottenere il risultato desiderato.
oldTransDate = (Microsoft.Dynamics.Ax.Xpp.AxShared.Date) new System.DateTime(2018,03,08)
Forse non è l'unico metodo che sia contemplato, ma sicuramente funziona.
Per gli enumerati invece:
(Dynamics.AX.Application.InventTransType)3
giovedì 26 luglio 2018
D365 - Inventory movement using a template
In D365 we can generate an inventory movement applying a work template and a location directive that can suggest the final location for the movement.
In order to do it we have to define a specific menuitem in the terminal warehouse as follows.
We should define the following parameters:
When we transfer the materials the system will show us to which location we have to move items, as reported below.
Clicking OK the movement is performed.
In order to do it we have to define a specific menuitem in the terminal warehouse as follows.
We should define the following parameters:
- work creation process defined as "Movement by template"
- in the field work template we can specify the work template that will we used in the generation of the works.
When we transfer the materials the system will show us to which location we have to move items, as reported below.
Clicking OK the movement is performed.
Iscriviti a:
Post (Atom)




















