import com.haulmont.cuba.core.entity.Entity
import com.haulmont.cuba.core.global.*
import com.groupstp.rtneo.entity.*
import com.groupstp.rtneo.service.*
import com.groupstp.rtneo.core.bean.*
import com.haulmont.cuba.core.global.ViewRepository;
import com.haulmont.cuba.core.global.View;
import java.util.function.*;
import com.haulmont.cuba.core.TransactionalDataManager
import java.math.RoundingMode;
import org.apache.commons.collections4.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import com.haulmont.bali.util.Preconditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.diedavids.cuba.runtimediagnose.groovy.*
//Нужно ли делать снапшот? Если да, то нужно раскомментировать создание снапшотов
//в методах createContractForCRE и createSuppContractForCRE. А также в расчетах по среднему
//SnapshotHistoryService snapshotHistoryService = AppBeans.get(SnapshotHistoryService.NAME);
df = new SimpleDateFormat("dd.MM.yyyy");
//Только офферта
def onlyOffer = false
cleanFailed = true
cleanOffer = false
//Отрефакторить
//Период договоров
start = df.parse('01.01.2019')
end = df.parse('31.12.2019')
//Дата допа
contractDate = df.parse("30.06.2019")
Date year2020 = df.parse('01.01.2020')
interface MyPredicate <T, U, C>{boolean test(T t, U u, C c);}
MyPredicate<Date, Date, ContragentRealEstate> crePred1 = {from, to, cre ->
cre.getValidityFrom() == null || cre.getValidityFrom().compareTo(to)<=0}
MyPredicate<Date, Date, ContragentRealEstate> crePred2 = {from, to, cre ->
cre.getValidityFrom().compareTo(from)>=0 && cre.getValidityFrom().compareTo(to)<=0}
//Разделение объектов
LinkedHashMap<String, HashMap<String, Object>> includedPeriod = new HashMap<>();
includedPeriod.putIfAbsent("cre1", ["from": null, "to": df.parse('01.01.2019'), "pred" : crePred1])
includedPeriod.putIfAbsent("cre2", ["from": df.parse('02.01.2019'), "to": df.parse('30.04.2019'), "pred" : crePred2])
includedPeriod.putIfAbsent("cre3", ["from": df.parse('01.05.2019'), "to": df.parse('31.12.2019'), "pred" : crePred2])
includedPeriod.putIfAbsent("cre5", ["from": df.parse('31.12.2019'), "to": df.parse('31.12.2020'), "pred" : crePred2])
//Не заполнена дата или она меньше 01.01.2019
//Дата больше date0Cre2 но меньше date1Cre2
//Дата больше date1Cre3 и меньше date1Cre4
//Дата больше date1Cre4 и меньше dateCreEnd
CommitContext ctx = new CommitContext()
//Добавляем к уже существующему представлению дополнительное свойство isLiving
View viewCre = getViewCre()
//Список отработанных контрагентов для вывода в лог, если нужно
List<String> contragentsLoging = new ArrayList<>()
//Если нужно убрать признак принятия допа
List<Contract> suppContracts = new ArrayList<>()
Contract mainContract;
long stP = System.currentTimeMillis();
//363
//for(i=10; i<=13; i++){
// System.out.println(">>>>>>>>>>>>>>>>>>>Counter script = "+i.toString())
long stQ = System.currentTimeMillis();
//Отобрать которые не заходили
List<Contragent> contragents = dataManager.load(Contragent.class)
// .query('select distinct e from rtneo$ContragentRealEstate r join rtneo$Contragent e where r.contragent = e and (r.category.isLiving is null or r.category.isLiving=false) and not r.realEstate.name = \'Земельный участок\' and size(e.contracts)=0 and not e.id in (select t.entityId from rtneo$EntityesTemporarySet t) order by e.id')
// .query('select distinct e from rtneo$ContragentRealEstate r join rtneo$Contragent e on r.contragent = e where ((r.category.isLiving is null or r.category.isLiving=false) and not r.realEstate.name = \'Земельный участок\' and size(e.contracts)=0 and (r.validityFrom is null or r.validityFrom >= \'2019-01-01\') and not r.excludeFromAccounting = true) or (e.id in (select t.entityId from rtneo$EntityesTemporarySet t where not t.setName = \'CreatedContractAllRecalc30-09\')) order by e.id EXCEPT select distinct e from rtneo$Contragent e join rtneo$EntityesTemporarySet t where e.id = t.entityId and t.setName = \'CreatedContractAllRecalc30-09\'')
.query('select c from rtneo$Contragent c where c.id = \'251d2e41-b732-915c-138d-b5b09ff88ec3\'')
// .query('select distinct e from rtneo$ContragentRealEstate r join rtneo$Contragent e on r.contragent = e where (((r.category.isLiving is null or r.category.isLiving=false) and not r.realEstate.name = \'Земельный участок\' and size(e.contracts)=0 and (r.validityFrom is null or r.validityFrom >= \'2019-01-01\') and not r.excludeFromAccounting = true) or (e.id in (select t.entityId from rtneo$EntityesTemporarySet t where not t.setName = \'CreatedContractAllRecalc30-09\'))) and not e.id in (select t.entityId from rtneo$EntityesTemporarySet t where t.setName = \'CreatedContractAllRecalc30-09\')')
// .query('select distinct c from rtneo$Contragent c join rtneo$EntityesTemporarySet t on c.id = t.entityId where t.setName = \'oneIsLogin04-10-20CreatedContract\' order by c.id')
// .query('select distinct c from rtneo$Contragent c join rtneo$EntityesTemporarySet t on c.id = t.entityId where size(c.contracts) = 1 and t.setName = \'oneIsNoLogin04-10-20CreatedContract\' order by c.id')
// .query('select distinct c from rtneo$Contragent c join rtneo$EntityesTemporarySet t on c.id = t.entityId where t.setName = \'AllContragentCreateContract_15-10-20\' order by c.id')
// .query('select c from rtneo$Contragent c join rtneo$EntityesTemporarySet t on c.id = t.entityId where t.setName = \'AllContragentCreateContract_15-10-20\' and not c.id in (select t.entityId from rtneo$EntityesTemporarySet t where t.setName = \'AllContragentCreateContract_15-10-20-OK\' or t.setName = \'AllContragentCreateContract_15-10-20-Failed\') order by c.id')
// .firstResult(i*100)
// .maxResults(100)
.view(viewCre)
.list()
long endQ = System.currentTimeMillis();
_("Perfomance ${endQ-stQ}");
for(Contragent contragent : contragents){
_(contragent.getId().toString()+' - '+contragent.getName())
//Паттерн стратегия
// if(onlyOffer) mainContract = getMainContract(contragent)
//Отрефакторить
// HashMap<String, List> mapCreList = onlyOffer ? ['cre1' : getCREFromMainContract(mainContract, viewCre)] : getCREList(contragent, start, dateCre1)
//Получаем список объектов
SelCREStrategy creList = new CreList(contragent, includedPeriod)
creList.setLog(log)
HashMap<String, List> mapCreList = creList.getList()
mapCreList.keySet().each{_(it)}
_("CreList >> ${mapCreList}")
//Создаем договор и доп
boolean isCreated = false
if(mapCreList.isEmpty())continue
//Удалять старые договора!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if(cleanOffer)cleanOfferContracts(contragent)
HashMap<String, Object> paramsContract = new HashMap<>()
paramsContract.put("contragent", contragent)
paramsContract.put("start", start)
paramsContract.put("end", end)
for(String key : mapCreList.keySet()){
if(CollectionUtils.isEmpty(mapCreList.get(key)))continue
// isCreated = createContract(mapCreList.get(key), paramsContract, contragentsLoging)
CreateContractStrategy created = new CreateContract()
created.setLog(log)
isCreated = created.createContract(mapCreList.get(key), paramsContract, contragentsLoging)
}
if(isCreated){
HashMap<String, String> paramsSet = new HashMap<>()
paramsSet.put("entityName", "Contragent")
paramsSet.put("setName", "AllContragentCreateContract_15-10-20")
paramsSet.put("comment", "Создание договоров всем")
// addInTemporarySet(contragent, paramsSet, onlyOffer)
}
}
//}//FOR
long endP = System.currentTimeMillis();
_("Perfomance ${endP-stP}");
//Убираем признак принятия допа
//unaccepted(suppContracts)
_("*****************************************************************************")
//Список обработанных контрагентов
contragentsLoging.each({_(it)})
/**
*
*/
interface SelCREStrategy{
HashMap<String, List> getList();
}
class CreList implements SelCREStrategy{
Contragent contragent;
LinkedHashMap<String, HashMap<String, Object>> predications;
DataManager dataManager = AppBeans.get(DataManager.class)
GroovyConsoleLogger log;
CreList(Contragent contragent, LinkedHashMap<String, HashMap<String, Object>> predications) {
this.contragent = contragent
this.predications = predications
}
@Override
HashMap<String, List> getList() {
HashMap<String, List> mapCreList = new HashMap<>()
//Берем только не покрытые объекты
List<ContragentRealEstate> cres = dataManager.load(ContragentRealEstate.class)
.query('select c from rtneo$ContragentRealEstate c where (select count(cp) from rtneo$ContractPosition cp where cp.contragentRealEstate.id = c.id) = 0 and c.contragent.id = :contragent_id and not c.realEstate.name = \'Земельный участок\' and not c.excludeFromAccounting = true and (c.category.isLiving is null or c.category.isLiving=false)')
.parameter("contragent_id", contragent.getId())
.view(getViewCre1())
.list()
//Распределяем объекты по группам//contragent.getRealEstates()
for(ContragentRealEstate cre : cres){
boolean isFind = false
if(checkCRE(cre))continue
for(def item : predications.entrySet()){
MyPredicate<Date, Date, ContragentRealEstate> pred = (MyPredicate<Date, Date, ContragentRealEstate>)item.getValue().get("pred")
Date from = (Date)item.getValue().get("from")
Date to = (Date)item.getValue().get("to")
if(pred.test(from, to, cre)){
mapCreList.putIfAbsent(item.getKey(), new ArrayList<ContragentRealEstate>())
mapCreList.get(item.getKey()).add(cre)
isFind = true
break
}
}
if(!isFind)log.debug("No set CRE ${cre}")
}
return mapCreList
}
View getViewCre1(){
ViewRepository vRep = AppBeans.get(ViewRepository.NAME)
// return vRep.getView(Contragent.class, "contragent-create-contract")
// .addProperty("realEstates",
return vRep.getView(Contragent.class, "contragent-create-contract")
.getProperty("realEstates").getView()
.addProperty("exportStartDate")
.addProperty("type", vRep.getView(RealEstateType.class, "_minimal")
.addProperty("isLiving")
)
// )
}
private boolean checkCRE(ContragentRealEstate cre){
def df = new SimpleDateFormat("dd.MM.yyyy");
def start = df.parse('01.01.2019')
boolean isSkip = false
if(cre.getCategory() == null){
log.debug("CRE ${cre.getId()} not category!")
isSkip = true
}
//Исключаем жилые
if(cre.getType() != null && Boolean.TRUE.equals(cre.getType().getIsLiving())){
log.debug("CRE ${cre.getId()} is living!")
isSkip = true
}
//Исключаем исключенные из учета
if(Boolean.TRUE.equals(cre.getExcludeFromAccounting())){
log.debug("CRE ${cre.getId()} is exclude!")
isSkip = true
}
//Исключаем земельные уастки
if(cre.getRealEstate().getName() != null && cre.getRealEstate().getName().equals('Земельный участок')){
log.debug("CRE ${cre.getId()} is land plot!")
isSkip = true
}
if(cre.getExportStartDate() != null && cre.getExportStartDate().compareTo(start) > 1){
log.debug("CRE ${cre.getId()} start export!")
isSkip = true
}
if (CollectionUtils.isEmpty(cre.getContainerYards())) {
log.debug("Contragent >> ${cre.getContragent().getId()} ContainerYards empty")
isSkip = true
}
if(cre.getRealEstate().getArea() == null){
log.debug("CRE ${cre.getId()} area is null")
isSkip = true
}
// if(!Boolean.TRUE.equals(cre.getCategory().getUnit().getIsArea()) && (cre.getCalculationAmount() == null || cre.getCalculationAmount() != (int)cre.getCalculationAmount())){
if(!Boolean.TRUE.equals(cre.getCategory().getUnit().getIsArea())){
log.debug("CRE ${cre.getId()} no set calculationAmount")
// def calculationAmount = new BigDecimal(cre.getRealEstate().getArea()*cre.getCategory().getRatio()).setScale(0, RoundingMode.HALF_UP)
// if (calculationAmount.compareTo(BigDecimal.ZERO) == 0) {
// calculationAmount = BigDecimal.ONE;
// }
// cre.setCalculationAmount(calculationAmount)
// dataManager.commit(cre)
}
return isSkip
}
}
abstract class CreateContractAbstract {
ContractService contractService = AppBeans.get(ContractService.class)
CalculationWorker calculationWorker = AppBeans.get(CalculationWorker.NAME)
DataManager dataManager = AppBeans.get(DataManager.class)
GroovyConsoleLogger log;
Contract contract;
HashMap<String, Object> params;
Contract create(){
try{
this.contract = create(params)
log.debug("Contract good >> ${contract}")
}catch(Exception e){
log.debug("Contract fail >>: ${e}")
return contract
}
return contract
}
abstract Contract create(HashMap<String, Object> params);
void processContract(Contract contract, boolean accepted, boolean confirm, Date acceptanceDate) {
CalculationWorker calculationWorker = AppBeans.get(CalculationWorker.NAME)
TransactionalDataManager txManager = AppBeans.get(TransactionalDataManager.class)
//получаем предыдущий договор
Contract lastContract = null;
if (contract.getMainContract() != null) {
List<Contract> contracts = dataManager.load(Contract.class)
.query('select c from rtneo$Contract c where (c.mainContract.id=:mainContract OR c.id=:mainContract) ' +
'AND NOT c.id=:id ' +
'order by c.createTs DESC')
.parameter("mainContract", contract.getMainContract().getId())
.parameter("id", contract.getId())
.view("contract-edit")
.maxResults(1)
.list();
if (contracts.size() > 0) {
lastContract = contracts.get(0);
}
}
if (accepted) {
//делаем предыдущий неактивным
if (lastContract != null) {
makeContractObsolete(lastContract, false);
}
//текущий делаем активным
makeContractObsolete(contract, true);
//коммит
contract.setAccepted(accepted);
contract.setAcceptanceDate(acceptanceDate);
dataManager.commit(contract)
} else {
if(!confirm)
dataManager.remove(contract);
return
}
}
private void makeContractObsolete(Contract contract, Boolean reverse) {
contract = dataManager.reload(contract, "contract-edit");
CommitContext commitContext = new CommitContext();
for (ContractPosition position : contract.getPositions()) {
position.setRelevance(reverse);
commitContext.addInstanceToCommit(position);
}
dataManager.commit(commitContext);
}
}
class ContractForCRE extends CreateContractAbstract{
Contract create(HashMap<String, Object> params){
Preconditions.checkNotNullArgument(params.cres)
contract = contractService.createNewBaseContractClean(params.contragent as Contragent, params.start as Date, params.end as Date)
// contractService.fillBaseContract(contragent, contract, start, end)
contractService.fillBaseContractR(params.contragent as Contragent, contract, params.cres as List<ContragentRealEstate>);
return contract
}
}
class SuppContractForCRE extends CreateContractAbstract{
def df = new SimpleDateFormat("dd.MM.yyyy");
Contract create(HashMap<String, Object> params){
Preconditions.checkNotNullArgument(params.cres)
Preconditions.checkNotNullArgument(params.baseContract)
params.baseContract = dataManager.reload(params.baseContract as Entity, "contract-view-createSupplementaryAggrements")
contract = contractService.createNewSuppContractClean(params.contragent as Contragent, params.baseContract as Contract, params.start as Date, params.end as Date)
contractService.buildContractPositionsForRealEstateSupp(params.contragent as Contragent, contract, params.start as Date, params.cres as List<ContragentRealEstate>);
UnaryOperator<Contract> consumer = {e ->
e.setTemplate("MSG310820")
e.setDate(df.parse("30.06.2019"))
return e
}
processContract(consumer.apply(contract), true, false, params.acceptanceDate as Date)
List<Accrual> accruals = calculationWorker.calculateAccruals(contract.getFrom(), df.parse("31.12.2020"), params.contragent as Contragent, new Date(), contract);
return contract
}
}
interface CreateContractStrategy{
Contract getContract();
}
class CreateContract implements CreateContractStrategy{
DataManager dataManager = AppBeans.get(DataManager.class)
GroovyConsoleLogger log;
CreateContract(GroovyConsoleLogger log){
this.log = log
}
@Override
Contract getContract() {
return null
}
Boolean createContract(List<ContragentRealEstate> cres, HashMap<String, Object> params, List<String> contragentsLoging){
Preconditions.checkNotNullArgument(params.contragent)
Preconditions.checkNotNullArgument(params.start)
Preconditions.checkNotNullArgument(params.end)
params.putIfAbsent("cres", cres)
Contract contract;
Contract suppContract;
def isCreated = false
ContractForCRE contractForCRE = new ContractForCRE();
contractForCRE.setParams(params)
contractForCRE.setLog(log)
contract = contractForCRE.create()
if(PersistenceHelper.isNew(contract))dataManager.commit(contract)
params.putIfAbsent("baseContract", contract)
SuppContractForCRE suppContractForCRE = new SuppContractForCRE();
suppContractForCRE.setParams(params)
suppContractForCRE.setLog(log)
suppContract = suppContractForCRE.create()
// suppContract = createSuppContractForCRE(params.contragent, onlyOffer ? params.mainContract : contract, params.start, params.end, cres)
if(suppContract != null){
contragentsLoging.add("${params.contragent}|${params.contragent.getName()}")
isCreated = true
}
return isCreated
}
}
/**
*
*
*/
public Contract getMainContract(Contragent contragent){
def mainContract = dataManager.load(Contract.class)
.query('select c from rtneo$Contract c where c.mainContract is null and c.contragent.id = :contragent')
.parameter("contragent", contragent.getId())
.view("_local")
.firstResult(0)
.maxResults(1)
.optional().orElse(null)
Preconditions.checkNotNullArgument(mainContract)
return mainContract;
}
public void cleanContracts(Contragent contragent){
List<Contract> contracts = dataManager.load(Contract.class)
.query('select c from rtneo$Contract c where c.contragent.id = :contragent')
.parameter("contragent", contragent.getId())
.view("_minimal")
.list()
contracts.each({dataManager.remove(it)})
}
public void cleanContract(Contract contract){
dataManager.remove(contract)
}
public void cleanOfferContracts(Contragent contragent){
List<Contract> contracts = dataManager.load(Contract.class)
.query('select c from rtneo$Contract c where c.contragent.id = :contragent and c.template = \'MSG310820\'')
.parameter("contragent", contragent.getId())
.view("_minimal")
.list()
contracts.each({dataManager.remove(it)})
}
public void unaccepted(List<Contract> contracts){
CommitContext ctx = new CommitContext()
for(Contract contract : contracts){
contract.setAccepted(false);
contract.setAcceptanceDate(null);
ctx.addInstanceToCommit(contract)
}
dataManager.commit(ctx)
}
void addInTemporarySet(Contragent contragent, HashMap<String, String> params, Boolean onlyOffer){
Preconditions.checkNotNullArgument(params.get("entityName"))
Preconditions.checkNotNullArgument(params.get("setName"))
Preconditions.checkNotNullArgument(params.get("comment"))
EntityesTemporarySet tempSet = dataManager.create(EntityesTemporarySet.class)
tempSet.setEntityId(contragent.getId())
tempSet.setEntityName(params.get("entityName"))
tempSet.setSetVersion(1)
if(isCreated){
tempSet.setSetName(params.get("setName").toString()+"-OK")
tempSet.setSetComment(params.get("comment"))
}else{
tempSet.setSetName(params.get("setName").toString()+"-Failed")
tempSet.setSetComment(params.get("comment"))
if(cleanFailed)cleanContract(contragent)
_("${contragent} cleans contract")
}
dataManager.commit(tempSet)
}
View getViewCre(){
ViewRepository vRep = AppBeans.get(ViewRepository.NAME)
return vRep.getView(Contragent.class, "contragent-create-contract")
.addProperty("realEstates", vRep.getView(Contragent.class, "contragent-create-contract")
.getProperty("realEstates").getView()
.addProperty("exportStartDate")
.addProperty("type", vRep.getView(RealEstateType.class, "_minimal")
.addProperty("isLiving")
)
)
}
List<ContragentRealEstate> getCREFromMainContract(Contract mainContract, View viewCre){
return dataManager.load(ContragentRealEstate.class)
.query('select c.contragentRealEstate from rtneo$ContractPosition c where c.contract.id = :contract and c.contragentRealEstate is not null')
.parameter("contract", mainContract.getId())
.view(viewCre.getProperty("realEstates").getView())
.list()
}
/**
* Логирование
*/
import com.haulmont.cuba.core.app.serialization.EntitySerializationAPI;
import com.groupstp.rtneo.util.JsonUtil;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
private _(Object obj, String... options){
if(obj == null){log("LOG.ERROR: Object is null!!!");return}
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("LOG.ERROR: JSON entity serialization failed")}
}
if(option.equals("objJson")){
JsonUtil jsonUtil = AppBeans.get(JsonUtil.NAME)
try{log.(jsonUtil.toJson(obj))}
catch(Exception e){log("LOG.ERROR: JSON object serialization failed")}
}
if(option.equals("date")){
DateFormat df = new SimpleDateFormat("dd.MM.yyyy");
try{log(df.format(obj))}
catch(Exception e){log("LOG.ERROR: Failed date format")}
}
}
}
private log(Object obj){log.debug(obj)}