import com.groupstp.datasupplier.data.BankData
import com.groupstp.datasupplier.service.BankDataSupplierService
import com.groupstp.rtneo.entity.*
import com.haulmont.cuba.core.entity.*
import org.apache.commons.collections4.CollectionUtils
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import com.github.declinationofnames.*
import com.haulmont.cuba.core.global.*;
import com.groupstp.rtneo.core.bean.calculation.CalculationWorkerHelper
import com.groupstp.rtneo.service.AccrualService
import com.groupstp.rtneo.data.ContainerYardSearchData
import com.groupstp.rtneo.core.bean.ContainerYardWorker
import org.apache.commons.lang.StringUtils
import com.groupstp.rtneo.service.CompanyService
import com.haulmont.cuba.core.app.*;
import com.haulmont.cuba.core.entity.EntitySnapshot;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**/
ViewRepository vRep = AppBeans.get(ViewRepository.NAME)
/**/
/**/
//Реквизиты
def props = [:]
//Объекты для первой таблицы
def realEstates = [];
//контейнерные площадки для второй таблицы
def containers = [];
//Объемы для третьей таблицы
def calculations = []
//factMonth
//Месяца для таблицы перерасчета
def factMonth = []
//Объемы для таблицы перерасчета
def factAmount = []
//factTotal
def factTotal = [:]
//Итог
def totals = [:]
//Результат
def root = [:]
//Не задействованы
//Начисления для расчетов
def accruals = []
//Начисления за арендаторов
def renters = []
//rentersPos Позиции за арендаторов в разрезе объектов недвижимости
def rentersPos = [:]
/**/
/**/
//def contract = dataManager.reload(params['contract'],'contract-print')
def r1 = "08d25e69-60c9-b132-4472-fc2407851d7b"
//def r1 = "4ba10d83-ae21-4887-c14d-6123c22a0274"
def params = [:]
Contract contract = dataManager.load(Contract.class).id(UUID.fromString(r1)).view('contract-print').optional().orElse(null)
DateFormat df = new SimpleDateFormat("dd.MM.yyyy");
Contragent contragent = contract.getContragent()
//Период действия договора
def (String contractFrom, String contractBefore) = getStartEndDate(contract, df)
/**/
/**/
//Заполнили реквизиты
props = fillRequisites(contract, params, df, contractFrom, contragent)
//Получаем все договора из истории
def cpList = getHistoryCP(contract)
//Удаляем перекрывающиеся договора
cpList = checkContractPeriod(cpList)
if(cpList.size() == 0)return null
//Создаем массив с периодами действия договоров
def itemsCP = getItemsCP(cpList)
//Создаем колекцию с позициями и датами в разрезе объектов
def cresWP = [:]
def itemsRE = getItemsRE(itemsCP, contract, cresWP)
//Удаляем лишние позиции
//rentersPos
removePositions(itemsRE, contract, rentersPos)
//Расставляем признаки изменения позиций
checkChange(itemsRE)
////Удаляем не измененные
//removeNoChanged(itemsRE)
//Нумеруем объекты
itemsRE = parseItemsRE(itemsRE, contract)
//Заполняем массив первой таблицы
realEstates = fillRealEstates(itemsRE)
//Создаем колекцию с позициями и датами в разрезе контейнерных площадок
def itemsCY = getItemsCY(itemsRE)
//Заполняем контейнерные площадки для второй таблицы
containers = fillContainers(itemsCY)
//Заполняем объемы для третьей таблицы
//rentersPos
calculations = fillCalculations(itemsRE, contract, rentersPos, cresWP)
//Заполняем объемы для таблицы при перерасчете по факту
factAmount = fillFactAmount(contract, factMonth)
def isContractRefact = contract.getIsFactRecalculation()!=null ? contract.getIsFactRecalculation() : false
if(isContractRefact){
factTotal = fillFatTotal(factAmount)
}
totals = fillTotals(factAmount, calculations)
root = [['props':props,'realEstates': realEstates, 'calculations': calculations, 'totals':totals, 'containers': containers, 'accruals': accruals, 'renters': renters, 'factAmount': factAmount, 'factMonth': factMonth, "factTotal": factTotal]]
return root
/**/
/*
/fill root
*/
//Заполняем реквизиты
private def fillRequisites(Contract contract, HashMap<Object, Object> params, SimpleDateFormat df, String startFrom, Contragent contragent) {
def companyService = AppBeans.get(CompanyService.NAME)
def bankDataService = AppBeans.get(BankDataSupplierService.NAME)
//Получаем реквизиты компании, действующие на момент даты договора
def company = contract.getCompany()
def companyRequisites = companyService.getCompanyRequisites(company, contract.getDate())
def companyManagerNameR = companyRequisites.getManagerName()
try {
companyManagerNameR = new RussianName(companyManagerNameR).fullName(RussianNameProcessor.gcaseRod)
} catch (e) {
}
//заполняем шапку
//документ-основание
contragentPersonReasonText = ', действующего на основании '
if (contragent.getType() == ContragentType.PERSONAL) {
contragentPersonReasonText = ''
}
contragentPersonReasonDoc = params['personReason']
if (contragentPersonReasonDoc == null) {
contragentPersonReasonDoc = contragent.getHeadPersonReasonDoc()
}
contragentPersonReasonDocR = contragentPersonReasonDoc
try {
contragentPersonReasonDocR = new RussianName(contragentPersonReasonDoc).fullName(RussianNameProcessor.gcaseRod)
} catch (e) {
}
if (contragentPersonReasonDocR == null) {
if (getContragentType(contragent) == ContragentType.ORGANISATION) {
contragentPersonReasonDocR = "устава"
} else if (getContragentType(contragent) == ContragentType.INDIVIDUAL) {
contragentPersonReasonDocR = "свидетельства / выписки о государственной регистрации в качестве индивидуального предпринимателя"
}
}
//подписант
contragentPersonName = params['personName']
if (contragentPersonName == null) {
contragentPersonName = contragent.getHeadPersonName()
if (contragent.getType() == ContragentType.PERSONAL) {
contragentPersonName = contragent.getName()
}
}
contragentPersonNameR = contragentPersonName
try {
contragentPersonNameR = new RussianName(contragentPersonName).fullName(RussianNameProcessor.gcaseRod)
} catch (e) {
}
//должность подписанта
contragentPersonPost = params['personPost']
if (contragentPersonPost == null) {
contragentPersonPost = contragent.getHeadPersonPost()
}
contragentPersonPostR = contragentPersonPost
try {
contragentPersonPostR = new RussianName(contragentPersonPost).fullName(RussianNameProcessor.gcaseRod)
} catch (e) {
}
//массив шапочных параметров
def props = [
'number' : contract.getNumber(),
'date' : getTextDate(contract.getDate()),
//a.kotvinskiy /--
'dateFromTKO' : df.format(contract.getFrom()),
'dateBeforeTKO' : df.format(contract.getBefore()),
//a.kotvinskiy --/
'contragentName' : contragent.getName(),
'contragentNameShort' : contragent.getShortName(),
'contragentPersonName' : contragentPersonName,
'contragentPersonNameR' : contragentPersonNameR,
'contragentPersonNameShort' : getShortFio(contragentPersonName),
'contragentPersonPost' : contragentPersonPost,
'contragentPersonPostR' : contragentPersonPostR,
'contragentPersonReasonDoc' : contragentPersonReasonDoc,
'contragentPersonReasonDocR' : contragentPersonReasonDocR,
'contragentPersonReasonText' : contragentPersonReasonText,
'contragentShortName' : contragent.getShortName(),
'legalAddress' : contragent.getLegalAddress(),
'actualAddress' : contragent.getActualAddress(),
'mailingAddress' : contragent.getMailingAddress(),
'registrationAddrees' : contragent.getRegistrationAddress(),
'passportSeries' : contragent.getPassportSeries(),
'passportNumber' : contragent.getPassportNumber(),
'passportGivenDate' : contragent.getPassportGivenDate(),
'inn' : contragent.getInn(),
'kpp' : contragent.getKpp(),
'ogrn' : contragent.getOgrn(),
'checkingAccount' : contragent.getCheckingAccount(),
'bankName' : contragent.getBankName(),
'correspondentAccount' : contragent.getCorrespondentAccount(),
'bik' : contragent.getBik()
, 'companyShortName' : company.shortName
, 'companyFullName' : company.fullName
, 'companyInn' : company.inn
, 'companyEmail' : company.email
, 'companyOgrn' : company.ogrn
, 'companyPhone' : company.phone
, 'companyLegalAddress' : companyRequisites.legalAddress
, 'companyActualAddress' : companyRequisites.actualAddress
, 'companyPostalAddress' : companyRequisites.postalAddress
, 'companyKpp' : companyRequisites.kpp
, 'companyBankName' : companyRequisites.bankName
, 'companyBankAccount' : companyRequisites.bankAccount
, 'companyCorrespondentAccount': companyRequisites.correspondentAccount
, 'companyRcbic' : companyRequisites.rcbic
, 'companyManagerTitle' : companyRequisites.managerTitle
, 'companyManagerTitleR' : companyRequisites.managerTitleR
, 'companyManagerName' : companyRequisites.managerName
, 'companyManagerNameR' : companyManagerNameR
, 'companyManagerNameShort' : getShortFio(companyRequisites.managerName)
, 'companyManagerDocumentR' : companyRequisites.managerDocumentR,
'startFrom' : startFrom
]
if (!StringUtils.isBlank(props['bik']) && (StringUtils.isBlank(props['bankName']) || StringUtils.isBlank(props['correspondentAccount']))) {
BankData bank = bankDataService.getSuggestionBankDetails(props['bik'])
if (bank != null) {
if (StringUtils.isBlank(props['bankName'])) {
props['bankName'] = bank.getName()
}
if (StringUtils.isBlank(props['correspondentAccount'])) {
props['correspondentAccount'] = bank.getCorrespondentAccount()
}
}
}
//телефон + почта
def phone = ''
if (contragent.getHeadPersonPhone() != null) {
phone = contragent.getHeadPersonPhone()
} else if (contragent.getContactPersonPhone() != null) {
phone = contragent.getContactPersonPhone()
}
def email = ''
if (contragent.getHeadPersonEmail() != null) {
email = contragent.getHeadPersonEmail()
} else if (contragent.getContactPersonEmail() != null) {
email = contragent.getContactPersonEmail()
}
props['phone'] = phone
props['email'] = email
//a.kotvinskiy 19-07-19/--
//В пункте 3 доп соглашения, указываем начало действия доп соглашения
props['dateFrom'] = getTextDate(contract.getFrom())
//a.kotvinskiy 19-07-19--/
//получаем номер и дату головного договора
if (contract.getMainContract() != null) {
props['mainContractNumber'] = contract.getMainContract().getNumber()
props['mainContractDate'] = getTextDate(contract.getMainContract().getDate())
}
//вычисляем подписантов и юридический адрес
def defaultDate = new Date().copyWith(year: 2019, month: Calendar.JANUARY, dayOfMonth: 17, hourOfDay: 0, minute: 0, second: 0);
def addressChangeDate = new Date().copyWith(year: 2019, month: Calendar.APRIL, dayOfMonth: 26, hourOfDay: 0, minute: 0, second: 0);
def contractDate = contract.getDate()
props['ourPersonPost'] = "Заместитель генерального директора по коммерческой работе"
props['ourPersonPostR'] = "Заместителя генерального директора по коммерческой работе"
props['ourPersonName'] = "Степанова Татьяна Анатольевна"
props['ourPersonNameR'] = "Степановой Татьяны Анатольевны"
props['ourPersonReasonDoc'] = "доверенность № РТ-05 от 11.01.2019 г"
props['ourPersonReasonDocR'] = "доверенности № РТ-05 от 11.01.2019 г"
props['ourPersonNameShort'] = "Степанова Т.А."
return props
}
//Заполняем объекты для первой таблицы
private def fillRealEstates(def itemsRE){
def realEstates = []
for(def item : itemsRE){
def pos = null
if(item["from"].equals("--")){
pos = createREItem(item["position"], item["n"])
}else{
String code = getCYCodesPosition(item["position"])
String codeKGO = getCYCodesKGOPosition(item["position"])
pos = createREItem(item["position"], code, codeKGO, item["n"], item["from"], item["before"])
}
realEstates.add(pos)
}
return realEstates
}
private def fillContainers(def itemsCY){
def list = []
def itemCY = [:]
//wp
def prevN = ""
//wp
for(def item : itemsCY){
def pos = null
String code = item.getKey()
for(def itemRE : item.getValue()){
def key = code+itemRE["from"]+itemRE["before"]
itemCY.putIfAbsent(key, ["code":code, "n":"", "from":itemRE["from"],"before":itemRE["before"], "cy":null, "isFact":itemRE["isFact"]]);
//wp
// itemCY[key]["n"] +=itemRE["n"]+"<br/>"
itemCY[key]["n"] += prevN == itemRE["n"]?"":itemRE["n"]+"<br/>"
//wp
itemCY[key]["cy"] = itemRE["cy"]
//wp
prevN = itemRE["n"]
//wp
itemCY[key]["cy"] = itemRE["cy"]
}
// pos = createCYItem()
}
for(def item : itemCY.values()){
pos = createCYItem(item["cy"], item["isFact"], item["from"], item["before"], item["n"])
for(def itemPos : pos){
list.add(itemPos)
}
}
return list
}
//rentersPos
private def fillCalculations(itemsRE, contract, rentersPos, cresWP){
//wp
SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy")
//wp
def list = []
for(def item : itemsRE){
if(item["changeRE"] != true)continue
def calculation = [:]
def position = item["position"]
BigDecimal totalVolumePosition = 0.0
if(position.getAccruals().size()>0){
for(Accrual accrual : position.getAccruals()){
// totalVolumePosition += getNN(accrual.getAmountBase())
if(!contract.getFrom().after(accrual.getPeriod()))totalVolumePosition += getNN(accrual.getAmountBase())
// endVolume = getNN(accrual.getAmountBase())
}
}
//renterPos
for(def renter : rentersPos){
if(position.getContragentRealEstate() == null)continue
if(position.getContragentRealEstate().getRealEstate().getId().equals(renter.getKey().getId())){
for(def pos : renter.getValue()["position"]){
if(pos.getAccruals().size()>0){
for(Accrual accrual : pos.getAccruals()){
if(!contract.getFrom().after(accrual.getPeriod()))totalVolumePosition += getNN(accrual.getAmountBase())
}
}
}
}
}
//Если вдруг позиция за период договора не попала в выборку, берем объемы по объекту из текущего договора. Если только договор не по факту
def isFact = !(contract.getIsFactCalculation() != null && contract.getIsFactCalculation() == true)
if(isFact && totalVolumePosition == BigDecimal.ZERO){
for(def itemCP : contract.getPositions()){
if(itemCP.getContragentRealEstate() == null || position.getContragentRealEstate() == null)continue
if(itemCP.getContragentRealEstate().getId().equals(position.getContragentRealEstate().getId())){
if(itemCP.getAccruals().size()>0){
for(Accrual accrual : itemCP.getAccruals()){
if(!contract.getFrom().after(accrual.getPeriod()))totalVolumePosition += getNN(accrual.getAmountBase())
}
}
}
}
}
def num = item["n"].toString()
if(num.endsWith("А")){
num = num.substring(0, num.length() - 1)
}
calculation['n'] = num
if (position.getIsFactCalculation()) {
calculation['unitName'] = '--'
calculation['norm'] = '--'
calculation['amount'] = 'расчет по факту'
calculation['calculationAmount'] = '--'
}else{
def calculationAmount = 0
if (position.getCalculationAmount() == null || position.getCalculationAmount() == 0) {
if (position.getContragentRealEstate() == null) {
calculationAmount = "--"
} else {
calculationAmount = getFormatNum(position.getContragentRealEstate().getCalculationAmount(), 5)
}
} else {
calculationAmount = getFormatNum(position.getCalculationAmount(), 5)
}
calculation['calculationAmount'] = calculationAmount
calculation['amount'] = getFormatNum(totalVolumePosition, 5);//???????????????????????????????
if (position.getCategory() != null) {
calculation['unitName'] = position.getUnit().getName()
}
if (position.getNorm() != null) {
calculation['norm'] = getFormatNum(position.getNorm(), 4)
}
if(position.getIsFactRecalculation()){
calculation['norm'] = "расчет по факту"
}
if (position.getWasteProject() != null) {
calculation['unitName'] = "ПНООЛР с ${position.getWasteProject().getValidityFrom() == null ? '--' : df.format(position.getWasteProject().getValidityFrom())} по ${position.getWasteProject().getValidityTo() == null ? '--' : df.format(position.getWasteProject().getValidityTo())}"
}
}
list.add(calculation)
if (position.getWasteProject() != null) {
for(def itemCRE : cresWP[position.getWasteProject()]){
// _(itemCRE.getRealEstate().getAddress())
def calculationWP = [:]
calculationWP['n'] = ''
calculationWP['unitName'] = itemCRE.getRealEstate().getAddress()
calculationWP['norm'] = '--'
calculationWP['amount'] = '--'
calculationWP['calculationAmount'] = '--'
list.add(calculationWP)
}
}
}
return list
}
private def fillFactAmount(Contract contract, factMonth){
Calendar cal = Calendar.getInstance()
cal.setTime(contract.getFrom())
LinkedList<Date> listMonth = new LinkedList<>();
while(cal.getTime().before(contract.getBefore())){
factMonth.add(["month":getTextDate(cal.getTime(), false)])
listMonth.add(cal.getTime())
cal.add(Calendar.MONTH, 1)
}
def factItems = []
List<ContainerYard> cyList = dataManager.load(ContainerYard.class)
.query('select distinct c.containerYard from rtneo$ContractPositionContainerYard c where c.contractPosition.contract.id = :contract and c.contractPosition.isFactRecalculation = 20')
.parameter("contract", contract.getId())
.view("_local")
.list();
def totalFactAmount = 0
for(ContainerYard cy : cyList){
/**
* Определяем период аренды
*/
Date rentFrom = null
Date rentTo = null
List<KeyValueEntity> listFrom = dataManager.loadValues('select c.contragentRealEstate.validityFrom from rtneo$ContractPositionContainerYard c where c.containerYard.code = :code and c.contractPosition.contract.id = :contract')
.parameter("code", cy.getCode())
.parameter("contract", contract.getId())
.properties("from")
.list();
List<KeyValueEntity> listTo = dataManager.loadValues('select c.contragentRealEstate.validityTo from rtneo$ContractPositionContainerYard c where c.containerYard.code = :code and c.contractPosition.contract.id = :contract')
.parameter("code", cy.getCode())
.parameter("contract", contract.getId())
.properties("to")
.list();
for(def val : listFrom.reverse()){
if(val.getValue('from') != null){
rentFrom = val.getValue('from')
}else{
rentFrom = null
break
}
}
for(def val : listTo){
if(val.getValue('to') != null){
rentTo = val.getValue('to')
}else{
rentTo = null
break
}
}
Calendar rentCal = Calendar.getInstance()
if(rentFrom != null){
rentCal.setTime(rentFrom)
rentCal.set(Calendar.DAY_OF_MONTH, rentCal.getActualMinimum(Calendar.DAY_OF_MONTH))
rentFrom = rentCal.getTime()
}
if(rentTo != null){
rentCal.setTime(rentTo)
rentCal.set(Calendar.DAY_OF_MONTH, rentCal.getActualMaximum(Calendar.DAY_OF_MONTH))
rentTo = rentCal.getTime()
}
/**
* Определяем начало верификации
*/
Date verify = null;
if(cy.getVerifiedDate() != null){
Calendar calVerify = Calendar.getInstance()
calVerify.setTime(cy.getVerifiedDate())
calVerify.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH))
verify = calVerify.getTime()
}
totalFactAmount += cy.getMaxWasteExportVol()
def fact = [:]
fact = ["n": cy.getCode()]
def count = 0
for(def date : listMonth){
count++
if(verify != null && date.before(verify)){
fact["${count}"] = BigDecimal.ZERO
}else{
fact["${count}"] = cy.getMaxWasteExportVol()
}
if(rentFrom != null && date.before(rentFrom)){fact["${count}"] = BigDecimal.ZERO}
if(rentTo != null && date.after(rentTo)){fact["${count}"] = BigDecimal.ZERO}
}
factItems.add(fact)
}
return factItems
}
private def fillTotals(factAmount, calculations){
// def totals = [
// //a.kotvinskiy /--
// //'amountBaseAll' : getNumber(amountBaseAll, false),
// //'amountBase' : getNumber(amountBase, false),
// 'amountBase' : getFormatNum(amountBase, 5),
// 'amountBaseNoRent' : getFormatNum(amountBaseNoRent, 5),
// 'amountBaseRent' : getFormatNum(amountBaseRent, 5),
// //a.kotvinskiy --/
// 'totalSumBaseNoNds' : getNumber(totalSumBaseNoNds),
// 'totalSumBase' : getNumber(totalSumBase),
// 'discount' : getNumber(discount),
// 'totalSum' : getNumber(totalSum),
// 'totalFactAmount' : getNumber(totalFactAmount)
// ]
BigDecimal totalFactAmount = BigDecimal.ZERO
for(def item : factAmount){
def totalAmountMounth = BigDecimal.ZERO
for(def itemFact : item){
if(itemFact.getKey().equals("n"))continue
totalAmountMounth = BigDecimal.valueOf(itemFact.getValue())
}
totalFactAmount += totalAmountMounth
}
BigDecimal amountBase = BigDecimal.ZERO
def lastItems = []
ListIterator it = calculations.listIterator()
while(it.hasNext()){
def item = it.next()
//wp
if(item["n"].equals(''))continue
//wp
if(it.hasNext()){
def itemNext = it.next()
if(itemNext["n"] != '' && !new BigDecimal(itemNext["n"]).equals(new BigDecimal(item["n"]).add(0.1)))lastItems.add(item)
it.previous()
}else{
lastItems.add(item)
}
}
for(def item : lastItems){
if(item["norm"].equals("--"))continue
def bd = new BigDecimal(item["amount"].replaceAll(",", ".").replaceAll(" ", ""))
amountBase += bd
}
def totals = [
'totalFactAmount' : getNumber(totalFactAmount),
'amountBase' : getFormatNum(amountBase, 5),
]
return totals
}
//private def getItemsRE(itemsCP, contract){
// def itemRE = [:]
// for(def item : itemsCP){
// for(def itemCP : item["positions"]){
// //исключаем жилые
// if(itemCP.getCategory() != null && itemCP.getCategory().getIsLiving()){
// continue;
// }
// def cre = [:]
// itemRE.putIfAbsent(itemCP.getContragentRealEstate().getId(), []);
// cre = [
// "cre":itemCP.getContragentRealEstate(),
// "n":"",
// "from":item["from"],
// "before":item["before"],
// "changeCY": false,
// "changeRE": false,
// "position":itemCP
// ]
// itemRE[itemCP.getContragentRealEstate().getId()].add(cre)
// }
// }
// return itemRE
//}
private def getItemsRE(itemsCP, contract, cresWP){
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd")
def itemRE = [:]
for(def item : itemsCP){
//wp
List<WasteGenerationProject> listWP = item["contract"].getContragent().getWasteGenerationProjects()
ListIterator it = listWP.listIterator()
while(it.hasNext()){
boolean isRemove = false
WasteGenerationProject contractWP = it.next()
if(contractWP.getValidityFrom() != null && contractWP.getValidityFrom().after(item["contract"].before)) isRemove = true
if(contractWP.validityTo != null && contractWP.getValidityTo().before(item["contract"].from)) isRemove = true
if(isRemove)it.remove()
}
listWP.each({cresWP.putIfAbsent(it, [])})
//wp
for(def itemCP : item["positions"]){
//исключаем жилые
if(itemCP.getCategory() != null && itemCP.getCategory().getIsLiving()){
continue;
}
//wp
if(itemCP.getWasteProject() != null){
def wp = [:]
itemRE.putIfAbsent(itemCP.getWasteProject().getId(), []);
wp = [
"cre":itemCP.getWasteProject(),
"n":"",
"from":item["from"],
"before":item["before"],
"changeCY": false,
"changeRE": false,
"position":itemCP
]
itemRE[itemCP.getWasteProject().getId()].add(wp)
}
//wp
if(itemCP.getContragentRealEstate() != null){
//Здесь проверяем, если объект недвижимости находится в актуальном проекте нормативов, то объкт не добавляем.
if(itemCP.getContragentRealEstate().getWasteGenerationProjects() != null && itemCP.getContragentRealEstate().getWasteGenerationProjects().size() != 0){
List<WasteGenerationProject> creWPs = itemCP.getContragentRealEstate().getWasteGenerationProjects()
creWPs.each({if(cresWP[it]!=null)cresWP[it].add(itemCP.getContragentRealEstate())})
if(listWP.stream().anyMatch({w-> creWPs.stream().anyMatch({creWP -> creWP.getId() == w.getId()})}))continue
}
itemRE.putIfAbsent(itemCP.getContragentRealEstate().getId(), []);
def cre = createCre(itemCP, item, item["from"], item["before"])
itemRE[itemCP.getContragentRealEstate().getId()].add(cre)
}
/**
*
*/
if(itemCP.getContainerYards().size() != 0){
Date verifiedDate = null
for(def itemCY : itemCP.getContainerYards()){
if(itemCY.getContainerYard().getVerifiedDate() != null){
if(verifiedDate == null || verifiedDate.after(itemCY.getContainerYard().getVerifiedDate())){
verifiedDate = itemCY.getContainerYard().getVerifiedDate()
}
}
}
if(verifiedDate != null && verifiedDate.after(itemCP.getPeriod())){
Calendar cal = Calendar.getInstance()
cal.setTime(verifiedDate)
cal.add(Calendar.MONTH, -1)
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
itemRE[itemCP.getContragentRealEstate().getId()].get(itemRE[itemCP.getContragentRealEstate().getId()].size()-1)["before"] = cal.getTime()
cal.add(Calendar.DAY_OF_MONTH, 1)
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
cre = createCre(itemCP, item, cal.getTime(), item["before"])
cre["changeCY"] = true
itemRE[itemCP.getContragentRealEstate().getId()].add(cre)
}
}
/**
*
*/
}
}
return itemRE
}
private def createCre(itemCP, item, from, before){
return [
"cre":itemCP.getContragentRealEstate(),
"n":"",
"from":from,
"before":before,
"changeCY": false,
"changeRE": false,
"position":itemCP
]
}
private def getItemsCY(def itemsRE){
SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy")
def listCY = [:]
for(def item : itemsRE){
if(item["from"].equals("--"))continue
for(def itemCPCY : item["position"].getContainerYards()){
def cre = [:]
listCY.putIfAbsent(itemCPCY.getContainerYard().getCode(), []);
cre = [
"n":item["n"],
"from":df.format(item["from"]),
"before":df.format(item["before"]),
"cy":itemCPCY.getContainerYard(),
"isFact":item["position"].getIsFactCalculation()||item["position"].getIsFactRecalculation()?true:false
]
listCY[itemCPCY.getContainerYard().getCode()].add(cre)
}
}
return listCY
}
//factTotal
private def fillFatTotal(factAmount){
def totals = [:]
def months = factAmount.get(0).size()
for(i=1; i<months; i++){
BigDecimal sum = BigDecimal.ZERO
factAmount.each({sum = sum.add(it.get(i.toString()))})
totals[i.toString()] = sum
}
return totals
}
/*
/functions
*/
//**************************************************************
//Получить историю позиции договора
//**************************************************************
def getHistoryCP(Contract contract){
DataManager dataManager = AppBeans.get(DataManager.NAME);
EntitySnapshotService entitySnapshotService = AppBeans.get(EntitySnapshotService.NAME);
def listSnapshotHistory = dataManager.load(SnapshotHistory.class)
.query('select s from rtneo$SnapshotHistory s where s.contragent.id = :contragent and s.contract.accepted = true or s.contract.id = :contractId order by s.contract.createTs asc')
.parameter("contragent", contract.getContragent().getId())
.parameter("contractId", contract.getId())
.view("_local")
.list();
def cpH = []
for(def snapshotHistory : listSnapshotHistory){
def cp = [:]
def entitySnapshot = dataManager.load(EntitySnapshot.class).id(snapshotHistory.getSnapshot()).optional().orElse(null)
Contract entity = entitySnapshotService.extractEntity(entitySnapshot)
// //Если доп не на перерасчет, не добавляем допы на перерасчет
// if(!(contract.getIsFactRecalculation() != null && contract.getIsFactRecalculation())){
// if(entity.getIsFactRecalculation() != null && entity.getIsFactRecalculation())continue
// }
cp.putIfAbsent(entity.getNumber(), ["contract":entity, "positions":[]]);
for(ContractPosition cpItem : entity.getPositions()){
//wp
// if(cpItem.getContragentRealEstate() == null && cpItem.getWasteProject() == null)continue;
//wp
cp[entity.getNumber()]["positions"].add(cpItem)
}
cpH.add(cp)
}
return cpH;
}
//Удаляем перекрывающиеся договора
private def checkContractPeriod(def cpList){
def sortCPList = []
def prevDate = null
def prevContract = null
Calendar startPeriod = Calendar.getInstance()
startPeriod.setTime(cpList.get(0).values()["contract"].get(0).getFrom())
for(def item : cpList.reverse()){
if(item.values()["contract"].get(0).getFrom().equals(startPeriod.getTime())){
sortCPList.add(item)
break
}
if(prevDate != item.values()["contract"].get(0).getFrom() && prevContract != item.values()["contract"].get(0).getNumber())sortCPList.add(item)
prevDate = item.values()["contract"].get(0).getFrom()
prevContract = item.values()["contract"].get(0).getNumber()
}
return sortCPList.reverse()
}
//Создаем колекцию с позициями и датами в разрезе объектов
/* def tmp["cre.id"] = [
// "cre"
// "from"
// "before"
// "changeCY"
// "changeRE"
// "position"
// ]
*/
def getItemsCP(List<ContractPosition> cpList){
SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy")
Calendar cal = Calendar.getInstance()
def itemsCP = []
for(def item : cpList){
def cp = [
"contract":item.values()["contract"].get(0),
"from":item.values()["contract"].get(0).getFrom(),
"before":item.values()["contract"].get(0).getBefore(),
"positions":item.values()["positions"].get(0)
]
if(itemsCP.size() != 0){
cal.setTime(item.values()["contract"].get(0).getFrom())
cal.add(Calendar.DATE, -1)
itemsCP[itemsCP.size()-1]["before"] = cal.getTime()
}
itemsCP.add(cp)
}
return itemsCP
}
//Расставляем признаки изменения позиций
private checkChange(def itemsCP){
for(def item : itemsCP){
def prevCP = null
for(def itemCP : item.getValue()){
if(!itemCP["changeCY"])itemCP["changeCY"] = changeCY(itemCP["position"], prevCP)
if(!itemCP["changeRE"])itemCP["changeRE"] = changeRE(itemCP["position"], prevCP)
prevCP = itemCP["position"]
}
}
}
//Устанавливаем нумерацию
private def parseItemsRE(itemsRE, contract){
def listRE = []
def n = ""
char nChar = 'А'
def nInt = BigDecimal.valueOf(1.0)
def prev = [
"nChar":null,
"nInt":null
]
for(def item : itemsRE){
nInt = nInt.setScale(0, RoundingMode.CEILING)
for(def itemCP : item.getValue()){
if(!itemCP["changeCY"] && !itemCP["changeRE"]){
listRE.get(listRE.size()-1)['before'] = itemCP["before"]
continue
}
if(itemCP["changeCY"] && !itemCP["changeRE"]){
if(nChar == 'А'){
def tmpCyItem = listRE.get(listRE.size()-1).clone()
listRE.get(listRE.size()-1)['from'] = "--"
listRE.get(listRE.size()-1)['before'] = "--"
listRE.get(listRE.size()-1)['changeRE'] = "--"
listRE.get(listRE.size()-1)['changeCY'] = "--"
// listRE.get(listRE.size()-1)['position'] = "--"
tmpCyItem['n'] = tmpCyItem['n'].toString()+nChar++
listRE.push(tmpCyItem)
}
n = (prev["nInt"].toString())+(nChar++)
}
if(itemCP["changeRE"]){
nChar = 'А'
// if(contract.getIsFactCalculation() != null && contract.getIsFactCalculation()) nInt +=0.1
nInt +=0.1
n=nInt
}
itemRE = [
"cre":itemCP["cre"],
"n":n,
"from":itemCP["from"],
"before":itemCP["before"],
"changeCY":itemCP["changeCY"],
"changeRE":itemCP["changeRE"],
"position":itemCP["position"],
]
listRE.add(itemRE)
//Устанавливаем предыдущие значения
prev["nInt"] = nInt
prev["nChar"] = nChar
}
if(listRE.size() !=0){
//wp
if(listRE.get(listRE.size()-1)['cre'].getClass()==WasteGenerationProject.class)continue
//wp
listRE.get(listRE.size()-1)['before'] = contract.getBefore()
}
}
return listRE
}
//Создание позиции для первой таблицы
private def createREItem(ContractPosition cp, String code, String codeKGO, Object n, Date from, Date before){
SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy")
// def kgo = false
//
// for(def container : cpcy.getContainerYard().getContainers()){
// BigDecimal volume = container.getType()?.getVolume() == null ? BigDecimal.ZERO : container.getType().getVolume()
// if(volume >= BigDecimal.valueOf(5.0))kgo = true;
// }
def isNull = false
isNull = cp.getContragentRealEstate() == null?true:false
//wp
def isWP = cp.getWasteProject()==null?false:true
//wp
def pos = [
realEstateName:isNull?'':cp.getContragentRealEstate().getRealEstate().getName(),
cadastralNumber:isWP?'ПНООЛР':isNull?'':cp.getContragentRealEstate().getRealEstate().getCadastralNumber(),
address:isNull?'':cp.getContragentRealEstate().getRealEstate().getAddress(),
startFrom:df.format(from),
endBefore:df.format(before),
containerYardNumber:code,
containerYardKGONumber: codeKGO,
n:n
]
return pos
}
private def createREItem(ContractPosition cp, Object n){
SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy")
// def kgo = false
//
// for(def container : cpcy.getContainerYard().getContainers()){
// BigDecimal volume = container.getType()?.getVolume() == null ? BigDecimal.ZERO : container.getType().getVolume()
// if(volume >= BigDecimal.valueOf(5.0))kgo = true;
// }
def isNull = false
isNull = cp.getContragentRealEstate() == null?true:false
def pos = [
realEstateName:isNull?'':cp.getContragentRealEstate().getRealEstate().getName(),
cadastralNumber:isNull?'':cp.getContragentRealEstate().getRealEstate().getCadastralNumber(),
address:isNull?'':cp.getContragentRealEstate().getRealEstate().getAddress(),
startFrom:"--",
endBefore:"--",
containerYardNumber:"",
containerYardKGONumber: "",
n:n
]
return pos
}
//Создаем контейнерную площадку для второй таблицы
private def createCYItem(ContainerYard cy, isFact, String startFrom, String endBefore, def n){
SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy")
def containerWasteBuff = [:]
def containers = []
for (ContainerWaste container : cy.getContainers()) {
String type = container.getType()?.getName() == null ? '' : container.getType().getName()
String volume = container.getType()?.getVolume() == null ? '' : getNumber(container.getType().getVolume(), false)
volume = volume.replaceAll(',', '.')
Integer count = container.getCount() == null ? 0 : container.getCount();
if(count == 0)continue
String typeVal = type + volume
String key = cy.getCode()
String typeExport = ''
if(isFact){
if(cy.getVerifiedDate() != null){
Calendar cal = Calendar.getInstance()
cal.setTime(cy.getVerifiedDate())
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH))
if(df.parse(startFrom).after(cal.getTime()) || df.parse(startFrom).equals(cal.getTime())){
typeExport = 'Исходя из количества и объема контейнеров'
}else{
typeExport = 'Исходя из нормативов накопления'
}
}else{
typeExport = 'Исходя из количества и объема контейнеров'
}
}else{
typeExport = 'Исходя из нормативов накопления'
}
// typeExport = isFact ? 'Исходя из количества и объема контейнеров' : 'Исходя из нормативов накопления'
def current = []
Map previous = containerWasteBuff[key]
// if (previous == null) {
current = [
'n' : n,
'code' : key,
'startFrom' : startFrom,
'endBefore' : endBefore,
'address' : cy.getAddress(),
'longitude' : getFormatNum(cy.getLongitude(), 5),
'latitude' : getFormatNum(cy.getLatitude(), 5),
'typeExport': typeExport,
'owner' : cy.getOwner(),
'type' : type,
'volume' : volume,
'count' : count,
'typeWaste' : isKGO(container) ? 'КГО' : 'ТКО'
]
if (containerWasteBuff[key] != null) {
// if(current['n'] == )
current['n'] = ''
current['code'] = ''
current['startFrom'] = ''
current['endBefore'] = ''
current['address'] = ''
current['longitude'] = ''
current['latitude'] = ''
current['owner'] = ''
}
containers.push(current)
containerWasteBuff[key] = current
}
return containers
}
//Удаляем лишние позиции
//rentersPos
private removePositions(itemsRE, Contract contract, rentersPos){
def isContractFact = contract.getIsFactCalculation()!=null ? contract.getIsFactCalculation() : false
def isContractRefact = contract.getIsFactRecalculation()!=null ? contract.getIsFactRecalculation() : false
for(def item : itemsRE){
Iterator it = item.getValue().iterator()
while(it.hasNext()){
def itItem = it.next()
def isRemove = false
//wp
if(itItem["position"].getWasteProject() != null)continue
//wp
def contractContragent = contract.getContragent().getId()
def creContragent = itItem["position"].getContragentRealEstate().getContragent()!=null ? itItem["position"].getContragentRealEstate().getContragent().getId() : contractContragent
//rentersPos
// if(!creContragent.equals(contractContragent))isRemove = true
//Если позиция оплата за арендатора, удаляем из общего списка, и вносим в список оплат за арендатора
if(!creContragent.equals(contractContragent)){
rentersPos.putIfAbsent(itItem["position"].getContragentRealEstate().getRealEstate(), [])
rentersPos[itItem["position"].getContragentRealEstate().getRealEstate()].add(itItem)
isRemove = true
}
// if(!isContractRefact && itItem["position"].getIsFactRecalculation())isRemove = true
//Может сломаться если раскоментировать вывод лога ниже
if(isRemove){it.remove()}
// _(itItem)
}
}
}
/*
/utils
*/
//Возвращает период действия договора
private List getStartEndDate(contract, SimpleDateFormat df) {
Calendar cal = Calendar.getInstance();
cal.setTime(contract.getFrom());
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
def startFrom = df.format(cal.getTime())
cal.setTime(contract.getBefore());
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
def endBefore = df.format(cal.getTime())
[startFrom, endBefore]
}
//получить дату словами
def getTextDate(Date date) {
getTextDate(date, true)
}
def getTextDate(Date date, boolean month) {
def result=''
def monthesRP = ['января','февраля','марта','апреля','мая','июня','июля','августа','сентября','октября','ноября','декабря']
Calendar cal = Calendar.getInstance()
cal.setTime(date);
if(month)result = cal.get(Calendar.DAY_OF_MONTH).toString()
result+=" "+monthesRP[cal.get(Calendar.MONTH)]
result+=" "+cal.get(Calendar.YEAR).toString()
if(month)result+=" г."
return result
}
//Сокращения ФИО
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
}
def getNN(BigDecimal value) {
return value == null ? BigDecimal.ZERO : value;
}
//форматирование чисел
def getNumber(BigDecimal number, boolean money = true, boolean scale = false) {
if (number == null) {
return "-"
}
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance()
symbols.setGroupingSeparator((char) ' ')
symbols.setDecimalSeparator((char) ',')
if (money){
DecimalFormat formatter = new DecimalFormat('###,###.00', symbols)
String result = formatter.format(number);
return result.startsWith(",") ? "0" + result : result;
} else {
//Временное решение чтобы, вывести норматив. 4 знака после запятой
if(scale){
DecimalFormat formatter = new DecimalFormat('###,###.####', symbols)
return formatter.format(number);
}else{
DecimalFormat formatter = new DecimalFormat('###,###.###', symbols)
return formatter.format(number);
}
}
}
//Временное решение, по формату отображения нулей после запятой
def getFormatNum(BigDecimal number, int s, boolean money = false){
if (number == null) {
return "-"
}
String formatString = '';
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance()
symbols.setGroupingSeparator((char) ' ')
symbols.setDecimalSeparator((char) ',')
switch(s){
case 1:
formatString = '###,###,###.#';
break;
case 2:
formatString = '###,###,###.##';
break;
case 3:
formatString = '###,###,###.###';
break;
case 4:
formatString = '###,###,###.####';
break;
case 5:
formatString = '###,###,###.######';
break;
}
DecimalFormat formatter = new DecimalFormat(formatString, symbols);
String result = formatter.format(number);
return result.startsWith(",") ? "0" + result : result;
}
def getContragentType(Contragent contragent) {
String name = contragent.getName();
if (name == null){
name = contragent.getShortName();
}
String inn = contragent.getInn();
ContragentType type = contragent.getType();
if (!StringUtils.isEmpty(name)) {
name = name.toLowerCase().trim();
if (name.startsWith("ип ") || name.endsWith(" ип") ||
name.contains(" ип ") ||
name.contains("инд.предп.") ||
name.contains("индивидуальный предприниматель")) {
type = ContragentType.INDIVIDUAL;
}
}
return type;
}
//Проверяем позиции на изменение контейнерной площадки
private Boolean changeCY(ContractPosition cp, ContractPosition prevCP){
if(prevCP == null) return true
def strCode = ""
def prevStrCode = ""
//Нужно отсортировать КП по номеру, перед конкатенацией
for(def item : cp.getContainerYards()){
strCode = strCode+item.getContainerYard().getCode()
}
for(def item : prevCP.getContainerYards()){
prevStrCode = prevStrCode+item.getContainerYard().getCode()
}
if(!strCode.equals(prevStrCode))return true
//Другие проверки
return false
}
//Проверяем позиции на изменение объекта недвижимости
private Boolean changeRE(ContractPosition cp, ContractPosition prevCP){
if(prevCP == null) return true
//Сравниваем кол-во р/е
if(prevCP.getContragentRealEstate().getCalculationAmount() != cp.getContragentRealEstate().getCalculationAmount())return true
//Сравниваем объемы по начислениям
BigDecimal totalVolumePosition = null
for(Accrual accrual : cp.getAccruals()){
totalVolumePosition=getNN(accrual.getAmountBase())
}
BigDecimal prevTotalVolumePosition = null
for(Accrual accrual : prevCP.getAccruals()){
prevTotalVolumePosition=getNN(accrual.getAmountBase())
}
if(!prevTotalVolumePosition.equals(totalVolumePosition))return true
//Другие проверки
if(prevCP.getIsFactCalculation() != cp.getIsFactCalculation())return true
return false
}
//Определяет тип КП, КГО или ТКО
private Boolean isKGO(ContainerYard cy){
for(def item : cy.getContainers()){
if(item.getCount() == null || item.getCount() == 0.0)continue
if(item.getType().getVolume() > new BigDecimal(6.0))return true
}
return false
}
private Boolean isKGO(ContainerWaste item){
if(item.getType().getVolume() > new BigDecimal(6.0))return true
return false
}
//Получаем коды КП с КГО и ТКО
private def getCYCodesPosition(ContractPosition cp){
//Определяем код КП
def strCodeCP = ""
for(def cpcy : cp.getContainerYards()){
def kgo = false
for(def container : cpcy.getContainerYard().getContainers()){
if(!isKGO(container)){kgo = true}
}
if(kgo)
{strCodeCP = strCodeCP+cpcy.getContainerYard().getCode()+"/"}
}
if(strCodeCP.endsWith("/")){
strCodeCP = strCodeCP.substring(0, strCodeCP.length() - 1)
}
return strCodeCP
}
private def getCYCodesKGOPosition(ContractPosition cp){
//Определяем код КП
def strCodeCP = ""
for(def cpcy : cp.getContainerYards()){
def kgo = false
for(def container : cpcy.getContainerYard().getContainers()){
if(isKGO(container))kgo = true
}
if(kgo)
{strCodeCP = strCodeCP+cpcy.getContainerYard().getCode()+"/"}
}
if(strCodeCP.endsWith("/")){
strCodeCP = strCodeCP.substring(0, strCodeCP.length() - 1)
}
return strCodeCP
}
/*
/log
*/
private _(Object obj, String options = ""){
String op = options
if(options.equals("for")){
for(def item : obj){
log(obj)
}
}
if(options.equals("")){
log(obj)
}
}
private log(Object obj){
log.debug(obj)
}