/*
* This program is part of the OpenLMIS logistics management information system platform software.
* Copyright © 2017 VillageReach
*
* 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.
*/
import React, { useMemo, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { Form } from 'react-final-form';
import arrayMutators from 'final-form-arrays';
import { FieldArray } from 'react-final-form-arrays';
import createDecorator from 'final-form-calculate';
import InputField from '../../react-components/form-fields/input-field';
import SelectField from '../../react-components/form-fields/select-field';
import ReadOnlyField from '../../react-components/form-fields/read-only-field';
import { formatLot, formatDate, formatDateISO } from '../format-utils';
import AddButton from '../../react-components/buttons/add-button';
import { appendToAdjustment } from '../reducers/adjustment';
const AddProductsPage = ({}) => {
const history = useHistory();
const dispatch = useDispatch();
const userHomeFacility = useSelector(state => state.facilities.userHomeFacility);
const productOptions = useSelector(state => state.productOptions.productOptions);
const reasons = useSelector(state => state.reasons.reasons);
const adjustment = useSelector(state => state.adjustment.adjustment);
const program = useSelector(state => state.program.program);
const decorator = useMemo(() => createDecorator({
field: /product/,
updates: {
stockOnHand: (productVal, itemsVal) => {
const orderable = itemsVal.items[0]?.product ?? [];
if (itemsVal.items[0].hasOwnProperty('lot')) {
delete itemsVal.items[0].lot;
}
const lotCode = null;
const stockOnHand = getStockOnHand(orderable, lotCode);
return stockOnHand;
}
}
},
{
field: /lot/,
updates: {
stockOnHand: (productVal, itemsVal) => {
const orderable = itemsVal.items[0]?.product ?? [];
const lotCode = itemsVal.items[0]?.lot?.lotCode ?? null;
const stockOnHand = getStockOnHand(orderable, lotCode);
return stockOnHand;
}
}
}
), []);
const isQuantityNotFilled = (quantity) => {
return _.isUndefined(quantity) || _.isNull(quantity) || _.isNaN(quantity) || quantity === "";
}
const validate = values => {
const errors = { items: [] };
values.items.forEach(item => {
let orderable = item.product;
if (!item.product) {
errors.items['product'] = { product: 'Required' };
orderable = [];
}
if (isQuantityNotFilled(item.quantity)) {
errors.items['quantity'] = { quantity: 'Required' };
}
if (!item.reason) {
errors.items['reason'] = { reason: 'Required' };
} else {
const stockOnHandQuantity = getStockOnHand(orderable, item?.lot?.lotCode ?? null);
if (!errors.items.hasOwnProperty('quantity')) {
if (item.reason.reasonType !== "CREDIT" && item.quantity > stockOnHandQuantity) {
errors.items['quantity'] = { quantity: 'Quantity cannot be greater than stock on hand value.' };
}
}
}
});
return errors;
};
const getStockOnHand = (orderable, lotCode) => {
let returnedStock = null;
orderable.forEach(product => {
const productLotCode = product?.lot?.lotCode ?? null;
if (lotCode === productLotCode) {
returnedStock = product.stockOnHand;
}
});
return returnedStock;
};
const cancel = () => {
if (!adjustment.length) {
history.goBack();
}
else {
history.push("/makeAdjustmentAddProducts/submitAdjustment");
}
};
const updateAdjustmentList = (values) => {
values.reasonFreeText = null;
values.occurredDate = formatDateISO(new Date());
values.reason = values.items[0].reason;
values.lot = values.items[0]?.lot ?? null;
values.displayLotMessage = values?.lot?.lotCode ?? "No lot defined";
values.quantity = values.items[0].quantity;
const productInformation = values.items[0].product;
const lotCode = values?.lot?.lotCode ?? null;
productInformation.forEach(prod => {
const productLotCode = prod?.lot?.lotCode ?? null;
if (lotCode === productLotCode) {
values.orderable = prod.orderable;
values.stockCard = prod.stockCard;
values.productName = prod.orderable.fullProductName;
}
});
dispatch(appendToAdjustment(values));
}
const onSubmit = (values) => {
updateAdjustmentList(values);
history.push("/makeAdjustmentAddProducts/submitAdjustment");
};
const onSubmitAddProduct = (values) => {
updateAdjustmentList(values);
history.push("/makeAdjustmentAddProducts");
};
const getLotsOptions = (orderableGroup) => {
const lots = _.chain(orderableGroup).pluck('lot')
.compact()
.map(lot => ({ ...lot, expirationDate: new Date(lot.expirationDate) }))
.value();
return _.map(lots, lot => ({ name: formatLot(lot), value: lot }));
};
const renderLotSelect = (fieldName, product, v) => {
const options = getLotsOptions(product);
const noOptions = !options?.length;
return (