Merge branch 'release/2.1.0'
This commit is contained in:
@@ -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<BillingLocation>("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<BillingLocation>("lokacije")
|
||||
.updateOne(
|
||||
{ _id: locationID },
|
||||
{ $set: { utilBillsProofOfPaymentAttachment: attachment } }
|
||||
{ $set: {
|
||||
utilBillsProofOfPaymentAttachment: attachment,
|
||||
utilBillsProofOfPaymentUploadedAt: new Date()
|
||||
} }
|
||||
);
|
||||
|
||||
return { success: true };
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<BillEditFormProps> = ({ location, bill }) => {
|
||||
}, [bill?.barcodeImage, hub3aText]);
|
||||
|
||||
|
||||
const billedTo_handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const billedTo_handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
setBilledToValue(event.target.value as BilledTo);
|
||||
}
|
||||
|
||||
@@ -227,33 +228,14 @@ export const BillEditForm: FC<BillEditFormProps> = ({ location, bill }) => {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="form-control mt-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="label-text">{t("billed-to-label")}</span>
|
||||
<label className="label cursor-pointer gap-2">
|
||||
<input
|
||||
type="radio"
|
||||
name="billedTo"
|
||||
value={BilledTo.Tenant}
|
||||
className="radio radio-primary"
|
||||
checked={billedToValue === BilledTo.Tenant}
|
||||
onChange={billedTo_handleChange}
|
||||
/>
|
||||
<span className="label-text">{t("billed-to-tenant-option")}</span>
|
||||
</label>
|
||||
<label className="label cursor-pointer gap-2">
|
||||
<input
|
||||
type="radio"
|
||||
name="billedTo"
|
||||
value={BilledTo.Landlord}
|
||||
className="radio radio-primary"
|
||||
checked={billedToValue === BilledTo.Landlord}
|
||||
onChange={billedTo_handleChange}
|
||||
/>
|
||||
<span className="label-text">{t("billed-to-landlord-option")}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<fieldset className="fieldset bg-base-200 border-base-300 rounded-box w-xs border p-4 pb-2 mt-4">
|
||||
<legend className="fieldset-legend font-semibold uppercase">{t("billed-to-legend")}</legend>
|
||||
<select className="select select-bordered w-full" name="billedTo" defaultValue={billedToValue} onChange={billedTo_handleChange}>
|
||||
<option value={BilledTo.Tenant}>{t("billed-to-tenant-option")}</option>
|
||||
<option value={BilledTo.Landlord}>{t("billed-to-landlord-option")}</option>
|
||||
</select>
|
||||
<InfoBox className="m-0 mt-3 mb-1 p-0">{t("billed-to-info")}</InfoBox>
|
||||
</fieldset>
|
||||
|
||||
{/* Show toggle only when adding a new bill (not editing) */}
|
||||
{!bill && (
|
||||
|
||||
@@ -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<LocationCardProps> = ({ 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<LocationCardProps> = ({ location, currency }) => {
|
||||
</div>
|
||||
|
||||
|
||||
{monthlyExpense > 0 || seenByTenant || utilBillsProofOfPaymentAttachment ?
|
||||
{monthlyExpense > 0 || seenByTenant || utilBillsProofOfPaymentUploadedAt ?
|
||||
|
||||
<fieldset className="card card-compact card-bordered border-1 border-neutral p-3 mt-2 mr-[3.5rem]">
|
||||
<legend className="fieldset-legend px-2 text-sm font-semibold uppercase">{t("monthly-statement-legend")}</legend>
|
||||
@@ -78,13 +78,13 @@ export const LocationCard: FC<LocationCardProps> = ({ location, currency }) => {
|
||||
<CheckCircleIcon className="h-5 w-5 text-success" />
|
||||
</div>
|
||||
)}
|
||||
{utilBillsProofOfPaymentAttachment && (
|
||||
{utilBillsProofOfPaymentUploadedAt && (
|
||||
<Link
|
||||
href={`/share/proof-of-payment/${_id}/`}
|
||||
target="_blank"
|
||||
className="flex items-center gap-2 mt-2 ml-4"
|
||||
>
|
||||
<LinkIcon className="h-5 w-5" />
|
||||
<TicketIcon className="h-5 w-5" />
|
||||
<span className="text-sm">{t("download-proof-of-payment-label")}</span>
|
||||
<CheckCircleIcon className="h-5 w-5 text-success" />
|
||||
</Link>
|
||||
|
||||
@@ -81,7 +81,6 @@ export const LocationEditForm: FC<LocationEditFormProps> = ({ location, yearMont
|
||||
</fieldset>
|
||||
<fieldset className="fieldset bg-base-200 border-base-300 rounded-box w-xs border p-4 pb-2 mt-4">
|
||||
<legend className="fieldset-legend font-semibold uppercase">{t("tenant-2d-code-legend")}</legend>
|
||||
|
||||
<InfoBox className="p-1 mb-1">{t("tenant-2d-code-info")}</InfoBox>
|
||||
|
||||
<fieldset className="fieldset">
|
||||
|
||||
@@ -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<string | undefined>(undefined);
|
||||
|
||||
@@ -37,13 +37,6 @@ export const PrintPreview: React.FC<PrintPreviewProps> = ({ 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<PrintPreviewProps> = ({ data, year, month, t
|
||||
.print-table thead tr {
|
||||
background: #f5f5f5 !important;
|
||||
}
|
||||
|
||||
.print-table td img {
|
||||
margin: 5em auto;
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
|
||||
@@ -144,15 +133,14 @@ export const PrintPreview: React.FC<PrintPreviewProps> = ({ data, year, month, t
|
||||
<div className="flex justify-center items-center">
|
||||
{
|
||||
item.hub3aText ?
|
||||
<Pdf417Barcode hub3aText={item.hub3aText} />
|
||||
<Pdf417Barcode hub3aText={item.hub3aText} className="max-h-28 w-auto max-w-[270px] print:m-[5em_auto] print:h-[auto] print:max-h-[85px] print:w-[69.6mm] print:max-w-[69.6mm]" />
|
||||
: (
|
||||
// LEGACY SUPPORT ... untill all bills have been migrated
|
||||
item.barcodeImage ?
|
||||
<img
|
||||
src={item.barcodeImage.startsWith('data:') ? item.barcodeImage : `data:image/png;base64,${item.barcodeImage}`}
|
||||
alt={`Barcode for ${item.billName}`}
|
||||
className="max-h-28 w-auto border border-gray-300 rounded print-barcode-img"
|
||||
style={{ maxWidth: '270px' }}
|
||||
className="max-h-28 w-auto max-w-[270px] print:m-[5em_auto] print:h-[auto] print:max-h-[85px] print:w-[69.6mm] print:max-w-[69.6mm]"
|
||||
/> : null
|
||||
)
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ export const ViewBillCard:FC<ViewBillCardProps> = ({ location, bill }) => {
|
||||
{
|
||||
hub3aText ?
|
||||
<div className="form-control p-1">
|
||||
<label className="cursor-pointer label p-2 grow bg-white justify-center">
|
||||
<label className="label p-2 grow bg-white border border-gray-300 rounded-box justify-center">
|
||||
<Pdf417Barcode hub3aText={hub3aText} />
|
||||
</label>
|
||||
<p className="text-xs my-1">{t.rich('barcode-disclaimer', { br: () => <br /> })}</p>
|
||||
@@ -70,7 +70,7 @@ export const ViewBillCard:FC<ViewBillCardProps> = ({ location, bill }) => {
|
||||
// LEGACY SUPPORT ... untill all bills have been migrated
|
||||
barcodeImage ?
|
||||
<div className="p-1">
|
||||
<label className="label p-2 grow bg-white">
|
||||
<label className="label p-2 grow bg-white border border-gray-300 rounded-box justify-center">
|
||||
<img src={barcodeImage} className="grow sm:max-w-[350px]" alt="2D Barcode" />
|
||||
</label>
|
||||
<p className="text-xs my-1">{t.rich('barcode-disclaimer', { br: () => <br /> })}</p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { FC, useState } from "react";
|
||||
import { FC, useEffect, useMemo, useState } from "react";
|
||||
import { BillAttachment, BilledTo, BillingLocation, UserSettings } from "../lib/db-types";
|
||||
import { formatYearMonth } from "../lib/format";
|
||||
import { formatCurrency } from "../lib/formatStrings";
|
||||
@@ -29,13 +29,15 @@ export const ViewLocationCard:FC<ViewLocationCardProps> = ({location, userSettin
|
||||
tenantTown,
|
||||
generateTenantCode,
|
||||
// NOTE: only the fileName is projected from the DB to reduce data transfer
|
||||
utilBillsProofOfPaymentAttachment
|
||||
utilBillsProofOfPaymentAttachment,
|
||||
utilBillsProofOfPaymentUploadedAt,
|
||||
} = location;
|
||||
|
||||
const t = useTranslations("home-page.location-card");
|
||||
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
const [uploadError, setUploadError] = useState<string | null>(null);
|
||||
const [attachmentUploadedAt, setAttachmentUploadedAt ] = useState<Date | null>(utilBillsProofOfPaymentUploadedAt ?? null);
|
||||
const [attachmentFilename, setAttachmentFilename] = useState(utilBillsProofOfPaymentAttachment?.fileName);
|
||||
|
||||
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -60,6 +62,7 @@ export const ViewLocationCard:FC<ViewLocationCardProps> = ({location, userSettin
|
||||
|
||||
if (result.success) {
|
||||
setAttachmentFilename(file.name);
|
||||
setAttachmentUploadedAt(new Date());
|
||||
} else {
|
||||
setUploadError(result.error || 'Upload failed');
|
||||
}
|
||||
@@ -74,27 +77,40 @@ export const ViewLocationCard:FC<ViewLocationCardProps> = ({location, userSettin
|
||||
// sum all the billAmounts (only for bills billed to tenant)
|
||||
const monthlyExpense = bills.reduce((acc, bill) => (bill.paid && (bill.billedTo ?? BilledTo.Tenant) === BilledTo.Tenant) ? acc + (bill.payedAmount ?? 0) : acc, 0);
|
||||
|
||||
const locationNameTrimmed_max20 = locationName.trimEnd().trimEnd().substring(0,19);
|
||||
const { hub3aText, paymentParams } = useMemo(() => {
|
||||
|
||||
const paymentParams:PaymentParams = {
|
||||
Iznos: (monthlyExpense/100).toFixed(2).replace(".",","),
|
||||
ImePlatitelja: tenantName ?? "",
|
||||
AdresaPlatitelja: tenantStreet ?? "",
|
||||
SjedistePlatitelja: tenantTown ?? "",
|
||||
Primatelj: userSettings?.ownerName ?? "",
|
||||
AdresaPrimatelja: userSettings?.ownerStreet ?? "",
|
||||
SjedistePrimatelja: userSettings?.ownerTown ?? "",
|
||||
IBAN: userSettings?.ownerIBAN ?? "",
|
||||
ModelPlacanja: "HR00",
|
||||
PozivNaBroj: formatYearMonth(yearMonth),
|
||||
SifraNamjene: "",
|
||||
OpisPlacanja: `Režije-${locationNameTrimmed_max20}-${formatYearMonth(yearMonth)}`, // max length 35 = "Režije-" (7) + locationName (20) + "-" (1) + "YYYY-MM" (7)
|
||||
};
|
||||
if(!userSettings?.show2dCodeInMonthlyStatement || !generateTenantCode) {
|
||||
return {
|
||||
hub3aText: "",
|
||||
paymentParams: {} as PaymentParams
|
||||
};
|
||||
}
|
||||
|
||||
const hub3a_text = EncodePayment(paymentParams);
|
||||
const locationNameTrimmed_max20 = locationName.trimEnd().trimEnd().substring(0,19);
|
||||
|
||||
const paymentParams:PaymentParams = {
|
||||
Iznos: (monthlyExpense/100).toFixed(2).replace(".",","),
|
||||
ImePlatitelja: tenantName ?? "",
|
||||
AdresaPlatitelja: tenantStreet ?? "",
|
||||
SjedistePlatitelja: tenantTown ?? "",
|
||||
Primatelj: userSettings?.ownerName ?? "",
|
||||
AdresaPrimatelja: userSettings?.ownerStreet ?? "",
|
||||
SjedistePrimatelja: userSettings?.ownerTown ?? "",
|
||||
IBAN: userSettings?.ownerIBAN ?? "",
|
||||
ModelPlacanja: "HR00",
|
||||
PozivNaBroj: formatYearMonth(yearMonth),
|
||||
SifraNamjene: "",
|
||||
OpisPlacanja: `Režije-${locationNameTrimmed_max20}-${formatYearMonth(yearMonth)}`, // max length 35 = "Režije-" (7) + locationName (20) + "-" (1) + "YYYY-MM" (7)
|
||||
};
|
||||
|
||||
return({
|
||||
hub3aText: EncodePayment(paymentParams),
|
||||
paymentParams
|
||||
});
|
||||
}, [userSettings?.show2dCodeInMonthlyStatement, generateTenantCode, locationName, tenantName, tenantStreet, tenantTown, userSettings, monthlyExpense, yearMonth]);
|
||||
|
||||
return(
|
||||
<div data-key={_id } className="card card-compact card-bordered max-w-[30em] min-w-[350px] bg-base-100 border-1 border-neutral my-1">
|
||||
<div data-key={_id } className="card card-compact card-bordered max-w-[30em] min-w-[330px] bg-base-100 border-1 border-neutral my-1">
|
||||
<div className="card-body">
|
||||
<h2 className="card-title mr-[2em] text-[1.3rem]">{formatYearMonth(yearMonth)} {locationName}</h2>
|
||||
<div className="card-actions mt-[1em] mb-[1em]">
|
||||
@@ -118,31 +134,38 @@ export const ViewLocationCard:FC<ViewLocationCardProps> = ({location, userSettin
|
||||
<li><strong>{t("payment-recipient-label")}</strong> <pre className="inline pl-1">{paymentParams.Primatelj}</pre></li>
|
||||
<li><strong>{t("payment-recipient-address-label")}</strong><pre className="inline pl-1">{paymentParams.AdresaPrimatelja}</pre></li>
|
||||
<li><strong>{t("payment-recipient-city-label")}</strong><pre className="inline pl-1">{paymentParams.SjedistePrimatelja}</pre></li>
|
||||
<li><strong>{t("payment-amount-label")}</strong> <pre className="inline pl-1">{paymentParams.Iznos}</pre></li>
|
||||
<li><strong>{t("payment-amount-label")}</strong> <pre className="inline pl-1">{paymentParams.Iznos} { userSettings?.currency }</pre></li>
|
||||
<li><strong>{t("payment-description-label")}</strong><pre className="inline pl-1">{paymentParams.OpisPlacanja}</pre></li>
|
||||
<li><strong>{t("payment-model-label")}</strong><pre className="inline pl-1">{paymentParams.ModelPlacanja}</pre></li>
|
||||
<li><strong>{t("payment-reference-label")}</strong><pre className="inline pl-1">{paymentParams.PozivNaBroj}</pre></li>
|
||||
<li><strong>{t("payment-purpose-code-label")}</strong><pre className="inline pl-1">{paymentParams.SifraNamjene}</pre></li>
|
||||
</ul>
|
||||
<Pdf417Barcode hub3aText={hub3a_text} />
|
||||
<label className="label p-2 grow bg-white border border-gray-300 rounded-box justify-center">
|
||||
<Pdf417Barcode hub3aText={hub3aText} />
|
||||
</label>
|
||||
</>
|
||||
: null
|
||||
}
|
||||
<fieldset className="fieldset bg-base-200 border-base-300 rounded-box w-xs border p-4 pb-2 pt-0 mt-2">
|
||||
<legend className="fieldset-legend font-semibold uppercase">{t("upload-proof-of-payment-legend")}</legend>
|
||||
|
||||
{attachmentFilename ? (
|
||||
<div className="mt-3 ml-[-.5rem]">
|
||||
<Link
|
||||
href={`/share/proof-of-payment/${_id}/`}
|
||||
target="_blank"
|
||||
className='text-center w-full max-w-[20rem] text-nowrap truncate inline-block'
|
||||
>
|
||||
<DocumentIcon className="h-[1em] w-[1em] text-2xl inline-block mr-1" />
|
||||
{decodeURIComponent(attachmentFilename)}
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
{
|
||||
// IF proof of payment was uploaded
|
||||
attachmentUploadedAt ? (
|
||||
// IF file name is available, show link to download
|
||||
// ELSE it's not available that means that the uploaded file was purged by housekeeping
|
||||
// -> don't show anything
|
||||
attachmentFilename ? (
|
||||
<div className="mt-3 ml-[-.5rem]">
|
||||
<Link
|
||||
href={`/share/proof-of-payment/${_id}/`}
|
||||
target="_blank"
|
||||
className='text-center w-full max-w-[20rem] text-nowrap truncate inline-block'
|
||||
>
|
||||
<DocumentIcon className="h-[1em] w-[1em] text-2xl inline-block mr-1" />
|
||||
{decodeURIComponent(attachmentFilename)}
|
||||
</Link>
|
||||
</div>
|
||||
) : null
|
||||
) : /* ELSE show upload input */ (
|
||||
<div className="form-control w-full">
|
||||
<label className="label">
|
||||
<span className="label-text">{t("upload-proof-of-payment-label")}</span>
|
||||
|
||||
@@ -124,9 +124,10 @@
|
||||
},
|
||||
"attachment": "Attachment",
|
||||
"back-button": "Back",
|
||||
"billed-to-label": "Billed to",
|
||||
"billed-to-tenant-option": "tenant",
|
||||
"billed-to-landlord-option": "landlord"
|
||||
"billed-to-legend": "Who bears the cost?",
|
||||
"billed-to-tenant-option": "the tenant bears this cost",
|
||||
"billed-to-landlord-option": "the landlord bears this cost",
|
||||
"billed-to-info": "This option is intended for cases where part of the utility costs are not charged to the tenant. If 'the landlord bears this cost' is selected, this bill will not be included in the monthly statement shown to the tenant."
|
||||
},
|
||||
"location-delete-form": {
|
||||
"text": "Please confirm deletion of realestate \"<strong>{name}</strong>\".",
|
||||
|
||||
@@ -123,9 +123,10 @@
|
||||
},
|
||||
"attachment": "Privitak",
|
||||
"back-button": "Nazad",
|
||||
"billed-to-label": "Račun plaća",
|
||||
"billed-to-tenant-option": "podstanar",
|
||||
"billed-to-landlord-option": "vlasnik"
|
||||
"billed-to-legend": "Tko snosi trošak?",
|
||||
"billed-to-tenant-option": "ovaj trošak snosi podstanar",
|
||||
"billed-to-landlord-option": "ovaj trošak snosi vlasnik",
|
||||
"billed-to-info": "Ova opcija je predviđena za slučaj kada se dio režija ne naplaćuje od podstanara. Ako je odabrano 'trošak snosi vlasnik', ovaj račun neće biti uključen u mjesečni obračun koji se prikazuje podstanaru."
|
||||
},
|
||||
"location-delete-form": {
|
||||
"text": "Molim potvrdi brisanje nekretnine \"<strong>{name}</strong>\".",
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "evidencija-rezija",
|
||||
"version": "2.0.1",
|
||||
"version": "2.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "2.0.1",
|
||||
"version": "2.1.0",
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
|
||||
@@ -58,5 +58,5 @@
|
||||
"engines": {
|
||||
"node": ">=18.17.0"
|
||||
},
|
||||
"version": "2.0.1"
|
||||
"version": "2.1.0"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user