diff --git a/app/lib/actions/locationActions.ts b/app/lib/actions/locationActions.ts index b689453..369f178 100644 --- a/app/lib/actions/locationActions.ts +++ b/app/lib/actions/locationActions.ts @@ -435,6 +435,7 @@ export const fetchAllLocations = withUser(async (user:AuthenticatedUser, year:nu // "bills.hub3aText": 1, // project only file name - leave out file content so that // less data is transferred to the client + "utilBillsProofOfPaymentUploadedAt": 1, "utilBillsProofOfPaymentAttachment.fileName": 1, }, }, @@ -630,6 +631,17 @@ export const uploadUtilBillsProofOfPayment = async (locationID: string, formData noStore(); try { + + // check if attachment already exists for the location + const dbClient = await getDbClient(); + + const existingLocation = await dbClient.collection("lokacije") + .findOne({ _id: locationID }, { projection: { utilBillsProofOfPaymentAttachment: 1 } }); + + if (existingLocation?.utilBillsProofOfPaymentAttachment) { + return { success: false, error: 'An attachment already exists for this location' }; + } + const file = formData.get('utilBillsProofOfPaymentAttachment') as File; // Validate file type @@ -643,13 +655,14 @@ export const uploadUtilBillsProofOfPayment = async (locationID: string, formData return { success: false, error: 'Invalid file' }; } - const dbClient = await getDbClient(); - // Update the location with the attachment await dbClient.collection("lokacije") .updateOne( { _id: locationID }, - { $set: { utilBillsProofOfPaymentAttachment: attachment } } + { $set: { + utilBillsProofOfPaymentAttachment: attachment, + utilBillsProofOfPaymentUploadedAt: new Date() + } } ); return { success: true }; diff --git a/app/lib/actions/monthActions.ts b/app/lib/actions/monthActions.ts index 2fcde2d..d33d929 100644 --- a/app/lib/actions/monthActions.ts +++ b/app/lib/actions/monthActions.ts @@ -41,6 +41,7 @@ export const addMonth = withUser(async (user:AuthenticatedUser, { year, month }: ...prevLocation, // clear properties specific to the month seenByTenant: undefined, + utilBillsProofOfPaymentUploadedAt: undefined, utilBillsProofOfPaymentAttachment: undefined, // assign a new ID _id: (new ObjectId()).toHexString(), diff --git a/app/lib/db-types.ts b/app/lib/db-types.ts index 7d8bebb..db92e21 100644 --- a/app/lib/db-types.ts +++ b/app/lib/db-types.ts @@ -71,6 +71,8 @@ export interface BillingLocation { seenByTenant?: boolean | null; /** (optional) utility bills proof of payment attachment */ utilBillsProofOfPaymentAttachment?: BillAttachment|null; + /** (optional) date when utility bills proof of payment was uploaded */ + utilBillsProofOfPaymentUploadedAt?: Date|null; }; export enum BilledTo { diff --git a/app/ui/BillEditForm.tsx b/app/ui/BillEditForm.tsx index 2c06236..f135be0 100644 --- a/app/ui/BillEditForm.tsx +++ b/app/ui/BillEditForm.tsx @@ -10,6 +10,7 @@ import { formatYearMonth } from "../lib/format"; import { decodeFromImage, DecodeResult, findDecodePdf417 } from "../lib/pdf/barcodeDecoder"; import { useLocale, useTranslations } from "next-intl"; import { Pdf417Barcode } from "./Pdf417Barcode"; +import { InfoBox } from "./InfoBox"; // Next.js does not encode an utf-8 file name correctly when sending a form with a file attachment // This is a workaround for that @@ -67,7 +68,7 @@ export const BillEditForm: FC = ({ location, bill }) => { }, [bill?.barcodeImage, hub3aText]); - const billedTo_handleChange = (event: React.ChangeEvent) => { + const billedTo_handleChange = (event: React.ChangeEvent) => { setBilledToValue(event.target.value as BilledTo); } @@ -227,33 +228,14 @@ export const BillEditForm: FC = ({ location, bill }) => { ))} -
-
- {t("billed-to-label")} - - -
-
+
+ {t("billed-to-legend")} + + {t("billed-to-info")} +
{/* Show toggle only when adding a new bill (not editing) */} {!bill && ( diff --git a/app/ui/LocationCard.tsx b/app/ui/LocationCard.tsx index 52c542b..238a4ff 100644 --- a/app/ui/LocationCard.tsx +++ b/app/ui/LocationCard.tsx @@ -1,6 +1,6 @@ 'use client'; -import { CheckCircleIcon, Cog8ToothIcon, PlusCircleIcon, ShareIcon, BanknotesIcon, DocumentIcon, EnvelopeIcon, LinkIcon, EyeIcon } from "@heroicons/react/24/outline"; +import { CheckCircleIcon, Cog8ToothIcon, PlusCircleIcon, ShareIcon, BanknotesIcon, EyeIcon, TicketIcon } from "@heroicons/react/24/outline"; import { FC } from "react"; import { BillBadge } from "./BillBadge"; import { BillingLocation } from "../lib/db-types"; @@ -23,7 +23,7 @@ export const LocationCard: FC = ({ location, currency }) => { bills, seenByTenant, // NOTE: only the fileName is projected from the DB to reduce data transfer - utilBillsProofOfPaymentAttachment + utilBillsProofOfPaymentUploadedAt } = location; const t = useTranslations("home-page.location-card"); @@ -58,7 +58,7 @@ export const LocationCard: FC = ({ location, currency }) => { - {monthlyExpense > 0 || seenByTenant || utilBillsProofOfPaymentAttachment ? + {monthlyExpense > 0 || seenByTenant || utilBillsProofOfPaymentUploadedAt ?
{t("monthly-statement-legend")} @@ -78,13 +78,13 @@ export const LocationCard: FC = ({ location, currency }) => { )} - {utilBillsProofOfPaymentAttachment && ( + {utilBillsProofOfPaymentUploadedAt && ( - + {t("download-proof-of-payment-label")} diff --git a/app/ui/LocationEditForm.tsx b/app/ui/LocationEditForm.tsx index f0355ce..9d21193 100644 --- a/app/ui/LocationEditForm.tsx +++ b/app/ui/LocationEditForm.tsx @@ -81,7 +81,6 @@ export const LocationEditForm: FC = ({ location, yearMont
{t("tenant-2d-code-legend")} - {t("tenant-2d-code-info")}
diff --git a/app/ui/Pdf417Barcode.tsx b/app/ui/Pdf417Barcode.tsx index fa24a72..2a4f769 100644 --- a/app/ui/Pdf417Barcode.tsx +++ b/app/ui/Pdf417Barcode.tsx @@ -3,7 +3,6 @@ import { useState, useEffect, FC } from 'react'; import { generateBarcode } from '../lib/pdf/pdf417'; import { renderBarcode } from '../lib/pdf/renderBarcode'; -import { EncodePayment, PaymentParams } from 'hub-3a-payment-encoder'; export const Pdf417Barcode:FC<{hub3aText:string, className?: string}> = ({hub3aText: hub3a_text, className}) => { const [bitmapData, setBitmapData] = useState(undefined); diff --git a/app/ui/PrintPreview.tsx b/app/ui/PrintPreview.tsx index 5d6c463..7f1d0fa 100644 --- a/app/ui/PrintPreview.tsx +++ b/app/ui/PrintPreview.tsx @@ -37,13 +37,6 @@ export const PrintPreview: React.FC = ({ data, year, month, t print-color-adjust: exact !important; } - .print-barcode-img { - width: 69.6mm !important; - max-width: 69.6mm !important; - height: auto !important; - max-height: 85px !important; - } - .print-table { page-break-inside: avoid; } @@ -79,10 +72,6 @@ export const PrintPreview: React.FC = ({ data, year, month, t .print-table thead tr { background: #f5f5f5 !important; } - - .print-table td img { - margin: 5em auto; - } } `} @@ -144,15 +133,14 @@ export const PrintPreview: React.FC = ({ data, year, month, t
{ item.hub3aText ? - + : ( // LEGACY SUPPORT ... untill all bills have been migrated item.barcodeImage ? {`Barcode : null ) } diff --git a/app/ui/ViewBillCard.tsx b/app/ui/ViewBillCard.tsx index 905ef35..de9d9f0 100644 --- a/app/ui/ViewBillCard.tsx +++ b/app/ui/ViewBillCard.tsx @@ -61,7 +61,7 @@ export const ViewBillCard:FC = ({ location, bill }) => { { hub3aText ?
-