create or replace procedure     S_SV_CALC_OST 
        
                   
 (                  
  v_nCategOID number,                  
  v_nPlanOID  number,                  
  v_dBeg      date,                  
  v_dEnd      date,                  
  v_nFilialID number,                  
  v_nPL1      number,                  
  v_nacValID  number         
  )       
         
AS    
  PRAGMA AUTONOMOUS_TRANSACTION;           
    
  v_DateAct date;      
  v_D4000 date;    
  v_D1990 date;     
  v_dDate date;    
      
  v_SID number(12);     
  v_curr_org number(12);    
  v_calc_org number(12);    
  v_OpenDay number(12);      
  v_ReCalc number(12);    
      
  v_mMessage varchar2(250);     
  v_iLockID varchar2(250);    
  v_aExecText varchar2(500);     
  v_nIsPril5ContextCalc number(12); 
BEGIN     
     
  S_PROGRESS (1000001,'Расчет баланса',0,0);      
  v_SID := to_number(sys_context('USERENV','SID'));      
  v_D4000 := to_date('12.12.4000','DD.MM.YYYY');           
  v_D1990 := to_date('01.01.1990','DD.MM.YYYY');       
  v_ReCalc := 1; 
      
  /* Запомним текущий контекст */        
  v_curr_org := S_GET_ORG();      
            
  for q in (select A.ID      
                  ,dbo.GS_SV_OSS_ATTRS('NAME',A.ID,v_dBeg) as NAME    
                  ,A.F_ONLINE      
                  ,A.SUBSCRIBERID      
                  ,A.MFID    
                  ,nvl(A.BASE_NAME,'') as BASE_NAME    
                  ,nvl(A.LOADNEV,0) as LOADNEV    
                  ,A.DDLOADNEV    
                  ,nvl(A.CHECKOPENDAY,0) as CHECKOPENDAY          
              from SV_OSS A              
             where A.ULEVEL = 3      
               and A.ID in (select B.FILIALID      
                              from SV_OSS_CONT_F B      
                             where B.VNESHID = v_nFilialID))              
  LOOP                 
        
          
  /*  v_ReCalc := S_SV_CHECK_DATEACT(1,v_dBeg,v_dEnd,q.ID);*//*проверка актуальностия в ядре*/     
    if v_ReCalc = 0 then    
      v_calc_org := S_SV_GET_CALC_ORG();  /* Установка контекста филиала */          
      S_SV_SET_ORG (v_calc_org);            
      v_ReCalc := S_SV_CHECK_DATEACT(2,v_dBeg,v_dEnd,q.ID);/*проверка актуальностия в отборе*/     
      S_SV_SET_ORG (v_curr_org); /* Восстановим контекст */          
    end if;     
    if  v_ReCalc = 1 then/*проверка актуальностия в ядре*/     
    
    /* Удаляются блокировки "мертвых" процессов и текущего */      
      delete from SV_CALC_LOCKID      
      where not exists (select A.SID from DEF_CONTEXT A where A.SID = SV_CALC_LOCKID.SPID)      
         or SPID = v_SID;     
           
      S_PROGRESS (1000001,'  Расчет подразделения "'||q.NAME||'"',0,0);                    
            
  /* ==================================================================== */        
  /*                            1. ПРОВЕРКИ                               */        
  /* ==================================================================== */               
      if (q.LOADNEV = 1) and (q.DDLOADNEV is null) then        
        Raise_Application_Error(-20202,'Не указана дата "Загружать невязки с даты"');        
      end if;             
       
      if q.CHECKOPENDAY = 1 then /*Проверка наличия открытых дней */        
       
        v_calc_org := S_SV_GET_CALC_ORG();  /* Установка контекста филиала */          
        S_SV_SET_ORG (v_calc_org);               
              
            
        v_dDate := v_dEnd - 1;        
          
        select count(*) into v_OpenDay from RKO_DAY where DDAY <=v_dDate;        
         
        S_SV_SET_ORG (v_curr_org); /* Восстановим контекст */           
            
        if v_OpenDay > 0 then        
          v_mMessage := 'В подразделении "'||q.NAME||'" есть незакрытые операционные дни.';        
          S_PROGRESS (1000001,v_mMessage,0,0);         
        end if;             
      end if;                                                                                            
  /* ==================================================================== */        
  /*                2. АКТУАЛИЗАЦИЯ ИСТОЧНИКА С БЛОКИРОВКОЙ               */        
  /* ==================================================================== */         
      v_iLockID := 'S_SV_PREPARE_FILIAL' || to_char(q.ID) /*||'OTB_LS'*/;        
      S_SV_LOCK (1,v_iLockID);    
        
      v_calc_org := S_SV_GET_CALC_ORG(); 
      S_SV_SET_ORG(v_calc_org); /*установим контекст филиала*/    
        
      S_PROGRESS (1000001,'Актуализация счетов',0,0);     
      v_aExecText := 'BEGIN '||'S_OTB_LS'||'(:v_dBeg,:v_dEnd,:v_nacValID,:v_filialID,:v_svID); END;';     
      begin     
        execute immediate v_aExecText using v_dBeg,v_dEnd,v_nacValID,q.ID,q.SUBSCRIBERID;     
          exception     
            when others then     
           Raise_Application_Error(-20202,'Ошибка в процедуре подготовки данных "'||'Актуализация счетов'|| 
                                           '" Имя процедуры: '||'S_OTB_LS'||' Ошибка: '||SQLERRM);           
      end;     
    COMMIT;                       
   
          
/*      S_SV_LOCK (2,v_iLockID);       */ 
          
        
      begin   /* Получим дату актуальности в источнике*/                   
        select nvl(DACT,v_D1990) into v_DateAct from OTB_SUBSCRIBER where SUBSCRIBER_ID = q.SUBSCRIBERID;               
         exception               
          when NO_DATA_FOUND then               
          Raise_Application_Error(-20202,'Регистрация подписчика данных не найдена');               
      end;               
                
      v_mMessage := 'Дата актуальности источника: '||to_char(v_DateAct,'DD.MM.YYYY');               
      S_PROGRESS (1000001,v_mMessage,0,0);               
                
           
     /* Установим дату актуальности с 3 типом */     
/*      v_iLockID := 'S_SV_PREPARE_FILIAL' || to_char(q.ID) ||'SV_ACT';       
      S_SV_LOCK (1,v_iLockID);      */               
      S_SV_SET_DATEACT (1000000,q.ID,3,0,null,v_DateAct);     
/*      S_SV_LOCK (2,v_iLockID);      */ 
          
    /* ==================================================================== */            
    /*                           ЛИЦЕВЫЕ СЧЕТА                              */            
    /* ==================================================================== */            
/*      v_iLockID := 'S_SV_PREPARE_FILIAL' || to_char(q.ID) ||'OTB_LS';            
      S_SV_LOCK (1,v_iLockID);   */      
                    
      S_SV_LOAD_ONLINE_LS(v_dBeg,v_dEnd,v_nacValID,q.ID,q.SUBSCRIBERID,1,null,1);        
                
/*      S_SV_LOCK (2,v_iLockID);     */                 
                     
/*      v_iLockID := 'S_SV_PREPARE_FILIAL' || to_char(q.ID) ||'OTB_LLC';            
      S_SV_LOCK (1,v_iLockID);        */ 
                    
      S_SV_LOAD_ONLINE_LC(v_dBeg,v_dEnd,v_nacValID,q.ID,q.SUBSCRIBERID,1,null,1);         
              
/*      S_SV_LOCK (2,v_iLockID);          */ 
                      
      /* ==================================================================== */            
      /*             Расчет балансовых счетов, округления и невязок           */            
      /* ==================================================================== */                                            
/*      v_iLockID := 'S_SV_PREPARE_FILIAL' || to_char(q.ID) ||'SV_BLC';            
      S_SV_LOCK (1,v_iLockID);        */ 
             
      IF v_DateAct < v_dEnd THEN             
         S_SV_CALC_LS2BS (1000000,q.ID,v_nacValID,v_dEnd); /* л/с -> б/с*/             
      END IF;             
              
      if (S_SV_CHECK (201,null,S_CONTEXT(1),SYSDATE) = 0 or v_nPL1 <> 0) then            
       
        S_SV_CALC_BSROUND (1000000,q.ID,4,v_dBeg,v_dEnd,v_nacValID,1);  
              
        /* saow 21 мая 2019: оптимизация Приложения 5 для НКЦ: невязки по лицевым счетам не разбрасываем: */ 
        begin 
          select count(*)  
            into v_nIsPril5ContextCalc 
            from SV_FORM_PARAMS 
           where SID = v_SID 
             and CATOID is null 
             and P1 = 'Pril_5'; 
        exception 
          when NO_DATA_FOUND then v_nIsPril5ContextCalc := 0; 
        end; 
                         
        if v_nIsPril5ContextCalc = 0 then 
          S_SV_CALC_LSROUND (1000000,q.ID,4,v_dBeg,v_dEnd,v_nacValID,1);             
        end if; 
                     
      end if;              
 
      S_SV_LOCK (2,v_iLockID);        
                       
      /* ==================================================================== */            
      /*                 Перенос невязок по балансовым счетам                 */            
      /* ==================================================================== */            
      v_iLockID := 'S_SV_PREPARE_FILIAL' || to_char(q.ID) ||'SV_NEV';            
      S_SV_LOCK (1,v_iLockID);         
                    
      S_SV_LOAD_ONLINE_BS_NEV(v_dBeg,v_dEnd,v_nacValID,q.ID,q.SUBSCRIBERID,1,null,1);         
             
      S_SV_LOCK (2,v_iLockID);    
         
      select S_SV_GET_ACT(q.ID,v_nPlanOID,3,0,null) into v_DateAct from dual;      
      if v_DateAct < v_dEnd then       
        S_PROGRESS (1000001,'Данные по подразделению "'||q.NAME||'" НЕ АКТУАЛЬНЫ. (Текущая дата актуальности: '||to_char(v_DateAct,'dd.mm.yyyy')||')',0,0,1);       
      end if;    
  else     
      v_mMessage := 'Данные по балансу на '||to_char(v_dEnd,'DD.MM.YYYY')||' актуальны';               
      S_PROGRESS (1000001,v_mMessage,0,0);       
                       
  end if;  /*хвост условия о необходимости расчета*/        
                   
  END LOOP;     
  COMMIT;                  
END S_SV_CALC_OST;       
      
      
 
