bar code imaghe is saved to DB

This commit is contained in:
2024-02-12 15:29:16 +01:00
parent c833a4afe6
commit dc8f7e335a
4 changed files with 44 additions and 17 deletions

View File

@@ -135,6 +135,7 @@ export const updateOrAddBill = withUser(async (user:AuthenticatedUser, locationI
} = validatedFields.data; } = validatedFields.data;
const billPaid = formData.get('billPaid') === 'on'; const billPaid = formData.get('billPaid') === 'on';
const barcodeImage = formData.get('barcodeImage')?.valueOf() as string;
// update the bill in the mongodb // update the bill in the mongodb
const dbClient = await getDbClient(); const dbClient = await getDbClient();
@@ -151,11 +152,14 @@ export const updateOrAddBill = withUser(async (user:AuthenticatedUser, locationI
"bills.$[elem].attachment": billAttachment, "bills.$[elem].attachment": billAttachment,
"bills.$[elem].notes": billNotes, "bills.$[elem].notes": billNotes,
"bills.$[elem].payedAmount": payedAmount, "bills.$[elem].payedAmount": payedAmount,
"bills.$[elem].barcodeImage": barcodeImage,
}: { }: {
"bills.$[elem].name": billName, "bills.$[elem].name": billName,
"bills.$[elem].paid": billPaid, "bills.$[elem].paid": billPaid,
"bills.$[elem].notes": billNotes, "bills.$[elem].notes": billNotes,
"bills.$[elem].payedAmount": payedAmount, "bills.$[elem].payedAmount": payedAmount,
"bills.$[elem].barcodeImage": barcodeImage,
}; };
// find a location with the given locationID // find a location with the given locationID
@@ -186,7 +190,8 @@ export const updateOrAddBill = withUser(async (user:AuthenticatedUser, locationI
paid: billPaid, paid: billPaid,
attachment: billAttachment, attachment: billAttachment,
notes: billNotes, notes: billNotes,
payedAmount payedAmount,
barcodeImage,
} }
} }
}); });

View File

@@ -44,4 +44,6 @@ export interface Bill {
attachment?: BillAttachment|null; attachment?: BillAttachment|null;
/** (optional) notes */ /** (optional) notes */
notes?: string|null; notes?: string|null;
/** (optional) image data containing PDF471 bar code */
barcodeImage?:string;
}; };

View File

@@ -7,7 +7,7 @@ import { BarcodeFormat, DecodeHintType, Result } from '@zxing/library';
export type BillInfo = { export type BillInfo = {
header: string, header: string,
currency: string, currency: string,
ammount: number, amount: number,
payerName: string, payerName: string,
payerAddress: string, payerAddress: string,
payerTown: string, payerTown: string,
@@ -32,7 +32,7 @@ export type BillInfo = {
* Decoded into: * Decoded into:
* header: HRVHUB30 * header: HRVHUB30
* currency:EUR * currency:EUR
* ammount:000000000012422 * amount:000000000012422
* payerName:DEREŽIĆ NIKOLA * payerName:DEREŽIĆ NIKOLA
* payerAddress:ULICA DIVKA BUDAKA 17/17 * payerAddress:ULICA DIVKA BUDAKA 17/17
* payerTown:10000 ZAGREB * payerTown:10000 ZAGREB
@@ -50,7 +50,7 @@ const parseHubText = (text: string) => {
const [ const [
header, header,
currency, currency,
ammount, amount,
payerName, payerName,
payerAddress, payerAddress,
payerTown, payerTown,
@@ -67,7 +67,7 @@ const parseHubText = (text: string) => {
return { return {
header, header,
currency, currency,
ammount: parseInt(ammount, 10), amount: parseInt(amount, 10),
payerName, payerName,
payerAddress, payerAddress,
payerTown, payerTown,
@@ -231,13 +231,7 @@ const copyBarcodeImage = (canvas:HTMLCanvasElement, decoderResult:Result) => {
// Convert the temporary canvas to a data URL // Convert the temporary canvas to a data URL
const dataURL = tempCanvas.toDataURL(); const dataURL = tempCanvas.toDataURL();
// Create a new Image object return(dataURL);
const barcodeImage = new Image();
// Set the src of the image object to the data URL
barcodeImage.src = dataURL;
return(barcodeImage);
} }
/** Finds PDF417 code within a file and decodes it */ /** Finds PDF417 code within a file and decodes it */
@@ -259,7 +253,7 @@ const decodeFromFile = async (file:File) => {
* @param {Event} event - The change event from an HTMLInputElement. * @param {Event} event - The change event from an HTMLInputElement.
* @return {Promise<HTMLCanvasElement | null>} The canvas with the first page of the PDF, or null if the document is not a PDF. * @return {Promise<HTMLCanvasElement | null>} The canvas with the first page of the PDF, or null if the document is not a PDF.
*/ */
export async function findDecodePdf417(event: React.ChangeEvent<HTMLInputElement>): Promise<{ billInfo: BillInfo, barcodeImage:HTMLImageElement } | null> { export async function findDecodePdf417(event: React.ChangeEvent<HTMLInputElement>): Promise<{ billInfo: BillInfo, barcodeImage:string } | null> {
const file = (event.target as HTMLInputElement).files?.[0]; const file = (event.target as HTMLInputElement).files?.[0];
if(!file) { if(!file) {

View File

@@ -25,22 +25,36 @@ export interface BillEditFormProps {
export const BillEditForm:FC<BillEditFormProps> = ({ location, bill }) => { export const BillEditForm:FC<BillEditFormProps> = ({ location, bill }) => {
const { _id: billID, name, paid, attachment, notes, payedAmount } = bill ?? { _id:undefined, name:"", paid:false, notes:"" }; const { _id: billID, name, paid, attachment, notes, payedAmount: initialPayedAmount, barcodeImage: initialBarcodeImage } = bill ?? { _id:undefined, name:"", paid:false, notes:"" };
const { yearMonth:{year: billYear, month: billMonth}, _id: locationID } = location; const { yearMonth:{year: billYear, month: billMonth}, _id: locationID } = location;
const initialState = { message: null, errors: {} }; const initialState = { message: null, errors: {} };
const handleAction = updateOrAddBillMiddleware.bind(null, locationID, billID, billYear, billMonth); const handleAction = updateOrAddBillMiddleware.bind(null, locationID, billID, billYear, billMonth);
const [ state, dispatch ] = useFormState(handleAction, initialState);
const [ state, dispatch ] = useFormState(handleAction, initialState);
const [ isPaid, setIsPaid ] = React.useState<boolean>(paid); const [ isPaid, setIsPaid ] = React.useState<boolean>(paid);
const [ payedAmount, setPayedAmount ] = React.useState<number>(initialPayedAmount ?? 0);
const [ barcodeImage, setBarcodeImage ] = React.useState<string | undefined>(initialBarcodeImage);
const billPaid_handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { const billPaid_handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setIsPaid(event.target.checked); setIsPaid(event.target.checked);
} }
const billAttachment_handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { const billAttachment_handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
findDecodePdf417(event).then(result => console.log(result)); findDecodePdf417(event)
.then(result => {
if(result) {
const {
barcodeImage,
billInfo
} = result;
setPayedAmount(billInfo.amount);
setBarcodeImage(barcodeImage);
}
});
} }
return( return(
@@ -99,7 +113,7 @@ export const BillEditForm:FC<BillEditFormProps> = ({ location, bill }) => {
<div className="form-control p-1"> <div className="form-control p-1">
<label className="cursor-pointer label p-0 flex"> <label className="cursor-pointer label p-0 flex">
<span className="label-text flex-none w-[6.4em]">Amount</span> <span className="label-text flex-none w-[6.4em]">Amount</span>
<input type="text" id="payedAmount" name="payedAmount" className="input input-bordered text-right w-full" placeholder="0.00" defaultValue={payedAmount === null || payedAmount === undefined ? undefined : payedAmount / 100}/> <input type="text" id="payedAmount" name="payedAmount" className="input input-bordered text-right w-full" placeholder="0.00" defaultValue={payedAmount/100}/>
</label> </label>
</div> </div>
<div id="status-error" aria-live="polite" aria-atomic="true"> <div id="status-error" aria-live="polite" aria-atomic="true">
@@ -113,6 +127,18 @@ export const BillEditForm:FC<BillEditFormProps> = ({ location, bill }) => {
</> </>
} }
<input type="hidden" name="barcodeImage" value={barcodeImage} />
{
barcodeImage ?
<div className="form-control w-[325px] p-1">
<label className="cursor-pointer label p-0">
<span>
<img src={barcodeImage} style={{ maxWidth:"325px" }} />
</span>
</label>
</div> : null
}
<textarea id="billNotes" name="billNotes" className="textarea textarea-bordered my-2 max-w-lg w-full block" placeholder="Note" defaultValue={notes ?? ''}></textarea> <textarea id="billNotes" name="billNotes" className="textarea textarea-bordered my-2 max-w-lg w-full block" placeholder="Note" defaultValue={notes ?? ''}></textarea>
<div id="status-error" aria-live="polite" aria-atomic="true"> <div id="status-error" aria-live="polite" aria-atomic="true">
{state.errors?.billNotes && {state.errors?.billNotes &&