public class UpdatePriceFormulaIdOnItemsService__Custom extends SysOperationServiceBase { #OCCRetrycount public void processOperation(UpdatePriceFormulaIdOnItemsContract__Custom _contract) { Query orderQuery; orderQuery = _contract.getQuery(); container compCon = str2con(_contract.parmCompany(), SysAppUtilities__Custom::semiColon); QueryRun queryRun = new QueryRun(orderQuery); while (queryRun.Next()) { InventTable inventTable = queryRun.get(tableNum(InventTable)); try { PriceFormulaId__Custom priceFormulaIdMaster = this.getPriceFormulaId(inventTable); //DSSE if (inventTable && inventTable.PriceFormulaIdMaster__Custom != priceFormulaIdMaster) { ttsbegin; inventTable.selectForUpdate(true); inventTable.PriceFormulaIdMaster__Custom = priceFormulaIdMaster; inventTable.PriceFormulaId__Custom = priceFormulaIdMaster; inventTable.doUpdate(); ttscommit; } for (int i=1; i<=conLen(compCon); i++) { DataAreaId company = conPeek(compCon, i); changecompany(company) { InventTable inventTableSales = InventTable::find(inventTable.ItemId); PriceFormulaId__Custom priceFormulaId = this.getPriceFormulaId(inventTableSales); if (inventTableSales && inventTableSales.PriceFormulaId__Custom != priceFormulaId) { ttsbegin; inventTableSales.selectForUpdate(true); inventTableSales.PriceFormulaIdMaster__Custom = priceFormulaIdMaster; inventTableSales.PriceFormulaId__Custom = priceFormulaId; inventTableSales.doUpdate(); ttscommit; } } } info(strfmt("@_CustomtITServices:SucessUpdateItem", inventTable.ItemId)); } catch (Exception::Deadlock) { retry; } catch (Exception::UpdateConflict) { if (appl.ttsLevel() == 0) { if (xSession::currentRetryCount() >= #RetryNum) { warning(strFmt("@_CustomtITServices:FaliedUpdateItem", inventTable.ItemId)); continue; } else { retry; } } else { warning(strFmt("@_CustomtITServices:FaliedUpdateItem", inventTable.ItemId)); continue; } } catch (Exception::Error) { warning(strFmt("@_CustomtITServices:FaliedUpdateItem", inventTable.ItemId)); continue; } } } public PriceFormulaId__Custom getPriceFormulaId(InventTable _inventTable) { DimensionValue brandDim; EcoResCategoryId ecoResCategoryId; container catCon = conNull(); if (_inventTable) { brandDim = _CustomtITServicesUtility__Custom::getDimension_CustomplayValue(_inventTable.DefaultDimension, SysAppUtilities__Custom::dimensionAttributeNameBrand); catCon = _CustomtITServicesUtility__Custom::getProdCategories(_inventTable.ItemId); } ItemPriceFormula__Custom itemPriceFormula; if (_inventTable.ItemId) { itemPriceFormula = ItemPriceFormula__Custom::findByItem(_inventTable.ItemId); } if (!itemPriceFormula && catCon != conNull() && brandDim) { for (int i=1; i<=conLen(catCon); i++) { ecoResCategoryId = EcoResCategory::find(conPeek(catCon, i)).RecId; itemPriceFormula = ItemPriceFormula__Custom::findByCategoryBrand(ecoResCategoryId, brandDim); if (itemPriceFormula) { break; } } } if (!itemPriceFormula && brandDim) { itemPriceFormula = ItemPriceFormula__Custom::findByBrand(brandDim); } if (!itemPriceFormula && catCon != conNull()) { for (int i=1; i<=conLen(catCon); i++) { ecoResCategoryId = conPeek(catCon, i); itemPriceFormula = ItemPriceFormula__Custom::findByCategory(ecoResCategoryId); if (itemPriceFormula) { break; } } } return itemPriceFormula.PriceFormulaId; } } ===================== public class UpdatePriceFormulaIdOnItemsController__Custom extends SysOperationServiceController { // <summary> /// Creates a new instance of <c>UpdateEndOfLifeOnItemsController__Custom</c> class. /// </summary> /// <param name = "_args">A controller arguments.</param> /// <returns>A instance of <c>SysOperationController</c> class.</returns> public static UpdatePriceFormulaIdOnItemsController__Custom construct(Args _args) { UpdatePriceFormulaIdOnItemsController__Custom controller = new UpdatePriceFormulaIdOnItemsController__Custom(); controller.parmArgs(_args); return controller; } /// <summary> /// Instantiate controller. /// </summary> protected void new() { super(classStr(UpdatePriceFormulaIdOnItemsService__Custom), methodStr(UpdatePriceFormulaIdOnItemsService__Custom, processOperation)); this.parmDialogCaption("@_CustomtITServices:UpdatePriceFormulaIdItem"); } /// <summary> /// Runs the class with the specified arguments. /// </summary> /// <param name = "_args">The specified arguments.</param> public static void main(Args _args) { UpdatePriceFormulaIdOnItemsController__Custom controller = UpdatePriceFormulaIdOnItemsController__Custom::newFromArgs(_args); controller.parmExecutionMode(SysOperationExecutionMode::Synchronous); controller.startOperation(); } /// <summary> /// Instantiate and initialize controller class. /// </summary> /// <param name = "_args">The specified arguments.</param> /// <returns> /// returns controller class. /// </returns> public static UpdatePriceFormulaIdOnItemsController__Custom newFromArgs(Args _args) { UpdatePriceFormulaIdOnItemsController__Custom controller = UpdatePriceFormulaIdOnItemsController__Custom::construct(_args); return controller; } } ================== [DataContractAttribute, SysOperationContractProcessingAttribute(ClassStr(UpdatePriceFormulaIdOnItemsUIbuilder__Custom))] public class UpdatePriceFormulaIdOnItemsContract__Custom { str packedQuery; Str company; /// <summary> /// Initialize query /// </summary> public void initQuery() { Query newQuery; newQuery = new Query(queryStr(InventTable)); this.setQuery(newQuery); } /// <summary> /// Get/Set the packed query /// </summary> /// <param name = "_packedQuery">query</param> /// <returns>string</returns> [ DataMemberAttribute, AifQueryTypeAttribute('_packedQuery', queryStr(InventTable)) ] public str parmPackedQuery(str _packedQuery = packedQuery) { packedQuery = _packedQuery; return packedQuery; } /// <summary> /// Get the query /// </summary> /// <returns>Query</returns> public Query getQuery() { return new Query(SysOperationHelper::base64Decode(packedQuery)); } /// <summary> /// Set the query /// </summary> /// <param name = "_query">query</param> public void setQuery(Query _query) { packedQuery = SysOperationHelper::base64Encode(_query.pack()); } // <summary> /// Gets or sets the value of the datacontract parameter company. /// </summary> /// <param name="_company"> /// The new value of the datacontract parameter company; optional. /// </param> /// <returns> /// The current value of datacontract parameter company /// </returns> [ DataMemberAttribute, SysOperationLabelAttribute(literalStr("@_CustomtITServices:Company")), SysOperation_CustomplayOrderAttribute("1") ] public Str parmCompany(Str _company = company) { company = _company; return company; } }
This blog is contains coding reference related to Microsoft AX 2012 and D365 finance and operations and Power platform
Showing posts with label SysOperations. Show all posts
Showing posts with label SysOperations. Show all posts
Tuesday, April 23, 2024
Sysoperation framework with Aot query
Saturday, April 24, 2021
Sysoperations frameworks Tips and tricks in AX
protected ClassDescription defaultCaption() { return "@CashManagement:CashFlowTimeSeriesInitializeControllerCaption"; } public ClassDescription caption() { return this.defaultCaption(); } /// <summary> /// Indicates if the class must run in batch or not. /// </summary> /// <returns> /// Always returns false. /// </returns> /// <remarks> /// This method must be in this class because it is called from the <c>dialogRunbase</c> class. /// </remarks> public boolean mustGoBatch() { return false; } /// <summary> /// Determines whether the job can be executed in batch. /// </summary> /// <returns> /// false if the job cannot be executed in batch; otherwise, true. /// </returns> public boolean canGoBatch() { return false; } /// <summary> /// Sets whether to show the batch tab or not. /// </summary> /// <param name = "_showBatchTab">Flag to identify whether to show the batch tab or not.</param> /// <returns>False for batch tab to be invisible</returns> public boolean showBatchTab(boolean _showBatchTab = showBatchTab) { return false; } public boolean showBatchRecurrenceButton(boolean _showBatchRecurrenceButton = showBatchRecurrenceButton) { return false; }
Tuesday, April 13, 2021
How to pass marked records from grid to sysoperations framework in AX
Controller class
/// <summary> /// /// </summary> class Sales_UpdateMoDSalesOrderController extends SysOperationServiceController { public static Sales_UpdateMoDSalesOrderController construct(Args _args) { Sales_UpdateMoDSalesOrderController controller = new Sales_UpdateMoDSalesOrderController(classStr( Sales_UpdateMoDSalesOrderService ), methodStr( Sales_UpdateMoDSalesOrderService, updateMoDSalesOrder ), SysOperationExecutionMode::Synchronous); controller.parmArgs( _args ); return controller; } public static void main(Args _args) { Set recordSet; SalesTable salesTable; MultiSelectionHelper multiselectionHelper; Sales_UpdateMoDSalesOrderContract dataContract; Sales_UpdateMoDSalesOrderController controller; controller = Sales_UpdateMoDSalesOrderController::construct( _args ); // Get marked records from calling form if (_args && _args.caller() is FormRun) { recordSet = new Set(Types::Record); multiselectionHelper = MultiSelectionHelper::createFromCaller(_args.caller()); salesTable = multiselectionHelper.getFirst(); while (salesTable) { recordSet.add(salesTable); salesTable = multiselectionHelper.getNext(); } } // Put records from calling datasource into dataContract dataContract = controller.getDataContractObject(); if (dataContract is Sales_UpdateMoDSalesOrderContract) { dataContract.parmRecordCon(recordSet.pack()); } controller.startOperation(); } }
Contract class
/// <summary> /// The data contract for Intercompany update of Mode of delivery /// </summary> [ DataContract, SysOperationGroup('GeneralGroup',"@SYS81043",'1',FormArrangeMethod::Vertical) ] class Sales_UpdateMoDSalesOrderContract implements SysOperationInitializable, SysOperationValidatable { UpsModeOfDelivery upsModeOfDelivery; container recordCon; /// <summary> /// Indicates whether the contract is valid. /// </summary> /// <returns> /// A Boolean value that indicates whether the contract is valid. /// </returns> public boolean validate() { boolean isValid = true; return isValid; } /// <summary> /// Initailizes the default values to parameters. /// </summary> public void initialize() { } /// <summary> /// Method used to specify the data memmber attribute /// </summary> /// <param> /// <name>parmShipmentDate</name>is used to set and get the shipmentDate /// </param> [ DataMember, SysOperationGroupMember('GeneralGroup'), SysOperationDisplayOrder('1'), SysOperationLabelAttribute(literalstr("@Warehouse:UpsModeOfDelivery")) ] public UpsModeOfDelivery parmUpsModeOfDelivery( UpsModeOfDelivery _upsModeOfDelivery = upsModeOfDelivery ) { upsModeOfDelivery = _upsModeOfDelivery; return upsModeOfDelivery; } /// <summary> /// Method used to specify the data memmber attribute /// </summary> /// <param name = "_recordCon"></param> /// <returns></returns> [DataMemberAttribute, SysOperationControlVisibilityAttribute(false)] public container parmRecordCon(container _recordCon = recordCon) { recordCon = _recordCon; return recordCon; } }
Service class
class Sales_UpdateMoDSalesOrderService { /// <summary> /// Creates transfer order for from and to wareshouse combination /// </summary> /// <param name = "_contract">TransferOrderCreateContract from dialog</param> public void updateMoDSalesOrder(Sales_UpdateMoDSalesOrderContract _contract) { Set recordSet; Common record; SalesTable salesTable; SetEnumerator se; ModeOfDeliverySetup smModeOfDeliverySetup; // Process records if (conLen(_contract.parmRecordCon()) > 0) { recordSet = Set::create(_contract.parmRecordCon()); se = recordSet.getEnumerator(); while (se.moveNext()) { record = se.current(); switch (record.TableId) { case tableNum(SalesTable): salesTable = record; salesTable.DlvMode = _contract.parmUpsModeOfDelivery(); info(strFmt("%1 %2", salesTable.SalesId, salesTable.DlvMode)); break; default: break; } } } } }
Sysoperations framework sample
UIBuilder class
/// <summary> /// The <c>TransferOrderCreateProposalUIBuilder</c> The data contract for Transfer order creation. /// </summary> class TransferOrderCreateProposalUIBuilder extends SysOperationAutomaticUIBuilder { DialogField toDate; DialogField timeFence; DialogField fromSite; DialogField fromWarehouse,toWarehouses; DialogField proposalModel; DialogField recalculateQuantities; DialogField replaceCurrentProposals; SysLookupMultiSelectCtrl ctrlSources; /// <summary> /// /// </summary> public void postBuild() { TransferOrderCreateProposalContract contract = this.dataContractObject() as TransferOrderCreateProposalContract; toDate = this.bindInfo().getDialogField(contract, methodStr(TransferOrderCreateProposalContract, parmToDate)); timeFence = this.bindInfo().getDialogField(contract, methodStr(TransferOrderCreateProposalContract, parmTimeFence)); fromSite = this.bindInfo().getDialogField(contract, methodStr(TransferOrderCreateProposalContract, parmInventSiteId)); fromWarehouse = this.bindInfo().getDialogField(contract, methodStr(TransferOrderCreateProposalContract, parmInventLocationIdFrom)); toWarehouses = this.bindInfo().getDialogField(contract, methodStr(TransferOrderCreateProposalContract, parmInventLocationIdTo)); proposalModel = this.bindInfo().getDialogField(contract, methodStr(TransferOrderCreateProposalContract, parmProposalModel)); recalculateQuantities = this.bindInfo().getDialogField(contract, methodStr(TransferOrderCreateProposalContract, parmRecalculateQuantities)); replaceCurrentProposals = this.bindInfo().getDialogField(contract, methodStr(TransferOrderCreateProposalContract, parmReplaceCurrentProposal)); replaceCurrentProposals.allowEdit(false); recalculateQuantities.visible(false); toWarehouses.lookupButton(FormLookupButton::Always); switch (this.controller().parmArgs().menuItemName()) { case menuItemActionStr(TransferOrderCreateProposal): replaceCurrentProposals.value(true); recalculateQuantities.value(false); toDate.value(DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone())); break; case menuItemActionStr(TransferOrderEditProposal): TransferOrderProposal transferOrderProposal = this.controller().parmArgs().record(); fromSite.allowEdit(false); fromWarehouse.allowEdit(false); proposalModel.allowEdit(false); recalculateQuantities.value(false); replaceCurrentProposals.value(false); toDate.value(transferOrderProposal.ToDate); fromSite.value(transferOrderProposal.InventSiteIdFrom); timeFence.value(transferOrderProposal.timeFence); proposalModel.value(transferOrderProposal.ProposalModel); fromWarehouse.value(transferOrderProposal.InventLocationIdFrom); break; case menuItemActionStr(TransferOrderRecalculateQty): toDate.visible(false); fromSite.visible(false); fromWarehouse.visible(false); timeFence.visible(false); toWarehouses.visible(false); replaceCurrentProposals.visible(false); recalculateQuantities.value(true); replaceCurrentProposals.value(false); break; default: break; } } /// <summary> /// /// </summary> public void postRun() { if ( this.controller().parmArgs().menuItemName() == menuItemActionStr(TransferOrderCreateProposal) ) { this.WarehouseLookup(false); } else if ( this.controller().parmArgs().menuItemName() == menuItemActionStr(TransferOrderEditProposal) ) { this.WarehouseLookup(true); } } /// <summary> /// Multi select lookup for warehouse /// </summary> /// <param name = "_preselectValues">true for preselect lookup values</param> public void WarehouseLookup(boolean _preselectValues) { Query query = new Query(); QueryBuildDataSource qbdsWarehouses = query.addDataSource(tablenum(InventLocation)); container selectedFields = [tableNum(InventLocation), fieldNum(InventLocation, InventLocationId)]; qbdsWarehouses.fields().addField(fieldNum(InventLocation, InventLocationId)); qbdsWarehouses.fields().addField(fieldNum(InventLocation, Name)); ctrlSources = SysLookupMultiSelectCtrl::constructWithQuery(this.dialog().formRun(), toWarehouses.control(), query, true, selectedFields); if (_preselectValues) { TransferOrderProposal transferOrderProposal, transferOrderProposalLoc = this.controller().parmArgs().record(); InventLocation inventLocation; container selectedRecIds; container selectedValues; while select InventLocationIdTo from transferOrderProposal group by InventLocationIdTo where transferOrderProposal.ProposalModel == transferOrderProposalLoc.ProposalModel { inventLocation = InventLocation::find(transferOrderProposal.InventLocationIdTo); selectedRecIds += inventLocation.RecId; selectedValues += inventLocation.InventLocationId; } ctrlSources.set([selectedRecIds, selectedValues]); } } }
Service class
/// <summary> /// The <c>TransferOrderCreationProposalService</c> is used to create Transfer order proposals /// for planned orders. /// </summary> class TransferOrderCreateProposalService { List toWareHouse; Query query; counter timeFence, lineNum; boolean replaceCurrentProposal; String20 proposalModel; TransDate fromDate,toDate; InventTable inventTable; InventSiteId fromInventSite; InventLocationId fromWarehouse; Enumerator enumerator; TransferOrderCreateProposalContract contract; /// <summary> /// Entry point for creating Transfer order propsal lines based on proposal model /// </summary> /// <param name = "_contract">TransferOrderCreateProposalContract passed from dialog</param> public void createTransferOrderProposal(TransferOrderCreateProposalContract _contract) { contract = _contract; this.initializeQuery(); this.initializeParameters(); ttsbegin; this.deleteTranferProposalsLines(proposalModel, replaceCurrentProposal); this.createTransferOrderProposalLines(); ttscommit; } /// <summary> /// Method is used to delete the Transfer order propsal lines based on proposal model /// </summary> /// <param name = "_proposalModel">from dialog</param> /// <param name = "_replaceCurrentProposal">true if creating new transfer order proposal</param> public void deleteTranferProposalsLines(ProposalModelId _proposalModel, boolean _replaceCurrentProposal) { if (_replaceCurrentProposal) { TransferOrderProposal transferOrderProposal; delete_from transferOrderProposal where transferOrderProposal.ProposalModel == _proposalModel; } } /// <summary> /// intilalize parameters /// </summary> public void initializeParameters() { toDate = contract.parmToDate(); timeFence = contract.parmTimeFence(); fromDate = contract.parmToDate() - timeFence; toWareHouse = contract.parmInventLocationIdTo(); fromWarehouse = contract.parmInventLocationIdFrom(); proposalModel = contract.parmProposalModel(); fromInventSite = contract.parmInventSiteId(); replaceCurrentProposal = contract.parmReplaceCurrentProposal(); } /// <summary> /// initialize query object /// </summary> public void initializeQuery() { query = contract.parmQuery(); } /// <summary> /// Method is used to create the Transfer order propsal lines based on proposal model /// </summary> public void createTransferOrderProposalLines() { Real workingdays; InventLocation inventLocation; InventQtyTotal inventQty; RecordInsertList transferOrderProposalInsertList = null; TransferOrderProposal transferOrderProposal; QueryRun queryRun = new QueryRun(query); while (queryRun.next()) { transferOrderProposalInsertList = new RecordInsertList(tablenum(TransferOrderProposal)); inventTable = queryRun.get(tablenum(InventTable)); enumerator = toWareHouse.getEnumerator(); try { ttsbegin; while (enumerator.moveNext()) { if (!replaceCurrentProposal) { if (TransferOrderProposal::exist(inventTable.ItemId, enumerator.current(), proposalModel)) { lineNum++; continue; } } transferOrderProposal.clear(); lineNum++; transferOrderProposal.LineNum = lineNum; transferOrderProposal.ItemId = inventTable.ItemId; transferOrderProposal.ItemName = inventTable.itemName(); transferOrderProposal.ToDate = toDate; transferOrderProposal.TimeFence = timeFence; transferOrderProposal.InventSiteIdFrom = fromInventSite; inventLocation = InventLocation::find(fromWarehouse); transferOrderProposal.InventLocationIdFrom = inventLocation.InventLocationId; transferOrderProposal.InventLocationIdFromName = inventLocation.Name; transferOrderProposal.InventSiteIdTo = fromInventSite; inventLocation = InventLocation::find(enumerator.current()); transferOrderProposal.InventLocationIdTo = inventLocation.InventLocationId; transferOrderProposal.InventLocationIdToName = inventLocation.Name; transferOrderProposal.ProposalModel = proposalModel; transferOrderProposal.CoverageGroup = inventTable.ReqGroupId; transferOrderProposal.RefillAvailablePhysical = this.getRefillItemAvailPhysicalBySiteAndWarehouse(transferOrderProposal.ItemId, transferOrderProposal.InventSiteIdFrom, transferOrderProposal.InventLocationIdFrom); inventQty = 0; inventQty = this.getItemTotalSalesBySiteAndWarehouse(transferOrderProposal.ItemId, transferOrderProposal.InventSiteIdFrom, transferOrderProposal.InventLocationIdFrom, fromDate, toDate); workingdays = 0; workingdays = this.getNumOfWorkingdays(transferOrderProposal.InventLocationIdFrom, fromDate, toDate); transferOrderProposal.RefillSalesPerDay = workingdays ? inventQty / workingdays : 0; transferOrderProposal.RefillCoverageDays = transferOrderProposal.RefillSalesPerDay ? transferOrderProposal.RefillAvailablePhysical / transferOrderProposal.RefillSalesPerDay : 0; transferOrderProposal.DCAvailablePhysical = this.getDCItemAvailPhysicalBySiteAndWarehouse(transferOrderProposal.ItemId, transferOrderProposal.InventSiteIdTo, transferOrderProposal.InventLocationIdTo); inventQty = 0; inventQty = this.getItemTotalSalesBySiteAndWarehouse(transferOrderProposal.ItemId, transferOrderProposal.InventSiteIdTo, transferOrderProposal.InventLocationIdTo, fromDate, toDate); workingdays = 0; workingdays = this.getNumOfWorkingdays(transferOrderProposal.InventLocationIdTo,fromDate, toDate); transferOrderProposal.DCSalesPerDay = workingdays ? inventQty / workingdays : 0; transferOrderProposal.DCCoverageDays = transferOrderProposal.DCSalesPerDay ? transferOrderProposal.DCAvailablePhysical / transferOrderProposal.DCSalesPerDay : 0; transferOrderProposalInsertList.add(transferOrderProposal); } transferOrderProposalInsertList.insertDatabase(); ttscommit; } catch(Exception::Error) { throw error( "@Planning:TransferOrderPropsalCreationError"); } catch(Exception::Deadlock ) { if(xSession::currentRetryCount() >= Planning_Constants::MaxOCCRetryCount) { throw Exception::Deadlock; } else { retry; } } catch(Exception::UpdateConflict) { if (appl.ttsLevel() == 0) { if (xSession::currentRetryCount() >= Planning_Constants::MaxOCCRetryCount) { throw Exception::UpdateConflictNotRecovered; } else { retry; } } else { throw Exception::UpdateConflict; } } info(strFmt("@Planning:TransferOrderProposalCreationSuccess", lineNum, proposalModel)); } } /// <summary> /// Calculate total sales between daterange for each item based on site and warehouse /// </summary> /// <param name = "_itemId"></param> /// <param name = "_inevntSiteId"></param> /// <param name = "_inventLocationId"></param> /// <returns></returns> public InventQtyTotal getItemTotalSalesBySiteAndWarehouse(ItemId _itemId, InventSiteId _inventSiteId, InventLocationId _inventLocationId, FromDate _fromDate, ToDate _toDate) { InventDim inventDim; InventTrans inventTrans; InventTransOrigin inventTransOrigin; select sum(Qty) from inventTrans where inventTrans.ItemId == _itemId && inventTrans.DatePhysical >= _fromDate && inventTrans.DatePhysical <= _toDate exists join inventTransOrigin where inventTransOrigin.RecId == inventTrans.InventTransOrigin && inventTransOrigin.ReferenceCategory == InventTransType::Sales exists join inventDim where inventDim.inventDimId == inventTrans.inventDimId && inventDim.InventSiteId == _inventSiteId && inventDim.InventLocationId == _inventLocationId; return abs(inventTrans.Qty); } /// <summary> /// calculates number of working days based on warehouse or Legal entity base calender /// </summary> /// <param name = "_inventLocationId"></param> /// <returns></returns> public Real getNumOfWorkingdays(InventLocationId _inventLocationId, FromDate _fromDate, ToDate _toDate) { Real workingdays; CalendarId calenderId; WorkCalendarDate WorkCalendarDate; if (InventLocation::find(_inventLocationId).ReqCalendarId) { calenderId = InventLocation::find(_inventLocationId).ReqCalendarId; } else { calenderId = CompanyInfo::find().ShippingCalendarId; } select count(RecId) from WorkCalendarDate where WorkCalendarDate.CalendarId == calenderId && (WorkCalendarDate.TransDate >= _fromDate && WorkCalendarDate.TransDate <= _toDate) && WorkCalendarDate.WorkTimeControl == WorkTimeControl::Open; workingdays = any2Real(WorkCalendarDate.RecId); if (!calenderId) { Real noOfDays = _toDate - _fromDate; //Formula for calculating working days if No base calender is present workingdays = (abs(noOfDays) / Planning_Constants::NumOfDaysInAWeek ) * Planning_Constants::MinWorkingDaysInAWeek; } return abs(workingdays); } /// <summary> /// Calculate avaialable physical inventory for each item based on site and warehouse /// </summary> /// <param name = "_itemId"></param> /// <param name = "_inevntSiteId"></param> /// <param name = "_inventLocationId"></param> /// <returns>Refill warehouse avail physical</returns> public InventQtyAvailPhysical getRefillItemAvailPhysicalBySiteAndWarehouse(ItemId _itemId, InventSiteId _inventSiteId, InventLocationId _inventLocationId) { InventDim inventDim; InventDimParm inventDimParm; inventDim = this.initInventDim(_inventSiteId, _inventLocationId); inventDimParm.initFromInventDim(inventDim); return abs(InventOnhand::newParameters(_itemId, inventDim, inventDimParm).availPhysical()); } /// <summary> /// Calculate avaialable physical inventory for each item based on site and warehouse /// </summary> /// <param name = "_itemId"></param> /// <param name = "_inevntSiteId"></param> /// <param name = "_inventLocationId"></param> /// <returns>DC warehouse avail physical</returns> public InventQtyAvailPhysical getDCItemAvailPhysicalBySiteAndWarehouse(ItemId _itemId, InventSiteId _inventSiteId, InventLocationId _inventLocationId) { InventDim inventDim; InventTrans inventTrans; InventDimParm inventDimParm; inventTransOrigin InventTransOrigin; InventQty totalAvailPhysical; inventDim = this.initInventDim(_inventSiteId, _inventLocationId); inventDimParm.initFromInventDim(inventDim); totalAvailPhysical = abs(InventOnhand::newParameters(_itemId, inventDim, inventDimParm).availPhysical()); inventDim.clear(); select sum(Qty) from inventTrans where inventTrans.ItemId == _itemId && inventTrans.DatePhysical == dateNull() && inventTrans.StatusIssue == StatusIssue::ReservPhysical exists join inventTransOrigin where inventTransOrigin.RecId == inventTrans.InventTransOrigin && (inventTransOrigin.ReferenceCategory == InventTransType::TransferOrderShip || inventTransOrigin.ReferenceCategory == InventTransType::TransferOrderReceive) exists join inventDim where inventDim.inventDimId == inventTrans.inventDimId && inventDim.InventSiteId == _inventSiteId && inventDim.InventLocationId == _inventLocationId; return totalAvailPhysical + abs(inventTrans.Qty); } /// <summary> /// Initilalize InevntDim by site and warehouse /// </summary> /// <param name = "_inevntSiteId">SiteId from proposal line</param> /// <param name = "_inventLocationId">LocationId from proposal line</param> /// <returns>InventDim buffer</returns> public InventDim initInventDim(InventSiteId _inevntSiteId, InventLocationId _inventLocationId) { InventDim inventDim; inventDim.InventSiteId = _inevntSiteId; inventDim.InventLocationId = _inventLocationId; inventDim = InventDim::findOrCreate(inventDim); return inventDim; } /// <summary> /// Recalculates and updates avail physical quanties /// </summary> /// <param name = "_contract">TransferOrderCreateProposalContract from dialog</param> public void recalculateQuanties(TransferOrderCreateProposalContract _contract) { TransferOrderProposal transferOrderProposal; InventQtyTotal inventQty; Real workingdays; while select forupdate transferOrderProposal where transferOrderProposal.ProposalModel == _contract.parmProposalModel() { try { ttsbegin; transferOrderProposal.RefillAvailablePhysical = this.getRefillItemAvailPhysicalBySiteAndWarehouse(transferOrderProposal.ItemId, transferOrderProposal.InventSiteIdFrom, transferOrderProposal.InventLocationIdFrom); inventQty = 0; inventQty = this.getItemTotalSalesBySiteAndWarehouse(transferOrderProposal.ItemId, transferOrderProposal.InventSiteIdFrom, transferOrderProposal.InventLocationIdFrom, transferOrderProposal.ToDate - transferOrderProposal.TimeFence, transferOrderProposal.ToDate); workingdays = 0; workingdays = this.getNumOfWorkingdays(transferOrderProposal.InventLocationIdFrom, transferOrderProposal.ToDate - transferOrderProposal.TimeFence, transferOrderProposal.ToDate); transferOrderProposal.RefillCoverageDays = transferOrderProposal.RefillSalesPerDay ? transferOrderProposal.RefillAvailablePhysical / transferOrderProposal.RefillSalesPerDay : 0; transferOrderProposal.DCAvailablePhysical = this.getDCItemAvailPhysicalBySiteAndWarehouse(transferOrderProposal.ItemId, transferOrderProposal.InventSiteIdTo, transferOrderProposal.InventLocationIdTo); inventQty = 0; inventQty = this.getItemTotalSalesBySiteAndWarehouse(transferOrderProposal.ItemId, transferOrderProposal.InventSiteIdTo, transferOrderProposal.InventLocationIdTo, transferOrderProposal.ToDate - transferOrderProposal.TimeFence, transferOrderProposal.ToDate); workingdays = 0; workingdays = this.getNumOfWorkingdays(transferOrderProposal.InventLocationIdFrom, transferOrderProposal.ToDate - transferOrderProposal.TimeFence, transferOrderProposal.ToDate); transferOrderProposal.DCCoverageDays = transferOrderProposal.DCSalesPerDay ? transferOrderProposal.DCAvailablePhysical / transferOrderProposal.DCSalesPerDay : 0; transferOrderProposal.update(); ttscommit; } catch(Exception::Error) { throw error( "@Planning:TransferOrderPropsalCreationError"); } catch(Exception::Deadlock ) { if(xSession::currentRetryCount() >= Planning_Constants::MaxOCCRetryCount) { throw Exception::Deadlock; } else { retry; } } catch(Exception::UpdateConflict) { if (appl.ttsLevel() == 0) { if (xSession::currentRetryCount() >= Planning_Constants::MaxOCCRetryCount) { throw Exception::UpdateConflictNotRecovered; } else { retry; } } else { throw Exception::UpdateConflict; } } } } }
Controller class
/// <summary> /// The controller for handling bulk Transfer order proposal creation. /// </summary> class TransferOrderCreateProposalController extends SysOperationServiceController { /// <summary> /// Constructs a new instance of the <c>TransferOrderCreateProposalController</c>. /// </summary> /// <param name = "_args">A set of arguments that is used for Transfer order proposal creation.</param> /// <returns>A new instance of the <c>TransferOrderCreateProposalController</c>.</returns> public static TransferOrderCreateProposalController construct(Args _args) { TransferOrderCreateProposalController controller; switch (_args.menuItemName()) { case menuItemActionStr(TransferOrderEditProposal): case menuItemActionStr(TransferOrderCreateProposal): controller = new TransferOrderCreateProposalController(classStr( TransferOrderCreateProposalService ), methodStr( TransferOrderCreateProposalService, createTransferOrderProposal ), SysOperationExecutionMode::Synchronous); break; case menuItemActionStr(TransferOrderRecalculateQty): controller = new TransferOrderCreateProposalController(classStr( TransferOrderCreateProposalService ), methodStr( TransferOrderCreateProposalService, recalculateQuanties ), SysOperationExecutionMode::Synchronous); break; default: break; } controller.parmArgs( _args ); return controller; } public static void main(Args _args) { TransferOrderCreateProposalController controller = TransferOrderCreateProposalController::construct( _args ); controller.startOperation(); //Only run if in Non batch mode if (controller.startResult == SysOperationStartResult::Started) { controller.RefreshCallingForm(_args); } } /// <summary> /// Refresh TransferOrderProposal from when not running in batch /// </summary> /// <param name = "_args"></param> private void RefreshCallingForm(args _args) { if (_args && _args.caller() && _args.caller() is formRun) { TransferOrderCreateProposalContract contract = this.getDataContractObject(); FormStringControl proposalModel; FormRun callerFormRun = _args.caller() as formRun; proposalModel = callerFormRun.design().controlName(formControlStr(TransferOrderProposal, ProposalModel)); proposalModel.Text(contract.parmProposalModel()); proposalModel.modified(); callerFormRun.dataSource(1).research(true); callerFormRun.dataSource(1).refresh(); callerFormRun.dataSource(2).research(true); callerFormRun.dataSource(2).refresh(); } } protected boolean canRunInNewSession() { return true; } }
Contract class
/// <summary> /// The data contract for Transfer order creation. /// </summary> [ DataContract, SysOperationGroup("HistoricalHorizoGroup","@:HistoricalHorizon","1",FormArrangeMethod::Vertical), SysOperationGroup("ReplaceCurrentProposalGroup","@:ReplaceCurrentProposal","2",FormArrangeMethod::Vertical), SysOperationContractProcessing(classStr(TransferOrderCreateProposalUIBuilder)) ] public class TransferOrderCreateProposalContract implements SysOperationInitializable, SysOperationValidatable { Query query; str packedQuery; TransDate fromDate,toDate; NoYesId replaceCurrentProposal; NoYesId recalculateQuantities; InventSiteId inventSiteId; InventLocationId inventLocationIdFrom; Integer timeFence; ProposalModelId proposalModel; List inventLocationIdTo; /// <summary> /// Indicates whether the contract is valid. /// </summary> /// <returns> /// A Boolean value that indicates whether the contract is valid. /// </returns> public boolean validate() { boolean isValid = true; if (!proposalModel) { isValid = checkFailed(strFmt("@SYS135209", "@:ProposalModel")); } else if (!this.confirmReplaceCurrentProposal(proposalModel, replaceCurrentProposal) && !recalculateQuantities) { isValid = false; } if (!replaceCurrentProposal && !recalculateQuantities) { isValid = this.checkProposalExists(); } return isValid; } /// <summary> /// check for transfer order proposals exists /// </summary> /// <returns>A Boolean value that indicates whether the contract is valid</returns> public boolean checkProposalExists() { Query queryVal; Counter lineNum; container results; Enumerator enumerator; InventTable inventTable; boolean isValid = true; if (query == null && packedQuery) { queryVal = new Query( SysOperationHelper::base64Decode( packedQuery ) ); } else { queryVal = query; } QueryRun queryRun = new QueryRun(queryVal); while (queryRun.next()) { inventTable = queryRun.get(tablenum(InventTable)); enumerator = inventLocationIdTo.getEnumerator(); while (enumerator.moveNext()) { if (TransferOrderProposal::exist(inventTable.ItemId, enumerator.current(), proposalModel)) { lineNum++; results += strFmt("@:ProposalExistsValidation", inventTable.ItemId, enumerator.current()); if (lineNum >= 100) { break; } } } } if (conLen(results) > 0) { warning(con2Str(results)); DialogButton diagBut; str strMessage = "@:TransferOrderAddlinesConfirmation"; str strTitle = "@ApplicationPlatform:SystemNotificationTitle"; diagBut = Box::okCancel(strMessage, DialogButton::Cancel, // Initial focus is on the Cancel button. strTitle); if (diagBut == DialogButton::Cancel) { isValid = false; } else { isValid = true; } } return isValid; } /// <summary> /// confirm from user to replace Marked/modifeied transfer order proposals /// </summary> /// <param name = "_proposalModel">user selected value</param> /// <param name = "_replaceCurrentProposal">true</param> /// <returns>A Boolean value that indicates whether the contract is valid </returns> public boolean confirmReplaceCurrentProposal(ProposalModelId _proposalModel, boolean _replaceCurrentProposal) { boolean ret = true; if(_proposalModel && _replaceCurrentProposal) { TransferOrderProposal transferOrderProposal; select firstonly RecId from transferOrderProposal where transferOrderProposal.ProposalModel == _proposalModel && (transferOrderProposal.AddToShipment == NoYes::Yes || transferOrderProposal.CaseQty != 0); if (transferOrderProposal.RecId) { DialogButton diagBut; str strMessage = "@:PropsalReplaceConfirmationText"; str strTitle = "@ApplicationPlatform:SystemNotificationTitle"; diagBut = Box::okCancel(strMessage, DialogButton::Cancel, // Initial focus is on the Cancel button. strTitle); if (diagBut == DialogButton::Cancel) { ret = false; } else { ret = true; } } } else { ret = true; } return ret; } /// <summary> /// Initailizes the default values to parameters. /// </summary> public void initialize() { query = new Query( queryStr( InventTableQuery ) ); } /// <summary> /// load query from syslast value /// </summary> /// <param name = "_packedQuery"></param> /// <returns> packed query string</returns> [ DataMember, AifQueryTypeAttribute('_packedQuery', queryStr( InventTableQuery ) ) ] public str parmPackedQuery( str _packedQuery = packedQuery) { packedQuery = _packedQuery; return packedQuery; } /// <summary> /// Encode/decode the query and set or get /// </summary> /// <param name = "_query"></param> /// <returns>query object</returns> public Query parmQuery( Query _query = query ) { if ( prmisDefault( _query ) && query == null ) { query = new Query( SysOperationHelper::base64Decode( packedQuery ) ); } else { packedQuery = SysOperationHelper::base64Encode( _query.pack() ); query = _query; } return query; } /// <summary> /// Method used to specify the data memmber attribute /// </summary> /// <param> /// <name>parmFromDate</name>is used to set and get the FromDate /// </param> [ DataMember, SysOperationGroupMember("HistoricalHorizoGroup"), SysOperationDisplayOrder("1"), SysOperationLabelAttribute(literalstr("@:TransferProposalModel")) ] public ProposalModelId parmProposalModel( ProposalModelId _proposalModel = proposalModel ) { proposalModel = _proposalModel; return proposalModel; } /// <summary> /// Method used to specify the data member attribute /// </summary> /// <param> /// <name>parmTimeFence</name>is used to set and get the historical time /// </param> [ DataMember, SysOperationGroupMember("HistoricalHorizoGroup"), SysOperationDisplayOrder("2"), SysOperationLabelAttribute(literalstr("@SYS315566")) ] public Integer parmTimeFence(Integer _timeFence = timeFence ) { timeFence = _timeFence; return timeFence; } /// <summary> /// Method used to specify the data member attribute /// </summary> /// <param> /// <name>parmToDate</name>is used to set and get the ToDate /// </param> [ DataMember, SysOperationGroupMember("HistoricalHorizoGroup"), SysOperationDisplayOrder("3"), SysOperationLabelAttribute(literalstr("@:ToDate")) ] public TransDate parmToDate( TransDate _toDate = toDate ) { toDate = _toDate; return toDate; } /// <summary> /// Method used to specify the data member attribute /// </summary> /// <param> /// <name>parmReplaceCurrentProposal</name>is used to set and get the parameter value /// </param> [ DataMember, SysOperationGroupMember("ReplaceCurrentProposalGroup"), SysOperationDisplayOrder("4"), SysOperationLabelAttribute(literalstr("@:ReplaceCurrentProposal")) ] public NoYesId parmReplaceCurrentProposal( NoYesId _replaceCurrentProposal = replaceCurrentProposal ) { replaceCurrentProposal = _replaceCurrentProposal; return replaceCurrentProposal; } /// <summary> /// Method used to specify the data memmber attribute /// </summary> /// <param> /// <name>parmToDate</name>is used to set and get the ToDate /// </param> [ DataMember, SysOperationGroupMember("ReplaceCurrentProposalGroup"), SysOperationDisplayOrder("5"), SysOperationLabelAttribute(literalstr("@SYS106955")) ] public InventSiteId parmInventSiteId( InventSiteId _inventSiteId = inventSiteId ) { inventSiteId = _inventSiteId; return inventSiteId; } /// <summary> /// Method used to specify the data memmber attribute /// </summary> /// <param> /// <name>parmToDate</name>is used to set and get the ToDate /// </param> [ DataMember, SysOperationGroupMember("ReplaceCurrentProposalGroup"), SysOperationDisplayOrder("6"), SysOperationLabelAttribute(literalstr("@SYS25253")) ] public InventLocationId parmInventLocationIdFrom( InventLocationId _inventLocationIdFrom = inventLocationIdFrom ) { inventLocationIdFrom = _inventLocationIdFrom; return inventLocationIdFrom; } /// <summary> /// Method used to specify the data memmber attribute /// </summary> /// <param> /// <name>parmToDate</name>is used to set and get the ToDate /// </param> [ DataMember, SysOperationGroupMember("ReplaceCurrentProposalGroup"), SysOperationDisplayOrder("7"), SysOperationLabelAttribute(literalstr("@SYS8519")), AifCollectionType('return', Types::String) ] public List parmInventLocationIdTo( List _inventLocationIdTo = inventLocationIdTo ) { inventLocationIdTo = _inventLocationIdTo; return inventLocationIdTo; } /// <summary> /// Method used to specify the data memmber attribute /// </summary> /// <param> /// <name>parmReplaceCurrentProposal</name>is used to set and get the parameter value /// </param> [ DataMember, SysOperationGroupMember("ReplaceCurrentProposalGroup"), SysOperationDisplayOrder("8"), SysOperationLabelAttribute(literalstr("@SYS40695")) ] public NoYesId parmRecalculateQuantities( NoYesId _recalculateQuantities = recalculateQuantities ) { recalculateQuantities = _recalculateQuantities; return recalculateQuantities; } }
Subscribe to:
Posts (Atom)