Trouble is that you can not change a table relation using extensions, AND you can not using extensions to introduce a new (correct) relation that overrides the existing one.
So instead of just changing the table relation (if that was possible and simple), I needed to do 4 extensions.
1) A new class with a formDataSource extension on form WHSPack, that unlocks the datasource which is actually non-editable, then locking all fields other than CarrierCode and CarrierServiceCode:
    /// <summary>
    /// Extension of active method on WHSShipmentTable datasource
    /// </summary>
    /// <returns>int</returns>
    int active()
    {
        FormDataSource shipmentFDS = this;
        FormDataObject fob;
        int noOfFieldsInDS,field,fieldID;
        DictTable shipmentDT;
        int ret = next active();
        shipmentDT = new DictTable(shipmentFDS.table());
        noOfFieldsInDS = shipmentDT.fieldCnt(TableScope::CurrentTableOnly);
        shipmentFDS.allowEdit(true);
        for(field=1;field <= noOfFieldsInDS;field++)
        {
            fieldID = shipmentDT.fieldCnt2Id(field);
            fob = shipmentFDS.object(fieldID);
            if (fieldId != fieldNum(WHSShipmentTable,CarrierCode) && fieldId != fieldNum(WHSShipmentTable,CarrierServiceCode))
            {
                if (shipmentFDS.object(fieldID))
                {
                    shipmentFDS.object(fieldID).allowEdit(false);
                }
            }
            else
            {
                if (shipmentFDS.object(fieldID))
                {
                    shipmentFDS.object(fieldID).allowEdit(true);
                }
            }
        }
        return ret;
    }
Now we see that the lookup on CarrierServiceCode is NOT filtered by the chosen Carrier, so what to do ?
2) A new class with a table extension on WHSShipmentTable that implemented a new edit method
[ExtensionOf(tableStr(WHSShipmentTable))]
final class HAINWHSShipmentTable_Extension
{
    public edit TMSCarrierServiceCode editCarrierServiceCode(boolean _set, TMSCarrierServiceCode _carrierServiceCode)
    {
        if (_set)
        {
            ttsbegin;
            this.CarrierServiceCode = _carrierServiceCode;
            this.update();
            ttscommit;
        }
        else
        {
            _carrierServiceCode = WHSShipmentTable::find(this.ShipmentId).CarrierServiceCode;
        }
        return _carrierServiceCode;
    }
}
3) A form extension that disables and makes the WHSShipmentTable_CarrierServiceCode field invisible, and introduces the edit-method from step 2 into the form design, remembering to set the 'Lookup button' property to value 'Always'
4) A class with EventHandlers for lookup on the new field using the edit-method from step 2 and OnModified-event on the CarrierCode field to clear the CarrierServiceCode field when CarrierCode is changed:
/// <summary>
/// Event handler for "over riding" default lookup on TMSCarrierService which is wrong due to table relation between WHSShipmentTable and TMSCarrierService
/// having only CarrierServiceCode defined - not taking in to consideration that a CarrierCode might be present - which SHOULD filter lookup on the chosen carrier
/// So normal field is disabled and a field based on a edit method is introduced, and this is handler helps making the correct lookup (filtered on chosen carrier)
/// </summary>
class HAINWHSPackFormCarrierServiceCodeLookup_EventHandler
{
    
    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormControlEventHandler(formControlStr(WHSPack, editCarrierServiceCode), FormControlEventType::Lookup)]
    public static void editCarrierServiceCode_OnLookup(FormControl _sender, FormControlEventArgs _e)
    {
        Query query;
        QueryBuildDataSource qbds;
        SysTableLookup sysTableLookup;
        FormControlCancelableSuperEventArgs event;
        TMSCarrierCode chosenCarrier;
        event = _e as FormControlCancelableSuperEventArgs;
        chosenCarrier = _sender.formRun().design().controlname(formControlStr(WHSPack,WHSShipmentTable_CarrierCode)).valueStr();
        query = new Query();   
        qbds = query.addDataSource(tableNum(TMSCarrierService));
        if (chosenCarrier)
        {
            qbds.addRange(fieldNum(TMSCarrierService,CarrierCode)).value(queryValue(chosenCarrier));
        }
        sysTableLookup = SysTableLookup::newParameters(tableNum(TMSCarrierService),_sender);
        sysTableLookup.addLookupfield(fieldNum(TMSCarrierService,CarrierServiceCode));
        sysTableLookup.addLookupfield(fieldNum(TMSCarrierService,Name));
        sysTableLookup.parmQuery(query);
        sysTableLookup.performFormLookup();
        event.CancelSuperCall();
    }
    /// <summary>
    ///
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    [FormDataFieldEventHandler(formDataFieldStr(WHSPack, WHSShipmentTable, CarrierCode), FormDataFieldEventType::Modified)]
    public static void CarrierCode_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
    {
        WHSShipmentTable shipment;
        shipment = sender.datasource().cursor() as WHSShipmentTable;
        shipment.CarrierServiceCode = '';
        shipment.update();
        sender.datasource().reread();
    }
}
If only you could add fields to table relations, or at least make a new relation that replaces the default one.
Sometimes I miss the old days, where thing could be overridden. ;-)
Comments
Post a Comment