package org.openlmis.core.view.viewmodel;
import org.openlmis.core.LMISApp;
import org.openlmis.core.R;
import org.openlmis.core.manager.MovementReasonManager;
import org.openlmis.core.model.Period;
import org.openlmis.core.model.Program;
import org.openlmis.core.model.ProgramDataForm;
import org.openlmis.core.model.ProgramDataFormItem;
import org.openlmis.core.model.ProgramDataFormSignature;
import org.openlmis.core.model.Signature;
import org.roboguice.shaded.goole.common.base.Predicate;
import org.roboguice.shaded.goole.common.collect.FluentIterable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.Data;
import lombok.Getter;
@Data
public class RapidTestReportViewModel implements Serializable {
Period period;
Status status;
private Date syncedTime;
MovementReasonManager movementReasonManager;
RapidTestFormItemViewModel itemTotal;
List<RapidTestFormItemViewModel> itemViewModelList = new ArrayList<>();
Map<String, RapidTestFormItemViewModel> itemViewModelMap = new HashMap<>();
private ProgramDataForm rapidTestForm = new ProgramDataForm();
public static long DEFAULT_FORM_ID = 0;
public RapidTestReportViewModel(Period period) {
this.period = period;
status = Status.MISSING;
setupCategories();
setItemViewModelMap();
}
private void setupCategories() {
movementReasonManager = MovementReasonManager.getInstance();
List<MovementReasonManager.MovementReason> issueReasons = FluentIterable.from(movementReasonManager.buildReasonListForMovementType(MovementReasonManager.MovementType.ISSUE))
.filter(new Predicate<MovementReasonManager.MovementReason>() {
@Override
public boolean apply(MovementReasonManager.MovementReason movementReason) {
return !movementReason.getCode().equals("PUB_PHARMACY");
}
}).toList();
for (MovementReasonManager.MovementReason movementReason: issueReasons) {
RapidTestFormItemViewModel item = new RapidTestFormItemViewModel(movementReason);
itemViewModelList.add(item);
}
MovementReasonManager.MovementReason totalCategory = new MovementReasonManager.MovementReason(MovementReasonManager.MovementType.ISSUE, "TOTAL", LMISApp.getInstance().getString(R.string.total));
itemTotal = new RapidTestFormItemViewModel(totalCategory);
itemViewModelList.add(itemTotal);
}
private void setItemViewModelMap() {
for (RapidTestFormItemViewModel viewModel : itemViewModelList) {
itemViewModelMap.put(viewModel.getIssueReason().getCode(), viewModel);
}
}
public RapidTestReportViewModel(ProgramDataForm programDataForm) {
setRapidTestForm(programDataForm);
period = Period.of(programDataForm.getPeriodBegin());
setupCategories();
setItemViewModelMap();
setFormItemViewModels(programDataForm.getProgramDataFormItemListWrapper());
}
private void setFormItemViewModels(List<ProgramDataFormItem> programDataFormItemList) {
for (ProgramDataFormItem item : programDataFormItemList) {
itemViewModelMap.get(item.getName()).setColumnValue(item.getProgramDataColumn(), item.getValue());
}
for (RapidTestFormGridViewModel.ColumnCode columnCode : RapidTestFormGridViewModel.ColumnCode.values()) {
updateTotal(columnCode, true);
updateTotal(columnCode, false);
}
}
public void setRapidTestForm(ProgramDataForm rapidTestForm) {
this.rapidTestForm = rapidTestForm;
switch (rapidTestForm.getStatus()) {
case DRAFT:
case SUBMITTED:
this.status = Status.INCOMPLETE;
break;
case AUTHORIZED:
this.status = Status.COMPLETED;
break;
default:
this.status = Status.MISSING;
}
if (rapidTestForm.isSynced()) {
this.status = Status.SYNCED;
}
}
public Date getSyncedTime() {
return rapidTestForm.getSubmittedTime();
}
public void convertFormViewModelToDataModel(Program program) {
rapidTestForm.setProgram(program);
rapidTestForm.setPeriodBegin(period.getBegin().toDate());
rapidTestForm.setPeriodEnd(period.getEnd().toDate());
rapidTestForm.getProgramDataFormItemListWrapper().clear();
convertFormItemViewModelToDataModel();
}
private void convertFormItemViewModelToDataModel() {
for (RapidTestFormItemViewModel itemViewModel : itemViewModelList) {
rapidTestForm.getProgramDataFormItemListWrapper().addAll(itemViewModel.convertToDataModel());
}
for (ProgramDataFormItem item : rapidTestForm.getProgramDataFormItemListWrapper()) {
item.setForm(rapidTestForm);
}
}
public boolean isSynced() {
return status == Status.SYNCED;
}
public boolean isEditable() {
return status.isEditable() && isDraft();
}
public boolean isDraft() {
return rapidTestForm.getStatus() == null || rapidTestForm.getStatus() == ProgramDataForm.STATUS.DRAFT;
}
public boolean validate() {
for (RapidTestFormItemViewModel itemViewModel : itemViewModelList) {
if (!itemViewModel.validate()) {
return false;
}
}
return true;
}
public void addSignature(String signature) {
if (rapidTestForm.getSignaturesWrapper().size() == 0) {
rapidTestForm.getSignaturesWrapper().add(new ProgramDataFormSignature(rapidTestForm, signature, Signature.TYPE.SUBMITTER));
rapidTestForm.setStatus(ProgramDataForm.STATUS.SUBMITTED);
} else {
rapidTestForm.getSignaturesWrapper().add(new ProgramDataFormSignature(rapidTestForm, signature, Signature.TYPE.APPROVER));
rapidTestForm.setStatus(ProgramDataForm.STATUS.AUTHORIZED);
rapidTestForm.setSubmittedTime(new Date());
status = Status.COMPLETED;
}
}
public boolean isAuthorized() {
return rapidTestForm.getStatus() == ProgramDataForm.STATUS.AUTHORIZED;
}
public boolean isFormEmpty() {
for (RapidTestFormItemViewModel itemViewModel : itemViewModelList) {
if (!itemViewModel.isEmpty()) {
return false;
}
}
return true;
}
public boolean isSubmitted() {
return rapidTestForm.getStatus() == ProgramDataForm.STATUS.SUBMITTED;
}
public void updateTotal(RapidTestFormGridViewModel.ColumnCode columnCode, boolean isConsume) {
itemTotal.clearValue(columnCode, isConsume);
long total = 0;
for (RapidTestFormItemViewModel itemViewModel : itemViewModelList) {
RapidTestFormGridViewModel gridViewModel = itemViewModel.getRapidTestFormGridViewModelMap().get(columnCode.toString());
if (isConsume && !gridViewModel.getConsumptionValue().equals("")) {
total += Long.parseLong(gridViewModel.getConsumptionValue());
} else if (!isConsume && !gridViewModel.getPositiveValue().equals("")) {
total += Long.parseLong(gridViewModel.getPositiveValue());
}
}
if (isConsume) {
itemTotal.getRapidTestFormGridViewModelMap().get(columnCode.toString()).setConsumptionValue(String.valueOf(total));
} else {
itemTotal.getRapidTestFormGridViewModelMap().get(columnCode.toString()).setPositiveValue(String.valueOf(total));
}
}
public enum Status {
MISSING(true, 0),
INCOMPLETE(true, 1),
COMPLETED(false, 2),
SYNCED(false, 3);
@Getter
private boolean editable;
private int viewType;
Status(boolean editable, int viewType) {
this.editable = editable;
this.viewType = viewType;
}
public int getViewType() {
return viewType;
}
}
}