modified th api's for bin, contract and task to have as passed in as a prop and not get it ffrom the global state directly in the api
This commit is contained in:
parent
4bcac4e346
commit
e2f5eb0557
31 changed files with 155 additions and 507 deletions
|
|
@ -1,385 +0,0 @@
|
|||
import ResponsiveDialog from "common/ResponsiveDialog";
|
||||
import { Bin, Field, HarvestYear } from "models";
|
||||
import React, { useCallback } from "react";
|
||||
import { useFieldAPI, useBinAPI, useHarvestYearAPI, useGlobalState } from "providers";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
FormControl,
|
||||
FormControlLabel,
|
||||
MenuItem,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
TextField
|
||||
} from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { pond } from "protobuf-ts/pond";
|
||||
import { useSnackbar } from "hooks";
|
||||
import moment from "moment";
|
||||
import GrainDescriber from "./GrainDescriber";
|
||||
|
||||
interface Props {
|
||||
activeBinSettings: pond.BinSettings;
|
||||
newGrainInventory: number;
|
||||
dialogControl: boolean;
|
||||
onClose(cancel?: boolean): void;
|
||||
afterUpdate?(secondBin?: Bin): void;
|
||||
}
|
||||
|
||||
//this component is going to be deprecated by grain transaction
|
||||
export default function GrainInventory(props: Props) {
|
||||
const { activeBinSettings, newGrainInventory, dialogControl, onClose, afterUpdate } = props;
|
||||
const binAPI = useBinAPI();
|
||||
const fieldAPI = useFieldAPI();
|
||||
const hYearAPI = useHarvestYearAPI();
|
||||
const [{ as }] = useGlobalState();
|
||||
const [binIndex, setBinIndex] = useState(0);
|
||||
const [fieldIndex, setFieldIndex] = useState<number>(-1);
|
||||
const [yearIndex, setYearIndex] = useState(0);
|
||||
const [bins, setBins] = useState<Bin[]>([]);
|
||||
const [fields, setFields] = useState<Field[]>([]);
|
||||
const [hYears, setHYears] = useState<Map<number, HarvestYear>>(new Map<number, HarvestYear>());
|
||||
const [currentBushels, setCurrentBushels] = useState(0);
|
||||
const { openSnack } = useSnackbar();
|
||||
const [increaseMode, setIncreaseMode] = useState<"correction" | "purchased" | "grown">(
|
||||
"correction"
|
||||
);
|
||||
const [decreaseMode, setDecreaseMode] = useState<"correction" | "sold" | "moved">("correction");
|
||||
|
||||
useEffect(() => {
|
||||
if (activeBinSettings.inventory && dialogControl) {
|
||||
setCurrentBushels(activeBinSettings.inventory.grainBushels);
|
||||
}
|
||||
}, [activeBinSettings, dialogControl]);
|
||||
|
||||
const loadBins = useCallback(() => {
|
||||
if (!dialogControl) return;
|
||||
binAPI
|
||||
.listBins(50, 0, "asc", "name", undefined, as)
|
||||
.then(resp => {
|
||||
setBins(resp.data.bins.map(b => Bin.any(b)));
|
||||
})
|
||||
.catch();
|
||||
}, [binAPI, as, dialogControl]);
|
||||
|
||||
const loadHYears = useCallback(() => {
|
||||
if (fields.length > 0 && fieldIndex > -1) {
|
||||
hYearAPI.listHarvestYears(50, 0, "asc", "year", fields[fieldIndex].fieldName()).then(resp => {
|
||||
let tempMap = new Map<number, HarvestYear>();
|
||||
resp.data.harvestYear.forEach(hy => {
|
||||
let tempHY = HarvestYear.any(hy);
|
||||
tempMap.set(tempHY.year(), tempHY);
|
||||
});
|
||||
setHYears(tempMap);
|
||||
});
|
||||
}
|
||||
}, [hYearAPI, fields, fieldIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
loadHYears();
|
||||
}, [loadHYears]);
|
||||
|
||||
useEffect(() => {
|
||||
loadBins();
|
||||
fieldAPI
|
||||
.listFields(500, 0, "asc", "fieldName", undefined, as)
|
||||
.then(resp => {
|
||||
setFields(resp.data.fields.map(f => Field.any(f)));
|
||||
})
|
||||
.catch();
|
||||
}, [loadBins, fieldAPI, as]);
|
||||
|
||||
const grainName = (bin: Bin) => {
|
||||
return bin.storage() === pond.BinStorage.BIN_STORAGE_SUPPORTED_GRAIN
|
||||
? GrainDescriber(bin.grain()).name
|
||||
: bin.customType();
|
||||
};
|
||||
|
||||
const dialogContent = () => {
|
||||
if (newGrainInventory < currentBushels) {
|
||||
return (
|
||||
<Box>
|
||||
<FormControl>
|
||||
<RadioGroup value={decreaseMode} name="radio-buttons-group">
|
||||
<FormControlLabel
|
||||
value="correction"
|
||||
control={<Radio />}
|
||||
label="Correction"
|
||||
onChange={() => setDecreaseMode("correction")}
|
||||
/>
|
||||
{/* Doesnt Actually Do Anything yet */}
|
||||
{/* <FormControlLabel
|
||||
value="sold"
|
||||
control={<Radio />}
|
||||
label="Sold"
|
||||
onChange={() => setDecreaseMode("sold")}
|
||||
/> */}
|
||||
<FormControlLabel
|
||||
value="moved"
|
||||
control={<Radio />}
|
||||
label="Moved"
|
||||
onChange={() => setDecreaseMode("moved")}
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
{decreaseMode === "moved" && (
|
||||
<TextField
|
||||
id="bins"
|
||||
fullWidth
|
||||
margin="normal"
|
||||
select
|
||||
label="Bin grain moved to"
|
||||
value={binIndex}
|
||||
onChange={e => setBinIndex(+e.target.value)}>
|
||||
{bins.map((option, i) => (
|
||||
<MenuItem key={i} value={i} disabled={option.key() === activeBinSettings.key}>
|
||||
{option.name()} - {grainName(option)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Box>
|
||||
<FormControl>
|
||||
<RadioGroup value={increaseMode} name="radio-buttons-group">
|
||||
<FormControlLabel
|
||||
value="correction"
|
||||
control={<Radio />}
|
||||
label="Correction"
|
||||
onChange={() => setIncreaseMode("correction")}
|
||||
/>
|
||||
{/* Doesnt Actually Do Anything yet */}
|
||||
{/* <FormControlLabel
|
||||
value="purchased"
|
||||
control={<Radio />}
|
||||
label="Purchased"
|
||||
onChange={() => setIncreaseMode("purchased")}
|
||||
/> */}
|
||||
<FormControlLabel
|
||||
value="grown"
|
||||
control={<Radio />}
|
||||
label="Grown"
|
||||
onChange={() => setIncreaseMode("grown")}
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
{increaseMode === "grown" && (
|
||||
<Box>
|
||||
<TextField
|
||||
id="fields"
|
||||
fullWidth
|
||||
margin="normal"
|
||||
select
|
||||
label="Field"
|
||||
helperText="Select the field that provided the grain"
|
||||
value={fieldIndex}
|
||||
onChange={e => setFieldIndex(+e.target.value)}>
|
||||
<MenuItem key="noField" value={-1}>
|
||||
No Field Selected
|
||||
</MenuItem>
|
||||
{fields.map((option, i) => (
|
||||
<MenuItem key={i} value={i}>
|
||||
{option.fieldName()}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
<TextField
|
||||
id="harvestYear"
|
||||
fullWidth
|
||||
margin="normal"
|
||||
select
|
||||
label="Harvest Year"
|
||||
helperText="Select which Year to track"
|
||||
value={yearIndex}
|
||||
onChange={e => setYearIndex(+e.target.value)}
|
||||
disabled={fieldIndex < 0}>
|
||||
<MenuItem key={0} value={0}>
|
||||
New Harvest Year
|
||||
</MenuItem>
|
||||
{Array.from(hYears.values()).length > 0 &&
|
||||
Array.from(hYears.values()).map(option => (
|
||||
<MenuItem key={option.year()} value={option.year()}>
|
||||
{option.year()}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const increaseInv = () => {
|
||||
let bin = activeBinSettings;
|
||||
let binInv = pond.BinInventory.fromObject({
|
||||
...bin.inventory
|
||||
});
|
||||
if (binInv.grainBushels === 0 && bin.mode === pond.BinMode.BIN_MODE_NONE) {
|
||||
bin.mode = pond.BinMode.BIN_MODE_STORAGE;
|
||||
}
|
||||
binInv.grainBushels = newGrainInventory;
|
||||
|
||||
if (fields.length > 0 && fieldIndex > -1) {
|
||||
if (fields[fieldIndex].crop() !== activeBinSettings.inventory?.grainType) {
|
||||
openSnack("Grain type of this bin does not match the Field");
|
||||
return;
|
||||
} else if (yearIndex === 0 && hYears.has(moment().year())) {
|
||||
openSnack("Current year already exists for this field");
|
||||
return;
|
||||
}
|
||||
binInv.grainSubtype = fields[fieldIndex].subtype();
|
||||
}
|
||||
|
||||
bin.inventory = binInv;
|
||||
|
||||
binAPI
|
||||
.updateBin(activeBinSettings.key, bin)
|
||||
.then(() => {
|
||||
if (increaseMode === "grown") {
|
||||
if (yearIndex === 0) {
|
||||
let hy = HarvestYear.create();
|
||||
hy.settings.field = fields[fieldIndex].fieldName();
|
||||
hy.settings.grain = fields[fieldIndex].crop();
|
||||
hy.settings.year = moment().year();
|
||||
hy.settings.bushels = newGrainInventory - currentBushels;
|
||||
hYearAPI.addHarvestYear(hy.settings).then(resp => {
|
||||
loadHYears();
|
||||
});
|
||||
} else {
|
||||
let hy = hYears.get(yearIndex);
|
||||
if (hy) {
|
||||
hy.settings.bushels = hy.totalBushels() + (newGrainInventory - currentBushels);
|
||||
hYearAPI.updateHarvestYear(hy.key(), hy.settings).then(resp => {
|
||||
loadHYears();
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (increaseMode === "purchased") {
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
openSnack("Failed to update grain inventory");
|
||||
})
|
||||
.finally(() => {
|
||||
if (afterUpdate) {
|
||||
loadBins();
|
||||
afterUpdate();
|
||||
}
|
||||
closeDialog();
|
||||
});
|
||||
};
|
||||
|
||||
const decreaseInv = () => {
|
||||
let binFrom = activeBinSettings;
|
||||
let binTo: Bin;
|
||||
let binFromInv = pond.BinInventory.fromObject({
|
||||
...binFrom.inventory
|
||||
});
|
||||
|
||||
if (decreaseMode === "moved") {
|
||||
//TODO-CS: re-think the logic for moving between bins since the addition of custom types,
|
||||
//possibly remove restrictions and just have a confirmation for the user to change the destination bins grain type
|
||||
binTo = bins[binIndex];
|
||||
if (binTo.settings.inventory && binTo.settings.specs) {
|
||||
let binToInv = binTo.settings.inventory;
|
||||
//check to make sure the grain types of both bins are the same
|
||||
if (binFromInv.grainType !== binToInv.grainType) {
|
||||
if (
|
||||
binToInv.grainType === pond.Grain.GRAIN_NONE ||
|
||||
binToInv.grainType === pond.Grain.GRAIN_INVALID ||
|
||||
binToInv.grainBushels < 1
|
||||
) {
|
||||
binTo.settings.inventory.grainType = binFromInv.grainType;
|
||||
} else {
|
||||
openSnack("Grain types of both bins must match");
|
||||
return;
|
||||
}
|
||||
}
|
||||
//check if the other bin has enough space to move the grain
|
||||
let space = binTo.settings.specs.bushelCapacity - binTo.settings.inventory.grainBushels;
|
||||
if (space < currentBushels - newGrainInventory) {
|
||||
openSnack("Bin does not have enough space");
|
||||
return;
|
||||
}
|
||||
binToInv.grainBushels = binToInv.grainBushels + (currentBushels - newGrainInventory);
|
||||
}
|
||||
}
|
||||
|
||||
binFromInv.grainBushels = newGrainInventory;
|
||||
binFrom.inventory = binFromInv;
|
||||
|
||||
binAPI
|
||||
.updateBin(activeBinSettings.key, binFrom)
|
||||
.then(() => {
|
||||
//update inventory of the bin that the grain was moved to if it was a decrease
|
||||
if (decreaseMode === "moved") {
|
||||
binAPI
|
||||
.updateBin(bins[binIndex].key(), binTo.settings)
|
||||
.then(() => {
|
||||
openSnack("Grain inventory updated");
|
||||
})
|
||||
.catch(err => {
|
||||
openSnack("Failed to update grain inventory");
|
||||
})
|
||||
.finally(() => {
|
||||
if (afterUpdate) {
|
||||
afterUpdate(binTo);
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
openSnack("Failed to update grain inventory");
|
||||
})
|
||||
.finally(() => {
|
||||
if (decreaseMode !== "moved" && afterUpdate) {
|
||||
afterUpdate();
|
||||
}
|
||||
closeDialog();
|
||||
});
|
||||
};
|
||||
|
||||
const setNewInventory = () => {
|
||||
if (currentBushels > newGrainInventory) {
|
||||
decreaseInv();
|
||||
} else {
|
||||
increaseInv();
|
||||
}
|
||||
};
|
||||
|
||||
const closeDialog = (useCallback?: boolean) => {
|
||||
onClose(useCallback);
|
||||
};
|
||||
|
||||
const disableButton = () => {
|
||||
if (increaseMode === "grown") {
|
||||
if (fields.length === 0 || fieldIndex < 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
return (
|
||||
<ResponsiveDialog open={dialogControl} onClose={() => closeDialog(true)}>
|
||||
<DialogTitle>Grain Adjustment for {activeBinSettings.name}</DialogTitle>
|
||||
<DialogContent>{dialogContent()}</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => closeDialog(true)} color="primary">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={setNewInventory} color="primary" disabled={disableButton()}>
|
||||
Confirm
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</ResponsiveDialog>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue