@yoryoboy/bi-mcp 1.19.0 → 1.20.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.
Files changed (53) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/mcp-use.json +6 -3
  3. package/dist/scripts/profile-mercadolibre-billing.js +634 -0
  4. package/dist/scripts/profile-mercadolibre-billing.js.map +7 -0
  5. package/dist/src/config/__tests__/tiendanube-profile-store.test.js +50 -0
  6. package/dist/src/config/__tests__/tiendanube-profile-store.test.js.map +7 -0
  7. package/dist/src/config/tiendanube-profile-store.js +31 -0
  8. package/dist/src/config/tiendanube-profile-store.js.map +7 -0
  9. package/dist/src/google-ads/report-utils.js +78 -0
  10. package/dist/src/google-ads/report-utils.js.map +7 -0
  11. package/dist/src/search-console/search-console-utils.js +275 -0
  12. package/dist/src/search-console/search-console-utils.js.map +7 -0
  13. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report-ventas.test.js +358 -0
  14. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report-ventas.test.js.map +7 -0
  15. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report.test.js +96 -0
  16. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report.test.js.map +7 -0
  17. package/dist/src/services/mercadolibre/mercadolibre-claim-return-lookup.js +15 -0
  18. package/dist/src/services/mercadolibre/mercadolibre-claim-return-lookup.js.map +7 -0
  19. package/dist/src/services/mercadolibre/mercadolibre-observability.js +12 -0
  20. package/dist/src/services/mercadolibre/mercadolibre-observability.js.map +7 -0
  21. package/dist/src/services/mercadolibre/mercadolibre-sale-reference.js +7 -0
  22. package/dist/src/services/mercadolibre/mercadolibre-sale-reference.js.map +7 -0
  23. package/dist/src/services/mercadolibre/mercadolibre-sales-report.js +553 -0
  24. package/dist/src/services/mercadolibre/mercadolibre-sales-report.js.map +7 -0
  25. package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js +165 -0
  26. package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js.map +7 -0
  27. package/dist/src/tools/config/__tests__/list-profiles.test.js +144 -1
  28. package/dist/src/tools/config/__tests__/list-profiles.test.js.map +2 -2
  29. package/dist/src/tools/config/list-profiles.js +50 -6
  30. package/dist/src/tools/config/list-profiles.js.map +2 -2
  31. package/dist/src/tools/mercadolibre/__tests__/get-sales-report-foundation.test.js +417 -0
  32. package/dist/src/tools/mercadolibre/__tests__/get-sales-report-foundation.test.js.map +7 -0
  33. package/dist/src/tools/mercadolibre/get-sales-report.js +474 -0
  34. package/dist/src/tools/mercadolibre/get-sales-report.js.map +7 -0
  35. package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js +233 -0
  36. package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js.map +7 -0
  37. package/dist/src/tools/vtex/catalog-admin-batch.js +298 -0
  38. package/dist/src/tools/vtex/catalog-admin-batch.js.map +7 -0
  39. package/dist/tests/meli/meli-sales-report-buyers-mcp-e2e.test.js +137 -0
  40. package/dist/tests/meli/meli-sales-report-buyers-mcp-e2e.test.js.map +7 -0
  41. package/dist/tests/meli/meli-sales-report-mcp-e2e-server.js +24 -0
  42. package/dist/tests/meli/meli-sales-report-mcp-e2e-server.js.map +7 -0
  43. package/dist/tests/meli/meli-sales-report-mcp-e2e.test.js +207 -0
  44. package/dist/tests/meli/meli-sales-report-mcp-e2e.test.js.map +7 -0
  45. package/dist/tests/meli/meli-sales-report-public-mcp-e2e-server.js +10 -0
  46. package/dist/tests/meli/meli-sales-report-public-mcp-e2e-server.js.map +7 -0
  47. package/dist/tests/meli/meli-sales-report-public-registration.test.js +98 -0
  48. package/dist/tests/meli/meli-sales-report-public-registration.test.js.map +7 -0
  49. package/dist/tests/smoke/process-harness.js +89 -0
  50. package/dist/tests/smoke/process-harness.js.map +7 -0
  51. package/dist/tests/smoke/process-harness.test.js +39 -0
  52. package/dist/tests/smoke/process-harness.test.js.map +7 -0
  53. package/package.json +1 -1
@@ -0,0 +1,358 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildSalesReportFiscalIncident, buildSalesReportPostPurchaseIncident, enrichSalesReportCompradores, enrichSalesReportDevolucionesReclamos, enrichSalesReportEnvios, enrichSalesReportFacturacion, enrichSalesReportPublicaciones, enrichSalesReportVentas, groupMercadoLibreOrders } from "../mercadolibre-sales-report.js";
3
+ import { buildSalesReportShipmentCoverage, getSalesReportPostPurchaseCoverageState } from "../../../tools/mercadolibre/get-sales-report.js";
4
+ const operation = (pack_id, ...orderIds) => ({
5
+ pack_id,
6
+ ordenes: orderIds.map((order_id) => ({ order_id })),
7
+ ventas: { paquete_de_varios_productos: pack_id !== null }
8
+ });
9
+ const detail = (order_id, code, amount, date, currency = "ARS", description) => ({
10
+ charge_info: { detail_sub_type: code, detail_type: "CHARGE", detail_amount: amount, transaction_detail: description, creation_date_time: date },
11
+ currency_info: { currency_id: currency },
12
+ sales_info: [{ order_id }]
13
+ });
14
+ const publicationOrder = (order_id, item) => ({
15
+ ...operation(null, order_id),
16
+ ordenes: [{
17
+ order_id,
18
+ ventas: { pertenece_a_un_kit: null },
19
+ publicaciones: {
20
+ sku: item.seller_sku ?? null,
21
+ numero_de_publicacion: item.id ?? null,
22
+ canal_de_venta: null,
23
+ titulo_de_la_publicacion: item.title ?? null,
24
+ variante: item.variation_attributes ? "Color: Rojo" : null,
25
+ precio_unitario_de_venta_de_la_publicacion_ars: item.unit_price ?? null,
26
+ tiene_cuotas_agregadas: null
27
+ }
28
+ }]
29
+ });
30
+ describe("sales report ventas enrichment", () => {
31
+ it("maps only validated return and claim fields, preserving independent sources", () => {
32
+ const result = enrichSalesReportDevolucionesReclamos([operation(null, "o-1")], {
33
+ returns: { results: [{ sale_reference: "o-1", resolution: { kind: "order", status: "partial" }, return_context: { return_status: "with_return", return: { quantities: 2 }, review: { status: "success", date_created: "2026-06-02", product_destination: { code: "seller" }, reason: { code: "accepted" } } } }] },
34
+ claims: { results: [{ sale_reference: "o-1", resolution: { kind: "order", status: "partial" }, claim_context: { completeness: "partial", claims: [{ claimed_quantity: 1, status: "opened", type: "mediations" }] } }] }
35
+ });
36
+ expect(result.operations[0].ordenes[0].devoluciones).toMatchObject({ unidades: 2, revisado_por_mercado_libre: true, fecha_de_revision: "2026-06-02", resultado: "success", destino: "seller", motivo_del_resultado: "accepted" });
37
+ expect(result.operations[0].ordenes[0].reclamos).toEqual({ unidades: 1, reclamo_abierto: true, reclamo_cerrado: false, con_mediacion: true });
38
+ });
39
+ it("keeps absence unknown and isolates pack members", () => {
40
+ const result = enrichSalesReportDevolucionesReclamos([operation("p-1", "o-1", "o-2")], {
41
+ returns: { results: [{ sale_reference: "p-1", resolution: { kind: "pack", status: "partial" }, members: [{ member_index: 0, return_context: { return_status: "without_return" } }, { member_index: 1, issues: [{ code: "return_data_unavailable" }] }] }] },
42
+ claims: { results: [{ sale_reference: "p-1", resolution: { kind: "pack", status: "resolved" }, members: [{ member_index: 0, claim_context: { order_id: "o-1", completeness: "complete", claims: [] } }, { member_index: 1, claim_context: { order_id: "o-2", completeness: "complete", claims: [{ claimed_quantity: 1, status: "closed", type: "return" }] } }] }] }
43
+ });
44
+ expect(result.operations[0].ordenes.map((order) => order.devoluciones.unidades)).toEqual([null, null]);
45
+ expect(result.operations[0].ordenes.map((order) => order.reclamos)).toEqual([
46
+ { unidades: null, reclamo_abierto: null, reclamo_cerrado: null, con_mediacion: null },
47
+ { unidades: 1, reclamo_abierto: false, reclamo_cerrado: true, con_mediacion: false }
48
+ ]);
49
+ });
50
+ it("discloses only an order-scoped nickname after seller ownership matches", () => {
51
+ const operations = groupMercadoLibreOrders([{
52
+ id: "o-1",
53
+ seller: { id: "seller-1" },
54
+ buyer: {
55
+ nickname: "buyer-nickname",
56
+ first_name: "Private",
57
+ document: { number: "12345678" },
58
+ shipping_address: { city: "Private City" }
59
+ },
60
+ order_items: [],
61
+ date_created: "2026-06-01T00:00:00Z"
62
+ }]);
63
+ const result = enrichSalesReportCompradores(operations, "seller-1");
64
+ expect(result.operations[0].ordenes[0].compradores).toEqual({
65
+ comprador: "buyer-nickname",
66
+ negocio: null,
67
+ dni: null,
68
+ domicilio: null,
69
+ ciudad: null,
70
+ estado: null,
71
+ codigo_postal: null,
72
+ pais: null
73
+ });
74
+ expect(JSON.stringify(result.operations)).not.toContain("Private");
75
+ });
76
+ it("blocks mismatched or malformed ownership and buyer identifiers", () => {
77
+ const operations = groupMercadoLibreOrders([
78
+ { id: "o-mismatch", seller: { id: "other-seller" }, buyer: { nickname: "hidden" }, order_items: [], date_created: "2026-06-01T00:00:00Z" },
79
+ { id: "o-malformed", seller: { id: "seller-1" }, buyer: { nickname: { value: "hidden" } }, order_items: [], date_created: "2026-05-31T00:00:00Z" }
80
+ ]);
81
+ const result = enrichSalesReportCompradores(operations, "seller-1");
82
+ expect(result.operations.flatMap((operation2) => operation2.ordenes).map((order) => order.compradores)).toEqual([
83
+ { comprador: null, negocio: null, dni: null, domicilio: null, ciudad: null, estado: null, codigo_postal: null, pais: null },
84
+ { comprador: null, negocio: null, dni: null, domicilio: null, ciudad: null, estado: null, codigo_postal: null, pais: null }
85
+ ]);
86
+ expect(result.incidents.map((incident) => incident.alcance)).toEqual(["order", "order"]);
87
+ });
88
+ it("keeps buyer evidence isolated between pack members", () => {
89
+ const operations = groupMercadoLibreOrders([
90
+ { id: "o-1", pack_id: "pack-1", seller: { id: "seller-1" }, buyer: { nickname: "buyer-1" }, order_items: [], date_created: "2026-06-01T00:00:00Z" },
91
+ { id: "o-2", pack_id: "pack-1", seller: { id: "other-seller" }, buyer: { nickname: "buyer-2" }, order_items: [], date_created: "2026-06-01T00:00:00Z" }
92
+ ]);
93
+ const result = enrichSalesReportCompradores(operations, "seller-1");
94
+ expect(result.operations[0].ordenes.map((order) => order.compradores.comprador)).toEqual(["buyer-1", null]);
95
+ expect(result.incidents).toHaveLength(1);
96
+ });
97
+ it("joins reordered pack evidence by explicit order_id, not member index", () => {
98
+ const result = enrichSalesReportDevolucionesReclamos([operation("p-1", "o-1", "o-2")], {
99
+ returns: { results: [{ sale_reference: "p-1", resolution: { kind: "pack", status: "resolved" }, members: [
100
+ { member_index: 0, return_context: { order_id: "o-2", return_status: "with_return", return: { quantities: 2 } }, issues: [] },
101
+ { member_index: 1, return_context: { order_id: "o-1", return_status: "with_return", return: { quantities: 1 } }, issues: [] }
102
+ ] }] },
103
+ claims: { results: [] }
104
+ });
105
+ expect(result.operations[0].ordenes.map((order) => order.devoluciones.unidades)).toEqual([1, 2]);
106
+ });
107
+ it("emits member-level reconciliation issues and preserves status/retryability", () => {
108
+ const result = enrichSalesReportDevolucionesReclamos([operation("p-1", "o-1")], {
109
+ returns: { results: [{ sale_reference: "p-1", resolution: { kind: "pack", status: "partial" }, members: [{ member_index: 0, return_context: { order_id: "o-1", return_status: "return_unverified" }, issues: [{ code: "return_data_unavailable" }] }] }] },
110
+ claims: { results: [] }
111
+ });
112
+ expect(result.incidents).toEqual([expect.objectContaining({ fuente: "returns", alcance: "order", identificadores: ["o-1"] })]);
113
+ expect(buildSalesReportPostPurchaseIncident("claims", new Error("transport"))).toMatchObject({ reintentable: true, estado_http: null });
114
+ expect(buildSalesReportPostPurchaseIncident("returns", { status: 404 })).toMatchObject({ reintentable: false, estado_http: 404 });
115
+ expect(getSalesReportPostPurchaseCoverageState("fulfilled", [{ status: "unavailable" }], 0)).toBe("partial");
116
+ expect(getSalesReportPostPurchaseCoverageState("fulfilled", [{ status: "resolved" }], 1)).toBe("partial");
117
+ expect(getSalesReportPostPurchaseCoverageState("rejected")).toBe("unavailable");
118
+ });
119
+ it("joins contextless return failure to the correct reordered pack member", () => {
120
+ const result = enrichSalesReportDevolucionesReclamos([operation("p-1", "o-1", "o-2")], {
121
+ returns: { results: [{ sale_reference: "p-1", resolution: { kind: "pack", status: "unavailable" }, members: [
122
+ { member_index: 0, order_id: "o-2", issues: [{ code: "order_unavailable" }] },
123
+ { member_index: 1, order_id: "o-1", return_context: { order_id: "o-1", return_status: "with_return", return: { quantities: 1 } } }
124
+ ] }] },
125
+ claims: { results: [] }
126
+ });
127
+ expect(result.operations[0].ordenes.map((order) => order.devoluciones.unidades)).toEqual([1, null]);
128
+ expect(result.incidents).toEqual([expect.objectContaining({ fuente: "returns", identificadores: ["o-2"] })]);
129
+ });
130
+ it("joins contextless claim failure to the correct reordered pack member", () => {
131
+ const result = enrichSalesReportDevolucionesReclamos([operation("p-1", "o-1", "o-2")], {
132
+ returns: { results: [] },
133
+ claims: { results: [{ sale_reference: "p-1", resolution: { kind: "pack", status: "unavailable" }, members: [
134
+ { member_index: 0, order_id: "o-2", issues: [{ code: "order_unavailable" }] },
135
+ { member_index: 1, order_id: "o-1", claim_context: { order_id: "o-1", completeness: "complete", claims: [{ claimed_quantity: 1, status: "closed", type: "return" }] } }
136
+ ] }] }
137
+ });
138
+ expect(result.operations[0].ordenes.map((order) => order.reclamos.unidades)).toEqual([1, null]);
139
+ expect(result.incidents).toEqual([expect.objectContaining({ fuente: "claims", identificadores: ["o-2"] })]);
140
+ });
141
+ it("maps only validated fiscal fields and keeps attachments and IIBB unsupported", () => {
142
+ const result = enrichSalesReportFacturacion(
143
+ [operation(null, "o-1")],
144
+ [{ orderId: "o-1", result: {
145
+ available: true,
146
+ order: { seller: { id: "seller-1" } },
147
+ billingInfo: { buyer: { billing_info: {
148
+ name: "Synthetic",
149
+ last_name: "Buyer",
150
+ identification: { type: "DNI", number: "12345678" },
151
+ address: { street_name: "Synthetic Street", street_number: 10, city_name: "Test City", state: "Test State", zip_code: "1000", country_id: "AR" },
152
+ taxes: { taxpayer_type: { id: "IVA_CF", description: "Consumidor Final" } }
153
+ } } }
154
+ } }]
155
+ );
156
+ expect(result.operations[0].ordenes[0].facturacion_al_comprador).toEqual({
157
+ factura_adjunta: null,
158
+ datos_personales_o_de_empresa: "Synthetic Buyer",
159
+ tipo_y_numero_de_documento: "DNI 12345678",
160
+ direccion: "Synthetic Street 10, Test City, Test State, 1000, AR",
161
+ condicion_fiscal_iva: "Consumidor Final",
162
+ numero_iibb: null
163
+ });
164
+ expect(result.fieldCoverage.factura_adjunta).toEqual({ solicitados: 1, obtenidos: 0 });
165
+ expect(result.fieldCoverage.numero_iibb).toEqual({ solicitados: 1, obtenidos: 0 });
166
+ });
167
+ it("keeps fiscal fields null and records a scoped incident for unavailable evidence", () => {
168
+ const unavailable = {
169
+ available: false,
170
+ reason: "order_seller_ownership_mismatch"
171
+ };
172
+ const result = enrichSalesReportFacturacion(
173
+ [operation(null, "o-1")],
174
+ [{ orderId: "o-1", result: unavailable }]
175
+ );
176
+ expect(result.operations[0].ordenes[0].facturacion_al_comprador).toEqual({
177
+ factura_adjunta: null,
178
+ datos_personales_o_de_empresa: null,
179
+ tipo_y_numero_de_documento: null,
180
+ direccion: null,
181
+ condicion_fiscal_iva: null,
182
+ numero_iibb: null
183
+ });
184
+ expect(result.incidents).toEqual(expect.arrayContaining([expect.objectContaining({
185
+ fuente: "billing_info",
186
+ alcance: "order.datos_personales_o_de_empresa",
187
+ identificadores: ["o-1"]
188
+ })]));
189
+ expect(result.fieldCoverage.datos_personales_o_de_empresa).toEqual({ solicitados: 1, obtenidos: 0 });
190
+ });
191
+ it("maps valid fiscal fields independently when name or address fields are partial", () => {
192
+ const result = enrichSalesReportFacturacion([operation("pack-1", "o-1", "o-2")], [
193
+ { orderId: "o-1", result: { available: true, order: {}, billingInfo: { buyer: { billing_info: {
194
+ identification: { type: "DNI", number: "12345678" },
195
+ address: { street_name: "Synthetic Street", street_number: 10, city_name: "Test City" },
196
+ taxes: { taxpayer_type: { description: "Consumidor Final" } }
197
+ } } } } },
198
+ { orderId: "o-2", result: { available: false, reason: "billing_info_fiscal_fields_missing" } }
199
+ ]);
200
+ expect(result.operations[0].ordenes[0].facturacion_al_comprador).toMatchObject({
201
+ datos_personales_o_de_empresa: null,
202
+ tipo_y_numero_de_documento: "DNI 12345678",
203
+ direccion: "Synthetic Street 10, Test City",
204
+ condicion_fiscal_iva: "Consumidor Final"
205
+ });
206
+ expect(result.operations[0].ordenes[1].facturacion_al_comprador.datos_personales_o_de_empresa).toBeNull();
207
+ expect(result.operations[0].ordenes[1].facturacion_al_comprador.tipo_y_numero_de_documento).toBeNull();
208
+ expect(result.incidents).toEqual(expect.arrayContaining([
209
+ expect.objectContaining({ alcance: "order.datos_personales_o_de_empresa", identificadores: ["o-1"] })
210
+ ]));
211
+ });
212
+ it("keeps unrelated fiscal fields when a synthetic field value is malformed", () => {
213
+ const result = enrichSalesReportFacturacion([operation(null, "o-1")], [{ orderId: "o-1", result: {
214
+ available: true,
215
+ order: {},
216
+ billingInfo: { buyer: { billing_info: {
217
+ name: { unexpected: "malformed" },
218
+ last_name: null,
219
+ identification: { type: "DNI", number: "12345678" },
220
+ address: { street_name: "Synthetic Street", street_number: 10, city_name: "Test City" },
221
+ taxes: { taxpayer_type: { id: { unexpected: "malformed" }, description: "Consumidor Final" } }
222
+ } } }
223
+ } }]);
224
+ expect(result.operations[0].ordenes[0].facturacion_al_comprador).toMatchObject({
225
+ datos_personales_o_de_empresa: null,
226
+ tipo_y_numero_de_documento: "DNI 12345678",
227
+ direccion: "Synthetic Street 10, Test City",
228
+ condicion_fiscal_iva: "Consumidor Final"
229
+ });
230
+ expect(result.incidents).toEqual(expect.arrayContaining([
231
+ expect.objectContaining({ alcance: "order.datos_personales_o_de_empresa", identificadores: ["o-1"] })
232
+ ]));
233
+ });
234
+ it.each([
235
+ [401, false],
236
+ [403, false],
237
+ [404, false],
238
+ [503, true],
239
+ [429, true],
240
+ [void 0, true]
241
+ ])("preserves fiscal request status %s and retryability", (statusCode, retryable) => {
242
+ const incident = buildSalesReportFiscalIncident("o-synthetic", statusCode, retryable);
243
+ expect(incident).toMatchObject({ fuente: "billing_info", estado_http: statusCode ?? null, reintentable: retryable });
244
+ expect(incident.mensaje).toContain(statusCode == null ? "transport" : `HTTP ${statusCode}`);
245
+ });
246
+ it("marks shipment coverage partial when mapping incidents exist without batch failures", () => {
247
+ expect(buildSalesReportShipmentCoverage(2, 2, 1, 0)).toEqual({
248
+ fuente: "shipments",
249
+ estado: "partial",
250
+ solicitados: 2,
251
+ obtenidos: 2,
252
+ incidentes: 1
253
+ });
254
+ });
255
+ it("maps shipment evidence only to its scoped order", () => {
256
+ const result = enrichSalesReportEnvios(
257
+ [operation(null, "o-1"), operation(null, "o-2")],
258
+ [{ order_id: "o-1", shipment: {
259
+ order_id: "o-1",
260
+ mode: "me2",
261
+ shipping_option: { name: "Express a domicilio" },
262
+ status_history: { date_shipped: "2026-06-01T10:00:00Z", date_delivered: "2026-06-03T10:00:00Z" },
263
+ carrier_info: { name: "Carrier One", url: "https://carrier.example/track/1" },
264
+ tracking_number: "TRACK-1"
265
+ } }]
266
+ );
267
+ expect(result.operations[0].ordenes[0].envios).toEqual({
268
+ forma_de_entrega: "Express a domicilio",
269
+ fecha_en_camino: "2026-06-01T10:00:00Z",
270
+ fecha_entregado: "2026-06-03T10:00:00Z",
271
+ transportista: "Carrier One",
272
+ numero_de_seguimiento: "TRACK-1",
273
+ url_de_seguimiento: "https://carrier.example/track/1"
274
+ });
275
+ expect(result.operations[1].ordenes[0].envios).toEqual({
276
+ forma_de_entrega: null,
277
+ fecha_en_camino: null,
278
+ fecha_entregado: null,
279
+ transportista: null,
280
+ numero_de_seguimiento: null,
281
+ url_de_seguimiento: null
282
+ });
283
+ });
284
+ it("keeps shipment fields null and records a scoped incident for mismatched evidence", () => {
285
+ const result = enrichSalesReportEnvios(
286
+ [operation(null, "o-1")],
287
+ [{ order_id: "o-1", shipment: { order_id: "o-elsewhere", tracking_number: "UNRELATED" } }]
288
+ );
289
+ expect(result.operations[0].ordenes[0].envios.numero_de_seguimiento).toBeNull();
290
+ expect(result.incidents).toEqual([expect.objectContaining({ fuente: "shipments", alcance: "order", identificadores: ["o-1"] })]);
291
+ });
292
+ it("does not infer unavailable carrier or lifecycle values", () => {
293
+ const result = enrichSalesReportEnvios(
294
+ [operation(null, "o-1")],
295
+ [{ order_id: "o-1", shipment: { order_id: "o-1", tracking_number: "TRACK-1" } }]
296
+ );
297
+ expect(result.operations[0].ordenes[0].envios).toEqual({
298
+ forma_de_entrega: null,
299
+ fecha_en_camino: null,
300
+ fecha_entregado: null,
301
+ transportista: null,
302
+ numero_de_seguimiento: "TRACK-1",
303
+ url_de_seguimiento: null
304
+ });
305
+ expect(result.incidents).toEqual(expect.arrayContaining([
306
+ expect.objectContaining({ alcance: "order.fecha_en_camino" }),
307
+ expect.objectContaining({ alcance: "order.fecha_entregado" }),
308
+ expect.objectContaining({ alcance: "order.transportista" }),
309
+ expect.objectContaining({ alcance: "order.url_de_seguimiento" })
310
+ ]));
311
+ expect(result.fieldCoverage).toMatchObject({
312
+ forma_de_entrega: { solicitados: 1, obtenidos: 0 },
313
+ fecha_en_camino: { solicitados: 1, obtenidos: 0 },
314
+ numero_de_seguimiento: { solicitados: 1, obtenidos: 1 },
315
+ transportista: { solicitados: 1, obtenidos: 0 },
316
+ url_de_seguimiento: { solicitados: 1, obtenidos: 0 }
317
+ });
318
+ });
319
+ it("aggregates a pack once, applies signed CDSD, and discovers billing periods", () => {
320
+ const result = enrichSalesReportVentas(
321
+ [operation("pack-1", "o-1", "o-2")],
322
+ { results: [{ order_id: "o-1", details: [detail("o-1", "CVFF", 10, "2026-06-01"), detail("o-2", "CVFV", 20, "2026-07-02"), detail("o-2", "CDSD", 5, "2026-07-02", "ARS", "Cargo por devoluci\xF3n")] }], order_ids_requested: ["o-1", "o-2"], order_ids_found: ["o-1", "o-2"], order_ids_not_found: [], chunks_total: 1, chunks_succeeded: 1, chunks_failed: 0, coverage_complete: true, failures: [] }
323
+ );
324
+ expect(result.operations[0].ventas).toMatchObject({ costo_fijo: -10, cargo_por_venta: -20, anulaciones_y_reembolsos_ars: -5, total_ars: -35, cargo_por_diferencias_en_medidas_y_peso_del_paquete: null, periodos_de_facturacion: ["2026-06", "2026-07"] });
325
+ });
326
+ it("keeps partial billing nulls, rejects foreign currency, and reports unknown concepts", () => {
327
+ const result = enrichSalesReportVentas(
328
+ [operation(null, "o-1"), operation(null, "o-2")],
329
+ { results: [{ order_id: "o-1", details: [detail("o-1", "NEW", 9, "2026-06-01", "USD"), detail("o-1", "CVFN", 3, "2026-06-01")] }], order_ids_requested: ["o-1", "o-2"], order_ids_found: ["o-1"], order_ids_not_found: ["o-2"], chunks_total: 1, chunks_succeeded: 1, chunks_failed: 0, coverage_complete: true, failures: [] }
330
+ );
331
+ expect(result.operations[0].ventas).toMatchObject({ costo_por_ofrecer_cuotas: -3, cargo_por_venta: null, total_ars: -3 });
332
+ expect(result.operations[1].ventas).toMatchObject({ costo_por_ofrecer_cuotas: null, total_ars: null });
333
+ expect(result.unknownConcepts).toEqual(["NEW"]);
334
+ expect(result.incidents[0].identificadores).toEqual(["o-2"]);
335
+ });
336
+ it("maps billing listing evidence per order and formats variation attributes", () => {
337
+ const result = enrichSalesReportPublicaciones(
338
+ [publicationOrder("o-1", { seller_sku: "SKU-1", id: "MLA-1", title: "Title", unit_price: 12 })],
339
+ { results: [{ order_id: "o-1", details: [{
340
+ sales_info: [{ order_id: "o-1", sales_channel: "marketplace" }],
341
+ items_info: [{ item_id: "MLA-1", item_price: 13, item_kit_id: "KIT-1", fees_added_in_publication: "Si" }]
342
+ }] }], order_ids_requested: ["o-1"], order_ids_found: ["o-1"], order_ids_not_found: [], chunks_total: 1, chunks_succeeded: 1, chunks_failed: 0, coverage_complete: true, failures: [] }
343
+ );
344
+ expect(result.operations[0].ordenes[0]).toMatchObject({
345
+ ventas: { pertenece_a_un_kit: true },
346
+ publicaciones: { canal_de_venta: "marketplace", tiene_cuotas_agregadas: true, precio_unitario_de_venta_de_la_publicacion_ars: 12 }
347
+ });
348
+ });
349
+ it("keeps publication billing signals null when the order is not covered", () => {
350
+ const result = enrichSalesReportPublicaciones(
351
+ [publicationOrder("o-1", { variation_attributes: [{ name: "Color", value_name: "Rojo" }] })],
352
+ { results: [], order_ids_requested: ["o-1"], order_ids_found: [], order_ids_not_found: ["o-1"], chunks_total: 1, chunks_succeeded: 1, chunks_failed: 0, coverage_complete: true, failures: [] }
353
+ );
354
+ expect(result.operations[0].ordenes[0].publicaciones).toMatchObject({ variante: "Color: Rojo", canal_de_venta: null, tiene_cuotas_agregadas: null });
355
+ expect(result.operations[0].ordenes[0].ventas.pertenece_a_un_kit).toBeNull();
356
+ });
357
+ });
358
+ //# sourceMappingURL=mercadolibre-sales-report-ventas.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/services/mercadolibre/__tests__/mercadolibre-sales-report-ventas.test.ts"],
4
+ "sourcesContent": ["import { describe, expect, it } from \"vitest\";\n\nimport { buildSalesReportFiscalIncident, buildSalesReportPostPurchaseIncident, enrichSalesReportCompradores, enrichSalesReportDevolucionesReclamos, enrichSalesReportEnvios, enrichSalesReportFacturacion, enrichSalesReportPublicaciones, enrichSalesReportVentas, groupMercadoLibreOrders } from \"../mercadolibre-sales-report.js\";\nimport type { MercadoLibreOrderBillingInfoResult } from \"../mercadolibre-order-billing-info.js\";\nimport type { SalesReportOperation } from \"../../../tools/mercadolibre/get-sales-report.js\";\nimport { buildSalesReportShipmentCoverage, getSalesReportPostPurchaseCoverageState } from \"../../../tools/mercadolibre/get-sales-report.js\";\n\nconst operation = (pack_id: string | null, ...orderIds: string[]) => ({\n pack_id,\n ordenes: orderIds.map((order_id) => ({ order_id })) as SalesReportOperation[\"ordenes\"],\n ventas: { paquete_de_varios_productos: pack_id !== null },\n}) as SalesReportOperation;\n\nconst detail = (order_id: string, code: string, amount: number, date: string, currency = \"ARS\", description?: string) => ({\n charge_info: { detail_sub_type: code, detail_type: \"CHARGE\", detail_amount: amount, transaction_detail: description, creation_date_time: date },\n currency_info: { currency_id: currency }, sales_info: [{ order_id }],\n});\n\nconst publicationOrder = (order_id: string, item: Record<string, unknown>) => ({\n ...operation(null, order_id),\n ordenes: [{\n order_id,\n ventas: { pertenece_a_un_kit: null },\n publicaciones: {\n sku: item.seller_sku ?? null, numero_de_publicacion: item.id ?? null,\n canal_de_venta: null, titulo_de_la_publicacion: item.title ?? null,\n variante: item.variation_attributes ? \"Color: Rojo\" : null, precio_unitario_de_venta_de_la_publicacion_ars: item.unit_price ?? null,\n tiene_cuotas_agregadas: null,\n },\n }],\n} as unknown as SalesReportOperation);\n\ndescribe(\"sales report ventas enrichment\", () => {\n it(\"maps only validated return and claim fields, preserving independent sources\", () => {\n const result = enrichSalesReportDevolucionesReclamos([operation(null, \"o-1\")], {\n returns: { results: [{ sale_reference: \"o-1\", resolution: { kind: \"order\", status: \"partial\" }, return_context: { return_status: \"with_return\", return: { quantities: 2 }, review: { status: \"success\", date_created: \"2026-06-02\", product_destination: { code: \"seller\" }, reason: { code: \"accepted\" } } } }] },\n claims: { results: [{ sale_reference: \"o-1\", resolution: { kind: \"order\", status: \"partial\" }, claim_context: { completeness: \"partial\", claims: [{ claimed_quantity: 1, status: \"opened\", type: \"mediations\" }] } }] },\n });\n expect(result.operations[0].ordenes[0].devoluciones).toMatchObject({ unidades: 2, revisado_por_mercado_libre: true, fecha_de_revision: \"2026-06-02\", resultado: \"success\", destino: \"seller\", motivo_del_resultado: \"accepted\" });\n expect(result.operations[0].ordenes[0].reclamos).toEqual({ unidades: 1, reclamo_abierto: true, reclamo_cerrado: false, con_mediacion: true });\n });\n\n it(\"keeps absence unknown and isolates pack members\", () => {\n const result = enrichSalesReportDevolucionesReclamos([operation(\"p-1\", \"o-1\", \"o-2\")], {\n returns: { results: [{ sale_reference: \"p-1\", resolution: { kind: \"pack\", status: \"partial\" }, members: [{ member_index: 0, return_context: { return_status: \"without_return\" } }, { member_index: 1, issues: [{ code: \"return_data_unavailable\" }] }] }] },\n claims: { results: [{ sale_reference: \"p-1\", resolution: { kind: \"pack\", status: \"resolved\" }, members: [{ member_index: 0, claim_context: { order_id: \"o-1\", completeness: \"complete\", claims: [] } }, { member_index: 1, claim_context: { order_id: \"o-2\", completeness: \"complete\", claims: [{ claimed_quantity: 1, status: \"closed\", type: \"return\" }] } }] }] },\n });\n expect(result.operations[0].ordenes.map((order) => order.devoluciones.unidades)).toEqual([null, null]);\n expect(result.operations[0].ordenes.map((order) => order.reclamos)).toEqual([\n { unidades: null, reclamo_abierto: null, reclamo_cerrado: null, con_mediacion: null },\n { unidades: 1, reclamo_abierto: false, reclamo_cerrado: true, con_mediacion: false },\n ]);\n });\n\n it(\"discloses only an order-scoped nickname after seller ownership matches\", () => {\n const operations = groupMercadoLibreOrders([{\n id: \"o-1\", seller: { id: \"seller-1\" }, buyer: {\n nickname: \"buyer-nickname\", first_name: \"Private\", document: { number: \"12345678\" },\n shipping_address: { city: \"Private City\" },\n }, order_items: [], date_created: \"2026-06-01T00:00:00Z\",\n }]);\n const result = enrichSalesReportCompradores(operations, \"seller-1\");\n\n expect(result.operations[0].ordenes[0].compradores).toEqual({\n comprador: \"buyer-nickname\", negocio: null, dni: null, domicilio: null,\n ciudad: null, estado: null, codigo_postal: null, pais: null,\n });\n expect(JSON.stringify(result.operations)).not.toContain(\"Private\");\n });\n\n it(\"blocks mismatched or malformed ownership and buyer identifiers\", () => {\n const operations = groupMercadoLibreOrders([\n { id: \"o-mismatch\", seller: { id: \"other-seller\" }, buyer: { nickname: \"hidden\" }, order_items: [], date_created: \"2026-06-01T00:00:00Z\" },\n { id: \"o-malformed\", seller: { id: \"seller-1\" }, buyer: { nickname: { value: \"hidden\" } }, order_items: [], date_created: \"2026-05-31T00:00:00Z\" },\n ]);\n const result = enrichSalesReportCompradores(operations, \"seller-1\");\n\n expect(result.operations.flatMap((operation) => operation.ordenes).map((order) => order.compradores)).toEqual([\n { comprador: null, negocio: null, dni: null, domicilio: null, ciudad: null, estado: null, codigo_postal: null, pais: null },\n { comprador: null, negocio: null, dni: null, domicilio: null, ciudad: null, estado: null, codigo_postal: null, pais: null },\n ]);\n expect(result.incidents.map((incident) => incident.alcance)).toEqual([\"order\", \"order\"]);\n });\n\n it(\"keeps buyer evidence isolated between pack members\", () => {\n const operations = groupMercadoLibreOrders([\n { id: \"o-1\", pack_id: \"pack-1\", seller: { id: \"seller-1\" }, buyer: { nickname: \"buyer-1\" }, order_items: [], date_created: \"2026-06-01T00:00:00Z\" },\n { id: \"o-2\", pack_id: \"pack-1\", seller: { id: \"other-seller\" }, buyer: { nickname: \"buyer-2\" }, order_items: [], date_created: \"2026-06-01T00:00:00Z\" },\n ]);\n const result = enrichSalesReportCompradores(operations, \"seller-1\");\n\n expect(result.operations[0].ordenes.map((order) => order.compradores.comprador)).toEqual([\"buyer-1\", null]);\n expect(result.incidents).toHaveLength(1);\n });\n\n it(\"joins reordered pack evidence by explicit order_id, not member index\", () => {\n const result = enrichSalesReportDevolucionesReclamos([operation(\"p-1\", \"o-1\", \"o-2\")], {\n returns: { results: [{ sale_reference: \"p-1\", resolution: { kind: \"pack\", status: \"resolved\" }, members: [\n { member_index: 0, return_context: { order_id: \"o-2\", return_status: \"with_return\", return: { quantities: 2 } }, issues: [] },\n { member_index: 1, return_context: { order_id: \"o-1\", return_status: \"with_return\", return: { quantities: 1 } }, issues: [] },\n ] }] },\n claims: { results: [] },\n });\n expect(result.operations[0].ordenes.map((order) => order.devoluciones.unidades)).toEqual([1, 2]);\n });\n\n it(\"emits member-level reconciliation issues and preserves status/retryability\", () => {\n const result = enrichSalesReportDevolucionesReclamos([operation(\"p-1\", \"o-1\")], {\n returns: { results: [{ sale_reference: \"p-1\", resolution: { kind: \"pack\", status: \"partial\" }, members: [{ member_index: 0, return_context: { order_id: \"o-1\", return_status: \"return_unverified\" }, issues: [{ code: \"return_data_unavailable\" }] }] }] },\n claims: { results: [] },\n });\n expect(result.incidents).toEqual([expect.objectContaining({ fuente: \"returns\", alcance: \"order\", identificadores: [\"o-1\"] })]);\n expect(buildSalesReportPostPurchaseIncident(\"claims\", new Error(\"transport\"))).toMatchObject({ reintentable: true, estado_http: null });\n expect(buildSalesReportPostPurchaseIncident(\"returns\", { status: 404 })).toMatchObject({ reintentable: false, estado_http: 404 });\n expect(getSalesReportPostPurchaseCoverageState(\"fulfilled\", [{ status: \"unavailable\" }], 0)).toBe(\"partial\");\n expect(getSalesReportPostPurchaseCoverageState(\"fulfilled\", [{ status: \"resolved\" }], 1)).toBe(\"partial\");\n expect(getSalesReportPostPurchaseCoverageState(\"rejected\")).toBe(\"unavailable\");\n });\n\n it(\"joins contextless return failure to the correct reordered pack member\", () => {\n const result = enrichSalesReportDevolucionesReclamos([operation(\"p-1\", \"o-1\", \"o-2\")], {\n returns: { results: [{ sale_reference: \"p-1\", resolution: { kind: \"pack\", status: \"unavailable\" }, members: [\n { member_index: 0, order_id: \"o-2\", issues: [{ code: \"order_unavailable\" }] },\n { member_index: 1, order_id: \"o-1\", return_context: { order_id: \"o-1\", return_status: \"with_return\", return: { quantities: 1 } } },\n ] }] }, claims: { results: [] },\n });\n expect(result.operations[0].ordenes.map((order) => order.devoluciones.unidades)).toEqual([1, null]);\n expect(result.incidents).toEqual([expect.objectContaining({ fuente: \"returns\", identificadores: [\"o-2\"] })]);\n });\n\n it(\"joins contextless claim failure to the correct reordered pack member\", () => {\n const result = enrichSalesReportDevolucionesReclamos([operation(\"p-1\", \"o-1\", \"o-2\")], {\n returns: { results: [] }, claims: { results: [{ sale_reference: \"p-1\", resolution: { kind: \"pack\", status: \"unavailable\" }, members: [\n { member_index: 0, order_id: \"o-2\", issues: [{ code: \"order_unavailable\" }] },\n { member_index: 1, order_id: \"o-1\", claim_context: { order_id: \"o-1\", completeness: \"complete\", claims: [{ claimed_quantity: 1, status: \"closed\", type: \"return\" }] } },\n ] }] },\n });\n expect(result.operations[0].ordenes.map((order) => order.reclamos.unidades)).toEqual([1, null]);\n expect(result.incidents).toEqual([expect.objectContaining({ fuente: \"claims\", identificadores: [\"o-2\"] })]);\n });\n\n it(\"maps only validated fiscal fields and keeps attachments and IIBB unsupported\", () => {\n const result = enrichSalesReportFacturacion(\n [operation(null, \"o-1\")],\n [{ orderId: \"o-1\", result: {\n available: true,\n order: { seller: { id: \"seller-1\" } },\n billingInfo: { buyer: { billing_info: {\n name: \"Synthetic\", last_name: \"Buyer\",\n identification: { type: \"DNI\", number: \"12345678\" },\n address: { street_name: \"Synthetic Street\", street_number: 10, city_name: \"Test City\", state: \"Test State\", zip_code: \"1000\", country_id: \"AR\" },\n taxes: { taxpayer_type: { id: \"IVA_CF\", description: \"Consumidor Final\" } },\n } } },\n } }],\n );\n\n expect(result.operations[0].ordenes[0].facturacion_al_comprador).toEqual({\n factura_adjunta: null,\n datos_personales_o_de_empresa: \"Synthetic Buyer\",\n tipo_y_numero_de_documento: \"DNI 12345678\",\n direccion: \"Synthetic Street 10, Test City, Test State, 1000, AR\",\n condicion_fiscal_iva: \"Consumidor Final\",\n numero_iibb: null,\n });\n expect(result.fieldCoverage.factura_adjunta).toEqual({ solicitados: 1, obtenidos: 0 });\n expect(result.fieldCoverage.numero_iibb).toEqual({ solicitados: 1, obtenidos: 0 });\n });\n\n it(\"keeps fiscal fields null and records a scoped incident for unavailable evidence\", () => {\n const unavailable: MercadoLibreOrderBillingInfoResult = {\n available: false,\n reason: \"order_seller_ownership_mismatch\",\n };\n const result = enrichSalesReportFacturacion(\n [operation(null, \"o-1\")],\n [{ orderId: \"o-1\", result: unavailable }],\n );\n\n expect(result.operations[0].ordenes[0].facturacion_al_comprador).toEqual({\n factura_adjunta: null, datos_personales_o_de_empresa: null,\n tipo_y_numero_de_documento: null, direccion: null,\n condicion_fiscal_iva: null, numero_iibb: null,\n });\n expect(result.incidents).toEqual(expect.arrayContaining([expect.objectContaining({\n fuente: \"billing_info\", alcance: \"order.datos_personales_o_de_empresa\", identificadores: [\"o-1\"],\n })]));\n expect(result.fieldCoverage.datos_personales_o_de_empresa).toEqual({ solicitados: 1, obtenidos: 0 });\n });\n\n it(\"maps valid fiscal fields independently when name or address fields are partial\", () => {\n const result = enrichSalesReportFacturacion([operation(\"pack-1\", \"o-1\", \"o-2\")], [\n { orderId: \"o-1\", result: { available: true, order: {}, billingInfo: { buyer: { billing_info: {\n identification: { type: \"DNI\", number: \"12345678\" },\n address: { street_name: \"Synthetic Street\", street_number: 10, city_name: \"Test City\" },\n taxes: { taxpayer_type: { description: \"Consumidor Final\" } },\n } } } } },\n { orderId: \"o-2\", result: { available: false, reason: \"billing_info_fiscal_fields_missing\" } },\n ]);\n\n expect(result.operations[0].ordenes[0].facturacion_al_comprador).toMatchObject({\n datos_personales_o_de_empresa: null,\n tipo_y_numero_de_documento: \"DNI 12345678\",\n direccion: \"Synthetic Street 10, Test City\",\n condicion_fiscal_iva: \"Consumidor Final\",\n });\n expect(result.operations[0].ordenes[1].facturacion_al_comprador.datos_personales_o_de_empresa).toBeNull();\n expect(result.operations[0].ordenes[1].facturacion_al_comprador.tipo_y_numero_de_documento).toBeNull();\n expect(result.incidents).toEqual(expect.arrayContaining([\n expect.objectContaining({ alcance: \"order.datos_personales_o_de_empresa\", identificadores: [\"o-1\"] }),\n ]));\n });\n\n it(\"keeps unrelated fiscal fields when a synthetic field value is malformed\", () => {\n const result = enrichSalesReportFacturacion([operation(null, \"o-1\")], [{ orderId: \"o-1\", result: {\n available: true, order: {}, billingInfo: { buyer: { billing_info: {\n name: { unexpected: \"malformed\" }, last_name: null,\n identification: { type: \"DNI\", number: \"12345678\" },\n address: { street_name: \"Synthetic Street\", street_number: 10, city_name: \"Test City\" },\n taxes: { taxpayer_type: { id: { unexpected: \"malformed\" }, description: \"Consumidor Final\" } },\n } } },\n } }]);\n\n expect(result.operations[0].ordenes[0].facturacion_al_comprador).toMatchObject({\n datos_personales_o_de_empresa: null,\n tipo_y_numero_de_documento: \"DNI 12345678\",\n direccion: \"Synthetic Street 10, Test City\",\n condicion_fiscal_iva: \"Consumidor Final\",\n });\n expect(result.incidents).toEqual(expect.arrayContaining([\n expect.objectContaining({ alcance: \"order.datos_personales_o_de_empresa\", identificadores: [\"o-1\"] }),\n ]));\n });\n\n it.each([\n [401, false], [403, false], [404, false], [503, true], [429, true], [undefined, true],\n ])(\"preserves fiscal request status %s and retryability\", (statusCode, retryable) => {\n const incident = buildSalesReportFiscalIncident(\"o-synthetic\", statusCode, retryable);\n expect(incident).toMatchObject({ fuente: \"billing_info\", estado_http: statusCode ?? null, reintentable: retryable });\n expect(incident.mensaje).toContain(statusCode == null ? \"transport\" : `HTTP ${statusCode}`);\n });\n\n it(\"marks shipment coverage partial when mapping incidents exist without batch failures\", () => {\n expect(buildSalesReportShipmentCoverage(2, 2, 1, 0)).toEqual({\n fuente: \"shipments\", estado: \"partial\", solicitados: 2, obtenidos: 2, incidentes: 1,\n });\n });\n\n it(\"maps shipment evidence only to its scoped order\", () => {\n const result = enrichSalesReportEnvios(\n [operation(null, \"o-1\"), operation(null, \"o-2\")],\n [{ order_id: \"o-1\", shipment: {\n order_id: \"o-1\", mode: \"me2\", shipping_option: { name: \"Express a domicilio\" },\n status_history: { date_shipped: \"2026-06-01T10:00:00Z\", date_delivered: \"2026-06-03T10:00:00Z\" },\n carrier_info: { name: \"Carrier One\", url: \"https://carrier.example/track/1\" }, tracking_number: \"TRACK-1\",\n } }],\n );\n expect(result.operations[0].ordenes[0].envios).toEqual({\n forma_de_entrega: \"Express a domicilio\", fecha_en_camino: \"2026-06-01T10:00:00Z\",\n fecha_entregado: \"2026-06-03T10:00:00Z\", transportista: \"Carrier One\",\n numero_de_seguimiento: \"TRACK-1\", url_de_seguimiento: \"https://carrier.example/track/1\",\n });\n expect(result.operations[1].ordenes[0].envios).toEqual({\n forma_de_entrega: null, fecha_en_camino: null, fecha_entregado: null,\n transportista: null, numero_de_seguimiento: null, url_de_seguimiento: null,\n });\n });\n\n it(\"keeps shipment fields null and records a scoped incident for mismatched evidence\", () => {\n const result = enrichSalesReportEnvios(\n [operation(null, \"o-1\")],\n [{ order_id: \"o-1\", shipment: { order_id: \"o-elsewhere\", tracking_number: \"UNRELATED\" } }],\n );\n expect(result.operations[0].ordenes[0].envios.numero_de_seguimiento).toBeNull();\n expect(result.incidents).toEqual([expect.objectContaining({ fuente: \"shipments\", alcance: \"order\", identificadores: [\"o-1\"] })]);\n });\n\n it(\"does not infer unavailable carrier or lifecycle values\", () => {\n const result = enrichSalesReportEnvios(\n [operation(null, \"o-1\")],\n [{ order_id: \"o-1\", shipment: { order_id: \"o-1\", tracking_number: \"TRACK-1\" } }],\n );\n expect(result.operations[0].ordenes[0].envios).toEqual({\n forma_de_entrega: null, fecha_en_camino: null, fecha_entregado: null,\n transportista: null, numero_de_seguimiento: \"TRACK-1\", url_de_seguimiento: null,\n });\n expect(result.incidents).toEqual(expect.arrayContaining([\n expect.objectContaining({ alcance: \"order.fecha_en_camino\" }),\n expect.objectContaining({ alcance: \"order.fecha_entregado\" }),\n expect.objectContaining({ alcance: \"order.transportista\" }),\n expect.objectContaining({ alcance: \"order.url_de_seguimiento\" }),\n ]));\n expect(result.fieldCoverage).toMatchObject({\n forma_de_entrega: { solicitados: 1, obtenidos: 0 },\n fecha_en_camino: { solicitados: 1, obtenidos: 0 },\n numero_de_seguimiento: { solicitados: 1, obtenidos: 1 },\n transportista: { solicitados: 1, obtenidos: 0 },\n url_de_seguimiento: { solicitados: 1, obtenidos: 0 },\n });\n });\n\n it(\"aggregates a pack once, applies signed CDSD, and discovers billing periods\", () => {\n const result = enrichSalesReportVentas(\n [operation(\"pack-1\", \"o-1\", \"o-2\")],\n { results: [{ order_id: \"o-1\", details: [detail(\"o-1\", \"CVFF\", 10, \"2026-06-01\"), detail(\"o-2\", \"CVFV\", 20, \"2026-07-02\"), detail(\"o-2\", \"CDSD\", 5, \"2026-07-02\", \"ARS\", \"Cargo por devoluci\u00F3n\")] }], order_ids_requested: [\"o-1\", \"o-2\"], order_ids_found: [\"o-1\", \"o-2\"], order_ids_not_found: [], chunks_total: 1, chunks_succeeded: 1, chunks_failed: 0, coverage_complete: true, failures: [] },\n );\n expect(result.operations[0].ventas).toMatchObject({ costo_fijo: -10, cargo_por_venta: -20, anulaciones_y_reembolsos_ars: -5, total_ars: -35, cargo_por_diferencias_en_medidas_y_peso_del_paquete: null, periodos_de_facturacion: [\"2026-06\", \"2026-07\"] });\n });\n\n it(\"keeps partial billing nulls, rejects foreign currency, and reports unknown concepts\", () => {\n const result = enrichSalesReportVentas(\n [operation(null, \"o-1\"), operation(null, \"o-2\")],\n { results: [{ order_id: \"o-1\", details: [detail(\"o-1\", \"NEW\", 9, \"2026-06-01\", \"USD\"), detail(\"o-1\", \"CVFN\", 3, \"2026-06-01\")] }], order_ids_requested: [\"o-1\", \"o-2\"], order_ids_found: [\"o-1\"], order_ids_not_found: [\"o-2\"], chunks_total: 1, chunks_succeeded: 1, chunks_failed: 0, coverage_complete: true, failures: [] },\n );\n expect(result.operations[0].ventas).toMatchObject({ costo_por_ofrecer_cuotas: -3, cargo_por_venta: null, total_ars: -3 });\n expect(result.operations[1].ventas).toMatchObject({ costo_por_ofrecer_cuotas: null, total_ars: null });\n expect(result.unknownConcepts).toEqual([\"NEW\"]);\n expect(result.incidents[0].identificadores).toEqual([\"o-2\"]);\n });\n\n it(\"maps billing listing evidence per order and formats variation attributes\", () => {\n const result = enrichSalesReportPublicaciones(\n [publicationOrder(\"o-1\", { seller_sku: \"SKU-1\", id: \"MLA-1\", title: \"Title\", unit_price: 12 })],\n { results: [{ order_id: \"o-1\", details: [{\n sales_info: [{ order_id: \"o-1\", sales_channel: \"marketplace\" }],\n items_info: [{ item_id: \"MLA-1\", item_price: 13, item_kit_id: \"KIT-1\", fees_added_in_publication: \"Si\" }],\n }] }], order_ids_requested: [\"o-1\"], order_ids_found: [\"o-1\"], order_ids_not_found: [], chunks_total: 1, chunks_succeeded: 1, chunks_failed: 0, coverage_complete: true, failures: [] },\n );\n expect(result.operations[0].ordenes[0]).toMatchObject({\n ventas: { pertenece_a_un_kit: true },\n publicaciones: { canal_de_venta: \"marketplace\", tiene_cuotas_agregadas: true, precio_unitario_de_venta_de_la_publicacion_ars: 12 },\n });\n });\n\n it(\"keeps publication billing signals null when the order is not covered\", () => {\n const result = enrichSalesReportPublicaciones(\n [publicationOrder(\"o-1\", { variation_attributes: [{ name: \"Color\", value_name: \"Rojo\" }] })],\n { results: [], order_ids_requested: [\"o-1\"], order_ids_found: [], order_ids_not_found: [\"o-1\"], chunks_total: 1, chunks_succeeded: 1, chunks_failed: 0, coverage_complete: true, failures: [] },\n );\n expect(result.operations[0].ordenes[0].publicaciones).toMatchObject({ variante: \"Color: Rojo\", canal_de_venta: null, tiene_cuotas_agregadas: null });\n expect(result.operations[0].ordenes[0].ventas.pertenece_a_un_kit).toBeNull();\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["operation"]
7
+ }
@@ -0,0 +1,96 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import {
3
+ buildOrderUniversePagePlan,
4
+ fetchMercadoLibreOrderUniverse,
5
+ groupMercadoLibreOrders,
6
+ selectMercadoLibreOrdersById
7
+ } from "../mercadolibre-sales-report.js";
8
+ import { getMercadoLibreOrderDetailsBatch, searchMercadoLibreOrders, searchMercadoLibreOrdersBatch } from "../mercadolibre-orders.js";
9
+ import { getMercadoLibrePackBatch } from "../mercadolibre-packs.js";
10
+ vi.mock("../mercadolibre-orders.js", () => ({
11
+ searchMercadoLibreOrders: vi.fn(),
12
+ searchMercadoLibreOrdersBatch: vi.fn(),
13
+ getMercadoLibreOrderDetailsBatch: vi.fn()
14
+ }));
15
+ vi.mock("../mercadolibre-packs.js", () => ({ getMercadoLibrePackBatch: vi.fn() }));
16
+ describe("mercadolibre sales report service", () => {
17
+ beforeEach(() => vi.clearAllMocks());
18
+ it("plans and fetches the page after a 200-order target when total is 201", async () => {
19
+ const records = Array.from({ length: 201 }, (_, index) => ({
20
+ id: index,
21
+ date_created: `2026-06-30T${String(23 - Math.floor(index / 60)).padStart(2, "0")}:00:00-03:00`,
22
+ ...index === 199 || index === 200 ? { pack_id: "pack-1" } : {}
23
+ }));
24
+ vi.mocked(searchMercadoLibreOrders).mockResolvedValue({
25
+ paging: { total: 201, limit: 50, offset: 0 },
26
+ results: records.slice(0, 50)
27
+ });
28
+ vi.mocked(searchMercadoLibreOrdersBatch).mockImplementation(async (_profile, _params, offsets) => ({
29
+ successful: offsets.map((offset) => ({
30
+ id: String(offset),
31
+ document: { results: records.slice(offset, offset + 50) }
32
+ })),
33
+ failed: []
34
+ }));
35
+ const universe = await fetchMercadoLibreOrderUniverse("profile-1", "from", "to", 200);
36
+ const operations = groupMercadoLibreOrders(universe.orders);
37
+ const pack = operations.find((item) => item.pack_id === "pack-1");
38
+ expect(buildOrderUniversePagePlan({ total: 201, limit: 50, offset: 0 }, 200)).toEqual([50, 100, 150, 200]);
39
+ expect(searchMercadoLibreOrdersBatch).toHaveBeenCalledWith(
40
+ "profile-1",
41
+ expect.objectContaining({ limit: 50 }),
42
+ [50, 100, 150, 200]
43
+ );
44
+ expect(universe.orders).toHaveLength(201);
45
+ expect(pack?.ordenes.map((order) => order.order_id)).toEqual(["199", "200"]);
46
+ });
47
+ it("selects multiple standalone orders with stable deduplication upstream", async () => {
48
+ vi.mocked(getMercadoLibreOrderDetailsBatch).mockResolvedValue({
49
+ successful: ["a", "b", "c"].map((id) => ({ id, document: { id, seller: { id: "seller-1" } } })),
50
+ failed: []
51
+ });
52
+ const result = await selectMercadoLibreOrdersById("profile-1", "seller-1", ["a", "b", "c"]);
53
+ expect(result.orders.map((order) => order.id)).toEqual(["a", "b", "c"]);
54
+ expect(getMercadoLibrePackBatch).not.toHaveBeenCalled();
55
+ });
56
+ it("expands each distinct pack once and excludes foreign members without leaking their IDs", async () => {
57
+ vi.mocked(getMercadoLibreOrderDetailsBatch).mockResolvedValueOnce({ successful: [
58
+ { id: "a", document: { id: "a", pack_id: "pack-1", seller: { id: "seller-1" } } },
59
+ { id: "b", document: { id: "b", pack_id: "pack-1", seller: { id: "seller-1" } } }
60
+ ], failed: [] }).mockResolvedValueOnce({ successful: [
61
+ { id: "c", document: { id: "c", pack_id: "pack-1", seller: { id: "seller-1" } } },
62
+ { id: "foreign", document: { id: "foreign", pack_id: "pack-1", seller: { id: "seller-2" }, buyer: { nickname: "secret" } } }
63
+ ], failed: [] });
64
+ vi.mocked(getMercadoLibrePackBatch).mockResolvedValue({
65
+ successful: [{ id: "pack-1", document: { orders: [{ id: "a" }, { id: "b" }, { id: "c" }, { id: "foreign" }] } }],
66
+ failed: []
67
+ });
68
+ const result = await selectMercadoLibreOrdersById("profile-1", "seller-1", ["a", "b"]);
69
+ expect(getMercadoLibrePackBatch).toHaveBeenCalledWith("profile-1", ["pack-1"], expect.any(Object));
70
+ expect(result.orders.map((order) => order.id)).toEqual(["a", "b", "c"]);
71
+ expect(JSON.stringify(result.incidents)).not.toContain("foreign");
72
+ expect(JSON.stringify(result)).not.toContain("secret");
73
+ });
74
+ it("keeps partial successes and scopes unavailable requested IDs", async () => {
75
+ vi.mocked(getMercadoLibreOrderDetailsBatch).mockResolvedValue({
76
+ successful: [{ id: "ok", document: { id: "ok", seller: { id: "seller-1" } } }],
77
+ failed: [{ id: "missing", message: "raw upstream transport detail", attempts: 3, retryable: true }]
78
+ });
79
+ const result = await selectMercadoLibreOrdersById("profile-1", "seller-1", ["ok", "missing"]);
80
+ expect(result.orders.map((order) => order.id)).toEqual(["ok"]);
81
+ expect(result.unavailableRequestedIds).toEqual(["missing"]);
82
+ expect(result.incidents).toContainEqual(expect.objectContaining({ identificadores: ["missing"], reintentable: true }));
83
+ expect(JSON.stringify(result.incidents)).not.toContain("raw upstream transport detail");
84
+ });
85
+ it("returns an empty partial selection when every requested order is unavailable or foreign", async () => {
86
+ vi.mocked(getMercadoLibreOrderDetailsBatch).mockResolvedValue({
87
+ successful: [{ id: "foreign", document: { id: "foreign", seller: { id: "seller-2" }, buyer: { nickname: "secret" } } }],
88
+ failed: [{ id: "missing", message: "not found", statusCode: 404, attempts: 1, retryable: false }]
89
+ });
90
+ const result = await selectMercadoLibreOrdersById("profile-1", "seller-1", ["foreign", "missing"]);
91
+ expect(result.orders).toEqual([]);
92
+ expect(result.unavailableRequestedIds).toEqual(["foreign", "missing"]);
93
+ expect(JSON.stringify(result)).not.toContain("secret");
94
+ });
95
+ });
96
+ //# sourceMappingURL=mercadolibre-sales-report.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/services/mercadolibre/__tests__/mercadolibre-sales-report.test.ts"],
4
+ "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport {\n buildOrderUniversePagePlan,\n fetchMercadoLibreOrderUniverse,\n groupMercadoLibreOrders,\n selectMercadoLibreOrdersById,\n} from \"../mercadolibre-sales-report.js\";\nimport { getMercadoLibreOrderDetailsBatch, searchMercadoLibreOrders, searchMercadoLibreOrdersBatch } from \"../mercadolibre-orders.js\";\nimport { getMercadoLibrePackBatch } from \"../mercadolibre-packs.js\";\n\nvi.mock(\"../mercadolibre-orders.js\", () => ({\n searchMercadoLibreOrders: vi.fn(),\n searchMercadoLibreOrdersBatch: vi.fn(),\n getMercadoLibreOrderDetailsBatch: vi.fn(),\n}));\nvi.mock(\"../mercadolibre-packs.js\", () => ({ getMercadoLibrePackBatch: vi.fn() }));\n\ndescribe(\"mercadolibre sales report service\", () => {\n beforeEach(() => vi.clearAllMocks());\n\n it(\"plans and fetches the page after a 200-order target when total is 201\", async () => {\n const records = Array.from({ length: 201 }, (_, index) => ({\n id: index,\n date_created: `2026-06-30T${String(23 - Math.floor(index / 60)).padStart(2, \"0\")}:00:00-03:00`,\n ...(index === 199 || index === 200 ? { pack_id: \"pack-1\" } : {}),\n }));\n vi.mocked(searchMercadoLibreOrders).mockResolvedValue({\n paging: { total: 201, limit: 50, offset: 0 },\n results: records.slice(0, 50),\n });\n vi.mocked(searchMercadoLibreOrdersBatch).mockImplementation(async (_profile, _params, offsets) => ({\n successful: offsets.map((offset) => ({\n id: String(offset),\n document: { results: records.slice(offset, offset + 50) },\n })),\n failed: [],\n }));\n\n const universe = await fetchMercadoLibreOrderUniverse(\"profile-1\", \"from\", \"to\", 200);\n const operations = groupMercadoLibreOrders(universe.orders);\n const pack = operations.find((item) => item.pack_id === \"pack-1\");\n\n expect(buildOrderUniversePagePlan({ total: 201, limit: 50, offset: 0 }, 200)).toEqual([50, 100, 150, 200]);\n expect(searchMercadoLibreOrdersBatch).toHaveBeenCalledWith(\n \"profile-1\",\n expect.objectContaining({ limit: 50 }),\n [50, 100, 150, 200],\n );\n expect(universe.orders).toHaveLength(201);\n expect(pack?.ordenes.map((order) => order.order_id)).toEqual([\"199\", \"200\"]);\n });\n\n it(\"selects multiple standalone orders with stable deduplication upstream\", async () => {\n vi.mocked(getMercadoLibreOrderDetailsBatch).mockResolvedValue({\n successful: [\"a\", \"b\", \"c\"].map((id) => ({ id, document: { id, seller: { id: \"seller-1\" } } })), failed: [],\n });\n const result = await selectMercadoLibreOrdersById(\"profile-1\", \"seller-1\", [\"a\", \"b\", \"c\"]);\n expect(result.orders.map((order) => order.id)).toEqual([\"a\", \"b\", \"c\"]);\n expect(getMercadoLibrePackBatch).not.toHaveBeenCalled();\n });\n\n it(\"expands each distinct pack once and excludes foreign members without leaking their IDs\", async () => {\n vi.mocked(getMercadoLibreOrderDetailsBatch)\n .mockResolvedValueOnce({ successful: [\n { id: \"a\", document: { id: \"a\", pack_id: \"pack-1\", seller: { id: \"seller-1\" } } },\n { id: \"b\", document: { id: \"b\", pack_id: \"pack-1\", seller: { id: \"seller-1\" } } },\n ], failed: [] })\n .mockResolvedValueOnce({ successful: [\n { id: \"c\", document: { id: \"c\", pack_id: \"pack-1\", seller: { id: \"seller-1\" } } },\n { id: \"foreign\", document: { id: \"foreign\", pack_id: \"pack-1\", seller: { id: \"seller-2\" }, buyer: { nickname: \"secret\" } } },\n ], failed: [] });\n vi.mocked(getMercadoLibrePackBatch).mockResolvedValue({\n successful: [{ id: \"pack-1\", document: { orders: [{ id: \"a\" }, { id: \"b\" }, { id: \"c\" }, { id: \"foreign\" }] } }], failed: [],\n });\n const result = await selectMercadoLibreOrdersById(\"profile-1\", \"seller-1\", [\"a\", \"b\"]);\n expect(getMercadoLibrePackBatch).toHaveBeenCalledWith(\"profile-1\", [\"pack-1\"], expect.any(Object));\n expect(result.orders.map((order) => order.id)).toEqual([\"a\", \"b\", \"c\"]);\n expect(JSON.stringify(result.incidents)).not.toContain(\"foreign\");\n expect(JSON.stringify(result)).not.toContain(\"secret\");\n });\n\n it(\"keeps partial successes and scopes unavailable requested IDs\", async () => {\n vi.mocked(getMercadoLibreOrderDetailsBatch).mockResolvedValue({\n successful: [{ id: \"ok\", document: { id: \"ok\", seller: { id: \"seller-1\" } } }],\n failed: [{ id: \"missing\", message: \"raw upstream transport detail\", attempts: 3, retryable: true }],\n });\n const result = await selectMercadoLibreOrdersById(\"profile-1\", \"seller-1\", [\"ok\", \"missing\"]);\n expect(result.orders.map((order) => order.id)).toEqual([\"ok\"]);\n expect(result.unavailableRequestedIds).toEqual([\"missing\"]);\n expect(result.incidents).toContainEqual(expect.objectContaining({ identificadores: [\"missing\"], reintentable: true }));\n expect(JSON.stringify(result.incidents)).not.toContain(\"raw upstream transport detail\");\n });\n\n it(\"returns an empty partial selection when every requested order is unavailable or foreign\", async () => {\n vi.mocked(getMercadoLibreOrderDetailsBatch).mockResolvedValue({\n successful: [{ id: \"foreign\", document: { id: \"foreign\", seller: { id: \"seller-2\" }, buyer: { nickname: \"secret\" } } }],\n failed: [{ id: \"missing\", message: \"not found\", statusCode: 404, attempts: 1, retryable: false }],\n });\n const result = await selectMercadoLibreOrdersById(\"profile-1\", \"seller-1\", [\"foreign\", \"missing\"]);\n expect(result.orders).toEqual([]);\n expect(result.unavailableRequestedIds).toEqual([\"foreign\", \"missing\"]);\n expect(JSON.stringify(result)).not.toContain(\"secret\");\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,15 @@
1
+ function createMercadoLibreClaimReturnLookup() {
2
+ const lookups = /* @__PURE__ */ new Map();
3
+ return (profileId, claimId, load) => {
4
+ const key = JSON.stringify([profileId, claimId]);
5
+ const existing = lookups.get(key);
6
+ if (existing) return existing;
7
+ const pending = load();
8
+ lookups.set(key, pending);
9
+ return pending;
10
+ };
11
+ }
12
+ export {
13
+ createMercadoLibreClaimReturnLookup
14
+ };
15
+ //# sourceMappingURL=mercadolibre-claim-return-lookup.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/services/mercadolibre/mercadolibre-claim-return-lookup.ts"],
4
+ "sourcesContent": ["type Json = Record<string, unknown>;\n\nexport type MercadoLibreClaimReturnLookup = (\n profileId: string,\n claimId: string,\n load: () => Promise<Json>,\n) => Promise<Json>;\n\nexport function createMercadoLibreClaimReturnLookup(): MercadoLibreClaimReturnLookup {\n const lookups = new Map<string, Promise<Json>>();\n\n return (profileId, claimId, load) => {\n const key = JSON.stringify([profileId, claimId]);\n const existing = lookups.get(key);\n if (existing) return existing;\n\n const pending = load();\n lookups.set(key, pending);\n return pending;\n };\n}\n"],
5
+ "mappings": "AAQO,SAAS,sCAAqE;AACnF,QAAM,UAAU,oBAAI,IAA2B;AAE/C,SAAO,CAAC,WAAW,SAAS,SAAS;AACnC,UAAM,MAAM,KAAK,UAAU,CAAC,WAAW,OAAO,CAAC;AAC/C,UAAM,WAAW,QAAQ,IAAI,GAAG;AAChC,QAAI,SAAU,QAAO;AAErB,UAAM,UAAU,KAAK;AACrB,YAAQ,IAAI,KAAK,OAAO;AACxB,WAAO;AAAA,EACT;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,12 @@
1
+ const defaultTelemetrySink = {
2
+ emit(event) {
3
+ console.info("[meli_reconcile_buyer_data]", JSON.stringify(event));
4
+ }
5
+ };
6
+ function getDefaultMercadoLibreBuyerReconciliationTelemetrySink() {
7
+ return defaultTelemetrySink;
8
+ }
9
+ export {
10
+ getDefaultMercadoLibreBuyerReconciliationTelemetrySink
11
+ };
12
+ //# sourceMappingURL=mercadolibre-observability.js.map