- feat: manual VAT override in order confirmation modal
- feat: order confirmation PDF respects user-selected applyVat toggle

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-04-23 18:17:20 +02:00
parent 07cb428287
commit 5a28f75303
4 changed files with 44 additions and 6 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "app-ts",
"version": "1.5.2",
"version": "1.5.3",
"description": "",
"main": "dist/server.js",
"scripts": {

View File

@@ -13,10 +13,15 @@ interface ConfirmationItem {
interface OrderConfirmationModalProps {
isOpen: boolean;
onClose: () => void;
onGenerate: (lang: string, items?: ConfirmationItem[]) => Promise<void>;
onGenerate: (
lang: string,
applyVat: boolean,
items?: ConfirmationItem[],
) => Promise<void>;
initialItems: ConfirmationItem[];
orderNumber: string;
defaultVatRate: number;
applyVat: boolean;
}
export default function OrderConfirmationModal({
@@ -26,16 +31,18 @@ export default function OrderConfirmationModal({
initialItems,
orderNumber,
defaultVatRate,
applyVat,
}: OrderConfirmationModalProps) {
const [step, setStep] = useState<"choose" | "edit">("choose");
const [lang, setLang] = useState<string>("cs");
const [applyVatState, setApplyVatState] = useState(applyVat);
const [items, setItems] = useState<ConfirmationItem[]>(initialItems);
const [loading, setLoading] = useState(false);
const handleUseExisting = async () => {
setLoading(true);
try {
await onGenerate(lang, undefined);
await onGenerate(lang, applyVatState, undefined);
} finally {
setLoading(false);
setStep("choose");
@@ -46,7 +53,7 @@ export default function OrderConfirmationModal({
const handleEditGenerate = async () => {
setLoading(true);
try {
await onGenerate(lang, items);
await onGenerate(lang, applyVatState, items);
} finally {
setLoading(false);
setStep("choose");
@@ -144,6 +151,34 @@ export default function OrderConfirmationModal({
</div>
</div>
<div className="admin-form-group">
<label className="admin-form-label">DPH</label>
<div className="flex-row gap-2">
<button
type="button"
onClick={() => setApplyVatState(true)}
className={
applyVatState
? "admin-btn admin-btn-primary admin-btn-sm"
: "admin-btn admin-btn-secondary admin-btn-sm"
}
>
S DPH
</button>
<button
type="button"
onClick={() => setApplyVatState(false)}
className={
!applyVatState
? "admin-btn admin-btn-primary admin-btn-sm"
: "admin-btn admin-btn-secondary admin-btn-sm"
}
>
Bez DPH
</button>
</div>
</div>
<div className="admin-form-group">
<label className="admin-form-label">Obsah potvrzení</label>
<p

View File

@@ -231,6 +231,7 @@ export default function OrderDetail() {
const handleGenerateConfirmation = async (
lang: string,
applyVat: boolean,
customItems?: Array<{
description: string;
quantity: number;
@@ -247,7 +248,7 @@ export default function OrderDetail() {
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ lang, items: customItems }),
body: JSON.stringify({ lang, applyVat, items: customItems }),
},
);
if (!response.ok) {
@@ -846,6 +847,7 @@ export default function OrderDetail() {
}))}
orderNumber={order.order_number}
defaultVatRate={Number(order.vat_rate) || 21}
applyVat={!!order.apply_vat}
/>
)}
</div>

View File

@@ -250,7 +250,8 @@ export default async function ordersPdfRoutes(
}
const currency = order.currency || "CZK";
const applyVat = !!order.apply_vat;
const applyVat =
body.applyVat !== undefined ? !!body.applyVat : !!order.apply_vat;
const orderVatRate = Number(order.vat_rate) || 21;
// Use custom items from body if provided, otherwise order items