>I'm wondering if there is a way to identify, within a file index, what
>type of file operation has occurred.

Hello, Jeff.

Listed below is a program that uses the index like a trigger. It can only
detect WRITE and DELETE statements though.  I used this approach with PI and
PI/open as they never supported triggers (unless one considered the AKUFS a
trigger).

I have not tried this approach on UniVerse so I can not speak to its
performance, however, I suspect it will work reasonably well. If you do give
it a try, please let me know your results.

Ask me questions about what it is doing if things are unclear. I published
an article in Infocus and an NPUG proceedings that describes the algorithm
in detail but I do not have that in electronic form. :-(

Best regards,
Gyle

**********************************************************
      SUBROUTINE BUILD.POD.INDEX(result)

* This program projects a nested Purchase Order into a normalized form
suitable for reporting purposes.

$INCLUDE PO.EQUATE.INS.IBAS
$INCLUDE POD.EQUATE.INS.IBAS

      DIM temporary.pod.record(2000)
      DIM purchase.order.record(100)

      EQUATE TRUE TO 1
      EQUATE FALSE TO 0

      EQUATE ADD TO 1
      EQUATE DELETING TO 2
      EQUATE UPDATE.FIRST.CALL TO 3
      EQUATE UPDATE.SECOND.CALL TO 4
      EQUATE NEEDLESS.WRITE.PERFORMED TO 5
      EQUATE BUILDING.INDEX TO 6

      COMMON /PO.POD/ Po.File.Variable,
         Pod.File.Variable,
         Last.Updated.Id,
         Last.Mode,
         Last.Added.Id,
         Build.Time

      result = ""
      IF NOT(FILEINFO(Po.File.Variable, 0)) THEN
         OPEN "", "PO" TO Po.File.Variable ELSE
            PRINT
            PRINT "Unable to open the PO file!  (BUILD.POD.INDEX)"
            RETURN
         END
         Last.Updated.Id = ""
         Last.Added.Id = ""
         Last.Mode = ""
         Build.Time = 0
      END

      IF NOT(FILEINFO(Pod.File.Variable, 0)) THEN
         OPEN "", "POD" TO Pod.File.Variable ELSE
            PRINT
            PRINT "Unable to open the POD file!  (BUILD.POD.INDEX)"
            RETURN
         END
         Last.Updated.Id = ""
         Last.Added.Id = ""
         Last.Mode = ""
         Build.Time = 0
      END

      IF @SENTENCE[1, 11] = "BUILD.INDEX" THEN
         Last.Mode = BUILDING.INDEX
      END ELSE
         Build.Time = 0
         READ temporary.record FROM Po.File.Variable, @ID THEN
            IF temporary.record = @RECORD THEN
               BEGIN CASE
                  CASE @ID = Last.Updated.Id
                     Last.Mode = UPDATE.SECOND.CALL
                     Last.Added.Id = ""
                  CASE @ID = Last.Added.Id
                     Last.Mode = NEEDLESS.WRITE.PERFORMED
                     Last.Added.Id = ""
                  CASE TRUE
                     Last.Mode = ADD
                     Last.Added.Id = @ID
               END CASE
               Last.Updated.Id = ""
            END ELSE
               Last.Mode = UPDATE.FIRST.CALL
               Last.Added.Id = ""
               Last.Updated.Id = @ID
            END
         END ELSE
            Last.Mode = DELETING
            Last.Updated.Id = ""
            Last.Added.Id = ""
            temporary.record = ""
         END
      END

      display.error.messages = TRUE
      ON Last.Mode GOSUB add:,
         delete:,
         update:,
         update.phase.2:,
         needless.write.performed:,
         build:

      RETURN

add:
      GOSUB build.pod.records:
      IF result # "ERROR" THEN
         GOSUB write.pod.records:
      END
      RETURN

delete:
      display.error.messages = FALSE
      GOSUB build.pod.records:
      GOSUB delete.pod.records:
      RETURN

update:
      display.error.messages = FALSE
      GOSUB build.pod.records:
      IF result # "ERROR" THEN
         GOSUB write.pod.records:
      END
      RETURN

update.phase.2:
      GOSUB delete.pod.records:
      GOSUB build.pod.records:
      IF result # "ERROR" THEN
         GOSUB write.pod.records:
      END
      RETURN

needless.write.performed:
      display.error.messages = FALSE
      GOSUB build.pod.records:
      RETURN

build:
      IF Build.Time = 0 THEN
         PRINT "Clearing the POD file.  (BUILD.POD.INDEX)"
         CLEARFILE Pod.File.Variable
         Build.Time = 1
      END
      GOSUB build.pod.records:
      IF result # "ERROR" THEN
         GOSUB write.pod.records:
      END
      RETURN

build.pod.records:

      MATPARSE purchase.order.record FROM @RECORD, @FM

      detail.record.counter = 0
      errors = ""
      result = ""
      number.of.backordered.line.items = 0
      number.of.excess.receipt.line.items = 0

      customer.id = purchase.order.record(PO.VENDOR.NUMBER)
      IF customer.id = "" THEN
         customer.id = purchase.order.record(6)
      END
      customer.po = purchase.order.record(PO.PURCHASE.ORDER.NUMBER)
      current.order.status = purchase.order.record(PO.STATUS)

      hold = purchase.order.record(14)
      purchase.order.type = purchase.order.record(27)
      work.order.sequense = purchase.order.record(63)

* Process each line item

      IF LEN(purchase.order.record(PO.LINE.ITEM)) THEN
         line.item.position = 0

         LOOP

            REMOVE line.item FROM purchase.order.record(PO.LINE.ITEM)
SETTING delimiter
            line.item.position += 1
            part.number = purchase.order.record(PO.LINE.ITEM.PART.NUMBER)<1,
line.item.position>
            part.description = purchase.order.record(PO.PART.DESCRIPTION)<1,
line.item.position>
            quantity.ordered = purchase.order.record(PO.ORDER.QUANTITY)<1,
line.item.position>
            unit.price = purchase.order.record(PO.UNIT.PRICE)<1,
line.item.position>
            vendor.description =
purchase.order.record(PO.VENDOR.DESCRIPTION)<1, line.item.position>
            product.manager = purchase.order.record(PO.PROD.MANAGER)<1,
line.item.position>
            condition = purchase.order.record(PO.CONDITION)<1,
line.item.position>
            production.notes = purchase.order.record(PO.PRODUCTION.NOTES)<1,
line.item.position>
            brokerage.po = purchase.order.record(PO.BROKERAGE.PO)<1,
line.item.position>
            manufacturer.code =
purchase.order.record(PO.MANUFACTURER.CODE)<1, line.item.position>
            trans.code = purchase.order.record(PO.TRANS.CODE)<1,
line.item.position>
            print.flag = purchase.order.record(71)<1, line.item.position>
            license.code = purchase.order.record(PO.LICENSE.CODE)<1,
line.item.position>
            line.item.hold = purchase.order.record(PO.ITEM.HOLD)<1,
line.item.position>
            ncon = purchase.order.record(PO.NCON)<1, line.item.position>
            dpac = purchase.order.record(PO.DPAC)<1, line.item.position>
            revision.level = purchase.order.record(PO.REVISION)<1,
line.item.position>
            back.order.quantity =
purchase.order.record(PO.BACK.ORDER.QUANTITY)<1, line.item.position>
            bums = purchase.order.record(PO.BUMS)<1, line.item.position>
            lsta = purchase.order.record(PO.LSTA)<1, line.item.position>
            change.notes = purchase.order.record(PO.CHANGE.NOTES)<1,
line.item.position>
            line.notes = purchase.order.record(PO.LINE.NOTES)<1,
line.item.position>
            receipts.field = purchase.order.record(39)<1,
line.item.position>
            scheduled.receipts.field = purchase.order.record(34)<1,
line.item.position>
            target.dates.field = purchase.order.record(70)<1,
line.item.position>

*---- Check integrity of key data

            line.errors = ""
            IF NOT(NUM(quantity.ordered)) THEN
               line.errors<-1> = "   The order quantity is invalid."
            END
            IF NOT(NUM(back.order.quantity)) THEN
               line.errors<-1> = "   The back order quantity is invalid."
            END
            IF NOT(NUM(unit.price)) THEN
               line.errors<-1> = "   The unit price is invalid."
            END
            IF LEN(line.errors) THEN
               errors<-1> = "Line item number : " : line.item : " is
incorrect!"
               errors<-1> = line.errors
            END ELSE

*---- Build skeleton detail record

               po.detail.record = ""
               po.detail.record<POD.LINE.ITEM.NUMBER> = line.item
               po.detail.record<POD.PART.NUMBER> = part.number
               po.detail.record<POD.PART.DESCRIPTION> = part.description
               po.detail.record<POD.BUMS> = bums
               po.detail.record<POD.DPAC> = dpac
               po.detail.record<POD.PO.TYPE> = purchase.order.type
               po.detail.record<POD.PMGR> = product.manager
               po.detail.record<POD.VEND.DESCRIPTION> = vendor.description
               po.detail.record<POD.UNIT.PRICE> = unit.price
               po.detail.record<POD.LI.HOLD> = line.item.hold
               po.detail.record<POD.REVISION> = revision.level
               po.detail.record<POD.WO.SEQ.NUMBER> = work.order.sequense
               po.detail.record<POD.DATE.CREATED> = DATE()
               po.detail.record<25> = condition
               po.detail.record<26> = line.notes
               po.detail.record<27> = change.notes

*---- Calculate the status of this line item

               GOSUB calculate.line.item.status:

*---- Build all necessary detail records

               IF there.are.backorders THEN
                  GOSUB build.scheduled.receipt.records:
               END
               IF there.are.receipts THEN
                  GOSUB build.receipt.records:
               END
               IF there.are.excess.receipts THEN
                  GOSUB build.excess.receipt.records:
               END
               IF total.line.item.scheduled.receipt.quantity = 0 THEN
                  GOSUB add.cancel.line:
               END

            END

         WHILE delimiter DO REPEAT

         IF LEN(errors) THEN
            result = "ERRORS"
            IF display.error.messages THEN
               IF Last.Mode = BUILDING.INDEX THEN
                  PRINT
               END
               PRINT "PO# : " : @ID : " has incorrect data.  The problems
are listed below." : @SYS.BELL
               LOOP
                  PRINT REMOVE(errors, delimiter)
               WHILE delimiter DO REPEAT
               PRINT "No further processing of this order is possible until
this problem"
               PRINT "is corrected."
            END
         END ELSE

            BEGIN CASE
               CASE current.order.status = "T"
                  result = ""
               CASE (number.of.backordered.line.items > 0) OR
(number.of.excess.receipt.line.items > 0)
                  IF current.order.status # "B" THEN
                     result = "B"
                  END
               CASE TRUE
                  IF current.order.status # "C" THEN
                     result = "C"
                  END
            END CASE

         END


      END
      RETURN

add.cancel.line:

      scheduled.receipts.field = scheduled.receipts.field
      LOOP
         REMOVE scheduled.receipts FROM scheduled.receipts.field SETTING
minor.delimiter
         REMOVE original.dates FROM target.dates.field SETTING
original.delimiter
         scheduled.receipt.date = FIELD(scheduled.receipts, "*", 1)
         scheduled.receipt.quantity = FIELD(scheduled.receipts, "*", 2)
         original.date = FIELD(original.dates, "*",1)

         po.detail.record<POD.SHIP.DATE> = scheduled.receipt.date
         po.detail.record<POD.QUANTITY> = scheduled.receipt.quantity
         po.detail.record<POD.CUSTOMER.ID> = customer.id
         po.detail.record<POD.PAYDATE> = ""
         po.detail.record<POD.DETAIL.TYPE> = "C"
         po.detail.record<28> = original.date

         detail.record.counter += 1
         temporary.pod.record(detail.record.counter) = po.detail.record

      UNTIL minor.delimiter = 0 REPEAT

      RETURN

calculate.line.item.status:

      total.line.item.received.quantity = 0
      IF LEN(receipts.field) THEN
         receipts.field = receipts.field
         there.are.receipts = TRUE
         LOOP
            REMOVE receipts FROM receipts.field SETTING minor.delimiter
            receipts.quantity = FIELD(receipts, "*", 2)
            total.line.item.received.quantity += receipts.quantity
         WHILE minor.delimiter DO REPEAT
      END ELSE
         there.are.receipts = FALSE
      END

      total.line.item.scheduled.receipt.quantity = 0
      IF LEN(scheduled.receipts.field) THEN
         scheduled.receipts.field = scheduled.receipts.field
         LOOP
            REMOVE scheduled.receipt FROM scheduled.receipts.field SETTING
minor.delimiter
            scheduled.receipt.quantity = FIELD(scheduled.receipt, "*", 2)
            total.line.item.scheduled.receipt.quantity +=
scheduled.receipt.quantity
         WHILE minor.delimiter DO REPEAT
      END

      total.line.item.backorder.quantity =
total.line.item.scheduled.receipt.quantity -
total.line.item.received.quantity

      there.are.backorders = FALSE
      there.are.excess.receipts = FALSE
      BEGIN CASE
         CASE total.line.item.backorder.quantity = 0
         CASE total.line.item.backorder.quantity > 0
            there.are.backorders = TRUE
            number.of.backordered.line.items += 1
         CASE total.line.item.backorder.quantity < 0
            there.are.excess.receipts = TRUE
            number.of.excess.receipt.line.items += 1
      END CASE


      RETURN

build.receipt.records:

      target.dates.quantities = purchase.order.record(70)<1,
line.item.position>
      save.original.date = ""
      GOSUB get.original.schedule.date:
      receipts.total = 0
      receipts.field = receipts.field
      LOOP
         REMOVE receipts FROM receipts.field SETTING minor.delimiter
         receipts.date = FIELD(receipts, "*", 1)
         receipts.quantity = FIELD(receipts, "*", 2)
         receipts.number = FIELD(receipts, "*", 3)
         receipts.payment.flag = FIELD(receipts, "*", 4)

         po.detail.record<POD.SHIP.DATE> = receipts.date
         po.detail.record<POD.QUANTITY> = receipts.quantity
         po.detail.record<POD.CUSTOMER.ID> = customer.id : "*" :
receipts.number
         po.detail.record<POD.PAYDATE> = receipts.payment.flag
         po.detail.record<POD.DETAIL.TYPE> = "S"
         receipts.total += receipts.quantity
         IF receipts.total GT original.quantity THEN
            receipts.total = 0
            GOSUB get.original.schedule.date:
         END
         po.detail.record<28> = original.date

         detail.record.counter += 1
         temporary.pod.record(detail.record.counter) = po.detail.record
      WHILE minor.delimiter DO REPEAT

      date.of.last.receipt = receipts.date
      RETURN

get.original.schedule.date:

      REMOVE original.date.quantity FROM target.dates.quantities SETTING
original.delimiter
      original.date = FIELD(original.date.quantity, "*",1)
      original.quantity = FIELD(original.date.quantity, "*",2)
      IF original.date = "" THEN
         original.date = save.original.date
      END ELSE
         save.original.date = original.date
      END

      RETURN


build.scheduled.receipt.records:

      scheduled.receipts.field = scheduled.receipts.field
      total.scheduled.receipts = 0
      total.receipts = total.line.item.received.quantity    ;* start with
all real receipts
      LOOP
         REMOVE scheduled.receipts FROM scheduled.receipts.field SETTING
minor.delimiter
         REMOVE original.dates FROM target.dates.field SETTING
original.delimiter
         scheduled.receipt.date = FIELD(scheduled.receipts, "*", 1)
         scheduled.receipt.quantity = FIELD(scheduled.receipts, "*", 2)
         original.date = FIELD(original.dates, "*",1)

         total.scheduled.receipts += scheduled.receipt.quantity
         IF total.scheduled.receipts > total.receipts THEN
            backorder.quantity = total.scheduled.receipts - total.receipts
            IF backorder.quantity > total.line.item.backorder.quantity THEN
               backorder.quantity = total.line.item.backorder.quantity
            END
            total.receipts += backorder.quantity  ;* add in scheduled
receipts

            po.detail.record<POD.SHIP.DATE> = scheduled.receipt.date
            po.detail.record<POD.QUANTITY> = backorder.quantity
            po.detail.record<POD.CUSTOMER.ID> = customer.id
            po.detail.record<POD.PAYDATE> = ""
            po.detail.record<POD.DETAIL.TYPE> = "B"
            po.detail.record<28> = original.date

            detail.record.counter += 1
            temporary.pod.record(detail.record.counter) = po.detail.record

         END
      WHILE minor.delimiter DO REPEAT

      RETURN


build.excess.receipt.records:

      po.detail.record<POD.SHIP.DATE> = date.of.last.receipt
      po.detail.record<POD.QUANTITY> =
ABS(total.line.item.backorder.quantity)
      po.detail.record<POD.PAYDATE> = ""
      po.detail.record<POD.DETAIL.TYPE> = "O"
      po.detail.record<28> = original.date

      detail.record.counter += 1
      temporary.pod.record(detail.record.counter) = po.detail.record

      RETURN

write.pod.records:

      FOR I = 1 TO detail.record.counter
         WRITE temporary.pod.record(I) TO Pod.File.Variable, I : '*' : @ID
      NEXT I

      RETURN

delete.pod.records:

      pod.sequence.number = 0
      end.of.pods = FALSE
      LOOP
         pod.sequence.number += 1
         READ dummy FROM Pod.File.Variable, pod.sequence.number : "*" : @ID
ELSE
            end.of.pods = TRUE
         END
      UNTIL end.of.pods DO
         DELETE Pod.File.Variable, pod.sequence.number : "*" : @ID
      REPEAT
      dummy = ""

      RETURN

   END
-------
u2-users mailing list
u2-users@listserver.u2ug.org
To unsubscribe please visit http://listserver.u2ug.org/

Reply via email to