giovedì 20 settembre 2012

AX 2012 - D365FFO - Framework propagazione del valore di testata ordine cliente a tutte le righe

La propagazione di un dato presente in testa ordine cliente a tutte le righe è uno scenario molto frequente in AX. Per questo motivo esite un framework standard che AX mette a disposizione per effettuare questa operazione.

In questo articolo vedremo come utilizzare questo framework estendendo il funzionamento ad un nuovo campo (myField di tipo stringa) che aggiungeremo sia in testata ordine che in riga. L'articolo si riferisce alla versione AX 2012 ma il funzionamento è rimasto invariato sia in AX 4.0 che in AX 2009.

Per prima cosa andiamo in: Contabilità clienti -> impostazioni -> parametri contabilità clienti -> aggiornamenti e clicchiamo sul pulsante "Aggiorna righe ordine":



In questo form sono presenti i campi di testata che attualmente sono gestiti da tale framework. Per ogni campo sono presenti tre possibili azioni:

Mai: Il valore non viene mai propagato alle righe
Sempre: Il valore viene sempre propagato alle righe
Avviso: Il valore viene propagato se l'utente autorizza l'azione

1)Per prima cosa occorre aggiungere il campo "MyField" a SalesTable ed a SalesLine.

2) Aggiungete il campo SalesTable.MyField al FieldGroup HeaderToLineUpdate

3)Modifichiamo la classe aXSalesTable aggiungendo nella class declaration la varianbile che conterrà il valore del campo e successivamente creiamo il metodo parm per tale variabile:

 public str parmMyField(str_MyField= '')  
 {  
   if (!prmisDefault(_MyField))  
   {  
     this.setField(fieldNum(SalesTable, MyField), _MyField);  
   }  
   return SalesTable.MyField;  
 }  

4)Modifichiamo poi la classe aXSalesLine:

 public str parmMyField(str_MyField= '')  
 {  
   if (!prmisDefault(_MyField))  
   {  
     this.setField(fieldNum(SalesLine, MyField), _MyField);  
   }  
   return SalesLine.MyField;  
 }  

 protected void setMyField()  
 {  
      if (this.isMethodExecuted(funcName(), fieldNum(SalesLine, MyField)))  
      {  
           return;  
      }  
      this.setAxSalesTableFields();  
      if (this.isAxSalesTableFieldsSet() || this.AxSalesTable().isFieldModified(fieldNum(SalesTable,MyField)))  
      {  
           this.parmMyField(this.axSalesTable().parmMyField());  
      }  
 }  

5)aggiungere nel metodo setTableFields() il nostro metodo in coda agli altri

 this.setMyField();  

6)Modifichiamo infine il metodo lineUpdateDescription() della classe SalesTable2LineFiled aggiungendo allo switch il case che gestisce il nostro campo:

 case fieldnum(SalesTable, MyField):  
 return fieldid2pname(tableNum(SalesLine), fieldNum(SalesLine, MyField));  

Riaprendo il form dei parametri di aggiornamento dovremmo ora vedere il nuovo campo:


A questo punto occorre solo rigenerare il contenuto della tabella SalesTable2LineParameters per far sì che AX posso gestire l'aggiornamento . Dobbiamo quindi per prima cosa cancellare tutto il contenuto per poi rigenerarlo tramite il metodo initiate(). Questa operazione và fatta per ogni company. Possiamo scrivere il seguente job che esegue tutte le operazioni:

 static void SalesTable2LineParametersInit(Args _args)  
 {  
   DataArea DataArea;  
   SalesTable2LineParameters SalesTable2LineParameters;  
   ;  
   ttsBegin;  
   while select DataArea where dataArea.isVirtual == NoYes::No  
   {  
     changeCompany(DataArea.id)  
     {  
       delete_from SalesTable2LineParameters;  
       SalesTable2LineParameters::initiate();  
     }  
   }  
   ttsCommit;  
   info("terminato");  
 }  

D365FFO:

Per effettuare la stessa modifica su D365 i passaggi sono quasi analoghi, ovviamente i passi 3) 4) e 5) vanno implementati tramite CoC, mentre per il punto 6) occorre sottoscrivere il delegato "lineUpdateDescriptionDelegate" così:

 [SubscribesTo(classStr(SalesTable2LineField), delegateStr(SalesTable2LineField, lineUpdateDescriptionDelegate))]  
   public static void SalesTable2LineField_lineUpdateDescriptionDelegate(FieldId _fieldId, TableId _tableId, EventHandlerResult _result)  
   {  
     FieldLabel       description;  
     switch(_fieldId)  
     {  
       case fieldNum(SalesTable, MyField) :  
         description = fieldId2pname(tableNum(SalesLine), fieldNum(SalesLine, MyField));  
         _result.result(description);  
         break;  
     }  
   }  

Nessun commento:

Posta un commento