@pimia/sdk 0.2.0 → 0.4.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/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,25 @@ export interface paths {
278
230
  };
279
231
  get?: never;
280
232
  put?: never;
281
- /** Handle the incoming request */
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
+ *
237
+ * Asistente de arranque: fija el tipo de cambio de cada moneda en uso y
238
+ * RECALCULA con él los importes base de todas las facturas, presupuestos y
239
+ * pagos de esa moneda — documentos ya emitidos incluidos. Corre una sola vez
240
+ * por empresa (mientras `bulk_exchange_rate_configured` sea 'NO').
241
+ *
242
+ * Reescribir en masa los importes de documentos emitidos es configuración de
243
+ * empresa, no una operación de uso diario: va con el mismo gate de owner que
244
+ * el resto de lo que escribe en Settings. Hasta 2026-08-10 no tenía ninguno
245
+ * —el FormRequest autoriza a todo el mundo— y para un token de API la única
246
+ * barrera era que `settings:write` no esté en el catálogo OAuth.
247
+ *
248
+ * OJO al frontend: el modal lo abre `LayoutBasic` en cuanto entra CUALQUIER
249
+ * usuario con la marca a 'NO'. Sin la condición de owner que se añadió allí,
250
+ * este gate deja a un empleado atrapado en un modal que no puede completar.
251
+ */
282
252
  post: operations["general.bulkExchangeRate"];
283
253
  delete?: never;
284
254
  options?: never;
@@ -429,7 +399,14 @@ export interface paths {
429
399
  };
430
400
  get?: never;
431
401
  put?: never;
432
- /** Handle the incoming request */
402
+ /**
403
+ * Convertir un presupuesto en factura borrador
404
+ * @description Acepta `external_ref` para etiquetar la factura resultante **en el mismo
405
+ * paso**. Etiquetarla después, con `PUT /invoices/{id}`, llega tarde:
406
+ * `invoice.created` ya ha salido con la referencia nula, y entre las dos
407
+ * llamadas hay una ventana en la que la factura existe y no la encuentras
408
+ * por tu referencia.
409
+ */
433
410
  post: operations["estimate.convertEstimate"];
434
411
  delete?: never;
435
412
  options?: never;
@@ -498,7 +475,10 @@ export interface paths {
498
475
  /** Display a listing of the resource */
499
476
  get: operations["custom-fields.index"];
500
477
  put?: never;
501
- /** Store a newly created resource in storage */
478
+ /**
479
+ * Store a newly created resource in storage
480
+ * @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.
481
+ */
502
482
  post: operations["custom-fields.store"];
503
483
  delete?: never;
504
484
  options?: never;
@@ -515,10 +495,16 @@ export interface paths {
515
495
  };
516
496
  /** Display the specified resource */
517
497
  get: operations["custom-fields.show"];
518
- /** Update the specified resource in storage */
498
+ /**
499
+ * Update the specified resource in storage
500
+ * @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.
501
+ */
519
502
  put: operations["custom-fields.update"];
520
503
  post?: never;
521
- /** Remove the specified resource from storage */
504
+ /**
505
+ * Remove the specified resource from storage
506
+ * @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.
507
+ */
522
508
  delete: operations["custom-fields.destroy"];
523
509
  options?: never;
524
510
  head?: never;
@@ -906,23 +892,6 @@ export interface paths {
906
892
  trace?: never;
907
893
  };
908
894
  "/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
895
  parameters: {
927
896
  query?: never;
928
897
  header?: never;
@@ -932,14 +901,38 @@ export interface paths {
932
901
  get?: never;
933
902
  put?: never;
934
903
  /**
935
- * Igual que el `sendResetLinkEmail()` del trait, pero con la validación en
936
- * un FormRequest en vez de en su `validateEmail()` privado: ahí dentro el
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()`.
904
+ * Toggle lock state for a quarter
905
+ * @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.
906
+ *
907
+ * Cerrar un trimestre corta el alta y la edición de facturas emitidas y
908
+ * recibidas con fecha en ese periodo ({@see FiscalQuarter::isLocked}); esta
909
+ * misma acción lo REABRE. Es cierre contable, así que va con el gate de
910
+ * owner que ya gobierna la configuración sensible del tenant.
911
+ *
912
+ * Hasta 2026-08-10 no tenía ninguno: el `index` y el `toggle` colgaban de la
913
+ * ability de LECTURA de informes que gatea la pantalla (VIEW_FINANCIAL_REPORT
914
+ * en el router del panel), de modo que cualquiera que pudiera ver el informe
915
+ * contable podía reabrir un ejercicio cerrado. Para un token de API la única
916
+ * barrera era que `reports:write` no esté en el catálogo OAuth — una ausencia
917
+ * que protegía por accidente y que este gate deja de necesitar.
918
+ *
919
+ * El `index` sigue sin gate a propósito: leer qué trimestres están cerrados
920
+ * es lo que pinta el panel y no cambia nada.
921
+ *
922
+ * `locked` (opcional) es el ESTADO DESEADO, y es lo que deberían mandar los
923
+ * clientes: con él la operación es idempotente y dice lo que quiere en vez
924
+ * de depender de lo que había. Sin él se conserva el alternado histórico.
925
+ *
926
+ * El alternado ciego tiene una carrera que no es teórica: el cliente decide
927
+ * qué va a pasar leyendo un estado que ya puede haber cambiado. El panel
928
+ * pinta «Cerrar T1» porque lo leyó abierto, otro usuario lo cierra, y el
929
+ * clic acaba REABRIENDO el trimestre que su botón prometía cerrar. Por la
930
+ * vía del MCP era peor: `toggle_fiscal_quarter_lock` declaraba este mismo
931
+ * parámetro y el servidor lo ignoraba, así que un agente que pidiera cerrar
932
+ * un trimestre ya cerrado lo abría — en una operación que el propio MCP
933
+ * anuncia como PELIGROSA.
941
934
  */
942
- post: operations["forgotPassword.sendResetLinkEmail"];
935
+ post: operations["fiscalQuarter.toggle"];
943
936
  delete?: never;
944
937
  options?: never;
945
938
  head?: never;
@@ -1597,7 +1590,31 @@ export interface paths {
1597
1590
  path?: never;
1598
1591
  cookie?: never;
1599
1592
  };
1600
- /** Handle the incoming request */
1593
+ /**
1594
+ * Siguiente número de documento (orientativo, NO lo reserva)
1595
+ * @description Calcula al vuelo qué número le tocaría al próximo documento del tipo pedido, con el
1596
+ * formato de numeración configurado por la empresa. Es lo que el panel pinta en el
1597
+ * formulario antes de guardar.
1598
+ *
1599
+ * **No reserva nada y no es determinista.** No consume secuencia: dos llamadas
1600
+ * seguidas —o dos integradores a la vez— reciben el MISMO número, y quien guarde
1601
+ * primero se lo queda; el segundo se estrella contra el `unique` con un `422`.
1602
+ * El valor caduca en cuanto alguien crea un documento de ese tipo.
1603
+ *
1604
+ * **No lo necesitas para escribir, y usarlo para eso te perjudica.** Desde el
1605
+ * 2026-08-10 ninguna alta exige que el número lo pongas tú: `invoice_number`,
1606
+ * `estimate_number`, `payment_number` y `received_invoice_number` son opcionales y,
1607
+ * si no llegan, los asigna el servidor con este mismo formateador ya dentro de la
1608
+ * transacción que escribe. Pedir el número aquí para reenviarlo en el cuerpo solo
1609
+ * añade una carrera que el servidor no tiene, y de paso rompe la reproducibilidad
1610
+ * del cuerpo entre reintentos con `Idempotency-Key` (guía del integrador §7).
1611
+ * Su uso legítimo es previsualizar en una interfaz el número que le tocaría al
1612
+ * documento — para eso lo llama el panel.
1613
+ *
1614
+ * **Comprueba `success` antes de leer `nextNumber`.** Un fallo llega con `200` y el
1615
+ * sobre `{"success": false, "message": "..."}`; desestructurar `nextNumber` a ciegas
1616
+ * degrada en silencio a `null`.
1617
+ */
1601
1618
  get: operations["general.nextNumber"];
1602
1619
  put?: never;
1603
1620
  post?: never;
@@ -2195,23 +2212,6 @@ export interface paths {
2195
2212
  patch?: never;
2196
2213
  trace?: never;
2197
2214
  };
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
2215
  "/search": {
2216
2216
  parameters: {
2217
2217
  query?: never;
@@ -2538,7 +2538,9 @@ export interface paths {
2538
2538
  put?: never;
2539
2539
  /**
2540
2540
  * POST tasks/{task}/delegate — delega esta tarea CRM a su agente Pim
2541
- * @description Reusa el plano async `delegated_tasks` (el mismo que ya cierra el round-trip
2541
+ * @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.
2542
+ *
2543
+ * Reusa el plano async `delegated_tasks` (el mismo que ya cierra el round-trip
2542
2544
  * delegar→agente→callback→sello): compone un context rico desde la tarea (título,
2543
2545
  * descripción y el lead/cliente/proyecto vinculado con sus datos), crea la
2544
2546
  * delegación, la entrega al Kanban del Copilot y la enlaza con la tarea.
@@ -3024,6 +3026,22 @@ export interface components {
3024
3026
  created_at: string;
3025
3027
  updated_at: string;
3026
3028
  };
3029
+ /**
3030
+ * ConvertEstimateRequest
3031
+ * @description Cuerpo —opcional— de la conversión de un presupuesto en factura.
3032
+ */
3033
+ ConvertEstimateRequest: {
3034
+ /**
3035
+ * @description Referencia externa: TU identificador para la factura que sale de
3036
+ * esta conversión (el id del pedido o de la venta cerrada en tu
3037
+ * sistema). Sin él la factura nace sin etiquetar y los webhooks
3038
+ * `invoice.created` e `invoice.paid` llegan con `external_ref`
3039
+ * nulo. El alcance es tu client OAuth, igual que en el alta
3040
+ * directa de facturas. Duplicada dentro de tu namespace → 422 con
3041
+ * `existing_id`, y la conversión entera se deshace.
3042
+ */
3043
+ external_ref?: string | null;
3044
+ };
3027
3045
  /** CountryResource */
3028
3046
  CountryResource: {
3029
3047
  id: number;
@@ -3129,6 +3147,17 @@ export interface components {
3129
3147
  prefix?: string | null;
3130
3148
  tax_id?: string | null;
3131
3149
  notes?: string | null;
3150
+ /**
3151
+ * @description Referencia externa: TU identificador para este cliente (el id
3152
+ * del deal, del contacto o del pedido en tu sistema). El alcance
3153
+ * es tu client OAuth, así que dos integradores pueden usar la
3154
+ * misma cadena sin pisarse y ninguno ve la del otro. Se consulta
3155
+ * con `GET /customers?external_ref=…`, vuelve en el recurso y
3156
+ * viaja en los webhooks `customer.*`. Si ya la lleva otro cliente
3157
+ * tuyo, la respuesta es un 422 con `existing_id` — que es el
3158
+ * find-or-create sin mantener mapeo local. `null` la desvincula.
3159
+ */
3160
+ external_ref?: string | null;
3132
3161
  currency_id?: string | null;
3133
3162
  payment_method_id?: number | null;
3134
3163
  billing?: {
@@ -3153,6 +3182,13 @@ export interface components {
3153
3182
  phone?: string | null;
3154
3183
  fax?: string | null;
3155
3184
  };
3185
+ /** @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. */
3186
+ customFields?: {
3187
+ /** @description Id de la definición del campo personalizado. */
3188
+ id: number;
3189
+ /** @description Valor a guardar. */
3190
+ value: string;
3191
+ }[];
3156
3192
  };
3157
3193
  /** CustomerResource */
3158
3194
  CustomerResource: {
@@ -3180,6 +3216,13 @@ export interface components {
3180
3216
  prefix: string;
3181
3217
  tax_id: string;
3182
3218
  notes: string;
3219
+ /**
3220
+ * @description Referencia externa DE QUIEN PREGUNTA: la resuelve el client OAuth
3221
+ * del token, así que dos integradores ven cada uno la suya y el
3222
+ * panel (sin client) ve la del namespace de la company. Siempre
3223
+ * presente aunque sea null, para que el tipo del SDK no alterne.
3224
+ */
3225
+ external_ref: string | null;
3183
3226
  iban: string;
3184
3227
  bic: string;
3185
3228
  sepa_mandate_id: string;
@@ -3321,6 +3364,12 @@ export interface components {
3321
3364
  template_name: string;
3322
3365
  customer_id: string;
3323
3366
  lead_id: string;
3367
+ /**
3368
+ * @description Referencia externa del client OAuth del token (null si no hay).
3369
+ * Es el asidero que `lead_id` no podía ser: aquel es un entero de
3370
+ * Pimia y no admite el cuid o el uuid de un CRM de fuera.
3371
+ */
3372
+ external_ref: string | null;
3324
3373
  exchange_rate: string;
3325
3374
  base_discount_val: string;
3326
3375
  base_sub_total: string;
@@ -3354,6 +3403,17 @@ export interface components {
3354
3403
  expiry_date?: string | null;
3355
3404
  customer_id?: number | null;
3356
3405
  lead_id?: number | null;
3406
+ /**
3407
+ * @description Referencia externa: TU identificador para este presupuesto (el
3408
+ * id de la oportunidad en tu CRM). Es el asidero que `lead_id` no
3409
+ * podía ser: aquel es un entero de Pimia y no admite un cuid ni un
3410
+ * uuid. El alcance es tu client OAuth. Se consulta con
3411
+ * `GET /estimates?external_ref=…` y viaja en el payload de
3412
+ * `estimate.accepted`, así que recuperas tu oportunidad en el
3413
+ * evento sin mantener ningún mapeo. Duplicada dentro de tu
3414
+ * namespace → 422 con `existing_id`. `null` la desvincula.
3415
+ */
3416
+ external_ref?: string | null;
3357
3417
  /**
3358
3418
  * @description Opcional en el alta: si no llega, lo genera el servidor con el mismo
3359
3419
  * SerialNumberFormatter que alimenta a GET /next-number, que es de donde
@@ -3402,6 +3462,13 @@ export interface components {
3402
3462
  percent?: number | null;
3403
3463
  amount?: number | null;
3404
3464
  }[] | null;
3465
+ /** @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. */
3466
+ customFields?: {
3467
+ /** @description Id de la definición del campo personalizado. */
3468
+ id: number;
3469
+ /** @description Valor a guardar. */
3470
+ value: string;
3471
+ }[];
3405
3472
  }[];
3406
3473
  taxes?: {
3407
3474
  tax_type_id?: number | null;
@@ -3415,6 +3482,13 @@ export interface components {
3415
3482
  */
3416
3483
  tax_per_item?: string | null;
3417
3484
  tax_included?: boolean | null;
3485
+ /** @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. */
3486
+ customFields?: {
3487
+ /** @description Id de la definición del campo personalizado. */
3488
+ id: number;
3489
+ /** @description Valor a guardar. */
3490
+ value: string;
3491
+ }[];
3418
3492
  };
3419
3493
  /** ExpenseCategoryRequest */
3420
3494
  ExpenseCategoryRequest: {
@@ -3448,6 +3522,10 @@ export interface components {
3448
3522
  * @description Maximum file size: 20000 kilobytes.
3449
3523
  */
3450
3524
  attachment_receipt?: string | null;
3525
+ /** @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"}]`. */
3526
+ customFields?: string;
3527
+ /** @description Borra el recibo adjunto del gasto. Solo surte efecto en la actualización; en `multipart/form-data` viaja como `1` o `0`. */
3528
+ is_attachment_receipt_removed?: boolean | null;
3451
3529
  };
3452
3530
  /** ExpenseResource */
3453
3531
  ExpenseResource: {
@@ -3479,23 +3557,6 @@ export interface components {
3479
3557
  currency?: components["schemas"]["CurrencyResource"];
3480
3558
  payment_method?: components["schemas"]["PaymentMethodResource"];
3481
3559
  };
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
3560
  /** InvestmentAssetResource */
3500
3561
  InvestmentAssetResource: {
3501
3562
  id: string;
@@ -3573,6 +3634,11 @@ export interface components {
3573
3634
  template_name: string;
3574
3635
  invoice_series_id: string;
3575
3636
  customer_id: string;
3637
+ /**
3638
+ * @description Referencia externa del client OAuth del token (null si no hay):
3639
+ * cada integrador ve la suya y solo la suya.
3640
+ */
3641
+ external_ref: string | null;
3576
3642
  payment_method_id: string;
3577
3643
  recurring_invoice_id: string;
3578
3644
  sequence_number: string;
@@ -3724,6 +3790,15 @@ export interface components {
3724
3790
  due_date?: string | null;
3725
3791
  customer_id: number;
3726
3792
  invoice_number?: string | null;
3793
+ /**
3794
+ * @description Referencia externa: TU identificador para esta factura (el id
3795
+ * del pedido o de la suscripción en tu sistema). El alcance es tu
3796
+ * client OAuth. Se consulta con `GET /invoices?external_ref=…` y
3797
+ * viaja en los payloads de `invoice.created` e `invoice.paid`.
3798
+ * Duplicada dentro de tu namespace → 422 con `existing_id`.
3799
+ * `null` la desvincula.
3800
+ */
3801
+ external_ref?: string | null;
3727
3802
  exchange_rate?: string | null;
3728
3803
  /**
3729
3804
  * @description Descuento global: opcional en el contrato y rellenado a 0 en
@@ -3771,6 +3846,13 @@ export interface components {
3771
3846
  percent?: number | null;
3772
3847
  amount?: number | null;
3773
3848
  }[] | null;
3849
+ /** @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. */
3850
+ customFields?: {
3851
+ /** @description Id de la definición del campo personalizado. */
3852
+ id: number;
3853
+ /** @description Valor a guardar. */
3854
+ value: string;
3855
+ }[];
3774
3856
  }[];
3775
3857
  taxes?: {
3776
3858
  tax_type_id?: number | null;
@@ -3784,6 +3866,13 @@ export interface components {
3784
3866
  */
3785
3867
  tax_per_item?: string | null;
3786
3868
  tax_included?: boolean | null;
3869
+ /** @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. */
3870
+ customFields?: {
3871
+ /** @description Id de la definición del campo personalizado. */
3872
+ id: number;
3873
+ /** @description Valor a guardar. */
3874
+ value: string;
3875
+ }[];
3787
3876
  };
3788
3877
  /** ItemCategory */
3789
3878
  ItemCategory: string[];
@@ -3841,6 +3930,8 @@ export interface components {
3841
3930
  stock_alert_qty?: number | null;
3842
3931
  allow_sale_without_stock?: boolean | null;
3843
3932
  purchase_tax_type_id?: number | null;
3933
+ /** @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. */
3934
+ opening_stock?: number | null;
3844
3935
  };
3845
3936
  /** LeadActivity */
3846
3937
  LeadActivity: string[];
@@ -3920,12 +4011,6 @@ export interface components {
3920
4011
  name: string;
3921
4012
  } | null;
3922
4013
  };
3923
- /** LoginRequest */
3924
- LoginRequest: {
3925
- username: string;
3926
- password: string;
3927
- device_name: string;
3928
- };
3929
4014
  /** Note */
3930
4015
  Note: {
3931
4016
  id: number;
@@ -3958,10 +4043,27 @@ export interface components {
3958
4043
  customer_id: string;
3959
4044
  exchange_rate?: string | null;
3960
4045
  amount: number;
3961
- payment_number: string;
4046
+ /**
4047
+ * @description Opcional en el alta: si no llega, lo genera el servidor con el mismo
4048
+ * SerialNumberFormatter que alimenta a GET /next-number?key=payment, que es
4049
+ * de donde lo saca el panel. Exigirlo obligaba a un cliente de la API a
4050
+ * replicar el formato de numeración de la empresa, y encima a congelar el
4051
+ * cuerpo entre reintentos: `next-number` no reserva nada, así que pedirlo
4052
+ * dos veces puede dar dos números distintos y el reintento con la misma
4053
+ * Idempotency-Key rebotaba con 422 por «cuerpo distinto».
4054
+ * En PUT sigue siendo obligatorio (más abajo): el pago ya tiene uno.
4055
+ */
4056
+ payment_number?: string | null;
3962
4057
  invoice_id?: string | null;
3963
4058
  payment_method_id?: string | null;
3964
4059
  notes?: string | null;
4060
+ /** @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. */
4061
+ customFields?: {
4062
+ /** @description Id de la definición del campo personalizado. */
4063
+ id: number;
4064
+ /** @description Valor a guardar. */
4065
+ value: string;
4066
+ }[];
3965
4067
  };
3966
4068
  /** PaymentResource */
3967
4069
  PaymentResource: {
@@ -4073,7 +4175,18 @@ export interface components {
4073
4175
  received_invoice_date: string;
4074
4176
  due_date?: string | null;
4075
4177
  supplier_id: string;
4076
- received_invoice_number: string;
4178
+ /**
4179
+ * @description Opcional en el alta: si no llega, lo genera el servidor con el mismo
4180
+ * SerialNumberFormatter que alimenta a GET /next-number?key=received_invoice,
4181
+ * que es de donde lo saca el panel. Es el número del LIBRO DE RECIBIDAS —el
4182
+ * del proveedor va en `reference_number`—, así que numerarlo es cosa nuestra,
4183
+ * no del cliente de la API: exigirlo le obligaba a replicar el formato de la
4184
+ * empresa y a congelar el cuerpo entre reintentos (`next-number` no reserva,
4185
+ * dos llamadas pueden dar números distintos y la misma Idempotency-Key
4186
+ * rebotaba con 422 por «cuerpo distinto»).
4187
+ * En PUT sigue siendo obligatorio (más abajo): la factura ya tiene uno.
4188
+ */
4189
+ received_invoice_number?: string | null;
4077
4190
  exchange_rate?: string | null;
4078
4191
  discount: number;
4079
4192
  discount_val: number;
@@ -4216,6 +4329,13 @@ export interface components {
4216
4329
  */
4217
4330
  tax_per_item?: string | null;
4218
4331
  tax_included?: boolean | null;
4332
+ /** @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. */
4333
+ customFields?: {
4334
+ /** @description Id de la definición del campo personalizado. */
4335
+ id: number;
4336
+ /** @description Valor a guardar. */
4337
+ value: string;
4338
+ }[];
4219
4339
  };
4220
4340
  /** RecurringInvoiceResource */
4221
4341
  RecurringInvoiceResource: {
@@ -4409,6 +4529,13 @@ export interface components {
4409
4529
  phone?: string | null;
4410
4530
  fax?: string | null;
4411
4531
  };
4532
+ /** @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. */
4533
+ customFields?: {
4534
+ /** @description Id de la definición del campo personalizado. */
4535
+ id: number;
4536
+ /** @description Valor a guardar. */
4537
+ value: string;
4538
+ }[];
4412
4539
  };
4413
4540
  /** SupplierResource */
4414
4541
  SupplierResource: {
@@ -4708,31 +4835,31 @@ export interface components {
4708
4835
  };
4709
4836
  };
4710
4837
  responses: {
4711
- /** @description Validation error */
4712
- ValidationException: {
4838
+ /** @description Authorization error */
4839
+ AuthorizationException: {
4713
4840
  headers: {
4714
4841
  [name: string]: unknown;
4715
4842
  };
4716
4843
  content: {
4717
4844
  "application/json": {
4718
- /** @description Errors overview. */
4845
+ /** @description Error overview. */
4719
4846
  message: string;
4720
- /** @description A detailed description of each field that failed validation. */
4721
- errors: {
4722
- [key: string]: string[];
4723
- };
4724
4847
  };
4725
4848
  };
4726
4849
  };
4727
- /** @description Authorization error */
4728
- AuthorizationException: {
4850
+ /** @description Validation error */
4851
+ ValidationException: {
4729
4852
  headers: {
4730
4853
  [name: string]: unknown;
4731
4854
  };
4732
4855
  content: {
4733
4856
  "application/json": {
4734
- /** @description Error overview. */
4857
+ /** @description Errors overview. */
4735
4858
  message: string;
4859
+ /** @description A detailed description of each field that failed validation. */
4860
+ errors: {
4861
+ [key: string]: string[];
4862
+ };
4736
4863
  };
4737
4864
  };
4738
4865
  };
@@ -5122,74 +5249,6 @@ export interface operations {
5122
5249
  };
5123
5250
  };
5124
5251
  };
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
5252
  "bank-accounts.index": {
5194
5253
  parameters: {
5195
5254
  query?: never;
@@ -5492,6 +5551,7 @@ export interface operations {
5492
5551
  "application/json": Record<string, never>;
5493
5552
  };
5494
5553
  };
5554
+ 403: components["responses"]["AuthorizationException"];
5495
5555
  422: components["responses"]["ValidationException"];
5496
5556
  };
5497
5557
  };
@@ -5815,7 +5875,11 @@ export interface operations {
5815
5875
  };
5816
5876
  cookie?: never;
5817
5877
  };
5818
- requestBody?: never;
5878
+ requestBody?: {
5879
+ content: {
5880
+ "application/json": components["schemas"]["ConvertEstimateRequest"];
5881
+ };
5882
+ };
5819
5883
  responses: {
5820
5884
  200: {
5821
5885
  headers: {
@@ -5827,6 +5891,7 @@ export interface operations {
5827
5891
  };
5828
5892
  403: components["responses"]["AuthorizationException"];
5829
5893
  404: components["responses"]["ModelNotFoundException"];
5894
+ 422: components["responses"]["ValidationException"];
5830
5895
  };
5831
5896
  };
5832
5897
  "general.countries": {
@@ -6130,7 +6195,10 @@ export interface operations {
6130
6195
  };
6131
6196
  "customers.index": {
6132
6197
  parameters: {
6133
- query?: never;
6198
+ query?: {
6199
+ /** @description Devuelve solo el recurso que lleve esta referencia externa. El alcance es el client OAuth del token: cada integrador consulta las suyas y nunca ve las de otro. Combinado con la escritura de `external_ref`, es el find-or-create sin mantener ningún mapeo local. */
6200
+ external_ref?: string;
6201
+ };
6134
6202
  header?: never;
6135
6203
  path?: never;
6136
6204
  cookie?: never;
@@ -6688,7 +6756,10 @@ export interface operations {
6688
6756
  };
6689
6757
  "estimates.index": {
6690
6758
  parameters: {
6691
- query?: never;
6759
+ query?: {
6760
+ /** @description Devuelve solo el recurso que lleve esta referencia externa. El alcance es el client OAuth del token: cada integrador consulta las suyas y nunca ve las de otro. Combinado con la escritura de `external_ref`, es el find-or-create sin mantener ningún mapeo local. */
6761
+ external_ref?: string;
6762
+ };
6692
6763
  header?: never;
6693
6764
  path?: never;
6694
6765
  cookie?: never;
@@ -7150,6 +7221,7 @@ export interface operations {
7150
7221
  "application/json": {
7151
7222
  year: number;
7152
7223
  quarter: number;
7224
+ locked?: boolean | null;
7153
7225
  };
7154
7226
  };
7155
7227
  };
@@ -7171,35 +7243,7 @@ export interface operations {
7171
7243
  };
7172
7244
  };
7173
7245
  };
7174
- 422: components["responses"]["ValidationException"];
7175
- };
7176
- };
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
- };
7246
+ 403: components["responses"]["AuthorizationException"];
7203
7247
  422: components["responses"]["ValidationException"];
7204
7248
  };
7205
7249
  };
@@ -8098,6 +8142,8 @@ export interface operations {
8098
8142
  parameters: {
8099
8143
  query?: {
8100
8144
  limit?: string;
8145
+ /** @description Devuelve solo el recurso que lleve esta referencia externa. El alcance es el client OAuth del token: cada integrador consulta las suyas y nunca ve las de otro. Combinado con la escritura de `external_ref`, es el find-or-create sin mantener ningún mapeo local. */
8146
+ external_ref?: string;
8101
8147
  };
8102
8148
  header?: never;
8103
8149
  path?: never;
@@ -8934,9 +8980,17 @@ export interface operations {
8934
8980
  };
8935
8981
  "general.nextNumber": {
8936
8982
  parameters: {
8937
- query?: {
8938
- invoice_series_id?: string;
8939
- series_id?: string;
8983
+ query: {
8984
+ /** @description Tipo de documento cuyo número se calcula. Obligatorio: un valor fuera de la lista devuelve `success: false`. */
8985
+ key: "invoice" | "credit_note" | "estimate" | "payment" | "delivery_note" | "received_invoice";
8986
+ /** @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. */
8987
+ series_id?: number;
8988
+ /** @description Alias histórico de `series_id`. En clientes nuevos usa `series_id`. */
8989
+ invoice_series_id?: number;
8990
+ /** @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. */
8991
+ model_id?: number;
8992
+ /** @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. */
8993
+ userId?: number;
8940
8994
  };
8941
8995
  header?: never;
8942
8996
  path?: never;
@@ -8944,12 +8998,18 @@ export interface operations {
8944
8998
  };
8945
8999
  requestBody?: never;
8946
9000
  responses: {
9001
+ /** @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
9002
  200: {
8948
9003
  headers: {
8949
9004
  [name: string]: unknown;
8950
9005
  };
8951
9006
  content: {
8952
- "application/json": Record<string, never>;
9007
+ "application/json": {
9008
+ success: boolean;
9009
+ nextNumber: string | null;
9010
+ isUsed: boolean;
9011
+ message?: string;
9012
+ };
8953
9013
  };
8954
9014
  };
8955
9015
  };
@@ -10292,39 +10352,6 @@ export interface operations {
10292
10352
  };
10293
10353
  };
10294
10354
  };
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
10355
  "general.search": {
10329
10356
  parameters: {
10330
10357
  query?: never;