/* * 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.misc.op; import eu.ggnet.dwoss.progress.SubMonitor; import eu.ggnet.dwoss.progress.MonitorFactory; import eu.ggnet.dwoss.stock.assist.Stocks; import eu.ggnet.dwoss.stock.emo.StockTransactionEmo; import eu.ggnet.dwoss.stock.emo.Transfer; import eu.ggnet.dwoss.stock.entity.StockUnit; import eu.ggnet.dwoss.stock.entity.Stock; import eu.ggnet.dwoss.uniqueunit.entity.UniqueUnit; import java.util.*; import java.util.Map.Entry; import java.util.stream.Collectors; import javax.ejb.Stateless; import javax.inject.Inject; import javax.persistence.EntityManager; import org.slf4j.*; import eu.ggnet.dwoss.stock.eao.StockUnitEao; import eu.ggnet.dwoss.stock.model.SalesChannelLine; import eu.ggnet.dwoss.uniqueunit.assist.UniqueUnits; import eu.ggnet.dwoss.uniqueunit.eao.UniqueUnitEao; import static eu.ggnet.dwoss.uniqueunit.entity.PriceType.*; import eu.ggnet.dwoss.uniqueunit.entity.UniqueUnit.Equipment; import eu.ggnet.dwoss.uniqueunit.entity.UniqueUnit.Identifier; import eu.ggnet.dwoss.uniqueunit.format.ProductFormater; import eu.ggnet.dwoss.util.UserInfoException; @Stateless public class SalesChannelHandlerOperation implements SalesChannelHandler { public static class LastCharsRefurbishIdSorter implements Comparator<SalesChannelLine> { // Sorts by last Character @Override public int compare(SalesChannelLine s1, SalesChannelLine s2) { String o1 = s1.getRefurbishedId(); String o2 = s2.getRefurbishedId(); if ( o1.length() < 3 || o2.length() < 3 ) return o1.compareTo(o2); return o1.substring(o1.length() - 2).compareTo(o2.substring(o2.length() - 2)); } } private final Logger L = LoggerFactory.getLogger(SalesChannelHandlerOperation.class); @Inject @Stocks private EntityManager stockEm; @Inject @UniqueUnits private EntityManager uuEm; @Inject private MonitorFactory monitorFactory; /** * Returns all units, which are in a stock. Units which are on a transaction, are not displayed. * * TODO: Turn it around. Fist take all StockUnits, which are not in a transaction. Then filter them against the SopoUnit information * <p/> * @return all units, which are in a stock */ @Override public List<SalesChannelLine> findAvailableUnits() { SubMonitor m = monitorFactory.newSubMonitor("Verkaufskanalmanager vorbereiten", 100); m.setLogger(L); m.start(); final UniqueUnitEao uniqueUnitService = new UniqueUnitEao(uuEm); List<SalesChannelLine> lines = new ArrayList<>(); m.message("Loading all available units."); List<StockUnit> stockUnits = new StockUnitEao(stockEm).findByNoTransaction(); m.worked(10); m.setWorkRemaining(stockUnits.size() + 5); for (StockUnit stockUnit : stockUnits) { m.worked(1, "Handling SopoNr " + stockUnit.getRefurbishId()); UniqueUnit uniqueUnit = uniqueUnitService.findById(stockUnit.getUniqueUnitId()); if ( uniqueUnit == null ) throw new RuntimeException( "StockUnit(id=" + stockUnit.getId() + ",uniqueUnitId=" + stockUnit.getUniqueUnitId() + ") has no uniqueUnit"); if ( uniqueUnit.getProduct() == null ) L.warn("UniqueUnit(id=" + uniqueUnit.getId() + ").product==null"); lines.add( SalesChannelLine.builder() .unitId(stockUnit.getId()) .refurbishedId(uniqueUnit.getRefurbishId()) .description(ProductFormater.toName(uniqueUnit.getProduct())) .comment((uniqueUnit.getEquipments().contains(Equipment.ORIGINAL_BOXED) ? "Originalkarton, " : "") + (uniqueUnit.getCondition().getNote())) .retailerPrice(uniqueUnit.getPrice(RETAILER)) .customerPrice(uniqueUnit.getPrice(CUSTOMER)) .stockName(stockUnit.getStock().getName()) .salesChannel(uniqueUnit.getSalesChannel()) .originalSalesChannel(uniqueUnit.getSalesChannel()) .stockId(stockUnit.getStock().getId()).build() ); m.worked(1); } m.finish(); return lines; } /** * Updates the salesChanel of all supplied units * <p/> * @param lines a list of salesChannelLines, must not be null. * @param arranger * @param transactionComment * @return true if something was changed. * @throws de.dw.util.UserInfoException */ @Override public boolean update(final List<SalesChannelLine> lines, String arranger, String transactionComment) throws UserInfoException { SubMonitor m = monitorFactory.newSubMonitor("Import der Verkaufskanäle", 100); m.start(); Map<Stock, List<Integer>> destinationsWithStockUnitIds = lines .stream() .filter(l -> l.getDestination() != null) // No Destination change .sorted(new LastCharsRefurbishIdSorter()) // Sort .collect(Collectors.groupingBy(SalesChannelLine::getDestination, Collectors.mapping(SalesChannelLine::getUnitId, Collectors.toList()))); StockTransactionEmo emo = new StockTransactionEmo(stockEm); SortedMap<Integer, String> histories = new TreeMap<>(); for (Entry<Stock, List<Integer>> entry : destinationsWithStockUnitIds.entrySet()) { histories.putAll(emo.prepare(Transfer.builder() .destinationStockId(entry.getKey().getId()) .stockUnitIds(entry.getValue()) .arranger(arranger) .comment(transactionComment) .maxTransactionSize(10) .build(), m)); } m.setWorkRemaining(lines.size()); UniqueUnitEao uniqueUnitEao = new UniqueUnitEao(uuEm); boolean hasChanged = false; for (SalesChannelLine line : lines) { m.worked(1, "verarbeite " + line.getRefurbishedId()); if ( !line.hasChanged() ) continue; hasChanged = true; UniqueUnit uu = uniqueUnitEao.findByIdentifier(Identifier.REFURBISHED_ID, line.getRefurbishedId()); uu.setSalesChannel(line.getSalesChannel()); uu.addHistory("SalesChannel set to " + line.getSalesChannel() + " by " + arranger); if ( histories.containsKey(uu.getId()) ) uu.addHistory(histories.get(uu.getId())); } m.finish(); return hasChanged; } }