/* * Copyright (C) 2014 bastian.venz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package eu.ggnet.dwoss.misc.op; import java.time.LocalDate; import java.util.*; import java.util.stream.Collectors; import javax.ejb.Stateless; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.persistence.EntityManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.ggnet.dwoss.event.UnitHistory; import eu.ggnet.dwoss.mandator.api.value.RepaymentCustomers; import eu.ggnet.dwoss.redtape.eao.DossierEao; import eu.ggnet.dwoss.redtape.entity.*; import eu.ggnet.dwoss.report.eao.ReportLineEao; import eu.ggnet.dwoss.report.emo.ReportEmo; import eu.ggnet.dwoss.report.entity.Report; import eu.ggnet.dwoss.report.entity.ReportLine; import eu.ggnet.dwoss.report.entity.ReportLine.SingleReferenceType; import eu.ggnet.dwoss.report.entity.partial.SimpleReportLine; import eu.ggnet.dwoss.rules.*; import eu.ggnet.dwoss.stock.assist.Stocks; import eu.ggnet.dwoss.stock.eao.StockUnitEao; import eu.ggnet.dwoss.stock.emo.StockTransactionEmo; import eu.ggnet.dwoss.stock.entity.*; import eu.ggnet.dwoss.util.UserInfoException; import static eu.ggnet.dwoss.rules.DocumentType.ANNULATION_INVOICE; import static eu.ggnet.dwoss.rules.DocumentType.CREDIT_MEMO; import static eu.ggnet.dwoss.rules.PositionType.UNIT; import static java.time.ZoneId.systemDefault; /** * * @author bastian.venz */ @Stateless public class ResolveRepaymentBean implements ResolveRepayment { private static final Logger L = LoggerFactory.getLogger(ResolveRepaymentBean.class); @Inject private ReportLineEao reportLineEao; @Inject private StockUnitEao stockUnitEao; @Inject private StockTransactionEmo stEmo; @Inject @Stocks private EntityManager stockEm; @Inject private Event<UnitHistory> history; @Inject private ReportEmo reportEmo; @Inject private DossierEao dossierEao; @Inject private RepaymentCustomers repaymentCustomers; @Override public List<ReportLine> getRepaymentLines(TradeName contractor) { List<ReportLine> findUnreportedUnits = reportLineEao.findUnreportedUnits(contractor, null, new Date()); // All return findUnreportedUnits.stream() .filter((l) -> { return l.getDocumentType() == ANNULATION_INVOICE || l.getDocumentType() == CREDIT_MEMO; }).collect(Collectors.toList()); } @Override public ResolveResult resolveUnit(String identifier, TradeName contractor, String arranger, String comment) throws UserInfoException { //search with refurbishid and serial number. List<SimpleReportLine> reportLines = reportLineEao.findReportLinesByIdentifiers(identifier.trim()); List<ReportLine> repaymentLines = getRepaymentLines(contractor); ReportLine line = null; List<Long> repaymentIds = repaymentLines.stream().map((l) -> l.getId()).collect(Collectors.toList()); for (SimpleReportLine reportLine : reportLines) { if ( repaymentIds.contains(reportLine.getId()) ) { line = reportLineEao.findById(reportLine.getId()); } } if ( line == null ) throw new UserInfoException("Es konnte keine ReportLine mit diesem Identifier gefunden werden"); if ( !line.getReports().isEmpty() ) throw new UserInfoException("ReportLine ist schon in einem Report.\nReports:" + line.getReports()); ReportLine reference = line.getReference(SingleReferenceType.WARRANTY); // Rolling out the unit if still in Stock. StockUnit stockUnit = line.getPositionType() == UNIT // Saftynet, e.g. unit annex shoud not clear units. ? stockUnitEao.findByRefurbishId(line.getRefurbishId()) : null; if ( stockUnit != null && stockUnit.isInTransaction() ) throw new UserInfoException("Unit is in einer StockTransaction. ID:" + stockUnit.getTransaction().getId()); ResolveResult msgs = new ResolveResult(); if ( stockUnit == null ) { msgs.stockMessage = "Es existiert keine Stock Unit (mehr) zu dem Gerät"; msgs.redTapeMessage = "Keine StockUnit, Kein Vorgang"; } else { LogicTransaction lt = stockUnit.getLogicTransaction(); long dossierId = lt.getDossierId(); Dossier dossier = dossierEao.findById(dossierId); if ( !repaymentCustomers.get(contractor).isPresent() || !repaymentCustomers.get(contractor).get().equals(dossier.getCustomerId()) ) { throw new UserInfoException("Unit is nicht auf einem Auftrag eines Repayment Customers. DossierId:" + dossier.getId()); } List<Document> activeDocuments = dossier.getActiveDocuments(DocumentType.BLOCK); if ( activeDocuments.size() != 1 ) { throw new UserInfoException("Der Gutschriftsvorgang " + dossier.toSimpleLine() + " ist fehlerhaft, entweder kein oder zu viele akive Blocker"); } Position pos = activeDocuments.get(0).getPositionByUniqueUnitId(stockUnit.getUniqueUnitId()); if ( pos == null ) { throw new UserInfoException("Auf Gutschriftsvorgang " + dossier.toSimpleLine() + " ist das Gerät " + stockUnit.toSimple() + " nicht auffindbar"); } msgs.redTapeMessage = "Kid: " + dossier.getCustomerId() + ", Vorgang:" + dossier.getIdentifier() + " wurde Gerät entfernt"; convertToComment(pos, arranger, comment); lt.remove(stockUnit); StockTransaction st = stEmo.requestRollOutPrepared(stockUnit.getStock().getId(), arranger, "Resolved Repayment"); st.addUnit(stockUnit); msgs.stockMessage = stockUnit.toSimple() + " aus Lager ausgerollt auf StockTransaction(id=" + st.getId() + ")"; history.fire(new UnitHistory(stockUnit.getUniqueUnitId(), "Resolved Repayment", arranger)); stEmo.completeRollOut(arranger, Arrays.asList(st)); stockEm.flush(); if ( lt.getUnits().isEmpty() ) { msgs.stockMessage += ", LogicTransaction " + lt.getId() + " ist jetzt leer, wird gelöscht"; stockEm.remove(lt); } } Date startOfYear = Date.from(LocalDate.of(LocalDate.now().getYear(), 1, 1).atStartOfDay(systemDefault()).toInstant()); Date endOfYear = Date.from(LocalDate.of(LocalDate.now().getYear(), 12, 31).atStartOfDay(systemDefault()).toInstant()); Report report = reportEmo.request(toReportName(contractor), contractor, startOfYear, endOfYear); line.setComment(comment); report.add(line); msgs.reportMessage = "Repayment Unit " + line.getRefurbishId() + " line " + line.getId() + " resolved in " + report.getName(); if ( reference != null ) { L.info("Warrenty Reference exist. Putted also into the report. ReportLine ID of Warrenty:{}", reference.getId()); reference.setComment(comment); report.add(reference); msgs.reportMessage += ", including warranty " + reference.getId(); } return msgs; } /** * This Returns the Name of a Report,based on contractor and year. * <p> * @param contractor * @return */ public static String toReportName(TradeName contractor) { return contractor.getName() + " Gutschriften " + LocalDate.now().getYear(); } private void convertToComment(Position position, String arranger, String comment) { position.setType(PositionType.COMMENT); position.setUniqueUnitId(0); position.setUniqueUnitProductId(0); position.setPrice(0); position.setAfterTaxPrice(0); position.setDescription("Entfernt durch Gutschrifstausgleich von " + arranger + ", war: " + position.getName() + ", Kommentar:" + comment); position.setName("Entfernt durch Gutschrifstausgleich von " + arranger); } }