/* * 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 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.joda.time.DateTime; import org.openlmis.core.LMISApp; import org.openlmis.core.utils.DateUtil; import org.openlmis.core.utils.ListUtil; import org.roboguice.shaded.goole.common.base.Predicate; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import lombok.Getter; import lombok.Setter; import static org.roboguice.shaded.goole.common.collect.FluentIterable.from; import static org.roboguice.shaded.goole.common.collect.Lists.newArrayList; @Getter @Setter @DatabaseTable(tableName = "rnr_forms") public class RnRForm extends BaseModel { public enum STATUS { DRAFT, SUBMITTED, AUTHORIZED, DRAFT_MISSED, SUBMITTED_MISSED, } @ForeignCollectionField() private ForeignCollection<RnrFormItem> rnrFormItemList; @Expose @SerializedName("products") private List<RnrFormItem> rnrFormItemListWrapper; @ForeignCollectionField() private ForeignCollection<RegimenItem> regimenItemList; @Expose @SerializedName("regimens") private List<RegimenItem> regimenItemListWrapper; @ForeignCollectionField() private ForeignCollection<BaseInfoItem> baseInfoItemList; @Expose @SerializedName("patientQuantifications") private List<BaseInfoItem> baseInfoItemListWrapper; @ForeignCollectionField() private ForeignCollection<RnRFormSignature> signatures; private List<RnRFormSignature> signaturesWrapper; @Expose @SerializedName("clientSubmittedNotes") @DatabaseField private String comments; @DatabaseField(defaultValue = "DRAFT") private STATUS status; @DatabaseField(foreign = true, foreignAutoRefresh = true) private Program program; @DatabaseField private boolean synced = false; @Expose @SerializedName("actualPeriodStartDate") @DatabaseField private Date periodBegin; @Expose @SerializedName("actualPeriodEndDate") @DatabaseField private Date periodEnd; @Expose @SerializedName("clientSubmittedTime") @DatabaseField private Date submittedTime; @Expose @DatabaseField private boolean emergency; public boolean isDraft() { return getStatus() == STATUS.DRAFT || getStatus() == STATUS.DRAFT_MISSED; } public boolean isMissed() { return getStatus() == STATUS.DRAFT_MISSED || getStatus() == STATUS.SUBMITTED_MISSED; } public boolean isSubmitted() { return getStatus() == STATUS.SUBMITTED || getStatus() == STATUS.SUBMITTED_MISSED; } public boolean isAuthorized() { return getStatus() == STATUS.AUTHORIZED; } public static RnRForm init(Program program, Date generateDate) { RnRForm rnrForm = new RnRForm(); rnrForm.program = program; Period period = DateUtil.generateRnRFormPeriodBy(generateDate); rnrForm.periodBegin = period.getBegin().toDate(); rnrForm.periodEnd = period.getEnd().toDate(); return rnrForm; } public static RnRForm init(Program program, Period period, boolean isEmergency) { RnRForm rnRForm = new RnRForm(); rnRForm.program = program; rnRForm.periodBegin = period.getBegin().toDate(); rnRForm.periodEnd = period.getEnd().toDate(); rnRForm.setEmergency(isEmergency); if (isMissed(period) && !isEmergency) { rnRForm.status = RnRForm.STATUS.DRAFT_MISSED; } else { rnRForm.status = RnRForm.STATUS.DRAFT; } return rnRForm; } private static boolean isMissed(Period period) { DateTime today = new DateTime(LMISApp.getInstance().getCurrentTimeMillis()); DateTime periodEnd = period.getEnd(); int monthOffset = DateUtil.calculateMonthOffset(today, periodEnd); return monthOffset > 0 || (monthOffset == 0 && today.getDayOfMonth() >= Period.INVENTORY_END_DAY_NEXT); } public static long calculateTotalRegimenAmount(Collection<RegimenItem> list) { long totalRegimenNumber = 0; for (RegimenItem item : list) { if (item.getAmount() != null) { totalRegimenNumber += item.getAmount(); } } return totalRegimenNumber; } public List<RnrFormItem> getRnrFormItemListWrapper() { rnrFormItemListWrapper = ListUtil.wrapOrEmpty(rnrFormItemList, rnrFormItemListWrapper); if (isAuthorized()) { sortRnrItemsListBasedOnProductCode(rnrFormItemListWrapper); return rnrFormItemListWrapper; } else { return sortProductList(rnrFormItemListWrapper); } } private List<RnrFormItem> sortProductList(List<RnrFormItem> rnrFormItems) { List<RnrFormItem> existingList = newArrayList(from(rnrFormItems).filter(new Predicate<RnrFormItem>() { @Override public boolean apply(RnrFormItem rnrFormItem) { return !rnrFormItem.isManualAdd(); } }).toList()); List<RnrFormItem> newlyAddedList = newArrayList(from(rnrFormItems).filter(new Predicate<RnrFormItem>() { @Override public boolean apply(RnrFormItem rnrFormItem) { return rnrFormItem.isManualAdd(); } }).toList()); sortRnrItemsListBasedOnProductCode(existingList); sortRnrItemsListBasedOnProductCode(newlyAddedList); rnrFormItems = existingList; rnrFormItems.addAll(newlyAddedList); return rnrFormItems; } private void sortRnrItemsListBasedOnProductCode(List<RnrFormItem> rnrFormItems) { Collections.sort(rnrFormItems, new Comparator<RnrFormItem>() { @Override public int compare(RnrFormItem r1, RnrFormItem r2) { if (r1.getProduct() != null && r2.getProduct() != null) { String code1 = r1.getProduct().getCode(); String code2 = r2.getProduct().getCode(); return code1.compareTo(code2); } else { return 0; } } }); } public List<BaseInfoItem> getBaseInfoItemListWrapper() { baseInfoItemListWrapper = ListUtil.wrapOrEmpty(baseInfoItemList, baseInfoItemListWrapper); return baseInfoItemListWrapper; } public List<RegimenItem> getRegimenItemListWrapper() { regimenItemListWrapper = ListUtil.wrapOrEmpty(regimenItemList, regimenItemListWrapper); return regimenItemListWrapper; } public List<RnRFormSignature> getSignaturesWrapper() { signaturesWrapper = ListUtil.wrapOrEmpty(signatures, signaturesWrapper); return signaturesWrapper; } public static void fillFormId(RnRForm rnRForm) { for (RnrFormItem item : rnRForm.getRnrFormItemListWrapper()) { item.setForm(rnRForm); } for (RegimenItem regimenItem : rnRForm.getRegimenItemListWrapper()) { regimenItem.setForm(rnRForm); } for (BaseInfoItem item : rnRForm.getBaseInfoItemListWrapper()) { item.setRnRForm(rnRForm); } } public List<RnrFormItem> getDeactivatedAndUnsupportedProductItems(final List<String> supportedProductCodes) { return from(getRnrFormItemListWrapper()).filter(new Predicate<RnrFormItem>() { @Override public boolean apply(RnrFormItem rnrFormItem) { return !(rnrFormItem.getProduct().isActive() && supportedProductCodes.contains(rnrFormItem.getProduct().getCode())); } }).toList(); } public List<RnrFormItem> getRnrItems(final Product.IsKit isKit) { return from(getRnrFormItemListWrapper()).filter(new Predicate<RnrFormItem>() { @Override public boolean apply(RnrFormItem rnrFormItem) { return isKit.isKit() == rnrFormItem.getProduct().isKit(); } }).toList(); } public void addSignature(String signature) { if (isDraft()) { getSignaturesWrapper().add(new RnRFormSignature(this, signature, RnRFormSignature.TYPE.SUBMITTER)); status = isMissed() ? RnRForm.STATUS.SUBMITTED_MISSED : RnRForm.STATUS.SUBMITTED; } else { getSignaturesWrapper().add(new RnRFormSignature(this, signature, RnRFormSignature.TYPE.APPROVER)); status = RnRForm.STATUS.AUTHORIZED; submittedTime = DateUtil.today(); } } public enum Emergency { Yes(true), No(false); public boolean Emergency() { return Emergency; } private boolean Emergency; Emergency(boolean Emergency) { this.Emergency = Emergency; } } }