Skip to content

Commit

Permalink
Merge pull request #5254 from msupply-foundation/5137-Requisition-lin…
Browse files Browse the repository at this point in the history
…e-edit-+-UI-updates-to-line-columns

5137.1 requisition line edit + UI updates to line columns
  • Loading branch information
roxy-dao authored Nov 4, 2024
2 parents 9e58843 + e11f861 commit 5ecf2f8
Show file tree
Hide file tree
Showing 16 changed files with 472 additions and 78 deletions.
13 changes: 11 additions & 2 deletions client/packages/common/src/intl/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@
"description.fc-line-total": "Foreign currency line total",
"description.fc-sell-price": "Foreign currency sell price per pack",
"description.forecast-quantity": "Forecast Quantity to Reach Target",
"description.initial-stock-on-hand": "Stock on hand on the first day of the program period",
"description.available-stock": "The customer's initial stock on hand + incoming stock +/- inventory adjustments - outgoing stock",
"description.invoice-number": "Shipment number",
"description.last-reading-datetime": "Date and time of the last reading",
"description.max-min-temperature": "Maximum or minimum temperature reading",
Expand Down Expand Up @@ -232,9 +234,9 @@
"error.failed-to-delete-item-variant": "Failed to delete item variant",
"error.failed-to-generate-excel": "Failed to generate Excel",
"error.failed-to-generate-report": "Failed to generate report",
"error.failed-to-save-item-variant": "Failed to save item variant",
"error.failed-to-save-service-charges": "Failed to save service charges",
"error.failed-to-save-vaccination": "Failed to save vaccination!",
"error.failed-to-save-item-variant": "Failed to save item variant",
"error.failed-to-save-vaccine-course": "Failed to save vaccine course",
"error.fetch-notifications": "Unable to display cold chain notifications",
"error.field-must-be-specified": "{{field}} must be specified",
Expand Down Expand Up @@ -503,6 +505,7 @@
"label.add-new-vaccine-course": "Add vaccine course",
"label.add-variant": "Add variant",
"label.additional-info": "Additional Info",
"label.additions": "Additions",
"label.address": "Address",
"label.adjust-by": "by",
"label.adjusted": "Adjusted",
Expand Down Expand Up @@ -531,6 +534,7 @@
"label.asset-properties": "Asset Properties",
"label.atc-category": "ATC category",
"label.auth-status": "Approval Status",
"label.available": "Available",
"label.available-batches": "Available batches",
"label.available-packs": "Available (packs)",
"label.available-quantity": "Available quantity: {{number}} units",
Expand Down Expand Up @@ -570,7 +574,6 @@
"label.cold-consecutive": "Cold Consecutive",
"label.cold-cumulative": "Cold Cumulative",
"label.cold-storage-location": "Cold storage location",
"label.storage-type": "Storage type",
"label.collapse": "Collapse",
"label.collapse-all": "Collapse all",
"label.color": "Colour",
Expand Down Expand Up @@ -616,6 +619,7 @@
"label.date-of-birth": "Date of Birth",
"label.date-time": "Date time",
"label.day": "day",
"label.days-out-of-stock": "Days out of stock",
"label.ddd": "Defined Daily Dose",
"label.deceased": "Deceased",
"label.decrease-qty": "Decrease quantity",
Expand Down Expand Up @@ -718,8 +722,10 @@
"label.inbound-not-delivered": "Inbound shipments not delivered",
"label.inbound-shipment": "Inbound shipment",
"label.inbound-shipment-cant-delete-reserved-line": "Batch {{batch}} (item code {{itemCode}}) is already reserved/issued",
"label.incoming": "Incoming",
"label.incoming-stock": "Stock arriving",
"label.increase-qty": "Increase quantity",
"label.initial-stock-on-hand": "Initial SOH",
"label.initialise-store-properties": "Initialise store properties for GAPS",
"label.initialised": "Initialised",
"label.installation-date": "Installation date",
Expand Down Expand Up @@ -836,6 +842,7 @@
"label.out-of-stock": "Out of stock",
"label.outbound-shipment": "Outbound shipment",
"label.outer-pack-size": "Outer pack size",
"label.outgoing": "Outgoing",
"label.pack": "Pack",
"label.pack-cost-price": "Pack cost price",
"label.pack-quantity": "Pack Qty",
Expand Down Expand Up @@ -935,6 +942,7 @@
"label.shipment-created": "Shipment created",
"label.shipments": "Shipments",
"label.shipped": "Shipped",
"label.short-expiry": "Short Expiry",
"label.showing": "Showing",
"label.site": "Site:",
"label.snapshot-num-of-packs": "Snapshot Packs",
Expand All @@ -953,6 +961,7 @@
"label.stocktake-comment": "Comment",
"label.stocktake-date": "Stocktake Date",
"label.stocktake-frequency": "Stocktake frequency",
"label.storage-type": "Storage type",
"label.store": "Store",
"label.strength": "Strength",
"label.sub-catalogue": "Sub catalogue",
Expand Down
23 changes: 21 additions & 2 deletions client/packages/common/src/types/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2934,13 +2934,21 @@ export type InsertResponseRequisitionLineErrorInterface = {
};

export type InsertResponseRequisitionLineInput = {
additionInUnits?: InputMaybe<Scalars['Float']['input']>;
averageMonthlyConsumption?: InputMaybe<Scalars['Float']['input']>;
comment?: InputMaybe<Scalars['String']['input']>;
daysOutOfStock?: InputMaybe<Scalars['Float']['input']>;
expiringUnits?: InputMaybe<Scalars['Float']['input']>;
id: Scalars['String']['input'];
incomingUnits?: InputMaybe<Scalars['Float']['input']>;
itemId: Scalars['String']['input'];
lossInUnits?: InputMaybe<Scalars['Float']['input']>;
optionId?: InputMaybe<Scalars['String']['input']>;
outgoingUnits?: InputMaybe<Scalars['Float']['input']>;
requestedQuantity?: InputMaybe<Scalars['Float']['input']>;
requisitionId: Scalars['String']['input'];
stockOnHand?: InputMaybe<Scalars['Float']['input']>;
supplyQuantity?: InputMaybe<Scalars['Float']['input']>;
theirStockOnHand?: InputMaybe<Scalars['Float']['input']>;
};

export type InsertResponseRequisitionLineResponse = InsertResponseRequisitionLineError | RequisitionLineNode;
Expand Down Expand Up @@ -6428,6 +6436,8 @@ export type RequisitionLineNode = {
alreadyIssued: Scalars['Float']['output'];
approvalComment?: Maybe<Scalars['String']['output']>;
approvedQuantity: Scalars['Float']['output'];
availableStockOnHand: Scalars['Float']['output'];
averageMonthlyConsumption: Scalars['Float']['output'];
comment?: Maybe<Scalars['String']['output']>;
daysOutOfStock: Scalars['Float']['output'];
expiringUnits: Scalars['Float']['output'];
Expand All @@ -6450,6 +6460,7 @@ export type RequisitionLineNode = {
/** OutboundShipment lines linked to requisitions line */
outboundShipmentLines: InvoiceLineConnector;
outgoingUnits: Scalars['Float']['output'];
reason?: Maybe<ReasonOptionNode>;
/**
* Quantity remaining to supply
* supplyQuantity minus all (including unallocated) linked invoice lines numberOfPacks * packSize
Expand Down Expand Up @@ -8084,11 +8095,19 @@ export type UpdateResponseRequisitionLineErrorInterface = {
};

export type UpdateResponseRequisitionLineInput = {
additionInUnits?: InputMaybe<Scalars['Float']['input']>;
averageMonthlyConsumption?: InputMaybe<Scalars['Float']['input']>;
comment?: InputMaybe<Scalars['String']['input']>;
daysOutOfStock?: InputMaybe<Scalars['Float']['input']>;
expiringUnits?: InputMaybe<Scalars['Float']['input']>;
id: Scalars['String']['input'];
incomingUnits?: InputMaybe<Scalars['Float']['input']>;
lossInUnits?: InputMaybe<Scalars['Float']['input']>;
optionId?: InputMaybe<Scalars['String']['input']>;
outgoingUnits?: InputMaybe<Scalars['Float']['input']>;
requestedQuantity?: InputMaybe<Scalars['Float']['input']>;
stockOnHand?: InputMaybe<Scalars['Float']['input']>;
supplyQuantity?: InputMaybe<Scalars['Float']['input']>;
theirStockOnHand?: InputMaybe<Scalars['Float']['input']>;
};

export type UpdateResponseRequisitionLineResponse = RequisitionLineNode | UpdateResponseRequisitionLineError;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const useResponseColumns = () => {
queryParams: { sortBy },
} = useUrlQueryParams({ initialSort: { key: 'itemName', dir: 'asc' } });
const { isRemoteAuthorisation } = useResponse.utils.isRemoteAuthorisation();
const { programName } = useResponse.document.fields(['programName']);

const columnDefinitions: ColumnDescription<ResponseLineFragment>[] = [
getCommentPopoverColumn(),
Expand Down Expand Up @@ -56,36 +57,160 @@ export const useResponseColumns = () => {
accessor: ({ rowData }) => rowData.itemStats.availableStockOnHand,
},
],
{
];

if (!programName) {
columnDefinitions.push({
key: 'customerStockOnHand',
label: 'label.customer-soh',
description: 'description.customer-soh',
width: 100,
align: ColumnAlign.Right,
getSortValue: rowData =>
rowData.linkedRequisitionLine?.itemStats?.availableStockOnHand ?? '',
Cell: PackQuantityCell,
accessor: ({ rowData }) =>
rowData.linkedRequisitionLine?.itemStats.availableStockOnHand ?? 0,
getSortValue: rowData => rowData.availableStockOnHand,
accessor: ({ rowData }) => rowData.availableStockOnHand,
});
}
columnDefinitions.push(
// TODO: Global pref to show/hide the next columns
{
key: 'initialStockOnHand',
label: 'label.initial-stock-on-hand',
width: 100,
align: ColumnAlign.Right,
sortable: false,
description: 'description.initial-stock-on-hand',
Cell: PackQuantityCell,
accessor: ({ rowData }) => rowData.initialStockOnHandUnits,
},
{
key: 'incomingStock',
label: 'label.incoming',
width: 100,
align: ColumnAlign.Right,
sortable: false,
Cell: PackQuantityCell,
accessor: ({ rowData }) => rowData.incomingUnits,
},
{
key: 'outgoingUnits',
label: 'label.outgoing',
width: 100,
align: ColumnAlign.Right,
sortable: false,
Cell: PackQuantityCell,
accessor: ({ rowData }) => rowData.outgoingUnits,
},
{
key: 'losses',
label: 'label.losses',
width: 100,
align: ColumnAlign.Right,
sortable: false,
Cell: PackQuantityCell,
accessor: ({ rowData }) => rowData.lossInUnits,
},
{
key: 'additions',
label: 'label.additions',
width: 100,
align: ColumnAlign.Right,
sortable: false,
Cell: PackQuantityCell,
accessor: ({ rowData }) => rowData.additionInUnits,
},
{
key: 'availableUnits',
label: 'label.available',
width: 100,
align: ColumnAlign.Right,
sortable: false,
description: 'description.available-stock',
Cell: PackQuantityCell,
accessor: ({ rowData }) => {
const stockOnHand = rowData.initialStockOnHandUnits;

const incomingStock = rowData.incomingUnits + rowData.additionInUnits;
const outgoingStock = rowData.lossInUnits + rowData.outgoingUnits;

return stockOnHand + incomingStock - outgoingStock;
},
},
{
key: 'expiringUnits',
label: 'label.short-expiry',
width: 100,
align: ColumnAlign.Right,
sortable: false,
Cell: PackQuantityCell,
accessor: ({ rowData }) => rowData.expiringUnits,
},
{
key: 'daysOutOfStock',
label: 'label.days-out-of-stock',
width: 100,
align: ColumnAlign.Right,
sortable: false,
Cell: PackQuantityCell,
accessor: ({ rowData }) => rowData.daysOutOfStock,
},
{
key: 'amc',
label: 'label.amc',
width: 100,
align: ColumnAlign.Right,
sortable: false,
Cell: PackQuantityCell,
accessor: ({ rowData }) => rowData.averageMonthlyConsumption,
},
{
key: 'mos',
label: 'label.months-of-stock',
width: 100,
align: ColumnAlign.Right,
sortable: false,
Cell: PackQuantityCell,
accessor: ({ rowData }) => {
const stockOnHand = rowData.initialStockOnHandUnits;
const incomingStock = rowData.incomingUnits + rowData.additionInUnits;
const outgoingStock = rowData.lossInUnits + rowData.outgoingUnits;

const available = stockOnHand + incomingStock - outgoingStock;

const averageMonthlyConsumption = rowData.averageMonthlyConsumption;

return averageMonthlyConsumption !== 0
? available / averageMonthlyConsumption
: 0;
},
},
{
key: 'suggestedQuantity',
label: 'label.suggested-quantity',
width: 150,
align: ColumnAlign.Right,
sortable: false,
Cell: PackQuantityCell,
accessor: ({ rowData }) => rowData.suggestedQuantity,
},
[
'requestedQuantity',
{
getSortValue: rowData => rowData.requestedQuantity,
Cell: PackQuantityCell,
accessor: ({rowData}) => rowData.requestedQuantity,
accessor: ({ rowData }) => rowData.requestedQuantity,
width: 150,
},
],
];
]
);

if (isRemoteAuthorisation) {
columnDefinitions.push({
key: 'approvedQuantity',
label: 'label.approved-quantity',
sortable: false,
Cell: PackQuantityCell,
accessor: ({rowData}) => rowData.approvedQuantity,
accessor: ({ rowData }) => rowData.approvedQuantity,
});
columnDefinitions.push({
key: 'approvalComment',
Expand All @@ -99,18 +224,26 @@ export const useResponseColumns = () => {
{
getSortValue: rowData => rowData.supplyQuantity,
Cell: PackQuantityCell,
accessor: ({rowData}) => rowData.requestedQuantity,
accessor: ({ rowData }) => rowData.requestedQuantity,
},
]);

// TODO: Global pref to show/hide column
columnDefinitions.push({
key: 'reason',
label: 'label.reason',
sortable: false,
accessor: ({ rowData }) => rowData.reason?.reason,
});

columnDefinitions.push({
label: 'label.already-issued',
description: 'description.already-issued',
key: 'alreadyIssued',
align: ColumnAlign.Right,
getSortValue: rowData => rowData.alreadyIssued,
Cell: PackQuantityCell,
accessor: ({rowData}) => rowData.alreadyIssued,
accessor: ({ rowData }) => rowData.alreadyIssued,
width: 100,
});

Expand All @@ -121,7 +254,7 @@ export const useResponseColumns = () => {
align: ColumnAlign.Right,
getSortValue: rowData => rowData.remainingQuantityToSupply,
Cell: PackQuantityCell,
accessor: ({rowData}) => rowData.remainingQuantityToSupply,
accessor: ({ rowData }) => rowData.remainingQuantityToSupply,
});
columnDefinitions.push(GenericColumnKey.Selection);

Expand Down
Loading

0 comments on commit 5ecf2f8

Please sign in to comment.