storno-cli 1.0.5
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.
- package/LICENSE +53 -0
- package/README.md +257 -0
- package/TOOLS.md +3309 -0
- package/dist/client.d.ts +42 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +162 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +30 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +172 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/accounting-export.d.ts +14 -0
- package/dist/tools/accounting-export.d.ts.map +1 -0
- package/dist/tools/accounting-export.js +97 -0
- package/dist/tools/accounting-export.js.map +1 -0
- package/dist/tools/admin.d.ts +8 -0
- package/dist/tools/admin.d.ts.map +1 -0
- package/dist/tools/admin.js +98 -0
- package/dist/tools/admin.js.map +1 -0
- package/dist/tools/anaf.d.ts +8 -0
- package/dist/tools/anaf.d.ts.map +1 -0
- package/dist/tools/anaf.js +115 -0
- package/dist/tools/anaf.js.map +1 -0
- package/dist/tools/api-keys.d.ts +8 -0
- package/dist/tools/api-keys.d.ts.map +1 -0
- package/dist/tools/api-keys.js +29 -0
- package/dist/tools/api-keys.js.map +1 -0
- package/dist/tools/auth.d.ts +8 -0
- package/dist/tools/auth.d.ts.map +1 -0
- package/dist/tools/auth.js +187 -0
- package/dist/tools/auth.js.map +1 -0
- package/dist/tools/backup.d.ts +62 -0
- package/dist/tools/backup.d.ts.map +1 -0
- package/dist/tools/backup.js +167 -0
- package/dist/tools/backup.js.map +1 -0
- package/dist/tools/bank-accounts.d.ts +14 -0
- package/dist/tools/bank-accounts.d.ts.map +1 -0
- package/dist/tools/bank-accounts.js +140 -0
- package/dist/tools/bank-accounts.js.map +1 -0
- package/dist/tools/borderou.d.ts +14 -0
- package/dist/tools/borderou.d.ts.map +1 -0
- package/dist/tools/borderou.js +233 -0
- package/dist/tools/borderou.js.map +1 -0
- package/dist/tools/clients.d.ts +14 -0
- package/dist/tools/clients.d.ts.map +1 -0
- package/dist/tools/clients.js +353 -0
- package/dist/tools/clients.js.map +1 -0
- package/dist/tools/companies.d.ts +8 -0
- package/dist/tools/companies.d.ts.map +1 -0
- package/dist/tools/companies.js +211 -0
- package/dist/tools/companies.js.map +1 -0
- package/dist/tools/company-registry.d.ts +31 -0
- package/dist/tools/company-registry.d.ts.map +1 -0
- package/dist/tools/company-registry.js +51 -0
- package/dist/tools/company-registry.js.map +1 -0
- package/dist/tools/cpv-codes.d.ts +17 -0
- package/dist/tools/cpv-codes.d.ts.map +1 -0
- package/dist/tools/cpv-codes.js +28 -0
- package/dist/tools/cpv-codes.js.map +1 -0
- package/dist/tools/dashboard.d.ts +23 -0
- package/dist/tools/dashboard.d.ts.map +1 -0
- package/dist/tools/dashboard.js +37 -0
- package/dist/tools/dashboard.js.map +1 -0
- package/dist/tools/defaults.d.ts +14 -0
- package/dist/tools/defaults.d.ts.map +1 -0
- package/dist/tools/defaults.js +29 -0
- package/dist/tools/defaults.js.map +1 -0
- package/dist/tools/delivery-notes.d.ts +185 -0
- package/dist/tools/delivery-notes.d.ts.map +1 -0
- package/dist/tools/delivery-notes.js +525 -0
- package/dist/tools/delivery-notes.js.map +1 -0
- package/dist/tools/document-series.d.ts +54 -0
- package/dist/tools/document-series.d.ts.map +1 -0
- package/dist/tools/document-series.js +171 -0
- package/dist/tools/document-series.js.map +1 -0
- package/dist/tools/efactura-messages.d.ts +34 -0
- package/dist/tools/efactura-messages.d.ts.map +1 -0
- package/dist/tools/efactura-messages.js +51 -0
- package/dist/tools/efactura-messages.js.map +1 -0
- package/dist/tools/einvoice.d.ts +8 -0
- package/dist/tools/einvoice.d.ts.map +1 -0
- package/dist/tools/einvoice.js +170 -0
- package/dist/tools/einvoice.js.map +1 -0
- package/dist/tools/email-templates.d.ts +14 -0
- package/dist/tools/email-templates.d.ts.map +1 -0
- package/dist/tools/email-templates.js +104 -0
- package/dist/tools/email-templates.js.map +1 -0
- package/dist/tools/exchange-rates.d.ts +14 -0
- package/dist/tools/exchange-rates.d.ts.map +1 -0
- package/dist/tools/exchange-rates.js +55 -0
- package/dist/tools/exchange-rates.js.map +1 -0
- package/dist/tools/exports.d.ts +14 -0
- package/dist/tools/exports.d.ts.map +1 -0
- package/dist/tools/exports.js +25 -0
- package/dist/tools/exports.js.map +1 -0
- package/dist/tools/import.d.ts +14 -0
- package/dist/tools/import.d.ts.map +1 -0
- package/dist/tools/import.js +221 -0
- package/dist/tools/import.js.map +1 -0
- package/dist/tools/invitations.d.ts +8 -0
- package/dist/tools/invitations.d.ts.map +1 -0
- package/dist/tools/invitations.js +70 -0
- package/dist/tools/invitations.js.map +1 -0
- package/dist/tools/invoices.d.ts +14 -0
- package/dist/tools/invoices.d.ts.map +1 -0
- package/dist/tools/invoices.js +1191 -0
- package/dist/tools/invoices.js.map +1 -0
- package/dist/tools/licensing.d.ts +8 -0
- package/dist/tools/licensing.d.ts.map +1 -0
- package/dist/tools/licensing.js +90 -0
- package/dist/tools/licensing.js.map +1 -0
- package/dist/tools/members.d.ts +8 -0
- package/dist/tools/members.d.ts.map +1 -0
- package/dist/tools/members.js +79 -0
- package/dist/tools/members.js.map +1 -0
- package/dist/tools/nc-codes.d.ts +17 -0
- package/dist/tools/nc-codes.d.ts.map +1 -0
- package/dist/tools/nc-codes.js +28 -0
- package/dist/tools/nc-codes.js.map +1 -0
- package/dist/tools/notifications.d.ts +8 -0
- package/dist/tools/notifications.d.ts.map +1 -0
- package/dist/tools/notifications.js +111 -0
- package/dist/tools/notifications.js.map +1 -0
- package/dist/tools/oauth2-clients.d.ts +8 -0
- package/dist/tools/oauth2-clients.d.ts.map +1 -0
- package/dist/tools/oauth2-clients.js +147 -0
- package/dist/tools/oauth2-clients.js.map +1 -0
- package/dist/tools/payments.d.ts +17 -0
- package/dist/tools/payments.d.ts.map +1 -0
- package/dist/tools/payments.js +109 -0
- package/dist/tools/payments.js.map +1 -0
- package/dist/tools/pdf-template-config.d.ts +14 -0
- package/dist/tools/pdf-template-config.d.ts.map +1 -0
- package/dist/tools/pdf-template-config.js +131 -0
- package/dist/tools/pdf-template-config.js.map +1 -0
- package/dist/tools/products.d.ts +40 -0
- package/dist/tools/products.d.ts.map +1 -0
- package/dist/tools/products.js +73 -0
- package/dist/tools/products.js.map +1 -0
- package/dist/tools/proforma-invoices.d.ts +198 -0
- package/dist/tools/proforma-invoices.d.ts.map +1 -0
- package/dist/tools/proforma-invoices.js +378 -0
- package/dist/tools/proforma-invoices.js.map +1 -0
- package/dist/tools/receipts.d.ts +166 -0
- package/dist/tools/receipts.d.ts.map +1 -0
- package/dist/tools/receipts.js +397 -0
- package/dist/tools/receipts.js.map +1 -0
- package/dist/tools/recurring-invoices.d.ts +187 -0
- package/dist/tools/recurring-invoices.d.ts.map +1 -0
- package/dist/tools/recurring-invoices.js +305 -0
- package/dist/tools/recurring-invoices.js.map +1 -0
- package/dist/tools/reports.d.ts +48 -0
- package/dist/tools/reports.d.ts.map +1 -0
- package/dist/tools/reports.js +200 -0
- package/dist/tools/reports.js.map +1 -0
- package/dist/tools/storage-config.d.ts +8 -0
- package/dist/tools/storage-config.d.ts.map +1 -0
- package/dist/tools/storage-config.js +117 -0
- package/dist/tools/storage-config.js.map +1 -0
- package/dist/tools/suppliers.d.ts +14 -0
- package/dist/tools/suppliers.d.ts.map +1 -0
- package/dist/tools/suppliers.js +205 -0
- package/dist/tools/suppliers.js.map +1 -0
- package/dist/tools/system.d.ts +8 -0
- package/dist/tools/system.d.ts.map +1 -0
- package/dist/tools/system.js +24 -0
- package/dist/tools/system.js.map +1 -0
- package/dist/tools/vat-rates.d.ts +14 -0
- package/dist/tools/vat-rates.d.ts.map +1 -0
- package/dist/tools/vat-rates.js +145 -0
- package/dist/tools/vat-rates.js.map +1 -0
- package/dist/tools/webhooks.d.ts +8 -0
- package/dist/tools/webhooks.d.ts.map +1 -0
- package/dist/tools/webhooks.js +305 -0
- package/dist/tools/webhooks.js.map +1 -0
- package/dist/utils/errors.d.ts +18 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +45 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/pagination.d.ts +9 -0
- package/dist/utils/pagination.d.ts.map +1 -0
- package/dist/utils/pagination.js +10 -0
- package/dist/utils/pagination.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,1191 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { apiRequest } from '../client.js';
|
|
3
|
+
import { formatResponse, notAuthenticated, noCompanySelected } from '../utils/errors.js';
|
|
4
|
+
import { getConfig } from '../config.js';
|
|
5
|
+
const lineItemSchema = z.object({
|
|
6
|
+
description: z.string().describe('Line item description (product or service name)'),
|
|
7
|
+
quantity: z.number().describe('Quantity of items'),
|
|
8
|
+
unitPrice: z.number().describe('Unit price per item (excluding VAT by default)'),
|
|
9
|
+
vatRateId: z
|
|
10
|
+
.string()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe('VAT rate UUID (from vat_rates_list). Uses company default if not provided.'),
|
|
13
|
+
unitOfMeasure: z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('Unit of measure code (e.g., "BUC", "ORE", "KG"). From invoice-defaults.'),
|
|
17
|
+
productId: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe('Product UUID reference from products catalog (optional)'),
|
|
21
|
+
discount: z.number().optional().describe('Fixed discount amount to subtract'),
|
|
22
|
+
discountPercent: z
|
|
23
|
+
.number()
|
|
24
|
+
.optional()
|
|
25
|
+
.describe('Discount as a percentage (e.g., 10 for 10%)'),
|
|
26
|
+
vatIncluded: z
|
|
27
|
+
.boolean()
|
|
28
|
+
.optional()
|
|
29
|
+
.describe('Whether unitPrice already includes VAT (default: false)'),
|
|
30
|
+
productCode: z.string().optional().describe('Product code or SKU for reference'),
|
|
31
|
+
});
|
|
32
|
+
function getCompanyId(params) {
|
|
33
|
+
return params.companyId || getConfig().companyId;
|
|
34
|
+
}
|
|
35
|
+
export const tools = [
|
|
36
|
+
{
|
|
37
|
+
name: 'invoices_list',
|
|
38
|
+
description: 'List invoices for the active company with pagination, filtering, and sorting. Supports filtering by status (draft/issued/sent_to_provider/validated/rejected/cancelled), direction (incoming/outgoing), date range, client, and search term. Returns paginated results with totals.',
|
|
39
|
+
inputSchema: z.object({
|
|
40
|
+
companyId: z
|
|
41
|
+
.string()
|
|
42
|
+
.optional()
|
|
43
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
44
|
+
page: z.number().int().optional().describe('Page number (default: 1)'),
|
|
45
|
+
limit: z
|
|
46
|
+
.number()
|
|
47
|
+
.int()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('Items per page, max 100 (default: 20)'),
|
|
50
|
+
search: z
|
|
51
|
+
.string()
|
|
52
|
+
.optional()
|
|
53
|
+
.describe('Search term for invoice number or client name'),
|
|
54
|
+
status: z
|
|
55
|
+
.enum([
|
|
56
|
+
'draft',
|
|
57
|
+
'issued',
|
|
58
|
+
'sent_to_provider',
|
|
59
|
+
'validated',
|
|
60
|
+
'rejected',
|
|
61
|
+
'cancelled',
|
|
62
|
+
])
|
|
63
|
+
.optional()
|
|
64
|
+
.describe('Filter by invoice status'),
|
|
65
|
+
direction: z
|
|
66
|
+
.enum(['incoming', 'outgoing'])
|
|
67
|
+
.optional()
|
|
68
|
+
.describe('Filter by direction: incoming or outgoing invoices'),
|
|
69
|
+
from: z
|
|
70
|
+
.string()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe('Start date filter in ISO 8601 format (YYYY-MM-DD)'),
|
|
73
|
+
to: z
|
|
74
|
+
.string()
|
|
75
|
+
.optional()
|
|
76
|
+
.describe('End date filter in ISO 8601 format (YYYY-MM-DD)'),
|
|
77
|
+
clientId: z.string().optional().describe('Filter by client UUID'),
|
|
78
|
+
sort: z
|
|
79
|
+
.enum(['issueDate', 'number', 'total', 'dueDate'])
|
|
80
|
+
.optional()
|
|
81
|
+
.describe('Field to sort by (default: issueDate)'),
|
|
82
|
+
order: z
|
|
83
|
+
.enum(['asc', 'desc'])
|
|
84
|
+
.optional()
|
|
85
|
+
.describe('Sort order: asc or desc (default: desc)'),
|
|
86
|
+
}),
|
|
87
|
+
handler: async (params) => {
|
|
88
|
+
if (!getConfig().token)
|
|
89
|
+
return notAuthenticated();
|
|
90
|
+
const companyId = getCompanyId(params);
|
|
91
|
+
if (!companyId)
|
|
92
|
+
return noCompanySelected();
|
|
93
|
+
const { page, limit, search, status, direction, from, to, clientId, sort, order, } = params;
|
|
94
|
+
const result = await apiRequest('/api/v1/invoices', {
|
|
95
|
+
companyId,
|
|
96
|
+
query: {
|
|
97
|
+
page: page,
|
|
98
|
+
limit: limit,
|
|
99
|
+
search: search,
|
|
100
|
+
status: status,
|
|
101
|
+
direction: direction,
|
|
102
|
+
from: from,
|
|
103
|
+
to: to,
|
|
104
|
+
clientId: clientId,
|
|
105
|
+
sort: sort,
|
|
106
|
+
order: order,
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
return formatResponse(result);
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'invoices_get',
|
|
114
|
+
description: 'Get complete details for a specific invoice by UUID, including all line items, payment history, events timeline, attachments, client and supplier info, XML/PDF generation status, and ANAF submission details.',
|
|
115
|
+
inputSchema: z.object({
|
|
116
|
+
uuid: z.string().describe('Invoice UUID'),
|
|
117
|
+
companyId: z
|
|
118
|
+
.string()
|
|
119
|
+
.optional()
|
|
120
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
121
|
+
}),
|
|
122
|
+
handler: async (params) => {
|
|
123
|
+
if (!getConfig().token)
|
|
124
|
+
return notAuthenticated();
|
|
125
|
+
const companyId = getCompanyId(params);
|
|
126
|
+
if (!companyId)
|
|
127
|
+
return noCompanySelected();
|
|
128
|
+
const { uuid } = params;
|
|
129
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}`, { companyId });
|
|
130
|
+
return formatResponse(result);
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'invoices_create',
|
|
135
|
+
description: 'Create a new draft invoice. Requires at least one line item and either a clientId or receiverName/receiverCif. The invoice starts in "draft" status and can be edited until issued. Use invoices_issue to finalize and generate XML/PDF.',
|
|
136
|
+
inputSchema: z.object({
|
|
137
|
+
companyId: z
|
|
138
|
+
.string()
|
|
139
|
+
.optional()
|
|
140
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
141
|
+
clientId: z
|
|
142
|
+
.string()
|
|
143
|
+
.optional()
|
|
144
|
+
.describe('Client UUID (from clients_list). Either clientId or receiverName should be provided.'),
|
|
145
|
+
receiverName: z
|
|
146
|
+
.string()
|
|
147
|
+
.optional()
|
|
148
|
+
.describe('Receiver name (used when no client entity exists). Either clientId or receiverName should be provided.'),
|
|
149
|
+
receiverCif: z
|
|
150
|
+
.string()
|
|
151
|
+
.optional()
|
|
152
|
+
.describe('Receiver tax ID / CIF (used together with receiverName when no client entity exists)'),
|
|
153
|
+
issueDate: z
|
|
154
|
+
.string()
|
|
155
|
+
.describe('Invoice issue date in ISO 8601 format (YYYY-MM-DD)'),
|
|
156
|
+
dueDate: z
|
|
157
|
+
.string()
|
|
158
|
+
.optional()
|
|
159
|
+
.describe('Payment due date in ISO 8601 format (YYYY-MM-DD)'),
|
|
160
|
+
seriesId: z
|
|
161
|
+
.string()
|
|
162
|
+
.optional()
|
|
163
|
+
.describe('Invoice series UUID (from document_series_list). Uses default if not provided.'),
|
|
164
|
+
currency: z
|
|
165
|
+
.string()
|
|
166
|
+
.optional()
|
|
167
|
+
.describe('ISO 4217 currency code (default: RON)'),
|
|
168
|
+
exchangeRate: z
|
|
169
|
+
.number()
|
|
170
|
+
.optional()
|
|
171
|
+
.describe('Exchange rate relative to RON (default: 1.0)'),
|
|
172
|
+
invoiceTypeCode: z
|
|
173
|
+
.string()
|
|
174
|
+
.optional()
|
|
175
|
+
.describe('UBL invoice type code: 380=commercial (default), 381=credit note, 384=corrected, 389=self-billed'),
|
|
176
|
+
notes: z
|
|
177
|
+
.string()
|
|
178
|
+
.optional()
|
|
179
|
+
.describe('Public notes visible to the client'),
|
|
180
|
+
paymentTerms: z
|
|
181
|
+
.string()
|
|
182
|
+
.optional()
|
|
183
|
+
.describe('Payment terms description (e.g., "Net 30")'),
|
|
184
|
+
deliveryLocation: z
|
|
185
|
+
.string()
|
|
186
|
+
.optional()
|
|
187
|
+
.describe('Delivery address'),
|
|
188
|
+
projectReference: z
|
|
189
|
+
.string()
|
|
190
|
+
.optional()
|
|
191
|
+
.describe('Project reference number'),
|
|
192
|
+
orderNumber: z
|
|
193
|
+
.string()
|
|
194
|
+
.optional()
|
|
195
|
+
.describe('Purchase order number'),
|
|
196
|
+
contractNumber: z
|
|
197
|
+
.string()
|
|
198
|
+
.optional()
|
|
199
|
+
.describe('Contract reference number'),
|
|
200
|
+
issuerName: z
|
|
201
|
+
.string()
|
|
202
|
+
.optional()
|
|
203
|
+
.describe('Name of person issuing the invoice'),
|
|
204
|
+
issuerId: z
|
|
205
|
+
.string()
|
|
206
|
+
.optional()
|
|
207
|
+
.describe('Issuer ID number'),
|
|
208
|
+
mentions: z
|
|
209
|
+
.string()
|
|
210
|
+
.optional()
|
|
211
|
+
.describe('Additional legal mentions on the invoice'),
|
|
212
|
+
internalNote: z
|
|
213
|
+
.string()
|
|
214
|
+
.optional()
|
|
215
|
+
.describe('Internal note (not visible to the client)'),
|
|
216
|
+
salesAgent: z
|
|
217
|
+
.string()
|
|
218
|
+
.optional()
|
|
219
|
+
.describe('Sales agent name'),
|
|
220
|
+
deputyName: z
|
|
221
|
+
.string()
|
|
222
|
+
.optional()
|
|
223
|
+
.describe('Deputy/representative name'),
|
|
224
|
+
deputyIdentityCard: z
|
|
225
|
+
.string()
|
|
226
|
+
.optional()
|
|
227
|
+
.describe('Deputy ID card number'),
|
|
228
|
+
deputyAuto: z
|
|
229
|
+
.string()
|
|
230
|
+
.optional()
|
|
231
|
+
.describe('Deputy vehicle registration number'),
|
|
232
|
+
collect: z
|
|
233
|
+
.union([
|
|
234
|
+
z.boolean(),
|
|
235
|
+
z.object({
|
|
236
|
+
value: z.number().optional().describe('Payment amount (defaults to invoice total)'),
|
|
237
|
+
type: z.enum(['bank_transfer', 'cash', 'card', 'other']).optional().describe('Payment method (default: bank_transfer)'),
|
|
238
|
+
issueDate: z.string().optional().describe('Payment date (YYYY-MM-DD)'),
|
|
239
|
+
documentNumber: z.string().optional().describe('Payment reference number'),
|
|
240
|
+
mentions: z.string().optional().describe('Payment notes'),
|
|
241
|
+
}),
|
|
242
|
+
])
|
|
243
|
+
.optional()
|
|
244
|
+
.describe('Record an immediate payment. Pass true for full payment with defaults, or an object with value/type/issueDate/documentNumber/mentions for details.'),
|
|
245
|
+
penaltyEnabled: z
|
|
246
|
+
.boolean()
|
|
247
|
+
.optional()
|
|
248
|
+
.describe('Enable late payment penalty (default: false)'),
|
|
249
|
+
penaltyPercentPerDay: z
|
|
250
|
+
.number()
|
|
251
|
+
.optional()
|
|
252
|
+
.describe('Daily penalty percentage (e.g., 0.05 for 0.05% per day)'),
|
|
253
|
+
penaltyGraceDays: z
|
|
254
|
+
.number()
|
|
255
|
+
.int()
|
|
256
|
+
.optional()
|
|
257
|
+
.describe('Grace period in days before penalty starts applying'),
|
|
258
|
+
language: z
|
|
259
|
+
.enum(['ro', 'en', 'de', 'fr'])
|
|
260
|
+
.optional()
|
|
261
|
+
.describe('Document language for PDF generation (default: ro)'),
|
|
262
|
+
autoApplyVatRules: z
|
|
263
|
+
.boolean()
|
|
264
|
+
.optional()
|
|
265
|
+
.describe('Auto-apply VAT rules (reverse charge for VIES-valid EU clients, OSS destination rate for non-VIES EU clients). Default: false.'),
|
|
266
|
+
vatIncluded: z
|
|
267
|
+
.boolean()
|
|
268
|
+
.optional()
|
|
269
|
+
.describe('When used with autoApplyVatRules, sets whether unit prices include VAT on all lines. Ensures correct totals after VAT rules change rates.'),
|
|
270
|
+
lines: z
|
|
271
|
+
.array(lineItemSchema)
|
|
272
|
+
.describe('Invoice line items (at least one required)'),
|
|
273
|
+
}),
|
|
274
|
+
handler: async (params) => {
|
|
275
|
+
if (!getConfig().token)
|
|
276
|
+
return notAuthenticated();
|
|
277
|
+
const companyId = getCompanyId(params);
|
|
278
|
+
if (!companyId)
|
|
279
|
+
return noCompanySelected();
|
|
280
|
+
const { companyId: _cid, ...body } = params;
|
|
281
|
+
const result = await apiRequest('/api/v1/invoices', {
|
|
282
|
+
method: 'POST',
|
|
283
|
+
companyId,
|
|
284
|
+
body: body,
|
|
285
|
+
});
|
|
286
|
+
return formatResponse(result);
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
name: 'invoices_update',
|
|
291
|
+
description: 'Update an existing draft invoice. Only invoices with status "draft" can be updated. When updating the lines array, the entire array is replaced — include all lines you want to keep. Once issued, use invoices_cancel instead.',
|
|
292
|
+
inputSchema: z.object({
|
|
293
|
+
uuid: z.string().describe('Invoice UUID to update'),
|
|
294
|
+
companyId: z
|
|
295
|
+
.string()
|
|
296
|
+
.optional()
|
|
297
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
298
|
+
clientId: z.string().optional().describe('Client UUID'),
|
|
299
|
+
seriesId: z.string().optional().describe('Invoice series UUID'),
|
|
300
|
+
issueDate: z
|
|
301
|
+
.string()
|
|
302
|
+
.optional()
|
|
303
|
+
.describe('Invoice issue date (YYYY-MM-DD)'),
|
|
304
|
+
dueDate: z
|
|
305
|
+
.string()
|
|
306
|
+
.optional()
|
|
307
|
+
.describe('Payment due date (YYYY-MM-DD)'),
|
|
308
|
+
currency: z.string().optional().describe('ISO 4217 currency code'),
|
|
309
|
+
exchangeRate: z.number().optional().describe('Exchange rate relative to RON'),
|
|
310
|
+
invoiceTypeCode: z.string().optional().describe('UBL invoice type code'),
|
|
311
|
+
notes: z.string().optional().describe('Public notes visible to the client'),
|
|
312
|
+
paymentTerms: z.string().optional().describe('Payment terms description'),
|
|
313
|
+
deliveryLocation: z.string().optional().describe('Delivery address'),
|
|
314
|
+
projectReference: z.string().optional().describe('Project reference number'),
|
|
315
|
+
orderNumber: z.string().optional().describe('Purchase order number'),
|
|
316
|
+
contractNumber: z.string().optional().describe('Contract reference number'),
|
|
317
|
+
issuerName: z.string().optional().describe('Name of person issuing the invoice'),
|
|
318
|
+
issuerId: z.string().optional().describe('Issuer ID number'),
|
|
319
|
+
mentions: z.string().optional().describe('Additional legal mentions'),
|
|
320
|
+
internalNote: z.string().optional().describe('Internal note (not visible to client)'),
|
|
321
|
+
salesAgent: z.string().optional().describe('Sales agent name'),
|
|
322
|
+
deputyName: z.string().optional().describe('Deputy/representative name'),
|
|
323
|
+
deputyIdentityCard: z.string().optional().describe('Deputy ID card number'),
|
|
324
|
+
deputyAuto: z.string().optional().describe('Deputy vehicle registration'),
|
|
325
|
+
penaltyEnabled: z.boolean().optional().describe('Enable late payment penalty'),
|
|
326
|
+
penaltyPercentPerDay: z
|
|
327
|
+
.number()
|
|
328
|
+
.optional()
|
|
329
|
+
.describe('Daily penalty percentage'),
|
|
330
|
+
penaltyGraceDays: z
|
|
331
|
+
.number()
|
|
332
|
+
.int()
|
|
333
|
+
.optional()
|
|
334
|
+
.describe('Grace period before penalty applies'),
|
|
335
|
+
language: z
|
|
336
|
+
.enum(['ro', 'en', 'de', 'fr'])
|
|
337
|
+
.optional()
|
|
338
|
+
.describe('Document language for PDF generation (default: ro)'),
|
|
339
|
+
autoApplyVatRules: z
|
|
340
|
+
.boolean()
|
|
341
|
+
.optional()
|
|
342
|
+
.describe('Auto-apply VAT rules (reverse charge for VIES-valid EU clients, OSS destination rate for non-VIES EU clients). Default: false.'),
|
|
343
|
+
vatIncluded: z
|
|
344
|
+
.boolean()
|
|
345
|
+
.optional()
|
|
346
|
+
.describe('When used with autoApplyVatRules, sets whether unit prices include VAT on all lines. Ensures correct totals after VAT rules change rates.'),
|
|
347
|
+
lines: z
|
|
348
|
+
.array(lineItemSchema)
|
|
349
|
+
.optional()
|
|
350
|
+
.describe('Invoice line items. WARNING: replaces all existing lines — include every line you want to keep.'),
|
|
351
|
+
}),
|
|
352
|
+
handler: async (params) => {
|
|
353
|
+
if (!getConfig().token)
|
|
354
|
+
return notAuthenticated();
|
|
355
|
+
const companyId = getCompanyId(params);
|
|
356
|
+
if (!companyId)
|
|
357
|
+
return noCompanySelected();
|
|
358
|
+
const { uuid, companyId: _cid, ...rest } = params;
|
|
359
|
+
const body = {};
|
|
360
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
361
|
+
if (value !== undefined)
|
|
362
|
+
body[key] = value;
|
|
363
|
+
}
|
|
364
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}`, {
|
|
365
|
+
method: 'PUT',
|
|
366
|
+
companyId,
|
|
367
|
+
body,
|
|
368
|
+
});
|
|
369
|
+
return formatResponse(result);
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
name: 'invoices_delete',
|
|
374
|
+
description: 'Permanently delete a draft invoice. Only invoices with status "draft" can be deleted. This action is irreversible. For issued invoices, use invoices_cancel instead.',
|
|
375
|
+
inputSchema: z.object({
|
|
376
|
+
uuid: z.string().describe('Invoice UUID to delete'),
|
|
377
|
+
companyId: z
|
|
378
|
+
.string()
|
|
379
|
+
.optional()
|
|
380
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
381
|
+
}),
|
|
382
|
+
handler: async (params) => {
|
|
383
|
+
if (!getConfig().token)
|
|
384
|
+
return notAuthenticated();
|
|
385
|
+
const companyId = getCompanyId(params);
|
|
386
|
+
if (!companyId)
|
|
387
|
+
return noCompanySelected();
|
|
388
|
+
const { uuid } = params;
|
|
389
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}`, {
|
|
390
|
+
method: 'DELETE',
|
|
391
|
+
companyId,
|
|
392
|
+
});
|
|
393
|
+
return formatResponse(result);
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
name: 'invoices_issue',
|
|
398
|
+
description: 'Issue a draft invoice. Validates the data, assigns a series number, generates UBL 2.1 XML, generates PDF (Pro plan), and changes status from "draft" to "issued". Once issued, the invoice cannot be edited. Use invoices_submit to send to ANAF e-Factura.',
|
|
399
|
+
inputSchema: z.object({
|
|
400
|
+
uuid: z.string().describe('Invoice UUID to issue'),
|
|
401
|
+
companyId: z
|
|
402
|
+
.string()
|
|
403
|
+
.optional()
|
|
404
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
405
|
+
}),
|
|
406
|
+
handler: async (params) => {
|
|
407
|
+
if (!getConfig().token)
|
|
408
|
+
return notAuthenticated();
|
|
409
|
+
const companyId = getCompanyId(params);
|
|
410
|
+
if (!companyId)
|
|
411
|
+
return noCompanySelected();
|
|
412
|
+
const { uuid } = params;
|
|
413
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/issue`, {
|
|
414
|
+
method: 'POST',
|
|
415
|
+
companyId,
|
|
416
|
+
});
|
|
417
|
+
return formatResponse(result);
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
name: 'invoices_submit',
|
|
422
|
+
description: 'Submit an issued invoice to the ANAF e-Factura system. The invoice must be in "issued" status. Changes status to "sent_to_provider". ANAF validates the invoice asynchronously — poll invoices_get or use invoices_events to check validation result.',
|
|
423
|
+
inputSchema: z.object({
|
|
424
|
+
uuid: z.string().describe('Invoice UUID to submit to ANAF'),
|
|
425
|
+
companyId: z
|
|
426
|
+
.string()
|
|
427
|
+
.optional()
|
|
428
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
429
|
+
}),
|
|
430
|
+
handler: async (params) => {
|
|
431
|
+
if (!getConfig().token)
|
|
432
|
+
return notAuthenticated();
|
|
433
|
+
const companyId = getCompanyId(params);
|
|
434
|
+
if (!companyId)
|
|
435
|
+
return noCompanySelected();
|
|
436
|
+
const { uuid } = params;
|
|
437
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/submit`, {
|
|
438
|
+
method: 'POST',
|
|
439
|
+
companyId,
|
|
440
|
+
});
|
|
441
|
+
return formatResponse(result);
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
name: 'invoices_validate',
|
|
446
|
+
description: 'Validate an invoice before issuing or submitting. Returns a list of errors and warnings. Use mode "quick" for fast validation (basic rules) or "full" for comprehensive UBL Schematron and CIUS-RO compliance checks.',
|
|
447
|
+
inputSchema: z.object({
|
|
448
|
+
uuid: z.string().describe('Invoice UUID to validate'),
|
|
449
|
+
companyId: z
|
|
450
|
+
.string()
|
|
451
|
+
.optional()
|
|
452
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
453
|
+
mode: z
|
|
454
|
+
.enum(['quick', 'full'])
|
|
455
|
+
.optional()
|
|
456
|
+
.describe('Validation mode: "quick" for fast basic rules (default), "full" for UBL Schematron + CIUS-RO compliance (slower)'),
|
|
457
|
+
}),
|
|
458
|
+
handler: async (params) => {
|
|
459
|
+
if (!getConfig().token)
|
|
460
|
+
return notAuthenticated();
|
|
461
|
+
const companyId = getCompanyId(params);
|
|
462
|
+
if (!companyId)
|
|
463
|
+
return noCompanySelected();
|
|
464
|
+
const { uuid, mode } = params;
|
|
465
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/validate`, {
|
|
466
|
+
method: 'POST',
|
|
467
|
+
companyId,
|
|
468
|
+
query: mode ? { mode } : undefined,
|
|
469
|
+
});
|
|
470
|
+
return formatResponse(result);
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
name: 'invoices_cancel',
|
|
475
|
+
description: 'Cancel an issued invoice. Requires a cancellation reason (minimum 10 characters). Changes status to "cancelled". Cancelled invoices remain in the system for record-keeping. Use invoices_restore to undo an accidental cancellation.',
|
|
476
|
+
inputSchema: z.object({
|
|
477
|
+
uuid: z.string().describe('Invoice UUID to cancel'),
|
|
478
|
+
reason: z
|
|
479
|
+
.string()
|
|
480
|
+
.min(10)
|
|
481
|
+
.describe('Reason for cancellation (minimum 10 characters)'),
|
|
482
|
+
companyId: z
|
|
483
|
+
.string()
|
|
484
|
+
.optional()
|
|
485
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
486
|
+
}),
|
|
487
|
+
handler: async (params) => {
|
|
488
|
+
if (!getConfig().token)
|
|
489
|
+
return notAuthenticated();
|
|
490
|
+
const companyId = getCompanyId(params);
|
|
491
|
+
if (!companyId)
|
|
492
|
+
return noCompanySelected();
|
|
493
|
+
const { uuid, reason } = params;
|
|
494
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/cancel`, {
|
|
495
|
+
method: 'POST',
|
|
496
|
+
companyId,
|
|
497
|
+
body: { reason },
|
|
498
|
+
});
|
|
499
|
+
return formatResponse(result);
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
name: 'invoices_restore',
|
|
504
|
+
description: 'Restore a cancelled invoice back to "draft" status. Only for accidental cancellations. Cannot restore if the invoice was submitted to ANAF, has credit notes, or has recorded payments. The invoice can then be edited and reissued.',
|
|
505
|
+
inputSchema: z.object({
|
|
506
|
+
uuid: z.string().describe('Invoice UUID to restore from cancelled status'),
|
|
507
|
+
companyId: z
|
|
508
|
+
.string()
|
|
509
|
+
.optional()
|
|
510
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
511
|
+
}),
|
|
512
|
+
handler: async (params) => {
|
|
513
|
+
if (!getConfig().token)
|
|
514
|
+
return notAuthenticated();
|
|
515
|
+
const companyId = getCompanyId(params);
|
|
516
|
+
if (!companyId)
|
|
517
|
+
return noCompanySelected();
|
|
518
|
+
const { uuid } = params;
|
|
519
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/restore`, {
|
|
520
|
+
method: 'POST',
|
|
521
|
+
companyId,
|
|
522
|
+
});
|
|
523
|
+
return formatResponse(result);
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
name: 'invoices_pdf',
|
|
528
|
+
description: 'Download the PDF representation of an invoice. Returns base64-encoded binary data with content type. Requires Pro plan. PDF is generated automatically on issue or on-demand when first requested.',
|
|
529
|
+
inputSchema: z.object({
|
|
530
|
+
uuid: z.string().describe('Invoice UUID'),
|
|
531
|
+
companyId: z
|
|
532
|
+
.string()
|
|
533
|
+
.optional()
|
|
534
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
535
|
+
}),
|
|
536
|
+
handler: async (params) => {
|
|
537
|
+
if (!getConfig().token)
|
|
538
|
+
return notAuthenticated();
|
|
539
|
+
const companyId = getCompanyId(params);
|
|
540
|
+
if (!companyId)
|
|
541
|
+
return noCompanySelected();
|
|
542
|
+
const { uuid } = params;
|
|
543
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/pdf`, {
|
|
544
|
+
companyId,
|
|
545
|
+
binary: true,
|
|
546
|
+
});
|
|
547
|
+
return formatResponse(result);
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
name: 'invoices_xml',
|
|
552
|
+
description: 'Download the UBL 2.1 XML file for an issued invoice. Returns the XML text content. The XML is the format required for ANAF e-Factura submission and conforms to CIUS-RO and EN 16931 standards.',
|
|
553
|
+
inputSchema: z.object({
|
|
554
|
+
uuid: z.string().describe('Invoice UUID'),
|
|
555
|
+
companyId: z
|
|
556
|
+
.string()
|
|
557
|
+
.optional()
|
|
558
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
559
|
+
}),
|
|
560
|
+
handler: async (params) => {
|
|
561
|
+
if (!getConfig().token)
|
|
562
|
+
return notAuthenticated();
|
|
563
|
+
const companyId = getCompanyId(params);
|
|
564
|
+
if (!companyId)
|
|
565
|
+
return noCompanySelected();
|
|
566
|
+
const { uuid } = params;
|
|
567
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/xml`, { companyId });
|
|
568
|
+
return formatResponse(result);
|
|
569
|
+
},
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
name: 'invoices_email',
|
|
573
|
+
description: 'Send an invoice via email with optional PDF and XML attachments. Use invoices_email_defaults first to get pre-filled subject and body. Emails are sent asynchronously via queue. PDF attachment requires Pro plan.',
|
|
574
|
+
inputSchema: z.object({
|
|
575
|
+
uuid: z.string().describe('Invoice UUID to email'),
|
|
576
|
+
companyId: z
|
|
577
|
+
.string()
|
|
578
|
+
.optional()
|
|
579
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
580
|
+
to: z.string().email().describe('Recipient email address'),
|
|
581
|
+
cc: z
|
|
582
|
+
.string()
|
|
583
|
+
.optional()
|
|
584
|
+
.describe('CC email address (comma-separated for multiple)'),
|
|
585
|
+
bcc: z
|
|
586
|
+
.string()
|
|
587
|
+
.optional()
|
|
588
|
+
.describe('BCC email address (comma-separated for multiple)'),
|
|
589
|
+
subject: z
|
|
590
|
+
.string()
|
|
591
|
+
.optional()
|
|
592
|
+
.describe('Email subject (uses default template if not provided)'),
|
|
593
|
+
body: z
|
|
594
|
+
.string()
|
|
595
|
+
.optional()
|
|
596
|
+
.describe('Email body text (uses default template if not provided)'),
|
|
597
|
+
attachPdf: z
|
|
598
|
+
.boolean()
|
|
599
|
+
.optional()
|
|
600
|
+
.describe('Attach PDF invoice (default: true, requires Pro plan)'),
|
|
601
|
+
attachXml: z
|
|
602
|
+
.boolean()
|
|
603
|
+
.optional()
|
|
604
|
+
.describe('Attach UBL XML file (default: false)'),
|
|
605
|
+
language: z
|
|
606
|
+
.enum(['ro', 'en'])
|
|
607
|
+
.optional()
|
|
608
|
+
.describe('Email template language: ro (default) or en'),
|
|
609
|
+
}),
|
|
610
|
+
handler: async (params) => {
|
|
611
|
+
if (!getConfig().token)
|
|
612
|
+
return notAuthenticated();
|
|
613
|
+
const companyId = getCompanyId(params);
|
|
614
|
+
if (!companyId)
|
|
615
|
+
return noCompanySelected();
|
|
616
|
+
const { uuid, companyId: _cid, ...rest } = params;
|
|
617
|
+
const body = {};
|
|
618
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
619
|
+
if (value !== undefined)
|
|
620
|
+
body[key] = value;
|
|
621
|
+
}
|
|
622
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/email`, {
|
|
623
|
+
method: 'POST',
|
|
624
|
+
companyId,
|
|
625
|
+
body,
|
|
626
|
+
});
|
|
627
|
+
return formatResponse(result);
|
|
628
|
+
},
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
name: 'invoices_email_defaults',
|
|
632
|
+
description: 'Get pre-filled email content for an invoice based on the company email template. Returns suggested "to", "cc", "subject", and "body" with template variables already substituted. Use this to populate the email form before calling invoices_email.',
|
|
633
|
+
inputSchema: z.object({
|
|
634
|
+
uuid: z.string().describe('Invoice UUID'),
|
|
635
|
+
companyId: z
|
|
636
|
+
.string()
|
|
637
|
+
.optional()
|
|
638
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
639
|
+
language: z
|
|
640
|
+
.enum(['ro', 'en'])
|
|
641
|
+
.optional()
|
|
642
|
+
.describe('Email language: ro (default) or en'),
|
|
643
|
+
}),
|
|
644
|
+
handler: async (params) => {
|
|
645
|
+
if (!getConfig().token)
|
|
646
|
+
return notAuthenticated();
|
|
647
|
+
const companyId = getCompanyId(params);
|
|
648
|
+
if (!companyId)
|
|
649
|
+
return noCompanySelected();
|
|
650
|
+
const { uuid, language } = params;
|
|
651
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/email-defaults`, {
|
|
652
|
+
companyId,
|
|
653
|
+
query: language ? { language } : undefined,
|
|
654
|
+
});
|
|
655
|
+
return formatResponse(result);
|
|
656
|
+
},
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
name: 'invoices_email_history',
|
|
660
|
+
description: 'Get the complete history of emails sent for an invoice, including delivery status, open/click tracking, bounce information, and who sent each email. Useful for audit trails and verifying client received the invoice.',
|
|
661
|
+
inputSchema: z.object({
|
|
662
|
+
uuid: z.string().describe('Invoice UUID'),
|
|
663
|
+
companyId: z
|
|
664
|
+
.string()
|
|
665
|
+
.optional()
|
|
666
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
667
|
+
}),
|
|
668
|
+
handler: async (params) => {
|
|
669
|
+
if (!getConfig().token)
|
|
670
|
+
return notAuthenticated();
|
|
671
|
+
const companyId = getCompanyId(params);
|
|
672
|
+
if (!companyId)
|
|
673
|
+
return noCompanySelected();
|
|
674
|
+
const { uuid } = params;
|
|
675
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/emails`, { companyId });
|
|
676
|
+
return formatResponse(result);
|
|
677
|
+
},
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
name: 'invoices_events',
|
|
681
|
+
description: 'Get the complete timeline of events for an invoice: status changes, ANAF submissions, validations, emails sent, payments received, and user actions. Useful for audit trails, debugging, and understanding invoice lifecycle history.',
|
|
682
|
+
inputSchema: z.object({
|
|
683
|
+
uuid: z.string().describe('Invoice UUID'),
|
|
684
|
+
companyId: z
|
|
685
|
+
.string()
|
|
686
|
+
.optional()
|
|
687
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
688
|
+
}),
|
|
689
|
+
handler: async (params) => {
|
|
690
|
+
if (!getConfig().token)
|
|
691
|
+
return notAuthenticated();
|
|
692
|
+
const companyId = getCompanyId(params);
|
|
693
|
+
if (!companyId)
|
|
694
|
+
return noCompanySelected();
|
|
695
|
+
const { uuid } = params;
|
|
696
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/events`, { companyId });
|
|
697
|
+
return formatResponse(result);
|
|
698
|
+
},
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
name: 'invoices_attachments',
|
|
702
|
+
description: 'Download a file attachment from an invoice. Returns base64-encoded binary data with the MIME type. Get attachment UUIDs from invoices_get (the "attachments" array). Supports PDF, images, Word, Excel, ZIP, and other file types.',
|
|
703
|
+
inputSchema: z.object({
|
|
704
|
+
uuid: z.string().describe('Invoice UUID'),
|
|
705
|
+
attachmentId: z.string().describe('Attachment UUID (from invoices_get attachments array)'),
|
|
706
|
+
companyId: z
|
|
707
|
+
.string()
|
|
708
|
+
.optional()
|
|
709
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
710
|
+
}),
|
|
711
|
+
handler: async (params) => {
|
|
712
|
+
if (!getConfig().token)
|
|
713
|
+
return notAuthenticated();
|
|
714
|
+
const companyId = getCompanyId(params);
|
|
715
|
+
if (!companyId)
|
|
716
|
+
return noCompanySelected();
|
|
717
|
+
const { uuid, attachmentId } = params;
|
|
718
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/attachments/${attachmentId}`, { companyId, binary: true });
|
|
719
|
+
return formatResponse(result);
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
name: 'invoices_verify_signature',
|
|
724
|
+
description: 'Verify the ANAF digital signature on a validated invoice. Checks certificate validity, signature cryptographic integrity, and XML content integrity. Requires Pro plan and the invoice must be in "validated" status (ANAF-signed).',
|
|
725
|
+
inputSchema: z.object({
|
|
726
|
+
uuid: z.string().describe('Invoice UUID (must be ANAF-validated)'),
|
|
727
|
+
companyId: z
|
|
728
|
+
.string()
|
|
729
|
+
.optional()
|
|
730
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
731
|
+
}),
|
|
732
|
+
handler: async (params) => {
|
|
733
|
+
if (!getConfig().token)
|
|
734
|
+
return notAuthenticated();
|
|
735
|
+
const companyId = getCompanyId(params);
|
|
736
|
+
if (!companyId)
|
|
737
|
+
return noCompanySelected();
|
|
738
|
+
const { uuid } = params;
|
|
739
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/verify-signature`, {
|
|
740
|
+
method: 'POST',
|
|
741
|
+
companyId,
|
|
742
|
+
});
|
|
743
|
+
return formatResponse(result);
|
|
744
|
+
},
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
name: 'invoices_export_csv',
|
|
748
|
+
description: 'Export a filtered list of invoices to CSV format. Accepts the same filters as invoices_list (status, direction, date range, client, etc.). Returns CSV text with UTF-8 BOM for Excel compatibility. Max 10,000 invoices; use invoices_export_zip for large exports with files.',
|
|
749
|
+
inputSchema: z.object({
|
|
750
|
+
companyId: z
|
|
751
|
+
.string()
|
|
752
|
+
.optional()
|
|
753
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
754
|
+
search: z.string().optional().describe('Search term for invoice number or client name'),
|
|
755
|
+
status: z
|
|
756
|
+
.enum([
|
|
757
|
+
'draft',
|
|
758
|
+
'issued',
|
|
759
|
+
'sent_to_provider',
|
|
760
|
+
'validated',
|
|
761
|
+
'rejected',
|
|
762
|
+
'cancelled',
|
|
763
|
+
])
|
|
764
|
+
.optional()
|
|
765
|
+
.describe('Filter by invoice status'),
|
|
766
|
+
direction: z
|
|
767
|
+
.enum(['incoming', 'outgoing'])
|
|
768
|
+
.optional()
|
|
769
|
+
.describe('Filter by direction'),
|
|
770
|
+
from: z.string().optional().describe('Start date (YYYY-MM-DD)'),
|
|
771
|
+
to: z.string().optional().describe('End date (YYYY-MM-DD)'),
|
|
772
|
+
clientId: z.string().optional().describe('Filter by client UUID'),
|
|
773
|
+
sort: z
|
|
774
|
+
.enum(['issueDate', 'number', 'total', 'dueDate'])
|
|
775
|
+
.optional()
|
|
776
|
+
.describe('Sort field'),
|
|
777
|
+
order: z.enum(['asc', 'desc']).optional().describe('Sort order'),
|
|
778
|
+
}),
|
|
779
|
+
handler: async (params) => {
|
|
780
|
+
if (!getConfig().token)
|
|
781
|
+
return notAuthenticated();
|
|
782
|
+
const companyId = getCompanyId(params);
|
|
783
|
+
if (!companyId)
|
|
784
|
+
return noCompanySelected();
|
|
785
|
+
const { search, status, direction, from, to, clientId, sort, order } = params;
|
|
786
|
+
const result = await apiRequest('/api/v1/invoices/export/csv', {
|
|
787
|
+
companyId,
|
|
788
|
+
query: { search, status, direction, from, to, clientId, sort, order },
|
|
789
|
+
});
|
|
790
|
+
return formatResponse(result);
|
|
791
|
+
},
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
name: 'invoices_export_zip',
|
|
795
|
+
description: 'Export a set of invoices (by UUID list) to a ZIP archive containing PDFs, XMLs, and a CSV summary. Processed asynchronously — returns an exportId and statusUrl. Poll the statusUrl or wait for webhook. Requires Pro plan. Max 100 invoices per export.',
|
|
796
|
+
inputSchema: z.object({
|
|
797
|
+
invoiceIds: z
|
|
798
|
+
.array(z.string())
|
|
799
|
+
.max(100)
|
|
800
|
+
.describe('Array of invoice UUIDs to include in the ZIP (max 100)'),
|
|
801
|
+
companyId: z
|
|
802
|
+
.string()
|
|
803
|
+
.optional()
|
|
804
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
805
|
+
includePdf: z
|
|
806
|
+
.boolean()
|
|
807
|
+
.optional()
|
|
808
|
+
.describe('Include PDF files in ZIP (default: true, requires Pro plan)'),
|
|
809
|
+
includeXml: z
|
|
810
|
+
.boolean()
|
|
811
|
+
.optional()
|
|
812
|
+
.describe('Include UBL XML files in ZIP (default: true)'),
|
|
813
|
+
includeCsv: z
|
|
814
|
+
.boolean()
|
|
815
|
+
.optional()
|
|
816
|
+
.describe('Include CSV summary in ZIP (default: true)'),
|
|
817
|
+
folderStructure: z
|
|
818
|
+
.enum(['flat', 'by-client', 'by-month', 'by-series'])
|
|
819
|
+
.optional()
|
|
820
|
+
.describe('ZIP folder organization: flat (default), by-client, by-month, or by-series'),
|
|
821
|
+
}),
|
|
822
|
+
handler: async (params) => {
|
|
823
|
+
if (!getConfig().token)
|
|
824
|
+
return notAuthenticated();
|
|
825
|
+
const companyId = getCompanyId(params);
|
|
826
|
+
if (!companyId)
|
|
827
|
+
return noCompanySelected();
|
|
828
|
+
const { invoiceIds, includePdf, includeXml, includeCsv, folderStructure } = params;
|
|
829
|
+
const body = { invoiceIds };
|
|
830
|
+
if (includePdf !== undefined)
|
|
831
|
+
body.includePdf = includePdf;
|
|
832
|
+
if (includeXml !== undefined)
|
|
833
|
+
body.includeXml = includeXml;
|
|
834
|
+
if (includeCsv !== undefined)
|
|
835
|
+
body.includeCsv = includeCsv;
|
|
836
|
+
if (folderStructure !== undefined)
|
|
837
|
+
body.folderStructure = folderStructure;
|
|
838
|
+
const result = await apiRequest('/api/v1/invoices/export/zip', {
|
|
839
|
+
method: 'POST',
|
|
840
|
+
companyId,
|
|
841
|
+
body,
|
|
842
|
+
});
|
|
843
|
+
return formatResponse(result);
|
|
844
|
+
},
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
name: 'invoices_bulk_delete',
|
|
848
|
+
description: 'Delete multiple draft invoices in batch. Only invoices with status "draft" can be deleted. This action is irreversible. Returns count of deleted invoices and any per-item errors.',
|
|
849
|
+
inputSchema: z.object({
|
|
850
|
+
ids: z
|
|
851
|
+
.array(z.string())
|
|
852
|
+
.min(1)
|
|
853
|
+
.max(100)
|
|
854
|
+
.describe('Array of invoice UUIDs to delete (1–100). Only draft invoices are eligible.'),
|
|
855
|
+
companyId: z
|
|
856
|
+
.string()
|
|
857
|
+
.optional()
|
|
858
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
859
|
+
}),
|
|
860
|
+
handler: async (params) => {
|
|
861
|
+
if (!getConfig().token)
|
|
862
|
+
return notAuthenticated();
|
|
863
|
+
const companyId = getCompanyId(params);
|
|
864
|
+
if (!companyId)
|
|
865
|
+
return noCompanySelected();
|
|
866
|
+
const { ids } = params;
|
|
867
|
+
const result = await apiRequest('/api/v1/invoices/bulk-delete', {
|
|
868
|
+
method: 'POST',
|
|
869
|
+
companyId,
|
|
870
|
+
body: { ids },
|
|
871
|
+
});
|
|
872
|
+
return formatResponse(result);
|
|
873
|
+
},
|
|
874
|
+
},
|
|
875
|
+
{
|
|
876
|
+
name: 'invoices_bulk_cancel',
|
|
877
|
+
description: 'Cancel multiple invoices in batch with an optional reason. Returns count of cancelled invoices and any per-item errors.',
|
|
878
|
+
inputSchema: z.object({
|
|
879
|
+
ids: z
|
|
880
|
+
.array(z.string())
|
|
881
|
+
.min(1)
|
|
882
|
+
.max(100)
|
|
883
|
+
.describe('Array of invoice UUIDs to cancel (1–100)'),
|
|
884
|
+
reason: z
|
|
885
|
+
.string()
|
|
886
|
+
.optional()
|
|
887
|
+
.describe('Reason for cancellation applied to all invoices in the batch'),
|
|
888
|
+
companyId: z
|
|
889
|
+
.string()
|
|
890
|
+
.optional()
|
|
891
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
892
|
+
}),
|
|
893
|
+
handler: async (params) => {
|
|
894
|
+
if (!getConfig().token)
|
|
895
|
+
return notAuthenticated();
|
|
896
|
+
const companyId = getCompanyId(params);
|
|
897
|
+
if (!companyId)
|
|
898
|
+
return noCompanySelected();
|
|
899
|
+
const { ids, reason } = params;
|
|
900
|
+
const body = { ids };
|
|
901
|
+
if (reason !== undefined)
|
|
902
|
+
body.reason = reason;
|
|
903
|
+
const result = await apiRequest('/api/v1/invoices/bulk-cancel', {
|
|
904
|
+
method: 'POST',
|
|
905
|
+
companyId,
|
|
906
|
+
body,
|
|
907
|
+
});
|
|
908
|
+
return formatResponse(result);
|
|
909
|
+
},
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
name: 'invoices_bulk_storno',
|
|
913
|
+
description: 'Create storno (refund/credit note) invoices for multiple invoices in batch. Only outgoing invoices with status "issued" or "validated" are eligible. Returns count of created storno invoices and any per-item errors.',
|
|
914
|
+
inputSchema: z.object({
|
|
915
|
+
ids: z
|
|
916
|
+
.array(z.string())
|
|
917
|
+
.min(1)
|
|
918
|
+
.max(100)
|
|
919
|
+
.describe('Array of invoice UUIDs to storno (1–100). Only outgoing, issued/validated invoices are eligible.'),
|
|
920
|
+
companyId: z
|
|
921
|
+
.string()
|
|
922
|
+
.optional()
|
|
923
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
924
|
+
}),
|
|
925
|
+
handler: async (params) => {
|
|
926
|
+
if (!getConfig().token)
|
|
927
|
+
return notAuthenticated();
|
|
928
|
+
const companyId = getCompanyId(params);
|
|
929
|
+
if (!companyId)
|
|
930
|
+
return noCompanySelected();
|
|
931
|
+
const { ids } = params;
|
|
932
|
+
const result = await apiRequest('/api/v1/invoices/bulk-storno', {
|
|
933
|
+
method: 'POST',
|
|
934
|
+
companyId,
|
|
935
|
+
body: { ids },
|
|
936
|
+
});
|
|
937
|
+
return formatResponse(result);
|
|
938
|
+
},
|
|
939
|
+
},
|
|
940
|
+
{
|
|
941
|
+
name: 'invoices_bulk_mark_paid',
|
|
942
|
+
description: 'Mark multiple invoices as fully paid in batch. Creates payment records for each invoice\'s remaining balance. paymentMethod defaults to "bank_transfer". Returns count of updated invoices and any per-item errors.',
|
|
943
|
+
inputSchema: z.object({
|
|
944
|
+
ids: z
|
|
945
|
+
.array(z.string())
|
|
946
|
+
.min(1)
|
|
947
|
+
.max(100)
|
|
948
|
+
.describe('Array of invoice UUIDs to mark as paid (1–100)'),
|
|
949
|
+
paymentMethod: z
|
|
950
|
+
.string()
|
|
951
|
+
.optional()
|
|
952
|
+
.describe('Payment method applied to all invoices (default: bank_transfer)'),
|
|
953
|
+
paidAt: z
|
|
954
|
+
.string()
|
|
955
|
+
.optional()
|
|
956
|
+
.describe('Payment date in ISO 8601 format (YYYY-MM-DD). Defaults to today.'),
|
|
957
|
+
companyId: z
|
|
958
|
+
.string()
|
|
959
|
+
.optional()
|
|
960
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
961
|
+
}),
|
|
962
|
+
handler: async (params) => {
|
|
963
|
+
if (!getConfig().token)
|
|
964
|
+
return notAuthenticated();
|
|
965
|
+
const companyId = getCompanyId(params);
|
|
966
|
+
if (!companyId)
|
|
967
|
+
return noCompanySelected();
|
|
968
|
+
const { ids, paymentMethod, paidAt } = params;
|
|
969
|
+
const body = { ids };
|
|
970
|
+
if (paymentMethod !== undefined)
|
|
971
|
+
body.paymentMethod = paymentMethod;
|
|
972
|
+
if (paidAt !== undefined)
|
|
973
|
+
body.paidAt = paidAt;
|
|
974
|
+
const result = await apiRequest('/api/v1/invoices/bulk-mark-paid', {
|
|
975
|
+
method: 'POST',
|
|
976
|
+
companyId,
|
|
977
|
+
body,
|
|
978
|
+
});
|
|
979
|
+
return formatResponse(result);
|
|
980
|
+
},
|
|
981
|
+
},
|
|
982
|
+
{
|
|
983
|
+
name: 'invoices_export_saga_xml',
|
|
984
|
+
description: 'Export invoices in Saga XML format for accounting software integration (e.g., Saga C). Accepts the same filters as invoices_export_csv. Returns XML text content.',
|
|
985
|
+
inputSchema: z.object({
|
|
986
|
+
companyId: z
|
|
987
|
+
.string()
|
|
988
|
+
.optional()
|
|
989
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
990
|
+
search: z.string().optional().describe('Search term for invoice number or client name'),
|
|
991
|
+
status: z
|
|
992
|
+
.enum([
|
|
993
|
+
'draft',
|
|
994
|
+
'issued',
|
|
995
|
+
'sent_to_provider',
|
|
996
|
+
'validated',
|
|
997
|
+
'rejected',
|
|
998
|
+
'cancelled',
|
|
999
|
+
])
|
|
1000
|
+
.optional()
|
|
1001
|
+
.describe('Filter by invoice status'),
|
|
1002
|
+
direction: z
|
|
1003
|
+
.enum(['incoming', 'outgoing'])
|
|
1004
|
+
.optional()
|
|
1005
|
+
.describe('Filter by direction'),
|
|
1006
|
+
from: z.string().optional().describe('Start date (YYYY-MM-DD)'),
|
|
1007
|
+
to: z.string().optional().describe('End date (YYYY-MM-DD)'),
|
|
1008
|
+
clientId: z.string().optional().describe('Filter by client UUID'),
|
|
1009
|
+
sort: z
|
|
1010
|
+
.enum(['issueDate', 'number', 'total', 'dueDate'])
|
|
1011
|
+
.optional()
|
|
1012
|
+
.describe('Sort field'),
|
|
1013
|
+
order: z.enum(['asc', 'desc']).optional().describe('Sort order'),
|
|
1014
|
+
}),
|
|
1015
|
+
handler: async (params) => {
|
|
1016
|
+
if (!getConfig().token)
|
|
1017
|
+
return notAuthenticated();
|
|
1018
|
+
const companyId = getCompanyId(params);
|
|
1019
|
+
if (!companyId)
|
|
1020
|
+
return noCompanySelected();
|
|
1021
|
+
const { search, status, direction, from, to, clientId, sort, order } = params;
|
|
1022
|
+
const result = await apiRequest('/api/v1/invoices/export/saga-xml', {
|
|
1023
|
+
companyId,
|
|
1024
|
+
query: { search, status, direction, from, to, clientId, sort, order },
|
|
1025
|
+
});
|
|
1026
|
+
return formatResponse(result);
|
|
1027
|
+
},
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
name: 'invoices_export_receipts_saga_xml',
|
|
1031
|
+
description: 'Export payment receipts (incasari) in Saga XML format. Exports all outgoing invoice payments for accounting software integration.',
|
|
1032
|
+
inputSchema: z.object({
|
|
1033
|
+
companyId: z
|
|
1034
|
+
.string()
|
|
1035
|
+
.optional()
|
|
1036
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
1037
|
+
}),
|
|
1038
|
+
handler: async (params) => {
|
|
1039
|
+
if (!getConfig().token)
|
|
1040
|
+
return notAuthenticated();
|
|
1041
|
+
const companyId = getCompanyId(params);
|
|
1042
|
+
if (!companyId)
|
|
1043
|
+
return noCompanySelected();
|
|
1044
|
+
const result = await apiRequest('/api/v1/invoices/export/receipts-saga-xml', {
|
|
1045
|
+
companyId,
|
|
1046
|
+
});
|
|
1047
|
+
return formatResponse(result);
|
|
1048
|
+
},
|
|
1049
|
+
},
|
|
1050
|
+
{
|
|
1051
|
+
name: 'invoices_export_payments_saga_xml',
|
|
1052
|
+
description: 'Export supplier payments (plati) in Saga XML format. Exports all incoming invoice payments for accounting software integration.',
|
|
1053
|
+
inputSchema: z.object({
|
|
1054
|
+
companyId: z
|
|
1055
|
+
.string()
|
|
1056
|
+
.optional()
|
|
1057
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
1058
|
+
}),
|
|
1059
|
+
handler: async (params) => {
|
|
1060
|
+
if (!getConfig().token)
|
|
1061
|
+
return notAuthenticated();
|
|
1062
|
+
const companyId = getCompanyId(params);
|
|
1063
|
+
if (!companyId)
|
|
1064
|
+
return noCompanySelected();
|
|
1065
|
+
const result = await apiRequest('/api/v1/invoices/export/payments-saga-xml', {
|
|
1066
|
+
companyId,
|
|
1067
|
+
});
|
|
1068
|
+
return formatResponse(result);
|
|
1069
|
+
},
|
|
1070
|
+
},
|
|
1071
|
+
{
|
|
1072
|
+
name: 'invoices_export_efactura_zip',
|
|
1073
|
+
description: 'Export e-Factura XML files as a ZIP archive. For large batches (>100 invoices), the export is processed asynchronously and returns a job ID to poll for completion.',
|
|
1074
|
+
inputSchema: z.object({
|
|
1075
|
+
direction: z
|
|
1076
|
+
.enum(['outgoing', 'incoming'])
|
|
1077
|
+
.describe('Invoice direction to export'),
|
|
1078
|
+
dateFrom: z
|
|
1079
|
+
.string()
|
|
1080
|
+
.optional()
|
|
1081
|
+
.describe('Start date filter in ISO 8601 format (YYYY-MM-DD)'),
|
|
1082
|
+
dateTo: z
|
|
1083
|
+
.string()
|
|
1084
|
+
.optional()
|
|
1085
|
+
.describe('End date filter in ISO 8601 format (YYYY-MM-DD)'),
|
|
1086
|
+
companyId: z
|
|
1087
|
+
.string()
|
|
1088
|
+
.optional()
|
|
1089
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
1090
|
+
}),
|
|
1091
|
+
handler: async (params) => {
|
|
1092
|
+
if (!getConfig().token)
|
|
1093
|
+
return notAuthenticated();
|
|
1094
|
+
const companyId = getCompanyId(params);
|
|
1095
|
+
if (!companyId)
|
|
1096
|
+
return noCompanySelected();
|
|
1097
|
+
const { direction, dateFrom, dateTo } = params;
|
|
1098
|
+
const body = { direction };
|
|
1099
|
+
if (dateFrom !== undefined)
|
|
1100
|
+
body.dateFrom = dateFrom;
|
|
1101
|
+
if (dateTo !== undefined)
|
|
1102
|
+
body.dateTo = dateTo;
|
|
1103
|
+
const result = await apiRequest('/api/v1/invoices/export/efactura-zip', {
|
|
1104
|
+
method: 'POST',
|
|
1105
|
+
companyId,
|
|
1106
|
+
body,
|
|
1107
|
+
});
|
|
1108
|
+
return formatResponse(result);
|
|
1109
|
+
},
|
|
1110
|
+
},
|
|
1111
|
+
{
|
|
1112
|
+
name: 'invoices_share_links_list',
|
|
1113
|
+
description: 'List all share links for an invoice, including view counts, expiry info, and status (active/revoked/expired).',
|
|
1114
|
+
inputSchema: z.object({
|
|
1115
|
+
uuid: z.string().describe('Invoice UUID'),
|
|
1116
|
+
companyId: z
|
|
1117
|
+
.string()
|
|
1118
|
+
.optional()
|
|
1119
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
1120
|
+
}),
|
|
1121
|
+
handler: async (params) => {
|
|
1122
|
+
if (!getConfig().token)
|
|
1123
|
+
return notAuthenticated();
|
|
1124
|
+
const companyId = getCompanyId(params);
|
|
1125
|
+
if (!companyId)
|
|
1126
|
+
return noCompanySelected();
|
|
1127
|
+
const { uuid } = params;
|
|
1128
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/share-links`, { companyId });
|
|
1129
|
+
return formatResponse(result);
|
|
1130
|
+
},
|
|
1131
|
+
},
|
|
1132
|
+
{
|
|
1133
|
+
name: 'invoices_share_links_create',
|
|
1134
|
+
description: 'Create a new shareable link for an invoice. Returns the share URL, token, and expiry date. The link allows the recipient to view the invoice without authentication.',
|
|
1135
|
+
inputSchema: z.object({
|
|
1136
|
+
uuid: z.string().describe('Invoice UUID'),
|
|
1137
|
+
expiryDays: z
|
|
1138
|
+
.number()
|
|
1139
|
+
.int()
|
|
1140
|
+
.optional()
|
|
1141
|
+
.describe('Number of days until the link expires (default: 30)'),
|
|
1142
|
+
companyId: z
|
|
1143
|
+
.string()
|
|
1144
|
+
.optional()
|
|
1145
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
1146
|
+
}),
|
|
1147
|
+
handler: async (params) => {
|
|
1148
|
+
if (!getConfig().token)
|
|
1149
|
+
return notAuthenticated();
|
|
1150
|
+
const companyId = getCompanyId(params);
|
|
1151
|
+
if (!companyId)
|
|
1152
|
+
return noCompanySelected();
|
|
1153
|
+
const { uuid, expiryDays } = params;
|
|
1154
|
+
const body = {};
|
|
1155
|
+
if (expiryDays !== undefined)
|
|
1156
|
+
body.expiryDays = expiryDays;
|
|
1157
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/share-links`, {
|
|
1158
|
+
method: 'POST',
|
|
1159
|
+
companyId,
|
|
1160
|
+
body,
|
|
1161
|
+
});
|
|
1162
|
+
return formatResponse(result);
|
|
1163
|
+
},
|
|
1164
|
+
},
|
|
1165
|
+
{
|
|
1166
|
+
name: 'invoices_share_links_revoke',
|
|
1167
|
+
description: 'Revoke/delete a share link for an invoice, making it permanently inaccessible. Get linkId from invoices_share_links_list.',
|
|
1168
|
+
inputSchema: z.object({
|
|
1169
|
+
uuid: z.string().describe('Invoice UUID'),
|
|
1170
|
+
linkId: z.string().describe('Share link ID to revoke (from invoices_share_links_list)'),
|
|
1171
|
+
companyId: z
|
|
1172
|
+
.string()
|
|
1173
|
+
.optional()
|
|
1174
|
+
.describe('Company UUID override (uses active company if not set)'),
|
|
1175
|
+
}),
|
|
1176
|
+
handler: async (params) => {
|
|
1177
|
+
if (!getConfig().token)
|
|
1178
|
+
return notAuthenticated();
|
|
1179
|
+
const companyId = getCompanyId(params);
|
|
1180
|
+
if (!companyId)
|
|
1181
|
+
return noCompanySelected();
|
|
1182
|
+
const { uuid, linkId } = params;
|
|
1183
|
+
const result = await apiRequest(`/api/v1/invoices/${uuid}/share-links/${linkId}`, {
|
|
1184
|
+
method: 'DELETE',
|
|
1185
|
+
companyId,
|
|
1186
|
+
});
|
|
1187
|
+
return formatResponse(result);
|
|
1188
|
+
},
|
|
1189
|
+
},
|
|
1190
|
+
];
|
|
1191
|
+
//# sourceMappingURL=invoices.js.map
|