Laddawn.com : Programming Spec - Checkout Shipping Instructions

The shipping instructions screen will contain a list of shipping instructions that the customer can select for each bundle.  Behind each shipping instruction is a standard comment from the COMMENTS.USR file.  The selection for this screen will be dynamic so that newly created comments will automatically appear on the web page according to the screen section and sort index entered for the comment.

Avante Comment Master Maintenance (SYS9012):

Add a new subscreen: F5-Web Info with the following new fields.  Secure this screen so that only authorized users can access from list of SB User ID's in SYSCON COMMENT.SEC.LAD field 1.

  1. Packaging Comment Type:
    1. F3 list and validation from new IIDEFN table "WEB.PKGCOMM.LAD"
    2. Validate categories:  1=Delivery, 2=Carrier Options, 3=Pallets, and 4=CE
  2. Sort Index - validate that this is numeric
  3. Input Format***THIS WAS MOVED TO THE MAIN SCREEN ASSOCIATED WITH INPUT1 AND INPUT2
    1. F3 list and validation from new IIDEFN table "WEB.FORMAT.LAD"
    2. Valid formats:  1=Text Box, 2=Date, 3=Time, 4=Grid
  4. Range Minimum - optional - this is only for comments where we have to validate a min/max range on inputs
  5. Range Maximum - optional - this is only for comments where we have to validate a min/max range on inputs
  6. LTL Upcharge - will contain a flat rate or per qty rate - UI will assume a flat rate unless it has special logic (ie, export pallets is #pallets x per pallet upcharge rate)
  7. Small Pkg Upcharge -  will contain a flat rate of per qty rate - Currently only residential has an upcharge
  8. Revenue Charge Code - This is an optional field.  Validate in CHGCODE File. (added to doc 12/23/13)
  9. Add 'Preference Flag' under Packaging Comment Type - This is an optional field with the following choices: *** added 5/27/14 (timeline 57-32):
    1. 0 or No = Not a Preference
    2. 1 or Yes = This is a preference comment - it will be used with Comment Type to return in getbyfilter
       

Add a new column to F3 on comment# (SYSX9012.1) showing Web Screen Section so these comments are easily identifiable.

  

BP WEB.COMMENTS.READ:

This program will open and read a single COMMENTS.USR record requested by the calling program passing KEY.  All fields in the COMMENTS.USR record will be passed back in DATAFIELDS via the argument list. Copy LD.INCLUDES COMMENTS.READ to BP WEB.COMMENTS.READ and continue with changes..  LD.INCLUDES COMMENTS.READ can then be deleted (copy into AVBP.DELETED file first, changing the name to LDINCLUDES*COMMENTS.READ).  We’ve decided to get away from LD.INCLUDES and go with a global standalone program so that we don’t have to recompile all programs when an INCLUDE changes.

LDLIB RPC$COMMENTS_GETBYFILTER:

This program, which already exists, will be changed to accept a named param called PKGCOMM.TYPE and select the COMMENTS.USR file for only the type requested, sorted by the new ‘sort index’ field in the record.  If PKGCOMM.TYPE is null, select all comments that have a Packaging Comment Type, sorted first by Pkg Comm Type and then by Sort Index.  Since there are other types of comments that live in this file that aren’t going away, we will identify the comments we want by the packaging comment type.  As each record is selected, set KEY and execute WEB.COMMENTS.READ, which will pass back all fields in DATAFIELDS in the argument list.  All packaging comment's info will be passed back to the UI all at once in RETURN.VALUE.  The UI side parses through each set of groups extracting information.  For example, if there are 5 fields in the COMMENTS.USR record and 2 records were selected, RETURN.VALUE would look like:

      COMM.NBR=123

      COMM.DESC=THIS IS A TEST DESC

      COMM.TYPE=1

      PKG.TYPE=2

      SORT.INDEX=1

      COMM.NBR=345

      COMM.DESC=SECOND RECORD

      COMM.TYPE=1

      PKG.TYPE=2

      SORT.INDEX=2   

NOTE:  You do not need to tell the UI which options were previously selected in the case where user left screen and came back.  The UI side will remember.

12/23/13 - Add'l logic for Enabling and setting default value for each comment:

  1. Pass back to the UI in RETURN.VALUE "ENABLED=" for each comment.  Assume ENABLED=1 except for the following:  
    1. 40x48 Pallets - If Packaging = "CS" OR (Packaging = "RL" AND FOLDED.WIDTH** <= 48) then 40x48 pallets s/b ENABLED else set ENABLED=0.  You will have to extract this info from CFORDER or use Joe's program that extracts all quote data because you won't have this info in SHOP. variables at checkout time.  Packaging is in CFORDER<13,191> and Folded Width is in <13,412> (Wayne is in the process of fixing this field).
  2. When a customer is accessing the special instructions screen, do not select comments with Pkg Comment Type = 4 (CE Only).  LDLIB FIND.AVANTE.WEBINFO will eventually return an array of operator data.  Once this is completed, you can call this program and check ARRAY< 3> to see if there is a ce operator code there.
  3. 01/22/14 - ***THIS HAS BEEN MOVED TO A SEPARATE PROGRAM - SEE NOTES DATED 1/28/14 BELOW*** When the customer has a 'preference' established for any special instructions comment, let the UI know that the box should displayed as 'checked' by returning DEFAULT.VALUE. This will be done regardless of who is entering the transaction (ce or customer):
    1. For each selected comment, locate the comment in the customer master record (CUSTMST.USR<63>) starting with the shipto customer (CUST.NBR)  first, then billto (BILLTO.NBR)
    2. If the comment# is found for the shipto or billto customer, set DEFAULT.VALUE = :"True" and return to UI.  If not found, return "False".

Enabling logic is assuming that access to the Special Instructions screen will not be allowed for Small Package Shipments.  Small Pkg Shipments will show a residential charge, if any, on the main bundling screen under "Special instructions" (will show as disabled).

 **Definition of Folded Width: If Fold Bags in Half (SHOP.FOLDED) is chosen, this is Width / 2.  If Folded not chosen, this is Width.  For Furniture Bags, replace Width with Length. For everything else this is Width.

5/27/14 - ADD'L CHANGES TO RPC$COMMENTS_GETBYFILTER (timeline 57-33):

If FLAG > 0, add a new CASE statement to select user preference comments only:

  • SELECT comments with pkg comment type # "" and with preference type = FLAG

LDLIB RPC$COMMENTS_GETBYID:

This program is identical to the #2-getbyfilter with the exception that it doesn’t do a select.  It sets KEY to a specific comment# and executes WEB.COMMENTS.READ.  It sends back the single record’s contents from DATAFIELDS in RETURN.VALUE

 

Save & Continue – Updating SHOPPINGCART.USR:

Once the user has selected packaging options and chosen SAVE/CONTINUE:

The UI will send back only the selected options using named params.  For now, a tilde will be used to denote a multivalue and a semi-colon for a sub-value.  These may be changed to characters that cannot be chosen on a keyboard so that we don’t have an issue with the user entering data that we are using as a delimiter (such as colon in a delivery time):  If a named param doesn't exist yet, you will have to add to SYSCON NAMED.PARAMS.LAD and recompile all programs.  Put update logic into RPC$SHOPPINGCART_SAVE.

 

BUNDLE.INDEX=1~2

PKGCOMM.NBR=100;135;150~017;122;020

PKG.INPUT1=12:00;;~;HELLO;

PKG.INPUT2=;;~;;

 

This data can then be changed to multi-values and sub-values and written to SHOPPINGCART.USR.

 

12/1713 - Additional Logic/Changes:

  1. SYS9012 - Web Screen: Remove MD2 on Range Minimum/Maximum fields.  Leave as Numeric fields ... if a decimal is needed it will be entered and stored
  2. SYS9012 - Web Screen: Remove 'Input Format' from this screen.  It is going to be moved to the main screen associated with Input1 and Input2
  3. SYS9012 - Main Screen: Move 'Input Format' from web screen and put it next to Screen Prompt1.  Add a second 'Input Format' to the dictionary and put it next to Screen Prompt2.  Add two new formats to the table:  Phone Nbr and Range.  Pass the new Input Format for Input2 to the UI from WEB.COMMENTS.READ.  Note:  The UI side will take care of validations based on Input Format.
  4. Write a new program that calculate the acceptable input range for the #Packages per Pallet comment:
    1. BP WEB.PALLET.NBRPKGS
    2. UI will pass QUOTE.NBR and PART.NBR (which is the MOD Item#) to the RPC, which in turn will call this program.  The RPC, when written, will call this program passing the MOD Item# in PARAM<1> and the Quote# in PARAM<2>.  You will pass Low Range back to RPC in PARAM< 3> and High Range in PARAM<4>.  The UI side will do the validation based on this range.
    3. Calculate the low/high range as follows
      1. Read CFORDER using QUDET< 39>
      2. Read Case or Roll weight from CFORDER<13,192>
      3. Read Packaging from CFORDER<13,109>
      4. Read Width from CFORDER<13,2>
      5. Read 'Fold Bags in Half' from CFORDER<13,410>
      6. Get Catalog Code from CFORDER<13,1>
      7. Determine 'Folded Width' - see *definition below
      8. Determine 'Max Per Skid' - see **definition below
      9. Put 250 'range pounds' in SYSCON "CONFIG.SETTINGS.LAD" field 9 (make sure you enter a comment)
        • Low Range = 250 lbs / Case or Roll Weight + .49 (rounded to whole number)
        • High Range
          • If Packaging = "Rolls, Cradlepacked" and Folded Width < 15": Max Per Skid x 3
          • If Packaging = "Rolls, Cradlepacked" and Folded Width >= 15 < 23: Max Per Skid x 2 
          • If Packaging = "Cases" or "Rolls, Boxed" or Cradlepacked and Folded Width >= 23 (ie, CASE 1):  Max Per Skid

        *Definition of Folded Width: If Fold Bags in Half=Y, this is Width / 2.  If Folded not chosen, this is Width.  For Furniture Bags (catalog code 104), this is Length.

        **Definition of Max Per Skid (use CALL WEB.TABLE.LOOKUP):

        • If Packaging = "Rolls, Cradlepacked": Max Per Skid comes from the Box Table, column MAXPKG, using Roll LxG
        • If Packaging = "Rolls, Boxed": Max Per Skid comes from the Box Table, column MAXPKG, using Folded Width
        • If Packaging = "Cases": Max Per Skid comes from the Box Table, column MAXPKG, using cubic inches

01/28/14 - Additions to Logic:

We are moving the default.value logic for shipping instructions into a stand-alone program and removing it from RPC$COMMENTS_GETBYFILTER.  This can be called from bundling to establish defaults for all shipping instructions that have a user-preference.  This will now be based on whether we believe the bundle will be shipped via a small package carrier (UPS/Fedex) or an LTL carrier (less than truckload common carrier). These preferences will be shown at the bottom of the bundling screen.  This way if the user never goes into the Shipping Instructions Screen, their user preference comments will already be on the bundle.  Change as follows:

  1. As part of the information returned to the UI from the Bundling Program, we will now determine whether this bundle will ship via Small Pkg or LTL using the same logic that Create Pickslips uses to assign the freight carrier on the Picking Slip.  The "LTL Flag" set to True or False will be returned to the UI for each bundle:
    1. If Ship Via for the Bundle is not "BW", read SYSTBL VIA*:Ship Via Code and get carrier type from SYSTBL<1>.  If Carrier Type = "CC", set LTL.FLAG=True else set LTL.FLAG=False.  Note: null carrier types (ie, CPU, PO, FC) will be handled like a small package).

    2. If Ship Via for the Bundle is "BW", establish the following info and execute SOPS4007.5PS passing this info in BESTWAY.PARAM:

        • Warehouse# on the bundle
        • Company:"*":Billto Customer
        • Company:"*":Shipto Customer
        • Shipping City, State Zip  (if SHOPPINGCART.USR<16> # "", use this else read shipto customer's address from CUSTMST)
        • Total Weight of the bundle.  Sum up weight of all items in the bundle, calculating as follows:
            MOD ITEMS:
          • CUSTOM.WGT   = 0   ;* MD1

             

            READV BLD.NBR FROM CFBLDHDR,CONFIG.REV,1 ELSE BLD.NBR=1

             

            CFBLD.USR.ID = CONFIG.REV : “.”:BLD.NBR

             

            READ CFBLD.USR.REC FROM CFBLD.USR,CFBLD.USR.ID THEN

             

                   CFBLD.TOT.ORDERED = CFBLD.USR.REC<3> + 0

             

                   CFBLD.TARGET.WGT  = OCONV(CFBLD.USR.REC<7> + 0,'MD1')

             

                   CFBLD.QTY.TO.MFG  = CFBLD.TOT.ORDERED

             

                   IF ALLOW.OVERRUN.FLAG = 1 THEN

             

                      QTY.OVERRUN      = INT(CFBLD.QTY.TO.MFG/10)

             

                      TEMP.QTY         = QTY.OVERRUN + CFBLD.QTY.TO.MFG

             

                      CFBLD.QTY.TO.MFG = TEMP.QTY

             

                   END

             

                   CUSTOM.WGT = CFBLD.QTY.TO.MFG * CFBLD.TARGET.WGT

             

                   IF CUSTOM.WGT = 0 THEN

             

                      CUSTOM.WGT = 0

             

                   END ELSE

             

                      CUSTOM.WGT = ICONV(CUSTOM.WGT,'MD1')

             

                   END

             

              END

          • STOCK ITEMS:  Bundle Qty x ITMMST<99> 

             
        • FOB Code (from bundling screen - Shipping Paid by ...  This must be passed as a valid FOB Code PPD, P&A, CPU, 3PB, COL)
        • Boxed or Cradlepacked (from SHOP.PKG) (string CRADL must exist in either the 2nd or 3rd sub-value of this parameter)
        • Config.Rev (from QUDET< 39> if this is a MOD Item bundle.  If Stock bundle, leave this blank
        • List of CPN's in the bundle.  For MOD items, put in CPN of part# "MOD"
        • List of Bundle Qtys associated with each item above
        • Allow Overrun Flag: Read from QUHDR.USR<5>.  If null, set to "1" (default is to allow overrun)
        • Execute SOPS4007.5PS
        • Using the carrier returned from SOPS9007.5PS, read SYSTBL VIA*:Ship Via Code and get carrier type from SYSTBL<1>.  If Carrier Type = "CC", set LTL.FLAG=True else set LTL.FLAG=False
    3. Pass the LTL.FLAG to the UI in RETURN.VALUE as True or False.  Create a NAMED.PARAM for LTL.FLAG
    4. Modify the shopping cart update program to write the LTL.FLAG (as 1 or 0) for each bundle.  You will need to add a new multi-valued field to SHOPPINGCART.USR
  2. Create a new LDLIB RPC$COMMENTS_GETDEFAULTS (the UI will call this program to get all Shipping Instruction defaults when it needs this info).  ***7/15/14 - John and I discussed this again and re-affirmed that the UI would call this RPC when it needs to display pref defaults at the bottom of the bundling screen as well as after calling RPC$COMMENTS_GETBYFILTER to check the boxes for customer preferences on the shipping instructions popup***:
    1. Use params CUST.NBR, BILLTO.NBR and LTL.FLAG
    2. Move the default comment logic (described in #3 above) from RPC$COMMENTS_GETBYFILTER into this program (deleting it from COMMENTS_GETBYFILTER)
    3. Change this default logic to be based on the LTL.FLAG of the bundle:
      1. If NOT(LTL.FLAG) then the only default will be for comment numbers that are listed in SYSCON CONFIG.SETTINGS.LAD<11> (strip off comment).  Today, the only comment# in this syscon is RESIDENTIAL DELIVERY (limited access was added).  Continue to default this comment only if found in CUSTMST.USR.
      2. If LTL.FLAG, any comment# found in CUSTMST.USR can be defaulted.
    4. Send all default info to the UI in RETURN.VALUE (same info that you were sending in COMMENTS_GETBYFILTER)

*** 7/14/14 - (judy) I finished up the programming started by Janice.  Only had to add the call to the WEB.GET.PREFDEFAULTS and removed logic that was looking through customer comments. I also added logic to shipmentbundling to use data from WEB.GET.PREFDEFAULTS.

 

02/03/14 - Calculation of Shipping Instruction Upcharges (Timeline 68-1):

The purpose of this new program is to calculate and return the detailed upcharges for some of the shipping instructions that the customer can choose.  Not all shipping instructions are upcharged.  This program will return both the detailed upcharges (for order creation) and the Total Upcharges for the Cart (including all bundles) for use by the Cart Total program.  This program will never be called directly from the UI Side, so data passed out can be in the form of an array passed via the Argument List.  Wayne is currently writing the Cart Total program, so please let him know when this program has been completed so that he can complete his side.

*** 2/27/14 - John and I realized that the Cart Total (which includes these upcharges) shows on the bundling screen.  This means that if this routine is called from the bundling screen, the UI side will have to pass you the info that you need.  If the UI info is null, that means you should take info from SHOPPINGCART.USR. Please provide John with the info that you need the UI to pass you from bundling.

Create new BP WEB.CALC.UPCHARGES:

10/3/14 - upcharges on:

  1. Inside Delivery
  2. Liftgate
  3. Tailgate
  4. Export Pallets
  5. Residential Delivery
  6. Limited Access (use same logic as residential but its own rates)

Only these 6 should say 'upcharge' on the bundling screen

For CPU MOD bundles, we are allowing them into the shipping instruction screen.  Only upcharge for export pallets since the rest have to do with carrier and they are picking up. 

  • All upcharges (except export pallets & pallet height) apply only to PPD (Shipping paid by Laddawn) or P&A (Shipping Paid by Customer) bundles.  These are bundles where we will get charged by the freight company, and in the case of P&A, pass the freight charge along to the customer.  If the customer is picking up (CPU), paying collect (COL), or third party (3PB), then no upcharges will apply.
  • Export Pallet and Pallet Height Upcharges will be applied regardless of FOB Code, because this has to do with the pallets that the goods are on, not with any delivery requirement like Liftgate, Residential Delivery, Inside Delivery, Tailgate and Limited Access.
  • All Flat Rate upcharges (Liftgate, Tailgate, Inside Delivery, LTL Residential, and Limited Access) will be charged on every Shipment of the order. To accomplish this on the order/invoicing side, we will setup the revenue charge code as a FRT type so that it will be added to every invoice.  For the Cart Total, the flat rate charge should be added to the Total Upcharge for every bundle (because a bundle equates to a shipment).  If the bundle contains more than one of these upcharge-type comments, add the charge for each comment.  One Flat Rate per Shipment.
  • You will need to know if this is an LTL (less than truckload) or Small Pkg (UPS/Fedex) shipment to determine the correct Flat or Per Lb Rate to pull from the COMMENTS.USR file.  An LTL Flag will be added to the SHOPPINGCART.USR associated with each bundle.  Note:  UI may have to pass this flag if calling from the bundling screen and this flag hasn't been written yet.  A new named param has been established for this.
  • Export Pallets will be a onetime charge on the 1st shipment for the 1st warehouse on the order.  ie, split shipments between 2 warehouses will be on the same order because they have the same ship date.  In this case, we will calculate the #pallets based on the entire order, then charge it on only one warehouse's invoice.  To keep this easy, calculate the #pallets on each of the bundles that have Export Pallets using only the items in that bundle.  If two bundles with Export Pallets are put together to create a single order, the one-time charge for the total order should come pretty close to the individual upcharges you calculated for each bundle (may be slightly off).  The calculation for the the Pallet Upcharge is (#Pallets x Per Pallet Rate).  The Per Pallet Rate is based on pallet size ranges, and will come from the configurator table "PKG_CHARGES".  Today there is one row called EXPORT.  I believe at phase I we will continue to use the single column EXPORT to determine the per pallet rate.  In phase II this may be broken out into multiple Rows because different pallet sizes have different lengths.  To calculate #Pallets:
    • For MOD Items, read #pallets from CFORDER<13,322> using quote# in SHOPPINGCART.USR<6> to QUDET< 39> for key to CFORDER  *** should we be adding overrun to this calculation????
    • For Stock Items, sum up the weight of all items in the bundle (Item Qty x ITMMST<99>), then: IF WIDTH <=48” THEN (ORDER WGT / 900 + .49) ELSE (ORDER WGT KG / 1200 + .49).
  • Residential Delivery upcharges - This will be a flat rate charge if LTL.FLAG=1 (going by common carrier).  This will be a per pound rate if this is going by small package carrier.  The per pound rate is in SYSCON CONFIG.SETTINGS.LAD<12> COMMENTS.USR<14> and the per pound comment# is in CONFIG.SETTS.LAD<13>.  Multiply this rate x Order Total Lbs**.
  • ** Order total lbs for stock is outlined above.  Order total lbs for MOD can be read from CFORDER<13,55>
  • Pass back via array in argument list:
    • Multi-valued comment numbers
    • Multi-valued comment text (swap out "\" for input1/input2 answers)
    • Multi-valued Rates (flat rate or per lb)
    • Multi-valued Upcharge Amts
    • Multi-valued Bundle# (this could be there multiple times if multiple comments within a bundle has an upcharge)
    • Multi-valued Revenue Charge Codes (from COMMENTS.USR<15>)
    •  Single Valued Total Upcharge Amt (MD2)

  

UI SIDE:

  1. The entire Shipping Instructions popup will be disabled for Small Package bundles (can't click on 'Change' link).  A small package bundle is defined as any bundle whose Ship Via is a UPS or Fedex choice (SYSTBL "VIA" field 1 = "UPS", "RPS" or "FE") or any "BW" ship via bundle whose shipping weight < xxxlbs.  Preferences that do apply such as Residential Delivery will be shown at the bottom of the bundling screen in Special Instructions. 
  2. The UI side will take care of all shipping instruction input validations based on the Input Format passed for the 2 input fields.
  3. After 'save' from the popup: the UI side will replace the "/" with the data from Input1/Input2 in the Comments text that was passed from the database and return as a text string to the main bundling screen for display.
  4. The UI must pass named param LTL.FLAG for the bundle when requesting comment defaults from RPC$COMMENTS_GETDEFAULTS.  The bundle LTL Flag is in SHOPPINGCART.USR<49,bundle#)