Skip to content

Commit

Permalink
Merge branch 'develop' into 5266-action-mechanism-for-json-forms
Browse files Browse the repository at this point in the history
  • Loading branch information
CarlosNZ committed Nov 14, 2024
2 parents 477fa98 + 21b8e81 commit 7b298c9
Show file tree
Hide file tree
Showing 16 changed files with 638 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ import {
useNavigate,
useDisabledNotificationPopover,
RouteBuilder,
useConfirmationModal,
FnUtils,
AssetLogStatusInput,
} from '@openmsupply-client/common';
import { AppRoute } from '@openmsupply-client/config';
import { useAssets } from '../api';
import { DraftAsset } from '../types';

export const AddFromScannerButtonComponent = () => {
const t = useTranslation();
Expand All @@ -30,19 +34,60 @@ export const AddFromScannerButtonComponent = () => {
const equipmentRoute = RouteBuilder.create(AppRoute.Coldchain).addPart(
AppRoute.Equipment
);
const { mutateAsync: fetchAsset } = useAssets.document.fetch();
const { mutateAsync: scanAsset } = useAssets.document.scan();
const { mutateAsync: saveNewAsset } = useAssets.document.insert();
const { insertLog, invalidateQueries } = useAssets.log.insert();
const newAssetData = useRef<DraftAsset>();

const showCreateConfirmation = useConfirmationModal({
onConfirm: () => {
if (newAssetData.current) {
saveNewAsset(newAssetData.current)
.then(async () => {
if (newAssetData.current) {
await insertLog({
id: FnUtils.generateUUID(),
assetId: newAssetData.current.id,
comment: t('label.created'),
status: AssetLogStatusInput.Functioning,
});
invalidateQueries();
navigate(equipmentRoute.addPart(newAssetData.current.id).build());
}
})
.catch(e => error(t('error.unable-to-save-asset', { error: e }))());
}
},
message: t('heading.create-new-asset'),
title: t('messages.create-new-asset-confirmation'),
});

const handleScanResult = async (result: ScanResult) => {
if (!!result.content) {
const { content } = result;
const id = content;
const asset = await fetchAsset(id).catch(() => {});
if (asset) {
navigate(equipmentRoute.addPart(id).build());

const asset = await scanAsset(content).catch(() => {});

if (asset?.__typename !== 'AssetNode') {
error(t('error.no-matching-asset', { id: result.content }))();
return;
}
if (asset?.id) {
navigate(equipmentRoute.addPart(asset?.id).build());
return;
}

error(t('error.no-matching-asset', { id }))();
// If not existing, offer to create from the parsed GS1 data
if (!asset?.id) {
newAssetData.current = {
...asset,
id: FnUtils.generateUUID(),
locationIds: [],
parsedProperties: {},
parsedCatalogProperties: {},
};
showCreateConfirmation();
}
}
};

Expand Down
7 changes: 7 additions & 0 deletions client/packages/coldchain/src/Equipment/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ export const getAssetQueries = (sdk: Sdk, storeId: string) => ({

throw new Error('Asset not found');
},
byScannerString: async (inputText: string) => {
const { assetByScannedString } = await sdk.assetByScannedString({
storeId,
inputText,
});
return assetByScannedString;
},
list: async (
{ first, offset, sortBy, filterBy }: ListParams<AssetFragment>,
storeCode?: string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { useAsset, useFetchAssetById } from './useAsset';
import {
useAsset,
useFetchAssetById,
useFetchAssetByScannerString,
} from './useAsset';
import { useAssetDelete } from './useAssetDelete';
import { useAssetFields } from './useAssetFields';
import { useAssetInsert } from './useAssetInsert';
Expand All @@ -18,5 +22,6 @@ export const Document = {
useAssetsDelete,
useAssetUpdate,
useFetchAssetById,
useFetchAssetByScannerString,
useAssetProperties,
};
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,10 @@ export const useFetchAssetById = () => {
onError: () => {},
});
};

export const useFetchAssetByScannerString = () => {
const api = useAssetApi();
return useMutation(api.get.byScannerString, {
onError: () => {},
});
};
1 change: 1 addition & 0 deletions client/packages/coldchain/src/Equipment/api/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const useAssets = {

document: {
fetch: Document.useFetchAssetById,
scan: Document.useFetchAssetByScannerString,
get: Document.useAsset,
list: Document.useAssets,
listAll: Document.useAssetsAll,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ export type AssetByIdQueryVariables = Types.Exact<{

export type AssetByIdQuery = { __typename: 'Queries', assets: { __typename: 'AssetConnector', totalCount: number, nodes: Array<{ __typename: 'AssetNode', catalogueItemId?: string | null, assetNumber?: string | null, createdDatetime: any, id: string, installationDate?: string | null, properties: string, catalogProperties?: string | null, modifiedDatetime: any, notes?: string | null, replacementDate?: string | null, serialNumber?: string | null, storeId?: string | null, donorNameId?: string | null, warrantyStart?: string | null, warrantyEnd?: string | null, needsReplacement?: boolean | null, documents: { __typename: 'SyncFileReferenceConnector', nodes: Array<{ __typename: 'SyncFileReferenceNode', fileName: string, id: string, mimeType?: string | null }> }, locations: { __typename: 'LocationConnector', totalCount: number, nodes: Array<{ __typename: 'LocationNode', id: string, code: string, name: string, onHold: boolean, coldStorageType?: { __typename: 'ColdStorageTypeNode', id: string, name: string, maxTemperature: number, minTemperature: number } | null }> }, statusLog?: { __typename: 'AssetLogNode', logDatetime: any, status?: Types.StatusType | null, reason?: { __typename: 'AssetLogReasonNode', reason: string } | null } | null, store?: { __typename: 'StoreNode', id: string, code: string, storeName: string } | null, catalogueItem?: { __typename: 'AssetCatalogueItemNode', manufacturer?: string | null, model: string } | null, assetType?: { __typename: 'AssetTypeNode', id: string, name: string } | null, assetClass?: { __typename: 'AssetClassNode', id: string, name: string } | null, assetCategory?: { __typename: 'AssetCategoryNode', id: string, name: string } | null, donor?: { __typename: 'NameNode', id: string, name: string } | null }> } };

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


export type AssetByScannedStringQuery = { __typename: 'Queries', assetByScannedString: { __typename: 'AssetNode', catalogueItemId?: string | null, assetNumber?: string | null, createdDatetime: any, id: string, installationDate?: string | null, properties: string, catalogProperties?: string | null, modifiedDatetime: any, notes?: string | null, replacementDate?: string | null, serialNumber?: string | null, storeId?: string | null, donorNameId?: string | null, warrantyStart?: string | null, warrantyEnd?: string | null, needsReplacement?: boolean | null, documents: { __typename: 'SyncFileReferenceConnector', nodes: Array<{ __typename: 'SyncFileReferenceNode', fileName: string, id: string, mimeType?: string | null }> }, locations: { __typename: 'LocationConnector', totalCount: number, nodes: Array<{ __typename: 'LocationNode', id: string, code: string, name: string, onHold: boolean, coldStorageType?: { __typename: 'ColdStorageTypeNode', id: string, name: string, maxTemperature: number, minTemperature: number } | null }> }, statusLog?: { __typename: 'AssetLogNode', logDatetime: any, status?: Types.StatusType | null, reason?: { __typename: 'AssetLogReasonNode', reason: string } | null } | null, store?: { __typename: 'StoreNode', id: string, code: string, storeName: string } | null, catalogueItem?: { __typename: 'AssetCatalogueItemNode', manufacturer?: string | null, model: string } | null, assetType?: { __typename: 'AssetTypeNode', id: string, name: string } | null, assetClass?: { __typename: 'AssetClassNode', id: string, name: string } | null, assetCategory?: { __typename: 'AssetCategoryNode', id: string, name: string } | null, donor?: { __typename: 'NameNode', id: string, name: string } | null } | { __typename: 'ScannedDataParseError' } };

export type AssetLogsQueryVariables = Types.Exact<{
filter: Types.AssetLogFilterInput;
sort?: Types.InputMaybe<Array<Types.AssetLogSortInput> | Types.AssetLogSortInput>;
Expand Down Expand Up @@ -242,6 +250,15 @@ export const AssetByIdDocument = gql`
}
}
${AssetFragmentDoc}`;
export const AssetByScannedStringDocument = gql`
query assetByScannedString($storeId: String!, $inputText: String!) {
assetByScannedString(storeId: $storeId, inputText: $inputText) {
... on AssetNode {
...Asset
}
}
}
${AssetFragmentDoc}`;
export const AssetLogsDocument = gql`
query assetLogs($filter: AssetLogFilterInput!, $sort: [AssetLogSortInput!], $storeId: String!) {
assetLogs(filter: $filter, sort: $sort, storeId: $storeId) {
Expand Down Expand Up @@ -346,6 +363,9 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
assetById(variables: AssetByIdQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<AssetByIdQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<AssetByIdQuery>(AssetByIdDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'assetById', 'query', variables);
},
assetByScannedString(variables: AssetByScannedStringQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<AssetByScannedStringQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<AssetByScannedStringQuery>(AssetByScannedStringDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'assetByScannedString', 'query', variables);
},
assetLogs(variables: AssetLogsQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<AssetLogsQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<AssetLogsQuery>(AssetLogsDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'assetLogs', 'query', variables);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ query assetById($storeId: String!, $assetId: String!) {
}
}

query assetByScannedString($storeId: String!, $inputText: String!) {
assetByScannedString(storeId: $storeId, inputText: $inputText) {
... on AssetNode {
...Asset
}
}
}

query assetLogs(
$filter: AssetLogFilterInput!
$sort: [AssetLogSortInput!]
Expand Down
4 changes: 3 additions & 1 deletion client/packages/common/src/intl/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@
"heading.consumption-history": "Consumption History (monthly)",
"heading.create-outbound-shipment": "Create Outbound Shipment",
"heading.create-vaccine-course": "Create vaccine course",
"heading.create-new-asset": "Create new asset",
"heading.custom": "Custom",
"heading.custom-logo": "Custom logo",
"heading.custom-logo-info": "Replaces the default \"mSupply man\". The logo has to be in svg format, e.g. <?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>...<svg...>",
Expand Down Expand Up @@ -1268,6 +1269,7 @@
"messages.create-stocktake-1": "You can create a stocktake based on items currently assigned to a location, items that you currently have in stock, items assigned to a master list, or items expiring before a particular date.",
"messages.create-stocktake-2": "To create an empty stocktake, simply click OK to continue.",
"messages.created-new-vaccine-course": "Successfully created vaccine course",
"messages.create-new-asset-confirmation": "The asset you scanned is not currently in the system, but has provided appropriate GS1 data. Would you like to create a new asset with this data?",
"messages.customer-requisition-created-on": "Customer requisition created on {{date}}",
"messages.delete-this-line": "Delete this line",
"messages.deleted-assets_one": "Deleted {{count}} asset",
Expand Down Expand Up @@ -1666,4 +1668,4 @@
"warning.caps-lock": "Warning: Caps lock is on",
"warning.field-not-parsed": "{{field}} not parsed",
"warning.nothing-to-supply": "Nothing left to supply!"
}
}
32 changes: 20 additions & 12 deletions client/packages/common/src/intl/locales/fr/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@
"heading.edit-item": "Éditer article",
"heading.edit-tax-rate": "Modifier le taux de taxe (%)",
"heading.edit-vaccine-course": "Modifier un calendrier vaccinal",
"heading.expiring": "En cours d'expiration",
"heading.expiring-stock": "Expiration des stocks",
"heading.expiring": "En cours de péremption",
"heading.expiring-stock": "Stock en voie de péremption",
"heading.foreign-currency": "Devise étrangère",
"heading.functional-status": "État fonctionnel",
"heading.grand-total": "Grand total",
Expand Down Expand Up @@ -641,10 +641,10 @@
"label.expired_many": "Lots expirés",
"label.expired_one": "Lot expiré",
"label.expired_other": "Lots expirés",
"label.expiring-item-period": "Période d'expiration de l'article",
"label.expiring-soon": "Stock expirant",
"label.expiring-soon_one": "Lot expirant dans les 30 jours",
"label.expiring-soon_other": "Lots expirant dans les 30 jours",
"label.expiring-item-period": "Période de péremption de l'article",
"label.expiring-soon": "Stock en voie de péremption",
"label.expiring-soon_one": "Lot périmant dans les 30 jours",
"label.expiring-soon_other": "Lots périmant dans les 30 jours",
"label.expiry": "Exp.",
"label.facility": "Facilité",
"label.fc-cost-price": "Prix d'achat en DE",
Expand Down Expand Up @@ -694,7 +694,7 @@
"label.item_many": "Articles",
"label.item_one": "Article",
"label.item_other": "Articles",
"label.items-expiring-before": "Articles expirant avant",
"label.items-expiring-before": "Produits périmant avant",
"label.items-no-stock_few": "Articles sans stock",
"label.items-no-stock_many": "Articles sans stock",
"label.items-no-stock_one": "Article en rupture de stock",
Expand Down Expand Up @@ -1400,10 +1400,10 @@
"report.created-date": "Créé le",
"report.entered-code": "Code saisi",
"report.expected-usage": "Consommation prévue",
"report.expiring": "En cours d'expiration",
"report.expiring-12-months": "Expirant dans 12 mois",
"report.expiring-6-months": "Expirant dans 6 mois",
"report.expiring-in-days": "Expire dans (jours)",
"report.expiring": "En cours de péremption",
"report.expiring-12-months": "Périmant dans 12 mois",
"report.expiring-6-months": "Périmant dans 6 mois",
"report.expiring-in-days": "Périme dans (jours)",
"report.expiry-date": "Date d'expiration",
"report.extension": "Montant Total",
"report.global-total": "Total global",
Expand Down Expand Up @@ -1650,5 +1650,13 @@
"messages.no-item-variants": "Aucune variante d'article configurée",
"messages.no-transaction-other-facility": "Les transactions de stock ne sont pas enregistrées pour les vaccinations administrées dans d'autres sites",
"messages.requisition-no-stock": "Aucun stock disponible actuellement",
"placeholder.enter-facility-code-or-name": "Entrez le code ou le nom du site"
"placeholder.enter-facility-code-or-name": "Entrez le code ou le nom du site",
"error.failed-to-delete-bundled-item": "Échec de la suppression de l'article groupé",
"description.bundle-ratio": "Le nombre d'unités de l'article groupé pour chaque unité de l'article de base",
"description.bundled-item-ratio": "Le nombre d'unités de l'article de base pour chaque unité de cet article",
"button.create-new": "Nouvelle création",
"button.view-patient": "Voir Patient",
"error.failed-to-save-bundled-item": "Échec de la suppression de l'élément groupé",
"button.next": "Suivant",
"button.previous": "Précédent"
}
Loading

0 comments on commit 7b298c9

Please sign in to comment.