/* * Copyright (C) 2014 GG-Net GmbH - Oliver Günther * * 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.receipt; import eu.ggnet.dwoss.mandator.api.value.DeleteCustomers; import eu.ggnet.dwoss.mandator.api.value.ScrapCustomers; import eu.ggnet.dwoss.mandator.api.value.PostLedger; import eu.ggnet.dwoss.redtape.entity.Dossier; import eu.ggnet.dwoss.redtape.entity.PositionBuilder; import eu.ggnet.dwoss.redtape.entity.Document; import eu.ggnet.dwoss.stock.entity.StockUnit; import eu.ggnet.dwoss.stock.entity.StockTransaction; import eu.ggnet.dwoss.stock.entity.LogicTransaction; import java.util.Arrays; import javax.ejb.Stateless; import javax.inject.Inject; import javax.persistence.EntityManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.ggnet.dwoss.redtape.assist.RedTapes; import eu.ggnet.dwoss.redtape.emo.DossierEmo; import eu.ggnet.dwoss.rules.PositionType; import eu.ggnet.dwoss.stock.assist.Stocks; import eu.ggnet.dwoss.stock.eao.StockUnitEao; import eu.ggnet.dwoss.stock.emo.LogicTransactionEmo; import eu.ggnet.dwoss.stock.emo.StockTransactionEmo; import eu.ggnet.dwoss.uniqueunit.assist.UniqueUnits; import eu.ggnet.dwoss.uniqueunit.eao.UniqueUnitEao; import eu.ggnet.dwoss.uniqueunit.entity.UniqueUnit; import eu.ggnet.dwoss.uniqueunit.format.UniqueUnitFormater; import eu.ggnet.dwoss.util.UserInfoException; import static eu.ggnet.dwoss.rules.SalesChannel.UNKNOWN; /** * Allows Scraping of Units. * * @a import static eu.ggnet.dwoss.rules.SalesChannel.UNKNOWN; uthor oliver.guenther */ @Stateless public class UnitDestroyerOperation implements UnitDestroyer { private final static Logger L = LoggerFactory.getLogger(UnitDestroyerOperation.class); @Inject @UniqueUnits private EntityManager uuEm; @Inject @Stocks private EntityManager stockEm; @Inject @RedTapes private EntityManager redTapeEm; @Inject private DeleteCustomers deleteCustomers; @Inject private ScrapCustomers scrapCustomers; @Inject private PostLedger postLedger; /** * Validates if a unit identified by refurbishedId is scrapable. * Throws Exception if: * <ul> * <li>No UniqueUnit,SopoUnit or StockUnit exists.</li> * <li>StockUnit is inTransaction</li> * <li>SopoUnit is in Auftrag or Balanced.</li> * </ul> * * @param refurbishId the refurbishedId * @return * @throws UserInfoException if not scrapable. */ @Override public UniqueUnit verifyScarpOrDeleteAble(String refurbishId) throws UserInfoException { UniqueUnitEao uniqueUnitEao = new UniqueUnitEao(uuEm); UniqueUnit uniqueUnit = uniqueUnitEao.findByIdentifier(UniqueUnit.Identifier.REFURBISHED_ID, refurbishId); if ( uniqueUnit == null ) throw new UserInfoException("Keine Gerät mit SopoNr " + refurbishId + " gefunden"); StockUnitEao stockUnitEao = new StockUnitEao(stockEm); StockUnit stockUnit = stockUnitEao.findByUniqueUnitId(uniqueUnit.getId()); if ( stockUnit == null ) throw new UserInfoException("Keine Lagergerät für SopoNr " + refurbishId + " gefunden, Verschrottung/Löschung unnötig"); if ( stockUnit.isInTransaction() ) throw new UserInfoException("StockUnit ist auf einer Transaktion, Verschrottung/Löschung unzulässig"); uniqueUnit.fetchEager(); return uniqueUnit; } /** * Delete the Unit. * Finds the StockUnit, destroys it via a Destroy Transaction. * Updates the UniqueUnit and SopoUnit in the internal comments, that it is destroyed. * Hint: For simplicity this method assumes, that verifyScarpOrDeleteAble was called, so no extra validation is done. * <p/> * @param uniqueUnit the unit to scrap * @param arranger the arranger * @param reason the reason */ @Override public void delete(UniqueUnit uniqueUnit, String reason, String arranger) { long cid = deleteCustomers.get(uniqueUnit.getContractor()).orElseThrow(() -> { return new IllegalArgumentException("No DeleteCustomer for " + uniqueUnit); }); scrapDelete(cid, "Löschen", uniqueUnit, reason, arranger); } /** * Scraps the Unit. * Finds the StockUnit, destroys it via a Destroy Transaction. * Updates the UniqueUnit and SopoUnit in the internal comments, that it is destroyed. * Hint: For simplicity this method assumes, that verifyScarpOrDeleteAble was called, so no extra validation is done. * <p/> * @param uniqueUnit the unit to scrap * @param arranger the arranger * @param reason the reason */ @Override public void scrap(final UniqueUnit uniqueUnit, final String reason, final String arranger) { long cid = scrapCustomers.get(uniqueUnit.getContractor()).orElseThrow(() -> { return new IllegalArgumentException("No ScrapCustomer for " + uniqueUnit); }); scrapDelete(cid, "Verschrottung", uniqueUnit, reason, arranger); } private void scrapDelete(final long targetCustomerId, final String operation, final UniqueUnit uniqueUnit, final String reason, final String arranger) { UniqueUnit uu = new UniqueUnitEao(uuEm).findById(uniqueUnit.getId()); StockTransactionEmo stockTransactionEmo = new StockTransactionEmo(stockEm); StockUnit stockUnit = new StockUnitEao(stockEm).findByUniqueUnitId(uu.getId()); Document doc = new DossierEmo(redTapeEm) .requestActiveDocumentBlock((int)targetCustomerId, "Blockaddresse KundenId " + targetCustomerId, "Erzeugung durch " + operation, arranger); Dossier dos = doc.getDossier(); doc.append(new PositionBuilder().setType(PositionType.UNIT) .setBookingAccount(postLedger.get(PositionType.UNIT).orElse(-1)) .setDescription(UniqueUnitFormater.toDetailedDiscriptionLine(uu)) .setName(UniqueUnitFormater.toPositionName(uu)) .setUniqueUnitId(uu.getId()) .setUniqueUnitProductId(uu.getProduct().getId()).createPosition()); doc.append(new PositionBuilder().setType(PositionType.COMMENT) .setBookingAccount(postLedger.get(PositionType.COMMENT).orElse(-1)) .setName(operation).setDescription(reason + " by " + arranger).createPosition()); LogicTransaction lt = new LogicTransactionEmo(stockEm).request(dos.getId()); lt.add(stockUnit); // Implicit removes it from an existing LogicTransaction StockTransaction st = stockTransactionEmo.requestDestroyPrepared(stockUnit.getStock().getId(), arranger, reason); st.addUnit(stockUnit); stockTransactionEmo.completeDestroy(arranger, Arrays.asList(st)); uu.addHistory(operation + " of Unit via " + st); uu.setInternalComment(uu.getInternalComment() + ", " + operation + " of Unit."); uu.setSalesChannel(UNKNOWN); L.info("Executed Operation {} for uniqueUnit(id={},refurbishId={}), added to LogicTransaction({}) and Dossier({})", operation, uniqueUnit.getId(), uniqueUnit.getRefurbishId(), lt.getId(), dos.getIdentifier()); } }