/* * This program is part of the OpenLMIS logistics management information * system platform software. * * Copyright © 2015 ThoughtWorks, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 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. For additional * information contact info@OpenLMIS.org */ package org.openlmis.core.model; import android.support.annotation.NonNull; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; import com.j256.ormlite.dao.ForeignCollection; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.field.ForeignCollectionField; import com.j256.ormlite.table.DatabaseTable; import org.openlmis.core.manager.MovementReasonManager; import org.openlmis.core.utils.ListUtil; import org.roboguice.shaded.goole.common.base.Predicate; import org.roboguice.shaded.goole.common.collect.FluentIterable; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import lombok.Getter; import lombok.Setter; @Getter @Setter @DatabaseTable(tableName = "stock_cards") public class StockCard extends BaseModel implements Comparable<StockCard> { public static final String DIVIDER = ","; @Deprecated @DatabaseField String expireDates; @Expose @SerializedName("product") @DatabaseField(foreign = true, foreignAutoRefresh = true) Product product; @Expose @SerializedName("stockMovementItems") private List<StockMovementItem> stockMovementItemsWrapper; @ForeignCollectionField() private ForeignCollection<StockMovementItem> foreignStockMovementItems; @Expose @DatabaseField @SerializedName("stockOnHand") long stockOnHand; @ForeignCollectionField() private ForeignCollection<LotOnHand> foreignLotOnHandList; @Expose @SerializedName("lotsOnHand") private List<LotOnHand> lotOnHandListWrapper; @DatabaseField private float avgMonthlyConsumption = -1; @Override public int compareTo(@NonNull StockCard another) { return product == null ? 0 : product.compareTo(another.getProduct()); } public StockMovementItem generateInitialStockMovementItem() { StockMovementItem initInventory = new StockMovementItem(this); initInventory.setReason(MovementReasonManager.INVENTORY); initInventory.setMovementType(MovementReasonManager.MovementType.PHYSICAL_INVENTORY); initInventory.setMovementQuantity(stockOnHand); return initInventory; } public List<StockMovementItem> getStockMovementItemsWrapper() { stockMovementItemsWrapper = ListUtil.wrapOrEmpty(foreignStockMovementItems, stockMovementItemsWrapper); return stockMovementItemsWrapper; } public float getCMM() { return (int) (this.avgMonthlyConsumption * 100 + 0.5) / 100f; } public boolean isOverStock() { return stockOnHand > (int) Math.ceil(this.avgMonthlyConsumption * 2); } public boolean isLowStock() { return stockOnHand < (int) Math.ceil(this.avgMonthlyConsumption * 0.05); } public List<LotOnHand> getLotOnHandListWrapper() { lotOnHandListWrapper = ListUtil.wrapOrEmpty(foreignLotOnHandList, lotOnHandListWrapper); return lotOnHandListWrapper; } public Date getEarliestLotExpiryDate() { List<LotOnHand> lotOnHandList = FluentIterable.from(getNonEmptyLotOnHandList()).filter(new Predicate<LotOnHand>() { @Override public boolean apply(LotOnHand lotOnHand) { return lotOnHand.getQuantityOnHand() > 0; } }).toList(); if (lotOnHandList.isEmpty()) { return null; } return Collections.min(lotOnHandList, new Comparator<LotOnHand>() { @Override public int compare(LotOnHand lhs, LotOnHand rhs) { return lhs.getLot().getExpirationDate().compareTo(rhs.getLot().getExpirationDate()); } }).getLot().getExpirationDate(); } public Date getLastStockMovementDate() { if (getStockMovementItemsWrapper().isEmpty()) { return null; } return Collections.max(getStockMovementItemsWrapper(), new Comparator<StockMovementItem>() { @Override public int compare(StockMovementItem lhs, StockMovementItem rhs) { return lhs.getMovementDate().compareTo(rhs.getMovementDate()); } }).getMovementDate(); } public List<LotOnHand> getNonEmptyLotOnHandList() { return FluentIterable.from(getLotOnHandListWrapper()).filter(new Predicate<LotOnHand>() { @Override public boolean apply(LotOnHand lotOnHand) { return lotOnHand.getQuantityOnHand() > 0; } }).toList(); } }