import com.haulmont.chile.core.model.MetaClass
import com.haulmont.cuba.core.global.*;
import com.groupstp.rtneo.entity.*;
import com.haulmont.cuba.core.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;
import java.util.stream.Collectors;
//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 service = AppBeans.get(AccrualService.NAME)
def companyService = AppBeans.get(CompanyService.NAME)
//Параметры
//def params =['number':2368210]
//Результаты
def result = new LinkedHashMap()
//Переменные
def monthesRP = ['января','февраля','марта','апреля','мая','июня','июля','августа','сентября','октября','ноября','декабря']
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))
}
KeyValueEntity value = dataManager.loadValues('select a.contragent.inn, a.contragent.kpp from rtneo$Accrual a where a.documentNumber = :number')
.properties("inn", "kpp")
.parameter("number", params.number)
.optional()
.orElse(null);
String inn = value.getValue("inn");
String kpp = value.getValue("kpp");
Accrual accrual = accruals.get(0)
/**
*Заполняем шапку
*/
def head = new LinkedHashMap()
//Acts act = getActualAct(accruals, inn, kpp, accrual.getPeriod())
Acts act = null
Acts adjustmen = null
List<Acts> acts = getAllAct(inn, kpp, accrual.getPeriod())
//Нужно сделать проверку acts на пустоту
boolean isAdj = false
acts.each({if(it.getAdjustments() != null)isAdj = true})
//head['number'] = String.valueOf((int) params.number)
//str = str.replaceAll("[^0-9]+", "");
//Сумма начислений
BigDecimal accSum = BigDecimal.ZERO
accruals.each({accSum = accSum.add(it.getTotalSum())})
accSum = accSum.setScale(2, BigDecimal.ROUND_UP);
if(!isAdj){
act = acts.get(0)
actSum = act.getSum().add(act.getSum_nds());
if(!accSum.equals(actSum)){
head['number'] = act.getNumber()
head['corrNumber'] = String.valueOf((int) params.number)
}
}else{
onlyActs = acts.stream().filter({e->e.getAdjustments() == null}).collect(Collectors.toList())
adjustmens = acts.stream().filter({e->e.getAdjustments() != null}).collect(Collectors.toList())
adjustmen = adjustmens.get(adjustmens.size()-1)
act = acts.get(0)
adjustmenSum = adjustmen.getSum().add(adjustmen.getSum_nds());
// if(accSum.equals(adjustmenSum)){
if(accSum.subtract(adjustmenSum).compareTo(BigDecimal.valueOf(0.02)) <=0 || accSum.subtract(adjustmenSum).compareTo(BigDecimal.valueOf(-0.02)) >=0){
head['number'] = act.getNumber()
head['corrNumber'] = adjustmen.getNumber().replaceAll("[^0-9]+", "")
}else{
head['number'] = adjustmen.getNumber().replaceAll("[^0-9]+", "")
head['corrNumber'] = String.valueOf((int) params.number)
act = adjustmen
adjustmen = null
}
}
//if(act.getAdjustments() == null){
// //Сумма начислений
// BigDecimal accSum = BigDecimal.ZERO
// accruals.each({accSum = accSum.add(it.getTotalSum())})
// accSum = accSum.setScale(2, BigDecimal.ROUND_UP);
//
// def actSum = act.getSum().add(act.getSum_nds());
//
// if(accSum.equals(actSum)){
//
// }
// head['number'] = act.getNumber()
// head['corrNumber'] = String.valueOf((int) params.number)
//}
//if(act.getAdjustments() != null){
// Acts selling = getActualAct(accruals, inn, kpp, accrual.getPeriod(), true)
// head['number'] = act.getNumber()
// head['corrNumber'] = selling.getNumber().replaceAll("[^0-9]+", "")
//}
//if(act.getAdjustments() == null && act.getSum != accrusls.getSum)
//
//
//head['number'] = String.valueOf((int) params.number)
//head['corrNumber'] = act.getNumber().replaceAll("[^0-9]+", "")
//a.kotvinskiy /--
//head['billDate'] = getTextDate(accrual.getDocumentDate() == null ? accrual.getCreateTs() : accrual.getDocumentDate())
//Берем период счета
Date billDate = getAccDate(accrual)
//Дата корректировки
Date corrDate = getCorrDate(accrual)
Calendar cal = Calendar.getInstance()
cal.setTime(billDate);
//Устанавливаем дату на последний день предыдущего месяца
//cal.add(Calendar.MONTH, -1);
//Текущего месяца
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.getCompany()
//a.kotvinskiy /--
//def companyRequisites = companyService.getCompanyRequisites(company, contract.date)
//def companyRequisites = companyService.getCompanyRequisites(company, billDate)
//a.kotvinskiy --/
def companyRequisites = getCompanyRequisites(company)
//a.kotvinskiy --/
CompanyRequisites getCompanyRequisites(Company company){
return dataManager.loadValue('select e from rtneo$CompanyRequisites e where ' +
'e.company.id = :company order by e.dateStart desc', CompanyRequisites.class)
.parameter("company", company)
.list()
.stream()
.findFirst()
.orElse(null);
}
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;
/**
* Заполняем подвал
*/
String reason = getReason(accrual);
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)
,'reason': reason]
//
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")));
//
//Acts act = getActualAct(accruals, inn, kpp, accrual.getPeriod())
def items
if(act != null && adjustmen != null){
items = fillItems(act, adjustmen)
}else{
items = fillItems(accruals, act)
}
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 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));
}
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
}
/**
*
*/
private Date getCorrDate(def accrual){
Date corrDate = new Date()
Calendar accrualPeriod = Calendar.getInstance()
accrualPeriod.setTime(accrual.getPeriod());
// accrualPeriod.set(Calendar.DAY_OF_MONTH, accrualPeriod.getActualMaximum(Calendar.DAY_OF_MONTH));
Date dateContract = dataManager.loadValue('select e.contractPosition.contract.date from rtneo$Accrual e where e.documentNumber = :documentNumber', Date.class)
.parameter("documentNumber", accrual.getDocumentNumber())
.one()
if(dateContract.after(accrualPeriod.getTime())){
// _("Выводим дату контракта")
corrDate = dateContract;
}else{
// _("Выводим дату окончания периода начисления")
Calendar cal = Calendar.getInstance()
cal.setTime(accrual.getPeriod())
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH))
corrDate = cal.getTime()
}
return corrDate;
}
private Date getAccDate(def accrual){
Date accDate = new Date()
Calendar accrualPeriod = Calendar.getInstance()
accrualPeriod.setTime(accrual.getPeriod());
accrualPeriod.set(Calendar.DAY_OF_MONTH, accrualPeriod.getActualMaximum(Calendar.DAY_OF_MONTH));
accDate = accrualPeriod.getTime()
// if(accrual.getContractPosition().getContract().getMainContract() != null){
// accDate = dataManager.loadValue('select e.contractPosition.contract.acceptanceDate from rtneo$Accrual e where e.documentNumber = :documentNumber', Date.class)
// .parameter("documentNumber", accrual.getDocumentNumber())
// .one()
// }
return accDate;
}
def fillItems(Acts adjustmen, Acts act){
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)
String period = getTextPeriod(act.getPeriod())
def tsw=act.getSum()
items['amount']= act.getCount()
items['month'] = getTextPeriod(act.getPeriod())
items['priceWoNds']=(act.getPrice())
items['totalSumWoNds']=tsw
items['ndsSum']=act.getSum_nds()
items['totalSum']=act.getSum()*1.2
items['amountCorr']= adjustmen.getCount().add(items['amountCorr'])
items['priceWoNdsCorr']=adjustmen.getPrice()
items['totalSumWoNdsCorr']=adjustmen.getSum().add(items['totalSumCorr'])
items['ndsSumCorr']=adjustmen.getSum_nds().add(items['ndsSumCorr'])
items['totalSumCorr']=items['totalSumWoNdsCorr']+items['ndsSumCorr']
items['increase']=items['totalSumWoNdsCorr']<items['totalSumWoNds']?items['totalSumWoNds']-items['totalSumWoNdsCorr']:0.00
items['decrease']=items['totalSumWoNdsCorr']>items['totalSumWoNds']?items['totalSumWoNdsCorr']-items['totalSumWoNds']:0.00
items['ndsDec']=items['ndsSumCorr']>items['ndsSum']?items['ndsSumCorr']-items['ndsSum']:0.00
items['ndsInc']=items['ndsSum']>items['ndsSumCorr']?items['ndsSum']-items['ndsSumCorr']:0.00
items['totalSumDec']=items['totalSum']<items['totalSumCorr']?items['totalSumCorr']-items['totalSum']:0.00
items['totalSumInc']=items['totalSum']>items['totalSumCorr']?items['totalSum']-items['totalSumCorr']:0.00
return items
}
def fillItems(List<Accrual> accs, Acts act){
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)
for(Accrual a:accs){
String period = getTextPeriod(a.getPeriod())
def tsw=a.getTotalSum().add(items['totalSumWoNds']).subtract(a.getNdsSumBase())
items['amount']= a.getAmount().add(items['amount'])
items['month'] = getTextPeriod(a.getPeriod())
items['priceWoNds']=(a.getPrice()/6*5)
items['totalSumWoNds']=tsw
items['ndsSum']=a.getNdsSumBase().add(items['ndsSum'])
items['totalSum']=a.getTotalSum().add(items['totalSum'])
}
items['amountCorr']= act.getCount().add(items['amountCorr'])
items['priceWoNdsCorr']=act.getPrice()
items['totalSumWoNdsCorr']=act.getSum().add(items['totalSumCorr'])
items['ndsSumCorr']=act.getSum_nds().add(items['ndsSumCorr'])
items['totalSumCorr']=items['totalSumWoNdsCorr']+items['ndsSumCorr']
items['increase']=items['totalSumWoNdsCorr']<items['totalSumWoNds']?items['totalSumWoNds']-items['totalSumWoNdsCorr']:0.00
items['decrease']=items['totalSumWoNdsCorr']>items['totalSumWoNds']?items['totalSumWoNdsCorr']-items['totalSumWoNds']:0.00
items['ndsDec']=items['ndsSumCorr']>items['ndsSum']?items['ndsSumCorr']-items['ndsSum']:0.00
items['ndsInc']=items['ndsSum']>items['ndsSumCorr']?items['ndsSum']-items['ndsSumCorr']:0.00
items['totalSumDec']=items['totalSum']<items['totalSumCorr']?items['totalSumCorr']-items['totalSum']:0.00
items['totalSumInc']=items['totalSum']>items['totalSumCorr']?items['totalSum']-items['totalSumCorr']:0.00
return items
}
private Acts getActualAct(List<Accrual> accruals, String inn, String kpp, Date period, boolean onlyAct = false){
List<Acts> acts = getAllAct(inn, kpp, period)
//Сумма начислений
BigDecimal accSum = BigDecimal.ZERO
accruals.each({accSum = accSum.add(it.getTotalSum())})
accSum = accSum.setScale(2, BigDecimal.ROUND_UP);
boolean isAdj = false
acts.each({if(it.getAdjustments() != null)isAdj = true})
def act = null
def adjustmens = []
//getAdjustments() это ссылка на акт к которому принадлежит корректирока
if(isAdj){
adjustmens = acts.stream().filter({e->e.getAdjustments() != null}).collect(Collectors.toList())
}
onlyActs = acts.stream().filter({e->e.getAdjustments() == null}).collect(Collectors.toList())
def adjustmen
for(def item : adjustmens.reverse()){
def adjSum = item.getSum().add(item.getSum_nds());
if(!adjSum.equals(accSum)){
act = item;
break;
}
}
if(act == null || onlyAct){
act = onlyActs.get(0)
}
return act
}
private List<Acts> getAllAct(String inn, String kpp, Date period){
List<Acts> acts = dataManager.load(Acts.class)
.query('select a from rtneo$Acts a where a.inn = :inn and a.kpp = :kpp and a.period = :period')
.parameter("inn", inn)
.parameter("kpp", kpp)
.parameter("period" ,period)
.view("acts-view")
.list()
return acts;
}
private String getReason(Accrual accrual){
if(accrual.getContractPosition().getContract().getMainContract() != null){
return "Дополнительное соглашение №"+accrual.contractPosition.contract.number;
}else{
return "Договор №"+accrual.contractPosition.contract.number;
}
}
/**
* Логирование
*/
import com.haulmont.cuba.core.app.serialization.EntitySerializationAPI;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
private _(Object obj, String... options){
if(options.size() == 0){log(obj)}
for(def option : options){
if(option.equals("str")){log(obj)}
if(option.equals("for")){obj.each({_(it)})}
if(option.equals("json")){
EntitySerializationAPI entitySerializationAPI = AppBeans.get(EntitySerializationAPI.NAME)
try{log(entitySerializationAPI.toJson(obj))}
catch(Exception e){log("JSON serialization failed")}
}
if(option.equals("date")){
DateFormat df = new SimpleDateFormat("dd.MM.yyyy");
try{log(df.format(obj))}
catch(Exception e){log("Failed date format")}
}
}
}
private log(Object obj){log.debug(obj)}