@voyantjs/finance-react 0.52.1 → 0.52.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -38,6 +38,58 @@ export declare function useInvoiceMutation(): {
38
38
  updatedAt: string;
39
39
  invoiceType?: "invoice" | "proforma" | "credit_note" | undefined;
40
40
  }, Error, CreateInvoiceInput, unknown>;
41
+ createFromBooking: import("@tanstack/react-query").UseMutationResult<{
42
+ [x: string]: unknown;
43
+ id: string;
44
+ invoiceNumber: string;
45
+ bookingId: string;
46
+ personId: string | null;
47
+ organizationId: string | null;
48
+ status: "void" | "draft" | "sent" | "partially_paid" | "paid" | "overdue";
49
+ currency: string;
50
+ subtotalCents: number;
51
+ taxCents: number;
52
+ totalCents: number;
53
+ paidCents: number;
54
+ balanceDueCents: number;
55
+ issueDate: string;
56
+ dueDate: string;
57
+ notes: string | null;
58
+ createdAt: string;
59
+ updatedAt: string;
60
+ invoiceType?: "invoice" | "proforma" | "credit_note" | undefined;
61
+ }, Error, CreateInvoiceFromBookingInput, unknown>;
62
+ convertToInvoice: import("@tanstack/react-query").UseMutationResult<{
63
+ [x: string]: unknown;
64
+ id: string;
65
+ invoiceNumber: string;
66
+ bookingId: string;
67
+ personId: string | null;
68
+ organizationId: string | null;
69
+ status: "void" | "draft" | "sent" | "partially_paid" | "paid" | "overdue";
70
+ currency: string;
71
+ subtotalCents: number;
72
+ taxCents: number;
73
+ totalCents: number;
74
+ paidCents: number;
75
+ balanceDueCents: number;
76
+ issueDate: string;
77
+ dueDate: string;
78
+ notes: string | null;
79
+ createdAt: string;
80
+ updatedAt: string;
81
+ invoiceType?: "invoice" | "proforma" | "credit_note" | undefined;
82
+ }, Error, {
83
+ id: string;
84
+ input?: ConvertProformaInput;
85
+ }, unknown>;
86
+ render: import("@tanstack/react-query").UseMutationResult<{
87
+ [x: string]: unknown;
88
+ id: string;
89
+ }, Error, {
90
+ id: string;
91
+ input?: RenderInvoiceInput;
92
+ }, unknown>;
41
93
  update: import("@tanstack/react-query").UseMutationResult<{
42
94
  [x: string]: unknown;
43
95
  id: string;
@@ -66,4 +118,24 @@ export declare function useInvoiceMutation(): {
66
118
  success: boolean;
67
119
  }, Error, string, unknown>;
68
120
  };
121
+ export interface ConvertProformaInput {
122
+ /** Optional override; server derives from the proforma number when omitted. */
123
+ invoiceNumber?: string;
124
+ issueDate?: string;
125
+ dueDate?: string;
126
+ }
127
+ export interface CreateInvoiceFromBookingInput {
128
+ bookingId: string;
129
+ invoiceNumber: string;
130
+ issueDate: string;
131
+ dueDate: string;
132
+ notes?: string | null;
133
+ /** Defaults to `invoice` on the server. Pass `proforma` for placeholders. */
134
+ invoiceType?: "invoice" | "proforma";
135
+ }
136
+ export interface RenderInvoiceInput {
137
+ format?: "pdf" | "html";
138
+ /** Optional invoice-template id; server falls back to the default. */
139
+ templateId?: string | null;
140
+ }
69
141
  //# sourceMappingURL=use-invoice-mutation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-invoice-mutation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-invoice-mutation.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,aAAa,EAA0C,MAAM,eAAe,CAAA;AAE1F,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;AAE5D,wBAAgB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAqBU,MAAM;eAAS,kBAAkB;;;;;EAoC5E"}
1
+ {"version":3,"file":"use-invoice-mutation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-invoice-mutation.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,aAAa,EAA0C,MAAM,eAAe,CAAA;AAE1F,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;AAE5D,wBAAgB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAqFU,MAAM;gBAAU,oBAAoB;;;;;;YAsBpC,MAAM;gBAAU,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;YAtFlC,MAAM;eAAS,kBAAkB;;;;;EAwG5E;AAED,MAAM,WAAW,oBAAoB;IACnC,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IACvB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B"}
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { useMutation, useQueryClient } from "@tanstack/react-query";
3
+ import { z } from "zod";
3
4
  import { fetchWithValidation } from "../client.js";
4
5
  import { useVoyantFinanceContext } from "../provider.js";
5
6
  import { financeQueryKeys } from "../query-keys.js";
@@ -40,5 +41,62 @@ export function useInvoiceMutation() {
40
41
  queryClient.removeQueries({ queryKey: financeQueryKeys.notes(id) });
41
42
  },
42
43
  });
43
- return { create, update, remove };
44
+ /**
45
+ * Create + issue an invoice (or proforma) from an existing booking. The
46
+ * server walks the booking's items, builds line items, and emits an
47
+ * `invoice.issued` event post-commit. Used by the Documents tab on the
48
+ * booking detail page to bootstrap an invoice when none exists yet.
49
+ */
50
+ const createFromBooking = useMutation({
51
+ mutationFn: async (input) => {
52
+ const { data } = await fetchWithValidation("/v1/finance/invoices/from-booking", invoiceSingleResponse, { baseUrl, fetcher }, { method: "POST", body: JSON.stringify(input) });
53
+ return data;
54
+ },
55
+ onSuccess: (data) => {
56
+ void queryClient.invalidateQueries({ queryKey: financeQueryKeys.invoices() });
57
+ queryClient.setQueryData(financeQueryKeys.invoice(data.id), { data });
58
+ },
59
+ });
60
+ /**
61
+ * Convert an issued proforma into a final invoice. Server-side this
62
+ * copies the proforma's line items + totals, marks the proforma as
63
+ * `void`, and emits `invoice.issued` with `convertedFromInvoiceId` so
64
+ * the SmartBill subscriber (and audit chain) sees the linkage.
65
+ */
66
+ const convertToInvoice = useMutation({
67
+ mutationFn: async ({ id, input }) => {
68
+ const { data } = await fetchWithValidation(`/v1/finance/invoices/${id}/convert-to-invoice`, invoiceSingleResponse, { baseUrl, fetcher }, { method: "POST", body: JSON.stringify(input ?? {}) });
69
+ return data;
70
+ },
71
+ onSuccess: (data) => {
72
+ void queryClient.invalidateQueries({ queryKey: financeQueryKeys.invoices() });
73
+ queryClient.setQueryData(financeQueryKeys.invoice(data.id), { data });
74
+ },
75
+ });
76
+ /**
77
+ * Render (or re-render) a PDF for an existing invoice. Server-side this
78
+ * inserts an `invoice_rendition` row + emits `invoice.rendered`, which a
79
+ * downstream subscriber turns into a stored PDF attachment. Use this for
80
+ * the operator's "Generate" / "Regenerate" buttons.
81
+ */
82
+ const render = useMutation({
83
+ mutationFn: async ({ id, input }) => {
84
+ const { data } = await fetchWithValidation(`/v1/finance/invoices/${id}/render`, invoiceRenditionResponse, { baseUrl, fetcher }, { method: "POST", body: JSON.stringify(input ?? { format: "pdf" }) });
85
+ return data;
86
+ },
87
+ onSuccess: (_data, variables) => {
88
+ void queryClient.invalidateQueries({
89
+ queryKey: financeQueryKeys.invoice(variables.id),
90
+ });
91
+ void queryClient.invalidateQueries({ queryKey: financeQueryKeys.invoices() });
92
+ },
93
+ });
94
+ return { create, createFromBooking, convertToInvoice, render, update, remove };
44
95
  }
96
+ // Light envelope schema for the render endpoint — the server returns
97
+ // `{ data: rendition }` where rendition is { id, invoiceId, format, ... }.
98
+ // We only assert the wrapper so the hook stays portable across renditions
99
+ // shape changes; consumers that care can narrow on the data field.
100
+ const invoiceRenditionResponse = z.object({
101
+ data: z.object({ id: z.string() }).passthrough(),
102
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/finance-react",
3
- "version": "0.52.1",
3
+ "version": "0.52.2",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,7 +41,7 @@
41
41
  "react": "^19.0.0",
42
42
  "react-dom": "^19.0.0",
43
43
  "zod": "^4.0.0",
44
- "@voyantjs/finance": "0.52.1"
44
+ "@voyantjs/finance": "0.52.2"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@tanstack/react-query": "^5.96.2",
@@ -52,12 +52,12 @@
52
52
  "typescript": "^6.0.2",
53
53
  "vitest": "^4.1.2",
54
54
  "zod": "^4.3.6",
55
- "@voyantjs/finance": "0.52.1",
56
- "@voyantjs/react": "0.52.1",
55
+ "@voyantjs/finance": "0.52.2",
56
+ "@voyantjs/react": "0.52.2",
57
57
  "@voyantjs/voyant-typescript-config": "0.1.0"
58
58
  },
59
59
  "dependencies": {
60
- "@voyantjs/react": "0.52.1"
60
+ "@voyantjs/react": "0.52.2"
61
61
  },
62
62
  "files": [
63
63
  "dist"