| Титов Александр 
 
 
 Joined: 26 Jul 2002
 Posts: 975
 Location: Титов Александр Александрович
 Occupation: Компания БЭСТ
 Interests: Москва
 
 | 
			
				|  Posted: 01 Sep 2005 14:29    Post subject: |   |  
				| 
 |  
				|  	  | garik wrote: |  	  | Хоть и стара тема.Но как здорово было бы посмотреть код этого алгоритма.Может в свете последних тенденций к открытию новых возможностей и поворота лицом к программистам, господа разработчики выложат данный код?  | 
 
 Добрый день!
 Код выложить не проблема (см.ниже). А вот подробно описать - это сложнее. Если кто будет разбираться - готов ответить на вопросы.
 
 
  	  | Code: |  	  | // // Функция ЕСН нужна для формирования справок по социальному налогу
 // в АРМ-е главного бухгалтера. Обрабатывает всех сотрудников предприятия.
 // независимо от установленных фильтров и т.д.
 // Пример:   ЕСН("001","2001.01","2001.04", 0, 100000, "С")
 // "001" - код фонда единого социального налога
 // "2001.01 - период начала обработки
 // "2001.04 - период окончания обработки
 // 0 - налогооблагаемая база от ...
 // 100000 - налогооблагаемая база до ...
 // cPens русские буквы  "С" -  страховая часть
 //                      "Н" -  накопительная часть
 // BYear - год рождения ОТ
 // EYear - год рождения ДО
 // cSex  - пол сотрудника
 // cLgot - признак вычета льготы из налоговой базы
 // nSotr - количество людей имеющих наибольший доход
 // функция возвращает массив из четырех элементов:
 // aRet[1] - общий облагаемый доход обрабатываемых сотрудников
 // aRet[2] - количество сотрудников
 // aRet[3] - общая сумма льготы по сотрудникам
 // aRet[4] - общая сумма начисления в фонд по всем сотрудникам
 // aRet[5] - общая сумма дохода обрабатываемых сотрудников
 //
 Function N4_2( cFond, cBPer, cEPer, SM1, SM2, cPens, BYear, EYear, cSex, cLgot, nSotr )
 Local aPens    := { {"Н","НАКОП"},;
 {"С","СТРАХ"};
 }
 Local aSexL    := {{"М","1"},{"Ж","2"}}
 Local nPens
 Local cTNum
 Local aRet     := { 0, 0, 0, 0, 0 }
 Local aRetSotr := {}
 Local aBases   := {"CodeInc","Arc_Inc","IncStaff", "CardSpri", "CardsSec"}
 // если не задан первый параметр - возвращаем нули
 if Empty( cFond )
 Return aRet
 endif
 // если период начала не задан, то он берется как январь года,
 // текущего расчетного периода из зарплаты.
 If( Y_Nil(cBPer) .OR. Empty(cBPer), cBPer := Left( S_PERIOD, 4) + ".01", NIL )
 // если период окончаняи не задан, то он берется как текущий
 // расчетный из зарплаты
 If( Y_Nil(cEPer) .OR. Empty(cEPer), cEPer := S_PERIOD, NIL )
 // если период начала обработки больше периода окончания, то возвращаем нули.
 if cBPer > cEPer
 Return aRet
 endif
 
 cPens := if( Y_Type(cPens, "C") .AND. Len(cPens) == 1 .AND.;
 ( nPens := ASCAN(aPens, {|a|a[1] == cPens} ) ) <> 0,;
 aPens[nPens,2],;
 NIL;
 )
 cSex  := if( Y_Type(cSex, "C") .AND. Len(cSex) == 1 .AND.;
 ( nPens := ASCAN( aSexL, {|a,i|a[1] == cSex} ) ) <> 0 ,;
 aSexL[nPens,2],;
 NIL;
 )
 
 if( Y_Type(BYear, "N") .AND. !Empty(BYear), NIL, BYear := NIL )
 if( Y_Type(EYear, "N") .AND. !Empty(EYear), NIL, EYear := NIL )
 SM1   := if( Y_Nil(SM1) .OR. Empty(SM1), NIL, if( Y_Type(SM1,'C'), Val( SM1 ), SM1 ) )
 SM2   := if( Y_Nil(SM2) .OR. Empty(SM2), 9999999999999999, if( Y_Type( SM2,'C'), Val( SM2 ), SM2 ) )
 
 DbOpenBases( aBases )
 
 
 DbxEval( "CardSpri", "01",,,;
 {|a|;
 a := S_ESN( cFond, cBPer, cEPer, cPens, cLgot ),;
 IF( ( Y_Nil(SM1) .OR. a[1] >= SM1 ) .AND. a[1] <= SM2,;
 If( N_Nil(nSotr),;
 AADD( aRetSotr, a ),;
 AEval( a, {|x,i|aRet[i] += x });
 ),;
 NIL;
 );
 },;
 {|| Empty( FiGet(STNum) ) .AND.;
 ( Y_Nil(cSex)  .OR. ( CardsSec->SEX == cSex ) ) .AND.;
 ( Y_Nil(BYear) .OR. ( YEAR(CardsSec->BIRTHDATE) >= BYear ) ) .AND.;
 ( Y_Nil(EYear) .OR. ( YEAR(CardsSec->BIRTHDATE) <= EYear ) );
 },,;
 {|| DBSetRelation( "CardsSec", {|| UPPER(TNUM)},"UPPER(TNUM)")},;
 {|| DBClearRelation()};
 )
 // Возврат суммы дохода (максимальной) по заданному количеству людей
 If N_Nil(nSotr) .AND. Y_Type(nSotr, "N") .AND. nSotr > 0
 ASort( aRetSotr,,, {|x,y|x[1] > y[1]} )
 AEval( aRetSotr, {|a|AEval( a, {|x,i|aRet[i] += x}) }, 1, nSotr)
 EndIf
 DBCloseBases( aBases )
 
 Return( aRet )
 
 
 
 // обработка данных по фонду социального налога для конкретного сотрудника
 // Используется из АРМ Главного бухгалтера ОБ.СУМ_ЕСН(cFond, cBPer, cEPer, cPens, cLgot)
 // cFond        - код фонда (или массив кодов)
 // cBPer, cEPer - интервал за который необходимо собрать данные
 // cPens        - данные по пенсионному накопительная или страховая
 // cLgot        - признак вычета льготы из налоговой базы
 Function S_ESN( cFond, cBPer, cEPer, cPens, cLgot )
 
 Local aPens    := { {"2", "НАКОП"},;
 {"1", "СТРАХ"};
 }
 Local nPens
 Local aRett    := { 0, 0, 0, 0, 0}
 Local cTNum    := CardSpri->TNum
 Local bFor     := If( Y_Type(cFond, "A"),{|| ASCAN( cFond,{|x|Upper(FiGet(Fond)) == Upper(x)}) <> 0},{||Upper( FiGet(Fond) ) == Upper( cFond )})
 Local bWork    := {|a, l|;
 a := Any("CodeInc", "IDCode", FiGet(IDCodeInc), {"CodeInCTG", "TaxIncCtg"} ),;
 l := ( Empty(cPens) .OR. a[2] == cPens ),;
 if( a[1] == '00', ( aRett[1] += FiGet(SummaInc), aRett[5] += FiGet(Summa)), NIL ),;
 if( a[1] == '02', aRett[3] += FiGet(Summa), NIL ),;
 if( l .AND. a[1] == '20' .AND. ( Empty(a[2]) .OR. !Empty(cPens) ),;
 aRett[4] += FiGet(Summa), NIL );
 }
 
 cPens := if( Y_Type(cPens, "C") .AND. (nPens := ASCAN( aPens, {|a|a[2] == cPens} )) <> 0,;
 aPens[nPens,1],;
 "";
 )
 // если период начала не задан, то он берется как январь года,
 // текущего расчетного периода из зарплаты.
 PV_Init(@cBPer, @cEPer)
 
 If( Y_Nil(cBPer) .OR. Empty(cBPer), cBPer := Left( S_PERIOD, 4) + ".01", NIL )
 // если период окончаняи не задан, то он берется как текущий
 // расчетный из зарплаты
 If( Y_Nil(cEPer) .OR. Empty(cEPer), cEPer := S_PERIOD, NIL )
 // если период начала обработки больше периода окончания, то возвращаем нули.
 if cBPer > cEPer
 Return aRett
 endif
 
 If cBPer < S_PERIOD
 DbxEval( "Arc_Inc", "TNUM1",,{"UPPER(TNUM+FPERIOD)", Upper(cTNum+cBPer), Upper(cTNum+cEPer)},;
 bWork, bFor;
 )
 EndIf
 If cEPer >= S_PERIOD .AND. ( CardSpri->SumIn != 0 .OR. CardSpri->SumOut != 0 )
 DbxEval( "IncStaff", "TNUM1",,{"UPPER(TNUM)", Upper(cTNum)}, bWork, bFor )
 EndIf
 if( ( aRett[3] := Min( aRett[1], aRett[3] ) ) <= 0, aRett[3] := 0, NIL)
 aRett[1] := aRett[1] - if( Empty(cPens) .AND. Empty(cLgot), aRett[3], 0 )
 aRett[2] := If( aRett[1] == 0 .AND. aRett[3] == 0 .AND. aRett[4] == 0, 0, 1)
 Return aRett
 | 
 _________________
 С уважением, Александр Титов, Компания БЭСТ, Москва, отдел разрабо
 |  |