Description: Enables the customer to find or filter exceptions and to add exception handling to the user interface of the Crane Team UI Work List table view. Each work instruction in the table is presented to a code extension of the type UNIT_WARNING_CODE_EXTENSION. The code extension uses the attributes of the work instruction to determine what exceptions may exist and what variform to display to enable the user to resolve the exception.
Helper methods from the super class AbstractUnitWarningCodeExtension get damages, holds, OOG, and runtime exceptions. The code extension needs to create a CraneWarning object for each warning; the super class method createCraneWarning() is a convenient helper to do that.
Abstract Base Class: AbstractUnitWarningCodeExtension
Method: List<CraneWarning> execute()
Interface: EUnitWarningCodeExtension
Module: Crane Team UI
Version Added: 2.6
Requires Code Extension Name or Name Pattern: Yes
Code Extension Name or Name Pattern: AbstractUnitWarningCodeExtension
System-Seeded Code Extensions Using this Type: UnitWarningCodeExtension
Code example
The following code adds exception handling to the user interface of the Work List table view:
class UnitWarningCodeExtension extends AbstractUnitWarningCodeExtension {
/**
* Return a list of CraneWarnings
*
* @param inCheShortName che short name
* @param inValueHolder ValueHolder that contains Unit, UFV, and WI attributes
* @param inAdditionalUfvVh ValueHolder with additional aggregated UFV info. This parameter is not null when called from aggregated views such
* as Job List
* @return List<CraneWarning> return a list of CraneWarnings containing icons/variforms and text to be displayed
*/
@Override
public List<CraneWarning> execute(@NotNull String inCheShortName, @NotNull ValueHolder inValueHolder, @Nullable ValueHolder inAdditionalUfvVh) {
List<CraneWarning> craneWarnings = new ArrayList();
// find any holds
Collection<IImpediment> impediments = getHoldsAndPermissions();
for (IImpediment impediment : impediments) {
if (impediment.isImpedimentActive()) {
IFlagType flagType = impediment.getFlagType();
if (FlagPurposeEnum.HOLD.equals(flagType.getPurpose())) {
CraneWarning ce = createCraneWarning(CraneWarning.CraneWarningType.CRANE_WARNING_DEFAULT,
"There is a hold: " + flagType.getId());
craneWarnings.add(ce);
}
}
}
// find any damageItems
ValueHolder[] damageItems = getUnrepairedDamageItems();
if (damageItems != null) {
for (ValueHolder damageItemVh : damageItems) {
CraneWarning ce = createCraneWarning(CraneWarning.CraneWarningType.CRANE_WARNING_HAZARDOUS_0,
CraneVariforms.FORM_CRANE_UNIT_INSPECTOR,
_unitGkey,
"Damage: [type=" + damageItemVh.getFieldValue(UnitField.DMGITEM_TYPE_DESC) + ", component=" +
damageItemVh.getFieldValue(UnitField.DMGITEM_CMP_DESC) + "]");
craneWarnings.add(ce);
}
}
// this is efficient way to get two warnings. The info is already pre-fetched om inUfvMap
// since this extention could be accessed from diffrent different part of application, we assume that _wiGkey and inUfvMap could be nulls
// in this case "per unit" approach is in "else" block
if (inAdditionalUfvVh != null) {
EquipIsoGroupEnum isoType = (EquipIsoGroupEnum) inAdditionalUfvVh.getFieldValue(
MetafieldIdFactory.getCompoundMetafieldId(UnitField.UNIT_PRIMARY_EQTYPE, ArgoRefField.EQTYP_ISO_GROUP));
if (isoType == null || EquipIsoGroupEnum.TD.equals(isoType) || EquipIsoGroupEnum.TN.equals(isoType) || EquipIsoGroupEnum.TG.equals(isoType)) {
CraneWarning ce = createCraneWarning(CraneWarning.CraneWarningType.CRANE_WARNING_TANK_RAIL,
ArgoVariforms.ARG006, (Long)inAdditionalUfvVh.getFieldValue(UnitField.UNIT_EQUIPMENT),
"Tank rail info is required.");
craneWarnings.add(ce);
}
Boolean isOog = inAdditionalUfvVh.getFieldValue(UnitField.UNIT_IS_OOG);
if (isOog != null && isOog) {
CraneWarning ce = createCraneWarning(CraneWarning.CraneWarningType.CRANE_WARNING_OVER_DIMENSION_MULTIPLE, "Container is OOG.");
craneWarnings.add(ce);
}
// this part invoked with "by unit" scenario
} else {
if (_unit != null && _unit.getPrimaryEq().getEqEquipType().isTank()) {
TankRailTypeEnum trte = getTankRailInfomation();
if (trte == null || TankRailTypeEnum.UNKNOWN.equals(trte)) {
CraneWarning ce = createCraneWarning(CraneWarning.CraneWarningType.CRANE_WARNING_TANK_RAIL,
ArgoVariforms.ARG006,
_unit.getPrimaryEq().getEqGkey(),
"Tank rail info is required.");
craneWarnings.add(ce);
}
}
if (_unit != null && _unit.isOutOfGuage()) {
CraneWarning ce = createCraneWarning(CraneWarning.CraneWarningType.CRANE_WARNING_OVER_DIMENSION_MULTIPLE,
"Container is OOG.");
craneWarnings.add(ce);
}
}
// find any runtime exceptions
Collection<Event> warningEventTypes = getCraneWarningEventTypes(inCheShortName, inValueHolder);
Map<String, CraneWarning.CraneWarningType> eventCraneWarningTypeMap = getRuntimeEventWarningTypeMap();
Set<String> filter = new HashSet<>();
for (Event eventType : warningEventTypes) {
// It's possible the system may have duplicated events with legitimate reasons, or due to custom event. Lets filter here.
String key = eventType.getEventTypeId() + ":" + eventType.getEventTypeDescription(); // generate a key so we can avoid duplicates
if (!filter.contains(key)) {
filter.add(key);
CraneWarning ce = createCraneWarning(eventCraneWarningTypeMap.get(eventType.getEventTypeId()), eventType.getEventTypeDescription());
craneWarnings.add(ce);
}
}
return craneWarnings;
}
/**
* This is the limit of calculated warnings. The bigger number, the slower Work List view responce.
* The calculated warmings are guaranteed to be fresh. Non calculated warnings depends on UnitRefresh job results
* @return limit
*/
@Override
int getNumberOfTopRowsToShowUnitWarnings() {
return 20;
}
}