import com.haulmont.chile.core.model.MetaClass
import com.haulmont.cuba.core.global.*;
import com.groupstp.rtneo.entity.*;
import com.groupstp.rtneo.service.AccrualService
import com.groupstp.rtneo.service.CompanyService
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.math.MathContext;
//Contract qwe = dataManager.load(Contract.class).query('select e from rtneo$Contract e where e.id=:id').parameter("id",UUID.fromString('3a67362c-7103-40ea-7f0b-d0491c927268')).one()
	def params =['number':2299874]
def service = AppBeans.get(AccrualService.NAME)
def companyService = AppBeans.get(CompanyService.NAME)
List<Accrual> accruals = dataManager.load(Accrual)
        .query('select a from rtneo$Accrual a where a.documentNumber = :documentNumber order by a.period asc')
        .parameter("documentNumber", params.number)
        .view('accrual-bill')
        .list()
	
    
if (accruals.size() == 0) {
    throw new RuntimeException(String.format("Начислений по номеру %s не найдено", params.number))
}
 
String inn = dataManager.loadValue('select e.contractPosition.contragent.inn from rtneo$Accrual e where e.documentNumber = :documentNumber', String.class)
 .parameter("documentNumber", params.number)
 .one()
//List<Accrual> corrAcc = dataManager.load(Accrual)
//        .query('select a from rtneo$Accrual a where a.contractPosition.contract.id = :id and a.period=:per order by a.period asc')
//        .parameter("id", params.corr.getId())
//        .parameter("per",accruals.get(0).getPeriod()) 
//        .view('accrual-bill')
//        .list()
List<Acts> acts = dataManager.load(Acts.class)
        .query('select a from rtneo$Acts a where a.inn = :inn and a.period = :period')
        .parameter("inn", inn)
        .parameter("period" ,accruals.get(0).getPeriod())
        .view("_local")
        .list()
Accrual accrual = accruals.get(0)
def result = new LinkedHashMap()
def head = new LinkedHashMap()
head['number'] = String.valueOf((int) params.number)
head['corrNumber'] = String.valueOf((int) params.number)+'/1'
//a.kotvinskiy /--
//head['billDate'] = getTextDate(accrual.getDocumentDate() == null ? accrual.getCreateTs() : accrual.getDocumentDate())
def monthesRP = ['января','февраля','марта','апреля','мая','июня','июля','августа','сентября','октября','ноября','декабря']
//Берем период счета
Date billDate = accrual.getPeriod();
Date corrDate = new Date();
if (billDate==null){
    billDate = accrual.getCreateTs()
}
Calendar cal = Calendar.getInstance()
cal.setTime(billDate);
//Устанавливаем дату на последний день предыдущего месяца
//cal.add(Calendar.MONTH, -1);
//Текущего месяца
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
head['billDate'] = cal.get(Calendar.DAY_OF_MONTH).toString()
head['billDate']+=" "+monthesRP[cal.get(Calendar.MONTH)]
head['billDate']+=" "+cal.get(Calendar.YEAR).toString()+" г."
def billDateNum = ''+cal.get(Calendar.DATE)+'.'+(cal.get(Calendar.MONTH)+1)+'.'+cal.get(Calendar.YEAR)
//a.kotvinskiy --/
cal.setTime(corrDate);
head['corrDate'] = cal.get(Calendar.DAY_OF_MONTH).toString()
head['corrDate']+=" "+monthesRP[cal.get(Calendar.MONTH)]
head['corrDate']+=" "+cal.get(Calendar.YEAR).toString()+" г."
Contragent contragent = accrual.getContragent()
head['name'] = contragent.getName();
head['shortName'] = contragent.getShortName();
if (head['shortName']==null){
    head['shortName'] = head['name'];
}
head['inn'] = contragent.getInn();
head['kpp'] = contragent.getKpp();
head['legalAddress'] = contragent.getLegalAddress();
def contract = accrual.contractPosition.contract
if (contract.mainContract != null)
    contract = contract.mainContract
def company = contract.company
//a.kotvinskiy /--
//def companyRequisites = companyService.getCompanyRequisites(company, contract.date)
def companyRequisites = companyService.getCompanyRequisites(company, billDate)
//a.kotvinskiy --/
head << ['contractNumber' : contract.number
         ,'contractDate' : contract.date
         ,'companyShortName' : company.shortName
         ,'companyInn':company.inn
         ,'companyKpp':companyRequisites.kpp
         ,'companyLegalAddress':companyRequisites.legalAddress
         ,'companyPhone':company.phone
         ,'companyBankName':companyRequisites.bankName
         ,'companyRcbic':companyRequisites.rcbic
         ,'companyCorrespondentAccount':companyRequisites.correspondentAccount
         ,'companyBankAccount':companyRequisites.bankAccount
]
result['head'] = head;
result['footer'] = [
        'billDate' : billDateNum
        ,'number' : params.number
        ,'shortName' : head['shortName']
        ,'inn' : contragent.inn
        ,'kpp' : contragent.kpp
        ,'companyShortName' : company.shortName
        ,'companyInn':company.inn
        ,'companyKpp':companyRequisites.kpp
        ,'companyManager' : getShortFio(companyRequisites.getManagerName())
        ,'companyManagerTitle':companyRequisites.managerTitle
        ,'companyAccountManager' : getShortFio(companyRequisites.managerName)]
def items = new LinkedHashMap()
items.put('amount',0.0)
items.put('priceWoNds',0.0)
items.put('totalSumWoNds',0.0)
items.put('NdsSum',0.0)
items.put('totalSum',0.0)
items.put('amountCorr',0.0)
items.put('priceWoNdsCorr',0.0)
items.put('totalSumWoNdsCorr',0.0)
items.put('NdsSumCorr',0.0)
items.put('totalSumCorr',0.0)
items.put('decrease',0.0)
items.put('increase',0.0)
items.put('NdsInc',0.0)
items.put('NdsDec',0.0)
items.put('totalSumInc',0.0)
items.put('totalSumDec',0.0)
//
ViewRepository vRep = AppBeans.get(ViewRepository.NAME)
View accrualView = vRep.getView(Accrual.class, "accrual-bill");
accrualView.addProperty("contractPosition", vRep.getView(ContractPosition.class, "_minimal").addProperty("contragentRealEstate", vRep.getView(ContragentRealEstate.class, "_minimal")));
//
fillItems(items, accruals, corrAcc)
result['items'] = items
def р = items['totalSumDec'].toString().split(',')
result['totals'] = ['increaseTotal':items['increase'],
'NdsIncTotal':items['NdsInc'],
'totalIncSum':items['totalSumInc'],
'decreaseTotal':items['decrease'],
'NdsDecTotal':items['NdsDec'],
'totalDecSum':getRussianNumber((Double)items['totalSumDec'],2)
]
return [result]
def fillItems(LinkedHashMap items, List<Accrual> accs, List<Accrual> corrs){
    for(Accrual a:accs){
            def tsw=a.getTotalSum().add(items['totalSumWoNds']).subtract(a.getNdsSumBase())
     
        items['amount']= a.getAmount().add(items['amount'])
        items['priceWoNds']=(a.getPrice()/6*5)
        items['totalSumWoNds']=tsw
        items['NdsSum']=a.getNdsSumBase().add(items['NdsSum'])
        items['totalSum']=a.getTotalSum().add(items['totalSum'])
       
}
for(Accrual a:corrs){
       def tsw=a.getTotalSum().add(items['totalSumWoNdsCorr']).subtract(a.getNdsSumBase())
 items['amountCorr']= a.getAmount().add(items['amountCorr'])
        items['priceWoNdsCorr']=a.getPrice().add(items['priceWoNdsCorr']).subtract(a.getPrice()/6)
        items['totalSumWoNdsCorr']=tsw
        items['NdsSumCorr']=a.getNdsSumBase().add(items['NdsSumCorr'])
        items['totalSumCorr']=a.getTotalSum().add(items['totalSumCorr'])
}
items['decrease']=items['totalSumWoNdsCorr']<items['totalSumWoNds']?items['totalSumWoNds']-items['totalSumWoNdsCorr']:0
items['increase']=items['totalSumWoNdsCorr']>items['totalSumWoNds']?items['totalSumWoNdsCorr']-items['totalSumWoNds']:0
items['NdsInc']=items['NdsSumCorr']>items['NdsSum']?items['NdsSumCorr']-items['NdsSum']:0
items['NdsDec']=items['NdsSum']>items['NdsSumCorr']?items['NdsSum']-items['NdsSumCorr']:0
items['totalSumInc']=items['totalSum']<items['totalSumCorr']?items['totalSumCorr']-items['totalSum']:0
items['totalSumDec']=items['totalSum']>items['totalSumCorr']?items['totalSum']-items['totalSumCorr']:0
      
   
}
def getRussianNumber(Double number, int precision = 2) {
    DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance()
    symbols.setGroupingSeparator((char) ' ')
    symbols.setDecimalSeparator((char) ',')
    
    String formatString = '';
    switch(precision){
        case 1:
            formatString = '###,###,##0.0';
            break;
        case 2:
            formatString = '###,###,##0.00';
            break;
        case 3:
            formatString = '###,###,##0.000';
            break;
        case 4:
            formatString = '###,###,##0.0000';
            break;
        case 5:
            formatString = '###,###,##0.00000';
            break;
    }
    DecimalFormat formatter = new DecimalFormat(formatString, symbols);
    return(formatter.format(number));
    
//    if (precision == 2){
//        DecimalFormat formatter = new DecimalFormat('###,###.##', symbols)
//        return(formatter.format(number));
//    } else {
//        DecimalFormat formatter = new DecimalFormat('###,###.###', symbols)
//        return(formatter.format(number));
//    }
    
}
def getTextPeriod(Date date) {
    def result=''
    if (date != null) {
        def monthesRP = ['январь','февраль','март','апрель','май','июнь','июль','август','сентябрь','октябрь','ноябрь','декабрь']
        Calendar cal = Calendar.getInstance()
        cal.setTime(date);
        result+=monthesRP[cal.get(Calendar.MONTH)]
        result+=" "+cal.get(Calendar.YEAR).toString()+" г."
    }
    return result
}
def getTextDate(Date date) {
    def result=''
    if (date != null) {
        def monthesRP = ['января','февраля','марта','апреля','мая','июня','июля','августа','сентября','октября','ноября','декабря']
        Calendar cal = Calendar.getInstance()
        cal.setTime(date);
        result = cal.get(Calendar.DAY_OF_MONTH).toString()
        result+=" "+monthesRP[cal.get(Calendar.MONTH)]
        result+=" "+cal.get(Calendar.YEAR).toString()+" г."
    }
    return result
}
def getNN(BigDecimal value) {
    return value == null ? BigDecimal.ZERO : value;
}
def getShortFio(String fio) {
    if (fio == null) return ""
    String pattern = "(\\S+\\s)(\\S{1})\\S+\\s(\\S{1})\\S+"
    String str = fio.replaceAll(pattern, '$1$2.$3.')
    return str
}