top of page

Charges on purchase order lines

Updated: Dec 3, 2021



In India localization, after doing the GRN for a purchase order, most of the cases, charges are required to be added in the PO lines. There can be many types of charges for instance Freight, Packing Expenses, Excise etc. There charges codes are first created in dynamics ax and basis this, after the GRN, all these charges can be added to the Purchase order lines. These charges will be added to item/ ledger account/ customer/vendor basis the setup done in the charge code initialization. How do you add these charges to a purchase order with hundreds of line items? This is going to be a nightmare for the accounts department at the time of PO invoicing unless it is handled through some functionality. I have created a utility that can take care of this in a less than few seconds. Sharing with you all the code to achieve the same.


In the purchase order form, create a button as shown below

Mark the button properties as shown below.


In the click event of this button, add the below code.


public static void uploadCharges(PurchTable _purchTable)
{
    #AviFiles
    SysOperationProgress        vvProgress;
    FileName                    filename;
    int                         maxRows = 0, row = 0, excelColumn = 1;
    Dialog                      d;
    DialogField                 df1, df2;
    CommaTextIo                 file;
    container                   rec;
    Name                        sheetName;
    MarkupTrans                 markupTrans;
    MarkupTrans_IN              MarkupTrans_IN;
    MarkupTable                 markupTable;
    PurchTable                  purchTable;
    PurchLine                   purchLine;

    CurrencyCode                currencyCode;
    PurchId                     purchId;
    LineNum                     POLineNo, lineNo;
    MarkupCode                  markupCode;
    MarkupValue                 markupValue;
    str                         strNotationalCharge;
    NoYes                       notationalCharge;
    PurchLine_IN                purchLineIN;
    NoYes                       taxParameterEnabled;
    NoYes                       miscChargesEnabled;
    ;
    filename ="";
    vvProgress = new SysOperationProgress();
    vvProgress.setCaption("Charges upload : " );
    vvProgress.setAnimation(#AviUpdate);
    vvProgress.setText("Uploading Charges.");

    d       = new Dialog("Import PO Charges on Lines");
    df1     = d.addField(ExtendedTypeStr("FilenameOpen"));

    purchId     = _purchTable.PurchId;
    if (d.run())
    {
        file = new CommaTextIo(df1.value(), 'r');
        file.inFieldDelimiter(',');

        rec = file.read();
        rec = file.read();

		while (rec)
		{
			ttsBegin;       
			POLineNo            =   conPeek(rec, 1);
			currencyCode        =   conPeek(rec, 2);
			markupCode          =   conPeek(rec, 3);
			markupValue         =   conPeek(rec, 4);
			strNotationalCharge =   conPeek(rec, 5);
			vvProgress.setText(strFmt("%1 of %2. Processing.", row-1, maxRows));
			vvProgress.setCaption("Importing Charges Lines...");
			vvProgress.setAnimation(#AviTransfer);
			if (strNotationalCharge && strNotationalCharge != '0')
					{
						notationalCharge= NoYes::Yes;
					}
			else
				{
					notationalCharge= NoYes::No;
				}

					markupTable     = MarkupTable::find(MarkupModuleType::Vend, markupCode);
					if(purchId =='' || currencyCode == '' || markupCode == '')
					{
						throw error(strFmt("Empty space found in line - %1", lineNo));
					}
					if(!markupTable)
					{
						throw error(strFmt("Charge - %1 doesnot exists in charge master in line no. %2", markupCode, lineNo));
					}
					purchTable  = PurchTable::find(purchId);
					select firstOnly RecId from purchLine
						where purchLine.PurchId     == purchTable.PurchId
							&& purchLine.LineNumber == POLineNo;
					if(!purchLine.RecId)
					{
						throw error("Purchase order - %1 doesnot exists", purchId);
					}
					//Insert MarkupTrans
					markupTrans.clear();
					markupTrans.initValue();
					markupTrans.CurrencyCode    = currencyCode;
					markupTrans.DocumentStatus  = purchTable.DocumentStatus;
					markupTrans.LineNum         = MarkupTrans::lastLineNum(tableNum(purchLine), purchLine.RecId) + 1;
					markupTrans.MarkupCode      = markupCode;
					markupTrans.ModuleType      = MarkupModuleType::Vend;
					markupTrans.TransRecId      = purchLine.RecId;
					markupTrans.TransTableId    = 340;
					markupTrans.Txt             = markupTable.Txt;
					markupTrans.Value           = markupValue;              
					markupTrans.insert();
					if (notationalCharge == 1)
					{
						purchLineIN = purchLine.purchLine_IN();
						purchLineIN.selectForUpdate(true);
						purchLineIN.AssessableValue_IN += markupValue;
						purchLineIN.AssessableValueAccountingCurrency = TaxAssessableValueHandler_IN::calcAssessableValueAccountingCurrency(purchLineIN.AssessableValue_IN, purchLine.CurrencyCode, purchLine.purchTable().AccountingDate);
						purchLineIN.doUpdate();                   
					}
			vvProgress.setText(strfmt('Processing Line Number %1 for Purchase Order %2.', row, _purchTable.PurchId));
			ttsCommit;
			rec = file.read();
			row++;
		}
    }
    if(row > 0)
    {
        info(strfmt("%1 rows have been uploaded.",(row-1)));
    }
    else
    {
        info(strfmt("No rows have been uploaded."));
    }
}

As I say always, before you deploy this in your production system, please test it properly in the UAT and pre-production environments.

Happy Daxing!


233 views0 comments

Recent Posts

See All

Import product master

Importing a product master in Dynamics AX at the time of implementation is a nightmare for most of the consultants or for those who are new into the Dynamics AX/D365 journey. Over the years, with seve

Post: Blog2_Post
bottom of page