@pimia/sdk 0.2.0 → 0.3.0
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/README.md +57 -0
- package/dist/api.d.ts +150 -254
- package/dist/client.d.ts +382 -11
- package/dist/client.js +27 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/webhooks.d.ts +305 -0
- package/dist/webhooks.js +230 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,6 +92,63 @@ if (meta.idempotentReplay) {
|
|
|
92
92
|
}
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
+
## Recibir webhooks
|
|
96
|
+
|
|
97
|
+
`verifyWebhook` comprueba la firma `PIMIA-WEBHOOK-v1` y te devuelve el evento
|
|
98
|
+
tipado. No reimplementes el HMAC:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import express from 'express'
|
|
102
|
+
import { verifyWebhook, WebhookVerificationError } from '@pimia/sdk'
|
|
103
|
+
|
|
104
|
+
// ⚠️ express.raw(), NO express.json(): Pimia firma los bytes que envía, y
|
|
105
|
+
// parsear + volver a serializar rompe la firma sin que se vea por qué.
|
|
106
|
+
app.post('/pimia', express.raw({ type: 'application/json' }), async (req, res) => {
|
|
107
|
+
let hook
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
hook = await verifyWebhook({
|
|
111
|
+
secret: process.env.PIMIA_WEBHOOK_SECRET,
|
|
112
|
+
headers: req.headers,
|
|
113
|
+
body: req.body,
|
|
114
|
+
})
|
|
115
|
+
} catch (error) {
|
|
116
|
+
return res.status(400).send((error as WebhookVerificationError).reason)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Pimia reintenta: la misma entrega llega con el mismo `delivery`.
|
|
120
|
+
// Procesar cada uno una sola vez es todo el exactly-once que necesitas.
|
|
121
|
+
if (await yaProcesado(hook.delivery)) return res.sendStatus(200)
|
|
122
|
+
|
|
123
|
+
if (hook.known) {
|
|
124
|
+
switch (hook.event) {
|
|
125
|
+
case 'estimate.accepted':
|
|
126
|
+
await facturar(hook.payload.id) // payload tipado, sin castings
|
|
127
|
+
break
|
|
128
|
+
case 'invoice.paid':
|
|
129
|
+
await cobrar(hook.payload.id)
|
|
130
|
+
break
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
res.sendStatus(200) // responde rápido; el trabajo pesado, a una cola
|
|
135
|
+
})
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Los ocho eventos del catálogo (`approval.decided`, `invoice.received`,
|
|
139
|
+
`app.revoked`, `customer.created`, `customer.updated`, `invoice.created`,
|
|
140
|
+
`estimate.accepted`, `invoice.paid`) vienen tipados. Uno que este SDK todavía
|
|
141
|
+
no conozca **no es un error**: se verifica igual y llega con `known: false`.
|
|
142
|
+
|
|
143
|
+
Detalles que ahorran un rato:
|
|
144
|
+
|
|
145
|
+
- `secret` acepta una **lista** de secretos, para rotarlo sin ventana de caída.
|
|
146
|
+
- La ventana anti-replay son 300 s; ajústala con `toleranceSeconds`.
|
|
147
|
+
- Los errores traen un `reason` (`signature_mismatch`, `timestamp_out_of_window`,
|
|
148
|
+
`missing_headers`, `invalid_timestamp`, `invalid_json`) para tus métricas.
|
|
149
|
+
- `signWebhook()` firma un cuerpo como lo haría Pimia: úsalo en **tus tests**,
|
|
150
|
+
no en producción.
|
|
151
|
+
|
|
95
152
|
## Más
|
|
96
153
|
|
|
97
154
|
Documentación completa, modelo mental (un tenant = una base URL = un token),
|
package/dist/api.d.ts
CHANGED
|
@@ -121,54 +121,6 @@ export interface paths {
|
|
|
121
121
|
patch?: never;
|
|
122
122
|
trace?: never;
|
|
123
123
|
};
|
|
124
|
-
"/auth/login": {
|
|
125
|
-
parameters: {
|
|
126
|
-
query?: never;
|
|
127
|
-
header?: never;
|
|
128
|
-
path?: never;
|
|
129
|
-
cookie?: never;
|
|
130
|
-
};
|
|
131
|
-
get?: never;
|
|
132
|
-
put?: never;
|
|
133
|
-
post: operations["auth.login"];
|
|
134
|
-
delete?: never;
|
|
135
|
-
options?: never;
|
|
136
|
-
head?: never;
|
|
137
|
-
patch?: never;
|
|
138
|
-
trace?: never;
|
|
139
|
-
};
|
|
140
|
-
"/auth/logout": {
|
|
141
|
-
parameters: {
|
|
142
|
-
query?: never;
|
|
143
|
-
header?: never;
|
|
144
|
-
path?: never;
|
|
145
|
-
cookie?: never;
|
|
146
|
-
};
|
|
147
|
-
get?: never;
|
|
148
|
-
put?: never;
|
|
149
|
-
post: operations["auth.logout"];
|
|
150
|
-
delete?: never;
|
|
151
|
-
options?: never;
|
|
152
|
-
head?: never;
|
|
153
|
-
patch?: never;
|
|
154
|
-
trace?: never;
|
|
155
|
-
};
|
|
156
|
-
"/auth/check": {
|
|
157
|
-
parameters: {
|
|
158
|
-
query?: never;
|
|
159
|
-
header?: never;
|
|
160
|
-
path?: never;
|
|
161
|
-
cookie?: never;
|
|
162
|
-
};
|
|
163
|
-
get: operations["auth.check"];
|
|
164
|
-
put?: never;
|
|
165
|
-
post?: never;
|
|
166
|
-
delete?: never;
|
|
167
|
-
options?: never;
|
|
168
|
-
head?: never;
|
|
169
|
-
patch?: never;
|
|
170
|
-
trace?: never;
|
|
171
|
-
};
|
|
172
124
|
"/bank-accounts": {
|
|
173
125
|
parameters: {
|
|
174
126
|
query?: never;
|
|
@@ -278,7 +230,10 @@ export interface paths {
|
|
|
278
230
|
};
|
|
279
231
|
get?: never;
|
|
280
232
|
put?: never;
|
|
281
|
-
/**
|
|
233
|
+
/**
|
|
234
|
+
* Handle the incoming request
|
|
235
|
+
* @description **No disponible para integradores.** Exige `settings:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
|
|
236
|
+
*/
|
|
282
237
|
post: operations["general.bulkExchangeRate"];
|
|
283
238
|
delete?: never;
|
|
284
239
|
options?: never;
|
|
@@ -498,7 +453,10 @@ export interface paths {
|
|
|
498
453
|
/** Display a listing of the resource */
|
|
499
454
|
get: operations["custom-fields.index"];
|
|
500
455
|
put?: never;
|
|
501
|
-
/**
|
|
456
|
+
/**
|
|
457
|
+
* Store a newly created resource in storage
|
|
458
|
+
* @description **No disponible para integradores.** Exige `settings:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
|
|
459
|
+
*/
|
|
502
460
|
post: operations["custom-fields.store"];
|
|
503
461
|
delete?: never;
|
|
504
462
|
options?: never;
|
|
@@ -515,10 +473,16 @@ export interface paths {
|
|
|
515
473
|
};
|
|
516
474
|
/** Display the specified resource */
|
|
517
475
|
get: operations["custom-fields.show"];
|
|
518
|
-
/**
|
|
476
|
+
/**
|
|
477
|
+
* Update the specified resource in storage
|
|
478
|
+
* @description **No disponible para integradores.** Exige `settings:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
|
|
479
|
+
*/
|
|
519
480
|
put: operations["custom-fields.update"];
|
|
520
481
|
post?: never;
|
|
521
|
-
/**
|
|
482
|
+
/**
|
|
483
|
+
* Remove the specified resource from storage
|
|
484
|
+
* @description **No disponible para integradores.** Exige `settings:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
|
|
485
|
+
*/
|
|
522
486
|
delete: operations["custom-fields.destroy"];
|
|
523
487
|
options?: never;
|
|
524
488
|
head?: never;
|
|
@@ -906,23 +870,6 @@ export interface paths {
|
|
|
906
870
|
trace?: never;
|
|
907
871
|
};
|
|
908
872
|
"/fiscal-quarters/toggle": {
|
|
909
|
-
parameters: {
|
|
910
|
-
query?: never;
|
|
911
|
-
header?: never;
|
|
912
|
-
path?: never;
|
|
913
|
-
cookie?: never;
|
|
914
|
-
};
|
|
915
|
-
get?: never;
|
|
916
|
-
put?: never;
|
|
917
|
-
/** Toggle lock state for a quarter */
|
|
918
|
-
post: operations["fiscalQuarter.toggle"];
|
|
919
|
-
delete?: never;
|
|
920
|
-
options?: never;
|
|
921
|
-
head?: never;
|
|
922
|
-
patch?: never;
|
|
923
|
-
trace?: never;
|
|
924
|
-
};
|
|
925
|
-
"/auth/password/email": {
|
|
926
873
|
parameters: {
|
|
927
874
|
query?: never;
|
|
928
875
|
header?: never;
|
|
@@ -932,14 +879,10 @@ export interface paths {
|
|
|
932
879
|
get?: never;
|
|
933
880
|
put?: never;
|
|
934
881
|
/**
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
* generador del OpenAPI no la ve y este endpoint se publicaba sin cuerpo.
|
|
938
|
-
* Mismas reglas (`required|email`)
|
|
939
|
-
* @description La RESPUESTA, en cambio, ya no es la del trait: es SIEMPRE la misma,
|
|
940
|
-
* exista el correo o no. Ver `respuestaNeutra()`.
|
|
882
|
+
* Toggle lock state for a quarter
|
|
883
|
+
* @description **No disponible para integradores.** Exige `reports:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
|
|
941
884
|
*/
|
|
942
|
-
post: operations["
|
|
885
|
+
post: operations["fiscalQuarter.toggle"];
|
|
943
886
|
delete?: never;
|
|
944
887
|
options?: never;
|
|
945
888
|
head?: never;
|
|
@@ -1597,7 +1540,31 @@ export interface paths {
|
|
|
1597
1540
|
path?: never;
|
|
1598
1541
|
cookie?: never;
|
|
1599
1542
|
};
|
|
1600
|
-
/**
|
|
1543
|
+
/**
|
|
1544
|
+
* Siguiente número de documento (orientativo, NO lo reserva)
|
|
1545
|
+
* @description Calcula al vuelo qué número le tocaría al próximo documento del tipo pedido, con el
|
|
1546
|
+
* formato de numeración configurado por la empresa. Es lo que el panel pinta en el
|
|
1547
|
+
* formulario antes de guardar.
|
|
1548
|
+
*
|
|
1549
|
+
* **No reserva nada y no es determinista.** No consume secuencia: dos llamadas
|
|
1550
|
+
* seguidas —o dos integradores a la vez— reciben el MISMO número, y quien guarde
|
|
1551
|
+
* primero se lo queda; el segundo se estrella contra el `unique` con un `422`.
|
|
1552
|
+
* El valor caduca en cuanto alguien crea un documento de ese tipo.
|
|
1553
|
+
*
|
|
1554
|
+
* **No lo necesitas para escribir, y usarlo para eso te perjudica.** Desde el
|
|
1555
|
+
* 2026-08-10 ninguna alta exige que el número lo pongas tú: `invoice_number`,
|
|
1556
|
+
* `estimate_number`, `payment_number` y `received_invoice_number` son opcionales y,
|
|
1557
|
+
* si no llegan, los asigna el servidor con este mismo formateador ya dentro de la
|
|
1558
|
+
* transacción que escribe. Pedir el número aquí para reenviarlo en el cuerpo solo
|
|
1559
|
+
* añade una carrera que el servidor no tiene, y de paso rompe la reproducibilidad
|
|
1560
|
+
* del cuerpo entre reintentos con `Idempotency-Key` (guía del integrador §7).
|
|
1561
|
+
* Su uso legítimo es previsualizar en una interfaz el número que le tocaría al
|
|
1562
|
+
* documento — para eso lo llama el panel.
|
|
1563
|
+
*
|
|
1564
|
+
* **Comprueba `success` antes de leer `nextNumber`.** Un fallo llega con `200` y el
|
|
1565
|
+
* sobre `{"success": false, "message": "..."}`; desestructurar `nextNumber` a ciegas
|
|
1566
|
+
* degrada en silencio a `null`.
|
|
1567
|
+
*/
|
|
1601
1568
|
get: operations["general.nextNumber"];
|
|
1602
1569
|
put?: never;
|
|
1603
1570
|
post?: never;
|
|
@@ -2195,23 +2162,6 @@ export interface paths {
|
|
|
2195
2162
|
patch?: never;
|
|
2196
2163
|
trace?: never;
|
|
2197
2164
|
};
|
|
2198
|
-
"/auth/reset/password": {
|
|
2199
|
-
parameters: {
|
|
2200
|
-
query?: never;
|
|
2201
|
-
header?: never;
|
|
2202
|
-
path?: never;
|
|
2203
|
-
cookie?: never;
|
|
2204
|
-
};
|
|
2205
|
-
get?: never;
|
|
2206
|
-
put?: never;
|
|
2207
|
-
/** Reset the given user's password */
|
|
2208
|
-
post: operations["resetPassword.reset"];
|
|
2209
|
-
delete?: never;
|
|
2210
|
-
options?: never;
|
|
2211
|
-
head?: never;
|
|
2212
|
-
patch?: never;
|
|
2213
|
-
trace?: never;
|
|
2214
|
-
};
|
|
2215
2165
|
"/search": {
|
|
2216
2166
|
parameters: {
|
|
2217
2167
|
query?: never;
|
|
@@ -2538,7 +2488,9 @@ export interface paths {
|
|
|
2538
2488
|
put?: never;
|
|
2539
2489
|
/**
|
|
2540
2490
|
* POST tasks/{task}/delegate — delega esta tarea CRM a su agente Pim
|
|
2541
|
-
* @description
|
|
2491
|
+
* @description **No disponible para integradores.** Exige `delegation:write`, que el Authorization Server de Pimia no emite: la acción la realiza el dueño desde su panel y un token de partner recibe `403`. Aparece en el contrato para que el hueco sea explícito, no para que se llame.
|
|
2492
|
+
*
|
|
2493
|
+
* Reusa el plano async `delegated_tasks` (el mismo que ya cierra el round-trip
|
|
2542
2494
|
* delegar→agente→callback→sello): compone un context rico desde la tarea (título,
|
|
2543
2495
|
* descripción y el lead/cliente/proyecto vinculado con sus datos), crea la
|
|
2544
2496
|
* delegación, la entrega al Kanban del Copilot y la enlaza con la tarea.
|
|
@@ -3153,6 +3105,13 @@ export interface components {
|
|
|
3153
3105
|
phone?: string | null;
|
|
3154
3106
|
fax?: string | null;
|
|
3155
3107
|
};
|
|
3108
|
+
/** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
|
|
3109
|
+
customFields?: {
|
|
3110
|
+
/** @description Id de la definición del campo personalizado. */
|
|
3111
|
+
id: number;
|
|
3112
|
+
/** @description Valor a guardar. */
|
|
3113
|
+
value: string;
|
|
3114
|
+
}[];
|
|
3156
3115
|
};
|
|
3157
3116
|
/** CustomerResource */
|
|
3158
3117
|
CustomerResource: {
|
|
@@ -3402,6 +3361,13 @@ export interface components {
|
|
|
3402
3361
|
percent?: number | null;
|
|
3403
3362
|
amount?: number | null;
|
|
3404
3363
|
}[] | null;
|
|
3364
|
+
/** @description Valores de campo personalizado DE LA LÍNEA (definiciones con `model_type` `InvoiceItem` o `EstimateItem`). Se acepta también la clave `custom_fields`, la forma histórica del panel. */
|
|
3365
|
+
customFields?: {
|
|
3366
|
+
/** @description Id de la definición del campo personalizado. */
|
|
3367
|
+
id: number;
|
|
3368
|
+
/** @description Valor a guardar. */
|
|
3369
|
+
value: string;
|
|
3370
|
+
}[];
|
|
3405
3371
|
}[];
|
|
3406
3372
|
taxes?: {
|
|
3407
3373
|
tax_type_id?: number | null;
|
|
@@ -3415,6 +3381,13 @@ export interface components {
|
|
|
3415
3381
|
*/
|
|
3416
3382
|
tax_per_item?: string | null;
|
|
3417
3383
|
tax_included?: boolean | null;
|
|
3384
|
+
/** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
|
|
3385
|
+
customFields?: {
|
|
3386
|
+
/** @description Id de la definición del campo personalizado. */
|
|
3387
|
+
id: number;
|
|
3388
|
+
/** @description Valor a guardar. */
|
|
3389
|
+
value: string;
|
|
3390
|
+
}[];
|
|
3418
3391
|
};
|
|
3419
3392
|
/** ExpenseCategoryRequest */
|
|
3420
3393
|
ExpenseCategoryRequest: {
|
|
@@ -3448,6 +3421,10 @@ export interface components {
|
|
|
3448
3421
|
* @description Maximum file size: 20000 kilobytes.
|
|
3449
3422
|
*/
|
|
3450
3423
|
attachment_receipt?: string | null;
|
|
3424
|
+
/** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. En `multipart/form-data` viaja como cadena JSON: `[{"id":3,"value":"REF-42"}]`. */
|
|
3425
|
+
customFields?: string;
|
|
3426
|
+
/** @description Borra el recibo adjunto del gasto. Solo surte efecto en la actualización; en `multipart/form-data` viaja como `1` o `0`. */
|
|
3427
|
+
is_attachment_receipt_removed?: boolean | null;
|
|
3451
3428
|
};
|
|
3452
3429
|
/** ExpenseResource */
|
|
3453
3430
|
ExpenseResource: {
|
|
@@ -3479,23 +3456,6 @@ export interface components {
|
|
|
3479
3456
|
currency?: components["schemas"]["CurrencyResource"];
|
|
3480
3457
|
payment_method?: components["schemas"]["PaymentMethodResource"];
|
|
3481
3458
|
};
|
|
3482
|
-
/**
|
|
3483
|
-
* ForgotPasswordRequest
|
|
3484
|
-
* @description Envío del enlace de restablecimiento (`POST /auth/password/email`).
|
|
3485
|
-
*
|
|
3486
|
-
* Mismas reglas que el `validateEmail()` del trait
|
|
3487
|
-
* `Illuminate\Foundation\Auth\SendsPasswordResetEmails` (laravel/ui), palabra
|
|
3488
|
-
* por palabra. Estaban ahí dentro y por eso el OpenAPI publicaba este endpoint
|
|
3489
|
-
* sin cuerpo: el generador solo mira la acción del controlador, y la acción
|
|
3490
|
-
* venía entera del trait.
|
|
3491
|
-
*/
|
|
3492
|
-
ForgotPasswordRequest: {
|
|
3493
|
-
/**
|
|
3494
|
-
* Format: email
|
|
3495
|
-
* @description Correo de la cuenta. La respuesta no distingue si existe o no.
|
|
3496
|
-
*/
|
|
3497
|
-
email: string;
|
|
3498
|
-
};
|
|
3499
3459
|
/** InvestmentAssetResource */
|
|
3500
3460
|
InvestmentAssetResource: {
|
|
3501
3461
|
id: string;
|
|
@@ -3771,6 +3731,13 @@ export interface components {
|
|
|
3771
3731
|
percent?: number | null;
|
|
3772
3732
|
amount?: number | null;
|
|
3773
3733
|
}[] | null;
|
|
3734
|
+
/** @description Valores de campo personalizado DE LA LÍNEA (definiciones con `model_type` `InvoiceItem` o `EstimateItem`). Se acepta también la clave `custom_fields`, la forma histórica del panel. */
|
|
3735
|
+
customFields?: {
|
|
3736
|
+
/** @description Id de la definición del campo personalizado. */
|
|
3737
|
+
id: number;
|
|
3738
|
+
/** @description Valor a guardar. */
|
|
3739
|
+
value: string;
|
|
3740
|
+
}[];
|
|
3774
3741
|
}[];
|
|
3775
3742
|
taxes?: {
|
|
3776
3743
|
tax_type_id?: number | null;
|
|
@@ -3784,6 +3751,13 @@ export interface components {
|
|
|
3784
3751
|
*/
|
|
3785
3752
|
tax_per_item?: string | null;
|
|
3786
3753
|
tax_included?: boolean | null;
|
|
3754
|
+
/** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
|
|
3755
|
+
customFields?: {
|
|
3756
|
+
/** @description Id de la definición del campo personalizado. */
|
|
3757
|
+
id: number;
|
|
3758
|
+
/** @description Valor a guardar. */
|
|
3759
|
+
value: string;
|
|
3760
|
+
}[];
|
|
3787
3761
|
};
|
|
3788
3762
|
/** ItemCategory */
|
|
3789
3763
|
ItemCategory: string[];
|
|
@@ -3841,6 +3815,8 @@ export interface components {
|
|
|
3841
3815
|
stock_alert_qty?: number | null;
|
|
3842
3816
|
allow_sale_without_stock?: boolean | null;
|
|
3843
3817
|
purchase_tax_type_id?: number | null;
|
|
3818
|
+
/** @description Existencias iniciales del artículo. En el alta se guarda 0 si no llega; en la actualización se conserva el valor que ya tenía. */
|
|
3819
|
+
opening_stock?: number | null;
|
|
3844
3820
|
};
|
|
3845
3821
|
/** LeadActivity */
|
|
3846
3822
|
LeadActivity: string[];
|
|
@@ -3920,12 +3896,6 @@ export interface components {
|
|
|
3920
3896
|
name: string;
|
|
3921
3897
|
} | null;
|
|
3922
3898
|
};
|
|
3923
|
-
/** LoginRequest */
|
|
3924
|
-
LoginRequest: {
|
|
3925
|
-
username: string;
|
|
3926
|
-
password: string;
|
|
3927
|
-
device_name: string;
|
|
3928
|
-
};
|
|
3929
3899
|
/** Note */
|
|
3930
3900
|
Note: {
|
|
3931
3901
|
id: number;
|
|
@@ -3958,10 +3928,27 @@ export interface components {
|
|
|
3958
3928
|
customer_id: string;
|
|
3959
3929
|
exchange_rate?: string | null;
|
|
3960
3930
|
amount: number;
|
|
3961
|
-
|
|
3931
|
+
/**
|
|
3932
|
+
* @description Opcional en el alta: si no llega, lo genera el servidor con el mismo
|
|
3933
|
+
* SerialNumberFormatter que alimenta a GET /next-number?key=payment, que es
|
|
3934
|
+
* de donde lo saca el panel. Exigirlo obligaba a un cliente de la API a
|
|
3935
|
+
* replicar el formato de numeración de la empresa, y encima a congelar el
|
|
3936
|
+
* cuerpo entre reintentos: `next-number` no reserva nada, así que pedirlo
|
|
3937
|
+
* dos veces puede dar dos números distintos y el reintento con la misma
|
|
3938
|
+
* Idempotency-Key rebotaba con 422 por «cuerpo distinto».
|
|
3939
|
+
* En PUT sigue siendo obligatorio (más abajo): el pago ya tiene uno.
|
|
3940
|
+
*/
|
|
3941
|
+
payment_number?: string | null;
|
|
3962
3942
|
invoice_id?: string | null;
|
|
3963
3943
|
payment_method_id?: string | null;
|
|
3964
3944
|
notes?: string | null;
|
|
3945
|
+
/** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
|
|
3946
|
+
customFields?: {
|
|
3947
|
+
/** @description Id de la definición del campo personalizado. */
|
|
3948
|
+
id: number;
|
|
3949
|
+
/** @description Valor a guardar. */
|
|
3950
|
+
value: string;
|
|
3951
|
+
}[];
|
|
3965
3952
|
};
|
|
3966
3953
|
/** PaymentResource */
|
|
3967
3954
|
PaymentResource: {
|
|
@@ -4073,7 +4060,18 @@ export interface components {
|
|
|
4073
4060
|
received_invoice_date: string;
|
|
4074
4061
|
due_date?: string | null;
|
|
4075
4062
|
supplier_id: string;
|
|
4076
|
-
|
|
4063
|
+
/**
|
|
4064
|
+
* @description Opcional en el alta: si no llega, lo genera el servidor con el mismo
|
|
4065
|
+
* SerialNumberFormatter que alimenta a GET /next-number?key=received_invoice,
|
|
4066
|
+
* que es de donde lo saca el panel. Es el número del LIBRO DE RECIBIDAS —el
|
|
4067
|
+
* del proveedor va en `reference_number`—, así que numerarlo es cosa nuestra,
|
|
4068
|
+
* no del cliente de la API: exigirlo le obligaba a replicar el formato de la
|
|
4069
|
+
* empresa y a congelar el cuerpo entre reintentos (`next-number` no reserva,
|
|
4070
|
+
* dos llamadas pueden dar números distintos y la misma Idempotency-Key
|
|
4071
|
+
* rebotaba con 422 por «cuerpo distinto»).
|
|
4072
|
+
* En PUT sigue siendo obligatorio (más abajo): la factura ya tiene uno.
|
|
4073
|
+
*/
|
|
4074
|
+
received_invoice_number?: string | null;
|
|
4077
4075
|
exchange_rate?: string | null;
|
|
4078
4076
|
discount: number;
|
|
4079
4077
|
discount_val: number;
|
|
@@ -4216,6 +4214,13 @@ export interface components {
|
|
|
4216
4214
|
*/
|
|
4217
4215
|
tax_per_item?: string | null;
|
|
4218
4216
|
tax_included?: boolean | null;
|
|
4217
|
+
/** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
|
|
4218
|
+
customFields?: {
|
|
4219
|
+
/** @description Id de la definición del campo personalizado. */
|
|
4220
|
+
id: number;
|
|
4221
|
+
/** @description Valor a guardar. */
|
|
4222
|
+
value: string;
|
|
4223
|
+
}[];
|
|
4219
4224
|
};
|
|
4220
4225
|
/** RecurringInvoiceResource */
|
|
4221
4226
|
RecurringInvoiceResource: {
|
|
@@ -4409,6 +4414,13 @@ export interface components {
|
|
|
4409
4414
|
phone?: string | null;
|
|
4410
4415
|
fax?: string | null;
|
|
4411
4416
|
};
|
|
4417
|
+
/** @description Valores de campo personalizado del recurso. `id` es el de la definición, que se descubre en `GET /custom-fields` (catálogo `meta`, legible con cualquier token); las definiciones las crea el dueño del tenant desde su panel. Se devuelven en la clave `fields` del recurso. */
|
|
4418
|
+
customFields?: {
|
|
4419
|
+
/** @description Id de la definición del campo personalizado. */
|
|
4420
|
+
id: number;
|
|
4421
|
+
/** @description Valor a guardar. */
|
|
4422
|
+
value: string;
|
|
4423
|
+
}[];
|
|
4412
4424
|
};
|
|
4413
4425
|
/** SupplierResource */
|
|
4414
4426
|
SupplierResource: {
|
|
@@ -5122,74 +5134,6 @@ export interface operations {
|
|
|
5122
5134
|
};
|
|
5123
5135
|
};
|
|
5124
5136
|
};
|
|
5125
|
-
"auth.login": {
|
|
5126
|
-
parameters: {
|
|
5127
|
-
query?: never;
|
|
5128
|
-
header?: never;
|
|
5129
|
-
path?: never;
|
|
5130
|
-
cookie?: never;
|
|
5131
|
-
};
|
|
5132
|
-
requestBody: {
|
|
5133
|
-
content: {
|
|
5134
|
-
"application/json": components["schemas"]["LoginRequest"];
|
|
5135
|
-
};
|
|
5136
|
-
};
|
|
5137
|
-
responses: {
|
|
5138
|
-
200: {
|
|
5139
|
-
headers: {
|
|
5140
|
-
[name: string]: unknown;
|
|
5141
|
-
};
|
|
5142
|
-
content: {
|
|
5143
|
-
"application/json": {
|
|
5144
|
-
/** @constant */
|
|
5145
|
-
type: "Bearer";
|
|
5146
|
-
token: string;
|
|
5147
|
-
};
|
|
5148
|
-
};
|
|
5149
|
-
};
|
|
5150
|
-
422: components["responses"]["ValidationException"];
|
|
5151
|
-
};
|
|
5152
|
-
};
|
|
5153
|
-
"auth.logout": {
|
|
5154
|
-
parameters: {
|
|
5155
|
-
query?: never;
|
|
5156
|
-
header?: never;
|
|
5157
|
-
path?: never;
|
|
5158
|
-
cookie?: never;
|
|
5159
|
-
};
|
|
5160
|
-
requestBody?: never;
|
|
5161
|
-
responses: {
|
|
5162
|
-
200: {
|
|
5163
|
-
headers: {
|
|
5164
|
-
[name: string]: unknown;
|
|
5165
|
-
};
|
|
5166
|
-
content: {
|
|
5167
|
-
"application/json": {
|
|
5168
|
-
success: boolean;
|
|
5169
|
-
};
|
|
5170
|
-
};
|
|
5171
|
-
};
|
|
5172
|
-
};
|
|
5173
|
-
};
|
|
5174
|
-
"auth.check": {
|
|
5175
|
-
parameters: {
|
|
5176
|
-
query?: never;
|
|
5177
|
-
header?: never;
|
|
5178
|
-
path?: never;
|
|
5179
|
-
cookie?: never;
|
|
5180
|
-
};
|
|
5181
|
-
requestBody?: never;
|
|
5182
|
-
responses: {
|
|
5183
|
-
200: {
|
|
5184
|
-
headers: {
|
|
5185
|
-
[name: string]: unknown;
|
|
5186
|
-
};
|
|
5187
|
-
content: {
|
|
5188
|
-
"application/json": boolean;
|
|
5189
|
-
};
|
|
5190
|
-
};
|
|
5191
|
-
};
|
|
5192
|
-
};
|
|
5193
5137
|
"bank-accounts.index": {
|
|
5194
5138
|
parameters: {
|
|
5195
5139
|
query?: never;
|
|
@@ -7174,35 +7118,6 @@ export interface operations {
|
|
|
7174
7118
|
422: components["responses"]["ValidationException"];
|
|
7175
7119
|
};
|
|
7176
7120
|
};
|
|
7177
|
-
"forgotPassword.sendResetLinkEmail": {
|
|
7178
|
-
parameters: {
|
|
7179
|
-
query?: never;
|
|
7180
|
-
header?: never;
|
|
7181
|
-
path?: never;
|
|
7182
|
-
cookie?: never;
|
|
7183
|
-
};
|
|
7184
|
-
requestBody: {
|
|
7185
|
-
content: {
|
|
7186
|
-
"application/json": components["schemas"]["ForgotPasswordRequest"];
|
|
7187
|
-
};
|
|
7188
|
-
};
|
|
7189
|
-
responses: {
|
|
7190
|
-
200: {
|
|
7191
|
-
headers: {
|
|
7192
|
-
[name: string]: unknown;
|
|
7193
|
-
};
|
|
7194
|
-
content: {
|
|
7195
|
-
"application/json": {
|
|
7196
|
-
/** @constant */
|
|
7197
|
-
message: "Password reset email sent.";
|
|
7198
|
-
/** @constant */
|
|
7199
|
-
data: "passwords.sent";
|
|
7200
|
-
};
|
|
7201
|
-
};
|
|
7202
|
-
};
|
|
7203
|
-
422: components["responses"]["ValidationException"];
|
|
7204
|
-
};
|
|
7205
|
-
};
|
|
7206
7121
|
"exchangeRate.getActiveProvider": {
|
|
7207
7122
|
parameters: {
|
|
7208
7123
|
query?: never;
|
|
@@ -8934,9 +8849,17 @@ export interface operations {
|
|
|
8934
8849
|
};
|
|
8935
8850
|
"general.nextNumber": {
|
|
8936
8851
|
parameters: {
|
|
8937
|
-
query
|
|
8938
|
-
|
|
8939
|
-
|
|
8852
|
+
query: {
|
|
8853
|
+
/** @description Tipo de documento cuyo número se calcula. Obligatorio: un valor fuera de la lista devuelve `success: false`. */
|
|
8854
|
+
key: "invoice" | "credit_note" | "estimate" | "payment" | "delivery_note" | "received_invoice";
|
|
8855
|
+
/** @description Serie de facturación a usar (solo `key=invoice`). Sin ella manda la serie por defecto de la empresa. `invoice_series_id` es su alias histórico y solo se mira si `series_id` no viene. */
|
|
8856
|
+
series_id?: number;
|
|
8857
|
+
/** @description Alias histórico de `series_id`. En clientes nuevos usa `series_id`. */
|
|
8858
|
+
invoice_series_id?: number;
|
|
8859
|
+
/** @description Id del documento que se está EDITANDO. Con él el cálculo reutiliza la secuencia que ese documento ya tiene en vez de proponer la siguiente; sin él siempre propone la siguiente. */
|
|
8860
|
+
model_id?: number;
|
|
8861
|
+
/** @description Id del cliente, para los formatos de numeración que llevan su serie o su contador (`{{CUSTOMER_SERIES}}`, `{{CUSTOMER_SEQUENCE}}`). Irrelevante en el resto de formatos. */
|
|
8862
|
+
userId?: number;
|
|
8940
8863
|
};
|
|
8941
8864
|
header?: never;
|
|
8942
8865
|
path?: never;
|
|
@@ -8944,12 +8867,18 @@ export interface operations {
|
|
|
8944
8867
|
};
|
|
8945
8868
|
requestBody?: never;
|
|
8946
8869
|
responses: {
|
|
8870
|
+
/** @description Siempre `200`, también cuando falla: el discriminante es `success`. `nextNumber` es el número propuesto (`null` si `success` es `false`) e `isUsed` dice si la empresa ya tiene algún documento de ese tipo — el panel lo usa para saber si el formato de numeración todavía se puede cambiar. */
|
|
8947
8871
|
200: {
|
|
8948
8872
|
headers: {
|
|
8949
8873
|
[name: string]: unknown;
|
|
8950
8874
|
};
|
|
8951
8875
|
content: {
|
|
8952
|
-
"application/json":
|
|
8876
|
+
"application/json": {
|
|
8877
|
+
success: boolean;
|
|
8878
|
+
nextNumber: string | null;
|
|
8879
|
+
isUsed: boolean;
|
|
8880
|
+
message?: string;
|
|
8881
|
+
};
|
|
8953
8882
|
};
|
|
8954
8883
|
};
|
|
8955
8884
|
};
|
|
@@ -10292,39 +10221,6 @@ export interface operations {
|
|
|
10292
10221
|
};
|
|
10293
10222
|
};
|
|
10294
10223
|
};
|
|
10295
|
-
"resetPassword.reset": {
|
|
10296
|
-
parameters: {
|
|
10297
|
-
query?: never;
|
|
10298
|
-
header?: never;
|
|
10299
|
-
path?: never;
|
|
10300
|
-
cookie?: never;
|
|
10301
|
-
};
|
|
10302
|
-
requestBody: {
|
|
10303
|
-
content: {
|
|
10304
|
-
"application/json": {
|
|
10305
|
-
token: string;
|
|
10306
|
-
/** Format: email */
|
|
10307
|
-
email: string;
|
|
10308
|
-
password: string;
|
|
10309
|
-
password_confirmation: string;
|
|
10310
|
-
};
|
|
10311
|
-
};
|
|
10312
|
-
};
|
|
10313
|
-
responses: {
|
|
10314
|
-
200: {
|
|
10315
|
-
headers: {
|
|
10316
|
-
[name: string]: unknown;
|
|
10317
|
-
};
|
|
10318
|
-
content: {
|
|
10319
|
-
"application/json": {
|
|
10320
|
-
/** @constant */
|
|
10321
|
-
message: "Password reset successfully.";
|
|
10322
|
-
} | Record<string, never>;
|
|
10323
|
-
};
|
|
10324
|
-
};
|
|
10325
|
-
422: components["responses"]["ValidationException"];
|
|
10326
|
-
};
|
|
10327
|
-
};
|
|
10328
10224
|
"general.search": {
|
|
10329
10225
|
parameters: {
|
|
10330
10226
|
query?: never;
|