/**
* Axelor Business Solutions
*
* Copyright (C) 2016 Axelor (<http://axelor.com>).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.axelor.apps.account.service.batch;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.axelor.apps.account.db.MoveLine;
import com.axelor.apps.account.db.Reimbursement;
import com.axelor.apps.account.db.repo.AccountingBatchRepository;
import com.axelor.apps.account.db.repo.MoveLineRepository;
import com.axelor.apps.account.db.repo.MoveRepository;
import com.axelor.apps.account.db.repo.ReimbursementRepository;
import com.axelor.apps.account.exception.IExceptionMessage;
import com.axelor.apps.account.service.AccountingService;
import com.axelor.apps.account.service.ReimbursementExportService;
import com.axelor.apps.account.service.cfonb.CfonbExportService;
import com.axelor.apps.base.db.Company;
import com.axelor.apps.base.db.Partner;
import com.axelor.apps.base.db.repo.PartnerRepository;
import com.axelor.db.JPA;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.IException;
import com.axelor.exception.service.TraceBackService;
import com.axelor.i18n.I18n;
import com.google.inject.Inject;
public class BatchReimbursementExport extends BatchStrategy {
private final Logger log = LoggerFactory.getLogger( getClass() );
protected boolean stop = false;
protected BigDecimal totalAmount = BigDecimal.ZERO;
protected String updateCustomerAccountLog = "";
protected ReimbursementRepository reimbursementRepo;
protected PartnerRepository partnerRepository;
@Inject
public BatchReimbursementExport(ReimbursementExportService reimbursementExportService, CfonbExportService cfonbExportService, BatchAccountCustomer batchAccountCustomer,
ReimbursementRepository reimbursementRepo, PartnerRepository partnerRepository) {
super(reimbursementExportService, cfonbExportService, batchAccountCustomer);
this.reimbursementRepo = reimbursementRepo;
this.partnerRepository = partnerRepository;
AccountingService.setUpdateCustomerAccount(false);
}
@Override
protected void start() throws IllegalArgumentException, IllegalAccessException, AxelorException {
super.start();
Company company = batch.getAccountingBatch().getCompany();
switch (batch.getAccountingBatch().getReimbursementExportTypeSelect()) {
case AccountingBatchRepository.REIMBURSEMENT_EXPORT_TYPE_GENERATE:
try {
this.testAccountingBatchBankDetails(batch.getAccountingBatch());
reimbursementExportService.testCompanyField(company);
} catch (AxelorException e) {
TraceBackService.trace(new AxelorException("", e, e.getcategory()), IException.REIMBURSEMENT, batch.getId());
incrementAnomaly();
stop = true;
}
break;
case AccountingBatchRepository.REIMBURSEMNT_EXPORT_TYPE_EXPORT:
try {
this.testAccountingBatchBankDetails(batch.getAccountingBatch());
reimbursementExportService.testCompanyField(company);
cfonbExportService.testCompanyExportCFONBField(company);
} catch (AxelorException e) {
TraceBackService.trace(new AxelorException("", e, e.getcategory()), IException.REIMBURSEMENT, batch.getId());
incrementAnomaly();
stop = true;
}
break;
default:
TraceBackService.trace(new AxelorException(String.format(I18n.get(IExceptionMessage.BATCH_PAYMENT_SCHEDULE_1), batch.getAccountingBatch().getActionSelect()), IException.INCONSISTENCY));
incrementAnomaly();
stop = true;
}
checkPoint();
}
@Override
protected void process() {
if(!stop) {
Company company = batch.getAccountingBatch().getCompany();
switch (batch.getAccountingBatch().getReimbursementExportTypeSelect()) {
case AccountingBatchRepository.REIMBURSEMENT_EXPORT_TYPE_GENERATE:
this.runCreateReimbursementExport(company);
break;
case AccountingBatchRepository.REIMBURSEMNT_EXPORT_TYPE_EXPORT:
this.runReimbursementExportProcess(company);
updateCustomerAccountLog += batchAccountCustomer.updateAccountingSituationMarked(companyRepo.find(company.getId()));
break;
default:
break;
}
}
}
public void runCreateReimbursementExport(Company company) {
List<Reimbursement> reimbursementList = (List<Reimbursement>) reimbursementRepo.all().filter("self.statusSelect != ?1 AND self.statusSelect != ?2 AND self.company = ?3",
ReimbursementRepository.STATUS_REIMBURSED, ReimbursementRepository.STATUS_CANCELED, company).fetch();
int i=0;
for(Reimbursement reimbursement : reimbursementList) {
log.debug("Remboursement n° {}", reimbursement.getRef());
updateReimbursement(reimbursementRepo.find(reimbursement.getId()));
}
List<Partner> partnerList = (List<Partner>) partnerRepository.all().filter("?1 IN self.companySet = ?1", company).fetch();
for(Partner partner : partnerList) {
try {
partner = partnerRepository.find(partner.getId());
log.debug("Tiers n° {}", partner.getName());
if(reimbursementExportService.canBeReimbursed(partner, companyRepo.find(company.getId()))) {
List<MoveLine> moveLineList = (List<MoveLine>) moveLineRepo.all().filter("self.account.reconcileOk = 'true' AND self.fromSchedulePaymentOk = 'false' " +
"AND self.move.statusSelect = ?1 AND self.amountRemaining > 0 AND self.credit > 0 AND self.partner = ?2 AND self.company = ?3 AND " +
"self.reimbursementStatusSelect = ?4 ",
MoveRepository.STATUS_VALIDATED, partnerRepository.find(partner.getId()), companyRepo.find(company.getId()), MoveLineRepository.REIMBURSEMENT_STATUS_NULL).fetch();
log.debug("Liste des trop perçus : {}", moveLineList);
if(moveLineList != null && moveLineList.size() != 0) {
Reimbursement reimbursement = reimbursementExportService.runCreateReimbursement(moveLineList, companyRepo.find(company.getId()), partnerRepository.find(partner.getId()));
if(reimbursement != null) {
updateReimbursement(reimbursementRepo.find(reimbursement.getId()));
this.totalAmount = this.totalAmount.add(reimbursementRepo.find(reimbursement.getId()).getAmountToReimburse());
i++;
}
}
}
} catch (AxelorException e) {
TraceBackService.trace(new AxelorException(String.format(I18n.get("Tiers")+"%s", partnerRepository.find(partner.getId()).getName()), e, e.getcategory()), IException.REIMBURSEMENT, batch.getId());
incrementAnomaly();
} catch (Exception e) {
TraceBackService.trace(new Exception(String.format(I18n.get("Tiers")+"%s", partnerRepository.find(partner.getId()).getName()), e), IException.REIMBURSEMENT, batch.getId());
incrementAnomaly();
log.error("Bug(Anomalie) généré(e) pour le tiers {}", partnerRepository.find(partner.getId()).getName());
} finally {
if (i % 10 == 0) { JPA.clear(); }
}
}
}
public void runReimbursementExportProcess(Company company) {
int i=0;
// On récupère les remboursements dont les trop perçu ont été annulés
List<Reimbursement> reimbursementToCancelList = (List<Reimbursement>) reimbursementRepo.all()
.filter("self.company = ?1 and self.statusSelect = ?2 and self.amountToReimburse = 0", ReimbursementRepository.STATUS_VALIDATED, company).fetch();
// On annule les remboursements
for(Reimbursement reimbursement : reimbursementToCancelList) {
reimbursement.setStatusSelect(ReimbursementRepository.STATUS_CANCELED);
}
// On récupère les remboursement à rembourser
List<Reimbursement> reimbursementList = (List<Reimbursement>) reimbursementRepo.all()
.filter("self.company = ?1 and self.statusSelect = ?2 and self.amountToReimburse > 0", company, ReimbursementRepository.STATUS_VALIDATED).fetch();
List<Reimbursement> reimbursementToExport = new ArrayList<Reimbursement>();
for(Reimbursement reimbursement : reimbursementList) {
try {
reimbursement = reimbursementRepo.find(reimbursement.getId());
if(reimbursementExportService.canBeReimbursed(reimbursement.getPartner(), reimbursement.getCompany())) {
reimbursementExportService.reimburse(reimbursement, company);
updateReimbursement(reimbursementRepo.find(reimbursement.getId()));
reimbursementToExport.add(reimbursement);
this.totalAmount = this.totalAmount.add(reimbursementRepo.find(reimbursement.getId()).getAmountReimbursed());
i++;
}
} catch (AxelorException e) {
TraceBackService.trace(new AxelorException(String.format(I18n.get("Reimbursement")+" %s", reimbursementRepo.find(reimbursement.getId()).getRef()), e, e.getcategory()), IException.REIMBURSEMENT, batch.getId());
incrementAnomaly();
} catch (Exception e) {
TraceBackService.trace(new Exception(String.format(I18n.get("Reimbursement")+" %s", reimbursementRepo.find(reimbursement.getId()).getRef()), e), IException.REIMBURSEMENT, batch.getId());
incrementAnomaly();
log.error("Bug(Anomalie) généré(e) pour l'export du remboursement {}", reimbursementRepo.find(reimbursement.getId()).getRef());
} finally {
if (i % 10 == 0) { JPA.clear(); }
}
}
if(reimbursementToExport != null && reimbursementToExport.size() != 0) {
try {
reimbursementExportService.exportSepa(companyRepo.find(company.getId()), batchRepo.find(batch.getId()).getStartDate(), reimbursementToExport, batchRepo.find(batch.getId()).getAccountingBatch().getBankDetails());
} catch (Exception e) {
TraceBackService.trace(new Exception(String.format(I18n.get(IExceptionMessage.BATCH_REIMBURSEMENT_1), batch.getId()), e), IException.REIMBURSEMENT, batch.getId());
incrementAnomaly();
log.error("Bug(Anomalie) généré(e)e dans l'export SEPA - Batch {}", batch.getId());
}
try {
cfonbExportService.exportCFONB(companyRepo.find(company.getId()), batchRepo.find(batch.getId()).getStartDate(), reimbursementToExport, batchRepo.find(batch.getId()).getAccountingBatch().getBankDetails());
} catch (Exception e) {
TraceBackService.trace(new Exception(String.format(I18n.get(IExceptionMessage.BATCH_REIMBURSEMENT_1), batch.getId()), e), IException.REIMBURSEMENT, batch.getId());
incrementAnomaly();
log.error("Bug(Anomalie) généré(e)e dans l'export CFONB - Batch {}", batch.getId());
}
}
}
/**
* As {@code batch} entity can be detached from the session, call {@code Batch.find()} get the entity in the persistant context.
* Warning : {@code batch} entity have to be saved before.
*/
@Override
protected void stop() {
String comment = "";
batch = batchRepo.find(batch.getId());
switch (batch.getAccountingBatch().getReimbursementExportTypeSelect()) {
case AccountingBatchRepository.REIMBURSEMENT_EXPORT_TYPE_GENERATE:
comment = I18n.get(IExceptionMessage.BATCH_REIMBURSEMENT_2);
comment += String.format("\t* %s "+I18n.get(IExceptionMessage.BATCH_REIMBURSEMENT_3)+"\n", batch.getDone());
comment += String.format("\t* "+I18n.get(IExceptionMessage.BATCH_INTERBANK_PO_IMPORT_5)+" : %s \n", this.totalAmount);
break;
case AccountingBatchRepository.REIMBURSEMNT_EXPORT_TYPE_EXPORT:
comment = I18n.get(IExceptionMessage.BATCH_REIMBURSEMENT_4);
comment += String.format("\t* %s "+I18n.get(IExceptionMessage.BATCH_REIMBURSEMENT_5)+"\n", batch.getDone());
comment += String.format("\t* "+I18n.get(IExceptionMessage.BATCH_INTERBANK_PO_IMPORT_5)+" : %s \n", this.totalAmount);
comment += String.format("\t* ------------------------------- \n");
comment += String.format("\t* %s ", updateCustomerAccountLog);
break;
default:
break;
}
comment += String.format(I18n.get(com.axelor.apps.base.exceptions.IExceptionMessage.ALARM_ENGINE_BATCH_5), batch.getAnomaly());
super.stop();
addComment(comment);
}
}