/* * Copyright 2011, MyCellar * * This file is part of MyCellar. * * MyCellar 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. * * MyCellar 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 MyCellar. If not, see <http://www.gnu.org/licenses/>. */ package fr.mycellar.application.stock.impl; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import jpasearch.repository.query.builder.SearchBuilder; import org.joda.time.LocalDate; import fr.mycellar.application.shared.AbstractSimpleService; import fr.mycellar.application.stock.MovementService; import fr.mycellar.application.stock.StockService; import fr.mycellar.domain.shared.exception.BusinessError; import fr.mycellar.domain.shared.exception.BusinessException; import fr.mycellar.domain.stock.Arrival; import fr.mycellar.domain.stock.ArrivalBottle; import fr.mycellar.domain.stock.Bottle; import fr.mycellar.domain.stock.Cellar; import fr.mycellar.domain.stock.Drink; import fr.mycellar.domain.stock.DrinkBottle; import fr.mycellar.domain.stock.Stock; import fr.mycellar.domain.stock.Stock_; import fr.mycellar.infrastructure.stock.repository.StockRepository; /** * @author speralta */ @Named @Singleton public class StockServiceImpl extends AbstractSimpleService<Stock, StockRepository> implements StockService { private StockRepository stockRepository; private MovementService movementService; @Override public void drink(Drink drink) throws BusinessException { for (DrinkBottle drinkBottle : drink.getDrinkBottles()) { removeFromStock(drinkBottle.getCellar(), drinkBottle.getBottle(), drinkBottle.getQuantity(), drink.getDate(), drink.getDrinkWith(), 0); } } @Override public void stock(Arrival arrival) throws BusinessException { Cellar cellar = arrival.getCellar(); float unitCharges = arrival.getCharges() / arrival.getArrivalBottles().size(); for (ArrivalBottle arrivalBottle : arrival.getArrivalBottles()) { Bottle bottle = arrivalBottle.getBottle(); addToStock(cellar, bottle, arrivalBottle.getQuantity(), arrival.getDate(), unitCharges, arrivalBottle.getPrice(), arrival.getSource()); } } @Override public Stock addToStock(Cellar cellar, Bottle bottle, Integer quantity, LocalDate date, float charges, float price, String source) throws BusinessException { Stock stock = updateStock(cellar, bottle, quantity); // Use cellar and bottle from stock, they could have been merged. movementService.createInput(stock.getCellar(), stock.getBottle(), quantity, date, charges, price, source); return stock; } @Override public Stock removeFromStock(Cellar cellar, Bottle bottle, Integer quantity, LocalDate date, String destination, float price) throws BusinessException { Stock stock = updateStock(cellar, bottle, -quantity); // Use cellar and bottle from stock, they could have been merged. movementService.createOutput(stock.getCellar(), stock.getBottle(), quantity, date, destination, price); return stock; } @Override public Stock updateStock(Cellar cellar, Bottle bottle, Integer quantity) throws BusinessException { Stock stock = findStock(bottle, cellar); if (stock == null) { stock = new Stock(); stock.setBottle(bottle); stock.setCellar(cellar); stock.setQuantity(0); } stock.setQuantity(stock.getQuantity() + quantity); if (stock.getQuantity() == 0) { stockRepository.delete(stock); return stock; } else { validate(stock); return stockRepository.save(stock); } } @Override public Stock findStock(Bottle bottle, Cellar cellar) { if ((bottle == null) || (bottle.getFormat() == null) || !bottle.getFormat().isIdSet() || (bottle.getWine() == null) || !bottle.getWine().isIdSet()) { return null; } return stockRepository.findUniqueOrNone(new SearchBuilder<Stock>() // .on(Stock_.bottle).equalsTo(bottle) // .on(Stock_.cellar).equalsTo(cellar).build()); } @Override public void validate(Stock entity) throws BusinessException { Stock existing = findStock(entity.getBottle(), entity.getCellar()); if ((existing != null) && ((entity.getId() == null) || !existing.getId().equals(entity.getId()))) { throw new BusinessException(BusinessError.STOCK_00001); } if (entity.getQuantity() < 0) { throw new BusinessException(BusinessError.STOCK_00002); } } @Override protected void deleteInternal(Stock entity) throws BusinessException { if (entity.getQuantity() > 0) { Stock removed = removeFromStock(entity.getCellar(), entity.getBottle(), entity.getQuantity(), new LocalDate(), "Régularisation", 0); super.deleteInternal(removed); } super.deleteInternal(entity); } @Override protected Stock saveInternal(Stock entity) throws BusinessException { Stock existing = findStock(entity.getBottle(), entity.getCellar()); if (existing != null) { if (existing.getQuantity() > entity.getQuantity()) { return removeFromStock(entity.getCellar(), entity.getBottle(), existing.getQuantity() - entity.getQuantity(), new LocalDate(), "Régularisation", 0); } else if (existing.getQuantity() < entity.getQuantity()) { return addToStock(entity.getCellar(), entity.getBottle(), entity.getQuantity() - existing.getQuantity(), new LocalDate(), 0, 0, "Régularisation"); } } else if (entity.getQuantity() >= 0) { return addToStock(entity.getCellar(), entity.getBottle(), entity.getQuantity(), new LocalDate(), 0, 0, "Régularisation"); } return super.saveInternal(entity); } @Override protected StockRepository getRepository() { return stockRepository; } @Inject public void setStockRepository(StockRepository stockRepository) { this.stockRepository = stockRepository; } @Inject public void setMovementService(MovementService movementService) { this.movementService = movementService; } }