Sunday, May 31, 2015

PO pallet wise receiving

Question

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;
  }  
 }
}