diff --git a/src/billable-services/billable-service.resource.ts b/src/billable-services/billable-service.resource.ts index 282e0807..1c42c179 100644 --- a/src/billable-services/billable-service.resource.ts +++ b/src/billable-services/billable-service.resource.ts @@ -7,6 +7,8 @@ import type { CreateBillableServicePayload, PaymentModePayload, UpdateBillableServicePayload, + CreateCashPointPayload, + UpdateCashPointPayload, } from '../types'; import type { BillingConfig } from '../config-schema'; @@ -106,6 +108,26 @@ export const updateBillableService = (uuid: string, payload: UpdateBillableServi }); }; +export const createCashPoint = (payload: CreateCashPointPayload) => { + return openmrsFetch(`${apiBasePath}cashPoint`, { + method: 'POST', + body: payload, + headers: { + 'Content-Type': 'application/json', + }, + }); +}; + +export const updateCashPoint = (uuid: string, payload: UpdateCashPointPayload) => { + return openmrsFetch(`${apiBasePath}cashPoint/${uuid}`, { + method: 'POST', + body: payload, + headers: { + 'Content-Type': 'application/json', + }, + }); +}; + export const createPaymentMode = (payload: PaymentModePayload) => { const url = `${restBaseUrl}/billing/paymentMode`; return openmrsFetch(url, { diff --git a/src/billable-services/cash-point/add-cash-point.modal.tsx b/src/billable-services/cash-point/add-cash-point.modal.tsx index ba2a2343..f8a14abb 100644 --- a/src/billable-services/cash-point/add-cash-point.modal.tsx +++ b/src/billable-services/cash-point/add-cash-point.modal.tsx @@ -5,31 +5,26 @@ import { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; import { Button, Dropdown, Form, ModalBody, ModalFooter, ModalHeader, Stack, TextInput } from '@carbon/react'; import { showSnackbar, openmrsFetch, restBaseUrl, getCoreTranslation } from '@openmrs/esm-framework'; +import { createCashPoint, updateCashPoint } from '../billable-service.resource'; +import type { CashPoint, CreateCashPointPayload, UpdateCashPointPayload } from '../../types'; type CashPointFormValues = { name: string; - uuid: string; location: string; }; interface AddCashPointModalProps { + cashPointToEdit?: CashPoint; closeModal: () => void; onCashPointAdded: () => void; } -const AddCashPointModal: React.FC = ({ closeModal, onCashPointAdded }) => { +const AddCashPointModal: React.FC = ({ cashPointToEdit, closeModal, onCashPointAdded }) => { const { t } = useTranslation(); const [locations, setLocations] = useState([]); const cashPointSchema = z.object({ name: z.string().min(1, t('cashPointNameRequired', 'Cash Point Name is required')), - uuid: z - .string() - .min(1, t('uuidRequired', 'UUID is required')) - .regex( - /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i, - t('invalidUuidFormat', 'Invalid UUID format'), - ), location: z.string().min(1, t('locationRequired', 'Location is required')), }); @@ -41,9 +36,8 @@ const AddCashPointModal: React.FC = ({ closeModal, onCas } = useForm({ resolver: zodResolver(cashPointSchema), defaultValues: { - name: '', - uuid: '', - location: '', + name: cashPointToEdit?.name ?? '', + location: cashPointToEdit?.location?.uuid ?? '', }, }); @@ -71,18 +65,19 @@ const AddCashPointModal: React.FC = ({ closeModal, onCas const onSubmit = async (data: CashPointFormValues) => { try { - await openmrsFetch(`${restBaseUrl}/billing/cashPoint`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: { + if (cashPointToEdit) { + const updatePayload: UpdateCashPointPayload = { name: data.name, - uuid: data.uuid, location: { uuid: data.location }, - }, - }); - + }; + await updateCashPoint(cashPointToEdit.uuid, updatePayload); + } else { + const createPayload: CreateCashPointPayload = { + name: data.name, + location: { uuid: data.location }, + }; + await createCashPoint(createPayload); + } showSnackbar({ title: t('success', 'Success'), subtitle: t('cashPointSaved', 'Cash point was successfully saved.'), @@ -90,7 +85,7 @@ const AddCashPointModal: React.FC = ({ closeModal, onCas }); closeModal(); - reset({ name: '', uuid: '', location: '' }); + reset({ name: '', location: '' }); onCashPointAdded(); } catch (err) { showSnackbar({ @@ -104,7 +99,10 @@ const AddCashPointModal: React.FC = ({ closeModal, onCas return ( <> - +
@@ -122,20 +120,6 @@ const AddCashPointModal: React.FC = ({ closeModal, onCas /> )} /> - ( - - )} - /> { const { t } = useTranslation(); const [cashPoints, setCashPoints] = useState([]); + const layout = useLayoutType(); const fetchCashPoints = useCallback(async () => { try { @@ -45,7 +57,15 @@ const CashPointConfiguration: React.FC = () => { }); }; - const rowData = cashPoints.map((point) => ({ + const handleEditCashPoint = (point: CashPoint) => { + const dispose = showModal('add-cash-point-modal', { + cashPointToEdit: point, + onCashPointAdded: fetchCashPoints, + closeModal: () => dispose(), + }); + }; + + const rowData = cashPoints.map((point: CashPoint) => ({ id: point.uuid, name: point.name, uuid: point.uuid, @@ -67,7 +87,7 @@ const CashPointConfiguration: React.FC = () => {
- + {({ rows, headers, getTableProps, getHeaderProps, getRowProps }) => ( @@ -78,6 +98,7 @@ const CashPointConfiguration: React.FC = () => { {header.header} ))} + @@ -86,6 +107,20 @@ const CashPointConfiguration: React.FC = () => { {row.cells.map((cell) => ( {cell.value} ))} + + + { + const cashPoint = cashPoints.find((point) => point.uuid === row.id); + if (cashPoint) { + handleEditCashPoint(cashPoint); + } + }} + /> + + ))} diff --git a/src/types/index.ts b/src/types/index.ts index b8293e6e..911c836b 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -33,7 +33,7 @@ interface Location { links: LocationLink[]; } -interface CashPoint { +export interface CashPoint { uuid: string; name: string; description: string; @@ -41,6 +41,15 @@ interface CashPoint { location: Location; } +export interface CreateCashPointPayload { + name: string; + description?: string; + location: { + uuid: string; + }; +} +export type UpdateCashPointPayload = Partial; + interface ProviderLink { rel: string; uri: string; diff --git a/translations/en.json b/translations/en.json index 80b0b8ce..9d1e8fd4 100644 --- a/translations/en.json +++ b/translations/en.json @@ -63,8 +63,6 @@ "cashPointNamePlaceholder": "For example, Pharmacy Cash Point", "cashPointNameRequired": "Cash point name is required", "cashPointSaved": "Cash point was successfully saved.", - "cashPointUuid": "Cash point UUID", - "cashPointUuidPlaceholder": "Enter UUID", "checkFilters": "Check the filters above", "confirmDeleteMessage": "Are you sure you want to delete this payment mode? Proceed cautiously.", "cumulativeBills": "Cumulative bills", @@ -81,6 +79,7 @@ "discountAmount": "Discount amount", "editBillableService": "Edit billable service", "editBillLineItem": "Edit bill line item", + "editCashPoint": "Edit cash point", "editPaymentMode": "Edit payment mode", "editThisBillItem": "Edit this bill item", "enterAmount": "Enter amount", @@ -106,7 +105,6 @@ "home": "Home", "identifier": "Identifier", "insuranceScheme": "Insurance scheme", - "invalidUuidFormat": "Invalid UUID format", "invalidWaiverAmount": "Invalid waiver amount", "inventoryItem": "Inventory item", "invoice": "Invoice", @@ -220,7 +218,6 @@ "unitPrice": "Unit price", "unitPriceHelperText": "This is the unit price for this item", "uuid": "UUID", - "uuidRequired": "UUID is required", "validationError": "Validation error", "visitTime": "Visit time", "waiverForm": "Waiver form"