feat: editable billing text on invoices
- Added billing_text column to invoices table (VARCHAR 500) - Prisma migration: 20260323_add_billing_text - Form field on invoice create page with placeholder - PDF uses billing_text, falls back to default translation - Stored on create and editable on draft invoices Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,7 @@ interface InvoiceForm {
|
||||
payment_method: string
|
||||
constant_symbol: string
|
||||
issued_by: string
|
||||
billing_text: string
|
||||
notes: string
|
||||
bank_account_id: number | string
|
||||
bank_name: string
|
||||
@@ -271,6 +272,7 @@ export default function InvoiceDetail() {
|
||||
payment_method: 'Příkazem',
|
||||
constant_symbol: '0308',
|
||||
issued_by: user?.fullName || '',
|
||||
billing_text: '',
|
||||
notes: '',
|
||||
bank_account_id: '',
|
||||
bank_name: '',
|
||||
@@ -855,6 +857,16 @@ export default function InvoiceDetail() {
|
||||
</FormField>
|
||||
</div>
|
||||
|
||||
<FormField label="Text fakturace (na PDF)">
|
||||
<input
|
||||
type="text"
|
||||
value={form.billing_text}
|
||||
onChange={(e) => setForm(prev => ({ ...prev, billing_text: e.target.value }))}
|
||||
className="admin-form-input"
|
||||
placeholder="Fakturujeme Vám za: (ponechte prázdné pro výchozí)"
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<div className="admin-form-row">
|
||||
<FormField label="Datum vystavení" error={errors.issue_date} required>
|
||||
<AdminDatePicker mode="date" value={form.issue_date} onChange={(val: string) => { setForm(prev => ({ ...prev, issue_date: val })); setErrors(prev => ({ ...prev, issue_date: '' })) }} />
|
||||
|
||||
@@ -880,7 +880,7 @@ ${indentCSS}
|
||||
</div>
|
||||
|
||||
<!-- Polozky -->
|
||||
<div class="billing-label">${escapeHtml(t.billing)}</div>
|
||||
<div class="billing-label">${escapeHtml(invoice.billing_text || t.billing)}</div>
|
||||
<table class="items">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@@ -27,6 +27,7 @@ export const CreateInvoiceSchema = z.object({
|
||||
due_date: z.string().nullish(),
|
||||
tax_date: z.string().nullish(),
|
||||
issued_by: z.string().nullish(),
|
||||
billing_text: z.string().nullish(),
|
||||
notes: z.string().nullish(),
|
||||
internal_notes: z.string().nullish(),
|
||||
items: z.array(InvoiceItemSchema).optional(),
|
||||
|
||||
@@ -251,6 +251,7 @@ export async function createInvoice(body: Record<string, any>) {
|
||||
due_date: body.due_date ? new Date(String(body.due_date)) : null,
|
||||
tax_date: body.tax_date ? new Date(String(body.tax_date)) : null,
|
||||
issued_by: body.issued_by ? String(body.issued_by) : null,
|
||||
billing_text: body.billing_text ? String(body.billing_text) : null,
|
||||
notes: body.notes ? String(body.notes) : null,
|
||||
internal_notes: body.internal_notes ? String(body.internal_notes) : null,
|
||||
},
|
||||
@@ -293,7 +294,7 @@ export async function updateInvoice(id: number, body: Record<string, any>) {
|
||||
// Only allow full editing in 'issued' state
|
||||
const isDraft = currentStatus === 'issued';
|
||||
if (isDraft) {
|
||||
const strFields = ['currency', 'payment_method', 'constant_symbol', 'bank_name', 'bank_swift', 'bank_iban', 'bank_account', 'issued_by'];
|
||||
const strFields = ['currency', 'payment_method', 'constant_symbol', 'bank_name', 'bank_swift', 'bank_iban', 'bank_account', 'issued_by', 'billing_text'];
|
||||
for (const f of strFields) {
|
||||
if (body[f] !== undefined) data[f] = body[f] ? String(body[f]) : null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user