Skip to content

Commit

Permalink
Merge pull request #5191 from msupply-foundation/5119-Allow-user-to-c…
Browse files Browse the repository at this point in the history
…reate-manual-requisitions

5119 allow user to create manual requisitions
  • Loading branch information
roxy-dao authored Oct 23, 2024
2 parents 3fe867e + 9245fad commit 007fe2a
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 7 deletions.
2 changes: 2 additions & 0 deletions client/packages/common/src/intl/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"button.new-outbound-shipment": "New Outbound Shipment",
"button.new-patient": "New Patient",
"button.new-prescription": "New Prescription",
"button.new-requisition": "New Requisition",
"button.new-return": "New Return",
"button.new-shipment": "New Shipment",
"button.new-stock": "New Stock",
Expand Down Expand Up @@ -1082,6 +1083,7 @@
"message.copy-success": "Copied to clipboard successfully",
"message.database-not-local": "Database is running on a server, so can't be downloaded here",
"message.database-not-sqlite": "Database download is only available for SQLite databases",
"message.failed-to-create-requisition": "Failed to create requisition!",
"message.no-supplier": "Inventory Adjustment",
"message.nothing-to-copy": "Nothing to copy",
"message.nothing-to-save": "Nothing to save",
Expand Down
27 changes: 26 additions & 1 deletion client/packages/common/src/types/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2776,6 +2776,24 @@ export type InsertProgramRequestRequisitionInput = {

export type InsertProgramRequestRequisitionResponse = InsertProgramRequestRequisitionError | RequisitionNode;

export type InsertProgramResponseRequisitionError = {
__typename: 'InsertProgramResponseRequisitionError';
error: InsertProgramResponseRequisitionErrorInterface;
};

export type InsertProgramResponseRequisitionErrorInterface = {
description: Scalars['String']['output'];
};

export type InsertProgramResponseRequisitionInput = {
id: Scalars['String']['input'];
otherPartyId: Scalars['String']['input'];
periodId: Scalars['String']['input'];
programOrderTypeId: Scalars['String']['input'];
};

export type InsertProgramResponseRequisitionResponse = InsertProgramResponseRequisitionError | RequisitionNode;

export type InsertRepackError = {
__typename: 'InsertRepackError';
error: InsertRepackErrorInterface;
Expand Down Expand Up @@ -3751,7 +3769,7 @@ export type MasterListSortInput = {

export type MasterListsResponse = MasterListConnector;

export type MaxOrdersReachedForPeriod = InsertProgramRequestRequisitionErrorInterface & {
export type MaxOrdersReachedForPeriod = InsertProgramRequestRequisitionErrorInterface & InsertProgramResponseRequisitionErrorInterface & {
__typename: 'MaxOrdersReachedForPeriod';
description: Scalars['String']['output'];
};
Expand Down Expand Up @@ -3835,6 +3853,7 @@ export type Mutations = {
*/
insertProgramPatient: InsertProgramPatientResponse;
insertProgramRequestRequisition: InsertProgramRequestRequisitionResponse;
insertProgramResponseRequisition: InsertProgramResponseRequisitionResponse;
insertRepack: InsertRepackResponse;
insertRequestRequisition: InsertRequestRequisitionResponse;
insertRequestRequisitionLine: InsertRequestRequisitionLineResponse;
Expand Down Expand Up @@ -4222,6 +4241,12 @@ export type MutationsInsertProgramRequestRequisitionArgs = {
};


export type MutationsInsertProgramResponseRequisitionArgs = {
input: InsertProgramResponseRequisitionInput;
storeId: Scalars['String']['input'];
};


export type MutationsInsertRepackArgs = {
input: InsertRepackInput;
storeId: Scalars['String']['input'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,27 @@ import {
LoadingButton,
EnvUtils,
Platform,
ToggleState,
FnUtils,
RouteBuilder,
ButtonWithIcon,
PlusCircleIcon,
useNavigate,
} from '@openmsupply-client/common';
import { useResponse } from '../api';
import { responsesToCsv } from '../../utils';
import { AppRoute } from '@openmsupply-client/config';
import { CustomerSearchModal } from '@openmsupply-client/system';

export const AppBarButtons = () => {
const { success, error } = useNotification();
export const AppBarButtons = ({
modalController,
}: {
modalController: ToggleState;
}) => {
const t = useTranslation();
const navigate = useNavigate();
const { success, error } = useNotification();
const { mutateAsync: onCreate } = useResponse.document.insert();
const { mutateAsync, isLoading } = useResponse.document.listAll({
key: 'createdDatetime',
direction: 'desc',
Expand All @@ -37,6 +51,11 @@ export const AppBarButtons = () => {
return (
<AppBarButtonsPortal>
<Grid container gap={1}>
<ButtonWithIcon
Icon={<PlusCircleIcon />}
label={t('button.new-requisition')}
onClick={modalController.toggleOn}
/>
<LoadingButton
startIcon={<DownloadIcon />}
isLoading={isLoading}
Expand All @@ -47,6 +66,32 @@ export const AppBarButtons = () => {
{t('button.export')}
</LoadingButton>
</Grid>
<CustomerSearchModal
open={modalController.isOn}
onClose={modalController.toggleOff}
onChange={async name => {
modalController.toggleOff();
try {
await onCreate({
id: FnUtils.generateUUID(),
otherPartyId: name.id,
}).then(({ requisitionNumber }) => {
navigate(
RouteBuilder.create(AppRoute.Distribution)
.addPart(AppRoute.CustomerRequisition)
.addPart(String(requisitionNumber))
.build(),
{ replace: true }
);
});
} catch (e) {
const errorSnack = error(
`${t('message.failed-to-create-requisition')}: ${(e as Error).message}`
);
errorSnack();
}
}}
/>
</AppBarButtonsPortal>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
useUrlQueryParams,
ColumnDescription,
TooltipTextCell,
useToggle,
} from '@openmsupply-client/common';
import { Toolbar } from './Toolbar';
import { AppBarButtons } from './AppBarButtons';
Expand All @@ -32,9 +33,10 @@ const useDisableResponseRows = (rows?: ResponseRowFragment[]) => {
};

export const ResponseRequisitionListView: FC = () => {
const { mutate: onUpdate } = useResponse.document.update();
const navigate = useNavigate();
const t = useTranslation();
const navigate = useNavigate();
const modalController = useToggle();
const { mutate: onUpdate } = useResponse.document.update();
const {
updateSortQuery,
updatePaginationQuery,
Expand Down Expand Up @@ -140,7 +142,7 @@ export const ResponseRequisitionListView: FC = () => {
return (
<>
<Toolbar filter={filter} />
<AppBarButtons />
<AppBarButtons modalController={modalController} />

<DataTable
id="requisition-list"
Expand Down
29 changes: 29 additions & 0 deletions client/packages/requisitions/src/ResponseRequisition/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,35 @@ export const getResponseQueries = (sdk: Sdk, storeId: string) => ({
throw new Error('Unable to load chart data');
},
},
insert: async ({
id,
otherPartyId,
}: {
id: string;
otherPartyId: string;
}): Promise<{
__typename: 'RequisitionNode';
id: string;
requisitionNumber: number;
}> => {
const result = await sdk.insertResponse({
storeId,
input: {
id,
otherPartyId,
maxMonthsOfStock: 1,
minMonthsOfStock: 0,
},
});

const { insertResponseRequisition } = result || {};

if (insertResponseRequisition?.__typename === 'RequisitionNode') {
return insertResponseRequisition;
}

throw new Error('Unable to create requisition');
},
update: async (
patch: Partial<ResponseFragment> & { id: string }
): Promise<{ __typename: 'RequisitionNode'; id: string }> => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useInsertResponse } from './useInsertResponse';
import { useResponse } from './useResponse';
import { useResponseFields } from './useResponseFields';
import { useResponses } from './useResponses';
Expand All @@ -10,4 +11,5 @@ export const Document = {
useResponses,
useResponsesAll,
useUpdateResponse,
useInsertResponse,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useQueryClient, useMutation } from '@openmsupply-client/common';
import { useResponseApi } from '../utils/useResponseApi';

export const useInsertResponse = () => {
const queryClient = useQueryClient();
const api = useResponseApi();
return useMutation(api.insert, {
onSuccess: () => {
queryClient.invalidateQueries(api.keys.base());
},
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const useResponse = {
list: Document.useResponses,
listAll: Document.useResponsesAll,

insert: Document.useInsertResponse,
update: Document.useUpdateResponse,

fields: Document.useResponseFields,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ export type ResponsesQueryVariables = Types.Exact<{

export type ResponsesQuery = { __typename: 'Queries', requisitions: { __typename: 'RequisitionConnector', totalCount: number, nodes: Array<{ __typename: 'RequisitionNode', colour?: string | null, comment?: string | null, createdDatetime: string, finalisedDatetime?: string | null, id: string, otherPartyName: string, requisitionNumber: number, sentDatetime?: string | null, status: Types.RequisitionNodeStatus, theirReference?: string | null, type: Types.RequisitionNodeType, otherPartyId: string, approvalStatus: Types.RequisitionNodeApprovalStatus, programName?: string | null, orderType?: string | null, period?: { __typename: 'PeriodNode', name: string, startDate: string, endDate: string } | null, shipments: { __typename: 'InvoiceConnector', totalCount: number } }> } };

export type InsertResponseMutationVariables = Types.Exact<{
storeId: Types.Scalars['String']['input'];
input: Types.InsertResponseRequisitionInput;
}>;


export type InsertResponseMutation = { __typename: 'Mutations', insertResponseRequisition: { __typename: 'InsertResponseRequisitionError', error: { __typename: 'OtherPartyNotACustomer', description: string } | { __typename: 'OtherPartyNotVisible', description: string } } | { __typename: 'RequisitionNode', id: string, requisitionNumber: number } };

export type UpdateResponseLineMutationVariables = Types.Exact<{
storeId: Types.Scalars['String']['input'];
input: Types.UpdateResponseRequisitionLineInput;
Expand Down Expand Up @@ -233,6 +241,31 @@ export const ResponsesDocument = gql`
}
}
${ResponseRowFragmentDoc}`;
export const InsertResponseDocument = gql`
mutation insertResponse($storeId: String!, $input: InsertResponseRequisitionInput!) {
insertResponseRequisition(input: $input, storeId: $storeId) {
... on RequisitionNode {
__typename
id
requisitionNumber
}
... on InsertResponseRequisitionError {
__typename
error {
description
... on OtherPartyNotACustomer {
__typename
description
}
... on OtherPartyNotVisible {
__typename
description
}
}
}
}
}
`;
export const UpdateResponseLineDocument = gql`
mutation updateResponseLine($storeId: String!, $input: UpdateResponseRequisitionLineInput!) {
updateResponseRequisitionLine(input: $input, storeId: $storeId) {
Expand Down Expand Up @@ -375,6 +408,9 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
responses(variables: ResponsesQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<ResponsesQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<ResponsesQuery>(ResponsesDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'responses', 'query', variables);
},
insertResponse(variables: InsertResponseMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<InsertResponseMutation> {
return withWrapper((wrappedRequestHeaders) => client.request<InsertResponseMutation>(InsertResponseDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'insertResponse', 'mutation', variables);
},
updateResponseLine(variables: UpdateResponseLineMutationVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<UpdateResponseLineMutation> {
return withWrapper((wrappedRequestHeaders) => client.request<UpdateResponseLineMutation>(UpdateResponseLineDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'updateResponseLine', 'mutation', variables);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,33 @@ query responses(
}
}

mutation insertResponse(
$storeId: String!
$input: InsertResponseRequisitionInput!
) {
insertResponseRequisition(input: $input, storeId: $storeId) {
... on RequisitionNode {
__typename
id
requisitionNumber
}
... on InsertResponseRequisitionError {
__typename
error {
description
... on OtherPartyNotACustomer {
__typename
description
}
... on OtherPartyNotVisible {
__typename
description
}
}
}
}
}

mutation updateResponseLine(
$storeId: String!
$input: UpdateResponseRequisitionLineInput!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ fn generate(
name_link_id: other_party_id,
store_id: store_id.to_string(),
r#type: RequisitionType::Response,
status: RequisitionStatus::Draft,
status: RequisitionStatus::New,
created_datetime: Utc::now().naive_utc(),
max_months_of_stock,
min_months_of_stock,
Expand Down

0 comments on commit 007fe2a

Please sign in to comment.