'use client' import { useState } from 'react' import { useRouter } from 'next/navigation' import { useLocale, useTranslations } from 'next-intl' import { getErrorMessage, type ErrorLocale } from '@/lib/errors/get-error-message' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { useToast } from '@/components/ui/use-toast' import { VTD_CLASS, VTH_CLASS } from '@/components/ui/dry-table' import { cn, formatCurrency } from '@/lib/utils' import type { WebshopOrder } from '@/types' interface CreateInvoiceFromOrderDialogProps { open: boolean onOpenChange: (open: boolean) => void order: WebshopOrder onCreated: () => void } /** * Order -> DRAFT kundfaktura (confirm up front, convention 10): the dialog * states exactly what will happen, the user confirms, and lands in the draft * to review before sending. The customer is matched by e-mail or created from * the order's billing snapshot server-side; the scraped orgnr is shown here * for the user to eyeball since it never auto-lands on legal invoice fields. */ export default function CreateInvoiceFromOrderDialog({ open, onOpenChange, order, onCreated, }: CreateInvoiceFromOrderDialogProps) { const t = useTranslations('webshop_orders') const locale = useLocale() as ErrorLocale const router = useRouter() const { toast } = useToast() const [submitting, setSubmitting] = useState(false) const customerLabel = order.customer_company || order.customer_name || t('invoice_no_customer') async function handleCreate() { setSubmitting(true) try { const res = await fetch(`/api/webshop-orders/${order.id}/create-invoice`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}), }) const json = (await res.json()) as { invoice_id?: string } if (!res.ok || !json.invoice_id) { toast({ title: t('invoice_create_failed'), description: getErrorMessage(json, { statusCode: res.status, locale }), variant: 'destructive', }) return } toast({ title: t('invoice_created') }) onCreated() router.push(`/invoices/${json.invoice_id}`) } catch { toast({ title: t('invoice_create_failed'), variant: 'destructive' }) } finally { setSubmitting(false) } } return ( {/* data-ph-mask: order number and customer name are user data */} {t('invoice_title', { number: order.order_number })} {t('invoice_description', { customer: customerLabel })}
{customerLabel}
{order.customer_email && (
{order.customer_email}
)} {order.customer_orgnr && (
{t('invoice_orgnr_hint', { orgnr: order.customer_orgnr })}
)}
{order.line_items.length > 0 && ( {order.line_items.map((item, index) => ( ))}
{t('invoice_col_item')} {t('invoice_col_amount')}
{item.quantity} × {item.name} {formatCurrency(item.total + item.total_tax, order.currency)}
)}
{t('invoice_total')} {formatCurrency(order.total, order.currency)}
) }