Docstoc

Q1 2005 Results and Forecast

Document Sample
Q1 2005 Results and Forecast Powered By Docstoc
					     Making QAD Dance to your Tunes!
A Case study demonstrating how Culligan added functionality to QAD,
using TailorPro’s rapid enhancements and non-invasive customizations



      Meera Ravindran – Culligan International
          Bruce LeBel – Prostar Systems


                                                      MMUG
                                                      Sept 2009

                                                             Culligan Confidential
Introduction



      Culligan has extensively utilized the TailorPro “source-free”
      development engine to create significant modifications to QAD’s
      Mfg/Pro screens, data structures and business logic
      TailorPro has enabled us to limit the number of changes made to
      Mfg/Pro.
      TailorPro solutions range from support for unique business process
      requirements such as Lead information captured at time of Sales
      Order/Contract entry (drives sales commission), to support for audit
      and security.




                                       2
                                                                     Culligan Confidential
Agenda



     Who we are ?
     Where we were then – a look at the QAD System, pre-TailorPro
     Why did we need a change?
     Examples of TailorPro usage, enabling sizeable return on investment.
     Where we are now
     Overview of the full set of capabilities of TailorPro
     A look ahead at how Culligan intends to apply TailorPro in the future




                                     3
                                                                   Culligan Confidential
Who We Are


             Founded by Emmett J. Culligan in 1936,
             headquarter in Rosemont, IL

             Over 1400 dealerships worldwide,
             615 dealerships in US alone, of which 70 are
             Company Owned Dealerships, the remainder
             Franchise

             5000+ employees in more than 100 countries

             Market share leader and a renowned
             household name for conditioned water.

             Full service provider of water treatment
             solutions, for homes and industries




              4
                                            Culligan Confidential
Who We Are –
Culligan Business Model




         Business model similar to McDonalds – Company Owned Dealers (COD)
         and Franchises
         CODs and Franchises sell or rent direct to households, service and
         deliver product
         CODs and Franchises purchase product from Culligan Corporate




                                       5
                                                                 Culligan Confidential
Who we are - Customer Segments

     Culligan delivers it’s convenience of bottled water, and the energy savings and
     health benefits of water softeners to customers in a variety of applications.




                                          6
                                                                            Culligan Confidential
Who We Are –
Product Line
         Household/Residential
         (Water Softeners, Water Filters
         & Reverse-Osmosis systems)




         Commercial & Industrial
         (Water Softeners, Water Filters
         & Reverse-Osmosis systems)




         Point-of-Use (POU)
         Bottleless Water coolers




         Retail Products
         (Shower heads & filters, Pitchers & filters,
         Faucet filters, RV filters, Icemaker & Water
         Dispenser filters)
                                                            Service
                                                            (Complimentary in home analysis,
         In-Store Bottle Water Dispensers                   Certified Sales, Installation and Service Technicians,
                                                            Full Service - Salt Delivery,
                                                        7   Full Service - Filter Exchange) Culligan Confidential
Who We Are –
Focus On Improving Efficiency




          Culligan was acquired by Clayton, Dubilier & Rice, Inc (CD&R) a
          private equity firm in 2004
          Since that time Culligan’s strategy has been focused around improving
          efficiency through re-engineering efforts
            Outsourced most manufacturing
            Implementing shared services
            Centralizing Finance
            Implementing single system to support North America




                                          8
                                                                       Culligan Confidential
Culligan Production Databases




                       eB2.1 Database for Culligan
                        North America Operations




                                                        Corporate/
                                                      Culiigan Owned
                            Wholesale Canada
                                                     Dealership Division
            Canada                                        (CODD)
                                                             US




                                       9
                                                                           Culligan Confidential
Ongoing customizations

      In Dec 2006, already had about 400 pieces of customized codes, for business
      specific requirements example: delivery route module, customized reporting,
      browses etc.
      There were several new application changes to be made, including –
           Screen Modifications
           New Screens, Browsers, Applications
           New Business Rules
           Logic-driven Defaults
           Data Validation
           User Control
      Had to find a better way to make QAD enhancements in a time-efficient manner.
      All changes had to be made in a manner that is upgrade-friendly.




                                         10
                                                                         Culligan Confidential
Our Approach




    Invited ProStar Software to provide us with a demonstration of their TailorPro tool.
    Analyzed the TailorPro tool and were impressed by the potential
    Acquired TailorPro, underwent a couple days of training
    Began working with the TailorPro product, got our feet wet
    Brought TailorPro back in for a couple more weeks of training, and implementation
    assistance
    Adopted a standard rule for QAD development -
          ALWAYS attempt to change with TailorPro first
    TailorPro changes made in ‘character’ interface, are reflected in ‘.Net UI’ in most
    cases.




                                            11
                                                                              Culligan Confidential
Example# 1 –
Item Master Maintenance


                               We can specify the
                               exact field position in
                               Character mode




                                       In .Net UI, new fields
                                       are added to end of all
                                       fields in the frame.




                          12
                                           Culligan Confidential
Example# 1
Set up anchors for Item Master new fields




                                            13
                                                 Culligan Confidential
Example# 1
Code Sample – Item Master new fields
    tpptchr09a.p                                       tpptchr09b.p
    { crtfill.i                                         {enable.i
           &FieldName       = '"pt_user1"'                 &FieldNames = '"pt_user1"'
           &FieldRow       =2                            }
           &FieldCol      = 34
           &Visible      = yes                          {enable.i
           &FrameName          = '"a"'                     &FieldNames = '"pt__chr09"'
           &DataType        = '"Character"'              }
           &TableName        = "pt_mstr"
           &FieldLabel     = '"RentFA"'                 {taborder.i
           &FieldFormat = '"x(1)"'                         &FieldNames =
           &FieldWidth     =1                               '"pt_um,pt_user1,pt__chr09,pt_desc1,pr_desc2"'
           &FieldSensitive = no                          }
           &PrevField      = '"pt_mstr.pt_um"'
           &Display       = yes
       }

      {crtfill.i
         &FieldName       = '"pt__chr09"'
         &FieldRow       =2
         &FieldCol      = 49
         &Visible      = yes
         &FrameName          = '"a"'
         &DataType        = '"Character"'
         &TableName        = "pt_mstr"
         &FieldLabel     = '"Division"'
         &FieldFormat = '"x(4)"'
         &FieldWidth     =4
         &FieldSensitive = no
         &PrevField      = '"pt_mstr.pt_user1"'
         &Display       = yes
       }

      {setvalue.i
         &ValueID   = '"ppptmta"'
         &ValueName    = '"ptpart-go"'
         &cValue    = "Yes"
       }                                          14
                                                                                                   Culligan Confidential
  Example# 1
  Code Sample – Item Master new fields                                                                    …continued
tpchr09go.p                                                        ptuser1 = if avail pt_mstr then pt_user1 else "N".           {getscrn.i
{mfdeclre.i}
                                                                       ptchr09 = if avail pt_mstr then pt__chr09 else "".           &FieldName = '"pt__chr09"'
  def var ptpart-go as char no-undo.                                                                                                &FrameName = '"a"'
  def var ptpart as char no-undo.                                      {scrnvalu.i                                                  &Variable = ptchr09
  def var ptchr09 as char no-undo.                                        &FieldName = '"pt_user1"'                               }
  def var ptuser1 as char no-undo.                                        &FrameName = '"a"'                                    find first pt_mstr exclusive
                                                                          &FieldValue = ptuser1                                    where pt_domain = global_domain
   {getvalue.i                                                          }                                                          and pt_part = ptpart.
      &ValueID = '"ppptmta"'
      &ValueName = '"ptpart-go"'                                                                                                if (keyfunction(lastkey) = "Go" or
                                                                        {scrnvalu.i                                                 keyfunction(lastkey) = "Return")
      &Variable = ptpart-go                                                &FieldName = '"pt__chr09"'                           and lookup(ptuser1,"Y,N") = 0
    }                                                                      &FrameName = '"a"'                                   and (pt_mstr.pt_user1 <> ptuser1) then
                                                                                                                                do:
                                                                           &FieldValue = ptchr09                                  message "Invalid RentFA. Must be Y or N.".
  /* There are 2 GOs in frame A:
   * 1: ptpart-go = yes                                                  }                                                        pause.
   *     If Go for pt_part                                                                                                        {entry.i &FieldName = '"pt_user1"'}
   *     Then Display the Item Division (pt__chr09)                  end. /* if ptpart-go... then do */                          end.
   * 2: ptpart-go = no                                                                                                           else
   *     If Go for pt_um, pt__chr09 (new), pt_desc1, pt_desc2        /* Update Item Division (pt__chr09) from the                if (keyfunction(lastkey) = "Go" or
   *     Then Update pt__chr09 from the screen value               screen value */                                                   keyfunction(lastkey) = "Return")
   *                                                                                                                             and lookup(ptchr09,",CORP,CODD") = 0
   * ptpart-go is set to yes in tpptchr09a.p (Entry of pt_part)      else do:                                                    and (pt_mstr.pt__chr09 <> ptchr09)
   * ptpart-go is set to no while handling the go for pt_part                                                                    then do:
   * ptpart-go is set to yes while handling the go for pt__chr09        {setvalue.i                                                 message "Invalid Division. Must be CODD, CORP or
   */                                                                      &ValueID = '"ppptmta"'                           blank.".
                                                                                                                                    pause.
  /* Display Item Division (pt__chr09) */                                  &ValueName = '"ptpart-go"'
                                                                                                                                  {entry.i     &FieldName = '"pt__chr09"'}
                                                                           &cValue  = "No"                                      end.
  if ptpart-go = "Yes" then do:                                          }                                                      else
                                                                                                                                if (keyfunction(lastkey) = "Go" or
    {setvalue.i                                                         {getscrn.i                                                  keyfunction(lastkey) = "Return")
        &ValueID = '"ppptmta"'                                             &FieldName = '"pt_part"'                             then do:
        &ValueName = '"ptpart-go"'                                                                                                 pt_mstr.pt__chr09 = ptchr09.
                                                                           &FrameName = '"a"'                                      pt_mstr.pt_user1 = ptuser1.
        &cValue  = "No"                                                    &Variable = ptpart                                   end.
      }                                                                  }
                                                                                                                              end. /* if ptpart-go... ELSE do */
    ptpart = frame-value.
                                                                        {getscrn.i                                            {disable.i &FieldNames = '"pt_user1"' }
    find first pt_mstr no-lock                                            &FieldName = '"pt_user1"'
       where pt_domain = global_domain                                    &FrameName = '"a"'                                  {disable.i &FieldNames = '"pt__chr09"' }
       and pt_part = ptpart no-error.                                     &Variable = ptuser1
                                                                        }                                                                                  Culligan Confidential
                                                                                             15
Example# 1
Anchor & Code Sample to enable scrolling for Item Master new fields

                                                                      tpptchr09dsp.p

                                                                      def input param pt-rowid as rowid no-undo.
                                                                      def var level as int init 1 no-undo.

                                                                      if pt-rowid <> ? then
                                                                      repeat while program-name(level) <> ?:
                                                                        if program-name(level) matches "*ppptmta.*"
                                                                        and program-name(level - 1) matches "*tppt_mstr.*"
                                                                        then do:
                                                                          find pt_mstr no-lock
                                                                             where rowid(pt_mstr) = pt-rowid.

                                                                        {scrnvalu.i
                                                                          &FieldName = '"pt_user1"'
                                                                          &FieldValue = pt_mstr.pt_user1
                                                                          &FrameName = '"a"'}
                                                                        {scrnvalu.i
                                                                           &FieldName = '"pt__chr09"'
                                                                           &FieldValue = pt_mstr.pt__chr09
                                                                           &FrameName = '"a"'}

  tppt_mstr.p                                                           leave.

  &global-define TableName pt_mstr
                                                                       end.
  {getbroker.i}
  {progvars.i}
  {tablevar.i}                                                         level = level + 1.
  &global-define AfterFind ~                                          end. /* repeat while */
     run tpptchr09dsp.p (rowid(pt_mstr)). ~
  {findrec.i}
  &Undefine AfterFind
  Procedure Create_Record:
  end procedure.
  {getrowid.i}                                                                                  Culligan Confidential
                                                        16
 Example# 2
 Sales Order Maintenance




New frame to accept
custom “lead data”
Fields that drives sales
commission calculations




                           17
                                Culligan Confidential
Example# 2
Set up anchor for SO Maintenance




                                   18
                                        Culligan Confidential
 Example# 2
 Code sample – Sales Order Maintenance
tpsotrl.p                                              space(25) vyesno label "Do you want to continue?"              {getscrn.i &fieldname = '"so_bill"'
                                                         skip
                                                                                                                              &framename = '"a"'
                                                         with side-labels title " Lead Source Validation"
{mfdeclre.i}.                                            size-chars 80 by 9 row 5 overlay.                                    &variable = temp-bill-to}.
DEF VAR temp-cancel-reason AS CHAR FORMAT "X(8)"       define frame frm-3
    INITIAL "" LABEL "Cancel Reason" NO-UNDO.            skip(2)                                                      FIND so_mstr
                                                         space(25) temp-call-ctr-ref label "Call Center                 WHERE so_mstr.so_domain = global_domain
DEF VAR temp-cancel-date AS DATE FORMAT
                                                       Reference"                                                       AND so_mstr.so_nbr = temp-so-nbr
   "99/99/99“ INITIAL ? LABEL "Cancel Date" NO-UNDO.                                                                    NO-LOCK NO-ERROR.
                                                         skip
DEF VAR temp-pap AS LOG FORMAT "Yes/No"                  space(25) vyesno label "Do you want to continue?"
 INITIAL "No" LABEL "APP" NO-UNDO.                       skip                                                          IF AVAILABLE so_mstr = FALSE THEN RETURN.
DEF VAR temp-bill-to AS CHAR NO-UNDO.                    with side-labels title " Call Center Reference Validation"    ASSIGN temp-site = so_mstr.so_site.
                                                         size-chars 80 by 9 row 5 overlay.                             FIND si_mstr
DEF VAR temp-lead-src AS INT FORMAT ">>9"
                                                                                                                        WHERE si_mstr.si_domain = global_domain
 INITIAL 0 LABEL "Lead Source" NO-UNDO.                                                                                 AND si_mstr.si_site = temp-site
                                                       define frame frm-4
DEF VAR temp-promo-code AS INT FORMAT ">>9"               skip(2)                                                       NO-LOCK NO-ERROR.
 INITIAL 0 LABEL "Promo Code" NO-UNDO.                    space(25) temp-lead-src label "Lead Source Value"
DEF VAR temp-lead-credit AS CHAR FORMAT "X(8)"            skip                                                         IF AVAILABLE si_mstr = TRUE
                                                          space(25) temp-call-ctr-ref label "Call Center                AND si_mstr.si_site >= "300"
 INITIAL "" LABEL "Lead Credit" NO-UNDO.
                                                       Reference"                                                       AND si_mstr.si_site <= "900" THEN
DEF VAR temp-call-ctr-ref AS CHAR FORMAT "X(8)"                                                                        DO:
                                                          skip
 INITIAL "" LABEL "Call Center Ref" NO-UNDO.              space(25) vyesno label "Do you want to continue?"             ASSIGN temp-lead-src = 0
DEF VAR temp-so-nbr AS CHAR NO-UNDO.                      skip                                                              temp-promo-code = 0
DEF VAR temp-site AS CHAR NO-UNDO.                        with side-labels title " Lead Source & Call Center Ref            temp-lead-credit = ""
                                                       Validation"                                                          temp-call-ctr-ref = ""
DEF VAR temp-run AS LOG NO-UNDO.
                                                          size-chars 80 by 9 row 5 overlay.                                 temp-pap = NO
DEF VAR temp-level AS INT NO-UNDO.                                                                                          temp-cancel-reason = ""
                                                       PAUSE 0 BEFORE-HIDE.
DEF VAR vyesno as log format "Yes/No"                  ASSIGN temp-run = YES                                                temp-cancel-date = ?.
 init "No" no-undo.                                          temp-level = 1.                                            FIND xxpi_mstr
DEF VAR lblank as char init "<Blank>" no-undo.         REPEAT WHILE program-name(temp-level) <> ?:                        WHERE xxpi_mstr.xxpi_domain = global_domain
                                                        IF program-name(temp-level) = "us/fs/fsrmamt.r" THEN              AND xxpi_mstr.xxpi_nbr = temp-so-nbr
                                                        DO:                                                               EXCLUSIVE-LOCK NO-ERROR.
DEFINE FRAME frm-1
                                                          ASSIGN temp-run = NO.
 temp-lead-src      AT ROW 1 COLUMN 5                     LEAVE.                                                        IF AVAILABLE xxpi_mstr = FALSE THEN
 temp-promo-code AT ROW 2 COLUMN 6                      END. /* IF program-name(temp-level) = "us/fs/fsrmamt.r"         DO:
 temp-lead-credit AT ROW 3 COLUMN 5                    THEN */                                                           CREATE xxpi_mstr.
                                                        ASSIGN temp-level = temp-level + 1.                              ASSIGN xxpi_mstr.xxpi_domain = global_domain
 temp-call-ctr-ref AT ROW 4 COLUMN 1
                                                       END. /* REPEAT WHILE program-name(temp-level) <>                      xxpi_mstr.xxpi_nbr = temp-so-nbr
 temp-pap          AT ROW 5 COLUMN 13                                                                                        xxpi_mstr.xxpi_lead_src = 0
                                                       ?: */
 temp-cancel-reason AT ROW 6 COLUMN 3                  IF temp-run = YES THEN                                                xxpi_mstr.xxpi_promo_code = 0
 temp-cancel-date AT ROW 7 COLUMN 5                    DO:                                                                   xxpi_mstr.xxpi_lead_credit = ""
  WITH SIDE-LABELS SIZE-CHARS 80 BY 9                                                                                        xxpi_mstr.xxpi_call_ctr_ref = ""
                                                        {getscrn.i &fieldname='"so_nbr"'
                                                                                                                             xxpi_mstr.xxpi_pap = NO
      ROW 5 OVERLAY.                                           &framename='"a"'                                              xxpi_mstr.xxpi_can_reason = ""
define frame frm-2                                             &variable=temp-so-nbr}.                                       xxpi_mstr.xxpi_can_date = ?.
  skip(2)                                                                                                               END. /* IF AVAILABLE xxpi_mstr = FALSE THEN */
  space(25) temp-lead-src label "Lead Source Value"
  skip                                                                              19
                                                                                                                                              Culligan Confidential
    Example# 2
    Code sample – Sales Order Maintenance                                                            …continued
ASSIGN temp-lead-src = xxpi_mstr.xxpi_lead_src               IF AVAILABLE xxpromo_mstr = FALSE THEN
                                                                                                                              /* ERROR: Invalid lead credit */
      temp-promo-code = xxpi_mstr.xxpi_promo_code               DO:
                                                                                                                              {pxmsg.i &MSGNUM=9341 &ERRORLEVEL=3}.
      temp-lead-credit = xxpi_mstr.xxpi_lead_credit              /* ERROR: Invalid promo code */
                                                                                                                              NEXT-PROMPT temp-lead-credit WITH FRAME frm-1.
      temp-call-ctr-ref = xxpi_mstr.xxpi_call_ctr_ref            {pxmsg.i &MSGNUM=9340 &ERRORLEVEL=3}.
                                                                                                                              NEXT loop1.
                                                                 NEXT-PROMPT temp-promo-code WITH FRAME frm-1.
      temp-pap = xxpi_mstr.xxpi_pap                                                                                           END. /* IF NOT CAN-FIND(emp_mstr... */
                                                                 NEXT loop1.
      temp-cancel-reason = xxpi_mstr.xxpi_can_reason            END. /* IF AVAILABLE xxpromo_mstr = FALSE THEN */
                                                                                                                           IF lookup(emp_title,"Technician,Driver,Inside Sales Rep,"
      temp-cancel-date = xxpi_mstr.xxpi_can_date.
                                                                                                                                            + "Retail Supervisor,Retail Associate") = 0
  loop1:                                                        IF xxpromo_mstr.xxpromo_start_date > so_mstr.so_ord_date
                                                                                                                                THEN DO:
  REPEAT ON ENDKEY UNDO, RETRY:                                  OR xxpromo_mstr.xxpromo_end_date < so_mstr.so_ord_date
                                                                                                                                 /* ERROR: Invalid lead credit */
                                                             THEN
    UPDATE temp-lead-src                                                                                                         {pxmsg.i &MSGNUM=9341 &ERRORLEVEL=3}.
                                                                DO:
         temp-promo-code                                                                                                        NEXT-PROMPT temp-lead-credit WITH FRAME frm-1.
                                                                 /* ERROR: Invalid promo code */
                                                                                                                                NEXT loop1.
         temp-lead-credit                                        {pxmsg.i &MSGNUM=9340 &ERRORLEVEL=3}.
                                                                                                                               END. /* IF CAN-FIND(sp_mstr... */
         temp-call-ctr-ref                                       NEXT-PROMPT temp-promo-code WITH FRAME frm-1.
                                                                                                                             END. /* IF temp-lead-credit <> "" THEN */
         temp-pap                                                NEXT loop1.
                                                                                                                             IF temp-pap = YES THEN
                                                                END. /* IF xxpromo_mstr.xxpromo_start_date >
         temp-cancel-reason                                                                                                  DO:
                                                             so_mstr.so_ord_date... */
         temp-cancel-date                                                                                                      IF NOT CAN-FIND(xxcm_pap
                                                                                                                                WHERE xxcm_pap.xxcm_domain = global_domain
           WITH FRAME frm-1.                                 IF xxpromo_mstr.xxpromo_allsites = NO THEN
                                                                                                                                AND xxcm_pap.xxcm_addr = temp-bill-to)
                                                                 DO:
                                                                                                                                AND NOT CAN-FIND(xxcc_mstr
   IF temp-lead-src = ? THEN temp-lead-src = 0.                   IF NOT CAN-FIND(xxpromosi_det
                                                                                                                                WHERE xxcc_mstr.xxcc_domain = global_domain
                                                                   WHERE xxpromosi_det.xxpromosi_domain = global_domain
   IF temp-promo-code = ? THEN temp-promo-code = 0.                                                                             AND xxcc_mstr.xxcc_addr = temp-bill-to) THEN
                                                                   AND xxpromosi_det.xxpromosi_code = temp-promo-code
   IF temp-lead-credit = ? THEN temp-lead-credit = "".                                                                         DO:
                                                                   AND xxpromosi_det.xxpromosi_site = so_mstr.so_site
                                                                                                                                /* ERROR: Customer must have active APP account */
   IF temp-call-ctr-ref = ? THEN temp-call-ctr-ref = "".           AND xxpromosi_det.xxpromosi_active = YES) THEN
                                                                                                                                {pxmsg.i &MSGNUM=9337 &ERRORLEVEL=3}.
   IF temp-pap = ? THEN temp-pap = NO.                            DO:
                                                                                                                                NEXT-PROMPT temp-pap WITH FRAME frm-1.
   IF temp-cancel-reason = ? THEN temp-cancel-reason = "".         /* ERROR: Invalid promo code */
                                                                                                                                NEXT loop1.
                                                                   {pxmsg.i &MSGNUM=9340 &ERRORLEVEL=3}.
   IF NOT CAN-FIND(code_mstr                                                                                                   END. /* IF NOT CAN-FIND(xxcm_pap... */
                                                                   NEXT-PROMPT temp-promo-code WITH FRAME frm-1.
    WHERE code_mstr.code_domain = global_domain                                                                              END. /* IF temp-pap = YES THEN */
                                                                   NEXT loop1.
    AND code_mstr.code_fldname = "temp-lead-src"                  END. /* IF NOT CAN-FIND(xxpromosi_det... */
                                                                                                                            IF temp-cancel-date <> ? THEN
    AND code_mstr.code_value = STRING(temp-lead-src,             END. /* IF xxpromo_mstr.xxpromo_allsites = NO THEN */
                                                                                                                            DO:
       "999")) THEN                                                                                                          IF temp-cancel-date < so_mstr.so_ord_date THEN
   DO:                                                          IF temp-lead-credit <> "" THEN
                                                                                                                             DO:
                                                                DO:
    /* ERROR: Invalid Lead Source */                                                                                           /* ERROR: Invalid cancel date */
                                                                 FIND emp_mstr
    {pxmsg.i &MSGNUM=9283 &ERRORLEVEL=3}.                                                                                     {pxmsg.i &MSGNUM=9904 &ERRORLEVEL=3}.
                                                                   WHERE emp_mstr.emp_domain = global_domain
                                                                                                                              NEXT-PROMPT temp-cancel-date WITH FRAME frm-1.
    NEXT-PROMPT temp-lead-src WITH FRAME frm-1.                    AND emp_mstr.emp_addr = temp-lead-credit
                                                                                                                              NEXT loop1.
    NEXT loop1.                                                    AND emp_mstr.emp_status <> "TR"
                                                                                                                             END. /* IF temp-cancel-date < lca_opn_date THEN */
   END. /* IF NOT CAN-FIND(code_mstr */                            NO-LOCK NO-ERROR.

                                                                 IF AVAILABLE emp_mstr = FALSE THEN
   FIND xxpromo_mstr                                             DO:
   WHERE xxpromo_mstr.xxpromo_domain = global_domain
    AND xxpromo_mstr.xxpromo_code = temp-promo-code
    NO-LOCK NO-ERROR.                                                                 20
                                                                                                                                                    Culligan Confidential
    Example# 2
    Code sample – Sales Order Maintenance                                                             …continued
IF temp-cancel-reason = "" THEN                                                                                                    xxpi_mstr.xxpi_can_reason = temp-cancel-reason
                                                          if vyesno = no then next loop1.                                          xxpi_mstr.xxpi_can_date = temp-cancel-date.
     DO:
                                                          else do:                                                            END. /* IF si_mstr.si_site >= 300... */
      /* ERROR: Reason code does not exist */               hide frame frm-1.                                                END. /* IF temp-run = YES THEN */
      {pxmsg.i &MSGNUM=534 &ERRORLEVEL=3}.                  leave loop1.
      NEXT-PROMPT temp-cancel-reason WITH FRAME           end.                                                               HIDE FRAME frm-1 NO-PAUSE.
        frm-1.                                           end. /* temp-lead-src = 0 */
      NEXT loop1.                                        else if temp-call-ctr-ref = "" and temp-lead-src <> 0
                                                         then do:
     END. /* IF temp-cancel-reason = "" THEN */
    END. /* IF temp-cancel-date <> ? THEN */
                                                       display lblank @ temp-call-ctr-ref with frame frm-3.
IF temp-cancel-reason <> "" THEN                            update vyesno with frame frm-3.
    DO:                                                     hide frame frm-3.
     IF NOT CAN-FIND(code_mstr                              if vyesno = no then next loop1.
      WHERE code_mstr.code_domain = global_domain           else do:
                                                              hide frame frm-1.
      AND code_mstr.code_fldname = "sa_sa_type"
                                                              leave loop1.
      AND code_mstr.code_value = temp-cancel-reason)        end.
        THEN                                              end. /* temp-call-ctr-ref = "" */
     DO:                                                  else if temp-lead-src = 0 and temp-call-ctr-ref = ""
      /* ERROR: Reason code does not exist */             then do:
      {pxmsg.i &MSGNUM=534 &ERRORLEVEL=3}.                 display temp-lead-src
                                                                  lblank @ temp-call-ctr-ref
      NEXT-PROMPT temp-cancel-reason WITH FRAME
                                                              with frame frm-4.
        frm-1.
                                                           update vyesno with frame frm-4.
      NEXT loop1.                                          hide frame frm-4.
     END. /* IF NOT CAN-FIND(code_mstr... */               if vyesno = no then next loop1.
                                                           else do:
    IF temp-cancel-date = ? THEN                             hide frame frm-1.
                                                             leave loop1.
    DO:
                                                           end.
     /* ERROR: Invalid cancel date */                      end. /* else if temp-lead-src = 0 and temp-call-ctr-ref = "" */
     {pxmsg.i &MSGNUM=9904 &ERRORLEVEL=3}.                 else
     NEXT-PROMPT temp-cancel-date WITH FRAME frm-1.         leave loop1.
     NEXT loop1.
                                                         END. /* loop1: REPEAT ON ENDKEY UNDO, RETRY: */
    END. /* IF temp-cancel-date = ? THEN */
   END. /* IF temp-cancel-reason <> "" THEN */           ASSIGN xxpi_mstr.xxpi_lead_src = temp-lead-src
                                                            xxpi_mstr.xxpi_promo_code = temp-promo-code
  vyesno = NO.                                              xxpi_mstr.xxpi_lead_credit = temp-lead-credit
  if temp-lead-src = 0 and temp-call-ctr-ref <> ""          xxpi_mstr.xxpi_call_ctr_ref = temp-call-ctr-ref
                                                            xxpi_mstr.xxpi_pap = temp-pap
  then do:
    display temp-lead-src with frame frm-2.
    update vyesno with frame frm-2.
    hide frame frm-2.
                                                                                    21
                                                                                                                                                  Culligan Confidential
Example# 2
Field Help



                                  New frame to capture
                                  additional data, to enable
                                  interface to another
                                  application.




F2 – help works with the
newly added fields, just
like it were a part of the
original QAD code.



                             22
                                             Culligan Confidential
Example# 3
PO Maintenance




                 23
                      Culligan Confidential
Example# 3
Set up anchor for PO Maintenance




                                   24
                                        Culligan Confidential
Example# 3
Code Sample – PO Maintenance

    tpvalsite.p

    {mfdeclre.i}

    def var vposite as char no-undo.

    {getscrn.i &fieldname='"po_site"'
               &variable=vposite }

    if vposite = "" then do:
        /*941 Blank site not allowed*/
        {pxmsg.i &MSGNUM=941 &ERRORLEVEL=3}

      {entry.i &fieldname='"po_site"'}
    end. /* vposite = "" */

    {setvalue.i &valuename='"tpvalsite"'
                &cvalue=vposite
                &valueid='"po"' }




                                              25
                                                   Culligan Confidential
Example# 4
TailorPro Audit




                  26
                       Culligan Confidential
Example# 4
Set up Audit records/fields in Tailor Pro




   Auto generates audit_vd_mstr.p
   Creates audit records in
   TailorPro’s “audittrail” table




                                            27
                                                 Culligan Confidential
Example# 4
Audit Trail Report

  xxtpauditrp.p C                             001    36.12.11 Tailorpro AuditTrail Report (C)                                Date: 09/08/09
  Page:    1                                                Culligan US1 - Test 07-07-09                                     Time: 17:36:59
  Date     Time User          TableName    FieldName    Old Value            New Value            Record Key Field               EventType
  -------- ----- -------      ------------ ------------ -------------------- -------------------- ------------------------------ ---------
  07/01/09 15:14 bmorgan      vd_mstr                                                             031816                         Create
  07/01/09 15:14 bmorgan      vd_mstr      vd_addr                           031816               031816                         Update
  07/01/09 15:15 bmorgan      vd_mstr      vd_sort                           SOLOMON, SALTSMAN & 031816                          Update
  07/01/09 15:15 bmorgan      vd_mstr      vd_promo                          ACTIVE               031816                         Update
  07/01/09 15:16 bmorgan      vd_mstr      vd_cr_terms                       N0                   031816                         Update

  07/02/09   10:41   dpatel   vd_mstr                                                            031818                         Create
  07/02/09   10:41   dpatel   vd_mstr     vd_addr                            031818              031818                         Update
  07/02/09   10:44   dpatel   vd_mstr     vd_sort                            COLONY INC          031818                         Update
  07/02/09   10:44   dpatel   vd_mstr     vd_promo                           ACTIVE              031818                         Update
  07/02/09   10:47   dpatel   vd_mstr     vd_cr_terms                        N45                 031818                         Update
  07/02/09   11:09   dpatel   vd_mstr                                                            031819                         Create
  07/02/09   11:09   dpatel   vd_mstr     vd_addr                            031819              031819                         Update
  07/02/09   11:10   dpatel   vd_mstr     vd_sort                            LINDA L BERNY       031819                         Update
  07/02/09   11:10   dpatel   vd_mstr     vd_promo                           ACTIVE              031819                         Update
  07/02/09   11:11   dpatel   vd_mstr     vd_cr_terms                        N0                  031819                         Update
  07/02/09   11:16   dpatel   vd_mstr                                                            194021                         Create
  07/02/09   11:16   dpatel   vd_mstr     vd_addr                            194021              194021                         Update
  07/02/09   11:17   dpatel   vd_mstr     vd_sort                            BARBARA HUNTT       194021                         Update
  07/02/09   11:17   dpatel   vd_mstr     vd_promo                           ACTIVE              194021                         Update
  07/02/09   11:18   dpatel   vd_mstr     vd_cr_terms                        N30                 194021                         Update
  07/02/09   11:20   dpatel   vd_mstr                                                            175100                         Create
  07/02/09   11:20   dpatel   vd_mstr     vd_addr                            175100              175100                         Update
  07/02/09   11:20   dpatel   vd_mstr     vd_sort                            MILTON ZAHN         175100                         Update
  07/02/09   11:20   dpatel   vd_mstr     vd_promo                           ACTIVE              175100                         Update
  07/02/09   11:23   dpatel   vd_mstr     vd_cr_terms                        N30                 175100                         Update
  07/02/09   11:25   dpatel   vd_mstr                                                            169725                         Create
  07/02/09   11:25   dpatel   vd_mstr     vd_addr                            169725              169725                         Update
  07/02/09   11:28   dpatel   vd_mstr     vd_sort                            MIKE LADD           169725                         Update
  07/02/09   11:28   dpatel   vd_mstr     vd_promo                           ACTIVE              169725                         Update
  07/02/09   11:28   dpatel   vd_mstr     vd_cr_terms                        N30                 169725                         Update
  07/02/09   15:28   dpatel   vd_mstr     vd_promo      INACTIVE             ACTIVE              187001                         Update
  07/02/09   15:42   dpatel   vd_mstr     vd_promo      INACTIVE             ACTIVE              KINSPR01                       Update
  07/02/09   15:43   dpatel   vd_mstr     vd_cr_terms   V40                  N40                 KINSPR01                       Update
  07/02/09   16:06   ekurty   vd_mstr                                                            10029996                       Create
  07/02/09   16:06   ekurty   vd_mstr     vd_addr                            10029996            10029996                       Update
  07/02/09   16:06   ekurty   vd_mstr     vd_sort                            CHERI BATES         10029996                       Update
  07/02/09   16:06   ekurty   vd_mstr     vd_cr_terms                        N0                  10029996                       Update
  07/02/09   16:06   ekurty   vd_mstr     vd_promo                           INACTIVE            10029996                       Update



                                                                        28
                                                                                                                          Culligan Confidential
Concerns?
 TailorPro cannot affect internal program variables

 TailorPro changes to screens are ignored by Mfg/Pro CIM loads

 TailorPro is not designed to handle "output" (i.e. reports), so you
 can't use the tool to change fields in a report

 We learned to ‘think differently’ in some instances such as
      Contract Start Date & End Date default values in 11.5.13.1
      Contract Maintenance needed to be modified. Anchoring our
      Tailorpro changes to the date field wasn’t providing the         assign hfield = self:handle.
      desired defaults, because QAD’s logic was overriding the
      Tailorpro change. Moved the anchor to “entry” of first field     /* get the CC, via handle (Tailorpro include doesn't work with this) */
      on the frame and used “NEW” function prior to QAD                repeat while valid-handle(hfield):
      program’s use of the function to achieve the results.
                                                                         if hfield:type = 'fill-in' and hfield:name = 'vod_cc' then
                                                                       def var hfield as handle no-undo.
       Scrolling frames do not respond as desired to the Tailorpro
       includes. So, for example, in 28.1 Voucher Maintenance, we      assign hfield = self:handle.
       used Progress handle, instead of the getscrn.i include file.
                                                                       /* get the CC, via handle (Tailorpro include doesn't work with this) */
                                                                       repeat while valid-handle(hfield):

                                                                         if hfield:type = 'fill-in' and hfield:name = 'vod_cc' then
                                                                             assign found-cc = yes
                                                                                      cc = hfield:screen-value.

                                                                         if hfield:type = 'fill-in' and hfield:name = 'vod_entity' then
                                                                             assign found-ent = yes
                                                                                      ent = hfield:screen-value.

                                                                         hfield = hfield:next-tab-item.
                                                                       end. /*repeat*/


                                                            29
                                                                                                                  Culligan Confidential
We can do what ???

       We can enable or disable display or updates to the Sales Order Maintenance without touching the code, by directly
       ‘anchoring’ a TailorPro code to a program.

 Seq       Event       Field        Program        Tailorpro        Frame                               Description

  1        Entry      sod_loc      sosomt1b.p   tplocreadonly1.p        d

  2        Entry        line       sosomta.p     tphidesodtl.p          c                     Hide some SO line detail fields

  3        Entry      sod_part     sosomta.p     tphidesodtl.p          c                  Hide some SO line entry detail fields

  4        Entry      sngl_ln      sosomta.p      tplineexit.p          a           show order summary after exiting line entry mode

  5        Entry        line       sosomta.p     tpskipreset.p          c                                skip frame

  6        Leave      sod_part     sosomta.p       tpsvpart.p           c                          Capture Part Number

  7        Leave      sod_part     sosomta.p       tpycode.p            c               Restrict New Lines for Y code Customers.

  8        Leave       so_nbr      sosomta1.p    tpgetsonbr.p           a                                get sonbr

  9        Entry       so_nbr      sosomta1.p    tpsetsonbr.p           a                                frame skip

 10         Go                     sosomta1.p     valcrtord.p           a       Validate that user can not enter a so_nbr that doesn't exist.

 11        Entry    so_tax_usage   sosomtb.p     tpskipframe.p      set_tax                            Skip a frame

 12        Entry     so_cr_init    sosomtc2.p     tpaskskip.p           d                                skip frame

 13        Entry     so_cr_init    sosomtc2.p     tphidesotrl.p         d                       hide some SO trailer fields

 14         exe      so_cr_init    sosomtc2.p     tphotkey.p            d

 15         Go                     sosomtc2.p    tpsoisbupd.p           d                                                                       30224

 16         Go                     sosomtc2.p     tpsostat1.p           d                                                                       31205

 17        Leave      so_cust      sosomtcm.p   tpchkcusttype.p         a       New Warning Message when a cod customer is selected.

 18        Leave      so_cust      sosomtcm.p     tpcustsite.p          a      Restrict COD users from entering Orders for Corp Customers

 19        Entry      so_cust      sosomtcm.p    tpgetsonbr.p           a                     Get sales order for new orders

 20        Leave       so_bill     sosomtcm.p      tplvbilto.p          a

 21        Leave      so_ship      sosomtcm.p     tpshiptolv.p          a

 22        Leave      so_ship      sosomtcm.p     tpshiptolv.p          a


                                                                   30
                                                                                                                       Culligan Confidential
We can do what ???
 Seq   Event      Field       Program       Tailorpro       Frame                                   Description

 23    Leave     so_cust     sosomtcm.p   tpupsochr01a.p         a                     BA 31531 flag order for Demar export

 24    Leave     so_cust     sosomtcm.p     tpycdcus.p           a            Capture Customer and Restrict Entry of new customers.

 25    Entry   sod_sob_std   sosomtf8.p    tphidesodtl.p        bom                     Hide some SO line entry detail fields

 26    Entry   reprice_dtl   sosomtla.p    tphidesocrt.p   line_pop                             Hide so_crt_int field

 27    Entry   sod_pr_list   sosomtla.p    tphidesocrt.p   line_pop               Hide so_crt_int field when entering new line item

 28    Entry   sod_list_pr   sosomtla.p    tphidesodtl.p         c                      Hide some SO line detail entry fields

 29    Leave   sod_pr_list   sosomtla.p    tphidesodtl.p   line_pop                     Hide some SO line entry detail fields

 30    Leave   sod_qty_ord   sosomtla.p    tppendob.p            c      Pending Obsolete - check to make sure there are enough in inventory

 31    Leave   sod_qty_ord   sosomtla.p   tpqtyordcase.p         c

 32     Go                   sosomtlb.p   tpcategorylv.p         d

 33    Entry     sod_loc     sosomtlb.p    tphidesodtl.p         d                         Hide some so line detail fields

 34     Go                   sosomtlb.p    tpsodpart.p           d                                                                            30224

 35    Entry   so_ord_date   sosomtp.p    tpdefremark.p          b

 36    Entry    so_slspsn    sosomtp.p    tphidesoshp.p          b1                    Hide some SO shipment frame fields

 37    Entry   so_req_date   sosomtp.p    tpskipframe.p          b                                   skip frame

 38    Entry    so_slspsn    sosomtp.p    tpskipframe.p          b1                                  skip frame

 39    Entry   so_ord_date   sosomtp.p    tpskipframe2.p         b

 40     Go                   sosomtp.p       tpslsrp.p           b1                            Salesperson validation

 41    Entry                 sosomtp.p    tptaxable_so.p         b                        Make Taxable flag “display only”

 42    Entry                 sosomtp.p    tptaxable_so.p    set_tax                       Make Taxable flag “display only”

 43    Entry   so_disc_pct   sosotrle.p    tphidesotrl.p        sotot                       Hide some SO trailer fields

 44     exe    so_disc_pct   sosotrle.p     tphotkey.p          sotot

 45     Go                   sosotrle.p    tpsoslsupd.p         sotot                Update sales person from header to detail

 46    Entry   so_disc_pct   sosotrle.p      tpsotrl.p          sotot                  new frame in sales order maintenance




                                                           31
                                                                                                                    Culligan Confidential
Where we are now

  We now have a total of approximately 180 TailorPro enhancements, involving non-invasive coding
  which includes:
      Added fields from QAD tables or Custom Database tables
      Default Field values displayed
      Edited field values
      Hidden fields
      Fields changed to View Only
      Large Sections of ‘applied’ logic
      Conditional Calls to other programs
      Auditing of DB table / field changes

  Time spent on the changes so far –
      With an average of 1 man day effort for a TailorPro program, we have spent 180 days working on
      the Tailorpro enhancements.
      An average of 1 week of effort for modifying the QAD code and all the related include files, we
      have 1260 man days (180 * 7 days) that would’ve been spent on QAD changes.
      That’s 1080 man days (1260 – 180) saved in coding time, alone.

  Time spent retro-fitting the codes for a future upgrade –
      Zero



                                                   32
                                                                                     Culligan Confidential
Conclusion

       Culligan needed a better fit between business needs and the
       business system.

       TailorPro provides the engine to enable the required
       customizations with no changes to source code or the production
       database.

       TailorPro could support Culligan’s need for audit compliance.

       QAD’s next upgrade will not require changes to TailorPro solutions.




                                    33
                                                                 Culligan Confidential
      34

34
     Culligan Confidential

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:14
posted:3/11/2012
language:English
pages:34