@pimia/sdk 0.12.0 → 0.13.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
@@ -3751,6 +3751,37 @@ export interface paths {
3751
3751
  patch?: never;
3752
3752
  trace?: never;
3753
3753
  };
3754
+ "/received-invoices/{id}/mark-goods-received": {
3755
+ parameters: {
3756
+ query?: never;
3757
+ header?: never;
3758
+ path?: never;
3759
+ cookie?: never;
3760
+ };
3761
+ get?: never;
3762
+ put?: never;
3763
+ /**
3764
+ * Marca la mercancía de la factura recibida como RECIBIDA y suma sus líneas
3765
+ * al almacén — el espejo exacto del `mark-delivered` del albarán de venta
3766
+ * (estudio de stock, decisión S3)
3767
+ * @description Es una acción explícita y no el alta de la factura a propósito: el OCR
3768
+ * crea borradores que se corrigen, y un borrador no es mercancía en la
3769
+ * estantería. El candado es `stock_added_at` —un instante, como el
3770
+ * `stock_deducted_at` del albarán (#473)— y hace la acción idempotente:
3771
+ * la segunda llamada es un 422, no una segunda suma.
3772
+ *
3773
+ * Reglas espejo del albarán, también a propósito: solo mueven almacén las
3774
+ * líneas con `item_id`, y un artículo con `opening_stock` NULL («nunca ha
3775
+ * llevado stock») no se estrena por una compra — se estrena en su ficha o
3776
+ * con un ajuste, que son los gestos que significan «declaro existencias».
3777
+ */
3778
+ post: operations["receivedInvoices.markGoodsReceived"];
3779
+ delete?: never;
3780
+ options?: never;
3781
+ head?: never;
3782
+ patch?: never;
3783
+ trace?: never;
3784
+ };
3754
3785
  "/banking/transactions": {
3755
3786
  parameters: {
3756
3787
  query?: never;
@@ -4566,6 +4597,60 @@ export interface paths {
4566
4597
  patch?: never;
4567
4598
  trace?: never;
4568
4599
  };
4600
+ "/items/{item}/stock-adjustments": {
4601
+ parameters: {
4602
+ query?: never;
4603
+ header?: never;
4604
+ path?: never;
4605
+ cookie?: never;
4606
+ };
4607
+ get?: never;
4608
+ put?: never;
4609
+ /** Ajusta las existencias de un artículo y devuelve el asiento */
4610
+ post: operations["item.stockAdjustments"];
4611
+ delete?: never;
4612
+ options?: never;
4613
+ head?: never;
4614
+ patch?: never;
4615
+ trace?: never;
4616
+ };
4617
+ "/stock-movements": {
4618
+ parameters: {
4619
+ query?: never;
4620
+ header?: never;
4621
+ path?: never;
4622
+ cookie?: never;
4623
+ };
4624
+ /** Los movimientos de stock de la empresa, del más nuevo al más viejo */
4625
+ get: operations["stockMovements.index"];
4626
+ put?: never;
4627
+ post?: never;
4628
+ delete?: never;
4629
+ options?: never;
4630
+ head?: never;
4631
+ patch?: never;
4632
+ trace?: never;
4633
+ };
4634
+ "/items/{item}/stock-movements": {
4635
+ parameters: {
4636
+ query?: never;
4637
+ header?: never;
4638
+ path?: never;
4639
+ cookie?: never;
4640
+ };
4641
+ /**
4642
+ * Los movimientos de stock de UN artículo — la pestaña «Movimientos» de su
4643
+ * ficha, la que responde «¿por qué tengo 47?»
4644
+ */
4645
+ get: operations["stockMovements.forItem"];
4646
+ put?: never;
4647
+ post?: never;
4648
+ delete?: never;
4649
+ options?: never;
4650
+ head?: never;
4651
+ patch?: never;
4652
+ trace?: never;
4653
+ };
4569
4654
  "/store/modules": {
4570
4655
  parameters: {
4571
4656
  query?: never;
@@ -5656,6 +5741,79 @@ export interface paths {
5656
5741
  patch?: never;
5657
5742
  trace?: never;
5658
5743
  };
5744
+ "/warehouses/{warehouse}/stock": {
5745
+ parameters: {
5746
+ query?: never;
5747
+ header?: never;
5748
+ path?: never;
5749
+ cookie?: never;
5750
+ };
5751
+ /**
5752
+ * Las existencias de UN almacén, artículo a artículo
5753
+ * @description La pregunta que la dimensión vino a contestar: «¿cuántos me quedan en la
5754
+ * tienda?». Sale de `item_warehouse_stock`, que es el reparto del contador
5755
+ * global y no una segunda cuenta: la suma por artículo de todos los
5756
+ * almacenes es exactamente `items.opening_stock`.
5757
+ */
5758
+ get: operations["warehouses.stock"];
5759
+ put?: never;
5760
+ post?: never;
5761
+ delete?: never;
5762
+ options?: never;
5763
+ head?: never;
5764
+ patch?: never;
5765
+ trace?: never;
5766
+ };
5767
+ "/warehouses": {
5768
+ parameters: {
5769
+ query?: never;
5770
+ header?: never;
5771
+ path?: never;
5772
+ cookie?: never;
5773
+ };
5774
+ /** Los almacenes de la empresa */
5775
+ get: operations["warehouses.index"];
5776
+ put?: never;
5777
+ /** Da de alta un almacén */
5778
+ post: operations["warehouses.store"];
5779
+ delete?: never;
5780
+ options?: never;
5781
+ head?: never;
5782
+ patch?: never;
5783
+ trace?: never;
5784
+ };
5785
+ "/warehouses/{warehouse}": {
5786
+ parameters: {
5787
+ query?: never;
5788
+ header?: never;
5789
+ path?: never;
5790
+ cookie?: never;
5791
+ };
5792
+ get: operations["warehouses.show"];
5793
+ /**
5794
+ * Edita un almacén
5795
+ * @description ⚠️ El por defecto no se puede APAGAR desde aquí: se cambia encendiendo
5796
+ * otro, que apaga este en la misma transacción. Un `is_default: false`
5797
+ * sobre el único que lo tiene dejaría a la empresa sin sitio donde anotar
5798
+ * lo que no elige, y el 422 lo dice en vez de aceptarlo y romperse luego.
5799
+ */
5800
+ put: operations["warehouses.update"];
5801
+ post?: never;
5802
+ /**
5803
+ * Borra un almacén VACÍO y sin historia
5804
+ * @description Tres negativas, y las tres con su código: el por defecto no se borra
5805
+ * (`default_warehouse_required`), uno con asientos tampoco
5806
+ * (`stock_movements_attached` — el asiento lo nombra, y la historia del
5807
+ * almacén es lo que hace de fiar el saldo), y uno con existencias, menos
5808
+ * (`stock_attached`: borrarlo evaporaría un saldo que sí está en el
5809
+ * contador global). Para el que ya no se usa está `is_active: false`.
5810
+ */
5811
+ delete: operations["warehouses.destroy"];
5812
+ options?: never;
5813
+ head?: never;
5814
+ patch?: never;
5815
+ trace?: never;
5816
+ };
5659
5817
  "/settings/webhooks": {
5660
5818
  parameters: {
5661
5819
  query?: never;
@@ -6679,6 +6837,16 @@ export interface components {
6679
6837
  delivery_note_number: string | null;
6680
6838
  delivery_note_date: string;
6681
6839
  status: string;
6840
+ /**
6841
+ * Format: date-time
6842
+ * @description Cuándo movió el almacén este albarán (NULL = aún no). El #473 lo
6843
+ * creó sin publicarlo y los clientes lo INFERÍAN del estado — que
6844
+ * es justo lo que `convertToInvoice` rompe al pisar `DELIVERED`
6845
+ * con `INVOICED`. Con el libro (estudio de stock, S1) deja de ser
6846
+ * contabilidad interna: es lo que la pantalla del albarán necesita
6847
+ * para contar lo que hizo.
6848
+ */
6849
+ stock_deducted_at: string | null;
6682
6850
  sub_total: number;
6683
6851
  total: number;
6684
6852
  tax: number;
@@ -7895,6 +8063,12 @@ export interface components {
7895
8063
  notes: string | null;
7896
8064
  price: number;
7897
8065
  purchase_price: number | null;
8066
+ /**
8067
+ * @description Coste medio ponderado en céntimos (S8, informativo): lo
8068
+ * recalcula cada compra recibida; NULL = aún no hay entradas con
8069
+ * coste anotadas.
8070
+ */
8071
+ average_cost_cents: number | null;
7898
8072
  default_discount: number;
7899
8073
  unit_id: number | null;
7900
8074
  company_id: number | null;
@@ -7931,6 +8105,7 @@ export interface components {
7931
8105
  description: string | null;
7932
8106
  price: number;
7933
8107
  purchase_price: number | null;
8108
+ average_cost_cents: number | null;
7934
8109
  default_discount: number;
7935
8110
  category_id: number | null;
7936
8111
  category?: {
@@ -7969,6 +8144,13 @@ export interface components {
7969
8144
  type: string | null;
7970
8145
  }[];
7971
8146
  };
8147
+ /** ItemWarehouseStockResource */
8148
+ ItemWarehouseStockResource: {
8149
+ item_id: number;
8150
+ item_name: string;
8151
+ warehouse_id: number;
8152
+ quantity: number;
8153
+ };
7972
8154
  /** ItemsRequest */
7973
8155
  ItemsRequest: {
7974
8156
  name: string;
@@ -7991,11 +8173,19 @@ export interface components {
7991
8173
  description?: string | null;
7992
8174
  notes?: string | null;
7993
8175
  is_active?: boolean | null;
8176
+ /**
8177
+ * @description Saldo de existencias del artículo. Pese al nombre NO es el
8178
+ * inicial: es el contador vivo que mueven albaranes, facturas,
8179
+ * compras y ajustes (el detalle, en `GET /items/{item}/stock-movements`).
8180
+ * En el alta se guarda 0 si no llega; en la actualización se
8181
+ * conserva el que había. Escribirlo aquí pisa el saldo (queda
8182
+ * anotado como `manual_edit`); para corregir con motivo está
8183
+ * `POST /items/{item}/stock-adjustments`.
8184
+ */
8185
+ opening_stock?: number | null;
7994
8186
  stock_alert_qty?: number | null;
7995
8187
  allow_sale_without_stock?: boolean | null;
7996
8188
  purchase_tax_type_id?: number | null;
7997
- /** @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. */
7998
- opening_stock?: number | null;
7999
8189
  };
8000
8190
  /** LeadActivity */
8001
8191
  LeadActivity: {
@@ -8477,6 +8667,14 @@ export interface components {
8477
8667
  received_invoice_number: string | null;
8478
8668
  reference_number: string | null;
8479
8669
  status: string;
8670
+ /**
8671
+ * Format: date-time
8672
+ * @description Cuándo se sumó la mercancía al almacén (mark-goods-received);
8673
+ * NULL si aún no. Se publica —al contrario que en su día el
8674
+ * `stock_deducted_at` del albarán— porque es lo que permite a un
8675
+ * cliente pintar el botón «Mercancía recibida» solo cuando toca.
8676
+ */
8677
+ stock_added_at: string | null;
8480
8678
  paid_status: string;
8481
8679
  tax_per_item: string | null;
8482
8680
  discount_per_item: string | null;
@@ -8751,7 +8949,7 @@ export interface components {
8751
8949
  * ningún permiso es una operación legítima, y `required` la
8752
8950
  * prohibiría (un array vacío no pasa `required`).
8753
8951
  */
8754
- abilities: ("dashboard" | "view-customer" | "create-customer" | "edit-customer" | "delete-customer" | "view-estimate" | "create-estimate" | "edit-estimate" | "delete-estimate" | "send-estimate" | "view-invoice" | "create-invoice" | "edit-invoice" | "delete-invoice" | "send-invoice" | "view-recurring-invoice" | "create-recurring-invoice" | "edit-recurring-invoice" | "delete-recurring-invoice" | "view-payment" | "create-payment" | "edit-payment" | "delete-payment" | "send-payment" | "view-expense" | "create-expense" | "edit-expense" | "delete-expense" | "view-delivery-note" | "create-delivery-note" | "edit-delivery-note" | "delete-delivery-note" | "view-item" | "create-item" | "edit-item" | "delete-item" | "view-lead" | "create-lead" | "edit-lead" | "delete-lead" | "convert-lead" | "view-contact" | "create-contact" | "edit-contact" | "delete-contact" | "view-project" | "create-project" | "edit-project" | "delete-project" | "view-task" | "create-task" | "edit-task" | "delete-task" | "view-own-task" | "edit-own-task" | "view-time-entry" | "create-time-entry" | "edit-time-entry" | "delete-time-entry" | "view-own-time-entry" | "create-own-time-entry" | "edit-own-time-entry" | "delete-own-time-entry" | "view-tax-type" | "create-tax-type" | "edit-tax-type" | "delete-tax-type" | "view-custom-field" | "create-custom-field" | "edit-custom-field" | "delete-custom-field" | "view-role" | "create-role" | "edit-role" | "delete-role" | "view-financial-reports" | "view-all-notes" | "manage-all-notes" | "time_clock.punch" | "time_clock.view_own" | "time_clock.view_team" | "time_clock.correct" | "absence.request" | "absence.approve" | "report.download_legal" | "view-employee" | "create-employee" | "edit-employee" | "delete-employee" | "view-work-schedule" | "manage-work-schedule" | "view-work-calendar" | "manage-work-calendar" | "pos.operate" | "pos.supervise" | "pos.void" | "pos.discount_high" | "pos.cash_movement" | "pos.return" | "pos.admin" | "pos.report" | "view-appointment" | "create-appointment" | "edit-appointment" | "delete-appointment" | "view-contract" | "create-contract" | "edit-contract" | "delete-contract")[];
8952
+ abilities: ("dashboard" | "view-customer" | "create-customer" | "edit-customer" | "delete-customer" | "view-estimate" | "create-estimate" | "edit-estimate" | "delete-estimate" | "send-estimate" | "view-invoice" | "create-invoice" | "edit-invoice" | "delete-invoice" | "send-invoice" | "view-recurring-invoice" | "create-recurring-invoice" | "edit-recurring-invoice" | "delete-recurring-invoice" | "view-payment" | "create-payment" | "edit-payment" | "delete-payment" | "send-payment" | "view-expense" | "create-expense" | "edit-expense" | "delete-expense" | "view-delivery-note" | "create-delivery-note" | "edit-delivery-note" | "delete-delivery-note" | "view-item" | "create-item" | "edit-item" | "delete-item" | "view-lead" | "create-lead" | "edit-lead" | "delete-lead" | "convert-lead" | "view-contact" | "create-contact" | "edit-contact" | "delete-contact" | "view-project" | "create-project" | "edit-project" | "delete-project" | "view-task" | "create-task" | "edit-task" | "delete-task" | "view-own-task" | "edit-own-task" | "view-time-entry" | "create-time-entry" | "edit-time-entry" | "delete-time-entry" | "view-own-time-entry" | "create-own-time-entry" | "edit-own-time-entry" | "delete-own-time-entry" | "view-tax-type" | "create-tax-type" | "edit-tax-type" | "delete-tax-type" | "view-custom-field" | "create-custom-field" | "edit-custom-field" | "delete-custom-field" | "view-role" | "create-role" | "edit-role" | "delete-role" | "view-financial-reports" | "view-all-notes" | "manage-all-notes" | "time_clock.punch" | "time_clock.view_own" | "time_clock.view_team" | "time_clock.correct" | "absence.request" | "absence.approve" | "report.download_legal" | "view-employee" | "create-employee" | "edit-employee" | "delete-employee" | "view-work-schedule" | "manage-work-schedule" | "view-work-calendar" | "manage-work-calendar" | "pos.operate" | "pos.supervise" | "pos.void" | "pos.discount_high" | "pos.cash_movement" | "pos.return" | "pos.admin" | "pos.report" | "view-appointment" | "create-appointment" | "edit-appointment" | "delete-appointment" | "view-contract" | "create-contract" | "edit-contract" | "delete-contract" | "view-warehouse" | "create-warehouse" | "edit-warehouse" | "delete-warehouse")[];
8755
8953
  };
8756
8954
  /**
8757
8955
  * RoleRequest
@@ -8776,7 +8974,7 @@ export interface components {
8776
8974
  name: string;
8777
8975
  abilities?: {
8778
8976
  /** @enum {string} */
8779
- ability: "dashboard" | "view-customer" | "create-customer" | "edit-customer" | "delete-customer" | "view-estimate" | "create-estimate" | "edit-estimate" | "delete-estimate" | "send-estimate" | "view-invoice" | "create-invoice" | "edit-invoice" | "delete-invoice" | "send-invoice" | "view-recurring-invoice" | "create-recurring-invoice" | "edit-recurring-invoice" | "delete-recurring-invoice" | "view-payment" | "create-payment" | "edit-payment" | "delete-payment" | "send-payment" | "view-expense" | "create-expense" | "edit-expense" | "delete-expense" | "view-delivery-note" | "create-delivery-note" | "edit-delivery-note" | "delete-delivery-note" | "view-item" | "create-item" | "edit-item" | "delete-item" | "view-lead" | "create-lead" | "edit-lead" | "delete-lead" | "convert-lead" | "view-contact" | "create-contact" | "edit-contact" | "delete-contact" | "view-project" | "create-project" | "edit-project" | "delete-project" | "view-task" | "create-task" | "edit-task" | "delete-task" | "view-own-task" | "edit-own-task" | "view-time-entry" | "create-time-entry" | "edit-time-entry" | "delete-time-entry" | "view-own-time-entry" | "create-own-time-entry" | "edit-own-time-entry" | "delete-own-time-entry" | "view-tax-type" | "create-tax-type" | "edit-tax-type" | "delete-tax-type" | "view-custom-field" | "create-custom-field" | "edit-custom-field" | "delete-custom-field" | "view-role" | "create-role" | "edit-role" | "delete-role" | "view-financial-reports" | "view-all-notes" | "manage-all-notes" | "time_clock.punch" | "time_clock.view_own" | "time_clock.view_team" | "time_clock.correct" | "absence.request" | "absence.approve" | "report.download_legal" | "view-employee" | "create-employee" | "edit-employee" | "delete-employee" | "view-work-schedule" | "manage-work-schedule" | "view-work-calendar" | "manage-work-calendar" | "pos.operate" | "pos.supervise" | "pos.void" | "pos.discount_high" | "pos.cash_movement" | "pos.return" | "pos.admin" | "pos.report" | "view-appointment" | "create-appointment" | "edit-appointment" | "delete-appointment" | "view-contract" | "create-contract" | "edit-contract" | "delete-contract";
8977
+ ability: "dashboard" | "view-customer" | "create-customer" | "edit-customer" | "delete-customer" | "view-estimate" | "create-estimate" | "edit-estimate" | "delete-estimate" | "send-estimate" | "view-invoice" | "create-invoice" | "edit-invoice" | "delete-invoice" | "send-invoice" | "view-recurring-invoice" | "create-recurring-invoice" | "edit-recurring-invoice" | "delete-recurring-invoice" | "view-payment" | "create-payment" | "edit-payment" | "delete-payment" | "send-payment" | "view-expense" | "create-expense" | "edit-expense" | "delete-expense" | "view-delivery-note" | "create-delivery-note" | "edit-delivery-note" | "delete-delivery-note" | "view-item" | "create-item" | "edit-item" | "delete-item" | "view-lead" | "create-lead" | "edit-lead" | "delete-lead" | "convert-lead" | "view-contact" | "create-contact" | "edit-contact" | "delete-contact" | "view-project" | "create-project" | "edit-project" | "delete-project" | "view-task" | "create-task" | "edit-task" | "delete-task" | "view-own-task" | "edit-own-task" | "view-time-entry" | "create-time-entry" | "edit-time-entry" | "delete-time-entry" | "view-own-time-entry" | "create-own-time-entry" | "edit-own-time-entry" | "delete-own-time-entry" | "view-tax-type" | "create-tax-type" | "edit-tax-type" | "delete-tax-type" | "view-custom-field" | "create-custom-field" | "edit-custom-field" | "delete-custom-field" | "view-role" | "create-role" | "edit-role" | "delete-role" | "view-financial-reports" | "view-all-notes" | "manage-all-notes" | "time_clock.punch" | "time_clock.view_own" | "time_clock.view_team" | "time_clock.correct" | "absence.request" | "absence.approve" | "report.download_legal" | "view-employee" | "create-employee" | "edit-employee" | "delete-employee" | "view-work-schedule" | "manage-work-schedule" | "view-work-calendar" | "manage-work-calendar" | "pos.operate" | "pos.supervise" | "pos.void" | "pos.discount_high" | "pos.cash_movement" | "pos.return" | "pos.admin" | "pos.report" | "view-appointment" | "create-appointment" | "edit-appointment" | "delete-appointment" | "view-contract" | "create-contract" | "edit-contract" | "delete-contract" | "view-warehouse" | "create-warehouse" | "edit-warehouse" | "delete-warehouse";
8780
8978
  }[] | null;
8781
8979
  };
8782
8980
  /** RoleResource */
@@ -8855,6 +9053,62 @@ export interface components {
8855
9053
  SettingRequest: {
8856
9054
  settings: string;
8857
9055
  };
9056
+ /** StockAdjustmentRequest */
9057
+ StockAdjustmentRequest: {
9058
+ /**
9059
+ * @description Cantidad FIRMADA que se aplica al contador: positiva repone,
9060
+ * negativa retira. Decimal a propósito (litros, kg); el contador
9061
+ * redondea y el asiento guarda la cantidad exacta.
9062
+ */
9063
+ quantity: number;
9064
+ /**
9065
+ * @description El motivo es obligatorio: un ajuste sin porqué es el contador
9066
+ * pisado de siempre, que es justo lo que el libro viene a retirar.
9067
+ */
9068
+ note: string;
9069
+ };
9070
+ /** StockMovementResource */
9071
+ StockMovementResource: {
9072
+ id: number;
9073
+ item_id: number | null;
9074
+ /**
9075
+ * @description El nombre del artículo, para que el índice GLOBAL del libro sea
9076
+ * legible sin cruzarlo con el catálogo en el cliente. NULL cuando
9077
+ * el artículo ya no existe (`item_id` es nullOnDelete: el asiento
9078
+ * sobrevive al artículo y su nombre no — el cliente lo enseña como
9079
+ * «artículo borrado», que es la verdad). Los dos índices lo cargan
9080
+ * con `with('item:id,name')`: sin eso sería un N+1 por fila.
9081
+ */
9082
+ item_name: string | null;
9083
+ /**
9084
+ * @description DÓNDE pasó (N2). Los asientos anteriores a la dimensión están
9085
+ * todos en el «Principal» que estrenó la migración: es la única
9086
+ * respuesta verdadera, porque nadie declaró jamás dónde estaban.
9087
+ * NULL solo si el almacén desapareció (`nullOnDelete`), igual que
9088
+ * `item_name` — y con el mismo eager load, `warehouse:id,name`.
9089
+ */
9090
+ warehouse_id: number | null;
9091
+ warehouse_name: string | null;
9092
+ /**
9093
+ * @description Cantidad FIRMADA que trajo la causa (decimal: hay artículos en
9094
+ * litros y kg). El contador redondea; la diferencia se ve en la
9095
+ * cadena de `balance_after`.
9096
+ */
9097
+ quantity: number;
9098
+ balance_after: number;
9099
+ /**
9100
+ * @description El coste unitario de una ENTRADA, en céntimos (S8). NULL en las
9101
+ * salidas y en las entradas sin coste conocido.
9102
+ */
9103
+ unit_cost_cents: number | null;
9104
+ reason: string;
9105
+ document_type: string | null;
9106
+ document_id: number | null;
9107
+ note: string | null;
9108
+ creator_id: number | null;
9109
+ /** Format: date-time */
9110
+ created_at: string;
9111
+ };
8858
9112
  /**
8859
9113
  * StoreApprovalRequest
8860
9114
  * @description POST /api/v1/approvals (paso 2, plataforma de integradores) — una app de
@@ -9392,6 +9646,37 @@ export interface components {
9392
9646
  role: string | null;
9393
9647
  }[];
9394
9648
  };
9649
+ /** WarehouseRequest */
9650
+ WarehouseRequest: {
9651
+ name: string;
9652
+ code?: string | null;
9653
+ address?: string | null;
9654
+ is_default?: boolean | null;
9655
+ is_active?: boolean | null;
9656
+ };
9657
+ /** WarehouseResource */
9658
+ WarehouseResource: {
9659
+ id: number;
9660
+ name: string;
9661
+ code: string | null;
9662
+ address: string | null;
9663
+ /**
9664
+ * @description Exactamente uno por empresa lo lleva puesto: es el que hereda
9665
+ * todo movimiento que no elige almacén, que hoy son casi todos
9666
+ * (solo albarán y recepción preguntan).
9667
+ */
9668
+ is_default: boolean;
9669
+ /**
9670
+ * @description Un almacén con historia no se borra —el asiento lo nombra—: se
9671
+ * desactiva. Desactivado no se ofrece para movimientos nuevos y
9672
+ * sigue explicando los viejos.
9673
+ */
9674
+ is_active: boolean;
9675
+ /** Format: date-time */
9676
+ created_at: string | null;
9677
+ /** Format: date-time */
9678
+ updated_at: string | null;
9679
+ };
9395
9680
  /** WorkCalendarRequest */
9396
9681
  WorkCalendarRequest: {
9397
9682
  name: string;
@@ -17658,6 +17943,43 @@ export interface operations {
17658
17943
  };
17659
17944
  };
17660
17945
  };
17946
+ "receivedInvoices.markGoodsReceived": {
17947
+ parameters: {
17948
+ query?: never;
17949
+ header?: never;
17950
+ path: {
17951
+ id: string;
17952
+ };
17953
+ cookie?: never;
17954
+ };
17955
+ requestBody?: never;
17956
+ responses: {
17957
+ /** @description `ReceivedInvoiceResource` */
17958
+ 200: {
17959
+ headers: {
17960
+ [name: string]: unknown;
17961
+ };
17962
+ content: {
17963
+ "application/json": {
17964
+ data: components["schemas"]["ReceivedInvoiceResource"];
17965
+ };
17966
+ };
17967
+ };
17968
+ 422: {
17969
+ headers: {
17970
+ [name: string]: unknown;
17971
+ };
17972
+ content: {
17973
+ "application/json": {
17974
+ /** @constant */
17975
+ error: "goods_already_received";
17976
+ /** @constant */
17977
+ message: "La mercancía de esta factura recibida ya se sumó al almacén.";
17978
+ };
17979
+ };
17980
+ };
17981
+ };
17982
+ };
17661
17983
  "reconciliation.transactions": {
17662
17984
  parameters: {
17663
17985
  query?: {
@@ -19175,6 +19497,123 @@ export interface operations {
19175
19497
  };
19176
19498
  };
19177
19499
  };
19500
+ "item.stockAdjustments": {
19501
+ parameters: {
19502
+ query?: never;
19503
+ header?: never;
19504
+ path: {
19505
+ item: string;
19506
+ };
19507
+ cookie?: never;
19508
+ };
19509
+ requestBody: {
19510
+ content: {
19511
+ "application/json": components["schemas"]["StockAdjustmentRequest"];
19512
+ };
19513
+ };
19514
+ responses: {
19515
+ /** @description `StockMovementResource` */
19516
+ 201: {
19517
+ headers: {
19518
+ [name: string]: unknown;
19519
+ };
19520
+ content: {
19521
+ "application/json": {
19522
+ data: components["schemas"]["StockMovementResource"];
19523
+ };
19524
+ };
19525
+ };
19526
+ 403: components["responses"]["AuthorizationException"];
19527
+ 422: components["responses"]["ValidationException"];
19528
+ };
19529
+ };
19530
+ "stockMovements.index": {
19531
+ parameters: {
19532
+ query?: {
19533
+ /** @description Solo los asientos de este artículo. */
19534
+ item_id?: number;
19535
+ /** @description Solo los asientos con este motivo (`initial`, `import`, `manual_edit`, `manual_adjustment`, `purchase`, `sale_invoice`, `delivery_note`, `pos_sale`, `pos_return`). */
19536
+ reason?: string;
19537
+ /** @description Solo los asientos de este almacén. */
19538
+ warehouse_id?: number;
19539
+ /** @description Desde esta fecha (YYYY-MM-DD). */
19540
+ from_date?: string;
19541
+ /** @description Hasta esta fecha (YYYY-MM-DD). */
19542
+ to_date?: string;
19543
+ };
19544
+ header?: never;
19545
+ path?: never;
19546
+ cookie?: never;
19547
+ };
19548
+ requestBody?: never;
19549
+ responses: {
19550
+ /** @description Array of `StockMovementResource` */
19551
+ 200: {
19552
+ headers: {
19553
+ [name: string]: unknown;
19554
+ };
19555
+ content: {
19556
+ "application/json": {
19557
+ data: components["schemas"]["StockMovementResource"][];
19558
+ meta: {
19559
+ stock_movement_total_count: number;
19560
+ /**
19561
+ * @description S8, informativo: lo que vale el almacén hoy, en céntimos —
19562
+ * existencias × coste medio aprendido, con el precio de compra
19563
+ * de la ficha como respaldo cuando aún no hay medio. Los
19564
+ * artículos sin ninguno de los dos cuentan 0: la cifra no se
19565
+ * inventa costes, y por eso puede quedarse corta — nunca
19566
+ * larga. NO es un asiento contable ni una valoración de
19567
+ * cierre (estudio de stock §6).
19568
+ */
19569
+ stock_value_cents: number;
19570
+ };
19571
+ };
19572
+ };
19573
+ };
19574
+ 403: components["responses"]["AuthorizationException"];
19575
+ };
19576
+ };
19577
+ "stockMovements.forItem": {
19578
+ parameters: {
19579
+ query?: never;
19580
+ header?: never;
19581
+ path: {
19582
+ item: string;
19583
+ };
19584
+ cookie?: never;
19585
+ };
19586
+ requestBody?: never;
19587
+ responses: {
19588
+ /** @description Array of `StockMovementResource` */
19589
+ 200: {
19590
+ headers: {
19591
+ [name: string]: unknown;
19592
+ };
19593
+ content: {
19594
+ "application/json": {
19595
+ data: components["schemas"]["StockMovementResource"][];
19596
+ meta: {
19597
+ opening_stock: number | null;
19598
+ /**
19599
+ * @description El reparto del saldo por almacén (N2). Su suma es
19600
+ * exactamente `opening_stock` de arriba — es el mismo número
19601
+ * contado por sitios, no una segunda cuenta. Se sirve entero
19602
+ * (una pyme tiene almacenes de contar con los dedos) y sin
19603
+ * paginar: es cabecera de la pestaña, no listado.
19604
+ */
19605
+ warehouse_stock: {
19606
+ warehouse_id: number;
19607
+ warehouse_name: string;
19608
+ quantity: number;
19609
+ }[];
19610
+ };
19611
+ };
19612
+ };
19613
+ };
19614
+ 403: components["responses"]["AuthorizationException"];
19615
+ };
19616
+ };
19178
19617
  "storeModules.index": {
19179
19618
  parameters: {
19180
19619
  query?: never;
@@ -24230,6 +24669,180 @@ export interface operations {
24230
24669
  422: components["responses"]["ValidationException"];
24231
24670
  };
24232
24671
  };
24672
+ "warehouses.stock": {
24673
+ parameters: {
24674
+ query?: {
24675
+ /** @description Filtra por nombre del artículo. */
24676
+ search?: string;
24677
+ /** @description Solo los artículos con saldo distinto de cero (`1`). */
24678
+ only_with_stock?: boolean;
24679
+ };
24680
+ header?: never;
24681
+ path: {
24682
+ /** @description The warehouse ID */
24683
+ warehouse: number;
24684
+ };
24685
+ cookie?: never;
24686
+ };
24687
+ requestBody?: never;
24688
+ responses: {
24689
+ /** @description Array of `ItemWarehouseStockResource` */
24690
+ 200: {
24691
+ headers: {
24692
+ [name: string]: unknown;
24693
+ };
24694
+ content: {
24695
+ "application/json": {
24696
+ data: components["schemas"]["ItemWarehouseStockResource"][];
24697
+ meta: {
24698
+ warehouse: components["schemas"]["WarehouseResource"];
24699
+ };
24700
+ };
24701
+ };
24702
+ };
24703
+ 403: components["responses"]["AuthorizationException"];
24704
+ 404: components["responses"]["ModelNotFoundException"];
24705
+ };
24706
+ };
24707
+ "warehouses.index": {
24708
+ parameters: {
24709
+ query?: {
24710
+ /** @description Filtra por nombre o código. */
24711
+ search?: string;
24712
+ /** @description Solo los activos (`1`) o solo los desactivados (`0`). */
24713
+ is_active?: boolean;
24714
+ };
24715
+ header?: never;
24716
+ path?: never;
24717
+ cookie?: never;
24718
+ };
24719
+ requestBody?: never;
24720
+ responses: {
24721
+ /** @description Array of `WarehouseResource` */
24722
+ 200: {
24723
+ headers: {
24724
+ [name: string]: unknown;
24725
+ };
24726
+ content: {
24727
+ "application/json": {
24728
+ data: components["schemas"]["WarehouseResource"][];
24729
+ };
24730
+ };
24731
+ };
24732
+ 403: components["responses"]["AuthorizationException"];
24733
+ };
24734
+ };
24735
+ "warehouses.store": {
24736
+ parameters: {
24737
+ query?: never;
24738
+ header?: never;
24739
+ path?: never;
24740
+ cookie?: never;
24741
+ };
24742
+ requestBody: {
24743
+ content: {
24744
+ "application/json": components["schemas"]["WarehouseRequest"];
24745
+ };
24746
+ };
24747
+ responses: {
24748
+ /** @description El recurso recién creado. */
24749
+ 201: {
24750
+ headers: {
24751
+ [name: string]: unknown;
24752
+ };
24753
+ content: {
24754
+ "application/json": 201;
24755
+ };
24756
+ };
24757
+ 403: components["responses"]["AuthorizationException"];
24758
+ 422: components["responses"]["ValidationException"];
24759
+ };
24760
+ };
24761
+ "warehouses.show": {
24762
+ parameters: {
24763
+ query?: never;
24764
+ header?: never;
24765
+ path: {
24766
+ /** @description The warehouse ID */
24767
+ warehouse: number;
24768
+ };
24769
+ cookie?: never;
24770
+ };
24771
+ requestBody?: never;
24772
+ responses: {
24773
+ /** @description `WarehouseResource` */
24774
+ 200: {
24775
+ headers: {
24776
+ [name: string]: unknown;
24777
+ };
24778
+ content: {
24779
+ "application/json": {
24780
+ data: components["schemas"]["WarehouseResource"];
24781
+ };
24782
+ };
24783
+ };
24784
+ 403: components["responses"]["AuthorizationException"];
24785
+ 404: components["responses"]["ModelNotFoundException"];
24786
+ };
24787
+ };
24788
+ "warehouses.update": {
24789
+ parameters: {
24790
+ query?: never;
24791
+ header?: never;
24792
+ path: {
24793
+ /** @description The warehouse ID */
24794
+ warehouse: number;
24795
+ };
24796
+ cookie?: never;
24797
+ };
24798
+ requestBody: {
24799
+ content: {
24800
+ "application/json": components["schemas"]["WarehouseRequest"];
24801
+ };
24802
+ };
24803
+ responses: {
24804
+ /** @description `WarehouseResource` */
24805
+ 200: {
24806
+ headers: {
24807
+ [name: string]: unknown;
24808
+ };
24809
+ content: {
24810
+ "application/json": {
24811
+ data: components["schemas"]["WarehouseResource"];
24812
+ } | string;
24813
+ };
24814
+ };
24815
+ 403: components["responses"]["AuthorizationException"];
24816
+ 404: components["responses"]["ModelNotFoundException"];
24817
+ 422: components["responses"]["ValidationException"];
24818
+ };
24819
+ };
24820
+ "warehouses.destroy": {
24821
+ parameters: {
24822
+ query?: never;
24823
+ header?: never;
24824
+ path: {
24825
+ /** @description The warehouse ID */
24826
+ warehouse: number;
24827
+ };
24828
+ cookie?: never;
24829
+ };
24830
+ requestBody?: never;
24831
+ responses: {
24832
+ 200: {
24833
+ headers: {
24834
+ [name: string]: unknown;
24835
+ };
24836
+ content: {
24837
+ "application/json": {
24838
+ success: string;
24839
+ };
24840
+ };
24841
+ };
24842
+ 403: components["responses"]["AuthorizationException"];
24843
+ 404: components["responses"]["ModelNotFoundException"];
24844
+ };
24845
+ };
24233
24846
  "webhookEndpoints.index": {
24234
24847
  parameters: {
24235
24848
  query?: never;
package/dist/client.d.ts CHANGED
@@ -25,6 +25,10 @@ export type InvoiceResource = Schemas['InvoiceResource'];
25
25
  export type EstimateResource = Schemas['EstimateResource'];
26
26
  /** Contrato de servicio tal y como lo devuelve la API. */
27
27
  export type ContractResource = Schemas['ContractResource'];
28
+ /** Almacén tal y como lo devuelve la API. */
29
+ export type WarehouseResource = Schemas['WarehouseResource'];
30
+ /** El saldo de un artículo EN un almacén. */
31
+ export type ItemWarehouseStockResource = Schemas['ItemWarehouseStockResource'];
28
32
  /** Cuerpo de alta/edición de cliente. Incluye `customFields`. */
29
33
  export type CustomerRequest = Schemas['CustomerRequest'];
30
34
  /** Cuerpo de alta/edición de factura. Incluye `customFields`. */
@@ -36,6 +40,12 @@ export type EstimatesRequest = Schemas['EstimatesRequest'];
36
40
  * vida va por sus acciones (`activate`/`cancel`/`renew`), nunca por el PUT.
37
41
  */
38
42
  export type ContractRequest = Schemas['ContractRequest'];
43
+ /**
44
+ * Cuerpo de alta/edición de almacén. `is_default` se manda como INTENCIÓN
45
+ * («que este sea el de por defecto»): el servidor apaga el anterior en la
46
+ * misma transacción, porque la empresa necesita exactamente uno.
47
+ */
48
+ export type WarehouseRequest = Schemas['WarehouseRequest'];
39
49
  /**
40
50
  * El sobre `{ data: … }` de Laravel para las escrituras que el spec **no
41
51
  * tipa**.
@@ -791,6 +801,66 @@ export declare class PimiaClient {
791
801
  invoices?: components["schemas"]["InvoiceResource"][];
792
802
  }>>;
793
803
  };
804
+ /**
805
+ * Almacenes: la DIMENSIÓN del stock. Exige `items:read` / `items:write` —
806
+ * el almacén cuelga del catálogo que dimensiona, sin scope propio.
807
+ *
808
+ * ⚠️ **Vive tras el módulo `stock`, que es opt-in**: si la empresa no lo ha
809
+ * instalado, estas rutas responden `403` con `error: module_not_installed`,
810
+ * y eso NO es un problema de permisos. El libro de movimientos, el ajuste
811
+ * con motivo y la mercancía recibida son de todos y no pasan por aquí.
812
+ *
813
+ * Exactamente un almacén lleva `is_default`, y es el que hereda todo
814
+ * movimiento que no elige otro. El saldo por almacén es el REPARTO del
815
+ * contador global: su suma por artículo es exactamente `opening_stock`.
816
+ */
817
+ get warehouses(): {
818
+ list: (query?: RequestOptions["query"], options?: ReadOptions) => Promise<{
819
+ data: components["schemas"]["WarehouseResource"][];
820
+ }>;
821
+ get: (id: number | string, options?: ReadOptions) => Promise<{
822
+ data: components["schemas"]["WarehouseResource"];
823
+ }>;
824
+ create: (body: WarehouseRequest, options?: WriteOptions) => Promise<ResourceEnvelope<{
825
+ id: number;
826
+ name: string;
827
+ code: string | null;
828
+ address: string | null;
829
+ is_default: boolean;
830
+ is_active: boolean;
831
+ created_at: string | null;
832
+ updated_at: string | null;
833
+ }>>;
834
+ update: (id: number | string, body: WarehouseRequest, options?: WriteOptions) => Promise<ResourceEnvelope<{
835
+ id: number;
836
+ name: string;
837
+ code: string | null;
838
+ address: string | null;
839
+ is_default: boolean;
840
+ is_active: boolean;
841
+ created_at: string | null;
842
+ updated_at: string | null;
843
+ }>>;
844
+ /**
845
+ * Borra un almacén VACÍO y sin historia. Tres negativas con su código:
846
+ * `default_warehouse_required`, `stock_movements_attached` (su pasado
847
+ * explica saldos de hoy) y `stock_attached`. Para el que ya no se usa,
848
+ * `update` con `is_active: false`.
849
+ */
850
+ delete: (id: number | string, options?: ReadOptions) => Promise<{
851
+ success: string;
852
+ }>;
853
+ /**
854
+ * Las existencias de UN almacén, artículo a artículo — la pregunta que
855
+ * la dimensión vino a contestar. `only_with_stock` deja fuera los ceros.
856
+ */
857
+ stock: (id: number | string, query?: RequestOptions["query"], options?: ReadOptions) => Promise<{
858
+ data: components["schemas"]["ItemWarehouseStockResource"][];
859
+ meta: {
860
+ warehouse: components["schemas"]["WarehouseResource"];
861
+ };
862
+ }>;
863
+ };
794
864
  get<T = unknown>(path: string, query?: RequestOptions['query'], options?: ReadOptions): Promise<T>;
795
865
  post<T = unknown>(path: string, body?: unknown, options?: WriteOptions): Promise<T>;
796
866
  put<T = unknown>(path: string, body?: unknown, options?: WriteOptions): Promise<T>;
package/dist/client.js CHANGED
@@ -164,6 +164,39 @@ export class PimiaClient {
164
164
  uploadDocument: (id, document, options) => this.post(`/contracts/${id}/document`, toFormData({ document }), options),
165
165
  };
166
166
  }
167
+ /**
168
+ * Almacenes: la DIMENSIÓN del stock. Exige `items:read` / `items:write` —
169
+ * el almacén cuelga del catálogo que dimensiona, sin scope propio.
170
+ *
171
+ * ⚠️ **Vive tras el módulo `stock`, que es opt-in**: si la empresa no lo ha
172
+ * instalado, estas rutas responden `403` con `error: module_not_installed`,
173
+ * y eso NO es un problema de permisos. El libro de movimientos, el ajuste
174
+ * con motivo y la mercancía recibida son de todos y no pasan por aquí.
175
+ *
176
+ * Exactamente un almacén lleva `is_default`, y es el que hereda todo
177
+ * movimiento que no elige otro. El saldo por almacén es el REPARTO del
178
+ * contador global: su suma por artículo es exactamente `opening_stock`.
179
+ */
180
+ get warehouses() {
181
+ return {
182
+ list: (query, options) => this.get('/warehouses', query, options),
183
+ get: (id, options) => this.get(`/warehouses/${id}`, undefined, options),
184
+ create: (body, options) => this.post('/warehouses', body, options),
185
+ update: (id, body, options) => this.put(`/warehouses/${id}`, body, options),
186
+ /**
187
+ * Borra un almacén VACÍO y sin historia. Tres negativas con su código:
188
+ * `default_warehouse_required`, `stock_movements_attached` (su pasado
189
+ * explica saldos de hoy) y `stock_attached`. Para el que ya no se usa,
190
+ * `update` con `is_active: false`.
191
+ */
192
+ delete: (id, options) => this.delete(`/warehouses/${id}`, options),
193
+ /**
194
+ * Las existencias de UN almacén, artículo a artículo — la pregunta que
195
+ * la dimensión vino a contestar. `only_with_stock` deja fuera los ceros.
196
+ */
197
+ stock: (id, query, options) => this.get(`/warehouses/${id}/stock`, query, options),
198
+ };
199
+ }
167
200
  get(path, query, options) {
168
201
  return this.request(path, { ...options, method: 'GET', query });
169
202
  }
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * salen los tipos de `./api`.
7
7
  */
8
8
  export { PimiaClient, toFormData } from './client.js';
9
- export type { ContractRequest, ContractResource, CustomerRequest, CustomerResource, EstimateResource, EstimatesRequest, InvoiceResource, InvoicesRequest, PimiaClientOptions, RateLimit, ReadOptions, RequestOptions, ResourceEnvelope, ResponseMeta, ResponseWithMeta, WriteOptions, } from './client.js';
9
+ export type { ContractRequest, ContractResource, CustomerRequest, CustomerResource, EstimateResource, EstimatesRequest, InvoiceResource, InvoicesRequest, ItemWarehouseStockResource, PimiaClientOptions, RateLimit, ReadOptions, RequestOptions, ResourceEnvelope, ResponseMeta, ResponseWithMeta, WarehouseRequest, WarehouseResource, WriteOptions, } from './client.js';
10
10
  export { OAuth, createPkceChallenge, createState } from './oauth.js';
11
11
  export type { AuthorizationServerMetadata, AuthorizeUrlOptions, OAuthConfig, PkceChallenge, } from './oauth.js';
12
12
  export { MemoryTokenStore, isExpired, tokenSetFromResponse } from './tokens.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pimia/sdk",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Cliente TypeScript de la API de Pimia para apps de partner: OAuth con PKCE, rotación de refresh persistida, reintentos de rate limit y tipos generados del OpenAPI.",
5
5
  "license": "MIT",
6
6
  "author": "Pimia (https://pimia.es)",