Я пытался написать логику для публикации данных из двух таблиц в ежедневную книгу, в которую будут записываться следующие данные.
1) Мы получим данные за предыдущий деньпоэтому мы опубликуем данные за последний день на сегодня.Например: в среду 26 июня мы опубликуем данные 25 июня.Однако следующие исключения делают его слишком сложным
1.1) если сегодня понедельник, то опубликуйте данные, которые мы получили бы в пятницу.например, в понедельник, 24 июня;мы опубликуем данные за четверг 20 июня, которые были получены в пятницу 21 июня, за пятницу, субботу и воскресенье.то есть 21, 22, 23 июня будут опубликованы те же данные с 20 июня, когда процедура будет выполняться в понедельник, 24 июня.
1.2), если конец месяца и он выпадает на выходные, тогда другая команда отправит данные в пятницу илипоследний рабочий день EOD, но они устанавливают дату как фактическое окончание месяца.Например, если это март 2019 года, 30 и 31 марта - выходные, поэтому размещение должно произойти следующим образом:
1.2.1) в пятницу 29 марта, утром мы опубликуем данные за четверг 28 марта.
1.2.2) В пятницу 29 марта, EOD, мы получим данные, для которых они установят дату на дату последнего месяца, 31 марта.Поэтому, когда мы запустим процедуру с 1 апреля до конца марта, мы опубликуем данные за пятницу, субботу, воскресенье (29, 30, 31 марта).Данные, полученные в пятницу, установлены на 31 марта, поэтому они будут опубликованы на пятницу, субботу, воскресенье (29, 30, 31 марта).
1.3) Если последний день месяца приходится на выходные, а следующий рабочий день - выходной.Например, 2 сентября 2019 года - выходной, а 31 августа и 1 сентября - выходные.Если процедура запускается во вторник 3 сентября, то публикуйте записи данных за 30, 31 августа и 1 сентября с данными, полученными в пятницу, 30 августа, EOD, для которых значение даты установлено как 31 августа.
Это почти вседела делятся по бизнесу.Это слишком запутанно, но было бы здорово, если бы кто-то мог поделиться здесь логикой.
--Query to get data is:
V_SQL := 'SELECT A.ACCOUNT_TYPE, B.FIN_ELEM, A.ORG_UNIT_ID, A.GL_ACCOUNT_ID, B.CMN_COA_ID, B.PROD1, B.PROD2, B.PROD3,
SUM(CURRENT_BAL) AS CB_SUM, SUM(AVG_BAL) AS AB_SUM, B.FLAG1 FROM DAILYGL_TEST A, AL_LOOKUP B '||
'WHERE A.GL_ACCOUNT_ID = B.GL_ACCT AND A.AS_OF_DATE = '||V_DATE_PARAM||
' AND ROWNUM <=15 GROUP BY A.ACCOUNT_TYPE, B.FIN_ELEM, A.ORG_UNIT_ID, A.GL_ACCOUNT_ID,B.CMN_COA_ID, B.PROD1,
B.PROD2, B.PROD3, A.AS_OF_DATE, B.FLAG1';
--V_DATE_PARAM is date for which logic needs to written as per above conditions.
---function to insert data
IF (V_END_BAL <> 0 OR V_AVG_BAL <>0) THEN
IF V_ACCT_TYPE = 1 OR V_ACCT_TYPE = 5 OR V_ACCT_TYPE = 10 OR V_ACCT_TYPE = 90 THEN
V_FIN1 := SUBSTR(V_FIN,1,2) || '100';
DBMS_OUTPUT.PUT_LINE('POST_DAILY_LEDGER..INSIDE 2 IF IN POST_DAILY_GL');
IN_LEDGER_STAT_DAILY(V_IDENTITY_CODE,V_CONSOLIDATION_CD,V_FIN1,V_ORG_UNIT_ID,V_GL_ACCOUNT_ID,V_CMN_COA_ID,
V_PROD1, V_PROD2, V_PROD3,V_DATE,V_SWITCH * V_END_BAL);
IN_LEDGER_STAT_DAILY(V_IDENTITY_CODE,V_CONSOLIDATION_CD,V_FIN,V_ORG_UNIT_ID,V_GL_ACCOUNT_ID,V_CMN_COA_ID,
V_PROD1, V_PROD2, V_PROD3,V_DATE,V_SWITCH * V_AVG_BAL);
ELSE
IN_LEDGER_STAT_DAILY(V_IDENTITY_CODE,V_CONSOLIDATION_CD,V_FIN,V_ORG_UNIT_ID,V_GL_ACCOUNT_ID,V_CMN_COA_ID,
V_PROD1, V_PROD2, V_PROD3,V_DATE,V_SWITCH * V_END_BAL);
--This needs to be run as per above logic. so if it's sep 3rd this will run for aug 30, 31 and sep 1 as per above conditions.
--complete proc for posting is as following
PROCEDURE POST_DAILY_GL(V_RUN_DATE NUMBER DEFAULT 0) AS
V_IDENTITY_CODE CONSTANT NUMBER(6):=112233;
V_CONSOLIDATION_CD CONSTANT NUMBER(3):=100;
-- variables store result of dynamic cursor
V_SQL VARCHAR2(2500);
TYPE V_CURSOR IS REF CURSOR;
seq V_CURSOR;
V_ORG_UNIT_ID LEDGER_STAT_DLY.ORG_UNIT_ID%TYPE;
V_GL_ACCOUNT_ID LEDGER_STAT_DLY.GL_ACCOUNT_ID%TYPE;
V_CMN_COA_ID LEDGER_STAT_DLY. COMMON_COA_ID%TYPE;
V_PROD1 LEDGER_STAT_DLY.PRODUCT_1_ID%TYPE;
V_PROD2 LEDGER_STAT_DLY.PRODUCT_ID%TYPE;
V_PROD3 LEDGER_STAT_DLY.PRODUCT_3_ID%TYPE;
V_DATE DAILYGL.AS_OF_DATE%TYPE;
V_DATE_PARAM DATE;
V_END_BAL NUMBER;
V_AVG_BAL NUMBER;
V_SWITCH NUMBER(1);
V_FLAG AL_LOOKUP.FLAG1%TYPE;
V_FIN AL_LOOKUP.FIN_ELEM%TYPE;
V_FIN1 AL_LOOKUP.FIN_ELEM%TYPE;
V_ACCT_TYPE NUMBER(2);
BEGIN
IF V_RUN_DATE = 0 THEN
SELECT INSTR_AS_OF_DATE INTO V_DATE FROM AS_OF_DATE;
ELSE
V_DATE := TO_DATE(LPAD(V_RUN_DATE, 8, '0'),'mmddyyyy');
END IF;
V_DATE_PARAM := RETURN_DATE(V_DATE);
V_SQL := 'SELECT A.ACCOUNT_TYPE, B.FIN_ELEM, A.ORG_UNIT_ID, A.GL_ACCOUNT_ID, B.CMN_COA_ID, B.PROD1, B.PROD2, B.PROD3,
SUM(CURRENT_BAL) AS CB_SUM, SUM(AVG_BAL) AS AB_SUM, B.FLAG1 FROM DAILYGL_TEST A, AL_LOOKUP B '||
'WHERE A.GL_ACCOUNT_ID = B.GL_ACCT AND A.AS_OF_DATE = '||V_DATE_PARAM||
' AND ROWNUM <=15 GROUP BY A.ACCOUNT_TYPE, B.FIN_ELEM, A.ORG_UNIT_ID, A.GL_ACCOUNT_ID,B.CMN_COA_ID, B.PROD1,
B.PROD2, B.PROD3, A.AS_OF_DATE, B.FLAG1';
DBMS_OUTPUT.PUT_LINE(V_DATE_PARAM);
DBMS_OUTPUT.PUT_LINE(V_SQL);
OPEN seq FOR V_SQL using V_RUN_DATE;
LOOP
V_SWITCH := 1;
FETCH seq INTO
V_ACCT_TYPE,
V_FIN,
V_ORG_UNIT_ID,
V_GL_ACCOUNT_ID,
V_CMN_COA_ID,
V_PROD1,
V_PROD2,
V_PROD3,
V_END_BAL,
V_AVG_BAL,
V_FLAG;
EXIT WHEN seq%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('POST_DAILY_LEDGER.. OPEN SEQ..AFTER FETCH');
-- CHANGE SIGN FOR CREDITS AND ADD 2 RECORDS FOR BS
IF V_FLAG = 'Y' THEN
V_SWITCH := -1;
ELSE
V_SWITCH := 1;
END IF;
IF V_ACCT_TYPE = 5 OR V_ACCT_TYPE = 10 OR V_ACCT_TYPE = 20 OR V_ACCT_TYPE = 35 THEN
V_SWITCH := V_SWITCH * -1;
END IF;
IF (V_END_BAL <> 0 OR V_AVG_BAL <>0) THEN
IF V_ACCT_TYPE = 1 OR V_ACCT_TYPE = 5 OR V_ACCT_TYPE = 10 OR V_ACCT_TYPE = 90 THEN
V_FIN1 := SUBSTR(V_FIN,1,2) || '100';
DBMS_OUTPUT.PUT_LINE('POST_DAILY_LEDGER..INSIDE 2 IF IN POST_DAILY_GL');
IN_LEDGER_STAT_DAILY(V_IDENTITY_CODE,V_CONSOLIDATION_CD,V_FIN1,V_ORG_UNIT_ID,V_GL_ACCOUNT_ID,V_CMN_COA_ID,
V_PROD1, V_PROD2, V_PROD3,V_DATE,V_SWITCH * V_END_BAL);
IN_LEDGER_STAT_DAILY(V_IDENTITY_CODE,V_CONSOLIDATION_CD,V_FIN,V_ORG_UNIT_ID,V_GL_ACCOUNT_ID,V_CMN_COA_ID,
V_PROD1, V_PROD2, V_PROD3,V_DATE,V_SWITCH * V_AVG_BAL);
ELSE
IN_LEDGER_STAT_DAILY(V_IDENTITY_CODE,V_CONSOLIDATION_CD,V_FIN,V_ORG_UNIT_ID,V_GL_ACCOUNT_ID,V_CMN_COA_ID,
V_PROD1, V_PROD2, V_PROD3,V_DATE,V_SWITCH * V_END_BAL);
END IF;
END IF;
END LOOP;
CLOSE seq;
END POST_DAILY_GL;