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