garage-erp/apps/dashboard/modules/purchase-orders/create-bill-from-po-button.tsx
2026-04-23 14:38:41 +03:00

82 lines
2.8 KiB
TypeScript

"use client"
import { useState } from "react"
import { FileText } from "lucide-react"
import { Button } from "@/shared/components/ui/button"
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/shared/components/ui/dialog"
import { ScrollArea } from "@/shared/components/ui/scroll-area"
import { BillForm } from "@/modules/bills/bill-form"
import { toRelation } from "@/shared/lib/utils"
import { usePurchaseOrder } from "./purchase-order-context"
import { getFullName } from "@/shared/utils/getFullName"
/**
* Maps a Purchase Order data object to a complete BillFormValues shape so that
* useResourceForm's shallow spread (`{ ...defaultValues, ...initialData }`) correctly
* pre-fills all relational and line-item fields.
*/
function mapPOToBillInitialData(po: Record<string, any>) {
return {
// Text fields
title: po.title ?? "",
notes: po.notes ?? "",
// Relation fields — must be { value, label } objects for RhfAsyncSelectField
vendor: toRelation(po.vendor_id, getFullName(po.vendor)),
department: toRelation(po.department_id, po.department.name),
job_card: toRelation(po.job_card_id, po.job_card.title ),
// Link bill back to the source PO
purchase_order: toRelation(po.id, po.order_number ?? po.title),
// Parts pre-filled from PO items
part_items: (po.parts ?? []).map((p: any) => ({
part_id: p.part_id ?? p.id,
title: p.part?.title ?? p.title ?? "",
quantity: Number(p.quantity) || 1,
rate: Number(p.rate) || 0,
description: p.description ?? "",
})),
// Services and expenses start empty (PO doesn't have them)
service_items: [],
expense_items: [],
}
}
export function CreateBillFromPOButton() {
const [open, setOpen] = useState(false)
const poContext = usePurchaseOrder()
if (!poContext) return null
const initialData = poContext.data ? mapPOToBillInitialData(poContext.data) : undefined
return (
<>
<Button variant="outline" size="sm" onClick={() => setOpen(true)}>
<FileText className="me-2 size-4" />
Create Bill
</Button>
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent className="min-w-6xl">
<DialogHeader>
<DialogTitle>Create Bill from Purchase Order</DialogTitle>
</DialogHeader>
<ScrollArea className="max-h-[75vh] px-1">
<BillForm
initialData={initialData}
onSuccess={() => setOpen(false)}
/>
</ScrollArea>
</DialogContent>
</Dialog>
</>
)
}