Tuesday, June 30, 2015

M3 MashUp Overview

M3 mashup tool can be used to combine information from several M3 panels, several external sources and other M3 sources in to one panel. With mash up tool it is easy to connect different panels, details, call APIs, do localisations, and create customer lists to ISO client.

With this tool, it is easy to continue business flows without memorizing several different panels.
Let’s see some real life experience in M3, which makes life harder to the user.

Ex: -
  1.  See item details.  – User needs to remember MMS001, MMS002, MMS003, and PDS001 and so on.
  2. See Supplier details – Starting with CRS620, if you need financials you need to go to CRS624, addresses different related option, like wise.
  3.  Purchase order / Customer order/ Manufacturing order information – You need to always start with header and go in to line level

Likewise there can be several scenarios based on your business flow.


Using M3 mash up tool we can put these pieces in to one panel and make life easier to the user.




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

Monday, January 19, 2015

Android Music player AnyPlayer

Enjoy high quality music playback experience with a unique equalizer, bass boosting, for mp3, mp4, 3gp, acc, flac, mid, ogg, and etc with this music player. Any player is designed for both simple and advanced users. It has simple interface with rich graphics which enables the user for smooth navigation through the music player. Enjoy high-quality mobile music playback experience. NOTE: Product is for ANDROID 3.0+ devices.


Get Pro - Get it on Google Play

Get Trial (30days) - Get it on Google Play



Get the user manual -

Features:

See feature demo

* Adjust the effect as you want – 5 bands Equalizer, Bass boost and volume knob.
* Music Player automatically detects all the music files in your phone, and add to relevant music lists
* Music Player Supports for playback of the most common music format such as mp3, mp4, 3gp, aac, flac, mid, ogg, etc.
* Music Player is available on 8 famous languages, ENGLISH, SPANISH, FRENCH, GERMAN, ITALIAN, RUSSIAN, CHINESE,PORTUGUESE and JAPANESE.
* Browse and play your music by ALBUMS, ARTISTS, FOLDERS, GENRES, ALL SONGS, and PLAYLISTS,
* LOCK SCREEN widget of size 4x1
* Music Player gives you a choice of 3 different home screen WIDGETS (4x1, 2x2, 4x4) with album art work, controllers and easy access to the player.
* NOTIFICATION STATUS with album art work and controllers.
*Automatically SLEEP PLAYER after some time with music fades out effect.
* HEADSET support with headset buttons and with bass boosting.
* Music Player SEARCH your favorite song based on title, album and artist.
* SWIPE gestures on home page (swipe left right- swipe album art to play next/ previous, swipe up /pause) and playlist.
* Create/Edit/Delete/Rename your favorite playlists.
* Mange song Queue as you want and save it as playlist.
* Share your favorite songs with your friends with Bluetooth and other Medias.
* If the device is equipped with Bluetooth, don’t hesitate to enjoy Bluetooth streaming.
*Equalizer / bass boost settings will automatically save your preferences for the next time.
Visit our web site