added to transaction api and built the submit function
This commit is contained in:
parent
49bd146de6
commit
a083f7d8ed
3 changed files with 97 additions and 16 deletions
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -10864,7 +10864,7 @@
|
||||||
},
|
},
|
||||||
"node_modules/protobuf-ts": {
|
"node_modules/protobuf-ts": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#6bf3baa3e9db19f0d7031dda1c3045f6f64c515b",
|
"resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#8269078a53ebd9089b32bc7861c3e53698ba4166",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"protobufjs": "^6.8.8"
|
"protobufjs": "^6.8.8"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { CheckOutlined } from "@mui/icons-material";
|
||||||
import { Autocomplete, Box, Button, Card, DialogActions, DialogContent, DialogTitle, TextField, Typography } from "@mui/material";
|
import { Autocomplete, Box, Button, Card, DialogActions, DialogContent, DialogTitle, TextField, Typography } from "@mui/material";
|
||||||
import ResponsiveDialog from "common/ResponsiveDialog";
|
import ResponsiveDialog from "common/ResponsiveDialog";
|
||||||
import ResponsiveTable from "common/ResponsiveTable";
|
import ResponsiveTable from "common/ResponsiveTable";
|
||||||
|
|
@ -9,7 +10,7 @@ import { Transaction } from "models/Transaction";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import ObjectDescriber from "objects/ObjectDescriber";
|
import ObjectDescriber from "objects/ObjectDescriber";
|
||||||
import { pond } from "protobuf-ts/pond";
|
import { pond } from "protobuf-ts/pond";
|
||||||
import { useBinAPI, useContractAPI, useFieldAPI, useGrainBagAPI, useTransactionAPI } from "providers";
|
import { useBinAPI, useContractAPI, useFieldAPI, useGrainBagAPI, useSnackbar, useTransactionAPI } from "providers";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import TransactionDataDisplay from "transactions/transactionDataDisplay";
|
import TransactionDataDisplay from "transactions/transactionDataDisplay";
|
||||||
|
|
@ -31,6 +32,7 @@ export default function BinTransactions(props: Props){
|
||||||
const [possibleTransactionMatches, setPossibleTransactionMatches] = useState<Transaction[]>([])
|
const [possibleTransactionMatches, setPossibleTransactionMatches] = useState<Transaction[]>([])
|
||||||
const [tablePage, setTablePage] = useState(0)
|
const [tablePage, setTablePage] = useState(0)
|
||||||
const [tablePageSize, setTablePageSize] = useState(10)
|
const [tablePageSize, setTablePageSize] = useState(10)
|
||||||
|
const { openSnack } = useSnackbar();
|
||||||
const [total, setTotal] = useState(0)
|
const [total, setTotal] = useState(0)
|
||||||
|
|
||||||
const [binOptions, setBinOptions] = useState<Option[]>([])
|
const [binOptions, setBinOptions] = useState<Option[]>([])
|
||||||
|
|
@ -106,8 +108,32 @@ export default function BinTransactions(props: Props){
|
||||||
},[state, bin, loadTransactionsFor])
|
},[state, bin, loadTransactionsFor])
|
||||||
|
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
//submit approval
|
let transaction = cloneDeep(selectedTransaction)
|
||||||
//in the response if it succeeded remove (not reject but fully delete it) the matched transaction
|
if(transaction){
|
||||||
|
if(selectedMatch){
|
||||||
|
if (transaction.transaction.fromKey === ""){
|
||||||
|
transaction.transaction.fromObject = selectedMatch.transaction.fromObject
|
||||||
|
transaction.transaction.fromKey = selectedMatch.transaction.fromKey
|
||||||
|
}
|
||||||
|
if (transaction.transaction.toKey === ""){
|
||||||
|
transaction.transaction.toObject = selectedMatch.transaction.toObject
|
||||||
|
transaction.transaction.toKey = selectedMatch.transaction.toKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//submit approval
|
||||||
|
transactionAPI.submitApproval(transaction.transaction.key, true, transaction.transaction).then(resp => {
|
||||||
|
//in the response if it succeeded remove (not reject but fully delete it) the matched transaction
|
||||||
|
if(selectedMatch){
|
||||||
|
transactionAPI.removeTransaction(selectedMatch.transaction.key).then(resp => {
|
||||||
|
openSnack("Updated and matched transactions")
|
||||||
|
}).catch(err => {
|
||||||
|
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
openSnack("Updated Transaction")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const reject = () => {
|
const reject = () => {
|
||||||
|
|
@ -145,9 +171,10 @@ export default function BinTransactions(props: Props){
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<Box>
|
<Box>
|
||||||
<Typography>{getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_WEIGHT ? weight + " mT" : bushels + " bushels"} of {grainTransaction.subtype} {grainDisplay} moved</Typography>
|
<Typography>{getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_WEIGHT ? weight + " mT" : bushels + " bushels"} of {grainTransaction.subtype} {grainDisplay} moved</Typography>
|
||||||
<Typography>From</Typography>
|
<Typography margin={1} fontWeight={650}>From:</Typography>
|
||||||
{/*Object type selection*/}
|
{/*Object type selection*/}
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
|
sx={{marginY: 1}}
|
||||||
disabled={fromDisabled}
|
disabled={fromDisabled}
|
||||||
id="autoFromTypes"
|
id="autoFromTypes"
|
||||||
value={fromType}
|
value={fromType}
|
||||||
|
|
@ -158,7 +185,7 @@ export default function BinTransactions(props: Props){
|
||||||
]}
|
]}
|
||||||
getOptionLabel={(option: pond.ObjectType) => ObjectDescriber(option).name}
|
getOptionLabel={(option: pond.ObjectType) => ObjectDescriber(option).name}
|
||||||
fullWidth
|
fullWidth
|
||||||
onChange={(e, val) => {
|
onChange={(_, val) => {
|
||||||
setFromType(val ?? pond.ObjectType.OBJECT_TYPE_UNKNOWN)
|
setFromType(val ?? pond.ObjectType.OBJECT_TYPE_UNKNOWN)
|
||||||
//based on what it is changed to need to load data if it is not already loaded
|
//based on what it is changed to need to load data if it is not already loaded
|
||||||
if(val === pond.ObjectType.OBJECT_TYPE_BIN){
|
if(val === pond.ObjectType.OBJECT_TYPE_BIN){
|
||||||
|
|
@ -175,13 +202,14 @@ export default function BinTransactions(props: Props){
|
||||||
/>
|
/>
|
||||||
{/* object selection */}
|
{/* object selection */}
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
|
sx={{marginY: 1}}
|
||||||
disabled={fromDisabled}
|
disabled={fromDisabled}
|
||||||
id="autoFromObjects"
|
id="autoFromObjects"
|
||||||
value={fromOption}
|
value={fromOption}
|
||||||
options={getOptions(fromType)}
|
options={getOptions(fromType)}
|
||||||
getOptionLabel={(option: Option) => option.label}
|
getOptionLabel={(option: Option) => option.label}
|
||||||
fullWidth
|
fullWidth
|
||||||
onChange={(e, val) => {
|
onChange={(_, val) => {
|
||||||
setFromOption(val ?? undefined)
|
setFromOption(val ?? undefined)
|
||||||
//once one is selected get the transactions for it that are requiring approval
|
//once one is selected get the transactions for it that are requiring approval
|
||||||
transactionAPI.listTransactionsFor(0, 0, "asc", val?.value, pond.TransactionState.TRANSACTION_STATE_APPROVAL_REQUIRED).then(resp => {
|
transactionAPI.listTransactionsFor(0, 0, "asc", val?.value, pond.TransactionState.TRANSACTION_STATE_APPROVAL_REQUIRED).then(resp => {
|
||||||
|
|
@ -197,8 +225,9 @@ export default function BinTransactions(props: Props){
|
||||||
}}
|
}}
|
||||||
renderInput={params => <TextField {...params} label="From" />}
|
renderInput={params => <TextField {...params} label="From" />}
|
||||||
/>
|
/>
|
||||||
<Typography>To</Typography>
|
<Typography margin={1} fontWeight={650}>To:</Typography>
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
|
sx={{marginY: 1}}
|
||||||
disabled={toDisabled}
|
disabled={toDisabled}
|
||||||
id="autoFromTypes"
|
id="autoFromTypes"
|
||||||
value={toType}
|
value={toType}
|
||||||
|
|
@ -209,7 +238,7 @@ export default function BinTransactions(props: Props){
|
||||||
]}
|
]}
|
||||||
getOptionLabel={(option: pond.ObjectType) => ObjectDescriber(option).name}
|
getOptionLabel={(option: pond.ObjectType) => ObjectDescriber(option).name}
|
||||||
fullWidth
|
fullWidth
|
||||||
onChange={(e, val) => {
|
onChange={(_, val) => {
|
||||||
setToType(val ?? pond.ObjectType.OBJECT_TYPE_UNKNOWN)
|
setToType(val ?? pond.ObjectType.OBJECT_TYPE_UNKNOWN)
|
||||||
//based on what it is changed to need to load data if it is not already loaded
|
//based on what it is changed to need to load data if it is not already loaded
|
||||||
if(val === pond.ObjectType.OBJECT_TYPE_BIN){
|
if(val === pond.ObjectType.OBJECT_TYPE_BIN){
|
||||||
|
|
@ -225,13 +254,14 @@ export default function BinTransactions(props: Props){
|
||||||
renderInput={params => <TextField {...params} label="Type" />}
|
renderInput={params => <TextField {...params} label="Type" />}
|
||||||
/>
|
/>
|
||||||
<Autocomplete
|
<Autocomplete
|
||||||
|
sx={{marginY: 1}}
|
||||||
disabled={toDisabled}
|
disabled={toDisabled}
|
||||||
id="autoFromObjects"
|
id="autoFromObjects"
|
||||||
value={toOption}
|
value={toOption}
|
||||||
options={getOptions(toType)}
|
options={getOptions(toType)}
|
||||||
getOptionLabel={(option: Option) => option.label}
|
getOptionLabel={(option: Option) => option.label}
|
||||||
fullWidth
|
fullWidth
|
||||||
onChange={(e, val) => {
|
onChange={(_, val) => {
|
||||||
//once one is selected get the transactions for it that are requiring approval
|
//once one is selected get the transactions for it that are requiring approval
|
||||||
transactionAPI.listTransactionsFor(0, 0, "asc", val?.value, pond.TransactionState.TRANSACTION_STATE_APPROVAL_REQUIRED).then(resp => {
|
transactionAPI.listTransactionsFor(0, 0, "asc", val?.value, pond.TransactionState.TRANSACTION_STATE_APPROVAL_REQUIRED).then(resp => {
|
||||||
let matches: Transaction[] = []
|
let matches: Transaction[] = []
|
||||||
|
|
@ -248,12 +278,41 @@ export default function BinTransactions(props: Props){
|
||||||
renderInput={params => <TextField {...params} label="From" />}
|
renderInput={params => <TextField {...params} label="From" />}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box paddingTop={1}>
|
||||||
|
<Typography variant="h6">Possible matching Transactions</Typography>
|
||||||
|
<Typography>Pick a transaction below if you want to match them together</Typography>
|
||||||
{possibleTransactionMatches.map(t => {
|
{possibleTransactionMatches.map(t => {
|
||||||
|
// get the display information for the transaction
|
||||||
|
const grainTransaction = t.transaction.transaction?.grainTransaction ?? pond.GrainTransaction.create()
|
||||||
|
const bushels = grainTransaction.bushels ?? 0
|
||||||
|
const weight = bushels / grainTransaction.bushelsPerTonne
|
||||||
|
let graintype = grainTransaction.grainType ?? pond.Grain.GRAIN_INVALID
|
||||||
|
const grainDisplay = graintype === pond.Grain.GRAIN_CUSTOM
|
||||||
|
? grainTransaction.customGrain
|
||||||
|
: GrainDescriber(grainTransaction.grainType).name
|
||||||
return (
|
return (
|
||||||
<Typography>
|
<Card sx={{marginTop: 1, padding: 1}}>
|
||||||
{t.transaction.timestamp}
|
<Box display="flex" justifyContent="space-between" height={40}>
|
||||||
</Typography>
|
<Typography sx={{fontWeight: 650, margin: "auto", marginLeft: 0}}>
|
||||||
|
{moment(t.transaction.timestamp).fromNow()}
|
||||||
|
</Typography>
|
||||||
|
<Box>
|
||||||
|
{selectedMatch?.transaction.key === t.transaction.key && <CheckOutlined htmlColor="green" />}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box display="flex" justifyContent="space-between">
|
||||||
|
<Typography sx={{margin: "auto", marginLeft: 0}}>{getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_WEIGHT ? weight + " mT" : bushels + " bushels"} of {grainTransaction.subtype} {grainDisplay} moved</Typography>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
disabled={selectedMatch?.transaction.key === t.transaction.key}
|
||||||
|
color="primary"
|
||||||
|
onClick={()=>{
|
||||||
|
setselectedMatch(t)
|
||||||
|
}}>
|
||||||
|
Set Match
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Card>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ export interface ITransactionAPIContext {
|
||||||
data: pond.TransactionData,
|
data: pond.TransactionData,
|
||||||
otherTeam?: string
|
otherTeam?: string
|
||||||
) => Promise<AxiosResponse<pond.UpdateTransactionResponse>>;
|
) => Promise<AxiosResponse<pond.UpdateTransactionResponse>>;
|
||||||
|
submitApproval: (key: string, approved: boolean, updatedData: pond.Transaction, otherTeam?: string) => Promise<AxiosResponse<pond.SubmitTransactionApprovalResponse>>;
|
||||||
|
removeTransaction: (key: string, otherTeam?: string) => Promise<AxiosResponse<pond.RemoveTransactionResponse>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TransactionAPIContext = createContext<ITransactionAPIContext>(
|
export const TransactionAPIContext = createContext<ITransactionAPIContext>(
|
||||||
|
|
@ -50,7 +52,7 @@ interface Props {}
|
||||||
|
|
||||||
export default function TransactionProvider(props: PropsWithChildren<Props>) {
|
export default function TransactionProvider(props: PropsWithChildren<Props>) {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
const { get, post, put } = useHTTP();
|
const { get, post, put, del } = useHTTP();
|
||||||
const [{ as }] = useGlobalState();
|
const [{ as }] = useGlobalState();
|
||||||
|
|
||||||
const addTransaction = (transaction: pond.Transaction, fileIDs?: string[], otherTeam?: string) => {
|
const addTransaction = (transaction: pond.Transaction, fileIDs?: string[], otherTeam?: string) => {
|
||||||
|
|
@ -158,6 +160,24 @@ export default function TransactionProvider(props: PropsWithChildren<Props>) {
|
||||||
return put<pond.TransactionPageDataResponse>(pondURL("/transactions/" + key + "/revoke"));
|
return put<pond.TransactionPageDataResponse>(pondURL("/transactions/" + key + "/revoke"));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const submitApproval = (key: string, approval: boolean, updatedData: pond.Transaction, otherTeam?: string) => {
|
||||||
|
const view = otherTeam ? otherTeam : as
|
||||||
|
let url = "/transactions/" + key + "/approval?approve=" + approval.toString()
|
||||||
|
if(view){
|
||||||
|
url = url + "&as=" + view
|
||||||
|
}
|
||||||
|
return post<pond.SubmitTransactionApprovalResponse>(url, updatedData)
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeTransaction = (key: string, otherTeam?: string) => {
|
||||||
|
const view = otherTeam ? otherTeam : as
|
||||||
|
let url = "/transactions/" + key + "/remove"
|
||||||
|
if(view){
|
||||||
|
url = url + "&as=" + view
|
||||||
|
}
|
||||||
|
return del<pond.RemoveTransactionResponse>(url)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TransactionAPIContext.Provider
|
<TransactionAPIContext.Provider
|
||||||
value={{
|
value={{
|
||||||
|
|
@ -166,7 +186,9 @@ export default function TransactionProvider(props: PropsWithChildren<Props>) {
|
||||||
listTransactionsFor,
|
listTransactionsFor,
|
||||||
updateTransaction,
|
updateTransaction,
|
||||||
transactionPageData,
|
transactionPageData,
|
||||||
revokeTransaction
|
revokeTransaction,
|
||||||
|
submitApproval,
|
||||||
|
removeTransaction
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
</TransactionAPIContext.Provider>
|
</TransactionAPIContext.Provider>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue