From a financial/inventory point of view, the external program COSTING is one of the most important programs under the Priority umbrella. For those that don't know, this program calculates the value of every part stored in a given 'accumulator', that in itself stores the inventory of each part in every warehouse at a given date (the program can also calculate for previous accumulators). Unlike the daily costing program, this program saves its data forever and so is extremely useful when wanting to know the value of inventory at a given date (normally the last day of a month).
There is a parameter (ARG) passed to COSTING that determines whether it will be a daily run (deleting previous values) or a monthly run (saving values). In the first case, ARG will equal 4, whereas in the second case, ARG will equal 1.
Until not so very long ago, one could schedule COSTING and it would run automatically, using the most current accumulator. Unfortunately, this behaviour changed a few versions ago, when a scheduled run would fail because it didn't have a date for the accumulator. As this program runs for 14-16 hours on my server, this meant that I would have to get up at 4:15 on a Friday morning, stumble to the computer, connect to the server and start the program.
Eventually I got fed up with this and tried to determine what would be needed to run COSTING automatically on the last accumulator only. Basically a two step procedure is required, but I added a third step to send me email that the procedure has completed. This code does indeed run COSTING automatically, creating a monthly costing.
Stage 10 - SQLI /* TEST_COSTINGACC - No'am, 25/09/25 A cut-down version of COSTINGACC that calculates for the last tzovar only - automatically. Parameters: DAT, type LINE */ :LASTDATE = 0; #include func/FashionCosting SELECT CURDATE INTO :LASTDATE FROM ACCDATES ORIG WHERE COSTFLAG <> 'Y' AND NOT EXISTS (SELECT 'X' FROM ACCDATES ORIG2 WHERE ORIG2.COSTFLAG = 'Y' AND ORIG2.CURDATE > ORIG.CURDATE) ORDER BY CURDATE DESC; /* My stuff */ :CURDATE = 01/01/88; SELECT MAX (CURDATE) INTO :CURDATE FROM ACCDATES; LINK ACCDATES TO :$.DAT; GENMSG 1001 WHERE :RETVAL <= 0; INSERT INTO ACCDATES SELECT * FROM ACCDATES ORIG WHERE CURDATE = :CURDATE; UNLINK ACCDATES; /* Input stage */ SELECT VALUE INTO :STARTDATE FROM LASTS WHERE NAME='COSTSTARTDATE'; :CURDATE = :FIRSTDATE = 0; :COUNT = 0; LINK ACCDATES TO :$.DAT; SELECT MIN(CURDATE), COUNT(*) INTO :CURDATE, :COUNT FROM ACCDATES WHERE CURDATE > 0; UNLINK ACCDATES; SELECT CURDATE INTO :FIRSTDATE FROM ACCDATES WHERE CURDATE > 0 AND COSTFLAG = 'Y' ORDER BY CURDATE; SELECT DTOA(0+:STARTDATE, 'XX/XX/XX') INTO :PAR1 FROM DUMMY; ERRMSG 1 WHERE :FIRSTDATE = 0 AND 0+:STARTDATE <> :CURDATE AND :STARTDATE <> 0; :ENAME = 'COSTINGACC'; :DATE = 0 + :CURDATE; #include func/CostingLog ----------------------------------------------------------------- STAGE 20: COSTING Parameters: ARG, type INT, value 1 MSG, type ASCII DAT, type LINE /* The parameters have to be in this order */ ----------------------------------------------------------------- STAGE 30: SQLI #include func/CostingMpart :PAR1 = '$'; MAILMSG 40 TO EMAIL 'tabula@gmail.com';
No comments:
Post a Comment