          SUBROUTINE (MODE,STKRCV,INIT.OID,INIT.GEN,VIEW.ONLY,POST.ENTRY)
** Version# 885.0002[5] - 12/17/2013 - 08:41pm - TSMITH - eclipse
*** V885.0002 Change - Custom Coding . - 12/17/2013 - TSMITH - eclipse
*** V885.0001 Change - Custom Coding . - 10/29/2013 - TSMITH - eclipse
*** Subroutine - OE
*-------------------------------------------------------------------------*
*** This routine is the main routine for Order Entry, and is used as a
*** basis for all Order Entry including Purchase Order, Sales Order,
*** Transfers etc.
*-------------------------------------------------------------------------*
*** MODE        - Mode (S=Sales,P=Purchase,T=Transfer)             [IN]
*** STKRCV      - Set to Yes or 'STOCK.RECEIPTS' indicates this is (IN)
***             - Stock Receipt
*** INIT.OID    - The Initial Order ID (existing) to open          (IN)
*** INIT.GEN    - The Initial Generation (existing)                (IN)
*** VIEW.ONLY   - View Only Flag Passed to program indicating if   (IN)
***             - if the order should allow updates.
*** POST.ENTRY  - Flag indicating Post Entry Mode                  (IN)
*-------------------------------------------------------------------------*
*** COMMON VARIABLES changed:
*** OID.DATA$       - Changed based on order / line item
*** OE.USER.VIEWS$  - Information on users view setup
*** UET.ENABLED$    - Unquality Event Tracking Enabled / Disabled
*** ABC.ENABLED$    - Activity Based Costing Enabled / Disabled
*** ACT.ID$         - User Defined screens.
*-------------------------------------------------------------------------*
*** Attributes of COMMON VARIABLE OID.DATA$:
*** <1> - OID         -- Order ID of current order active in LED
*** <2> - GEN         -- Current GEN of the active LED
*** <3> - LDID        -- Current Ledger Detail (Line Item) User is on
*** <4> - CN          -- Ship-To ID of the current order
*** <5> - PN          -- Part Number of current Product for current line
*** <8> - NEW.ORDER   -- Flag to note new order entered.
*** <9> - POST.ENTRY  -- Flag for post entry mode
*-------------------------------------------------------------------------*
*** Note: Variables that are valid throughout all of OE should be kept in
*** CC OE.EUQATES and they should end in "%".  For example, OID% is
*** equated to OE.VARS(1).  This id done for two reasons:
***
*** 1) This makes it easier to determin the scope of a variable.
*** 2) It makes it easier to pass many different variables at one time.
***
*** See CC OE.EQUATES for further details.
*-------------------------------------------------------------------------*
*           IF USER.ID='BRANDTB' THEN
*          NAME = OCONV(FIELD(TRANS('INITIALS',USER.ID,3,'X'),' ',1),"MCT")
*          MSG = 'Check the blue button ':NAME:'!'
*          SEND.MESSAGE 'Phantom',USER.ID,MSG
*          RETURN
*          END


          $INCLUDE CC OE.EQUATES
          $INCLUDE CC DIM.EQUATES

          DIM OE.VARS(DIM.OE.VARS.SIZE%)
          DIM PAF.DATA(5)      ;* Pass-Along-Fright Flags
          DIM OE.SFLAGS(5)     ;* Flags used to highlight hotkeys
          DIM OE.STATE(150)    ;* Variables Used to Maintain the State
                               ;* Inside of OE.
          DIM LD2(200)         ;* Second ld array
          WINDOW 1,1,80,23,9

          GOSUB INIT.OE
          IF ABORT THEN GOTO FINISH

          DISPLAY.SCREEN SCREEN.NAME%

START:    *** Come here when blanking out the screen and asking for
          *** another order.
          CLEAR.SCREEN
          MENU.CLEAR
          POLE.DISP.PRINT

          GOSUB INIT.START

          VSCROLL.DEFINE 1,1,6,78,10
          VSCROLL.SET 1

          *** This routine will read in an OID, or do what's neccesary
          *** to start a new one, as determined by the user.
          GOSUB GET.OID

          *** This routine will actually create a new led, and it pulls
          *** back all the information on the ledger records.
          GOSUB RECALL.ORDER
          *** Print the view specific screen data (ie - headings & columns)
          GOSUB DISP.ORDER

          *** Prepare for possible entry and navigation of the order.
          GOSUB ENTER.BODY
          *move the logic down here. It'll be a little bit slower but
          * it only happens at load time once. This is to ensure that all
          * the lines have been loaded before we search for an item.
          * If this was to be before displaying the order, we won't be able
          * to find the line item
          IF INIT.PN% THEN
             OE.FIND.PN MAT OE.VARS,LDID.LIST%,LINE.XREF%,INIT.PN%,LINE%
             *need to do this to reload the line.xref% array.
             *See IN.TABLE
             OE.LI.PRINT MAT OE.VARS,VIEW.REC%,SUBR.INFO%,LDID.LIST%,LINE.XREF%,,LN.MOVED,LI.NEW.QTY%
          END
          COL% = 1
          INITIAL.MOVE = YES
*-------------------------------------------------------------------------*
INBODY:   *** Set up the variables used by PARSEMOVE.
          QUIT        = NO
          IF INITIAL.MOVE THEN
             MOVE         = 'X'
             INITIAL.MOVE = NO
          END ELSE
             MOVE        = 0
          END
          LASTKEY     = 0
          DISP.MESS   = YES
          INIT.PN%    = ''
*-------------------------------------------------------------------------*
MOVENEXT: *** This section handles all the navigation rules in the screen.
          IF QUIT OR NOT(OE.OK%) THEN GOTO EXIT.LNS

          LI.MSGS    = ''   ;* Any actions for this line item.
          LINE.CT%   = DCOUNT(LINE.XREF%<1>,VM)
          IF LINE% = '' THEN LINE% = 1

          GOSUB LOG.CHANGE

          *** Restrict movement when in View.Only
          IF VIEW.ONLY% THEN
             COLS     = 1
             DOWNOK   = (LINE% < LINE.CT%)
          END ELSE
             COLS     = DCOUNT(TRIM(TRIM(VIEW.REC%<7>,0,'A'),VM),VM)
             DOWNOK   = (LINE% <= LINE.CT%)
          END

          * Save off the move as we use it to determine if this is the
          * first line of an order and the initial time in the order.
          * the first time in MOVE = 'X' and parsemove overrides this
          SV.MOVE = MOVE

          OE.PARSEMOVE COL%,COLS,VIEW.ONLY%,LDID.LIST%,LINE.XREF%,LN.MOVED,LI.NEW.QTY%,,NEED.REDISP

IN.TABLE: * Make sure we have the XREFS array built
          IF (NEED.REDISP OR CHNG) THEN
             *** only rebuild the LINE.XREFS array if something changed or
             *** if the user moved out of the current display area
             *** NEED.REDISP is set in OE.PARSEMOVE
             OE.LI.PRINT MAT OE.VARS,VIEW.REC%,SUBR.INFO%,LDID.LIST%,LINE.XREF%,,LN.MOVED,LI.NEW.QTY%
             CHNG = NO
          END

          NEED.REDISP = YES

          LINE%   = LINE.XREF%<4>
          LX      = LINE.XREF%<1,LINE%>
          TOT.LD  = LINE.XREF%<3,LINE%>
          DISP.CT = "Item ":LX:" of ":TOT.LD
          PRINT @(59,16):DISP.CT "20ÍL"
          IF LN.MOVED THEN
             LI.MSG = ''
             DISP.MESS = YES
          END

          * if we moved lines or if this is the first time into the order
          * set call.type to 1 so we process the actions for the line item
          IF LN.MOVED OR SV.MOVE = 'X' THEN
             CALL.TYPE = 1
          END ELSE
             CALL.TYPE = ''
          END

          GOSUB GET.LINE

          *** if we are on a brand new line and the subs hotke was
          *** active for the previous line we want to make sure that it
          *** isn't active for the new line so that the Subs hotkey won't
          *** light up.
          IF LDID% = '' THEN SUB.ACTIVE% = NO

          GOSUB HIGHLIGHT.HOTKEYS
          GOSUB CHECK.COL
          OE.LI.GET.COL VIEW.REC%,COL%,DATA.COL

          LI.MSGS  = ''
          VO.ERR   = LINE.DATA%<1,DATA.COL,4>

          * If the order is view only, then the current input is view
          * only. Likewise, if the user is in the quantity column (COL%=1)
          * or if the user is in the description (COL%=2), and the user
          * does not have auth to change the quantity, set the input
          * to view only.
          VO.INP   = (VIEW.ONLY% OR (COL% = 1 AND NOT(QTY.CHNG.OK%)))
          VO.INP   = VO.INP OR ((COL% = 2) AND NOT(QTY.CHNG.OK%))
           * View only for Job Management.
          JM.ORDER = LED(83)<1,1>[1,7] = "@JOBNO=" ; * Job Management
          IF JM.ORDER AND NOT(VO.INP) THEN
             READ JM.EUSERS FROM CTRLFILE,'JM.EDIT.USERS' ELSE JM.EUSERS=''
             LOCATE USER.ID IN JM.EUSERS SETTING NADA THEN
                JM.EDIT = YES
             END ELSE
                JM.EDIT = NO
             END
             IF USER.ID = "ECLIPSE" OR JM.EDIT THEN
                IF LED(33)<1,GEN%> # "" THEN VO.INP = YES
             END ELSE
                VO.INP = YES
             END
          END

          *** This is the routine that does all the inputs in the body of
          *** the order, the updating happens later.
          OE.LI.INP MAT OE.VARS,LINE%,DATA.COL,LINE.DATA%,VIEW.REC%,SUBR.INFO%,VO.INP,VALUE,OLD.VALUE,CHNG,SUB.OPT
          SV.HELP  = HELP
          BEGIN CASE
          CASE NOT(CHNG) AND NOT(HELP); NULL  ;* No change = No update
          CASE VO.ERR;      GOSUB DISP.ERR    ;* Show View Only Errors
          CASE COL% = 1;    GOSUB UPD.QO      ;* Update Quantity
          CASE COL% = 2;    GOSUB UPD.PN      ;* Update Product
          CASE OTHERWISE;   GOSUB UPD.INP     ;* Generic Column Update
          END CASE

          IF LI.MSGS THEN
             OE.ACTS%<-1> = LI.MSGS
          END

          IF (SV.HELP OR CHNG) AND NOT(LDID% = '' AND COL% = 1 AND LI.NEW.QTY%) THEN
             GOSUB GET.LINE.DATA
             GOSUB DISP.ALL.LINES
          END

          IF SUB.OPT THEN GOSUB SUBS

          * must set the change order quantity variable to no.  the change
          * order quantity should only display once if the user enters
          * the order intially and changes the order quantity for the
          * line.  Once the user moves out of this field then the
          * message should not display again.
          CHECK.QO.CHANGE% = NO

          GOTO MOVENEXT
*-------------------------------------------------------------------------*
DISP.ERR: *** If a cell is uneditable, SVM 4 has the message codes for
          *** the error message explaining to the user why they cannot
          *** edit the cell.  This routine adds those messages to the
          *** line item messages array.
          CT = DCOUNT(VO.ERR,SVM)
          FOR J = 1 TO CT
             AMSG = RAISE(RAISE(RAISE(VO.ERR<1,1,J>)))
             ACTION.ADD.MSG LI.MSGS,,,AMSG,,,YES
          NEXT J

          GOSUB SHOW.LI.MSGS

          RETURN
*-------------------------------------------------------------------------*
UPD.QO:   *** This updates the quantity for the current line item.  This
          *** is not handled using generic update routines like most view
          *** elements because it involves adding a line item to the order.

          *** Don't do anything if just help is true...
          IF NOT(CHANGED) THEN RETURN

          *** Don't let the user accidentally change the QO when they
          *** first enter an existing order.
          IF NOT(NEW.ORDER%) AND OLD.VALUE # '' AND CHECK.QO.CHANGE% THEN
             PLAY '$CHANGE.WARNING'
             SURE = ''
IN.QO2:      INP.PROMPT SURE,'%12','YN',1
             IF NOT(SURE) THEN
                RETURN
             END
          END

          IF LD(1) = '' THEN
             *** If this is a new line and doesn't have a LD() record yet,
             *** just save the quantity they enter and add a line item
             *** when they fill in the product.  If they leave this line
             *** w/o entering a product, the new line qty goes away.
             LI.NEW.QTY% = VALUE

             *** Since there is no product yet, don't bother redisplaying
             CHNG = NO
          END

          *** Only edit the quantity for products (not comments, subtotals)
          IS.PN = (NUM(LD(1)) AND LD(1) # '')
          IF NOT(IS.PN) THEN RETURN
          OE.PARSE.QO MAT OE.VARS,OLD.VALUE,LD(1),PARSE.OK,ALLOC.ZONE,OLD.QO,OLD.Q1,OLD.U1,OLD.Q2,OLD.U2
          OE.PARSE.QO MAT OE.VARS,VALUE,LD(1),PARSE.OK,ALLOC.ZONE,QO,Q1,U1,Q2,U2

          *** Do not let the user try and update the Quantity Ordered to
          *** anything but 1 on a Gift Card/Certificate product.
          IF LD(136) AND QO # 1 THEN
             GCMSG  = 'Only A Quantity Of 1 Is Allowed On A Gift '
             GCMSG := 'Card Purchase.'
             ERR.MESS 10,5,GCMSG
             RETURN
          END

          *if QO is 0, don't allow updating ...
          IF NOT(QO) THEN RETURN
          IF NOT(PARSE.OK) THEN RETURN
          ZONE.CHANGED = NO
          IF ALLOC.ZONE # '' THEN
             IF ALLOC.ZONE # LD(41) THEN
                ZONE.CHANGED = YES
             END
          END

          IF SHOULD.PROMPT.PAF% AND NOT(HAVE.PROMPTED.PAF%) THEN
             OE.PROMPT.PAF MAT OE.VARS, MAT PAF.DATA
          END

          *** Update the quantity (both update logic and UI)
          ADD.LINES = ''
          ALL.ADDED = ''
          MSGS      = ''
          RESPS     = ''
          MSG.FLAG  = NO
          ABORTED   = NO
          UPD.LOC   = '' ;* This is used to keep track of what has
                         ;* already been updated in OE.UPD.QO.

          LOOP
             ACT.ID = 'OE~ORIG.ORD.QTY'
             LOCATE ACT.ID IN RESPS<1> SETTING OPOS THEN
                RESPS<2,OPOS> = OLD.QO
             END ELSE
                RESPS<1,OPOS> = ACT.ID
                RESPS<2,OPOS> = OLD.QO
             END

             OE.UPD.QO MAT OE.VARS,MAT OE.SFLAGS,GROUP,QO,U1,ALLOC.ZONE,,UPD.LOC,MSG.FLAG,MSGS,RESPS

             ACT.ID = 'OE~ORIG.ORD.QTY'
             LOCATE ACT.ID IN RESPS<1> SETTING OPOS THEN
                RESPS = DELETE(RESPS,1,OPOS)
                RESPS = DELETE(RESPS,2,OPOS)
             END

             IF MSG.FLAG OR MSGS THEN
                OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,ADD.LINES,MSGS,ABORTED,RESPS,CUSTOM.XREF%
             END
             IF F12 THEN ABORTED = YES

             WHILE MSG.FLAG AND NOT(ABORTED)
          REPEAT

          *** Updating the quantity might cause the current line item to
          *** be deleted... this will remove it from the LINE.XREF% array
          *** so that the line will print correctly.
          OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%
          LOCATE LDID% IN LDID.LIST%<1> SETTING NOTHING ELSE
             LDID%      = ''
             LINE.XREF% = ''
             GOSUB DISP.ALL.LINES
          END
          CALL.TYPE = 2
          OE.LI.GET.ADDL MAT OE.VARS,MAT OE.SFLAGS,CALL.TYPE,LI.MSGS
          GOSUB CHECK.CREDIT

          DISP.MESS = YES

          IF ADD.LINES THEN
             GOTO ADD.LINES
          END ELSE
             RETURN
          END
*-------------------------------------------------------------------------*
UPD.PN:   *** This is the logic that handles the selection of the part(s).
          *** Adding on a new line item, or changing a part,or even adding
          *** multiple parts.

          SV.MOVE    = MOVE
          SV.LASTKEY = LASTKEY

          *** No update if the user is trying to leave...
          IF QUIT THEN RETURN

          * Don't allow changes on Gens with Branches the user is not
          * authed for.
          * This check is only needed on Sales Orders open generations
          * which are the only cases where we might access line items
          * that are a different GEN with different branches
          * Statuses I,$,X,and Y are not open
          IF MODE% = 'S' AND NOT(INDEX('I$XY',LED(6)<1,GEN%>,1)) THEN
             * Find the GEN that this line item is on
             FIND LDID% IN LED(48) SETTING LDID.AM,LDID.GEN,LDID.SVM ELSE
                LDID.GEN = GEN%
             END

             * Check if user is authed for the line item's Gen's branches
             OE.USER.BRANCH.AUTH MODE%,LDID.GEN,AUTH.MSG

             * Display Branch auth message and clear PN selection
             IF AUTH.MSG THEN
                PNS = ''
                MSGS = ''
                ACTION.ADD.MSG MSGS,,YES,AUTH.MSG,,,YES
                OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,ADD.LINES,MSGS,,,CUSTOM.XREF%
                GOSUB DISP.ALL.LINES
                RETURN TO IN.TABLE
             END
          END

SELECT.PNS:*
          GOSUB UP.PASS
          GOSUB CHK.TAG.ALONG
          IF TAG.CONTINUE THEN
             OE.SELECT.PNS OID%,GEN%,LINE%,VALUE,PNS,PN.QTYS,ADDL.PASS,CMNTS
          END ELSE
             PNS = ''
          END
          IF PNS = '' THEN
             * if there was something previsouly in LD(1) then we want
             * to make sure that we redisplay that.....
             IF LD(1) # '' THEN
                GOSUB DISP.ALL.LINES
             END ELSE
                * want to reset these varibles to keep the system from
                * redisplaying the line.  This will keep the original
                * data entered in the input.
                CHNG = NO
                NEED.REDISP = NO
             END
             RETURN TO IN.TABLE
          END
          *With this control record on, we may have to clear a previous msg
          IF DISP.PROD.NOTES THEN
             WINDOW.CHILD.CLOSE
          END

          * Save off what LDID we are currently looking at, especially
          * if it's null, signifying we are adding a brand new line item.
          ORIG.LDID = LDID%

          *** If LDID is currently set, then reset the subs cross-ref for
          *** the LDID. This allows the subs and related items screens to
          *** display if the new entry has subs or related items.
          IF LDID% THEN
             LOCATE LDID% IN SUBS.XREF% SETTING POS THEN
                SUBS.XREF% = DELETE(SUBS.XREF%,POS)
             END
          END

          * Save the displayed UOM and quantity information for the
          * previous product.
          GOSUB GET.ORIG.UOM.DISP

          * If adding a new item to a generation, see if user wants
          * to recalc pass along freight if generation has pass along
          * freight posted
          IF SHOULD.PROMPT.PAF% AND NOT(HAVE.PROMPTED.PAF%) THEN
             OE.PROMPT.PAF MAT OE.VARS, MAT PAF.DATA
          END

          IF SCHED.TOGGLE THEN
             CHECK.KEY MODE%:'OE.SCHEDULE',,SCHED.ACTIVE%
             * If they have set Sched to On and they don't have the auth
             * key or are a superuser, then make it behave like they have
             * the level 1 auth key.
             IF SCHED.ACTIVE% = 99 OR SCHED.ACTIVE%='' THEN
                SCHED.ACTIVE% = YES
             END
          END

          PN.CT     = DCOUNT(PNS,VM)
          ADD.LINES = ''
          FOR PNN = 1 TO PN.CT
             PN.DATA = PN.QTYS<1,PNN>
             PN      = PNS<1,PNN>
             * Don't allow changes to required tag along products
             IF LD(132) # '' THEN
                PARENT.LDID = LD(132)
                LD.GET2 MAT LD2, PARENT.LDID
                GET.TAG.ALONG.INFO LD2(1),P.DESC,T.PNS,T.QTYS,T.REQD
                LOCATE LD(1) IN T.PNS SETTING TAGPOS THEN
                   IF T.REQD<TAGPOS> THEN
                      ERR.MESS 10,5,'%764',,'OE~TAGALONG'
                      CONTINUE
                   END
                END
             END
             * Count the number of lines in the comment
             CT.LNS    = DCOUNT(CMNTS<1,PNN>,SVM)
             SINGLE.LN = ''
             CMT       = ''
             FOR CMT.LN = 1 TO CT.LNS
                * Add the comment line
                SINGLE.LN<1,CMT.LN,1> = CMNTS<1,PNN,CMT.LN>
                * Add the comment type
                SINGLE.LN<1,CMT.LN,2> = 'F'
             NEXT CMT.LN
             * Lower the comment so that it is passed correctly into
             * OE.ADD.LINES
             CMT<1,1> = LOWER(SINGLE.LN)

             ADDL.DATA = ''
             INIT.LDID = ''

             GOSUB CHECK.PDW
             IF PN = '' THEN CONTINUE

             GET.ALL.PRD LED(2)<1,GEN%,2>,PN,QSIGN%

             IF PN.DATA # '' THEN
                INS.LINE = YES
                IF PN.DATA<1,1,1> = '*' THEN
                   ADDL.DATA   = PN.DATA
                   ALLOC.ZONE  = ''
                END ELSE
                   ALLOC.ZONE  = UPCASE(FIELD(PN.DATA<1,1,1>,',',2))
                   QO          = PN.DATA<1,1,1>
                   *we should not set U1 to null here. If U1 is set to
                   *null here, system will try to find the largest UOM
                   *to use instead of the default UOM when adding line
                   *items from family search or reorder pad
                   DFLT.PER.GET MODE%,,U1
                   *Make sure that quantities are parsed accordingly,
                   *even if they have been entered by a screen such as
                   *QuickScan
                   OE.PARSE.QO MAT OE.VARS,QO,PN,PARSE.OK,ALLOC.ZONE,QO,,U1
                   IF NOT(PARSE.OK) THEN CONTINUE
                END
             END ELSE
                *** Manual Entry
                INS.LINE = NO
                IF LD(1) = '' THEN
                   INS.LINE = YES
                   *** New Line Item
                   OE.PARSE.QO MAT OE.VARS,LI.NEW.QTY%,PN,PARSE.OK,ALLOC.ZONE,QO,,U1
                   IF NOT(PARSE.OK) THEN CONTINUE
                END ELSE
                   QO         = LD(4) * QSIGN%
                   U1         = LD(23)
                   ALLOC.ZONE = LD(41)
                   IF PN # LD(1) THEN
                      GOSUB CONVERT.UOM.TO.NEW.PRODUCT
                   END
                END
             END

             *** Set up all the data for each of the lines getting added.
             *if there is a valid active LDID%, we want to add the line
             * line item below the current line instead of adding it to
             * "1".
             IF LDID%+0 > 0 THEN
                OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%
                LOCATE LDID% IN LDID.LIST%<1> SETTING LDID.POS THEN
                   LINE.NUM = LDID.POS+1
                END
             END
             OE.ADD.LINES ADD.LINES,PN,QO,U1,ALLOC.ZONE,INS.LINE,LINE.NUM,,,ADDL.DATA,INIT.LDID,,,CMT
             CMT = ''
          NEXT PNN
          LI.NEW.QTY% = ''
          DISP.MESS   = YES
          IF NOT(ADD.LINES) THEN
             RETURN TO MOVENEXT
          END
ADD.LINES:*

          * When there are multipled parents and we are adding the children
          * at the same time, the line numbers will be off... fix that here
          PREV.LINES = 0
          CUR.OFFSET = 0
          AD.CT = DCOUNT(ADD.LINES,AM)
          LINE.NUM = ADD.LINES<AD.CT,6>
          * Step backwards through ADD.LINES... unless somebody adds param
          * to OE.LI.COMMIT.MULTI below so it adds in correct order rather
          * than backwards.
          FOR J = AD.CT TO 1 STEP -1
             * The line number (ADD.LINES<J,6>) will be the same for all
             * children of a given parent.  Every change of a line number
             * indicates another parent... Unless logic changes in the
             * call flow to get to OE.PROD.TAG.ALONG.ADD (LINE.NUM += 1).
             CHK.NUM = ADD.LINES<J,6>
             IF CHK.NUM # LINE.NUM THEN
                CUR.OFFSET = PREV.LINES
                LINE.NUM = CHK.NUM
             END
             PREV.LINES += 1
             IF CUR.OFFSET THEN ADD.LINES<J,6> += CUR.OFFSET
          NEXT J

          * If we allowed the user to select PNs & qtys by calling
          * POE.SELECT.PN.QTYS, then we want to pass an exception type
          * to OE.LI.COMMIT.MULTI so that it doesn't display the buy
          * package warnings a second time when we are adding the items
          * to the PO.
          BEGIN CASE
          CASE ADDL.PASS<1,5> = 'POE.SELECT.PN.QTYS'
             EXCEPT.TYPE = 'CHK.BUY.PKG'
          CASE ADDL.PASS<1,5> = 'OE.SELECT.PN.QTYS'
             EXCEPT.TYPE = 'CHK.MIN.SELL'
          CASE OTHERWISE
             EXCEPT.TYPE = ''
          END CASE

          *** This actually applies the individual part numbers to the
          *** order.
          OE.LI.COMMIT.MULTI MAT OE.VARS,MAT OE.SFLAGS,MAT PAF.DATA,SUBS.XREF%,ADD.LINES,,ADDED.LDIDS%,CUSTOM.XREF%,EXCEPT.TYPE
          NEW.PN.DISP = YES
          OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%
          LOCATE LDID% IN LDID.LIST%<1> SETTING XXX ELSE LDID% = ''
          * LDID% will be null if we did not actually add the line so we
          * just need to return to movenext
          IF LDID% = '' THEN RETURN TO MOVENEXT

          IF ALL.ADDED # '' THEN ALL.ADDED := AM
          ALL.ADDED := ADDED.LDIDS%
          GOSUB GET.ADDL

          * If the Orig LDID was null, then we have prob'ly added an item,
          * either a single, or multiples... If we have added multiples
          * (like via Substitutes) we don't want to get stuck on the
          * most recently added line item, try to have the the lines as
          * much as possible on the screen. If the original line was blank,
          * keep cursor on that line, otherwise use the last added item
          IF ORIG.LDID = '' THEN
             EARLY.IX = LINE.XREF%<1,LINE%>
             SV.LDID  = LDID.LIST%<1,EARLY.IX>
          END ELSE
             SV.LDID  = ORIG.LDID
             IF LINE% > 5 THEN
                IF ADDED.LDIDS% # '' THEN
                   SV.LDID  = ADDED.LDIDS%<1>
                END
             END
          END

          * Check to see if we added kits that will be backordered
          SOE.BACKORDERED.KITS MAT OE.VARS,MAT OE.STATE

          * Reset ld and product information after bo kit check
          LDID% = SV.LDID
          LD.GET LDID%
          MAT OLD.LD = MAT LD
          PN         = LD(1)
          IF NUM(PN) AND PN#'' THEN
             GET.ALL.PRD LED(2)<1,GEN%,2>,PN,QSIGN%
          END

          NEW.VLIN      = LINE.XREF%<4>
          NEW.LIIX      = LINE.XREF%<5>:'~END'

          LOCATE LDID% IN LDID.LIST%<1> SETTING NEW.LIIX ELSE
             NEW.VLIN   = 1
             NEW.LIIX   = 1
          END
          LINE.XREF%<4> = NEW.VLIN
          LINE.XREF%<5> = NEW.LIIX

          * If there are only two editable columns and we enter a product
          * in the second column check to see if there are any product
          * messages that need to be displayed.
          IF COLS = 2 THEN
             CALL.TYPE = 2
             GOSUB GET.LINE
             SKIP.PRD.MSGS = NO
          END
          * The parent ldid is the main product we added that caused us
          * to add additional tag along products. The parent ldid is
          * used to reset the user to the parent line on the order
          PARENT.LDID = ''
          *** delete the parent and remaining tag alongs from the order
          IF MODE% = 'S' THEN
             MATBUILD SV.LD FROM LD
             MATBUILD SV.OLD.LD FROM OLD.LD
             SV.LDID = LDID%
             REMOVING.PARENT = NO
             LDCNT = DCOUNT(ALL.ADDED,AM)
             FOR EACH.LDID = 1 TO LDCNT
                LDID% = ALL.ADDED<EACH.LDID>
                IF LDID% = '' THEN CONTINUE
                LD.GET LDID%
                MAT OLD.LD = MAT LD

                OE.CHECK.FOR.TAG.ALONGS MAT OE.VARS,MAT OE.STATE,PNS,QTY,REQ,REMOVE.PARENT

                IF ORIG.LDID = '' THEN
                   IF PARENT.LDID = '' THEN PARENT.LDID = LD(132)
                END ELSE
                   PARENT.LDID = LD(132)
                END
                * Make sure that the PARENT LD array is updated with the
                * posssibly new child LDID
                OE.UPD.PARENT.TAG.ALONG MAT OE.VARS,MAT OE.STATE
                IF REMOVE.PARENT THEN
                   LDID% = REMOVE.PARENT
                   REMOVING.PARENT = YES
                   GOTO DEL.LINE
                END
             NEXT EACH.LDID

             * If a parent LDID was set then we know that we are in the
             * process of adding a product with tag alongs. Make sure
             * to put the user back on the parent's line so that if
             * the review screen opens automatically we are on the
             * right LDID
             IF PARENT.LDID THEN
                LDID% = PARENT.LDID
                LD.GET PARENT.LDID
                MAT OLD.LD = MAT LD
             END ELSE
                LDID% = SV.LDID
                MATPARSE LD FROM SV.LD
                MATPARSE OLD.LD FROM SV.OLD.LD
             END

             ALL.ADDED = ''
             OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%

             NEW.LIIX = LINE.XREF%<5>
             LOCATE LDID% IN LDID.LIST%<1> SETTING NEW.LIIX ELSE
                NEW.LIIX = 1
             END
             LINE.XREF%<5> = NEW.LIIX
          END

          SV.OE.OK = OE.OK%
          GOSUB CHECK.CREDIT
          IF MODE%='S' THEN
             !!!if we are adding one single line item and the customer goes
             !!!over credit limit, then we want to remove that line item
             !!!otherwise, we have to put the order in view only mode
             LDCNT = DCOUNT(ADDED.LDIDS%,AM)
             *if the OE.OK flag is set to YES before credit checking and
             *it is set to no after credit checking, we should not have
             *allowed user to enter that product. The product is being
             *removed here ...
             IF SV.OE.OK AND NOT(OE.OK%) THEN
                IF NOT(ORIG.LDID) AND LDCNT = 1 THEN
                   AUTO.DEL = YES
                   ***DEL.LINE will check credit
                   OE.OK% = SV.OE.OK
                   GOSUB DEL.LINE
                   * if the deletion is some how unsuccessful, we
                   * need to set the order to view only
                   IF NOT(DEL.OK) THEN VIEW.ONLY% = YES
                   AUTO.DEL = NO
                END ELSE
                   VIEW.ONLY% = YES
                END
             END
          END

          *** Check to see if there are parent/tag alongs on the order
          *** and force them all onto the same generation.
          IF NEW.ORDER% THEN
             SHIP.TAG.ALONGS.TOGETHER MAT OE.VARS
          END
          GOSUB DISP.ALL.LINES

          QUIT    = NO
          MOVE    = SV.MOVE
          LASTKEY = SV.LASTKEY

          GOSUB DISP.ALL.LINES

          RETURN TO MOVENEXT
*-------------------------------------------------------------------------*
GET.ORIG.UOM.DISP:*** This gets the UOM and quantity information for the
                  *** current line item.
                  ***
                  *** Note: If there was no original line item or if
                  ***       there was no original UM, then everything
                  ***       will be set to "".

          IF ORIG.LDID = '' OR LD(23) = '' THEN
             ORIG.UOM.DISP = ''
          END ELSE
             IQ.TO.ALPHA PLNE(3),PRD(7),LD(23),(LD(4) * QSIGN%),ORIG.QTY.1,ORIG.UOM.1,ORIG.QTY.2,ORIG.UOM.2
             ORIG.UOM.DISP = ORIG.QTY.1:ORIG.UOM.1:' ':ORIG.QTY.2:ORIG.UOM.2
          END

          RETURN
*-------------------------------------------------------------------------*
CONVERT.UOM.TO.NEW.PRODUCT:*** When the user changes the product, the UOMs
          *** and quantities should be translated to the new product.
          *** For example, if the open quantity is '1cs 5bx' for the old
          *** product, then it should be '1cs 5bx' for the new product
          *** (regardless of any differences in UOM per).  If the new
          *** product doesn't have one or more of the displayed UOMs, then
          *** the user should be prompted.
          ***
          *** For a good explanation of the intended behavior,
          *** see CTQ398.
          ***
          *** Note: This assumes that the user manually entered this new
          ***       product.  If the UOMs don't match up, this will open
          ***       a window.

          * Parse the UOM and quantity information for the new product.
          * Note: This might open a window.
          OE.PARSE.QO MAT OE.VARS,ORIG.UOM.DISP,PN,PARSE.OK,ALLOC.ZONE,QO,,U1

          IF NOT(PARSE.OK) OR QO = '' OR QO = 0 THEN
             TEMP.MSG  = 'Could not recoginize the UOM(s). '
             TEMP.MSG := 'The quantity has been set to 1.'
             TEMP.MSG := AM:'Press <Enter> to Continue'
             ERR.MESS ,,TEMP.MSG,YES,'CONVERT.UOM'
             QO = 1
          END

          RETURN
*-------------------------------------------------------------------------*
 CHK.TAG.ALONG:  ***This routine is used to make sure the product they are
                 ***attempting to type over is not part of a tag along
                 ***product.  If it is, the user will be forced to delete
                 ***it before adding the separate product - forcing the
                 ***break to the tag along product by creating a new ldid.
           TAG.CONTINUE = YES
           IF LD(132) # '' OR LD(121) # '' THEN
              ERR.MESS 10,5,'The original product is part of a related product. You must delete':AM:'the product before replacing it with another one.'
              TAG.CONTINUE = NO
           END
           RETURN
*-------------------------------------------------------------------------*
UP.PASS:  *** This routine is used to make sure the quantity multiplier
          *** is set prior to calling OE.SELECT.PNS. This routine handles
          *** when a user changes a current line to do a family search.
          *** When a quantity is entered on a blank line and a family
          *** search is being done. Some fail safe to make sure
          *** that ADDL.INFO<1,3> has a valid integer to be used in
          *** OE.SELECT.FAMILY if the PROD.FAMILY.MULT control records set

          ADDL.PASS = ''
          BEGIN CASE
          CASE LD(4) # '' AND LD(1) # '' AND NUM(LD(4)) AND NUM(LD(1))
             * active line get the quantity from LD(4)
             * switch the sign of LD(4) since stored as neg for purchases
             ADDL.PASS<1,3> = LD(4) * QSIGN%
          CASE LI.NEW.QTY%
             * new line with no active LD
             TEMP.VALUE = LI.NEW.QTY%
             PARSE.QTY TEMP.VALUE, TEMP.N1
             ADDL.PASS<1,3> = TEMP.N1
          CASE OTHERWISE
             * line may be  a comment, or other unknown case
             ADDL.PASS<1,3> = 1
          END CASE

          * Keep these to make sure that ADDL.PASS<1,3> is numeric.
          * This is here as a fail safe that may slip through case stmt.
          * We want ADDL.PASS<1,3> to be a number.
          ATMP = ADDL.PASS<1,3>
          IF NOT(NUM(ATMP)) THEN
             * if it is not a number then make it 1
             ADDL.PASS<1,3> = 1
          END ELSE
             IF ATMP+0=0 THEN
                ADDL.PASS<1,3> = 1
             END
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.PDW: *** This checks to see if the PDW product has alrady been
          *** created.  If so, then the PDW product is added like any
          *** other product.  If not, the OE.NONSTOCK must be opened
          *** to allow the user to enter the product (or abort if they
          *** want).

          IF PN[1,3] = 'IDW' THEN
             PDW.ID = PN[4,LEN(PN)-3]
             PDW.GET.PRD.ID PDW.ID,TST.PN
             IF TST.PN # '' THEN
                *** Let the user know the product already exists...
IN.PDW:         INP.PROMPT ,'%52',,0
                PN = TST.PN
             END ELSE
                ORIG.PN = LD(1)
                IF ORIG.PN # '' THEN INIT.LDID = LDID%
                OE.NONSTOCK OID%,GEN%,INIT.LDID,PN,QSIGN%,VIEW.ONLY%,,LDID.LIST%,LINE%
                PN = LD(1)

                IF PN # ''  THEN
                   GEN.MV = GEN%
                   OE.UPDATE.LDID INIT.LDID,OID%,GEN%,LOG.MV%,QSIGN%
                END

                IF ORIG.PN = '' THEN
                   MAT LD = ''
                END
             END
          END

          RETURN
*-------------------------------------------------------------------------*
UPD.INP:  *** This is the section that does all the updating based on
          *** view element, line item, and user input.
          ACTION.REQD = YES
IN$$2:    INP.ABT     = NO
          SV.HELP     = HELP
          RESPS       = ''
          SV.QUIT     = QUIT
          SV.MOVE     = MOVE
          SV.LASTKEY  = LASTKEY
          LOOP

             ACTION.REQD = NO
             REENTRY = NO

             OE.LI.VE.UPD MAT OE.VARS,VIEW.REC%,SUBR.INFO%,DATA.COL,VALUE,SV.HELP,CHNG,LI.MSGS,RESPS,REENTRY
             IF REENTRY = YES THEN ACTION.REQD = YES

             IF REENTRY OR LI.MSGS THEN
                OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,,LI.MSGS,INP.ABT,RESPS,CUSTOM.XREF%
                IF LI.MSGS THEN ACTION.REQD = YES
             END
             IF ACTION.REQD = NO OR INP.ABT THEN EXIT
          REPEAT

          IF NOT(INP.ABT) THEN
             GEN.MV = LOG.MV%
             LOCATE GEN% IN GEN.MV<1> SETTING DUMMY ELSE
                GEN.MV<1,-1> = GEN%
             END
             UPDATE.LEDGER OID%,GEN.MV
          END

          QUIT    = SV.QUIT
          MOVE    = SV.MOVE
          LASTKEY = SV.LASTKEY

          RETURN
*-------------------------------------------------------------------------*
GET.LINE: *** This loads the data for the current line item & displays
          *** any messages / actions that occure becuase a new line is
          *** loaded.

          *** Include any initialization messages before the line item
          *** messages are displayed.
          LI.MSGS  = OE.ACTS%
          OE.ACTS% = ''

          * Does not clear LI.NEW.QTY% if a product is not returned in
          * upd.pn. This will position the cursor back to the product
          * column upon return.
          LINE.NUM     = LINE.XREF%<1,LINE%>
          LDID%        = LDID.LIST%<1,LINE.NUM>
          *With this control record on, we may have to clear a previous msg
          IF LDID% AND LN.MOVED AND DISP.PROD.NOTES THEN
             WINDOW.CHILD.CLOSE
          END

          CHECK.KEY 'ENTITY.PN.EDIT',EN.OK
          GOSUB GET.LINE.DATA
          OE.LI.GET.ADDL MAT OE.VARS,MAT OE.SFLAGS,CALL.TYPE,LI.MSGS
          GOSUB SAVE.PROD.MSGS
          IF LI.MSGS AND DISP.MESS THEN
             OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,ADD.LINES,LI.MSGS,,,CUSTOM.XREF%
             DISP.MESS = NO
          END

          RETURN
*-------------------------------------------------------------------------*
GET.LINE.DATA:*** This fills in the LINE.DATA% variable by calling
              *** OE.LI.GET
          ADDL.INFO    = LINE.NUM
          ADDL.INFO<2> = PRC.KEY%
          ADDL.INFO<3> = RECV.GEN.ONLY%
          ADDL.INFO<4> = QTY.KEY%
          OE.LI.GET MAT OE.VARS,SUBR.INFO%,ADDL.INFO,LINE.DATA%

          ** Check to make sure that there is pricing data for this part
          ** in the current gen.
          IF LDID% # '' AND LD(8)<1,GEN%> = '' THEN
             PGN.CT = DCOUNT(LED(12),VM)
             FOR PGN = 1 TO PGN.CT
                IF LED(8)<1,PGN> = '' AND LD(8)<1,PGN> # '' THEN EXIT
             NEXT PGN
             OE.COPY.PRICING GEN%,PGN
          END

          QTY.CHNG.OK% = ADDL.INFO<4>
          * Lock line item to view only if:
          * 1. This line item is on a Shipment
          * 2. If LD(117) has been filled in, then we have information
          *    pertaining to a "Modified Product" that needs to be
          *    evaluated. It may be the case the line item should be locked
          *    based on the step it is currently on.

          * In Modified Products, LD(115) stores the display string
          * AND the id in each VM, with the Display String in SVM 1
          * and the ID in SVM 2.  This is different from Cut Product
          * which stores only the Display strings at VM level
          IF LINE.LOCK.VO = '@@@' AND LD(117)<1,GEN%> # '' THEN
             * Find the current step in a list of all steps
             FIND LD(117)<1,GEN%,2> IN LD(115) SETTING X,POS,Y THEN
                * LD(117)<1,GEN,2> will exist only on Modifed Product,
                * not in Cut Product
                * Check to see what step (line) the line item should be
                * locked on
                LOCK.LINE = LD(116)<1,2>
                IF NOT(NUM(LOCK.LINE)) THEN LOCK.LINE = 0

                * If we are on or passed the line to lock the item on,
                * then proceed to lock the line item by setting VIEW.ONLY%
                * and saving its current state
                IF (POS >= LOCK.LINE) AND (LOCK.LINE > 1) THEN
                   LINE.LOCK.VO = VIEW.ONLY%
                   VIEW.ONLY%   = YES
                END ELSE
                   * Only restore VIEW.ONLY% if LINE.LOCK.VO has been
                   * set. If so, reset LINE.LOCK.VO to @@@
                   IF (LINE.LOCK.VO # "@@@") THEN
                      VIEW.ONLY%   = LINE.LOCK.VO
                      LINE.LOCK.VO = "@@@"
                   END
                END
             END ELSE
                * Only restore VIEW.ONLY% if LINE.LOCK.VO has been
                * set. If so, reset LINE.LOCK.VO to @@@
                IF (LINE.LOCK.VO # "@@@") THEN
                   VIEW.ONLY%   = LINE.LOCK.VO
                   LINE.LOCK.VO = "@@@"
                END
             END
          END ELSE
             * Only restore VIEW.ONLY% if LINE.LOCK.VO has been
             * set. If so, reset LINE.LOCK.VO to @@@
             IF (LINE.LOCK.VO # "@@@") THEN
                VIEW.ONLY%   = LINE.LOCK.VO
                LINE.LOCK.VO = "@@@"
             END
          END
          RETURN
*-------------------------------------------------------------------------*
SAVE.PROD.MSGS:*** Save a product msg so that we can control when it is
               *** erased from the screen
          IF LD(1) THEN
             * We are on a line with a product so save any product reminder
             PRD.REM.MSGS = ''
             MSG.CT = DCOUNT(LI.MSGS,AM)
             FOR QQ = 1 TO MSG.CT
                THIS.MSG = LI.MSGS<QQ>
                IF THIS.MSG<1,2> = 'PROD.REMINDER' THEN
                   PRD.REM.MSGS<-1> = THIS.MSG
                   SKIP.PRD.MSGS = YES
                END
             NEXT QQ
          END
          RETURN
*-------------------------------------------------------------------------*
GET.PROD.MSGS:*** make sure product reminders are not erased at wrong time
          IF SKIP.PRD.MSGS THEN
             SKIP.PRD.MSGS = NO
             RETURN
          END
          IF PRD.REM.MSGS AND DISP.PROD.NOTES THEN
             LI.MSGS<-1> = PRD.REM.MSGS
          END
          RETURN
*-------------------------------------------------------------------------*
GET.ADDL: *** This gets all the additional actions for newly added line
          *** items and prompts the user when necissary.

          ADD.LINES = ''
          LDID.CT = DCOUNT(ADDED.LDIDS%,AM)
          FOR LDIDX = 1 TO LDID.CT
             NEW.LINES = ''
             LDID% = ADDED.LDIDS%<LDIDX>
             LOCATE LDID% IN LDID.LIST%<1> SETTING LINE.NUM ELSE CONTINUE

             CHECK.KEY 'ENTITY.PN.EDIT',EN.OK

             LI.MSGS      = ''
             ADDL.INFO    = LINE.NUM
             ADDL.INFO<2> = PRC.KEY%
             ADDL.INFO<3> = RECV.GEN.ONLY%
             ADDL.INFO<4> = QTY.KEY%
             OE.LI.GET MAT OE.VARS,SUBR.INFO%,ADDL.INFO,LINE.DATA%
             QTY.CHNG.OK% = ADDL.INFO<4>
             CALL.TYPE = 3
             OE.LI.GET.ADDL MAT OE.VARS,MAT OE.SFLAGS,CALL.TYPE,LI.MSGS
             IF LI.MSGS THEN
                OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,NEW.LINES,LI.MSGS,,,CUSTOM.XREF%
             END
             IF NEW.LINES # '' THEN
                IF ADD.LINES # '' THEN ADD.LINES := AM
                ADD.LINES := NEW.LINES
             END
          NEXT LDIDX
          IF ADD.LINES # '' THEN
             SV.MOVE    = MOVE
             SV.LASTKEY = LASTKEY
             RETURN TO ADD.LINES
          END

          RETURN
*-------------------------------------------------------------------------*
SHOW.LI.MSGS:*** This displays any queued actions in either LI.MSGS or
             *** OE.ACTS%.

          *** Include any initialization messages before the line item
          *** messages are displayed.
          IF OE.ACTS% # '' THEN
             LI.MSGS<-1> = OE.ACTS%
             OE.ACTS% = ''
          END

          GOSUB GET.PROD.MSGS
          IF LI.MSGS THEN
             OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,,LI.MSGS,,,CUSTOM.XREF%
          END

          NEW.PN.DISP = NO

          RETURN
*-------------------------------------------------------------------------*
HIGHLIGHT.HOTKEYS:*** This will highlight or un-highlight the appropriate
                  *** hotkeys based on the current line item.

          *** Either highlight or un-highlight the subs hotkey
          IF SUB.ACTIVE% THEN
             PRINT @(39,19):BLINK$:"Su":
             PRINT @(42,19):"s":NORM$
          END ELSE
             PRINT @(39,19):NORM$:"Su":
             PRINT @(42,19):"s":
          END

          *** Print the schduling hotkey as either on or off
          IF SCHED.TOGGLE THEN TMP = 'n' ELSE TMP = 'ff'
          IF REMOTE.CUST THEN
             PRINT @(64,19):TMP      "L#2"
          END ELSE
             PRINT @(59,19):TMP      "L#2"
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.COL:*** This makes sure that the cursor is in the right column when
          *** dealing with new line items.

          IF NOT(NEW.ITEM%) THEN RETURN

          BEGIN CASE
          CASE NOT(NEW.ITEM%);    NULL     ;* No restrictions
          CASE LI.NEW.QTY% = '';  COL% = 1 ;* Quantity before Product
          CASE COL% > 2;          COL% = 2
          END CASE

          RETURN
*-------------------------------------------------------------------------*
EXIT.LNS: *** User gets here when trying to leave the body of the order.
          * Only restore VIEW.ONLY% if LINE.LOCK.VO has been set. If so,
          * reset LINE.LOCK.VO to @@@
          IF (LINE.LOCK.VO # "@@@") THEN
             VIEW.ONLY%   = LINE.LOCK.VO
             LINE.LOCK.VO = "@@@"
          END

          IF VIEW.ONLY% THEN
             OE.STATUS MAT OE.VARS,MAT OE.SFLAGS,MAT PAF.DATA,ORIG.SHP.DTS%
             IF MOVE = 2 THEN GOTO GO.BACK

             * Before anything we should make sure that the USERID is equal
             * to the person editing the order or the order isn't being edited
             * if the order is VIEW.ONLY
             CHECK.RECORD.LOCK LEDFILE,OID%,IS.LOCKED,USER.LOCKED
             IF (USER.LOCKED # USER.ID) AND (USER.LOCKED # '') THEN GOTO RESTART

             GOTO PRT.DOCS
          END
          IS.NEW = NEW.ORDER%
          * Ensure order is new prior to allowing deletion.
          IF IS.NEW THEN
             OE.IS.NEW.ORDER OID%,IS.NEW
          END
          IF (F12 OR (LED(49)='' AND LED(8)='')) AND IS.NEW THEN
             OE.DEL.ORDER OID%,QSIGN%
             IF QUIT THEN
                GOTO IN.TABLE
             END ELSE
                GOTO RESTART
             END
          END
          IF F12 THEN
             IF NOT(NEW.ORDER%) AND ORD.CHG THEN
                *** Changes have been made, the user cannot abort!
                ACTION.ADD.MSG OE.ACTS%,,,'%104',,2,,10,2
                GOTO IN.TABLE
             END ELSE
                GOTO RESTART
             END
          END
          OE.DEL.NULL.LINES OID%,GEN%,LDID.LIST%,REDISP%
          IF REDISP% THEN
             LINE.XREF% = ''
             GOSUB DISP.ALL.LINES
          END
          *** Check for zero price lines on order if control record is set
          OE.ZERO.PRC.CHK LDID.LIST%,CONT.OK
          IF NOT(CONT.OK) THEN
             QUIT = 0; MOVE = 0; LASTKEY = 0
             GOTO MOVENEXT
          END
          IF NEW.ORDER% AND MODE% = 'S' THEN
             FOR TX = 1 TO DCOUNT(LED(10),VM)
                *** If MIRROR.REQ.DT CMP record is set for this branch
                CTRB.ID = 'MIRROR.REQ.DT~':LED(2)<1,TX,2>
                READV MIRROR FROM CTRBFILE,CTRB.ID,1 ELSE MIRROR = ''
                IF MIRROR THEN
                   ** If there are lead time days spec'd for ST, add them
                   IF CUSS(75) THEN
                      LED(10)<1,TX> = LED(9)<1,TX> + CUSS(75)
                   END ELSE
                      LED(10)<1,TX> = LED(9)<1,TX>
                   END
                END
             NEXT TX
          END

          *** If user chose to update pass along freight, recalc the new
          *** pass along freight value
          IF UPDATE.PAF.FLAG% THEN
             GOSUB UPDATE.PAF
          END
          GOSUB CHECK.PAF          ;* always reset values for next change

          UPDATE.LEDGER OID%
          OLD.GID = LED(12)<1,GEN%>
          OQN = LED(95)<1,GEN%>
          OE.DEL.NULL.GENS OID%,GEN%
          CREDIT.CHECKED = NO
          IF NOT(VIEW.ONLY%) AND LED(12)<1,GEN%>#OLD.GID THEN
             IF LED(8)<1,GEN%> THEN
                OE.RECALLIT.STATE MAT OE.VARS,MAT OE.STATE,,ABORT
                GOSUB CHECK.CREDIT
                CREDIT.CHECKED = YES
             END
          END
          IF CREDIT.CHECKED = NO AND NOT(VIEW.ONLY%) THEN
             IF MODE% = 'S' THEN
                OE.OK = NO
                SOE.CHECK.NO.OE BT.CN%,ST.CN%,OE.OK,NO.OE
                IF NOT(OE.OK) THEN
                   GOTO IN.TABLE
                END
             END
          END

          IF OLD.GID # LED(12)<1,GEN%> AND OQN THEN
             UT.OPEN.FILE "JOB.QUOTE",LOTFILE,ERR.MSG
             READU OJOB FROM LOTFILE,OQN ELSE OJOB = ""
             NJID = OID%:'.':LED(12)<1,GEN%> "R%4"
             OJID = OID%:'.':OLD.GID  "R%4"
             LOCATE OJID IN OJOB<10> SETTING XPOS THEN
                OJOB<10> = DELETE(OJOB<10>,1,XPOS)
                LOCATE NJID IN OJOB<10> SETTING NADA ELSE
                   OJOB<10,-1> = NJID
                END
             END
             IF MODE = 'S' THEN
                JCUS = LED(1)<1,GEN%>
                LOCATE JCUS IN OJOB<13> SETTING JPOS THEN
                   LOCATE OJID IN OJOB<14,JPOS> SETTING XPOS THEN
                      OJOB<14> = DELETE(OJOB<14>,1,JPOS,XPOS)
                      LOCATE NJID IN OJOB<14,JPOS> SETTING NADA ELSE
                         OJOB<14,JPOS,-1> = NJID
                      END
                   END
                END
             END ELSE
                IF MODE = 'P' THEN
                   JVEN = LED(1)<1,GEN%>
                   LOCATE JVEN IN OJOB<18> SETTING JPOS THEN
                      LOCATE OJID IN OJOB<19,JPOS> SETTING XPOS THEN
                         OJOB<19> = DELETE(OJOB<19>,1,JPOS,XPOS)
                         LOCATE NJID IN OJOB<19,JPOS> SETTING NADA ELSE
                            OJOB<19,JPOS,-1> = NJID
                         END
                      END
                   END
                END
             END
             WRITE OJOB ON LOTFILE,OQN
          END

          IF MODE% = 'S' AND NEW.ORDER% AND VERF.SHIP.ADDR$ THEN
             SOE.HEADER OID%,GEN%,LOG.MV%,NEW.ORDER%,REDISP%,'Esc - Status',,1,POST.ENTRY%
             BT.CN% = LED(1)<1,GEN%>
             ST.CN% = LED(5)<1,GEN%>
             IF REDISP% THEN
                GOSUB PARTIAL.INIT.XREF
                GOSUB DISP.ORDER
             END
          END ELSE
             GOSUB CHK.PO
             GOSUB CHK.GEO
             GOSUB CHK.FTERM
             GOSUB CHK.REQC
          END

          *** If this is a new Sales Order (not a Bid and not a Direct)
          *** see if there are GENs that can be combined
          IF (MODE% = 'S') AND (NEW.ORDER%) THEN
             SOE.COMBINE.ALL OID%,LOG.MV%
          END
          IF MODE% = 'S' THEN
             * Change freight allowed flag to 'Y' if order over min amt
             SOE.FRT.MIN.ORD ST.CN%,OID%,GEN%,'UPD'
             OE.TRIGGERS 4,OID%,GEN%,NEW.ORDER%,,VIEW.ONLY%
          END
IN.STAT:  OE.STATUS MAT OE.VARS,MAT OE.SFLAGS,MAT PAF.DATA,ORIG.SHP.DTS%
          IF OID% = '' THEN GOTO RESTART

          * Make sure we can navigate back to the right position
          * in the table based on any line item changes above.
          GOSUB RESET.LXREFS

          GOSUB LOG.CHANGE

          *** If status of GEN is now an Invoice, need to see if we need
          *** to look for PAF and note changes
          IF SHOULD.PROMPT.PAF% = NO THEN GOSUB CHECK.PAF
          IF MOVE = 2                THEN GOTO GO.BACK

          GOSUB CHK.PO
          GOSUB CHK.GEO
          GOSUB CHK.FTERM
          IF NOT(NEW.ORDER%) AND ORD.CHG THEN
             OE.ADD.COMMENT OID%,LOWER(ORD.CHG)
          END
          IF REMOTE.CUST THEN
             OE.REMOTE.LOG OID%,GEN%,LOG.MV%,NEW.ORDER%,LED(5)<1,GEN%>
          END
          UET.ENABLED.BR% = NO
          IF UET.ENABLED$ THEN
             CTRB.ID = 'UET.ENABLED~':LED(2)<1,GEN%,2>
             READV UET.ENABLED.BR% FROM CTRBFILE,CTRB.ID,1 ELSE UET.ENABLED.BR%=NO
          END
          IF UET.ENABLED.BR% THEN
             UET.CHECK.NEW.ORDER OID%,GEN%
          END
PRT.DOCS: *
          *** Activity Trigger for New Orders, no need for msgs/resps as
          *** this not java.
          IF NEW.ORDER% OR ACTIVATE.TRIGGERS THEN
             SV.GEN = GEN%
             GEN.CT = DCOUNT(LED(9),VM)
             FOR GEN = 1 TO GEN.CT
                GEN% = GEN
                OE.ACTIVITY.TRIGGER MAT OE.VARS
             NEXT GEN
             GEN% = SV.GEN
          END

          BEGIN CASE
          CASE MODE% = 'S'
             SOE.PRINT.DOCS OID%,VIEW.ONLY%
             CTRB.ID = 'RF.EXCL.TICKET~':STK.BR%
             READV EXCL FROM CTRBFILE,CTRB.ID,1 ELSE EXCL = ''
             IF EXCL[1,1] = 'P' THEN          ; * Prompt on exiting OE
                IF NOT(VIEW.ONLY%) THEN
                   RF.EXCL.PRINT.DOCS OID%
                END
             END ELSE
                IF NEW.ORDER% THEN
                   IF EXCL[1,1] = 'F' THEN    ; * First OE/Bid Change
                      RF.EXCL.PRINT.DOCS OID%
                   END
                END
             END
          CASE MODE% = 'P';           POE.PRINT.DOCS OID%
          CASE MODE% = 'T'
             TOE.PRINT.DOCS OID%
             CTRB.ID = 'RF.EXCL.TICKET~':STK.BR%
             READV EXCL FROM CTRBFILE,CTRB.ID,1 ELSE EXCL = ''
             IF EXCL[1,1] = 'P' THEN          ; * Prompt on exiting OE
                RF.EXCL.PRINT.DOCS OID%
             END ELSE
                IF NEW.ORDER% THEN
                   IF EXCL[1,1] = 'F' THEN    ; * First OE/Bid Change
                      RF.EXCL.PRINT.DOCS OID%
                   END
                END
             END
          END CASE
          GOTO RESTART
*-------------------------------------------------------------------------*
RESET.LXREFS: *** This was originally suppoed to set the line anchor
          *** point after drilling into another OE screen such as Totals,
          *** Status, etc. This logic was REMOVED in v878 because it
          *** simply didn't work. It was investigated on a Mission
          *** Critical release (8.6.8) and we decided not to take the
          *** time to try to make this work in Mission Critical. This has
          *** been here since the start of Release 8 and never worked
          *** properly. Since nobody reported the problem after 8 years,
          *** we decided we could live without it for now. To see the code
          *** that had been here, go to v877. It was found that we were
          *** looking up LDIDs in Line Item XREF tables. Some of the time,
          *** those might coincidentally be the same, which is why this
          *** appeared to work some of the time. But at the end of the
          *** day, this was a problem. -- KEVINM 07/06/2010
          LINE.XREF%    = ""
          LINE.XREF%<4> = 1
          LINE.XREF%<5> = 1
          RETURN
*-------------------------------------------------------------------------*
RESTART:  *** Going to re-enter OE so the user can choose another order.
          IF DISP.PROD.NOTES THEN
             WINDOW.CHILD.CLOSE
          END
          IF LOCKED.LED% AND OID% # '' THEN
             OE.UNLOCK.LED OID%
          END
          CT     = DCOUNT(EXTRA.LOCKS%,VM)
          FOR JX = 1 TO CT
             EL.OID = EXTRA.LOCKS%<1,JX>
             IF EL.OID # '' THEN
                OE.UNLOCK.LED EL.OID
             END
          NEXT JX
          VIEW.ONLY% = NO
          *** CRD.RBL will get set when user does a credit/rebill. At this
          *** point, user should be able to edit the rebilled gen if
          *** program is called from another or menu level is greater than
          *** one.

          IF NOT(EDIT.OE%) AND NOT(CRD.RBL%) THEN
             IF AUTO.EXIT% OR TTY.RELOG% OR TCL.LEVEL > 0 THEN GOTO FINISH
          END
          CRD.RBL% = NO
          IF DONT.FORGET% OR E.MESS.<WINDOW.LEVEL> THEN
             WINDOW.CHILD.CLOSE
             E.MESS.<WINDOW.LEVEL> = ''
          END
          GOTO START
*-------------------------------------------------------------------------*
CHK.REQC: *** Check to see if the sales order requires a catalog.

          IF MODE='S' AND LED(6)<1,GEN%>#'B' AND LED(6)<1,GEN%>#'X' THEN
             CTRB.ID = "SOE.REQR.CATALOG~":LED(2)<1,GEN%,2>
             READV CAT.REQD FROM CTRBFILE,CTRB.ID,1 ELSE CAT.REQD = ''
             IF CAT.REQD AND LED(111) = '' THEN
                OE.HEADER OID%,GEN%,LOG.MV%,NEW.ORDER%,REDISP%,'Esc - Status',,POST.ENTRY%
                BT.CN% = LED(1)<1,GEN%>
                ST.CN% = LED(5)<1,GEN%>
                IF MOVE=2 THEN RETURN TO GO.BACK
             END
          END
          RETURN
*-------------------------------------------------------------------------*
CHK.PO:   *** See if REL# or PO# or Ordered By are req'd fields that need            *** to be filled in the header screen.
          IF MODE%='S' AND LED(6)<1,GEN%>#'B' AND LED(6)<1,GEN%>#'X' THEN
             NPRB       = CUSS(45)<1,1>
             NPRB.OK    = (NPRB#'' AND NPRB#'R' AND NPRB#0 AND NPRB#'N')
             PO.CHK     = (NPRB.OK AND LED(13)<1,GEN%>='')
             REL.CHK    = (NPRB='R' OR NPRB='B' AND LED(65)<1,GEN%>='')
             AUTH.CHK   = (CUSS(27) AND LED(68)<1,GEN%>='')
             IF PO.CHK OR REL.CHK OR AUTH.CHK THEN
                OE.HEADER OID%,GEN%,LOG.MV%,NEW.ORDER%,REDISP%,'Esc - Status',,POST.ENTRY%
                BT.CN% = LED(1)<1,GEN%>
                ST.CN% = LED(5)<1,GEN%>
                IF MOVE = 2 THEN RETURN TO GO.BACK
             END
          END
          IF MODE%= 'P' AND LED(6)<1,GEN%>#'B' AND LED(6)<1,GEN%>#'X' THEN
             NWIB       = CUSS(45)<1,1>
             WITH.CHK   = ((NWIB='W' OR NWIB='B') AND LED(68)<1,GEN%>='')
             ID.CHK     = ((NWIB='I' OR NWIB='B') AND LED(13)<1,GEN%> = '')
             IF WITH.CHK OR ID.CHK OR REQ.PO.HDR% THEN
                OE.HEADER OID%,GEN%,LOG.MV%,NEW.ORDER%,REDISP%,'Esc - Status',,POST.ENTRY%
                REQ.PO.HDR% = NO
                BT.CN% = LED(1)<1,GEN%>
                ST.CN% = LED(5)<1,GEN%>
                IF MOVE = 2 THEN RETURN TO GO.BACK
             END
          END
          RETURN
*-------------------------------------------------------------------------*
CHK.GEO:  *** See if the geocode is a req'd field that needs to be filled.

          USE.STAX = (USE.STAX$ AND USE.STAX$ <= LED(9)<1,GEN%>)
          IF NOT(USE.STAX) OR MODE% # "S" THEN RETURN

          IF LED(79)<1,GEN%,1> THEN
             ROOT = LED(79)<1,GEN%,1>:'~':DATE()
             BSCAN GG FROM STAXFILE,ROOT USING '&INDEX&' BY 'D' THEN
                IF FIELD(GG,'~',1) = LED(79)<1,GEN%,1> THEN RETURN
             END
          END
          OE.HEADER OID%,GEN%,LOG.MV%,NEW.ORDER%,REDISP%,'Esc - Status',,POST.ENTRY%
          BT.CN% = LED(1)<1,GEN%>
          ST.CN% = LED(5)<1,GEN%>
          IF MOVE=2 THEN RETURN TO GO.BACK
          RETURN
*-------------------------------------------------------------------------*
CHK.FTERM:*** Make sure if the site's using freight terms, one's filled in
          IF MODE% = 'P' AND LED(69)<1,GEN%,1> = "" AND FRT.TERMS% # "" THEN
             OE.HEADER OID%,GEN%,LOG.MV%,NEW.ORDER%,REDISP%,'Esc - Status',,POST.ENTRY%
             BT.CN% = LED(1)<1,GEN%>
             ST.CN% = LED(5)<1,GEN%>
             IF MOVE=2 THEN RETURN TO GO.BACK
          END

          RETURN
*-------------------------------------------------------------------------*
GO.BACK:  *** Go back to the order the user just tried to leave.
          IF GEN%=0 OR LED(6)<1,GEN%,1>='X' OR LED(1)<1,GEN%>='' THEN
             OE.NEXT.SHIPDATE GEN%
             IF GEN%=0 THEN GOTO RESTART
          END
          OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%
          OE.GET.KEYS OID%,GEN%,NEW.ORDER%,VIEW.ONLY%,PRC.KEY%,QTY.KEY%
          IF PRC.KEY% AND LED(110)<1,1>='S' THEN PRC.KEY%=NO

          * Redisplay entire screen as generation information may have
          * changed when coming back to order via status or header screens
          * by resetting LINE.XREF%, OE.LI.PRINT will regenerate the list
          * Cursor will be placed at the first line, first column.
          GOSUB PARTIAL.INIT.XREF
          COL% = 1
          OE.SET.COMMON.DATA MAT OE.VARS
          GOSUB DISP.ORDER
          NEED.REDISP = NO

          GOTO IN.TABLE
*-------------------------------------------------------------------------*
SET.PRC.EXPIRE:*** Set the price date one day earlier for all open gens.
          OE.SET.PRICE.EXPIRE OID%
          RETURN
*-------------------------------------------------------------------------*
QUICK.PRICE:*** This will allow the user to quickly price the current line
            *** item by pulling the price from a past sale of the same
            *** product.

          *** Warn user that they are not able to access the quick price
          *** screen for any Change Order line item that is tagged to
          *** an MJB line item.
          IF LED(129)<1,2> AND LD(108) THEN
             ACTION.ADD.MSG OE.ACTS%,,,'%278'
             RETURN TO IN.TABLE
          END

          MSGS = ''
          ACTION.ADD MSGS,'QUICK.PRICE'
          OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,,MSGS,,,CUSTOM.XREF%
          GOSUB DISP.ALL.LINES

          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
DUTY.INFO:*** Collect customs information for the item
          MSGS  = ''
          RESPS = ''
          ACTION.ADD MSGS,'DUTY.INFO',,,,,YES
          OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,,MSGS,,RESPS,CUSTOM.XREF%

          LOCATE 'REDISP.LI' IN RESPS<1> SETTING NOTHING THEN
             GOSUB DISP.ALL.LINES
          END

          QUIT    = NO ;* Checked at MOVENEXT:
          MOVE    = '' ;* Used in PARSEMOVE
          LASTKEY = 'X';* Used in PARSEMOVE
          RETURN TO MOVENEXT
*-------------------------------------------------------------------------*
VS.DISPLAY: *** Display the Virtual Supplier Information for this line
          *** item.

          OE.VS.INFO.DISPLAY MAT OE.VARS

          QUIT = NO ;* Checked at MOVENEXT:

          RETURN
*-------------------------------------------------------------------------*
VS.ROUTE.GEN: *** Route this item via the Virtual Supplier Product.

          OE.VS.ROUTE.GEN MAT OE.VARS

          GOSUB DISP.ORDER

          RETURN
*-------------------------------------------------------------------------*
PASTE:    *** Paste line items in from the Clipboard.

          ADD.LINES      = ''
          CLIP.MSGS      = ''
          CLIP.RESPS     = ''
          CLIP.REENTRY   = NO
          SV.MOVE        = MOVE
          SV.LASTKEY     = LASTKEY

          LOOP
             IF VIEW.ONLY% THEN
                ACTION.ADD.MESSAGE CLIP.MSGS,,,'%220',BELL,YES
             END ELSE
                OE.CLIPBOARD.PASTE MAT OE.VARS,PASSER.COM,ADD.LINES,CLIP.MSGS,CLIP.RESPS,CLIP.REENTRY
             END

             IF CLIP.MSGS THEN
                OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,,ADD.LINES,CLIP.MSGS,,CLIP.RESPS,CUSTOM.XREF%
             END

             WHILE CLIP.REENTRY
          REPEAT

          IF ADD.LINES THEN
             GOTO ADD.LINES
          END ELSE
             RETURN
          END
*-------------------------------------------------------------------------*
PRC.ITEM: *** Price the current item.
          OE.PRICE.ITEM OID%,GEN%,LDID%,PN%,QO%,QSIGN%,GROUP%,LOG.MV%,,LDID.LIST%,DLINE.XREF%,VIEW.ID%
          RETURN
*-------------------------------------------------------------------------*
SUBS:     *** Hotkey functions.
          ORIG.LDID    = LDID%
          BEGIN CASE
          CASE SUB.OPT =  1;  GOTO INS.LINE
          CASE SUB.OPT =  2;  GOTO DEL.LINE
          CASE SUB.OPT =  3;  GOTO COMMENT
          CASE SUB.OPT =  4;  GOTO PRICING
          CASE SUB.OPT =  5;  GOTO CHANGE.VIEW
          CASE SUB.OPT =  6;  GOTO CHNG.MODE
          CASE SUB.OPT =  7;  GOTO NONSTOCK
          CASE SUB.OPT =  8;  GOTO SUBTOL
          CASE SUB.OPT =  9;  GOTO SCHEDULE
          CASE SUB.OPT =  10; GOTO SCHED.TOGGLE
          CASE SUB.OPT =  11; GOTO HEADER
          CASE SUB.OPT =  12; GOTO TOTALS
          CASE SUB.OPT =  13; GOTO SUBSTITUTES
          CASE SUB.OPT =  14; GOTO PRDXREF
          CASE SUB.OPT =  15; GOTO CHNG.SHIPDATE
          CASE SUB.OPT =  16; GOTO CRED.REBILL
          CASE SUB.OPT =  17; GOTO VIEW.GL
          CASE SUB.OPT =  18; GOTO INQ
          CASE SUB.OPT =  19; GOTO LABELS
          CASE SUB.OPT =  20; GOTO EDMODE
          CASE SUB.OPT =  21; GOTO FINDPN
          CASE SUB.OPT =  22; GOTO IMPRT
          CASE SUB.OPT =  23; GOTO TRIGGERS
          CASE SUB.OPT =  24; GOTO CUS.INDEX
          CASE SUB.OPT =  25; GOTO XCURR
          CASE SUB.OPT =  26; GOTO XCURR
          CASE SUB.OPT =  27; GOTO QUICK.PRICE
          CASE SUB.OPT =  28; GOTO DUTY.INFO
          CASE SUB.OPT =  29; GOTO CUSTOM.OPT
          CASE SUB.OPT =  30; GOTO VS.DISPLAY
          CASE SUB.OPT =  31; GOTO VS.ROUTE.GEN
          CASE SUB.OPT = 100; GOTO PASTE
          CASE OTHERWISE;    PRINT BELL:;
                             RETURN
          END CASE
*-------------------------------------------------------------------------*
INS.LINE: *** Insert a line before the currrent line.

          NO.GO = NO
          BEGIN CASE
          CASE VIEW.ONLY%
             NO.GO = YES
          CASE LX > TOT.LD
             NO.GO = YES
          CASE LDID% = ""
             NO.GO = YES
          CASE OE.LOCKED.DIR$
             NO.GO = YES
          END CASE

          IF NO.GO THEN
             PRINT BELL:;
             RETURN
          END

          LDID.LIST% = INSERT(LDID.LIST%,1,LX;"")

          RETURN TO INBODY
*-------------------------------------------------------------------------*
DEL.LINE: *** Delete Current Line

          *** If set, we do not want to allow users to edit any fields
          *** where we would allow updating to the PO side of the direct
          IF OE.LOCKED.DIR$ THEN PRINT BELL:; RETURN

          *** If we are view only input on the line we should not allow
          *** deleting of that line.
          IF VO.INP THEN PRINT BELL:; RETURN

          IF LDID% = '' THEN
             *** If this is an empty line, then just remove it from the
             *** vscroll region and the xrefs.
             LINE.NUM     = LINE.XREF%<1,LINE%>
             LDID.LIST% = DELETE(LDID.LIST%,1,LINE.NUM)
             RETURN TO INBODY
          END


          *** If deleting item off of generation, see if user wants
          *** to recalc pass along freight if generation has pass along
          *** freight posted
          IF SHOULD.PROMPT.PAF% AND NOT(HAVE.PROMPTED.PAF%) THEN
             OE.PROMPT.PAF MAT OE.VARS, MAT PAF.DATA
          END

          DEL.ABT   = NO
          MSG.FLAG  = NO
          DEL.ACTS  = ''
          DEL.RESPS = ''
          * If we are removing a parent product from the order because
          * a tag along could not be added we will preload the RESPS
          * array to that the user will not be prompted when deleteing
          * the parent and remaining tags from the order
          IF REMOVING.PARENT THEN
             DEL.ACTS<1>      = ''
             DEL.RESPS<1,1>   = 'OE.SUBS.DEL.LINE~PARENT'
             DEL.RESPS<2,1,1> = YES
             ERR.MESS 10,5,'One or more tag along products could not be added to the order.':AM:'The Parent product and all tag alongs will be removed.'
IN$$3:       INPNO A,,,0
          END
          LOOP
             OE.SUBS.DEL.LINE MAT OE.VARS,DEL.OK,MSG.FLAG,DEL.ACTS,DEL.RESPS
             * If there is a Gift Card/Certificate error, delete the item
             * off sales order and do not prompt the user
             IF GIFT.CERT.ERR THEN
                GIFT.CERT.ERR = NO
                DEL.ACTS      = ''
                DEL.RESPS     = "OE.SUBS.DEL.LINE~PROMPT":AM:1
             END ELSE
                IF MSG.FLAG OR DEL.ACTS THEN
                   OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,,DEL.ACTS,DEL.ABT,DEL.RESPS,CUSTOM.XREF%
                END
             END

             WHILE MSG.FLAG AND NOT(DEL.ABT)
          REPEAT

          IF DEL.OK THEN
             OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%
             GOSUB DISP.ALL.LINES
             GOSUB CHECK.CREDIT
          END

          ***if this routine is called programtically (ie, not because of
          ***Alt-Delete) we want to return to the place where we
          ***called it.
          IF NOT(ASSIGNED(AUTO.DEL)) OR NOT(AUTO.DEL) THEN
             INITIAL.MOVE = YES
             RETURN TO INBODY
          END ELSE RETURN
*-------------------------------------------------------------------------*
COMMENT:  *** Add/Modify to the comments on the current L.I.
          IF LD(1)  = 'S' THEN
             *** Subtotals don't get to have comments
             PRINT BELL:;
             RETURN
          END

          IF LDID%  = '' THEN MAT LD = ''
          OE.COMMENTS OID%,GEN%,LDID%,VIEW.ONLY%
          IF F12 OR (LD(3) = '' AND LDID% = '') THEN
             *** The user aborted...
             RETURN TO IN.TABLE
          END
          IF LDID% = '' THEN
             PN%   = 'C'
             LD(1) = PN%
             OE.NEW.LDID OID%,LDID%,LDID.LIST%,LINE%
             OE.INSERT.LDID LDID.LIST%,LINE.XREF%,LINE%,LDID%
          END

          OE.LI.UPDATE MAT OE.VARS,LDID.LIST%
          GOSUB DISP.ALL.LINES

          QUIT = 0; MOVE = 4
          RETURN TO MOVENEXT
*-------------------------------------------------------------------------*
PRICING:  *** Call the pricing screen.
          *** Warn user that they are not able to access the labels
          *** screen for any Change Order line item that is tagged to
          *** a MJB line item.
          IF LED(129)<1,2> AND LD(108) THEN
             ACTION.ADD.MSG OE.ACTS%,,,'%278'
             RETURN TO IN.TABLE
          END

          SV.VIEW.ONLY = VIEW.ONLY%
          IF RECV.GEN.ONLY% THEN SV.VIEW.ONLY = YES

          * This check is needed for Hajoca sites only to retrict users
          * from changing costs if there are negative items on the order.
          * For core sites, this check is not needed.
          IF HAJOCA.SITE$ THEN
             OLD.VIEW.ONLY = VIEW.ONLY%
             GOSUB CHECK.COST.EDIT.OK
             IF FORCE.VIEW.ONLY THEN VIEW.ONLY% = YES
          END

          OE.PRICING.OVRD OID%,GEN%,QSIGN%,LOG.MV%,REDISP%,PRC.KEY%,SV.VIEW.ONLY,RESTART,LDID%

          IF HAJOCA.SITE$ THEN
             VIEW.ONLY% = OLD.VIEW.ONLY
          END

          IF RESTART THEN
             OE.RECALLIT.STATE MAT OE.VARS,MAT OE.STATE,,ABORT
             GOSUB CHECK.CREDIT
          END
          IF REDISP% THEN
             GOSUB PARTIAL.INIT.XREF
             GOSUB DISP.ORDER
          END
          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
CHANGE.VIEW:*** This prompts the user with a menu table of every available
            *** view for them to display the order in.

          OE.CHNG.VIEW MAT OE.VARS,VIEW.ID%,NEW.VIEW.ID

          *** If the user cancels, nothing to do
          IF NEW.VIEW.ID = '' THEN RETURN

          IF NEW.VIEW.ID # VIEW.ID% THEN
             VIEW.ID% = NEW.VIEW.ID
             GOSUB PARTIAL.INIT.XREF
             GOSUB DISP.ORDER
          END

          QUIT       = NO
          MOVE       = 'X'
          LASTKEY    = ''

          RETURN TO MOVENEXT
*-------------------------------------------------------------------------*
CHNG.MODE:*** Change the order type.
          SV.NO        = NEW.ORDER%
          SV.PO        = LED(13)<1,1>
          SV.CUS       = LED(1)<1,GEN%>
          SV.STAT      = LED(6)<1,GEN%>
          OID.DATA$<8> = NEW.ORDER%
          SV.BR        = LED(2)<1,GEN%,2>
          ADD.LINES    = ''
          SV.MOVE      = MOVE
          SV.LASTKEY   = LASTKEY

          *** If not allowed to modify QTY (from SOE.OPEN.QTY.EDIT or
          *** SOE.CLOSED.QTY.EDIT), force into view only mode to determine
          *** valid modes
          IF NOT(QTY.KEY%) THEN
             OE.CHNG.MODE OID%,GEN%,QSIGN%,LOG.MV%,COPY.OID,NEW.ORDER%,YES
          END ELSE
             IS.NEW.GEN = (OLD.GEN # '' AND OLD.GEN # GEN%)
             SV.VIEW.ONLY = VIEW.ONLY%
             IF RECV.GEN.ONLY% OR OE.LOCKED.DIR$ THEN SV.VIEW.ONLY = YES
             OE.CHNG.MODE OID%,GEN%,QSIGN%,LOG.MV%,COPY.OID,NEW.ORDER%,SV.VIEW.ONLY,ADD.LINES,IS.NEW.GEN
          END
          IF COPY.OID # "" AND COPY.OID # "@@@" THEN
             RETURN TO RESTART
          END
          IF COPY.OID # "@@@" THEN
             OE.RECALLIT.STATE MAT OE.VARS,MAT OE.STATE,,ABORT
             GOSUB CHECK.CREDIT
          END
          IF ABORT THEN
             RETURN TO RESTART
          END
          IF ADD.LINES AND COPY.OID = '' THEN
             GOTO ADD.LINES
          END
          IF COPY.OID # "@@@" THEN
             GOSUB DISP.ORDER
          END

          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
NONSTOCK: *** Restrict access to the Nonstock screen and the Lot Item
          *** Status screen for remote customers.

          IF REMOTE.CUST OR RECV.GEN.ONLY%    THEN RETURN

          *** Go to the lot item section.
          IF LD(1) # '' AND PRD(3) = 9 THEN
             GOSUB LOT.ITEM

             * Check credit
             LOCATE 'CHECK.CREDIT' IN RESPS<1> SETTING NOTHING ELSE
                RESPS<1,-1> = 'CHECK.CREDIT'
             END
             * NOTE: This is an integration of v740 for CRO348.
             * If version 738 for CRI649 is integrated, make sure this is
             * placed properly in the IF statement.
             GOSUB DISP.ALL.LINES

             RETURN TO IN.TABLE
          END

          *** Don't duplicate too much code.
          RET.ERR = NO
          *** If set, we do not want to allow users to edit any fields
          *** where we would allow updating to the PO side of the direct
          IF OE.LOCKED.DIR$ THEN RET.ERR = YES

          *** Custom work around for hidden hotkey for testing purposes.
          IF LD(1) # '' AND PRD(3) # 2 THEN RET.ERR = YES
          IF LD(1) # '' AND QTY.KEY%<2 AND NOT(NEW.ORDER%) THEN
             IF INIT.OID<1,1> = 'S' AND LED(6)<1,GEN%,1> # 'B' THEN
                RET.ERR = YES
             END
          END

          *** Get out if there was an error.
          IF RET.ERR THEN
             PRINT BELL:;
             RETURN
          END

          *** Warn user that they are not able to access the nonstock
          *** screen for any Change Order line item that is tagged
          *** to a master job bid.
          IF LED(129)<1,2> AND LD(108) THEN
             ACTION.ADD.MSG OE.ACTS%,,,'%278'
             RETURN TO IN.TABLE
          END

          *** "Enter Qty First".
          IF LD(1) = '' AND NOT(LI.NEW.QTY%) THEN
             ACTION.ADD.MSG OE.ACTS%,,,'%128',,2,,,10
             RETURN TO IN.TABLE
          END

          NEW.NONSTOCK = (LDID% = '')
          IF NEW.NONSTOCK THEN
             QO = LI.NEW.QTY%
          END ELSE
             * The Quantity Ordered needs to be the current quantity
             * open so that when a user views the nonstock screen
             * and possibly changes something like pricing we don't
             * update the quantity of the nonstock. When we pass through
             * the quantity ordered to OE.LI.COMMIT, if it is something
             * different than the current quantity open it will detect
             * a difference in quantity and increase the quantity for
             * this gen.
             OE.CALC.QOPEN OID%,QSIGN%,QO,GEN%
          END

          *** If this is an "EDI PRODUCT NOT FOUND" line item, then
          *** run OE.NONSTOCK in "new nonstock" mode
          IF LD(1) = EDI.DFLT.PN THEN LD(1) = ''

          OE.NONSTOCK OID%,GEN%,LDID%,LD(1),QSIGN%,VIEW.ONLY%,CHECK.GP,LDID.LIST%,LINE%
          *** If the user did not select an item, return out.
          IF LD(1) = '' THEN
             PRINT BELL:;
             RETURN
          END
          * In view only mode, we don't want to update anything
          * otherwise, the line item of an existing nonstock will
          * be unneccessarily updated
          IF VIEW.ONLY% THEN RETURN TO IN.TABLE

          IF NEW.NONSTOCK THEN
             OE.PARSE.QO MAT OE.VARS,QO,LD(1),PARSE.OK,ALLOC.ZONE,QO,Q1,U1,Q2,U2
          END ELSE
             U1          = LD(23)
          END
          ALLOC.ZONE  = LD(41)
          LINE.NUM    = LINE.XREF%<1,LINE%>
          IF NEW.NONSTOCK THEN
             IF LDID% THEN INS.LINE = NO ELSE INS.LINE = YES
          END ELSE
             INS.LINE = NO
          END
          ADD.LINES   = ''
          OE.ADD.LINES ADD.LINES,LD(1),QO,U1,ALLOC.ZONE,INS.LINE,LINE.NUM

          OE.LI.COMMIT.MULTI MAT OE.VARS,MAT OE.SFLAGS,MAT PAF.DATA,SUBS.XREF%,ADD.LINES,CUSTOM.XREF%,ADDED.LDIDS%,1,'','',NEW.NONSTOCK
          OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%
          LOCATE LDID% IN LDID.LIST%<1> SETTING XXX ELSE LDID% = ''
          GOSUB GET.ADDL

          IF NEW.NONSTOCK THEN
             OE.INSERT.LDID LDID.LIST%,LINE.XREF%,LINE%,LDID%
             IF PRD(3) = '9' AND LDID% # '' THEN
                ADDED.LDIDS% = LDID%
                GOSUB GET.ADDL
             END
          END
           !!! End Custom CSG812
          *** Custom Code Starts for CSI540
          OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%
          *** Custom Code Ends for CSI540
          PARENT.LDID = ''
          !IF MODE% = 'S' AND TAG.MODE # 'Review' THEN
          IF MODE% = 'S' THEN
             MATBUILD SV.LD FROM LD
             MATBUILD SV.OLD.LD FROM OLD.LD
             SV.LDID = LDID%
             REMOVING.PARENT = NO
             !!! Begin Custom CRR754
             * Save the parent LDID to reset the line on the order
             !!! End Custom CRR754
             LDCNT = DCOUNT(ADDED.LDIDS%,AM)
             FOR EACH.LDID = 1 TO LDCNT
                LDID% = ADDED.LDIDS%<EACH.LDID>
                LD.GET LDID%
                MAT OLD.LD = MAT LD
                !!! Begin Custom CRR754
                OE.CHECK.FOR.TAG.ALONGS MAT OE.VARS,MAT OE.STATE,PNS,QTY,REQ,REMOVE.PARENT
                PARENT.LDID = LD(132)
                * Make sure that the PARENT LD array is updated with the
                * posssibly new child LDID
                OE.UPD.PARENT.TAG.ALONG MAT OE.VARS,MAT OE.STATE
                !!! End Custom CRR754
                IF REMOVE.PARENT THEN
                   LDID% = REMOVE.PARENT
                   REMOVING.PARENT = YES
                   GOTO DEL.LINE
                END
             NEXT EACH.LDID

             OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%


             * If a parent LDID was set then we know that we are in the
             * process of adding a product with tag alongs. Make sure
             * to put the user back on the parent's line so that if
             * the review screen opens automatically we are on the
             * right LDID
             IF PARENT.LDID THEN
                LDID% = PARENT.LDID
             END ELSE
                LDID% = SV.LDID
             END

             NEW.LIIX      = LINE.XREF%<5>
             LOCATE LDID% IN LDID.LIST%<1> SETTING NEW.LIIX ELSE
                NEW.LIIX   = 1
             END
             LINE.XREF%<5> = NEW.LIIX

             * If a parent LDID was set then we know that we are in the
             * process of adding a product with tag alongs. Make sure
             * to put the user back on the parent's line so that if
             * the review screen opens automatically we are on the
             * right LDID
              IF PARENT.LDID THEN
                 LDID% = PARENT.LDID
                 LD.GET PARENT.LDID
                 MAT OLD.LD = MAT LD
              END ELSE
                 LDID% = SV.LDID
                 MATPARSE LD FROM SV.LD
                 MATPARSE OLD.LD FROM SV.OLD.LD
              END
          END
          GOSUB DISP.ALL.LINES

          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
LOT.ITEM: *** Enter the Lot Item Status Screen if the user is on an
          *** appropriate line item and gen.
          IF NOT(NUM(LD(1))) OR LD(1) = "" THEN RETURN

          * Clear the messages and responses array.
          MSGS  = ""
          RESPS = ""

          OE.CHECK.LOT.BILLING OID%,GEN%,,MSGS
          IF MSGS THEN RETURN

          OE.LOT.BILL.STATUS OID%,GEN%,LDID%,QSIGN%,VIEW.ONLY%
          OE.LI.UPDATE MAT OE.VARS

          RETURN
*-------------------------------------------------------------------------*
WIZARD:   *** Logic that will allow wizard routine for a particular
          *** product to be called manually.
          IF NOT(NUM(LD(1))) OR LD(1) = "" THEN RETURN

          CALL.OK = NO
          SUB.ID  = PRD(140)<1>

          * Verify a wizard is setup for this product
          IF SUB.ID # "" THEN

             * Open the OC (Object Code) file and VOC (Vocabulary) file
             UT.OPEN.FILE "OC",OCFILE,OCERR,YES
             UT.OPEN.FILE "VOC",VOCFILE,VOCERR,YES

             * Make sure both files opened without a problem
             IF NOT(OCERR) AND NOT(VOCERR) THEN

                * Read the first attribute from the VOC to ensure this
                * routine is a Verb (V). If so, we can assume it has been
                * catalogged and can be run.
                READV IS.CAT FROM VOCFILE,SUB.ID,1 ELSE IS.CAT = ""

                * Read the first line of the subroutine in order to count
                * the number of parameters. There needs to be three in
                * order for the routine to run.
                READV LINE.1 FROM OCFILE,SUB.ID,1 ELSE LINE.1 = ""

                * Take everything after the first parenthesis
                LINE.1 = FIELD(LINE.1,"(",2)

                * Trim off all the trailing parenthesis
                LINE.1 = TRIM(LINE.1,")","T")

                * Convert the commas to attribute marks
                CONVERT "," TO AM IN LINE.1

                * Count the number of parameters
                PARAM.CT = DCOUNT(LINE.1,AM)

                IF IS.CAT = "V" AND PARAM.CT = 3 THEN CALL.OK = YES
             END
          END

          * Setup additional data to be used in the wizard
          * NOTE: ADDL.DATA needs to be set to NULL inside the wizard
          * after pulling out the data.
          ADDL.DATA      = OID%
          ADDL.DATA<1,2> = GEN%
          ADDL.DATA<1,3> = LDID%
          ADDL.DATA<1,4> = QSIGN%
          ADDL.DATA<1,5> = VIEW.ONLY%

          * Get the product number
          PN = LD(1)

          * Call the routine
          CALL @SUB.ID(SUBR.RESULT,PN,ADDL.DATA)

          * If the result was favorable, redisplay the lines
          * If there are l.i. updates, redisplay the lines
          IF SUBR.RESULT OR ADDL.DATA THEN

             * The user may have changed something, so if there's data
             * coming back out, then we need to call the Commital routine.
             IF ADDL.DATA THEN
                OE.LI.COMMIT.MULTI MAT OE.VARS,MAT OE.SFLAGS,MAT PAF.DATA,SUBS.XREF%,ADDL.DATA,CUSTOM.XREF%
                ADDL.DATA = ''
             END

             GOSUB DISP.ALL.LINES
          END

          RETURN
*-------------------------------------------------------------------------*
SUBTOL:   *** This subroutine allows a user to add, edit, or view a
          *** subtotal.

          *** Warn user that they are not able to access the subtotals
          *** screen for any Change Order line item.
          IF LED(129)<1,2> THEN
             ACTION.ADD.MSG OE.ACTS%,,,'%277'
             RETURN TO IN.TABLE
          END

          IF (LD(1)#'S' AND LD(1)#'') THEN
             *** The user must be on an empty line before adding a subtol
             ACTION.ADD.MSG OE.ACTS%,,,'%134',,2,NO,,3
             RETURN TO IN.TABLE
          END
          IF LED(98)<1,GEN%> THEN
             *** Subtotals are not allowed on lot billing generations
             ACTION.ADD.MSG OE.ACTS%,,,'%135',,2,NO,,3
             RETURN TO IN.TABLE
          END
          IF RECV.GEN.ONLY% THEN RETURN

          IF NOT(VIEW.ONLY%) THEN
             IF LDID%#'' THEN
                NEW.SUB = NO
             END ELSE
                NEW.SUB = YES
                PN%     = 'S'
                LD(1)   = PN%
                OE.NEW.LDID OID%,LDID%,LDID.LIST%,LINE%
                OE.INSERT.LDID LDID.LIST%,LINE.XREF%,LINE%,LDID%
             END
          END ELSE
             IF LDID% = '' THEN
                *** Cannot add a subtotal in view only mode, but the
                *** user can view the subtotal screen.
                ACTION.ADD.MSG OE.ACTS%,,,'%136',,2,NO,,3
                RETURN TO IN.TABLE
             END
          END

          REDISP = NO

          * This check is needed for Hajoca sites only to retrict users
          * from changing costs if there are negative items on the order.
          * For core sites, this check is not needed.
          IF HAJOCA.SITE$ THEN
             OLD.VIEW.ONLY = VIEW.ONLY%
             GOSUB CHECK.COST.EDIT.OK
             IF FORCE.VIEW.ONLY THEN VIEW.ONLY% = YES
          END

          OE.SUBTOTALS OID%,GEN%,LDID%,LDID.LIST%,QSIGN%,REDISP,PRC.KEY%,VIEW.ONLY%,SUB.F12,LOG.MV%

          IF HAJOCA.SITE$ THEN
             VIEW.ONLY% = OLD.VIEW.ONLY
          END

          MOVE.ON = NO
          IF NOT(VIEW.ONLY%) AND NOT(OE.LOCKED.DIR$) THEN
             IF NOT(SUB.F12) THEN
                OE.LI.UPDATE MAT OE.VARS,LDID.LIST%
                GOSUB DISP.ALL.LINES
                GOSUB CHECK.CREDIT
                QUIT = 0; MOVE = 4
                MOVE.ON = YES
             END ELSE
                IF NEW.SUB THEN
                   OE.DELETE.LINE MAT OE.VARS,YES
                   OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%
                   LOCATE LDID% IN LDID.LIST%<1> SETTING NOTHING ELSE
                      * This will rebuild the LINE.XREF array without this
                      * subtotal line (which has been deleted)
                      LDID% = ''
                      GOSUB DISP.ALL.LINES
                   END
                END
             END
          END

          *** If the user's complete with a subtotal, move them on in the
          *** screen so they don't have to hit another keystroke
          IF MOVE.ON THEN
             RETURN TO MOVENEXT
          END
          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
SCHED.TOGGLE:*** This toggles the schedule setting from on to off or vice
             *** versa.  This setting effects when the scheduling screeen
             *** is automatically opened for the user.

          SCHED.TOGGLE  = NOT(SCHED.TOGGLE)

          * If we turn on the scheduling, reset SCHED.ACTIVE%
          IF SCHED.TOGGLE THEN
             CHECK.KEY MODE%:'OE.SCHEDULE',,SCHED.ACTIVE%
             * If they have set Sched to On and they don't have the auth
             * key or are a superuser, then make it behave like they have
             * the level 1 auth key.
             IF SCHED.ACTIVE% = 99 OR SCHED.ACTIVE%='' THEN
                SCHED.ACTIVE% = YES
             END
          END ELSE
             SCHED.ACTIVE% = NO
          END

          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
SCHEDULE: *** This opens the scheduling screen.
          *** Warn user that they are not able to access the schedule
          *** screen for any Change Order line item.
          IF LED(129)<1,2> THEN
             ACTION.ADD.MSG OE.ACTS%,,,'%277'
             RETURN TO IN.TABLE
          END

          MSGS      = ''
          RESPS     = ''
          ADD.LINES = ''
          ACTION.ADD MSGS,'SCHEDULE'
          OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,ADD.LINES,MSGS,,RESPS,CUSTOM.XREF%

          IF ADD.LINES # '' THEN
             SV.MOVE    = MOVE
             SV.LASTKEY = LASTKEY
             GOTO ADD.LINES
          END

          LOCATE 'REDISP.LI' IN RESPS<1> SETTING NOTHING THEN
             * Reset ldid list so that all lines on gen are redisplayed,
             * for example when a restocking fee is added on a return.
             OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%
             LOCATE LDID% IN LDID.LIST%<1> SETTING NOTHING ELSE LDID% = ''
             GOSUB PARTIAL.INIT.XREF
             GOSUB DISP.ORDER
          END ELSE
             GOSUB DISP.ALL.LINES
          END

          LOCATE 'CHECK.CREDIT' IN RESPS<1> SETTING NOTHING THEN
             GOSUB CHECK.CREDIT
          END

          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
HEADER:   *** Call the header screen.
          OE.HEADER OID%,GEN%,LOG.MV%,NEW.ORDER%,REDISP%,'Body',VIEW.ONLY%,POST.ENTRY%
          BT.CN% = LED(1)<1,GEN%>
          ST.CN% = LED(5)<1,GEN%>
          IF REDISP% THEN
             GOSUB PARTIAL.INIT.XREF
             GOSUB DISP.ORDER
          END
          GOSUB CHECK.CREDIT

          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
TOTALS:   *** Call the Totals Screen
          IF MODE%='S' AND LED(6)<1,GEN%>#'B' AND LED(6)<1,GEN%>#'X' THEN
             NPRB       = CUSS(45)<1,1>
             NPRB.OK    = (NPRB#'' AND NPRB#'R' AND NPRB#0 AND NPRB#'N')
             PO.CHK     = (NPRB.OK AND LED(13)<1,GEN%>='')
             IF PO.CHK AND NOT(VIEW.ONLY%) THEN
                OE.HEADER OID%,GEN%,LOG.MV%,NEW.ORDER%,REDISP%,'Esc - Status',,POST.ENTRY%
                BT.CN% = LED(1)<1,GEN%>
                ST.CN% = LED(5)<1,GEN%>
                IF MOVE = 2 THEN RETURN TO GO.BACK
             END
          END
          * Change freight allowed flag to 'Y' if order over min amt
          SOE.FRT.MIN.ORD ST.CN%,OID%,GEN%,'UPD'
          IF UPDATE.PAF.FLAG% THEN
             GOSUB UPDATE.PAF
          END
          MATBUILD SV.LD FROM LD
          OE.TOTALS OID%,GEN%,LOG.MV%,NEW.ORDER%,'Body',,VIEW.ONLY%,REDISP%,POST.ENTRY%
          MATPARSE OLD.LD FROM SV.LD
          LD.GET LDID%
          GOSUB CHECK.PAF
          IF REDISP% THEN
             GOSUB DISP.ALL.LINES
          END
          GOSUB CHECK.CREDIT

          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
SUBSTITUTES:** Invoke the Substitutes screen.
          IF NOT(QTY.CHNG.OK%)          THEN RETURN
          IF OE.LOCKED.DIR$             THEN RETURN

          *** Warn user that they are not able to access the quick price
          *** screen for any Change Order line item that is tagged to
          *** an MJB line item.
          IF LED(129)<1,2> AND LD(108) THEN
             ACTION.ADD.MSG OE.ACTS%,,,'%278'
             RETURN TO IN.TABLE
          END

          MSGS        = ''
          ADD.LINES   = ''
          FORCE.ENTRY = 1
          ACTION.ADD MSGS,'SUBS.ENTRY',,,,,FORCE.ENTRY
          OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,ADD.LINES,MSGS,,,CUSTOM.XREF%

          IF ADD.LINES = '' THEN
             OE.GET.LDID.LIST LDID.LIST%,OID%,GEN%
             GOSUB DISP.ALL.LINES
          END ELSE
             SV.MOVE    = MOVE
             SV.LASTKEY = LASTKEY
             GOTO ADD.LINES
          END

          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
CUSTOM.OPT: *** this hotkey can be used for any custom modification that
          *** might need a hotkey but is not part of the standard package

          *** Check for Product Wizard
          IF LD(1) # "" AND PRD(140) # "" THEN
             GOSUB WIZARD
             RETURN TO IN.TABLE
          END

          IF NOT(QTY.CHNG.OK%) THEN RETURN

          MSGS        = ''
          ADD.LINES   = ''
          FORCE.ENTRY = 1
          ACTION.ADD MSGS,'CUSTOM.MOD',,,,,FORCE.ENTRY
          OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,SUBS.XREF%,ADD.LINES,MSGS,,,CUSTOM.XREF%

          IF ADD.LINES = '' THEN
             GOSUB DISP.ALL.LINES
          END ELSE
             SV.MOVE    = MOVE
             SV.LASTKEY = LASTKEY
             GOTO ADD.LINES
          END

          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
PRDXREF:  *** Product External References.
          PRD.XREF.VIEW LD(1)
          RETURN
*-------------------------------------------------------------------------*
CHNG.SHIPDATE:*** Change to or add a shipdate on the order.
          *** Warn user that they are not able to access the change shipdt
          *** screen for any Change Order line item.
          IF LED(129)<1,2>  THEN
             ACTION.ADD.MSG OE.ACTS%,,,'%277'
             RETURN TO IN.TABLE
          END

          OLD.GEN = GEN%
          OE.CHNG.SHIPDATE OID%,GEN%,VIEW.ONLY%,NEWGEN
          IF OLD.GEN # GEN% THEN
RETRY.RCL:   ***
             GOSUB RECALL.ORDER
             GOSUB CHECK.CREDIT

             IF ABORT THEN
                PRINT BELL:;
                IF OLD.GEN = '' THEN
                   RETURN TO RESTART
                END ELSE
                   GEN% = OLD.GEN
                   GOTO RETRY.RCL
                END
             END

             IF NEWGEN AND VIEW.ONLY% THEN
                GOTO EDMODE
             END
             CURRENT.GEN = GEN%
             GOSUB DISP.ORDER
          END

          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
CRED.REBILL:*** Access the Credit/Rebill functionality.
          IF MODE%='T'                                       THEN RETURN
          CHECK.KEY MODE%:'OE.CREDIT.REBILL',ENTRY.OK
          IF NOT(ENTRY.OK)                      THEN PRINT BELL:; RETURN
          IF LED(30)<1,GEN%> = 'HST' THEN
             ERR.MESS 10,5,'Credit/Rebill Disallowed for Converted Invoices.'
IN$$1:       INPNO A,,,0
             RETURN
          END

          * Do not allow credit/rebill on orders that were used in Close
          * Counter Order to collect payment for multiple orders.
          IF (LED(30)<1,1> = "CCO-MULT") THEN
             MSG  = "Credit/Rebill Disallowed on orders that paid for":AM
             MSG := "multiple orders through Close Counter Order."
             ERR.MESS 10,5,MSG
IN$$4:       INPNO A,,,0
             RETURN
          END

          *** We must clear out the locked direct flag to create the
          *** new credit and rebill gens.  We need to reset flag if
          *** we are returning from this gosub for any reason.
          IF OE.LOCKED.DIR$ THEN
             CHECK.KEY 'SOE.EDIT.LOCKED.DIRECT',DIR.EDIT.OK
             IF NOT(DIR.EDIT.OK) THEN RETURN
          END
          SV.LOCK.DIR = OE.LOCKED.DIR$
          OE.LOCKED.DIR$ = ''

          * Warn user that they are not able to access the credit/rebill
          * functioality for any Change Order.
          IF LED(129)<1,2> THEN
             IF LED(128)<1,8> = 'C' AND LED(30)<1,1> # 'COUC' THEN
                OE.CHANGE.ORDER.REBILL OID%

                * Make sure the LD gets re-loaded.
                OE.LOCKED.DIR$ = SV.LOCK.DIR
                RETURN TO IN.TABLE
             END
             CO.ERR.ID = '%416'
             IF LED(30)<1,1> = 'COUC' THEN CO.ERR.ID = '%415'
             ACTION.ADD.MSG OE.ACTS%,,,CO.ERR.ID
             OE.LOCKED.DIR$ = SV.LOCK.DIR
             RETURN TO IN.TABLE
          END

          OE.LOCK.LED OID%,LOCK.MSG,YES

          IF LOCK.MSG AND VIEW.ONLY% THEN
             PRINT BELL:;
             OE.LOCKED.DIR$ = SV.LOCK.DIR
             RETURN
          END

          MATBUILD SV.LD FROM LD
          CRGEN,DBGEN = OE.CREDIT.REBILL(ERRCODE,OID%,GEN%)

          *** Pgm loops thru all LDIDs calling LD.GET for each one so you
          *** could have a diff LD array active now than when you entered
          IF ERRCODE THEN
             MATPARSE LD FROM SV.LD
             PRINT BELL:
             *** If was originally View Only then we need to get rid of the
             *** lock.
             IF VIEW.ONLY% THEN
                OE.UNLOCK.LED OID%
             END
             OE.LOCKED.DIR$ = SV.LOCK.DIR
             RETURN
          END
          INIT.OID%    = OID%;   INIT.GEN% = DBGEN
          IF INIT.GEN% = '' THEN INIT.GEN% = CRGEN
          OE.UNLOCK.LED OID%
          INIT.VIEW.ONLY% = NO;  VIEW.ONLY% = NO;   CRD.RBL% = YES
          OE.LOCKED.DIR$ = SV.LOCK.DIR
          RETURN TO RESTART
*-------------------------------------------------------------------------*
VIEW.GL:  *** Hidden auth key Alt~ shows GL postings. Must have Cost/COGS
          *** authorization.
          CHECK.KEY 'COGS.VIEW',COGS.VIEW.OK
          CHECK.KEY 'COST.VIEW',COST.VIEW.OK

          IF COGS.VIEW.OK AND COST.VIEW.OK THEN
             VIEW.GL OID%,GEN%
          END ELSE
             EMSG = 'Not authorized to view COGS/Comm Cost Information.'
             ERR.MESS 10,5,EMSG
IN$$10:      INPNO A,,,0
          END
          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
INQ:      *** Invoke the Inquiries screen.
          OE.INQS OID%,GEN%,LDID%
          RETURN
*-------------------------------------------------------------------------*
LABELS:   *** Access the labels.
          *** Warn user that they are not able to access the labels
          *** screen for any Change Order line item.
          IF LED(129)<1,2> THEN
             ACTION.ADD.MSG OE.ACTS%,,,'%277'
             RETURN TO IN.TABLE
          END

          SV.LDID = LDID%
          READV SORT.PO FROM CTRLFILE,'SORT.JOHNSTONE.PO',1 ELSE SORT.PO=''
          *** We need to update the ledger before calling label routines
          *** Like for Johnstone that does a sort of the PO.
          IF SORT.PO THEN
             JS.SORT.PO OID%,GEN%
          END
          OE.LABEL.PRINT OID%,GEN%,SV.LDID
          IF SORT.PO THEN
             OE.RECALLIT.STATE MAT OE.VARS,MAT OE.STATE,,ABORT
             GOSUB CHECK.CREDIT
             GOSUB PARTIAL.INIT.XREF
             GOSUB DISP.ORDER
          END
          RETURN
*-------------------------------------------------------------------------*
EDMODE:   *** Switch to Edit Mode
          IF NOT(VIEW.ONLY%)                     THEN PRINT BELL:; RETURN

          * Unlock the current order before doing extra locks
          IF LOCKED.LED% AND OID% # "" THEN
             OE.UNLOCK.LED OID%
          END

          *** Need to clear any extra locks that still remain
          CT = DCOUNT(EXTRA.LOCKS%,VM)
          FOR J = 1 TO CT
             OE.UNLOCK.LED EXTRA.LOCKS%<1,J>
          NEXT J

          *** Force to not be in view only mode
          VIEW.ONLY% = NO;   INIT.VIEW.ONLY% = NO
          INIT.OID%  = OID%; INIT.GEN%       = GEN%

          RETURN TO START
*-------------------------------------------------------------------------*
FINDPN:   *** Find a product on the current order.
          OE.FIND.PN MAT OE.VARS,LDID.LIST%,LINE.XREF%,,LINE%
          RETURN TO IN.TABLE
*-------------------------------------------------------------------------*
IMPRT:    *** Import data.
          PAF.PN = PN%
          IF OE.LOCKED.DIR$ THEN RETURN
          OE.IMPORT.DATA OID%,GEN%

          IF SHOULD.PROMPT.PAF% AND NOT(HAVE.PROMPTED.PAF%) THEN
             PAF.APN   = PN%
             IF PAF.PN # PAF.APN THEN
                OE.PROMPT.PAF MAT OE.VARS, MAT PAF.DATA
             END
          END

          RETURN TO GO.BACK
*-------------------------------------------------------------------------*
TRIGGERS: *** See the OE.PROMPTS affecting this order.
          IF NOT(NUM(LD(1))) OR LD(1)='' THEN PLDID = '' ELSE PLDID = LDID%
          OE.TRIGGERS ,OID%,GEN%,NEW.ORDER%,PLDID,VIEW.ONLY%
          RETURN
*-------------------------------------------------------------------------*
CUS.INDEX:** Show the customer demand index screen
          IF VIEW.ONLY% OR OE.LOCKED.DIR$ THEN RETURN
          *** Read control record to default the reorder pad to Bill-To
          *** or Ship-To criteria.
          CRTL.ID = 'OE.REORDER.PAD.DFLT'
          READ DFLT.OPT FROM CTRLFILE,CRTL.ID ELSE DFLT.OPT = 'Bill-To'
          IF DFLT.OPT = 'Bill-To' THEN
             VALUE    = '/,'
          END ELSE
             VALUE    = '/.'
          END
          SV.MOVE    = MOVE
          SV.LASTKEY = LASTKEY

          GOTO SELECT.PNS
*-------------------------------------------------------------------------*
XCURR:    *** Change the currency of the current order.
          OE.XCURR.MAINT OID%,GEN%,REDISP%
          IF REDISP% THEN
             GOSUB PARTIAL.INIT.XREF
             GOSUB DISP.ORDER
          END
          RETURN TO IN.TABLE

*-------------------------------------------------------------------------*
CHK.NEW:  *** Check to see if the order is truely a new Order if it is
          *** then set the NEW.ORDER Flag.  This is only called if 2nd
          *** Value Mark Position of INIT.OID is set.

          * Can only set new order flag for 1 gen orders
          G.CT = DCOUNT(LED(12),VM)
          IF G.CT > 1 THEN RETURN

          * Get the ledger log record
          READV PRT.LOG FROM LEDLFILE,OID%,1 ELSE PRT.LOG = ''

          * Check to see if this order gen has been printed before
          PRT.LOG = PRT.LOG<1,1>
          CONVERT SVM TO "" IN PRT.LOG
          IF PRT.LOG # "" THEN RETURN

          NEW.ORDER% = NEW.ORDER.OVRD

          RETURN
*-------------------------------------------------------------------------*
CHECK.CREDIT:*** Only for sales orders, this checks the customers credit
             *** to make sure that nothing is wrong.  Not only can this
             *** display a credit warning message, it will also returns
             *** CLIM.MESS that might contain a credit limit warning msg.

          CLIM.MESS = '' ;* Credit LIMit Warning MESSage
          IF MODE% # 'S' THEN RETURN

          IF NOT(LED(128)<1,1>) THEN
             SOE.CREDIT.CHECK ST.CN%,NO.OE,,,NO.SHIP,LED(76),MSG,OID%,GEN%,CLIM.MESS%
             IF NOT(VIEW.ONLY%) AND (NO.SHIP OR NO.OE) THEN
                ABC.ENABLED.BR% = NO
                IF ABC.ENABLED$ THEN
                   CTRB.ID = 'ABC.ENABLED~':LED(2)<1,GEN%,2>
                   READV ABC.ENABLED.BR% FROM CTRBFILE,CTRB.ID,1 ELSE
                      ABC.ENABLED.BR% = NO
                   END
                END
                IF ABC.ENABLED.BR% AND MODE% = 'S' THEN
                   ACD = 'COAHOLD'
                   *** Check that this invoice has not already been logged
                   *** for credit hold
                   LOCATE ACD IN LED(120)<1> SETTING XX ELSE
                      LED(120)<1,-1> = ACD
                      OE.SET.COMMON.DATA MAT OE.VARS
                      ABC.LOG.AUTO ACD
                   END
                END
             END
             IF NOT(VIEW.ONLY%) AND NO.OE AND OE.OK%#2 THEN
                SOE.CHECK.NO.OE BT.CN%,ST.CN%,OE.OK%
                IF NOT(OE.OK%) AND NOT(NEW.ORDER%) THEN
                   VIEW.ONLY% = YES
                   OE.OK%     = YES
                END
             END
          END ELSE
             OE.CHECK.MASTER.ESTIMATE OID,MSG
          END

          IF TRIM(MSG)#'' THEN
             PRINT @(52,17):BLINK$:MSG "L#25":NORM$
          END ELSE
             PRINT @(52,17):NORM$:''   "L#25"
          END

          RETURN
*-------------------------------------------------------------------------*
UPDATE.PAF:*** Update Pass along freight for this Gen as long as the
           *** Override Flag LED(36)<1,GEN,1> is still a 5, 6, or 7
          OVRD.FLAG = LED(36)<1,PAF.GEN%,1>
          IF OVRD.FLAG = 5 OR OVRD.FLAG = 6 OR OVRD.FLAG = 7 THEN
             SOE.RECALC.PASS.ALONG.FRT OID%,PAF.GEN%,QSIGN%
             *** Re-establish LD because the LD array is changed in the
             *** Update
             LD.GET LDID%
             MAT OLD.LD = MAT LD
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.PAF:*** Set Recalc Flag for Pass Along Freight "Soft Tags"/ Hard Tags
          *** only on Sales Orders which had pass along freight override
          *** flag set when ticket printed initially.

          *** Need to keep track of Gen at time of setting prompting flag
          PAF.GEN%           = GEN%
          UPDATE.PAF.FLAG%   = NO
          SHOULD.PROMPT.PAF% = NO
          HAVE.PROMPTED.PAF% = NO

          IF MODE% = "S" AND LED(8)<1,GEN%> AND LED(6)<1,GEN%> # 'D' THEN
             OVRD.FLAG = LED(36)<1,PAF.GEN%,1>
             IF OVRD.FLAG = 5 OR OVRD.FLAG = 6 OR OVRD.FLAG = 7 THEN
                SHOULD.PROMPT.PAF% = YES
             END
          END

          RETURN
*-------------------------------------------------------------------------*
DISP.ALL.LINES:*** This re-prints all the line items for the current gen.
          *** OE.VARS    - OID, GEN, etc..                         [IN]
          *** VIEW.REC%  - The current view's record               [IN]
          *** SUBR.INFO% - The current view's subroutine list      [IN]
          *** LDID.LIST% - The LDIDs for the current gen by VM     [IN]
          *** LINE.XREF% - The LDID/VSCROLL line xref              (OUT)

          OE.LI.PRINT MAT OE.VARS,VIEW.REC%,SUBR.INFO%,LDID.LIST%,LINE.XREF%
          CHNG = NO
          NEED.REDISP = NO

          * See if we've exceeded the estimated amts.
          IF LED(128)<1,1> THEN
             GOSUB CHECK.CREDIT
          END ELSE
             LOCATE 'CHECK.CREDIT' IN RESPS<1> SETTING NOTHING THEN
                GOSUB CHECK.CREDIT
             END
          END

          RETURN
*-------------------------------------------------------------------------*
DISP.ORDER:*** This routine will display the entire order (the header,
           *** footer, & line items).  This only prints to the screen, this
           *** does _not_ display any messages.

          DISPLAY.SCREEN SCREEN.NAME%

          OE.LI.GET.VIEW.DATA VIEW.ID%,VIEW.REC%,SUBR.INFO%
          OE.DISP.VIEW.COLS VIEW.REC%<9>,VIEW.REC%<10>,VIEW.REC%<11>

          *** If in an open sales order, set Qty Shipped col to inactive
          IF MODE% = 'S' AND LED(6)<1,GEN%> # 'I' THEN
             LOCATE 'QTY.SHIPPED' IN VIEW.REC%<3> SETTING VPOS THEN
                VIEW.REC%<7,VPOS> = 0
             END
          END

          *** This will display the title & *I* for images.
          OE.DISP.TITLE OID%,GEN%,VIEW.ONLY%

          TERMS.CREDIT.OVRD.GET OID%,GEN%

          OE.DISP.BT.ST GEN%,MODE%
          OE.DISP.DATES OID%,GEN%
          OE.DISP.MODE OID%,GEN%
          OE.DISP.ESC.PATH OID%,GEN%,NEW.ORDER%

          GOSUB DISP.SPLIT

          IF LINE.XREF%<1> THEN LINE.XREF% = ''
          OE.LI.PRINT MAT OE.VARS,VIEW.REC%,SUBR.INFO%,LDID.LIST%,LINE.XREF%
          CHNG = NO
          OE.LOAD.HOTKEYS MODE%
          GOSUB CHECK.CREDIT

          RETURN
*-------------------------------------------------------------------------*
DISP.SPLIT:*** Checks to see if this gen is a result of a Split Terms Inv.
           *** This is new code to replace the Split Payment Notice
           *** so that it is in bright yellow to most glaringly
           *** obvious to the user when they reenter a split sales order
           *** that it is in fact a split sales order.

          IF NOT(LED(30)<1,GEN%>)    THEN RETURN
          IF LED(30)<1,GEN%> # 'SPT' THEN RETURN

          ACTION.ADD.MSG OE.ACTS%,,,'%108',,2,,15,5,'%109'

          RETURN
*-------------------------------------------------------------------------*
INIT.START:*** Initialize any variables that need to be set EVERY TIME OE
           *** starts with a new OID.

          *** This lets SOE.CHECK.NO.OE know that the user has
          *** already authorized order entry for this ledger once
          *** and shouldn't need to authorize it again.
          NO.OE.OVRD$    = NO

          * This is set in chng.shipdate. It is used in chng.mode to check
          * if the current gen is a new gen.
          OLD.GEN = ''

          EDIT.OE%       = NO
          ENT.MSG.ON%    = NO
          SKIP.PRD.MSG%  = YES
          OID.DATA$      = ''
          PRC.BR%        = TTY.BR%

          OE.VIEW.DATA$  = ''
          VIEW.ID%       = ''
          HDATA%         = ''

          MAT LED        = ''
          QO.ALPHA%      = ''
          DONT.FORGET%   = NO
          NEW.ORDER%     = NO

          LINE%          = ''
          DLINE%         = 1
          DLINE.XREF%    = 1

          LOG.MV%        = ''
          NEW.ORDER%     = NO

          OLD.CRED.MSG%  = ''
          AUTO.EXIT%     = NO

          VIEW%          = 1
          DLGTH%         = 35
          LOCKED.LED%    = NO

          ALLOC.ZONE%    = ''
          GEN%           = ''
          DPOS%          = 13

          SWAP.GEN%      = NO
          SUBS.XREF%     = ''
          CUSTOM.XREF%   = ''
          NEW.ITEM%      = NO

          AUTO.DUTY%     = NO
          FROM.SUB%      = YES

          ADD.LOT%       = NO
          CRD.RBL%       = NO
          IN.SUBS%       = NO

          RECV.GEN.ONLY% = NO
          DF.PN.CHNG%    = NO
          DF.LAST.COL%   = 1

          DF.MOVE.MULT%  = NO
          LN.CHK.GP%     = NO
          DF.LINE.CHNG%  = NO

          DISP.DUP.LN%   = YES
          QTY.CHNG.OK%   = ''
          PNN%           = ''

          FORCE.DEL%     = NO
          NEW.PNS%       = ''
          NEW.PN.QTYS%   = ''

          PN.PRCS%       = ''
          PRC.ERROR%     = ''

          CHECK.QO.CHANGE%  = YES
          FIRST.IN%         = YES
          OE.ACTS%          = ''

          SUB.ACTIVE%    = NO
          SCHED.ACTIVE%  = NO
          CLIM.MESS%     = ""
          RESPS          = ''

          PRD.REM.MSGS   = '' ;* product reminder messages
          SKIP.PRD.MSGS  = NO ;* Do not display prod reminder this time
          NEW.PN.DISP    = NO

          GIFT.CERT.ERR  = NO

          * Need to reset the CURRENT.GEN variable so it is not in
          * a left over state from the previous order
          CURRENT.GEN = ""

          CHECK.KEY MODE%:'OE.SCHEDULE',,SCHED.ACTIVE%
          * Superusers should always default to 'Sched-Off'
          IF SCHED.ACTIVE% = 99 THEN SCHED.ACTIVE% = NO

          SCHED.TOGGLE   = SCHED.ACTIVE%

          READV NEW.PIL% FROM CTRLFILE,'SOE.NEW.PIL.CHECK',1 ELSE
             NEW.PIL%    = ''
          END
          READV DIR.PIL% FROM CTRLFILE,'SOE.DIR.PIL.CHECK',1 ELSE
             DIR.PIL%    = ''
          END
          READV CRD.PIL% FROM CTRLFILE,'OE.RETURN.PIL.CHK',1 ELSE
             CRD.PIL%    = ''
          END
          ! NOTE: This control record has been deprecated as of 862.
          READV ADISP.MSG% FROM CTRLFILE,'AUTO.ADD.OE.MSG',1 ELSE
             ADISP.MSG%  = ''
          END
          ! NOTE: This control record has been deprecated as of 862.
          READV SUB.TYPE% FROM CTRLFILE,'AUTO.OE.SUBS.TYPE',1 ELSE
             SUB.TYPE%   = ''
          END
          READV REQ.PO.HDR% FROM CTRLFILE,'REQ.PO.HDR',1 ELSE
             REQ.PO.HDR%   = ''
          END

          *** Determine whether the site is using vendor freight terms.
          FRT.TERMS%     = ''
          IF MODE% = "P" THEN
             CTRL.ID     = 'VENDOR.FREIGHT.TERMS'
             READV FRT.TERMS% FROM CTRLFILE,CTRL.ID,1 ELSE NULL
          END

          READV EDI.DFLT.PN FROM CTRLFILE,'EDI.DFLT.PN',1 ELSE
             EDI.DFLT.PN = ''
          END

          EXTRA.LOCKS%   = ''
          OE.VIEW.DATA$  = ''
          HDATA%         = ''
          OE.GET.QSIGN QSIGN%,MODE%

          ADDL.PASS = ''
          ADDL.PASS<1,3> = 1

          * Array to keep track of GENs that have changed on this order
          * this must be reset each time we enter a new order.
          ORD.CHG  = ''

          RETURN
*-------------------------------------------------------------------------*
GET.OID:  *** This routine will read in an OID, or do what's neccesary
          *** to start a new one,as determined by the user.  NOTE: this
          *** might return to FINISH or RESTART.
          *** OE.VARS - Order Entry State                          [IN/OUT]

          IF INIT.OID%#'' THEN
             AUTO.EXIT% = YES
             MODE.OK% = (INIT.OID%[1,1] = 'R' AND MODE% = 'S')
             IF MODE% # INIT.OID%[1,1] AND NOT(MODE.OK%) THEN
                PRINT BELL:;
                RETURN TO FINISH
             END
             MATREAD LED FROM LEDFILE,INIT.OID% ELSE
                PRINT BELL
                RETURN TO FINISH
             END
             IF INIT.GEN%+0 = 0 THEN
                OE.NEXT.SHIPDATE INIT.GEN%
                IF INIT.GEN%=0 THEN INIT.GEN% = 1
             END
             IF LED(6)<1,INIT.GEN%> = 'Y' THEN
                LOCATE LED(33)<1,INIT.GEN%> IN LED(12)<1> SETTING GEN% ELSE
                   RETURN TO FINISH
                END
             END ELSE
                GEN% = INIT.GEN%
             END
             OID%    = INIT.OID%
             PRC.BR% = LED(2)<1,GEN%,1>
             BT.LED.POS = 1    ;* Bill to ledger default
             ST.LED.POS = 5    ;* Ship to ledger default
             * For transfers, check to see if we are viewing the receiving
             * branch.  If we are, flip the ledger attribute postions to
             * make the bill to and ship to branch info sho up properly in
             * the header screen.
             HST.RCV.GN = (LED(30)<1,GEN%>='HST' AND LED(6)<1,GEN%>='R')
             IF MODE = 'T' AND (LED(30)<1,GEN%> = 'RX' OR HST.RCV.GN) THEN
                BT.LED.POS = 5 ;* Swap bill to with ship to
                ST.LED.POS = 1 ;* Swap ship to with bill to
             END
             BT.CN%  = LED(BT.LED.POS)<1,GEN%>
             ST.CN%  = LED(ST.LED.POS)<1,GEN%>

          END ELSE
             OID%    = MODE%
             IF MT.TERM.PBR% THEN PRC.BR% = ''
             PRINT @(22,17):PRC.BR% "L#4"
IN.BR:       IF MODE% # 'T' AND PRC.BR% = '' THEN
                * We need to allow for non-stocking branches to be
                * entered in this field if and ONLY if that branch has a
                * ship branch override in the appropriate control record
                * We will accomplish this by passing in a TERR.TYPE value
                * for VERIFY.BR to interpret
                IF MODE% = 'P' THEN
                   TTYPE = 11
                END ELSE
                   TTYPE = 10
                END
INPBR:          INP.BR 22,17,4,PRC.BR%,BNAME,,TTYPE
                IF QUIT THEN
                   RETURN TO FINISH
                END

                PRINT @(22,17):PRC.BR% "L#4"
                IF TTY.BR% = '' THEN TTY.BR% = PRC.BR%
             END
             BT.CN% = ''
             ST.CN% = ''
             OID% = ''

             OE.SELECT.ENTITY PRC.BR%,RCV.BR%,BT.CN%,ST.CN%,OID%,GEN%,MODE%,POST.ENTRY%,VIEW.ONLY%
             IF QUIT THEN
                RETURN TO FINISH
             END
          END
          GET.CUS PRC.BR%,BT.CN%,ST.CN%,QSIGN%

          IF NOT(VIEW.ONLY%) AND (MODE%='S' OR MODE%='P') THEN
             SOE.CHECK.NO.OE BT.CN%,ST.CN%,OE.OK%
             *** If the user is just trying to see an existing order, put
             *** them into view.only...  If trying to create, don't let
             *** it happen...
             IF NOT(OE.OK%) THEN
                IF OID% = 'NEW' THEN
                   RETURN TO RESTART
                END ELSE
                   VIEW.ONLY% = YES
                   OE.OK%     = YES
                END
             END
          END ELSE
             OE.OK% = YES
          END


          CHECK.KEY MODE%:'OE.ALLOWED',OE.ENTRY.OK,OE.LEVEL

          * Check level of Mode%:'OE.ALLOWED'. New level added for Rel8.
          * Level 1 = Cannot create new order,can only view existing
          * Level 2 = Can create new order,can only view existing (prev 1)
          * Level 3 = Can create new order,edit existing (prev 2)
          WRITER=LED(73)<1,GEN%>
          AUTH.PURCH=TRANS('INITIALS',USER.ID,102,'X')
          IF AUTH.PURCH # '1' THEN
          IF STKRCV% OR MODE%='P' AND WRITER # USER.ID THEN RETURN TO RESTART
          END
          IF OE.ENTRY.OK THEN
             IF OE.LEVEL < 3 THEN
                IF OE.LEVEL = 1 THEN
                   IF OID% = 'NEW' THEN RETURN TO RESTART
                   IF NOT(STKRCV%) THEN VIEW.ONLY% = YES
                END ELSE
                   IF OID% # 'NEW' AND NOT(STKRCV%) THEN VIEW.ONLY% = YES
                END
             END
          END ELSE
             PRINT BELL:
             RETURN TO FINISH
          END
          * If 'Reserve' inventory then always put user in view only - but
          * only check this if it's not a new gen coming in.
          IF GEN% # 'New' THEN
             IF MODE%='S' AND LED(6)<1,GEN%>='R' THEN VIEW.ONLY% = YES
          END

          VIEW.ONLY = VIEW.ONLY%
          OID.DATA$<11,1> = PRC.BR%
          RETURN
*-------------------------------------------------------------------------*
RECALL.ORDER: *** This routine will actually create a new led,
              *** and it pulls back all the information on the
              *** ledger records.

          IF OID%='NEW' THEN
             OE.NEW.LED MODE%,PRC.BR%,RCV.BR%,BT.CN%,ST.CN%,OID%,GL.SOURCE%,TTY.SHIPVIA%,ABORT,POST.ENTRY%
             IF ABORT THEN RETURN TO RESTART

             GEN%           = 1
             LOCKED.LED%    = YES
             LDID.LIST%     = ''
             NEW.ORDER%     = YES
             LDID%          = ''
             PN%            = ''
             LED(28)        = BATCH%
             OE.SET.COMMON.DATA MAT OE.VARS
             OE.GET.KEYS OID%,GEN%,NEW.ORDER%,VIEW.ONLY%,PRC.KEY%,QTY.KEY%
             OE.CHECK.CONSIGN MAT OE.VARS
             IF PRC.KEY% AND LED(110)<1,1>='S' THEN PRC.KEY%=NO
          END ELSE
             MODE.OK%= (OID%[1,1] = 'R' AND MODE% = 'S')
             IF OID%[1,1]#MODE% AND NOT(MODE.OK%) THEN
                OE OID%[1,1],INIT.VIEW%,OID%,GEN%,VIEW.ONLY%,POST.ENTRY%
                RETURN TO RESTART
             END
             ***************************************************
             ***we need to reset VIEW.ONLY% flag here otherwise
             ***the view only mode doesn't change when switching
             ***shipdates.
             VIEW.ONLY% = VIEW.ONLY

             ****************************************************

             OE.RECALLIT.STATE MAT OE.VARS,MAT OE.STATE,YES,ABORT
             GOSUB CHECK.CREDIT
             IF ABORT THEN RETURN TO RESTART

             IF NEW.ORDER.OVRD THEN
                * Check to make sure this order is really new, if it is
                * following routine will set the NEW.ORDER flag so that
                * the rest of OE will treat it as a new Order.
                GOSUB CHK.NEW
             END
          END

          * Check to make sure that the generation has been set
          IF (NUM(GEN%) AND (GEN% # "")) THEN
             READ.CN = NO            ;* Should we re-read in the CUS arrays

             * Check to see if the BT/ST CN is NULL. If so, set it up
             * from the ledger record
             IF (BT.CN% = "") OR (ST.CN% = "") THEN
                BT.CN% = LED(1)<1,GEN%>
                ST.CN% = LED(5)<1,GEN%>
                READ.CN = YES
             END ELSE
                * Check for rare instance that there are multiple vendors
                IF MODE% = 'P' THEN
                   *** ST.CN% and/or BT.CN% might be wrong and not
                   *** match the BT and ST for the gen, if they don't
                   *** match, we need to set and reload CUS and CUSS
                   IF (ST.CN% # LED(5)<1,GEN%>) OR (BT.CN% # LED(1)<1,GEN%>) THEN
                      READ.CN = YES
                      ST.CN% = LED(5)<1,GEN%>
                      BT.CN% = LED(1)<1,GEN%>
                   END
                END
             END

             * Check to see if we need to re-read in the CUS and CUSS
             * arrays
             IF (READ.CN) THEN
                GET.CUS PRC.BR%,BT.CN%,ST.CN%,QSIGN%
             END
          END

          OE.RECV.GEN.ONLY OID%,GEN%,RECV.GEN.ONLY%

          IF LED(6)<1,GEN%,1>='$' THEN
             SOE.EDIT.DEPOSIT OID%,GEN%,EDIT.OE%
             IF EDIT.OE% THEN
                INIT.OID% = OID%
                INIT.GEN% = EDIT.OE%
             END
             RETURN TO RESTART
          END

          OID.DATA$<8> = NEW.ORDER%
          OID.DATA$<9> = POST.ENTRY%

          IF VIEW.ID% = '' THEN
             OE.GET.DFLT.VIEW OID%,GEN%,NEW.ORDER%,VIEW.ID%,STKRCV%
          END

          * Check the Credit Limit for the Current Customer
          GOSUB CHECK.CREDIT

          IF NOT(OE.OK%) AND NEW.ORDER% THEN
             OE.DEL.ORDER OID%,QSIGN%,YES,NO,ERR.MSG
             RETURN TO FINISH
          END

          * If a Credit Warning Message was returned from the routine,
          * add the message to the actions array to be displayed in Order
          * Entry.
          IF (CLIM.MESS% # "") THEN
             READV CNAME FROM CUSFILE,ST.CN%,1 ELSE CNAME = "CN#":ST.CN%
             CLIM.MESS% = CNAME:" ":CLIM.MESS%
             ACTION.ADD.MSG OE.ACTS%,,,CLIM.MESS%
          END

          IF MODE% = 'S' THEN
             * Change freight allowed flag to 'Y' if order over min amt
             * Doing this here at order-load time because order may have
             * been updated such that this is now allowed.
             SOE.FRT.MIN.ORD ST.CN%,OID%,GEN%,'UPD'
          END

          RETURN
*-------------------------------------------------------------------------*
ENTER.BODY:*** Prepares the OE screen for navigation by the user.
           *** Sets up hotkeys. Activates some OE.PROMPTS.  Initializes
           *** some variables.

          STK.BR% = LED(2)<1,GEN%,2>
          OID.DATA$<11,2> = STK.BR%

          DFMT%  = 'L#':DLGTH%
          OTCOL% = 1
          OCOL%  = 1

          *** Display the entity reminders
          BEGIN CASE
          CASE LED(33)<1,GEN%>;   TRIG = 10
          CASE MODE = 'P';        TRIG = 4
          CASE MODE = 'T';        TRIG = 7
          CASE OTHERWISE;         TRIG = 1
          END CASE
          REMINDER.CHECK BT.CN%,ST.CN%,,TRIG,OE.ACTS%

          *** Logic to add Order to the User History List
          BEGIN CASE
          CASE MODE% = 'S';  USER.LOG.HISTORY '1',OID%
          CASE MODE% = 'P';  USER.LOG.HISTORY '2',OID%
          CASE MODE% = 'T';  USER.LOG.HISTORY '3',OID%
          END CASE

          *** If they pass in a PN, make them press enter after entity msg
          DO.CONT = (INIT.PN% # '')
          ACTION.ADD.ENTITY.MSG OE.ACTS%,BT.CN%,ST.CN%,PRC.BR%,,,DO.CONT

          *** Check to see if the Ordered By is required, and ask for it
          *** if it is...
          IF MODE% = 'S' OR MODE% = 'T' THEN
             GOSUB CHECK.ORDERED.BY
             IF ABORTED.AUTH THEN
                QUIT = NO; F12 = NO
                RETURN TO RESTART
             END ELSE
                *** If there is an authorized user selected then we need to
                *** check the credit to make sure this user is not over the
                *** limit and that the ticket unintentionally gets put on
                *** hold.
                IF LED(68)<1,GEN%> THEN
                   GOSUB CHECK.CREDIT
                END
             END
          END

          * Prompt for any triggers setup for when they enter the body
          IF MODE% = 'S' THEN
             OE.TRIGGERS 3,OID%,GEN%,NEW.ORDER%,,VIEW.ONLY%
          END
          OE.LOAD.HOTKEYS MODE%
          ORIG.SHP.DTS% = LED(9)

          GOSUB CHECK.PAF

          GIFT.CERT.ERR = NO

          RETURN
*-------------------------------------------------------------------------*
CHECK.ORDERED.BY:  *** See if the customer is set up so that we have to
          *** ensure we're only taking an order from their authorized
          *** employees.

          ABORTED.AUTH = NO

          IF NOT(NEW.ORDER%) THEN RETURN ;* only done on new orders

          RESPS   = ''

          !!!we have to call this subroutine twice to save the ordered-by
          !!!name. The first call is to get info for the user to select,
          !!!the second call is called with user responses to save the
          !!!name in LED(68)<1,GEN%>. REENTRY should not be set to YES
          !!!in the second call ...
AUTHED.CHECK: REENTRY = NO
          SOE.CHECK.AUTH.ORDER.BY MAT OE.VARS,OE.ACTS%,RESPS,REENTRY
          IF REENTRY THEN
             OE.ACTION.DISPLAY MAT OE.VARS,MAT PAF.DATA,MAT OE.SFLAGS,,,OE.ACTS%,ABORTED.AUTH,RESPS,CUSTOM.XREF%
             IF NOT(ABORTED.AUTH) THEN
                GOTO AUTHED.CHECK
             END
          END

          * If they aborted see if they want to delete order if not
          * then put them right back into the prompt.
          IF ABORTED.AUTH THEN
             OE.DEL.ORDER OID%,QSIGN%
             IF QUIT THEN
                RESPS = ''
                GOTO AUTHED.CHECK
             END
          END

          RETURN
*-------------------------------------------------------------------------*
PARTIAL.INIT.XREF: *** Partial initialization of LINE.XREF. Leaves
          *** attributes 4 and 5 to maintain line positioning.
          LINE.XREF%<1> = ''
          LINE.XREF%<2> = ''
          LINE.XREF%<3> = ''
          LINE.XREF%<6> = ''
          RETURN
*-------------------------------------------------------------------------*
INIT.OE:  *** Initialize the OE.VARS state-holding object here, and pre-
          *** set any variable that needs to be used before going into
          *** OE.INIT.START.
          *** VIEW.ONLY  - The view only flag passed into OE       [IN]
          *** MODE       - The order mode passed into OE           [IN]
          *** INIT.OID   - The initial order to display            (IN)
          ***              There can be two value marks, if there
          ***              is the second value mark is a NEW.ORDER
          ***              override.  This should only be used
          ***              for new orders.
          *** INIT.GEN   - The initial gen to display              (IN)
          *** POST.ENTRY - The post entry flag (wether or not this (IN)
          ***            - order is in the past).
          *** ABORT      - Boolean, if this is YES, then there is  (OUT)
          ***            - an error such that OE cannot be run.
          *** OE.VARS    - Order Entry State                       (OUT)

          MAT OE.VARS       = ''
          MAT OE.STATE      = ''
          INIT.VIEW.ONLY%   = VIEW.ONLY
          VIEW.ONLY%        = VIEW.ONLY
          LINE.LOCK.VO      = "@@@"
          OE.USER.VIEWS$<5> = YES
          OE.USER.VIEWS$<6> = 1
          MSG.OK%           = YES
          EXTRA.LOCKS%      = ''
          ***to be sure, initialize AUTO.DEL here.
          ***a undefined variable variable was seen but was not
          ***consistently recreatable
          AUTO.DEL          = NO
          MODE%             = MODE
          ACTIVATE.TRIGGERS = INIT.GEN<1,3>
          ***Disable the logic from CTR046 allowing trigger processing
          ***even if not a new order
          ACTIVATE.TRIGGERS = NO
          INIT.PN%          = INIT.GEN<1,2>
          INIT.GEN%         = INIT.GEN<1,1>
          INIT.VIEW%        = 1
          INIT.OID%         = INIT.OID<1,1>
          NEW.ORDER.OVRD    = INIT.OID<1,2>
          ABORTED.AUTH      = NO

          IF STKRCV = "STOCK.RECEIPTS" THEN
             STKRCV%        = YES
          END
          POST.ENTRY%       = POST.ENTRY

          REMOVING.PARENT   = NO

          OE.INIT.MODE MODE%,INIT.VIEW%,INIT.OID%,GL.SOURCE%,SCREEN.NAME%,ABORT

          GET.TTY TTY.BR%,,,TTY.SHIPVIA%,TTY.RELOG%
          IF NOT(TTY.BR%) THEN
             READV MT.TERM.PBR% FROM CTRLFILE,'REPROMPT.PRICE.BR',1 ELSE
                MT.TERM.PBR% = NO
             END
          END ELSE
             MT.TERM.PBR% = NO
          END

          IF NOT(ABORT) AND NOT(VIEW.ONLY%) AND POST.ENTRY% THEN
             OE.GET.BATCH BATCH%,ABORT
          END ELSE
             BATCH% = ''
          END

          * Determine how long product reminder notes will be displayed.
          READV DISP.PROD.NOTES FROM CTRLFILE,'DISPLAY.PROD.NOTES',1 ELSE
             DISP.PROD.NOTES = ''
          END
          DISP.PROD.NOTES = RAISE(RAISE(DISP.PROD.NOTES))
          BEGIN CASE
             CASE MODE% = 'S' AND DISP.PROD.NOTES<1>
                DISP.PROD.NOTES = YES
             CASE MODE% = 'P' AND DISP.PROD.NOTES<2>
                DISP.PROD.NOTES = YES
             CASE MODE% = 'T' AND DISP.PROD.NOTES<3>
                DISP.PROD.NOTES = YES
             CASE OTHERWISE
                DISP.PROD.NOTES = NO
          END CASE
          CMNTS     = ''
          CMT       = ''
          PNN.CMT   = ''
          CHNG      = ''
          ORD.CHG   = ''
          ORIG.LDID = ''
          ALL.ADDED = ''

          RETURN
*-------------------------------------------------------------------------*
CHECK.COST.EDIT.OK: *** check for any line items on a po that are negative
          *** if there are lines that are negative and they
          *** do not have proper authorization then they will
          *** be in view only mode for the subtotals screen
          *** and pricing screen.

          FORCE.VIEW.ONLY = NO
          IF (MODE = "P") AND NOT(VIEW.ONLY%) THEN
             CHECK.KEY "POE.RETURN.COST.EDIT",COST.CHNG.OK
             IF NOT(COST.CHNG.OK) THEN
                SV.LDID = LDID%
                MATBUILD SV.LD FROM LD

                IF LED(8)<1,GEN%> # "" THEN
                   LLIST = RAISE(LED(48)<1,GEN%>)
                END ELSE
                   LLIST = (LED(49)<1>)
                END

                LD.CNT  = DCOUNT(LLIST<1>,VM)
                FOR LDD = 1 TO LD.CNT
                   LDID = LLIST<1,LDD>
                   LD.GET LDID
                   IF LD(1) = 'C' THEN CONTINUE
                   IF LD(4) < 0 THEN
                      FORCE.VIEW.ONLY = YES
                      EXIT
                   END
                NEXT LDD

                LDID% = SV.LDID
                MATPARSE LD FROM SV.LD
             END
          END

          RETURN
*-------------------------------------------------------------------------*
LOG.CHANGE:
          IF LOG.MV% THEN
             UT.UNION.LIST.AL ORD.CHG,RAISE(LOG.MV%)
          END

          LOG.MV% = ''

          RETURN
*-------------------------------------------------------------------------*
FINISH:   *** Close out the windows and get ready to leave.
          WINDOW.CLOSE
          *** Need to clear any extra locks that still remain
          CT = DCOUNT(EXTRA.LOCKS%,VM)
          FOR J = 1 TO CT
             OE.UNLOCK.LED EXTRA.LOCKS%<1,J>
          NEXT J
          IF TTY.RELOG% THEN RELOG.NOW = YES
          RETURN
*-------------------------------------------------------------------------*
!TSMITH~12/17/13~20:41
