Java tutorial
/** * Axelor Business Solutions * * Copyright (C) 2015 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.debtrecovery; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import javax.persistence.Query; import org.joda.time.LocalDate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.axelor.apps.account.db.Account; import com.axelor.apps.account.db.AccountConfig; import com.axelor.apps.account.db.Invoice; import com.axelor.apps.account.db.Move; import com.axelor.apps.account.db.MoveLine; import com.axelor.apps.account.db.Reconcile; import com.axelor.apps.account.db.repo.MoveLineRepository; import com.axelor.apps.account.db.repo.MoveRepository; import com.axelor.apps.account.service.ReconcileService; import com.axelor.apps.account.service.config.AccountConfigService; import com.axelor.apps.account.service.move.MoveLineService; import com.axelor.apps.account.service.move.MoveService; import com.axelor.apps.base.db.Company; import com.axelor.apps.base.db.Partner; import com.axelor.apps.base.service.administration.GeneralService; import com.axelor.db.JPA; import com.axelor.exception.AxelorException; import com.axelor.inject.Beans; import com.google.inject.Inject; import com.google.inject.persist.Transactional; public class DoubtfulCustomerService { private final Logger log = LoggerFactory.getLogger(getClass()); protected MoveService moveService; protected MoveRepository moveRepo; protected MoveLineService moveLineService; protected MoveLineRepository moveLineRepo; protected ReconcileService reconcileService; protected AccountConfigService accountConfigService; protected LocalDate today; @Inject public DoubtfulCustomerService(MoveService moveService, MoveRepository moveRepo, MoveLineService moveLineService, MoveLineRepository moveLineRepo, ReconcileService reconcileService, AccountConfigService accountConfigService) { this.moveService = moveService; this.moveRepo = moveRepo; this.moveLineService = moveLineService; this.moveLineRepo = moveLineRepo; this.reconcileService = reconcileService; this.accountConfigService = accountConfigService; this.today = Beans.get(GeneralService.class).getTodayDate(); } /** * Procdure permettant de vrifier le remplissage des champs dans la socit, ncessaire au traitement du passage en client douteux * @param company * Une socit * @throws AxelorException */ public void testCompanyField(Company company) throws AxelorException { AccountConfig accountConfig = accountConfigService.getAccountConfig(company); accountConfigService.getDoubtfulCustomerAccount(accountConfig); accountConfigService.getMiscOperationJournal(accountConfig); accountConfigService.getSixMonthDebtPassReason(accountConfig); accountConfigService.getThreeMonthDebtPassReason(accountConfig); } /** * * Procdure permettant de crer les critures de passage en client douteux pour chaque criture de facture * @param moveLineList * Une liste d'critures de facture * @param doubtfulCustomerAccount * Un compte client douteux * @param debtPassReason * Un motif de passage en client douteux * @throws AxelorException */ public void createDoubtFulCustomerMove(List<Move> moveList, Account doubtfulCustomerAccount, String debtPassReason) throws AxelorException { for (Move move : moveList) { this.createDoubtFulCustomerMove(move, doubtfulCustomerAccount, debtPassReason); } } /** * * Procdure permettant de crer les critures de passage en client douteux pour chaque criture de facture * @param moveLineList * Une liste d'critures de facture * @param doubtfulCustomerAccount * Un compte client douteux * @param debtPassReason * Un motif de passage en client douteux * @throws AxelorException */ @Transactional(rollbackOn = { AxelorException.class, Exception.class }) public void createDoubtFulCustomerMove(Move move, Account doubtfulCustomerAccount, String debtPassReason) throws AxelorException { log.debug("Ecriture concerne : {} ", move.getReference()); BigDecimal totalAmountRemaining = BigDecimal.ZERO; Company company = move.getCompany(); Partner partner = move.getPartner(); Move newMove = moveService.getMoveCreateService().createMove( company.getAccountConfig().getMiscOperationJournal(), company, move.getInvoice(), partner, move.getPaymentMode()); int ref = 1; List<Reconcile> reconcileList = new ArrayList<Reconcile>(); List<MoveLine> moveLineList = move.getMoveLineList(); for (MoveLine moveLine : moveLineList) { if (moveLine.getAccount().getReconcileOk() && moveLine.getAmountRemaining().compareTo(BigDecimal.ZERO) > 0 && moveLine.getAccount() != doubtfulCustomerAccount && moveLine.getDebit().compareTo(BigDecimal.ZERO) > 0) { BigDecimal amountRemaining = moveLine.getAmountRemaining(); // Ecriture au crdit sur le 411 MoveLine creditMoveLine = moveLineService.createMoveLine(newMove, moveLine.getPartner(), moveLine.getAccount(), amountRemaining, false, today, ref, null); newMove.getMoveLineList().add(creditMoveLine); Reconcile reconcile = reconcileService.createReconcile(moveLine, creditMoveLine, amountRemaining); reconcileList.add(reconcile); totalAmountRemaining = totalAmountRemaining.add(amountRemaining); ref++; } } // Ecriture au dbit sur le 416 (client douteux) MoveLine debitMoveLine = moveLineService.createMoveLine(newMove, newMove.getPartner(), doubtfulCustomerAccount, totalAmountRemaining, true, today, ref, null); newMove.getMoveLineList().add(debitMoveLine); debitMoveLine.setPassageReason(debtPassReason); moveService.getMoveValidateService().validateMove(newMove); moveRepo.save(newMove); for (Reconcile reconcile : reconcileList) { reconcileService.confirmReconcile(reconcile); } this.invoiceProcess(newMove, doubtfulCustomerAccount, debtPassReason); } public void createDoubtFulCustomerRejectMove(List<MoveLine> moveLineList, Account doubtfulCustomerAccount, String debtPassReason) throws AxelorException { for (MoveLine moveLine : moveLineList) { this.createDoubtFulCustomerRejectMove(moveLine, doubtfulCustomerAccount, debtPassReason); } } /** * Procdure permettant de crer les critures de passage en client douteux pour chaque ligne d'criture de rejet de facture * @param moveLineList * Une liste de lignes d'critures de rejet de facture * @param doubtfulCustomerAccount * Un compte client douteux * @param debtPassReason * Un motif de passage en client douteux * @throws AxelorException */ @Transactional(rollbackOn = { AxelorException.class, Exception.class }) public void createDoubtFulCustomerRejectMove(MoveLine moveLine, Account doubtfulCustomerAccount, String debtPassReason) throws AxelorException { log.debug("Ecriture concerne : {} ", moveLine.getName()); Company company = moveLine.getMove().getCompany(); Partner partner = moveLine.getPartner(); Move newMove = moveService.getMoveCreateService().createMove( company.getAccountConfig().getMiscOperationJournal(), company, null, partner, moveLine.getMove().getPaymentMode()); List<Reconcile> reconcileList = new ArrayList<Reconcile>(); BigDecimal amountRemaining = moveLine.getAmountRemaining(); // Ecriture au crdit sur le 411 MoveLine creditMoveLine = moveLineService.createMoveLine(newMove, partner, moveLine.getAccount(), amountRemaining, false, today, 1, null); newMove.addMoveLineListItem(creditMoveLine); Reconcile reconcile = reconcileService.createReconcile(moveLine, creditMoveLine, amountRemaining); reconcileList.add(reconcile); reconcileService.confirmReconcile(reconcile); // Ecriture au dbit sur le 416 (client douteux) MoveLine debitMoveLine = moveLineService.createMoveLine(newMove, newMove.getPartner(), doubtfulCustomerAccount, amountRemaining, true, today, 2, null); newMove.getMoveLineList().add(debitMoveLine); debitMoveLine.setInvoiceReject(moveLine.getInvoiceReject()); debitMoveLine.setPassageReason(debtPassReason); moveService.getMoveValidateService().validateMove(newMove); moveRepo.save(newMove); this.invoiceRejectProcess(debitMoveLine, doubtfulCustomerAccount, debtPassReason); } /** * Procdure permettant de mettre jour le motif de passage en client douteux, et crer l'vnement li. * @param moveList * Une liste d'citure de facture * @param doubtfulCustomerAccount * Un compte client douteux * @param debtPassReason * Un motif de passage en client douteux */ public void updateDoubtfulCustomerMove(List<Move> moveList, Account doubtfulCustomerAccount, String debtPassReason) { for (Move move : moveList) { for (MoveLine moveLine : move.getMoveLineList()) { if (moveLine.getAccount().equals(doubtfulCustomerAccount) && moveLine.getDebit().compareTo(BigDecimal.ZERO) > 0) { moveLine.setPassageReason(debtPassReason); moveLineRepo.save(moveLine); break; } } } } /** * Procdure permettant de mettre jour les champs de la facture avec la nouvelle criture de dbit sur le compte 416 * @param move * La nouvelle criture de dbit sur le compte 416 * @param doubtfulCustomerAccount * Un compte client douteux * @param debtPassReason * Un motif de passage en client douteux * @throws AxelorException */ public Invoice invoiceProcess(Move move, Account doubtfulCustomerAccount, String debtPassReason) throws AxelorException { Invoice invoice = move.getInvoice(); if (invoice != null) { invoice.setOldMove(invoice.getMove()); invoice.setMove(move); invoice.setPartnerAccount(doubtfulCustomerAccount); invoice.setDoubtfulCustomerOk(true); // Recalcule du restant payer de la facture invoice.setCompanyInTaxTotalRemaining(moveService.getMoveToolService().getInTaxTotalRemaining(invoice)); } return invoice; } /** * Procdure permettant de mettre jour les champs d'une facture rejete avec la nouvelle criture de dbit sur le compte 416 * @param move * La nouvelle ligne d'criture de dbit sur le compte 416 * @param doubtfulCustomerAccount * Un compte client douteux * @param debtPassReason * Un motif de passage en client douteux */ public Invoice invoiceRejectProcess(MoveLine moveLine, Account doubtfulCustomerAccount, String debtPassReason) { Invoice invoice = moveLine.getInvoiceReject(); invoice.setRejectMoveLine(moveLine); // invoice.setPartnerAccount(doubtfulCustomerAccount); invoice.setDoubtfulCustomerOk(true); return invoice; } /** * Fonction permettant de rcuprer les critures de facture transfrer sur le compte client douteux * @param rule * Le rgle appliquer : * <ul> * <li>0 = Crance de + 6 mois</li> * <li>1 = Crance de + 3 mois</li> * </ul> * @param doubtfulCustomerAccount * Le compte client douteux * @param company * La socit * @return * Les critures de facture transfrer sur le compte client douteux */ public List<Move> getMove(int rule, Account doubtfulCustomerAccount, Company company) { LocalDate date = null; switch (rule) { //Crance de + 6 mois case 0: date = this.today.minusMonths(company.getAccountConfig().getSixMonthDebtMonthNumber()); break; //Crance de + 3 mois case 1: date = this.today.minusMonths(company.getAccountConfig().getThreeMonthDebtMontsNumber()); break; default: break; } log.debug("Date de crance prise en compte : {} ", date); String request = "SELECT DISTINCT m FROM MoveLine ml, Move m WHERE ml.move = m AND ml.company.id = " + company.getId() + " AND ml.account.reconcileOk = 'true' " + "AND ml.invoice IS NOT NULL AND ml.amountRemaining > 0.00 AND ml.debit > 0.00 AND ml.dueDate < '" + date.toString() + "' AND ml.account.id != " + doubtfulCustomerAccount.getId(); log.debug("Requete : {} ", request); Query query = JPA.em().createQuery(request); @SuppressWarnings("unchecked") List<Move> moveList = query.getResultList(); return moveList; } /** * Fonction permettant de rcuprer les lignes d'criture de rejet de facture transfrer sur le compte client douteux * @param rule * Le rgle appliquer : * <ul> * <li>0 = Crance de + 6 mois</li> * <li>1 = Crance de + 3 mois</li> * </ul> * @param doubtfulCustomerAccount * Le compte client douteux * @param company * La socit * @return * Les lignes d'criture de rejet de facture transfrer sur le comtpe client douteux */ public List<? extends MoveLine> getRejectMoveLine(int rule, Account doubtfulCustomerAccount, Company company) { LocalDate date = null; List<? extends MoveLine> moveLineList = null; switch (rule) { //Crance de + 6 mois case 0: date = this.today.minusMonths(company.getAccountConfig().getSixMonthDebtMonthNumber()); moveLineList = moveLineRepo.all().filter("self.company = ?1 AND self.account.reconcileOk = 'true' " + "AND self.invoiceReject IS NOT NULL AND self.amountRemaining > 0.00 AND self.debit > 0.00 AND self.dueDate < ?2 " + "AND self.account != ?3", company, date, doubtfulCustomerAccount).fetch(); break; //Crance de + 3 mois case 1: date = this.today.minusMonths(company.getAccountConfig().getThreeMonthDebtMontsNumber()); moveLineList = moveLineRepo.all().filter("self.company = ?1 AND self.account.reconcileOk = 'true' " + "AND self.invoiceReject IS NOT NULL AND self.amountRemaining > 0.00 AND self.debit > 0.00 AND self.dueDate < ?2 " + "AND self.account != ?3", company, date, doubtfulCustomerAccount).fetch(); break; default: break; } log.debug("Date de crance prise en compte : {} ", date); return moveLineList; } }