@pimia/sdk 0.1.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/dist/api.d.ts CHANGED
@@ -10,7 +10,18 @@ export interface paths {
10
10
  path?: never;
11
11
  cookie?: never;
12
12
  };
13
- /** Get accounting summary by quarter for a fiscal year */
13
+ /**
14
+ * Accounting summary. Two modes:
15
+ * @description - `year` (solo): array de 4 trimestres con revenue/expenses/vat/irpf/result.
16
+ * Lo consume AccountingSummaryReport.vue — su shape es contrato estable.
17
+ * - `from_date`+`to_date` (o `quarter`+`year`): objeto agregado del rango con
18
+ * total_sales, total_received, total_expenses, net_profit, vat_collected,
19
+ * vat_paid, vat_balance, irpf, counts y tax_breakdown. Con
20
+ * `group_by=customer` añade by_customer; con `group_by=category`, by_category.
21
+ * Lo consumen las tools MCP de informes (invoice-shelf-mcp).
22
+ *
23
+ * Importes en céntimos, como el resto de la API.
24
+ */
14
25
  get: operations["accountingSummary.index"];
15
26
  put?: never;
16
27
  post?: never;
@@ -69,23 +80,7 @@ export interface paths {
69
80
  patch?: never;
70
81
  trace?: never;
71
82
  };
72
- "/auth/login": {
73
- parameters: {
74
- query?: never;
75
- header?: never;
76
- path?: never;
77
- cookie?: never;
78
- };
79
- get?: never;
80
- put?: never;
81
- post: operations["auth.login"];
82
- delete?: never;
83
- options?: never;
84
- head?: never;
85
- patch?: never;
86
- trace?: never;
87
- };
88
- "/auth/logout": {
83
+ "/approvals": {
89
84
  parameters: {
90
85
  query?: never;
91
86
  header?: never;
@@ -94,21 +89,30 @@ export interface paths {
94
89
  };
95
90
  get?: never;
96
91
  put?: never;
97
- post: operations["auth.logout"];
92
+ /**
93
+ * POST /api/v1/approvals — el partner crea una propuesta (nace 'proposed'
94
+ * en modo preview, pendiente de la decisión del owner)
95
+ */
96
+ post: operations["approvals.store"];
98
97
  delete?: never;
99
98
  options?: never;
100
99
  head?: never;
101
100
  patch?: never;
102
101
  trace?: never;
103
102
  };
104
- "/auth/check": {
103
+ "/approvals/{id}": {
105
104
  parameters: {
106
105
  query?: never;
107
106
  header?: never;
108
107
  path?: never;
109
108
  cookie?: never;
110
109
  };
111
- get: operations["auth.check"];
110
+ /**
111
+ * GET /api/v1/approvals/{id} — estado de una propuesta DEL client del
112
+ * token. Escopeado por origin_client_id + tenant: cualquier otra cosa es
113
+ * 404 (no se filtra ni la existencia)
114
+ */
115
+ get: operations["approvals.show"];
112
116
  put?: never;
113
117
  post?: never;
114
118
  delete?: never;
@@ -226,7 +230,10 @@ export interface paths {
226
230
  };
227
231
  get?: never;
228
232
  put?: never;
229
- /** 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
+ */
230
237
  post: operations["general.bulkExchangeRate"];
231
238
  delete?: never;
232
239
  options?: never;
@@ -436,6 +443,52 @@ export interface paths {
436
443
  patch?: never;
437
444
  trace?: never;
438
445
  };
446
+ "/custom-fields": {
447
+ parameters: {
448
+ query?: never;
449
+ header?: never;
450
+ path?: never;
451
+ cookie?: never;
452
+ };
453
+ /** Display a listing of the resource */
454
+ get: operations["custom-fields.index"];
455
+ put?: never;
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
+ */
460
+ post: operations["custom-fields.store"];
461
+ delete?: never;
462
+ options?: never;
463
+ head?: never;
464
+ patch?: never;
465
+ trace?: never;
466
+ };
467
+ "/custom-fields/{customField}": {
468
+ parameters: {
469
+ query?: never;
470
+ header?: never;
471
+ path?: never;
472
+ cookie?: never;
473
+ };
474
+ /** Display the specified resource */
475
+ get: operations["custom-fields.show"];
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
+ */
480
+ put: operations["custom-fields.update"];
481
+ post?: never;
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
+ */
486
+ delete: operations["custom-fields.destroy"];
487
+ options?: never;
488
+ head?: never;
489
+ patch?: never;
490
+ trace?: never;
491
+ };
439
492
  "/customers/{customer}/stats": {
440
493
  parameters: {
441
494
  query?: never;
@@ -825,7 +878,10 @@ export interface paths {
825
878
  };
826
879
  get?: never;
827
880
  put?: never;
828
- /** Toggle lock state for a quarter */
881
+ /**
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.
884
+ */
829
885
  post: operations["fiscalQuarter.toggle"];
830
886
  delete?: never;
831
887
  options?: never;
@@ -833,23 +889,6 @@ export interface paths {
833
889
  patch?: never;
834
890
  trace?: never;
835
891
  };
836
- "/auth/password/email": {
837
- parameters: {
838
- query?: never;
839
- header?: never;
840
- path?: never;
841
- cookie?: never;
842
- };
843
- get?: never;
844
- put?: never;
845
- /** Send a reset link to the given user */
846
- post: operations["forgotPassword.sendResetLinkEmail"];
847
- delete?: never;
848
- options?: never;
849
- head?: never;
850
- patch?: never;
851
- trace?: never;
852
- };
853
892
  "/currencies/{currency}/active-provider": {
854
893
  parameters: {
855
894
  query?: never;
@@ -1501,7 +1540,31 @@ export interface paths {
1501
1540
  path?: never;
1502
1541
  cookie?: never;
1503
1542
  };
1504
- /** Handle the incoming request */
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
+ */
1505
1568
  get: operations["general.nextNumber"];
1506
1569
  put?: never;
1507
1570
  post?: never;
@@ -2099,23 +2162,6 @@ export interface paths {
2099
2162
  patch?: never;
2100
2163
  trace?: never;
2101
2164
  };
2102
- "/auth/reset/password": {
2103
- parameters: {
2104
- query?: never;
2105
- header?: never;
2106
- path?: never;
2107
- cookie?: never;
2108
- };
2109
- get?: never;
2110
- put?: never;
2111
- /** Reset the given user's password */
2112
- post: operations["resetPassword.reset"];
2113
- delete?: never;
2114
- options?: never;
2115
- head?: never;
2116
- patch?: never;
2117
- trace?: never;
2118
- };
2119
2165
  "/search": {
2120
2166
  parameters: {
2121
2167
  query?: never;
@@ -2242,7 +2288,15 @@ export interface paths {
2242
2288
  path?: never;
2243
2289
  cookie?: never;
2244
2290
  };
2245
- /** Handle the incoming request */
2291
+ /**
2292
+ * Handle the incoming request
2293
+ * @description Recibía un `Request` pelado y **no validaba nada**, al revés que las
2294
+ * vistas previas de presupuesto y factura. La consecuencia no era un error
2295
+ * sino algo peor: sin `body` la previsualización se renderizaba igual, con
2296
+ * el cuerpo vacío, así que enseñaba un correo que no era el que se iba a
2297
+ * mandar — y el envío de después sí valida, con lo que la vista previa
2298
+ * mentía justo en el caso en que había algo que corregir.
2299
+ */
2246
2300
  get: operations["payment.sendPaymentPreview"];
2247
2301
  put?: never;
2248
2302
  post?: never;
@@ -2434,7 +2488,9 @@ export interface paths {
2434
2488
  put?: never;
2435
2489
  /**
2436
2490
  * POST tasks/{task}/delegate — delega esta tarea CRM a su agente Pim
2437
- * @description Reusa el plano async `delegated_tasks` (el mismo que ya cierra el round-trip
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
2438
2494
  * delegar→agente→callback→sello): compone un context rico desde la tarea (título,
2439
2495
  * descripción y el lead/cliente/proyecto vinculado con sus datos), crea la
2440
2496
  * delegación, la entrega al Kanban del Copilot y la enlaza con la tarea.
@@ -2757,6 +2813,26 @@ export interface components {
2757
2813
  };
2758
2814
  /** Appointment */
2759
2815
  Appointment: string[];
2816
+ /**
2817
+ * AppointmentRequest
2818
+ * @description Cita de agenda. Reglas movidas literalmente desde el método privado
2819
+ * `AppointmentController::validated()`, que el generador del OpenAPI no podía
2820
+ * ver: solo recorre el AST de la propia acción, no los ayudantes a los que
2821
+ * llama. Ver docs/guia-integradores.md.
2822
+ */
2823
+ AppointmentRequest: {
2824
+ customer_id?: number | null;
2825
+ item_id?: number | null;
2826
+ staff_user_id?: number | null;
2827
+ /** Format: date-time */
2828
+ starts_at: string;
2829
+ /** Format: date-time */
2830
+ ends_at?: string | null;
2831
+ /** @enum {string|null} */
2832
+ status?: "booked" | "confirmed" | "attended" | "no_show" | "cancelled" | null;
2833
+ source?: string | null;
2834
+ notes?: string | null;
2835
+ };
2760
2836
  /** BankAccount */
2761
2837
  BankAccount: {
2762
2838
  id: number;
@@ -2822,18 +2898,51 @@ export interface components {
2822
2898
  exchange_rate: string;
2823
2899
  }[];
2824
2900
  };
2901
+ /**
2902
+ * ChangeInvoiceStatusRequest
2903
+ * @description Cambio de estado de una factura (`POST /invoices/{invoice}/status`).
2904
+ *
2905
+ * El juego de valores es CERRADO y son exactamente las tres transiciones que
2906
+ * el controlador implementa. Antes se aceptaba cualquier string: `DRAFT`,
2907
+ * `VIEWED` y `OVERDUE` —que el servidor MCP llegó a anunciar— respondían
2908
+ * `200 {"success": true}` sin tocar la factura, así que ni el panel ni un
2909
+ * agente podían distinguir un cambio real de uno que no ocurrió. Mismo patrón
2910
+ * que ChangeEstimateStatusController, que ya validaba así.
2911
+ *
2912
+ * Los tres que NO están, y por qué:
2913
+ * - `DRAFT`: volver a borrador no existe. Publicar asigna número oficial y
2914
+ * registra en VeriFactu; deshacerlo se hace con una rectificativa.
2915
+ * - `VIEWED`: lo pone el servidor cuando el cliente abre el PDF
2916
+ * (InvoicePdfController), no es una transición que se pida.
2917
+ * - `OVERDUE`: no es un estado almacenado sino un filtro derivado de
2918
+ * `due_date` + `paid_status` (ver el scope de Invoice).
2919
+ */
2920
+ ChangeInvoiceStatusRequest: {
2921
+ /**
2922
+ * @description PUBLISHED asigna el número oficial y lanza el registro en
2923
+ * VeriFactu; SENT publica antes si aún era borrador; COMPLETED
2924
+ * exige que ya esté publicada o enviada.
2925
+ * @enum {string}
2926
+ */
2927
+ status: "PUBLISHED" | "SENT" | "COMPLETED";
2928
+ /**
2929
+ * @description Slug de la plantilla a fijar al publicar. Si no existe en la
2930
+ * compañía, se ignora en silencio y la factura conserva la suya.
2931
+ */
2932
+ template_name?: string | null;
2933
+ };
2825
2934
  /** CompanyResource */
2826
2935
  CompanyResource: {
2827
- id: string;
2936
+ id: number;
2828
2937
  name: string;
2829
2938
  trade_name: string;
2830
- vat_id: string;
2939
+ vat_id: string | null;
2831
2940
  tax_id: string;
2832
- logo: string;
2941
+ logo: string | null;
2833
2942
  logo_path: string;
2834
- unique_hash: string;
2943
+ unique_hash: string | null;
2835
2944
  owner_id: string;
2836
- slug: string;
2945
+ slug: string | null;
2837
2946
  address?: components["schemas"]["AddressResource"];
2838
2947
  roles: components["schemas"]["RoleResource"][];
2839
2948
  };
@@ -2869,35 +2978,60 @@ export interface components {
2869
2978
  };
2870
2979
  /** CountryResource */
2871
2980
  CountryResource: {
2872
- id: string;
2981
+ id: number;
2873
2982
  code: string;
2874
2983
  name: string;
2875
2984
  phone_code: string;
2876
2985
  };
2877
2986
  /** Currency */
2878
- Currency: string[];
2987
+ Currency: {
2988
+ id: number;
2989
+ name: string;
2990
+ code: string;
2991
+ symbol: string | null;
2992
+ precision: number;
2993
+ exchange_rate: string | null;
2994
+ swap_currency_symbol: string;
2995
+ thousand_separator: string;
2996
+ decimal_separator: string;
2997
+ /** Format: date-time */
2998
+ created_at: string | null;
2999
+ /** Format: date-time */
3000
+ updated_at: string | null;
3001
+ };
2879
3002
  /** CurrencyResource */
2880
3003
  CurrencyResource: {
2881
- id: string;
3004
+ id: number;
2882
3005
  name: string;
2883
3006
  code: string;
2884
- symbol: string;
2885
- precision: string;
3007
+ symbol: string | null;
3008
+ precision: number;
2886
3009
  thousand_separator: string;
2887
3010
  decimal_separator: string;
2888
3011
  swap_currency_symbol: string;
2889
- exchange_rate: string;
3012
+ exchange_rate: string | null;
3013
+ };
3014
+ /** CustomFieldRequest */
3015
+ CustomFieldRequest: {
3016
+ name: string;
3017
+ label: string;
3018
+ model_type: string;
3019
+ order: string;
3020
+ type: string;
3021
+ is_required: boolean;
3022
+ options?: string[];
3023
+ placeholder?: string | null;
2890
3024
  };
2891
3025
  /** CustomFieldResource */
2892
3026
  CustomFieldResource: {
2893
- id: string;
3027
+ id: number;
2894
3028
  name: string;
2895
3029
  slug: string;
2896
3030
  label: string;
2897
3031
  model_type: string;
2898
3032
  type: string;
2899
- placeholder: string;
2900
- options: string;
3033
+ placeholder: string | null;
3034
+ options: string | null;
2901
3035
  boolean_answer: string;
2902
3036
  date_answer: string;
2903
3037
  time_answer: string;
@@ -2906,29 +3040,29 @@ export interface components {
2906
3040
  date_time_answer: string;
2907
3041
  is_required: string;
2908
3042
  in_use: string;
2909
- order: string;
2910
- company_id: string;
3043
+ order: number;
3044
+ company_id: number | null;
2911
3045
  default_answer: string;
2912
- company?: components["schemas"]["CompanyResource"];
3046
+ company?: components["schemas"]["CompanyResource"] | null;
2913
3047
  };
2914
3048
  /** CustomFieldValueResource */
2915
3049
  CustomFieldValueResource: {
2916
- id: string;
3050
+ id: number;
2917
3051
  custom_field_valuable_type: string;
2918
- custom_field_valuable_id: string;
3052
+ custom_field_valuable_id: number;
2919
3053
  type: string;
2920
- boolean_answer: string;
2921
- date_answer: string;
2922
- time_answer: string;
2923
- string_answer: string;
2924
- number_answer: string;
2925
- date_time_answer: string;
2926
- custom_field_id: string;
2927
- company_id: string;
3054
+ boolean_answer: string | null;
3055
+ date_answer: string | null;
3056
+ time_answer: string | null;
3057
+ string_answer: string | null;
3058
+ number_answer: string | null;
3059
+ date_time_answer: string | null;
3060
+ custom_field_id: number;
3061
+ company_id: number | null;
2928
3062
  default_answer: string;
2929
3063
  default_formatted_answer: string | null;
2930
3064
  custom_field?: components["schemas"]["CustomFieldResource"];
2931
- company?: components["schemas"]["CompanyResource"];
3065
+ company?: components["schemas"]["CompanyResource"] | null;
2932
3066
  };
2933
3067
  /** Customer */
2934
3068
  Customer: {
@@ -2971,6 +3105,13 @@ export interface components {
2971
3105
  phone?: string | null;
2972
3106
  fax?: string | null;
2973
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
+ }[];
2974
3115
  };
2975
3116
  /** CustomerResource */
2976
3117
  CustomerResource: {
@@ -3037,6 +3178,20 @@ export interface components {
3037
3178
  DeleteReceivedInvoicesRequest: {
3038
3179
  ids: string;
3039
3180
  };
3181
+ /**
3182
+ * DeleteRecurringInvoicesRequest
3183
+ * @description Borrado múltiple de facturas recurrentes (`POST /recurring-invoices/delete`).
3184
+ * Mismo patrón que DeleteEstimatesRequest / DeleteInvoiceRequest, que es como
3185
+ * se declara el resto de borrados múltiples del panel.
3186
+ *
3187
+ * El endpoint leía `$request->ids` sin validar y
3188
+ * `RecurringInvoice::deleteRecurringInvoice()` itera sin comprobar el `find()`,
3189
+ * así que un id inexistente reventaba con un 500. Con el `exists` pasa a ser un
3190
+ * 422 que dice cuál falla.
3191
+ */
3192
+ DeleteRecurringInvoicesRequest: {
3193
+ ids: number[];
3194
+ };
3040
3195
  /** DeleteSuppliersRequest */
3041
3196
  DeleteSuppliersRequest: {
3042
3197
  ids: number[];
@@ -3152,6 +3307,88 @@ export interface components {
3152
3307
  company?: components["schemas"]["CompanyResource"];
3153
3308
  currency?: components["schemas"]["CurrencyResource"];
3154
3309
  };
3310
+ /** EstimatesRequest */
3311
+ EstimatesRequest: {
3312
+ estimate_date: string;
3313
+ expiry_date?: string | null;
3314
+ customer_id?: number | null;
3315
+ lead_id?: number | null;
3316
+ /**
3317
+ * @description Opcional en el alta: si no llega, lo genera el servidor con el mismo
3318
+ * SerialNumberFormatter que alimenta a GET /next-number, que es de donde
3319
+ * lo saca el panel. Exigirlo obligaba a un cliente de la API a replicar el
3320
+ * formato de numeración de la empresa para poder crear un presupuesto.
3321
+ * En PUT sigue siendo obligatorio (más abajo): el documento ya tiene uno.
3322
+ */
3323
+ estimate_number?: string | null;
3324
+ exchange_rate?: string | null;
3325
+ /**
3326
+ * @description Descuento global: opcional en el contrato y rellenado a 0 en
3327
+ * prepareForValidation (el panel lo manda siempre, un cliente de la API
3328
+ * no tiene por qué). Ver DocumentHeaderPayload.
3329
+ */
3330
+ discount?: number | null;
3331
+ discount_val?: number | null;
3332
+ /**
3333
+ * @description Agregados: el servidor es su oráculo —DocumentTotals los recompone desde
3334
+ * las líneas y getEstimatePayload los sobrescribe—, así que exigirlos era
3335
+ * pedirle al cliente un cálculo que se iba a descartar. Si llegan, siguen
3336
+ * comprobándose contra las líneas (ValidatesDocumentTotals).
3337
+ */
3338
+ sub_total?: number | null;
3339
+ total?: number | null;
3340
+ tax?: string | null;
3341
+ template_name?: string | null;
3342
+ items: {
3343
+ description?: string | null;
3344
+ name: string;
3345
+ quantity: number;
3346
+ price: number;
3347
+ /**
3348
+ * @description Derivables: opcionales en el contrato y rellenados en prepareForValidation
3349
+ * (el panel los manda siempre; un cliente de la API no tiene por qué).
3350
+ */
3351
+ discount_val?: number | null;
3352
+ tax?: number | null;
3353
+ total?: number | null;
3354
+ /**
3355
+ * @description Impuestos. El importe es derivable a partir del porcentaje
3356
+ * (DocumentTaxPayload), así que un cliente de la API puede declarar
3357
+ * «IVA 21 %» sin calcular nada; el panel sigue mandándolo ya hecho.
3358
+ */
3359
+ taxes?: {
3360
+ tax_type_id?: number | null;
3361
+ percent?: number | null;
3362
+ amount?: number | null;
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
+ }[];
3371
+ }[];
3372
+ taxes?: {
3373
+ tax_type_id?: number | null;
3374
+ percent?: number | null;
3375
+ amount?: number | null;
3376
+ }[] | null;
3377
+ /**
3378
+ * @description Sin `in:YES,NO`: hay documentos antiguos persistidos con 'NO ' (el
3379
+ * espacio de más que arrastraba el payload de aquí), y el panel reenvía
3380
+ * al editar lo que leyó. Se normaliza al leerlo, no se rechaza.
3381
+ */
3382
+ tax_per_item?: string | null;
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
+ }[];
3391
+ };
3155
3392
  /** ExpenseCategoryRequest */
3156
3393
  ExpenseCategoryRequest: {
3157
3394
  name: string;
@@ -3167,6 +3404,28 @@ export interface components {
3167
3404
  formatted_created_at: string;
3168
3405
  company?: components["schemas"]["CompanyResource"];
3169
3406
  };
3407
+ /** ExpenseRequest */
3408
+ ExpenseRequest: {
3409
+ expense_date: string;
3410
+ expense_number?: string | null;
3411
+ expense_category_id: string;
3412
+ exchange_rate?: string | null;
3413
+ payment_method_id?: string | null;
3414
+ amount: string;
3415
+ customer_id?: string | null;
3416
+ supplier_id?: string | null;
3417
+ notes?: string | null;
3418
+ currency_id: string;
3419
+ /**
3420
+ * Format: binary
3421
+ * @description Maximum file size: 20000 kilobytes.
3422
+ */
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;
3428
+ };
3170
3429
  /** ExpenseResource */
3171
3430
  ExpenseResource: {
3172
3431
  id: string;
@@ -3331,6 +3590,22 @@ export interface components {
3331
3590
  company?: components["schemas"]["CompanyResource"];
3332
3591
  currency?: components["schemas"]["CurrencyResource"];
3333
3592
  };
3593
+ /**
3594
+ * InvoiceSeriesRequest
3595
+ * @description Serie de numeración de facturas. Reglas movidas literalmente desde el método
3596
+ * privado `InvoiceSeriesController::validatedData()`, que el generador del
3597
+ * OpenAPI no podía ver: solo recorre el AST de la propia acción, no los
3598
+ * ayudantes a los que llama. Ver docs/guia-integradores.md.
3599
+ */
3600
+ InvoiceSeriesRequest: {
3601
+ code: string;
3602
+ name: string;
3603
+ number_format?: string | null;
3604
+ default_template_id?: number | null;
3605
+ next_sequence?: number;
3606
+ is_default?: boolean;
3607
+ is_active?: boolean;
3608
+ };
3334
3609
  /** InvoiceSeriesResource */
3335
3610
  InvoiceSeriesResource: {
3336
3611
  id: string;
@@ -3349,6 +3624,46 @@ export interface components {
3349
3624
  created_at: string;
3350
3625
  updated_at: string;
3351
3626
  };
3627
+ /**
3628
+ * InvoiceTemplatePreviewRequest
3629
+ * @description Previsualización en PDF de una plantilla YA GUARDADA
3630
+ * (`POST /invoice-templates/{invoiceTemplate}/preview`).
3631
+ *
3632
+ * Ojo, el cuerpo aquí NO es el del previsualizador genérico
3633
+ * `POST /templates/preview` (ese sí recibe `config` y `base_template` sueltos y
3634
+ * los valida en línea, así que el OpenAPI ya los publicaba). En esta ruta
3635
+ * `InvoiceTemplateController::preview()` hace `merge()` de `config`,
3636
+ * `base_template` y `template_id` **desde la plantilla de la ruta**, pisando lo
3637
+ * que mande el cliente. Lo único que el cliente controla de verdad es lo de
3638
+ * abajo, y eso es lo que el contrato debe decir.
3639
+ */
3640
+ InvoiceTemplatePreviewRequest: {
3641
+ /**
3642
+ * @description Factura de la que sacar los datos de muestra. Sin ella se coge
3643
+ * una cualquiera de la compañía que tenga líneas y cliente.
3644
+ */
3645
+ invoice_id?: number | null;
3646
+ /**
3647
+ * @description Membrete aún no guardado (editor): data-URI para verlo al
3648
+ * instante. 5 MB de imagen ≈ 7 M de caracteres en base64.
3649
+ */
3650
+ letterhead?: string | null;
3651
+ };
3652
+ /**
3653
+ * InvoiceTemplateRequest
3654
+ * @description Plantilla de factura. Reglas movidas literalmente desde el método privado
3655
+ * `InvoiceTemplateController::validatedData()`, que el generador del OpenAPI no
3656
+ * podía ver: solo recorre el AST de la propia acción, no los ayudantes a los
3657
+ * que llama. Ver docs/guia-integradores.md.
3658
+ */
3659
+ InvoiceTemplateRequest: {
3660
+ name: string;
3661
+ slug?: string;
3662
+ /** @enum {string} */
3663
+ base_template?: "invoice1" | "invoice2" | "invoice3" | "invoice4" | "invoice5" | "invoice6" | "invoice7" | "invoice8" | "invoice9";
3664
+ config?: string[];
3665
+ is_default?: boolean;
3666
+ };
3352
3667
  /** InvoiceTemplateResource */
3353
3668
  InvoiceTemplateResource: {
3354
3669
  id: string;
@@ -3364,7 +3679,86 @@ export interface components {
3364
3679
  updated_at: string;
3365
3680
  };
3366
3681
  /** InvoicesRequest */
3367
- InvoicesRequest: Record<string, never>;
3682
+ InvoicesRequest: {
3683
+ invoice_date: string;
3684
+ due_date?: string | null;
3685
+ customer_id: number;
3686
+ invoice_number?: string | null;
3687
+ exchange_rate?: string | null;
3688
+ /**
3689
+ * @description Descuento global: opcional en el contrato y rellenado a 0 en
3690
+ * prepareForValidation (el panel lo manda siempre, un cliente de la API
3691
+ * no tiene por qué). Ver DocumentHeaderPayload.
3692
+ */
3693
+ discount?: number | null;
3694
+ discount_val?: number | null;
3695
+ /**
3696
+ * @description Agregados: el servidor es su oráculo —DocumentTotals los recompone desde
3697
+ * las líneas y getInvoicePayload los sobrescribe—, así que exigirlos era
3698
+ * pedirle al cliente un cálculo que se iba a descartar. Si llegan, siguen
3699
+ * comprobándose contra las líneas (ValidatesDocumentTotals).
3700
+ */
3701
+ sub_total?: number | null;
3702
+ total?: number | null;
3703
+ tax?: string | null;
3704
+ /**
3705
+ * @description Opcional como en EstimatesRequest: getInvoicePayload cae a 'invoice1'.
3706
+ * Exigirlo obligaba a un cliente de la API a conocer el nombre interno de
3707
+ * una plantilla para poder emitir una factura.
3708
+ */
3709
+ template_name?: string | null;
3710
+ invoice_series_id?: number | null;
3711
+ payment_method_id?: number | null;
3712
+ items: {
3713
+ description?: string | null;
3714
+ name: string;
3715
+ quantity: number;
3716
+ price: number;
3717
+ /**
3718
+ * @description Derivables: opcionales en el contrato y rellenados en prepareForValidation
3719
+ * (el panel los manda siempre; un cliente de la API no tiene por qué).
3720
+ */
3721
+ discount_val?: number | null;
3722
+ tax?: number | null;
3723
+ total?: number | null;
3724
+ /**
3725
+ * @description Impuestos. El importe es derivable a partir del porcentaje
3726
+ * (DocumentTaxPayload), así que un cliente de la API puede declarar
3727
+ * «IVA 21 %» sin calcular nada; el panel sigue mandándolo ya hecho.
3728
+ */
3729
+ taxes?: {
3730
+ tax_type_id?: number | null;
3731
+ percent?: number | null;
3732
+ amount?: number | null;
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
+ }[];
3741
+ }[];
3742
+ taxes?: {
3743
+ tax_type_id?: number | null;
3744
+ percent?: number | null;
3745
+ amount?: number | null;
3746
+ }[] | null;
3747
+ /**
3748
+ * @description Sin `in:YES,NO`: hay documentos antiguos persistidos con 'NO ' (el
3749
+ * espacio de más que arrastra EstimatesRequest), y el panel reenvía al
3750
+ * editar lo que leyó. Se normaliza al leerlo, no se rechaza.
3751
+ */
3752
+ tax_per_item?: string | null;
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
+ }[];
3761
+ };
3368
3762
  /** ItemCategory */
3369
3763
  ItemCategory: string[];
3370
3764
  /** ItemResource */
@@ -3421,6 +3815,8 @@ export interface components {
3421
3815
  stock_alert_qty?: number | null;
3422
3816
  allow_sale_without_stock?: boolean | null;
3423
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;
3424
3820
  };
3425
3821
  /** LeadActivity */
3426
3822
  LeadActivity: string[];
@@ -3500,14 +3896,20 @@ export interface components {
3500
3896
  name: string;
3501
3897
  } | null;
3502
3898
  };
3503
- /** LoginRequest */
3504
- LoginRequest: {
3505
- username: string;
3506
- password: string;
3507
- device_name: string;
3508
- };
3509
3899
  /** Note */
3510
- Note: string[];
3900
+ Note: {
3901
+ id: number;
3902
+ type: string;
3903
+ name: string | null;
3904
+ notes: string | null;
3905
+ noteable_type: string;
3906
+ noteable_id: number;
3907
+ company_id: number | null;
3908
+ /** Format: date-time */
3909
+ created_at: string | null;
3910
+ /** Format: date-time */
3911
+ updated_at: string | null;
3912
+ };
3511
3913
  /** PaymentMethodRequest */
3512
3914
  PaymentMethodRequest: {
3513
3915
  name: string;
@@ -3520,6 +3922,34 @@ export interface components {
3520
3922
  type: string;
3521
3923
  company?: components["schemas"]["CompanyResource"];
3522
3924
  };
3925
+ /** PaymentRequest */
3926
+ PaymentRequest: {
3927
+ payment_date: string;
3928
+ customer_id: string;
3929
+ exchange_rate?: string | null;
3930
+ amount: number;
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;
3942
+ invoice_id?: string | null;
3943
+ payment_method_id?: string | null;
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
+ }[];
3952
+ };
3523
3953
  /** PaymentResource */
3524
3954
  PaymentResource: {
3525
3955
  id: string;
@@ -3625,14 +4055,51 @@ export interface components {
3625
4055
  base_total: string;
3626
4056
  taxes?: components["schemas"]["TaxResource"][];
3627
4057
  };
3628
- /** ReceivedInvoiceResource */
3629
- ReceivedInvoiceResource: {
3630
- id: string;
4058
+ /** ReceivedInvoiceRequest */
4059
+ ReceivedInvoiceRequest: {
3631
4060
  received_invoice_date: string;
3632
- due_date: string;
3633
- received_invoice_number: string;
3634
- reference_number: string;
3635
- status: string;
4061
+ due_date?: string | null;
4062
+ supplier_id: string;
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;
4075
+ exchange_rate?: string | null;
4076
+ discount: number;
4077
+ discount_val: number;
4078
+ sub_total: number;
4079
+ total: number;
4080
+ tax: string;
4081
+ items: {
4082
+ name: string;
4083
+ quantity: number;
4084
+ price: number;
4085
+ description?: string | null;
4086
+ /**
4087
+ * @description Derivables: opcionales en el contrato y rellenados en prepareForValidation
4088
+ * (el panel los manda siempre; un cliente de la API no tiene por qué).
4089
+ */
4090
+ discount_val?: number | null;
4091
+ tax?: number | null;
4092
+ total?: number | null;
4093
+ }[];
4094
+ };
4095
+ /** ReceivedInvoiceResource */
4096
+ ReceivedInvoiceResource: {
4097
+ id: string;
4098
+ received_invoice_date: string;
4099
+ due_date: string;
4100
+ received_invoice_number: string;
4101
+ reference_number: string;
4102
+ status: string;
3636
4103
  paid_status: string;
3637
4104
  tax_per_item: string;
3638
4105
  discount_per_item: string;
@@ -3670,6 +4137,91 @@ export interface components {
3670
4137
  company?: components["schemas"]["CompanyResource"];
3671
4138
  currency?: components["schemas"]["CurrencyResource"];
3672
4139
  };
4140
+ /** RecurringInvoiceRequest */
4141
+ RecurringInvoiceRequest: {
4142
+ starts_at: string;
4143
+ /**
4144
+ * @description Los tres de abajo el panel los manda siempre porque su formulario los
4145
+ * tiene a mano (stub/recurring-invoice.js: send_automatically true, status
4146
+ * ACTIVE, limit_by NONE). Exigirlos obligaba a un cliente de la API a
4147
+ * declarar decisiones que tienen un valor por defecto obvio; los pone
4148
+ * getRecurringInvoicePayload con ese mismo valor.
4149
+ */
4150
+ send_automatically?: boolean | null;
4151
+ status?: string | null;
4152
+ limit_by?: string | null;
4153
+ customer_id: number;
4154
+ exchange_rate?: string | null;
4155
+ /**
4156
+ * @description Descuento global: opcional en el contrato y rellenado a 0 en
4157
+ * prepareForValidation (el panel lo manda siempre, un cliente de la API
4158
+ * no tiene por qué). Ver DocumentHeaderPayload.
4159
+ */
4160
+ discount?: number | null;
4161
+ discount_val?: number | null;
4162
+ /**
4163
+ * @description Agregados: desde este cambio el servidor es su oráculo también aquí
4164
+ * —DocumentTotals los recompone desde las líneas y
4165
+ * getRecurringInvoicePayload los sobrescribe—, así que exigirlos era
4166
+ * pedirle al cliente un cálculo que se va a descartar. Si llegan, se
4167
+ * comprueban contra las líneas (ValidatesDocumentTotals).
4168
+ */
4169
+ sub_total?: number | null;
4170
+ total?: number | null;
4171
+ tax?: string | null;
4172
+ /**
4173
+ * @description Igual que en facturas y presupuestos desde el #296: si no llega, la pone
4174
+ * el payload. Un cliente de la API no tiene por qué conocer el nombre
4175
+ * interno de una plantilla.
4176
+ */
4177
+ template_name?: string | null;
4178
+ frequency: string;
4179
+ limit_count?: string;
4180
+ limit_date?: string;
4181
+ items: {
4182
+ name: string;
4183
+ quantity: number;
4184
+ price: number;
4185
+ description?: string | null;
4186
+ /**
4187
+ * @description Derivables: opcionales en el contrato y rellenados en prepareForValidation
4188
+ * (el panel los manda siempre; un cliente de la API no tiene por qué).
4189
+ */
4190
+ discount_val?: number | null;
4191
+ tax?: number | null;
4192
+ total?: number | null;
4193
+ /**
4194
+ * @description Impuestos, por línea o de documento. El `amount` es opcional: si no
4195
+ * llega, lo deriva el servidor del porcentaje (DocumentTaxPayload), así
4196
+ * que un cliente de la API puede declarar «IVA 21 %» sin calcular nada;
4197
+ * el panel sigue mandándolo ya hecho.
4198
+ */
4199
+ taxes?: {
4200
+ tax_type_id?: number | null;
4201
+ percent?: number | null;
4202
+ amount?: number | null;
4203
+ }[] | null;
4204
+ }[];
4205
+ taxes?: {
4206
+ tax_type_id?: number | null;
4207
+ percent?: number | null;
4208
+ amount?: number | null;
4209
+ }[] | null;
4210
+ /**
4211
+ * @description Sin `in:YES,NO`: hay documentos antiguos persistidos con 'NO ' (el
4212
+ * espacio de más que arrastraba este mismo request), y el panel reenvía
4213
+ * al editar lo que leyó. Se normaliza al leerlo, no se rechaza.
4214
+ */
4215
+ tax_per_item?: string | null;
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
+ }[];
4224
+ };
3673
4225
  /** RecurringInvoiceResource */
3674
4226
  RecurringInvoiceResource: {
3675
4227
  id: string;
@@ -3713,7 +4265,16 @@ export interface components {
3713
4265
  currency?: components["schemas"]["CurrencyResource"];
3714
4266
  };
3715
4267
  /** Role */
3716
- Role: string[];
4268
+ Role: {
4269
+ id: number;
4270
+ name: string;
4271
+ title: string | null;
4272
+ scope: number | null;
4273
+ /** Format: date-time */
4274
+ created_at: string | null;
4275
+ /** Format: date-time */
4276
+ updated_at: string | null;
4277
+ };
3717
4278
  /** RoleResource */
3718
4279
  RoleResource: {
3719
4280
  id: string;
@@ -3723,7 +4284,12 @@ export interface components {
3723
4284
  formatted_created_at: string | null;
3724
4285
  abilities: string | string[];
3725
4286
  };
3726
- /** SendEstimatesRequest */
4287
+ /**
4288
+ * SendEstimatesRequest
4289
+ * @description Mandar un presupuesto por correo (`POST /estimates/{id}/send`) y su vista
4290
+ * previa. Todo el cuerpo —y el remitente que pone la instancia— está en
4291
+ * {@see SendDocumentMailRequest}.
4292
+ */
3727
4293
  SendEstimatesRequest: {
3728
4294
  subject: string;
3729
4295
  body: string;
@@ -3732,16 +4298,26 @@ export interface components {
3732
4298
  cc?: string | null;
3733
4299
  bcc?: string | null;
3734
4300
  };
3735
- /** SendInvoiceRequest */
4301
+ /**
4302
+ * SendInvoiceRequest
4303
+ * @description Mandar una factura por correo (`POST /invoices/{id}/send`) y su vista previa.
4304
+ * Todo el cuerpo —y el remitente que pone la instancia— está en
4305
+ * {@see SendDocumentMailRequest}.
4306
+ */
3736
4307
  SendInvoiceRequest: {
3737
- body: string;
3738
4308
  subject: string;
4309
+ body: string;
3739
4310
  from: string;
3740
4311
  to: string;
3741
4312
  cc?: string | null;
3742
4313
  bcc?: string | null;
3743
4314
  };
3744
- /** SendPaymentRequest */
4315
+ /**
4316
+ * SendPaymentRequest
4317
+ * @description Mandar un recibo de pago por correo (`POST /payments/{id}/send`) y su vista
4318
+ * previa. Todo el cuerpo —y el remitente que pone la instancia— está en
4319
+ * {@see SendDocumentMailRequest}.
4320
+ */
3745
4321
  SendPaymentRequest: {
3746
4322
  subject: string;
3747
4323
  body: string;
@@ -3756,6 +4332,54 @@ export interface components {
3756
4332
  formatted_execution_date: string;
3757
4333
  formatted_total: string;
3758
4334
  };
4335
+ /**
4336
+ * StoreApprovalRequest
4337
+ * @description POST /api/v1/approvals (paso 2, plataforma de integradores) — una app de
4338
+ * partner propone un write-effect sobre el tenant. La forma de `proposal` es
4339
+ * EXACTAMENTE la del contrato estructurado del flujo de delegación
4340
+ * (summary + changes[] + evals[], ver
4341
+ * {@see \App\Http\Controllers\Api\TenantDelegationCallbackController::structuredResultRules}):
4342
+ * misma primitiva, mismo panel, misma decisión del owner.
4343
+ *
4344
+ * La autorización NO va aquí: es scope (api.scopes, dominio `approvals`) +
4345
+ * credencial de partner (token OAuth con ability `approvals:write`), que el
4346
+ * controller comprueba explícitamente — el partner no es owner del tenant y no
4347
+ * pasa gate de Bouncer.
4348
+ */
4349
+ StoreApprovalRequest: {
4350
+ title: string;
4351
+ task_type?: string | null;
4352
+ context?: string | null;
4353
+ /** @description Propuesta estructurada — réplica del contrato del flujo actual. */
4354
+ proposal: {
4355
+ schema_version?: number | null;
4356
+ /** @enum {string|null} */
4357
+ mode?: "applied" | "preview" | null;
4358
+ agent_trace_id?: string | null;
4359
+ summary: string;
4360
+ changes?: {
4361
+ label: string;
4362
+ type?: string | null;
4363
+ action?: string | null;
4364
+ link?: string | null;
4365
+ record_id?: string | null;
4366
+ apply?: string[] | null;
4367
+ }[] | null;
4368
+ evals?: {
4369
+ label: string;
4370
+ pass: boolean;
4371
+ detail?: string | null;
4372
+ nivel?: number | null;
4373
+ cuenta_para_sello?: boolean | null;
4374
+ }[] | null;
4375
+ verifiability?: {
4376
+ nivel?: number | null;
4377
+ cuenta_para_sello?: boolean | null;
4378
+ /** @enum {string|null} */
4379
+ sello?: "pass" | "fail" | "n/a" | null;
4380
+ } | null;
4381
+ };
4382
+ };
3759
4383
  /** SupplierRequest */
3760
4384
  SupplierRequest: {
3761
4385
  name: string;
@@ -3790,6 +4414,13 @@ export interface components {
3790
4414
  phone?: string | null;
3791
4415
  fax?: string | null;
3792
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
+ }[];
3793
4424
  };
3794
4425
  /** SupplierResource */
3795
4426
  SupplierResource: {
@@ -3870,6 +4501,13 @@ export interface components {
3870
4501
  agent_skill: string | null;
3871
4502
  status: string;
3872
4503
  hermes_kanban_id: string | null;
4504
+ /**
4505
+ * @description Paso 2 (integradores): el panel pinta «propuesto por X» cuando la
4506
+ * propuesta viene de una app de partner y no del agente Pim.
4507
+ */
4508
+ plane: string;
4509
+ origin_client_id: string | null;
4510
+ origin_client_name: string | null;
3873
4511
  /** @description Lazo de verificar (Fase 2): lo que el panel pinta del callback. */
3874
4512
  result: string | null;
3875
4513
  result_data: unknown[] | null;
@@ -4065,16 +4703,16 @@ export interface components {
4065
4703
  formatted_created_at: string;
4066
4704
  currency?: components["schemas"]["CurrencyResource"];
4067
4705
  companies?: {
4068
- id: string;
4706
+ id: number;
4069
4707
  name: string;
4070
4708
  trade_name: string;
4071
- vat_id: string;
4709
+ vat_id: string | null;
4072
4710
  tax_id: string;
4073
- logo: string;
4711
+ logo: string | null;
4074
4712
  logo_path: string;
4075
- unique_hash: string;
4713
+ unique_hash: string | null;
4076
4714
  owner_id: string;
4077
- slug: string;
4715
+ slug: string | null;
4078
4716
  address?: components["schemas"]["AddressResource"];
4079
4717
  roles: components["schemas"]["RoleResource"][];
4080
4718
  role: string | null;
@@ -4133,7 +4771,11 @@ export interface operations {
4133
4771
  "accountingSummary.index": {
4134
4772
  parameters: {
4135
4773
  query?: {
4136
- year?: string;
4774
+ from_date?: string | null;
4775
+ to_date?: string | null;
4776
+ quarter?: number | null;
4777
+ year?: number | null;
4778
+ group_by?: "customer" | "category" | null;
4137
4779
  };
4138
4780
  header?: never;
4139
4781
  path?: never;
@@ -4158,9 +4800,38 @@ export interface operations {
4158
4800
  irpf: number;
4159
4801
  result: string;
4160
4802
  }[];
4803
+ } | {
4804
+ data: {
4805
+ from_date: unknown;
4806
+ to_date: unknown;
4807
+ total_sales: number;
4808
+ total_received: number;
4809
+ total_expenses: string;
4810
+ net_profit: string;
4811
+ vat_collected: number;
4812
+ vat_paid: number;
4813
+ vat_balance: string;
4814
+ irpf: number;
4815
+ invoices_count: number;
4816
+ received_invoices_count: number;
4817
+ expenses_count: number;
4818
+ tax_breakdown: {
4819
+ name: string;
4820
+ percent: number;
4821
+ base: number;
4822
+ tax_amount: number;
4823
+ }[];
4824
+ by_customer: {
4825
+ customer_name: string | "Sin cliente";
4826
+ total: number;
4827
+ count: number;
4828
+ }[];
4829
+ by_category: unknown[];
4830
+ };
4161
4831
  };
4162
4832
  };
4163
4833
  };
4834
+ 422: components["responses"]["ValidationException"];
4164
4835
  };
4165
4836
  };
4166
4837
  appVersion: {
@@ -4214,7 +4885,11 @@ export interface operations {
4214
4885
  path?: never;
4215
4886
  cookie?: never;
4216
4887
  };
4217
- requestBody?: never;
4888
+ requestBody: {
4889
+ content: {
4890
+ "application/json": components["schemas"]["AppointmentRequest"];
4891
+ };
4892
+ };
4218
4893
  responses: {
4219
4894
  200: {
4220
4895
  headers: {
@@ -4237,6 +4912,7 @@ export interface operations {
4237
4912
  };
4238
4913
  };
4239
4914
  };
4915
+ 422: components["responses"]["ValidationException"];
4240
4916
  };
4241
4917
  };
4242
4918
  "appointment.show": {
@@ -4274,7 +4950,11 @@ export interface operations {
4274
4950
  };
4275
4951
  cookie?: never;
4276
4952
  };
4277
- requestBody?: never;
4953
+ requestBody: {
4954
+ content: {
4955
+ "application/json": components["schemas"]["AppointmentRequest"];
4956
+ };
4957
+ };
4278
4958
  responses: {
4279
4959
  200: {
4280
4960
  headers: {
@@ -4287,6 +4967,7 @@ export interface operations {
4287
4967
  };
4288
4968
  };
4289
4969
  404: components["responses"]["ModelNotFoundException"];
4970
+ 422: components["responses"]["ValidationException"];
4290
4971
  };
4291
4972
  };
4292
4973
  "appointment.destroy": {
@@ -4314,7 +4995,7 @@ export interface operations {
4314
4995
  404: components["responses"]["ModelNotFoundException"];
4315
4996
  };
4316
4997
  };
4317
- "auth.login": {
4998
+ "approvals.store": {
4318
4999
  parameters: {
4319
5000
  query?: never;
4320
5001
  header?: never;
@@ -4323,30 +5004,75 @@ export interface operations {
4323
5004
  };
4324
5005
  requestBody: {
4325
5006
  content: {
4326
- "application/json": components["schemas"]["LoginRequest"];
5007
+ "application/json": components["schemas"]["StoreApprovalRequest"];
4327
5008
  };
4328
5009
  };
4329
5010
  responses: {
4330
- 200: {
5011
+ 201: {
5012
+ headers: {
5013
+ [name: string]: unknown;
5014
+ };
5015
+ content: {
5016
+ "application/json": {
5017
+ approval: {
5018
+ id: number;
5019
+ plane: string;
5020
+ title: string;
5021
+ task_type: string | null;
5022
+ context: unknown[] | null;
5023
+ /**
5024
+ * @description pending|in_progress|completed|failed — para el partner:
5025
+ * in_progress = pendiente de decisión; completed = aprobada;
5026
+ * failed = rechazada.
5027
+ */
5028
+ status: string;
5029
+ proposal: unknown[] | null;
5030
+ /**
5031
+ * @description proposed|needs_changes|approved|rejected. `needs_changes` NO es
5032
+ * terminal: el owner pidió una revisión — en v1 el partner remite
5033
+ * una propuesta nueva (no hay PATCH) o espera la decisión.
5034
+ */
5035
+ proposal_status: string | null;
5036
+ result: string | null;
5037
+ proposed_at: string;
5038
+ created_at: string;
5039
+ updated_at: string;
5040
+ };
5041
+ };
5042
+ };
5043
+ };
5044
+ 403: {
5045
+ headers: {
5046
+ [name: string]: unknown;
5047
+ };
5048
+ content: {
5049
+ "application/json": {
5050
+ /** @constant */
5051
+ message: "Este endpoint exige un token OAuth de app de partner con el scope approvals:write.";
5052
+ };
5053
+ };
5054
+ };
5055
+ 409: {
4331
5056
  headers: {
4332
5057
  [name: string]: unknown;
4333
5058
  };
4334
5059
  content: {
4335
5060
  "application/json": {
4336
5061
  /** @constant */
4337
- type: "Bearer";
4338
- token: string;
5062
+ message: "No hay un tenant en contexto para esta propuesta.";
4339
5063
  };
4340
5064
  };
4341
5065
  };
4342
5066
  422: components["responses"]["ValidationException"];
4343
5067
  };
4344
5068
  };
4345
- "auth.logout": {
5069
+ "approvals.show": {
4346
5070
  parameters: {
4347
5071
  query?: never;
4348
5072
  header?: never;
4349
- path?: never;
5073
+ path: {
5074
+ id: number;
5075
+ };
4350
5076
  cookie?: never;
4351
5077
  };
4352
5078
  requestBody?: never;
@@ -4357,27 +5083,53 @@ export interface operations {
4357
5083
  };
4358
5084
  content: {
4359
5085
  "application/json": {
4360
- success: boolean;
5086
+ approval: {
5087
+ id: number;
5088
+ plane: string;
5089
+ title: string;
5090
+ task_type: string | null;
5091
+ context: unknown[] | null;
5092
+ /**
5093
+ * @description pending|in_progress|completed|failed — para el partner:
5094
+ * in_progress = pendiente de decisión; completed = aprobada;
5095
+ * failed = rechazada.
5096
+ */
5097
+ status: string;
5098
+ proposal: unknown[] | null;
5099
+ /**
5100
+ * @description proposed|needs_changes|approved|rejected. `needs_changes` NO es
5101
+ * terminal: el owner pidió una revisión — en v1 el partner remite
5102
+ * una propuesta nueva (no hay PATCH) o espera la decisión.
5103
+ */
5104
+ proposal_status: string | null;
5105
+ result: string | null;
5106
+ proposed_at: string;
5107
+ created_at: string;
5108
+ updated_at: string;
5109
+ };
4361
5110
  };
4362
5111
  };
4363
5112
  };
4364
- };
4365
- };
4366
- "auth.check": {
4367
- parameters: {
4368
- query?: never;
4369
- header?: never;
4370
- path?: never;
4371
- cookie?: never;
4372
- };
4373
- requestBody?: never;
4374
- responses: {
4375
- 200: {
5113
+ 403: {
4376
5114
  headers: {
4377
5115
  [name: string]: unknown;
4378
5116
  };
4379
5117
  content: {
4380
- "application/json": boolean;
5118
+ "application/json": {
5119
+ /** @constant */
5120
+ message: "Este endpoint exige un token OAuth de app de partner con el scope approvals:write.";
5121
+ };
5122
+ };
5123
+ };
5124
+ 409: {
5125
+ headers: {
5126
+ [name: string]: unknown;
5127
+ };
5128
+ content: {
5129
+ "application/json": {
5130
+ /** @constant */
5131
+ message: "No hay un tenant en contexto para esta propuesta.";
5132
+ };
4381
5133
  };
4382
5134
  };
4383
5135
  };
@@ -4730,7 +5482,11 @@ export interface operations {
4730
5482
  };
4731
5483
  cookie?: never;
4732
5484
  };
4733
- requestBody?: never;
5485
+ requestBody: {
5486
+ content: {
5487
+ "application/json": components["schemas"]["ChangeInvoiceStatusRequest"];
5488
+ };
5489
+ };
4734
5490
  responses: {
4735
5491
  200: {
4736
5492
  headers: {
@@ -4754,26 +5510,7 @@ export interface operations {
4754
5510
  };
4755
5511
  };
4756
5512
  403: components["responses"]["AuthorizationException"];
4757
- 422: {
4758
- headers: {
4759
- [name: string]: unknown;
4760
- };
4761
- content: {
4762
- "application/json": {
4763
- success: boolean;
4764
- /** @constant */
4765
- message: "Solo se pueden completar facturas ya publicadas o enviadas.";
4766
- } | {
4767
- success: boolean;
4768
- /** @constant */
4769
- message: "Solo se pueden enviar facturas en estado borrador o publicada.";
4770
- } | {
4771
- success: boolean;
4772
- /** @constant */
4773
- message: "Solo se pueden publicar facturas en estado borrador.";
4774
- };
4775
- };
4776
- };
5513
+ 422: components["responses"]["ValidationException"];
4777
5514
  };
4778
5515
  };
4779
5516
  "estimate.cloneEstimate": {
@@ -4939,167 +5676,303 @@ export interface operations {
4939
5676
  };
4940
5677
  requestBody?: never;
4941
5678
  responses: {
4942
- /** @description `ContactResource` */
5679
+ /** @description `ContactResource` */
5680
+ 200: {
5681
+ headers: {
5682
+ [name: string]: unknown;
5683
+ };
5684
+ content: {
5685
+ "application/json": {
5686
+ data: components["schemas"]["ContactResource"];
5687
+ };
5688
+ };
5689
+ };
5690
+ 403: components["responses"]["AuthorizationException"];
5691
+ 404: components["responses"]["ModelNotFoundException"];
5692
+ };
5693
+ };
5694
+ "contact.update": {
5695
+ parameters: {
5696
+ query?: never;
5697
+ header?: never;
5698
+ path: {
5699
+ /** @description The contact ID */
5700
+ contact: number;
5701
+ };
5702
+ cookie?: never;
5703
+ };
5704
+ requestBody: {
5705
+ content: {
5706
+ "application/json": components["schemas"]["ContactRequest"];
5707
+ };
5708
+ };
5709
+ responses: {
5710
+ /** @description `ContactResource` */
5711
+ 200: {
5712
+ headers: {
5713
+ [name: string]: unknown;
5714
+ };
5715
+ content: {
5716
+ "application/json": {
5717
+ data: components["schemas"]["ContactResource"];
5718
+ };
5719
+ };
5720
+ };
5721
+ 403: components["responses"]["AuthorizationException"];
5722
+ 404: components["responses"]["ModelNotFoundException"];
5723
+ 422: components["responses"]["ValidationException"];
5724
+ };
5725
+ };
5726
+ "contact.destroy": {
5727
+ parameters: {
5728
+ query?: never;
5729
+ header?: never;
5730
+ path: {
5731
+ /** @description The contact ID */
5732
+ contact: number;
5733
+ };
5734
+ cookie?: never;
5735
+ };
5736
+ requestBody?: never;
5737
+ responses: {
5738
+ 200: {
5739
+ headers: {
5740
+ [name: string]: unknown;
5741
+ };
5742
+ content: {
5743
+ "application/json": {
5744
+ success: boolean;
5745
+ };
5746
+ };
5747
+ };
5748
+ 403: components["responses"]["AuthorizationException"];
5749
+ 404: components["responses"]["ModelNotFoundException"];
5750
+ };
5751
+ };
5752
+ "estimate.convertEstimate": {
5753
+ parameters: {
5754
+ query?: never;
5755
+ header?: never;
5756
+ path: {
5757
+ /** @description The estimate ID */
5758
+ estimate: number;
5759
+ };
5760
+ cookie?: never;
5761
+ };
5762
+ requestBody?: never;
5763
+ responses: {
5764
+ 200: {
5765
+ headers: {
5766
+ [name: string]: unknown;
5767
+ };
5768
+ content: {
5769
+ "application/json": Record<string, never>;
5770
+ };
5771
+ };
5772
+ 403: components["responses"]["AuthorizationException"];
5773
+ 404: components["responses"]["ModelNotFoundException"];
5774
+ };
5775
+ };
5776
+ "general.countries": {
5777
+ parameters: {
5778
+ query?: never;
5779
+ header?: never;
5780
+ path?: never;
5781
+ cookie?: never;
5782
+ };
5783
+ requestBody?: never;
5784
+ responses: {
5785
+ /** @description Array of `CountryResource` */
5786
+ 200: {
5787
+ headers: {
5788
+ [name: string]: unknown;
5789
+ };
5790
+ content: {
5791
+ "application/json": {
5792
+ data: components["schemas"]["CountryResource"][];
5793
+ };
5794
+ };
5795
+ };
5796
+ };
5797
+ };
5798
+ "invoice.creditNote": {
5799
+ parameters: {
5800
+ query?: never;
5801
+ header?: never;
5802
+ path: {
5803
+ invoice: string;
5804
+ };
5805
+ cookie?: never;
5806
+ };
5807
+ requestBody?: never;
5808
+ responses: {
4943
5809
  200: {
4944
5810
  headers: {
4945
5811
  [name: string]: unknown;
4946
5812
  };
4947
5813
  content: {
4948
- "application/json": {
4949
- data: components["schemas"]["ContactResource"];
4950
- };
5814
+ "application/json": Record<string, never>;
4951
5815
  };
4952
5816
  };
4953
5817
  403: components["responses"]["AuthorizationException"];
4954
- 404: components["responses"]["ModelNotFoundException"];
4955
5818
  };
4956
5819
  };
4957
- "contact.update": {
5820
+ "general.currencies": {
4958
5821
  parameters: {
4959
5822
  query?: never;
4960
5823
  header?: never;
4961
- path: {
4962
- /** @description The contact ID */
4963
- contact: number;
4964
- };
5824
+ path?: never;
4965
5825
  cookie?: never;
4966
5826
  };
4967
- requestBody: {
4968
- content: {
4969
- "application/json": components["schemas"]["ContactRequest"];
4970
- };
4971
- };
5827
+ requestBody?: never;
4972
5828
  responses: {
4973
- /** @description `ContactResource` */
5829
+ /** @description Array of `CurrencyResource` */
4974
5830
  200: {
4975
5831
  headers: {
4976
5832
  [name: string]: unknown;
4977
5833
  };
4978
5834
  content: {
4979
5835
  "application/json": {
4980
- data: components["schemas"]["ContactResource"];
5836
+ data: components["schemas"]["CurrencyResource"][];
4981
5837
  };
4982
5838
  };
4983
5839
  };
4984
- 403: components["responses"]["AuthorizationException"];
4985
- 404: components["responses"]["ModelNotFoundException"];
4986
- 422: components["responses"]["ValidationException"];
4987
5840
  };
4988
5841
  };
4989
- "contact.destroy": {
5842
+ "custom-fields.index": {
4990
5843
  parameters: {
4991
5844
  query?: never;
4992
5845
  header?: never;
4993
- path: {
4994
- /** @description The contact ID */
4995
- contact: number;
4996
- };
5846
+ path?: never;
4997
5847
  cookie?: never;
4998
5848
  };
4999
5849
  requestBody?: never;
5000
5850
  responses: {
5851
+ /** @description Array of `CustomFieldResource` */
5001
5852
  200: {
5002
5853
  headers: {
5003
5854
  [name: string]: unknown;
5004
5855
  };
5005
5856
  content: {
5006
5857
  "application/json": {
5007
- success: boolean;
5858
+ data: components["schemas"]["CustomFieldResource"][];
5008
5859
  };
5009
5860
  };
5010
5861
  };
5011
5862
  403: components["responses"]["AuthorizationException"];
5012
- 404: components["responses"]["ModelNotFoundException"];
5013
5863
  };
5014
5864
  };
5015
- "estimate.convertEstimate": {
5865
+ "custom-fields.store": {
5016
5866
  parameters: {
5017
5867
  query?: never;
5018
5868
  header?: never;
5019
- path: {
5020
- /** @description The estimate ID */
5021
- estimate: number;
5022
- };
5869
+ path?: never;
5023
5870
  cookie?: never;
5024
5871
  };
5025
- requestBody?: never;
5872
+ requestBody: {
5873
+ content: {
5874
+ "application/json": components["schemas"]["CustomFieldRequest"];
5875
+ };
5876
+ };
5026
5877
  responses: {
5878
+ /** @description `CustomFieldResource` */
5027
5879
  200: {
5028
5880
  headers: {
5029
5881
  [name: string]: unknown;
5030
5882
  };
5031
5883
  content: {
5032
- "application/json": Record<string, never>;
5884
+ "application/json": {
5885
+ data: components["schemas"]["CustomFieldResource"];
5886
+ };
5033
5887
  };
5034
5888
  };
5035
5889
  403: components["responses"]["AuthorizationException"];
5036
- 404: components["responses"]["ModelNotFoundException"];
5890
+ 422: components["responses"]["ValidationException"];
5037
5891
  };
5038
5892
  };
5039
- "general.countries": {
5893
+ "custom-fields.show": {
5040
5894
  parameters: {
5041
5895
  query?: never;
5042
5896
  header?: never;
5043
- path?: never;
5897
+ path: {
5898
+ /** @description The custom field ID */
5899
+ customField: number;
5900
+ };
5044
5901
  cookie?: never;
5045
5902
  };
5046
5903
  requestBody?: never;
5047
5904
  responses: {
5048
- /** @description Array of `CountryResource` */
5905
+ /** @description `CustomFieldResource` */
5049
5906
  200: {
5050
5907
  headers: {
5051
5908
  [name: string]: unknown;
5052
5909
  };
5053
5910
  content: {
5054
5911
  "application/json": {
5055
- data: components["schemas"]["CountryResource"][];
5912
+ data: components["schemas"]["CustomFieldResource"];
5056
5913
  };
5057
5914
  };
5058
5915
  };
5916
+ 403: components["responses"]["AuthorizationException"];
5917
+ 404: components["responses"]["ModelNotFoundException"];
5059
5918
  };
5060
5919
  };
5061
- "invoice.creditNote": {
5920
+ "custom-fields.update": {
5062
5921
  parameters: {
5063
5922
  query?: never;
5064
5923
  header?: never;
5065
5924
  path: {
5066
- invoice: string;
5925
+ /** @description The custom field ID */
5926
+ customField: number;
5067
5927
  };
5068
5928
  cookie?: never;
5069
5929
  };
5070
- requestBody?: never;
5930
+ requestBody: {
5931
+ content: {
5932
+ "application/json": components["schemas"]["CustomFieldRequest"];
5933
+ };
5934
+ };
5071
5935
  responses: {
5936
+ /** @description `CustomFieldResource` */
5072
5937
  200: {
5073
5938
  headers: {
5074
5939
  [name: string]: unknown;
5075
5940
  };
5076
5941
  content: {
5077
- "application/json": Record<string, never>;
5942
+ "application/json": {
5943
+ data: components["schemas"]["CustomFieldResource"];
5944
+ };
5078
5945
  };
5079
5946
  };
5080
5947
  403: components["responses"]["AuthorizationException"];
5948
+ 404: components["responses"]["ModelNotFoundException"];
5949
+ 422: components["responses"]["ValidationException"];
5081
5950
  };
5082
5951
  };
5083
- "general.currencies": {
5952
+ "custom-fields.destroy": {
5084
5953
  parameters: {
5085
5954
  query?: never;
5086
5955
  header?: never;
5087
- path?: never;
5956
+ path: {
5957
+ /** @description The custom field ID */
5958
+ customField: number;
5959
+ };
5088
5960
  cookie?: never;
5089
5961
  };
5090
5962
  requestBody?: never;
5091
5963
  responses: {
5092
- /** @description Array of `CurrencyResource` */
5093
5964
  200: {
5094
5965
  headers: {
5095
5966
  [name: string]: unknown;
5096
5967
  };
5097
5968
  content: {
5098
5969
  "application/json": {
5099
- data: components["schemas"]["CurrencyResource"][];
5970
+ success: boolean;
5100
5971
  };
5101
5972
  };
5102
5973
  };
5974
+ 403: components["responses"]["AuthorizationException"];
5975
+ 404: components["responses"]["ModelNotFoundException"];
5103
5976
  };
5104
5977
  };
5105
5978
  "customer.customerStats": {
@@ -5790,7 +6663,11 @@ export interface operations {
5790
6663
  path?: never;
5791
6664
  cookie?: never;
5792
6665
  };
5793
- requestBody?: never;
6666
+ requestBody: {
6667
+ content: {
6668
+ "application/json": components["schemas"]["EstimatesRequest"];
6669
+ };
6670
+ };
5794
6671
  responses: {
5795
6672
  /** @description `EstimateResource` */
5796
6673
  200: {
@@ -5844,7 +6721,11 @@ export interface operations {
5844
6721
  };
5845
6722
  cookie?: never;
5846
6723
  };
5847
- requestBody?: never;
6724
+ requestBody: {
6725
+ content: {
6726
+ "application/json": components["schemas"]["EstimatesRequest"];
6727
+ };
6728
+ };
5848
6729
  responses: {
5849
6730
  /** @description `EstimateResource` */
5850
6731
  200: {
@@ -6056,7 +6937,11 @@ export interface operations {
6056
6937
  path?: never;
6057
6938
  cookie?: never;
6058
6939
  };
6059
- requestBody?: never;
6940
+ requestBody: {
6941
+ content: {
6942
+ "multipart/form-data": components["schemas"]["ExpenseRequest"];
6943
+ };
6944
+ };
6060
6945
  responses: {
6061
6946
  /** @description `ExpenseResource` */
6062
6947
  200: {
@@ -6110,7 +6995,11 @@ export interface operations {
6110
6995
  };
6111
6996
  cookie?: never;
6112
6997
  };
6113
- requestBody?: never;
6998
+ requestBody: {
6999
+ content: {
7000
+ "multipart/form-data": components["schemas"]["ExpenseRequest"];
7001
+ };
7002
+ };
6114
7003
  responses: {
6115
7004
  /** @description `ExpenseResource` */
6116
7005
  200: {
@@ -6229,40 +7118,6 @@ export interface operations {
6229
7118
  422: components["responses"]["ValidationException"];
6230
7119
  };
6231
7120
  };
6232
- "forgotPassword.sendResetLinkEmail": {
6233
- parameters: {
6234
- query?: never;
6235
- header?: never;
6236
- path?: never;
6237
- cookie?: never;
6238
- };
6239
- requestBody?: never;
6240
- responses: {
6241
- 200: {
6242
- headers: {
6243
- [name: string]: unknown;
6244
- };
6245
- content: {
6246
- "application/json": {
6247
- /** @constant */
6248
- message: "Password reset email sent.";
6249
- data: string;
6250
- };
6251
- };
6252
- };
6253
- 403: {
6254
- headers: {
6255
- [name: string]: unknown;
6256
- };
6257
- content: {
6258
- "application/json": {
6259
- /** @constant */
6260
- error: "Email could not be sent to this email address.";
6261
- };
6262
- };
6263
- };
6264
- };
6265
- };
6266
7121
  "exchangeRate.getActiveProvider": {
6267
7122
  parameters: {
6268
7123
  query?: never;
@@ -6651,7 +7506,11 @@ export interface operations {
6651
7506
  path?: never;
6652
7507
  cookie?: never;
6653
7508
  };
6654
- requestBody?: never;
7509
+ requestBody: {
7510
+ content: {
7511
+ "application/json": components["schemas"]["InvoiceSeriesRequest"];
7512
+ };
7513
+ };
6655
7514
  responses: {
6656
7515
  /** @description `InvoiceSeriesResource` */
6657
7516
  200: {
@@ -6665,6 +7524,7 @@ export interface operations {
6665
7524
  };
6666
7525
  };
6667
7526
  403: components["responses"]["AuthorizationException"];
7527
+ 422: components["responses"]["ValidationException"];
6668
7528
  };
6669
7529
  };
6670
7530
  "invoice-series.show": {
@@ -6704,7 +7564,11 @@ export interface operations {
6704
7564
  };
6705
7565
  cookie?: never;
6706
7566
  };
6707
- requestBody?: never;
7567
+ requestBody: {
7568
+ content: {
7569
+ "application/json": components["schemas"]["InvoiceSeriesRequest"];
7570
+ };
7571
+ };
6708
7572
  responses: {
6709
7573
  /** @description `InvoiceSeriesResource` */
6710
7574
  200: {
@@ -6719,6 +7583,7 @@ export interface operations {
6719
7583
  };
6720
7584
  403: components["responses"]["AuthorizationException"];
6721
7585
  404: components["responses"]["ModelNotFoundException"];
7586
+ 422: components["responses"]["ValidationException"];
6722
7587
  };
6723
7588
  };
6724
7589
  "invoice-series.destroy": {
@@ -6804,7 +7669,11 @@ export interface operations {
6804
7669
  };
6805
7670
  cookie?: never;
6806
7671
  };
6807
- requestBody?: never;
7672
+ requestBody?: {
7673
+ content: {
7674
+ "application/json": components["schemas"]["InvoiceTemplatePreviewRequest"];
7675
+ };
7676
+ };
6808
7677
  responses: {
6809
7678
  200: {
6810
7679
  headers: {
@@ -6816,6 +7685,7 @@ export interface operations {
6816
7685
  };
6817
7686
  403: components["responses"]["AuthorizationException"];
6818
7687
  404: components["responses"]["ModelNotFoundException"];
7688
+ 422: components["responses"]["ValidationException"];
6819
7689
  };
6820
7690
  };
6821
7691
  "invoiceTemplate.showLetterhead": {
@@ -6936,7 +7806,11 @@ export interface operations {
6936
7806
  path?: never;
6937
7807
  cookie?: never;
6938
7808
  };
6939
- requestBody?: never;
7809
+ requestBody: {
7810
+ content: {
7811
+ "application/json": components["schemas"]["InvoiceTemplateRequest"];
7812
+ };
7813
+ };
6940
7814
  responses: {
6941
7815
  /** @description `InvoiceTemplateResource` */
6942
7816
  200: {
@@ -6950,6 +7824,7 @@ export interface operations {
6950
7824
  };
6951
7825
  };
6952
7826
  403: components["responses"]["AuthorizationException"];
7827
+ 422: components["responses"]["ValidationException"];
6953
7828
  };
6954
7829
  };
6955
7830
  "invoice-templates.show": {
@@ -6989,7 +7864,11 @@ export interface operations {
6989
7864
  };
6990
7865
  cookie?: never;
6991
7866
  };
6992
- requestBody?: never;
7867
+ requestBody: {
7868
+ content: {
7869
+ "application/json": components["schemas"]["InvoiceTemplateRequest"];
7870
+ };
7871
+ };
6993
7872
  responses: {
6994
7873
  /** @description `InvoiceTemplateResource` */
6995
7874
  200: {
@@ -7004,17 +7883,7 @@ export interface operations {
7004
7883
  };
7005
7884
  403: components["responses"]["AuthorizationException"];
7006
7885
  404: components["responses"]["ModelNotFoundException"];
7007
- 422: {
7008
- headers: {
7009
- [name: string]: unknown;
7010
- };
7011
- content: {
7012
- "application/json": {
7013
- /** @constant */
7014
- message: "Las plantillas del sistema no se pueden modificar. Crea una copia para personalizarla.";
7015
- };
7016
- };
7017
- };
7886
+ 422: components["responses"]["ValidationException"];
7018
7887
  };
7019
7888
  };
7020
7889
  "invoice-templates.destroy": {
@@ -7175,11 +8044,9 @@ export interface operations {
7175
8044
  path?: never;
7176
8045
  cookie?: never;
7177
8046
  };
7178
- requestBody?: {
8047
+ requestBody: {
7179
8048
  content: {
7180
- "application/json": components["schemas"]["InvoicesRequest"] & {
7181
- items?: string;
7182
- };
8049
+ "application/json": components["schemas"]["InvoicesRequest"];
7183
8050
  };
7184
8051
  };
7185
8052
  responses: {
@@ -7232,11 +8099,9 @@ export interface operations {
7232
8099
  };
7233
8100
  cookie?: never;
7234
8101
  };
7235
- requestBody?: {
8102
+ requestBody: {
7236
8103
  content: {
7237
- "application/json": components["schemas"]["InvoicesRequest"] & {
7238
- items?: string;
7239
- };
8104
+ "application/json": components["schemas"]["InvoicesRequest"];
7240
8105
  };
7241
8106
  };
7242
8107
  responses: {
@@ -7984,9 +8849,17 @@ export interface operations {
7984
8849
  };
7985
8850
  "general.nextNumber": {
7986
8851
  parameters: {
7987
- query?: {
7988
- invoice_series_id?: string;
7989
- series_id?: string;
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;
7990
8863
  };
7991
8864
  header?: never;
7992
8865
  path?: never;
@@ -7994,12 +8867,18 @@ export interface operations {
7994
8867
  };
7995
8868
  requestBody?: never;
7996
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. */
7997
8871
  200: {
7998
8872
  headers: {
7999
8873
  [name: string]: unknown;
8000
8874
  };
8001
8875
  content: {
8002
- "application/json": Record<string, never>;
8876
+ "application/json": {
8877
+ success: boolean;
8878
+ nextNumber: string | null;
8879
+ isUsed: boolean;
8880
+ message?: string;
8881
+ };
8003
8882
  };
8004
8883
  };
8005
8884
  };
@@ -8317,7 +9196,11 @@ export interface operations {
8317
9196
  path?: never;
8318
9197
  cookie?: never;
8319
9198
  };
8320
- requestBody?: never;
9199
+ requestBody: {
9200
+ content: {
9201
+ "application/json": components["schemas"]["PaymentRequest"];
9202
+ };
9203
+ };
8321
9204
  responses: {
8322
9205
  /** @description `PaymentResource` */
8323
9206
  200: {
@@ -8371,7 +9254,11 @@ export interface operations {
8371
9254
  };
8372
9255
  cookie?: never;
8373
9256
  };
8374
- requestBody?: never;
9257
+ requestBody: {
9258
+ content: {
9259
+ "application/json": components["schemas"]["PaymentRequest"];
9260
+ };
9261
+ };
8375
9262
  responses: {
8376
9263
  /** @description `PaymentResource` */
8377
9264
  200: {
@@ -8829,7 +9716,11 @@ export interface operations {
8829
9716
  path?: never;
8830
9717
  cookie?: never;
8831
9718
  };
8832
- requestBody?: never;
9719
+ requestBody: {
9720
+ content: {
9721
+ "application/json": components["schemas"]["ReceivedInvoiceRequest"];
9722
+ };
9723
+ };
8833
9724
  responses: {
8834
9725
  /** @description `ReceivedInvoiceResource` */
8835
9726
  200: {
@@ -8881,7 +9772,11 @@ export interface operations {
8881
9772
  };
8882
9773
  cookie?: never;
8883
9774
  };
8884
- requestBody?: never;
9775
+ requestBody: {
9776
+ content: {
9777
+ "application/json": components["schemas"]["ReceivedInvoiceRequest"];
9778
+ };
9779
+ };
8885
9780
  responses: {
8886
9781
  /** @description `ReceivedInvoiceResource` */
8887
9782
  200: {
@@ -9171,7 +10066,11 @@ export interface operations {
9171
10066
  path?: never;
9172
10067
  cookie?: never;
9173
10068
  };
9174
- requestBody?: never;
10069
+ requestBody: {
10070
+ content: {
10071
+ "application/json": components["schemas"]["DeleteRecurringInvoicesRequest"];
10072
+ };
10073
+ };
9175
10074
  responses: {
9176
10075
  200: {
9177
10076
  headers: {
@@ -9184,6 +10083,7 @@ export interface operations {
9184
10083
  };
9185
10084
  };
9186
10085
  403: components["responses"]["AuthorizationException"];
10086
+ 422: components["responses"]["ValidationException"];
9187
10087
  };
9188
10088
  };
9189
10089
  "recurring-invoices.index": {
@@ -9219,7 +10119,11 @@ export interface operations {
9219
10119
  path?: never;
9220
10120
  cookie?: never;
9221
10121
  };
9222
- requestBody?: never;
10122
+ requestBody: {
10123
+ content: {
10124
+ "application/json": components["schemas"]["RecurringInvoiceRequest"];
10125
+ };
10126
+ };
9223
10127
  responses: {
9224
10128
  /** @description `RecurringInvoiceResource` */
9225
10129
  200: {
@@ -9273,7 +10177,11 @@ export interface operations {
9273
10177
  };
9274
10178
  cookie?: never;
9275
10179
  };
9276
- requestBody?: never;
10180
+ requestBody: {
10181
+ content: {
10182
+ "application/json": components["schemas"]["RecurringInvoiceRequest"];
10183
+ };
10184
+ };
9277
10185
  responses: {
9278
10186
  /** @description `RecurringInvoiceResource` */
9279
10187
  200: {
@@ -9313,39 +10221,6 @@ export interface operations {
9313
10221
  };
9314
10222
  };
9315
10223
  };
9316
- "resetPassword.reset": {
9317
- parameters: {
9318
- query?: never;
9319
- header?: never;
9320
- path?: never;
9321
- cookie?: never;
9322
- };
9323
- requestBody: {
9324
- content: {
9325
- "application/json": {
9326
- token: string;
9327
- /** Format: email */
9328
- email: string;
9329
- password: string;
9330
- password_confirmation: string;
9331
- };
9332
- };
9333
- };
9334
- responses: {
9335
- 200: {
9336
- headers: {
9337
- [name: string]: unknown;
9338
- };
9339
- content: {
9340
- "application/json": {
9341
- /** @constant */
9342
- message: "Password reset successfully.";
9343
- } | Record<string, never>;
9344
- };
9345
- };
9346
- 422: components["responses"]["ValidationException"];
9347
- };
9348
- };
9349
10224
  "general.search": {
9350
10225
  parameters: {
9351
10226
  query?: never;
@@ -9535,8 +10410,8 @@ export interface operations {
9535
10410
  "invoice.sendInvoicePreview": {
9536
10411
  parameters: {
9537
10412
  query: {
9538
- body: string;
9539
10413
  subject: string;
10414
+ body: string;
9540
10415
  from: string;
9541
10416
  to: string;
9542
10417
  cc?: string | null;
@@ -9597,7 +10472,14 @@ export interface operations {
9597
10472
  };
9598
10473
  "payment.sendPaymentPreview": {
9599
10474
  parameters: {
9600
- query?: never;
10475
+ query: {
10476
+ subject: string;
10477
+ body: string;
10478
+ from: string;
10479
+ to: string;
10480
+ cc?: string | null;
10481
+ bcc?: string | null;
10482
+ };
9601
10483
  header?: never;
9602
10484
  path: {
9603
10485
  /** @description The payment ID */
@@ -9617,6 +10499,7 @@ export interface operations {
9617
10499
  };
9618
10500
  403: components["responses"]["AuthorizationException"];
9619
10501
  404: components["responses"]["ModelNotFoundException"];
10502
+ 422: components["responses"]["ValidationException"];
9620
10503
  };
9621
10504
  };
9622
10505
  "sepaRemittance.eligibleInvoices": {
@@ -10018,6 +10901,13 @@ export interface operations {
10018
10901
  agent_skill: string | null;
10019
10902
  status: string;
10020
10903
  hermes_kanban_id: string | null;
10904
+ /**
10905
+ * @description Paso 2 (integradores): el panel pinta «propuesto por X» cuando la
10906
+ * propuesta viene de una app de partner y no del agente Pim.
10907
+ */
10908
+ plane: string;
10909
+ origin_client_id: string | null;
10910
+ origin_client_name: string | null;
10021
10911
  /** @description Lazo de verificar (Fase 2): lo que el panel pinta del callback. */
10022
10912
  result: string | null;
10023
10913
  result_data: unknown[] | null;
@@ -10068,6 +10958,13 @@ export interface operations {
10068
10958
  agent_skill: string | null;
10069
10959
  status: string;
10070
10960
  hermes_kanban_id: string | null;
10961
+ /**
10962
+ * @description Paso 2 (integradores): el panel pinta «propuesto por X» cuando la
10963
+ * propuesta viene de una app de partner y no del agente Pim.
10964
+ */
10965
+ plane: string;
10966
+ origin_client_id: string | null;
10967
+ origin_client_name: string | null;
10071
10968
  /** @description Lazo de verificar (Fase 2): lo que el panel pinta del callback. */
10072
10969
  result: string | null;
10073
10970
  result_data: unknown[] | null;
@@ -10100,6 +10997,13 @@ export interface operations {
10100
10997
  agent_skill: string | null;
10101
10998
  status: string;
10102
10999
  hermes_kanban_id: string | null;
11000
+ /**
11001
+ * @description Paso 2 (integradores): el panel pinta «propuesto por X» cuando la
11002
+ * propuesta viene de una app de partner y no del agente Pim.
11003
+ */
11004
+ plane: string;
11005
+ origin_client_id: string | null;
11006
+ origin_client_name: string | null;
10103
11007
  /** @description Lazo de verificar (Fase 2): lo que el panel pinta del callback. */
10104
11008
  result: string | null;
10105
11009
  result_data: unknown[] | null;