May 06, 2013

X++ Code to Create Purchase Order and Post the Invoice.

X++ Code to Create Purchase Order and Post the Invoice.

Following code will create the Purchase order from code and post the invoice as well by making use of "PurchFormLetter" class.

static void TheaxaptaCreatePOInvoice(Args _args)
{

NumberSeq numberSeq;
Purchtable Purchtable;
PurchLine PurchLine;
PurchFormLetter purchFormLetter;
;
ttsbegin;
numberSeq = NumberSeq::newGetNumFromCode(purchParameters::numRefPurchaseOrderId().NumberSequence,true);
// Initialize Purchase order values
Purchtable.initValue();
Purchtable.PurchId = numberSeq.num();
Purchtable.OrderAccount = '3000';
Purchtable.initFromVendTable();
if (!Purchtable.validateWrite())
{
throw Exception::Error;
}
Purchtable.insert();
// Initialize Purchase Line items
PurchLine.PurchId = Purchtable.PurchId;
PurchLine.ItemId = 'B-R14';
PurchLine.createLine(true, true, true, true, true, false);
ttscommit;
purchFormLetter = purchFormLetter::construct(DocumentStatus::Invoice);
purchFormLetter.update(purchtable, // Purchase record Buffer
"Inv_"+purchTable.PurchId, // Invoice Number
systemdateget()); // Transaction date
if (PurchTable::find(purchTable.PurchId).DocumentStatus == DocumentStatus::Invoice)
{
info(strfmt("Posted invoiced journal for purchase order %1",purchTable.PurchId));
}
}


You can Change the document status to packingSlip , if you want to post packing slip by using the same code.

-Harry

May 03, 2013

How to Enable/Disable fields in a dialog

How to Enable/Disable fields in a dialog

If you need to enable/disable the dialog fields use dialog postrun method in your code.
here is some code sample for enabling/disable dialog fields.

public void dialogPostRun(DialogRunbase _dialog)
{
    ;
    super(_dialog);
// allow to call the event methods of this class (e.g. theaxapta1_modified() method)
    _dialog.dialogForm().formRun().controlMethodOverload(true);
    _dialog.dialogForm().formRun().controlMethodOverloadObject(this);
}


Now you can create event methods on your dialog fields like theaxapta1.modified() where you can address other components in the dialog, and modify their properties as well.

public boolean theaxapta1_modified()
{
    FormStringControl   control = dialog.formRun().controlCallingMethod();
    boolean             isFieldModified;
    ;
    isFieldModified = control.modified();
// every time the employee id is changed,it will update the employee name
    if(isFieldModified)
    {
        dlgFldEmplName.value(EmplTable::find(control.text()).Name());
    }
    return isFieldModified;
}


You have to make sure that the control “Employee ID” gets the same control ID as used in the event method name (). This should be done at the time of adding the control to the dialog. for eg:

protected Object dialog(DialogRunbase _dialog, boolean _forceOnClient)
{
    ;
    dialog = super(_dialog, _forceOnClient);
// Add a new field by explicitly specifying the field id.
    // This field id is used to create the field event methods (e.g. 
theaxapta1_modified()).
    dlgFldEmplId = new DialogField(dialog, typeid(EmplId), #dlgFlgEmplIdFieldNo);
    dialog.addCtrlDialogField(dlgFldEmplId.name());
    dlgFldEmplId.init(dialog);
    dlgFldEmplId.label("@SYS81251");
    dlgFldEmplId.helpText("@SYS81251");
    dlgFldEmplId.value(emplId);
// verify that the field name generated by the system is correct
    if(dlgFldEmplId.name() != #dlgFlgEmplIdFieldName)
    {
        throw error(strfmt("@SYS79285", dlgFldEmplId.name(), #dlgFlgEmplIdFieldName));
    }
// Add a new field and let the Dialog framework to do all the work by assigning the field id and initializing the control since there are no event methods for that field.
    dlgFldEmplName = dialog.addFieldValue(typeid(EmplName), emplName, "@SYS54564", "@SYS54564");
    dlgFldEmplName.enabled(false);
    return dialog;
}


Then you can get the value of fields using this method :

public boolean getFromDialog()
{
    boolean ret;
    ret = super();
// get the values from the dialog in order to save them in SysLastValue (using pack() method)
    emplId      = dlgFldEmplId.value();
    emplName    = dlgFldEmplName.value();
    return ret;
}
verify whether a correct employee id has been specified
public boolean fld900_1_validate()
{
    FormStringControl   control = dialog.formRun().controlCallingMethod();
    ;
// verify whether a correct employee id has been specified
    return EmplTable::checkExist(control.text());
}


The pack and unpack methods are used as following:

public container pack()
{
// pack the employee id and employee name and save them in SysLastValue
    return [#CurrentVersion, #CurrentList];
}

public boolean unpack(container packedClass)
{
    boolean  ret;
    Integer  version = conpeek(packedClass,1);
    ;
    switch (version)
    {
        case #CurrentVersion:
// get the employee id and employee name values from the container that has been saved in the SysLastValue record
            [version, #CurrentList] = packedClass;
            ret = true;
            break;
        default:
            ret = false;
    }
    return ret;
}


Finally, in the main method :

static void main(Args args)
{
    SETutorialDialogControlEvent  seTutorialDialogControlEvent = SETutorialDialogControlEvent::construct();
    ;
// show the dialog
    if (seTutorialDialogControlEvent.prompt())
    {
// if OK is pressed, run some code (in that case, run() method should be overriden in the current class)
        seTutorialDialogControlEvent.run();
    }
}


Where SETutorialDialogControlEvent is defined as following:

public static SETutorialDialogControlEvent construct()
{

return new SETutorialDialogControlEvent();
}

As you can see the macro #dlgFlgEmplIdFieldNo is used to assign the ID to the dialog control. 
Overriding the event methods (e.g. modify, validate, selectionChange) on dialog controls is not as straight forward as it is on form controls.


-Harry