Customer wanted to receive PO pallet wise (PPS300). But these items were not lot controlled. Their requirement was to receive pallets with different receiving numbers. Our initial try was to use API calls for each pallet. Latter we realized that in each API call receiving number changes as bellow,
1000003001, 1000004001, 1000005001
But we don’t want that since when it comes to put away we cannot put each and every receiving number. In each time user should be able to see all the pallets of one PO line under the same screen. In that case number series should be generated as bellow,
1000003001, 1000003002, 1000003003……n
So that user can see all the pallets we received under one PO line.
Answer
We realized that when user receive PO lines with pallet quantities (partial quantities), receiving number changes in the desired way. So we came up with an automation which runs on the PPS300/B panel.
Main problem here is not to close PPS300 screen each time. Designing automation which follows same user operations would be the only possible option.
Step 1: Set up input fields and buttons on the PPS300/B1 pannel.
Step 2: Initial validations before process starts.
Step 3: Processing the bulk (Receiving multiple pallets)
/****** Program - PPS300 Devloped - Aurora Devs Requested - ****** Des - This script will GRN good based on pallet quantity. ******/ import System; import System.Windows; import System.Windows.Controls; import MForms; import Mango.UI; import Lawson.M3.MI; import System.Windows.Input; package MForms.JScript { class PPS300_AutoRecipt { var controller; var debug; var content; public var loopCount; public var runLoopFor; var location; var packSize; public var partialPalet; var listControl; public var puno; public var item; public var line; public var batchNum; var batchL; public var mnfDate; var mnfDateL; var quantity; var listView; var linNumColumn; var lineClose: boolean = false; var linesWhenBreak=0 ; public function Init(element: Object, args: Object, controller : Object, debug : Object) { this.content = controller.RenderEngine.Content; this.controller = controller; this.debug = debug; debug.WriteLine("Script Initializing."); var receivePalet = new Button(); setButton(receivePalet, 60, 6 ); setLabel(batchL, "Batch Num:", 20, 6); batchNum= new TextBox(); setTextBox(batchNum,27, 6); setLabel(mnfDateL, "Mfg Date:", 39, 6); mnfDate = new DatePicker(); setDate(mnfDate,46, 6); } //Adding button public function setButton(name, col, row ){ name.Content = 'Rpt Receipt'; name.ToolTip = 'Click here to automatically report pallets'; name.HorizontalAlignment = HorizontalAlignment.Left; Grid.SetColumn(name, col); Grid.SetColumnSpan(name, 98); name.VerticalAlignment = VerticalAlignment.Top; Grid.SetRow(name, row); Grid.SetRowSpan(name, 23); controller.RenderEngine.Content.Children.Add(name); name.add_Click(OnClick_receivePalet); } //Adding the TEXT Box public function setTextBox(name, col, row ){ name.Text=''; name.Width= 10* Configuration.CellWidth; name.Height= 15;//* Configuration.CellHeight; name.FontSize = 12; name.HorizontalAlignment=HorizontalAlignment.Left; Grid.SetColumn(name,col); Grid.SetColumnSpan(name,98); name.VerticalAlignment=VerticalAlignment.Top; Grid.SetRow(name,row); Grid.SetRowSpan(name,23); controller.RenderEngine.Content.Children.Add(name); } //Adding the Lable public function setLabel(variable, name, col, row){ variable = new Label(); variable.Content = name; variable.Padding = new Thickness(1); Grid.SetColumn(variable, col); Grid.SetRow(variable, row); Grid.SetColumnSpan(variable, 12); controller.RenderEngine.Content.Children.Add(variable); } //Adding date picker public function setDate(variable, col, row){ variable.Width= 10* Configuration.CellWidth; variable.Height= 20; variable.FontSize = 10; Grid.SetColumn(variable, col); Grid.SetRow(variable, row); Grid.SetColumnSpan(variable, 11); controller.RenderEngine.Content.Children.Add(variable); } // event handler for user clicks function OnClick_receivePalet(sender: Object, e: RoutedEventArgs) { debug.WriteLine("clicked"); puno = ScriptUtil.FindChild(content, "WWPUNO"); listControl =controller.RenderEngine.ListControl; listView = listControl.ListView; var itemColumn = listControl.GetColumnIndexByName('ITNO'); var locationColumn = listControl.GetColumnIndexByName('WHSL'); var quantityColumn = listControl.GetColumnIndexByName('RVQA'); linNumColumn = listControl.GetColumnIndexByName('PNLI'); //debug.WriteLine("r--"+linNumColumn); var rowItems = listView.SelectedItems; var i= 0; partialPalet = 0; item = ""; location = ""; line = ""; quantity = 0; for (var row in rowItems) { item = row[itemColumn]; location = row[locationColumn]; quantity = row[quantityColumn]; line = row[linNumColumn]; i++; } if(i==0){ MessageBox.Show('Please select a line!'); } else if(i==1){ debug.WriteLine(item+" Location:-"+ location+" line-"+line); if(true == String.IsNullOrEmpty(location.Text)){ MessageBox.Show('Location must be entered!'); } else if(true == String.IsNullOrEmpty(quantity.Text)){ MessageBox.Show('Quantity must be entered!'); } else if((true == String.IsNullOrEmpty(batchNum.Text)) || (true == String.IsNullOrEmpty(mnfDate.Text))){ MessageBox.Show('Batch number/ Mfg date must be entered!'); } else{ packSize = 0; debug.WriteLine("conditions made"); retrieveContainer(item); debug.WriteLine("pack size="+packSize); } } else{ MessageBox.Show('Please select only one line!'); } } public function OnRequesting(sender : Object, e : CancelRequestEventArgs) { if((true == controller.RenderEngine.PanelHeader.EndsWith("PPS300/A")) || (true == controller.RenderEngine.PanelHeader.EndsWith("PPS300/E"))) // are we on panel A/E { var strError = checkForError(); if(true != String.IsNullOrEmpty(strError)) { debug.WriteLine("there is a msg"); CleanUp(); } } } public function requestComplete(sender: Object, e: RequestEventArgs) if(true == controller.RenderEngine.PanelHeader.EndsWith("PPS300/B1")) // are we on panel B1 { debug.WriteLine("came to B1"); if((runLoopFor+2) == loopCount){ CleanUp(); if(lineClose){ //loopCount MessageBox.Show('Reporting of '+ linesWhenBreak+' pallets is finished successfully, But process braked up since line is closed'); } else{ MessageBox.Show('Reporting of '+ (loopCount-2)+' pallets,\n and '+partialPalet+' unit/s, is finished successfully!'); } }else{ if(((runLoopFor+1) == loopCount) && (partialPalet == 0)){ CleanUp(); MessageBox.Show('Reporting of '+ runLoopFor+' pallets is finished successfully!'); }else{ listControl = controller.RenderEngine.ListControl; var lv = listControl.ListView; lv.SelectedIndex=0; controller.ListOption("2"); } } } if(true == controller.RenderEngine.PanelHeader.EndsWith("PPS300/E")) // are we on panel E { if((runLoopFor+1) == loopCount){ packSize = partialPalet; } var lineInt: int = line; loopCount++; var pnliF = ScriptUtil.FindChild(content, "IBPNLI"); var pnliInt: int = pnliF.Text; debug.WriteLine("came to E- line"+ line +"--"+ pnliF.Text+" lineint"+lineInt+" pnliF "+pnliInt); if(lineInt == pnliInt){ var rvqaF = ScriptUtil.FindChild(content, "WBRVQA"); var whslF = ScriptUtil.FindChild(content, "WLWHSL"); var repnF = ScriptUtil.FindChild(content, "WWREPN"); var camuF = ScriptUtil.FindChild(content, "WTCAMU"); var prdtF = ScriptUtil.FindChild(content, "WLPRDT"); var brefF = ScriptUtil.FindChild(content, "WLBREF"); var lpudF = ScriptUtil.FindChild(content, "WBLPUD"); rvqaF.Text = packSize; whslF.Text = location; camuF.Text = repnF.Text; brefF.Text = batchNum.Text; prdtF.Value = mnfDate.SelectedDate; lineClose = false; controller.PressKey("ENTER"); } else{ linesWhenBreak = loopCount; loopCount = runLoopFor+2; lineClose = true; controller.PressKey("F12"); } } } public function CleanUp() { controller.remove_RequestCompleted(requestComplete); controller.remove_Requesting(OnRequesting); debug.WriteLine("Cleaned up"); } private function checkForError() { var strResult : String = null; var strStatusMessage : String = MForms.Runtime.Runtime(controller.Runtime).Result; // objRuntime.Result; try { var iStartPosition : int = 0; iStartPosition = strStatusMessage.IndexOf(""); // if Msg doesn't exist, then we didn't have an error if(-1 == iStartPosition) { // we are all good! } else { var iEndPosition : int = strStatusMessage.IndexOf(" "); if((-1 == iEndPosition) && (0 != iEndPosition)) { iEndPosition = strStatusMessage.length-1; } strResult = strStatusMessage.substring(iStartPosition+5, iEndPosition); } } catch(ex) { MessageBox.Show("checkForError() exception: " + ex.message); } return(strResult); } public function retrieveContainer(itemS) { try { debug.WriteLine("Starting validation for Container " ); var api="MDBREADMI"; // Name of MI (general API) var trans = "GetMPACIT10";// Transaction name var record = new MIRecord(); record["DXIT"]="1"; // item identity record["PACT"]="PALLET"; // packaging record["ITNO"] = itemS; //item num MIWorker.Run(api, trans, record, OnResponse); //call the API SetWaitCursor(true); //wait till the response is arrived } catch (ex) { debug.WriteLine(ex); } } public function OnResponse(response : MIResponse) { debug.WriteLine("in1"); packSize = 0; if (response.HasError) { debug.WriteLine("inError"); debug.WriteLine("MIAccess error. " + response.Error.ToString()); //return; }else{ debug.WriteLine("inProcess"); var d1qtR; var d2qtR; var d3qtR; var itnoR = ""; d1qtR = response.Item.GetString("D1QT"); //reading form the MI response d2qtR = response.Item.GetString("D2QT"); d3qtR = response.Item.GetString("D3QT"); itnoR = response.Item.GetString("ITNO"); debug.WriteLine("a"+d1qtR+" b= "+ itnoR + "itno - "+item); if((itnoR == item) && (d1qtR > 0.0) ){ debug.WriteLine("pack qty =1="+d1qtR); var withoutZero: float = d1qtR; if(withoutZero <= quantity.Text){ packSize = withoutZero; debug.WriteLine("pack qty =2="+packSize); CheckBatchQty(); } else{ MessageBox.Show('Entered Qty is less than pallet Qty!'); } } } debug.WriteLine("out"); SetWaitCursor(false); } public function runMainProcess(){ var reportingQty = quantity.Text; partialPalet = reportingQty%packSize; runLoopFor = (reportingQty-partialPalet)/packSize; debug.WriteLine("run loop for -"+ runLoopFor); loopCount = 1; var gvGridView = listView.View; gvGridView.Columns[linNumColumn].Header.Content.Children[1].Text = line; controller.PressKey("ENTER"); var porceed = ConfirmDialog.ShowQuestionDialog("Proceed?","Package size: "+packSize+"\nNumber of pallets: "+runLoopFor+"\nQty of partial pallet: "+partialPalet +"\nBatch Num: "+batchNum.Text+"\nManufacture Date: "+mnfDate.Text); if (porceed){ listControl =controller.RenderEngine.ListControl; listView = listControl.ListView; //gvGridView = listView.View; debug.WriteLine("proceed"); listView.SelectedIndex=0; controller.add_Requesting(OnRequesting); controller.add_RequestCompleted(requestComplete); controller.ListOption("2"); } else{ debug.WriteLine("cancel"); //break; } } public function CheckBatchQty() { try { debug.WriteLine("Starting validation for supplier " ); //isValidating = true; var CONO = UserContext.CurrentCompany; var api="PPS001MI"; // Name of MI (general API) var trans = "GetLine";// Transaction name var record = new MIRecord(); record["CONO"]= CONO; // Company record["PUNO"] = puno.Text; //PO num record["PNLI"] = line; //PO Line var parameters = new MIParameters(); parameters.OutputFields = ['CFQA', 'ORQA']; MIWorker.Run(api, trans, record, OnResponseCheckBatchQty,parameters ); SetWaitCursor(true); //wait till the response is arrived //this.test1() ; //test case without API call } catch (ex) { debug.WriteLine(ex); } } public function OnResponseCheckBatchQty(response : MIResponse) { SetWaitCursor(false); if (response.HasError) { debug.WriteLine("MIAccess error. " + response.Error.ToString()); MessageBox.Show('Somthing wrong with the API transaction or the provided po get line'); return; } else{ var cfqa = ""; var orqa = ""; cfqa = response.Item.GetString("CFQA"); //reading form the MI response orqa = response.Item.GetString("ORQA"); //debug.WriteLine("cfqa- "+ cfqa+ " orqa - "+ orqa + " quantity.Text- "+quantity.Text); //quantity if(cfqa > 0){ if(quantity.Text > cfqa){ MessageBox.Show('Entered Qty is greater than the ordered/confirmed qty !'); } } else{ if(quantity.Text > orqa){ MessageBox.Show('Entered Qty is greater than the ordered/confirmed qty !'); } } runMainProcess(); } } public function SetWaitCursor(wait) { var element = controller.Host.Implementation; element.Cursor = wait ? Cursors.Wait : Cursors.Arrow; element.ForceCursor = true; } } }