@yoryoboy/bi-mcp 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +346 -0
- package/bin/bi-mcp.js +2 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/index.js +768 -0
- package/dist/index.js.map +7 -0
- package/dist/mcp-use.json +7 -0
- package/dist/public/favicon.ico +0 -0
- package/dist/public/icon.svg +6 -0
- package/dist/src/analytics/ga4-channel-groups.js +20 -0
- package/dist/src/analytics/ga4-channel-groups.js.map +7 -0
- package/dist/src/analytics/ga4-report-utils.js +117 -0
- package/dist/src/analytics/ga4-report-utils.js.map +7 -0
- package/dist/src/config/benchmarks.js +128 -0
- package/dist/src/config/benchmarks.js.map +7 -0
- package/dist/src/config/google.js +41 -0
- package/dist/src/config/google.js.map +7 -0
- package/dist/src/config/vtex.js +26 -0
- package/dist/src/config/vtex.js.map +7 -0
- package/dist/src/google-ads/report-utils.js +78 -0
- package/dist/src/google-ads/report-utils.js.map +7 -0
- package/dist/src/prompts/reporte-ventas.js +75 -0
- package/dist/src/prompts/reporte-ventas.js.map +7 -0
- package/dist/src/search-console/search-console-utils.js +275 -0
- package/dist/src/search-console/search-console-utils.js.map +7 -0
- package/dist/src/services/analytics/ga4-client.js +69 -0
- package/dist/src/services/analytics/ga4-client.js.map +7 -0
- package/dist/src/services/analytics/oauth.js +30 -0
- package/dist/src/services/analytics/oauth.js.map +7 -0
- package/dist/src/services/google-ads/google-ads-client.js +54 -0
- package/dist/src/services/google-ads/google-ads-client.js.map +7 -0
- package/dist/src/services/search-console/search-console-client.js +45 -0
- package/dist/src/services/search-console/search-console-client.js.map +7 -0
- package/dist/src/services/vtex/vtex-api.js +51 -0
- package/dist/src/services/vtex/vtex-api.js.map +7 -0
- package/dist/src/services/vtex/vtex-catalog.js +18 -0
- package/dist/src/services/vtex/vtex-catalog.js.map +7 -0
- package/dist/src/services/vtex/vtex-logistics.js +151 -0
- package/dist/src/services/vtex/vtex-logistics.js.map +7 -0
- package/dist/src/services/vtex/vtex-orders.js +143 -0
- package/dist/src/services/vtex/vtex-orders.js.map +7 -0
- package/dist/src/services/vtex/vtex-pricing.js +17 -0
- package/dist/src/services/vtex/vtex-pricing.js.map +7 -0
- package/dist/src/tools/analytics/attribution-gaps.js +109 -0
- package/dist/src/tools/analytics/attribution-gaps.js.map +7 -0
- package/dist/src/tools/analytics/channel-mix.js +74 -0
- package/dist/src/tools/analytics/channel-mix.js.map +7 -0
- package/dist/src/tools/analytics/ecommerce-tracking-health.js +89 -0
- package/dist/src/tools/analytics/ecommerce-tracking-health.js.map +7 -0
- package/dist/src/tools/analytics/engagement-overview.js +71 -0
- package/dist/src/tools/analytics/engagement-overview.js.map +7 -0
- package/dist/src/tools/analytics/index.js +12 -0
- package/dist/src/tools/analytics/index.js.map +7 -0
- package/dist/src/tools/analytics/list-accessible-properties.js +46 -0
- package/dist/src/tools/analytics/list-accessible-properties.js.map +7 -0
- package/dist/src/tools/analytics/property-info.js +54 -0
- package/dist/src/tools/analytics/property-info.js.map +7 -0
- package/dist/src/tools/analytics/revenue-by-channel.js +70 -0
- package/dist/src/tools/analytics/revenue-by-channel.js.map +7 -0
- package/dist/src/tools/analytics/revenue-overview.js +77 -0
- package/dist/src/tools/analytics/revenue-overview.js.map +7 -0
- package/dist/src/tools/analytics/revenue-trend.js +69 -0
- package/dist/src/tools/analytics/revenue-trend.js.map +7 -0
- package/dist/src/tools/analytics/source-medium-breakdown.js +86 -0
- package/dist/src/tools/analytics/source-medium-breakdown.js.map +7 -0
- package/dist/src/tools/analytics/top-landing-pages.js +79 -0
- package/dist/src/tools/analytics/top-landing-pages.js.map +7 -0
- package/dist/src/tools/google-ads/account-overview.js +103 -0
- package/dist/src/tools/google-ads/account-overview.js.map +7 -0
- package/dist/src/tools/google-ads/account-risks.js +267 -0
- package/dist/src/tools/google-ads/account-risks.js.map +7 -0
- package/dist/src/tools/google-ads/break-even-analysis.js +107 -0
- package/dist/src/tools/google-ads/break-even-analysis.js.map +7 -0
- package/dist/src/tools/google-ads/campaign-performance.js +157 -0
- package/dist/src/tools/google-ads/campaign-performance.js.map +7 -0
- package/dist/src/tools/google-ads/channel-mix.js +129 -0
- package/dist/src/tools/google-ads/channel-mix.js.map +7 -0
- package/dist/src/tools/google-ads/compare-accounts.js +122 -0
- package/dist/src/tools/google-ads/compare-accounts.js.map +7 -0
- package/dist/src/tools/google-ads/customer-clients.js +77 -0
- package/dist/src/tools/google-ads/customer-clients.js.map +7 -0
- package/dist/src/tools/google-ads/customer-info.js +64 -0
- package/dist/src/tools/google-ads/customer-info.js.map +7 -0
- package/dist/src/tools/google-ads/index.js +12 -0
- package/dist/src/tools/google-ads/index.js.map +7 -0
- package/dist/src/tools/google-ads/scaling-health.js +174 -0
- package/dist/src/tools/google-ads/scaling-health.js.map +7 -0
- package/dist/src/tools/google-ads/search-terms-summary.js +131 -0
- package/dist/src/tools/google-ads/search-terms-summary.js.map +7 -0
- package/dist/src/tools/google-ads/time-series.js +126 -0
- package/dist/src/tools/google-ads/time-series.js.map +7 -0
- package/dist/src/tools/index.js +5 -0
- package/dist/src/tools/index.js.map +7 -0
- package/dist/src/tools/search-console/country-breakdown.js +85 -0
- package/dist/src/tools/search-console/country-breakdown.js.map +7 -0
- package/dist/src/tools/search-console/device-breakdown.js +85 -0
- package/dist/src/tools/search-console/device-breakdown.js.map +7 -0
- package/dist/src/tools/search-console/high-impression-low-click-queries.js +95 -0
- package/dist/src/tools/search-console/high-impression-low-click-queries.js.map +7 -0
- package/dist/src/tools/search-console/index.js +15 -0
- package/dist/src/tools/search-console/index.js.map +7 -0
- package/dist/src/tools/search-console/list-accessible-sites.js +42 -0
- package/dist/src/tools/search-console/list-accessible-sites.js.map +7 -0
- package/dist/src/tools/search-console/low-ctr-opportunities.js +98 -0
- package/dist/src/tools/search-console/low-ctr-opportunities.js.map +7 -0
- package/dist/src/tools/search-console/page-performance.js +104 -0
- package/dist/src/tools/search-console/page-performance.js.map +7 -0
- package/dist/src/tools/search-console/product-demand-low-capture-queries.js +93 -0
- package/dist/src/tools/search-console/product-demand-low-capture-queries.js.map +7 -0
- package/dist/src/tools/search-console/query-page-matrix.js +99 -0
- package/dist/src/tools/search-console/query-page-matrix.js.map +7 -0
- package/dist/src/tools/search-console/query-performance.js +109 -0
- package/dist/src/tools/search-console/query-performance.js.map +7 -0
- package/dist/src/tools/search-console/quick-win-opportunities.js +93 -0
- package/dist/src/tools/search-console/quick-win-opportunities.js.map +7 -0
- package/dist/src/tools/search-console/rising-non-brand-queries.js +121 -0
- package/dist/src/tools/search-console/rising-non-brand-queries.js.map +7 -0
- package/dist/src/tools/search-console/search-performance.js +89 -0
- package/dist/src/tools/search-console/search-performance.js.map +7 -0
- package/dist/src/tools/search-console/site-context.js +43 -0
- package/dist/src/tools/search-console/site-context.js.map +7 -0
- package/dist/src/tools/search-console/visibility-declines.js +146 -0
- package/dist/src/tools/search-console/visibility-declines.js.map +7 -0
- package/dist/src/tools/vtex/computed-price.js +48 -0
- package/dist/src/tools/vtex/computed-price.js.map +7 -0
- package/dist/src/tools/vtex/index.js +11 -0
- package/dist/src/tools/vtex/index.js.map +7 -0
- package/dist/src/tools/vtex/inventory-check.js +148 -0
- package/dist/src/tools/vtex/inventory-check.js.map +7 -0
- package/dist/src/tools/vtex/order-details.js +56 -0
- package/dist/src/tools/vtex/order-details.js.map +7 -0
- package/dist/src/tools/vtex/orders-summary.js +83 -0
- package/dist/src/tools/vtex/orders-summary.js.map +7 -0
- package/dist/src/tools/vtex/product-offers.js +28 -0
- package/dist/src/tools/vtex/product-offers.js.map +7 -0
- package/dist/src/tools/vtex/sku-offers.js +30 -0
- package/dist/src/tools/vtex/sku-offers.js.map +7 -0
- package/dist/src/tools/vtex/sku-price.js +42 -0
- package/dist/src/tools/vtex/sku-price.js.map +7 -0
- package/dist/src/tools/vtex/update-inventory.js +43 -0
- package/dist/src/tools/vtex/update-inventory.js.map +7 -0
- package/dist/src/tools/vtex/update-lead-time.js +32 -0
- package/dist/src/tools/vtex/update-lead-time.js.map +7 -0
- package/dist/src/tools/vtex/warehouse-inventory.js +42 -0
- package/dist/src/tools/vtex/warehouse-inventory.js.map +7 -0
- package/dist/src/utils/case-conversion.js +21 -0
- package/dist/src/utils/case-conversion.js.map +7 -0
- package/dist/src/utils/currency.js +52 -0
- package/dist/src/utils/currency.js.map +7 -0
- package/dist/src/utils/format-order-details.js +137 -0
- package/dist/src/utils/format-order-details.js.map +7 -0
- package/dist/src/utils/google-ads.js +78 -0
- package/dist/src/utils/google-ads.js.map +7 -0
- package/dist/src/utils/money.js +83 -0
- package/dist/src/utils/money.js.map +7 -0
- package/dist/src/utils/order-status.js +11 -0
- package/dist/src/utils/order-status.js.map +7 -0
- package/dist/src/utils/pagination.js +45 -0
- package/dist/src/utils/pagination.js.map +7 -0
- package/dist/src/utils/strip-payload.js +40 -0
- package/dist/src/utils/strip-payload.js.map +7 -0
- package/dist/src/utils/type-guards.js +7 -0
- package/dist/src/utils/type-guards.js.map +7 -0
- package/package.json +66 -0
- package/public/favicon.ico +0 -0
- package/public/icon.svg +6 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/vtex/orders-summary.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { listOrders } from \"../../services/vtex/vtex-orders.js\";\nimport { formatVtexError } from \"../../services/vtex/vtex-api.js\";\nimport { buildCurrencyMetrics } from \"../../utils/currency.js\";\nimport { moneyFromCents } from \"../../utils/money.js\";\nimport { normalizeOrderStatus } from \"../../utils/order-status.js\";\nimport { createPaginationMetadata } from \"../../utils/pagination.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nconst dateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction buildDateFilter(startDate: string, endDate: string): string {\n return `creationDate:[${startDate}T00:00:00.000Z TO ${endDate}T23:59:59.999Z]`;\n}\n\nfunction formatCompactDate(dateTime?: string): string {\n if (!dateTime) {\n return \"\";\n }\n\n const match = dateTime.match(/^(\\d{4}-\\d{2}-\\d{2})T(\\d{2}:\\d{2})/);\n if (!match) {\n return dateTime;\n }\n\n return `${match[1]} ${match[2]}`;\n}\n\nconst ordersSchema = [\"id\", \"date\", \"status\", \"value\", \"currency\", \"payment\", \"channel\", \"items\"] as const;\nconst metricsSchema = {\n breakdown: [\"count\", \"revenue\"] as const,\n};\n\nexport const ordersSummarySchema = z.object({\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format\"),\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format\"),\n page: z.number().int().min(1).max(30).optional().describe(\"Page number (1-30)\"),\n perPage: z.number().int().min(1).max(100).optional().describe(\"Orders per page (1-100)\"),\n status: z.string().optional().describe(\"Optional VTEX status filter (f_status)\"),\n salesChannel: z.string().optional().describe(\"Optional sales channel filter (f_salesChannel)\"),\n paymentName: z.string().optional().describe(\"Optional payment filter (f_paymentNames)\"),\n utmSource: z.string().optional().describe(\"Optional UTM source filter (f_UtmSource)\"),\n orderBy: z\n .string()\n .optional()\n .describe(\"Sort order in VTEX format, e.g. creationDate,desc\"),\n});\n\nexport async function ordersSummaryHandler(params: z.infer<typeof ordersSummarySchema>) {\n try {\n const page = params.page ?? 1;\n const perPage = params.perPage ?? 100;\n\n const ordersResponse = await listOrders({\n page,\n per_page: perPage,\n orderBy: params.orderBy,\n f_creationDate: buildDateFilter(params.startDate, params.endDate),\n f_status: params.status,\n f_salesChannel: params.salesChannel,\n f_paymentNames: params.paymentName,\n f_UtmSource: params.utmSource,\n });\n\n const orders = Array.isArray(ordersResponse.list) ? ordersResponse.list : [];\n const metadata = createPaginationMetadata(ordersResponse.paging ?? {}, perPage, orders.length);\n const metrics = buildCurrencyMetrics(orders);\n const compactOrders = orders.map((order) => [\n order.orderId,\n formatCompactDate(order.creationDate),\n normalizeOrderStatus(order.status),\n moneyFromCents(order.totalValue),\n order.currencyCode ?? \"\",\n order.paymentNames ?? \"\",\n order.salesChannel ?? \"\",\n Number(order.totalItems ?? 0),\n ]);\n\n return object(\n stripNulls({\n metadata,\n metrics_schema: metricsSchema,\n metrics,\n orders_schema: ordersSchema,\n orders: compactOrders,\n })\n );\n } catch (err) {\n return error(formatVtexError(err, \"Failed to fetch orders summary\"));\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { formatVtexError } from "../../services/vtex/vtex-api.js";
|
|
4
|
+
import { getProductOffers } from "../../services/vtex/vtex-catalog.js";
|
|
5
|
+
import { toSnakeCaseKeys } from "../../utils/case-conversion.js";
|
|
6
|
+
import { stripNulls } from "../../utils/strip-payload.js";
|
|
7
|
+
const productOffersSchema = z.object({
|
|
8
|
+
productId: z.string().min(1).describe("Product identifier")
|
|
9
|
+
});
|
|
10
|
+
async function productOffersHandler({ productId }) {
|
|
11
|
+
try {
|
|
12
|
+
const offers = await getProductOffers(productId);
|
|
13
|
+
const normalizedOffers = toSnakeCaseKeys(offers);
|
|
14
|
+
return object(
|
|
15
|
+
stripNulls({
|
|
16
|
+
product_id: productId,
|
|
17
|
+
offers: normalizedOffers
|
|
18
|
+
})
|
|
19
|
+
);
|
|
20
|
+
} catch (err) {
|
|
21
|
+
return error(formatVtexError(err, `Failed to fetch product offers for ${productId}`));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
productOffersHandler,
|
|
26
|
+
productOffersSchema
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=product-offers.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/vtex/product-offers.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { formatVtexError } from \"../../services/vtex/vtex-api.js\";\nimport { getProductOffers } from \"../../services/vtex/vtex-catalog.js\";\nimport { toSnakeCaseKeys } from \"../../utils/case-conversion.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const productOffersSchema = z.object({\n productId: z.string().min(1).describe(\"Product identifier\"),\n});\n\nexport async function productOffersHandler({ productId }: z.infer<typeof productOffersSchema>) {\n try {\n const offers = await getProductOffers(productId);\n const normalizedOffers = toSnakeCaseKeys(offers);\n\n return object(\n stripNulls({\n product_id: productId,\n offers: normalizedOffers,\n })\n );\n } catch (err) {\n return error(formatVtexError(err, `Failed to fetch product offers for ${productId}`));\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AAEpB,MAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,oBAAoB;AAC5D,CAAC;AAED,eAAsB,qBAAqB,EAAE,UAAU,GAAwC;AAC7F,MAAI;AACF,UAAM,SAAS,MAAM,iBAAiB,SAAS;AAC/C,UAAM,mBAAmB,gBAAgB,MAAM;AAE/C,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,gBAAgB,KAAK,sCAAsC,SAAS,EAAE,CAAC;AAAA,EACtF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { formatVtexError } from "../../services/vtex/vtex-api.js";
|
|
4
|
+
import { getSkuOffers } from "../../services/vtex/vtex-catalog.js";
|
|
5
|
+
import { toSnakeCaseKeys } from "../../utils/case-conversion.js";
|
|
6
|
+
import { stripNulls } from "../../utils/strip-payload.js";
|
|
7
|
+
const skuOffersSchema = z.object({
|
|
8
|
+
productId: z.string().min(1).describe("Product identifier"),
|
|
9
|
+
skuId: z.string().min(1).describe("SKU identifier")
|
|
10
|
+
});
|
|
11
|
+
async function skuOffersHandler({ productId, skuId }) {
|
|
12
|
+
try {
|
|
13
|
+
const offers = await getSkuOffers(productId, skuId);
|
|
14
|
+
const normalizedOffers = toSnakeCaseKeys(offers);
|
|
15
|
+
return object(
|
|
16
|
+
stripNulls({
|
|
17
|
+
product_id: productId,
|
|
18
|
+
sku_id: skuId,
|
|
19
|
+
offers: normalizedOffers
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
} catch (err) {
|
|
23
|
+
return error(formatVtexError(err, `Failed to fetch SKU offers for product ${productId} and sku ${skuId}`));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
skuOffersHandler,
|
|
28
|
+
skuOffersSchema
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=sku-offers.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/vtex/sku-offers.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { formatVtexError } from \"../../services/vtex/vtex-api.js\";\nimport { getSkuOffers } from \"../../services/vtex/vtex-catalog.js\";\nimport { toSnakeCaseKeys } from \"../../utils/case-conversion.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const skuOffersSchema = z.object({\n productId: z.string().min(1).describe(\"Product identifier\"),\n skuId: z.string().min(1).describe(\"SKU identifier\"),\n});\n\nexport async function skuOffersHandler({ productId, skuId }: z.infer<typeof skuOffersSchema>) {\n try {\n const offers = await getSkuOffers(productId, skuId);\n const normalizedOffers = toSnakeCaseKeys(offers);\n\n return object(\n stripNulls({\n product_id: productId,\n sku_id: skuId,\n offers: normalizedOffers,\n })\n );\n } catch (err) {\n return error(formatVtexError(err, `Failed to fetch SKU offers for product ${productId} and sku ${skuId}`));\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AAEpB,MAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,oBAAoB;AAAA,EAC1D,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,gBAAgB;AACpD,CAAC;AAED,eAAsB,iBAAiB,EAAE,WAAW,MAAM,GAAoC;AAC5F,MAAI;AACF,UAAM,SAAS,MAAM,aAAa,WAAW,KAAK;AAClD,UAAM,mBAAmB,gBAAgB,MAAM;AAE/C,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,gBAAgB,KAAK,0CAA0C,SAAS,YAAY,KAAK,EAAE,CAAC;AAAA,EAC3G;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { formatVtexError } from "../../services/vtex/vtex-api.js";
|
|
4
|
+
import { getSkuPrice } from "../../services/vtex/vtex-pricing.js";
|
|
5
|
+
import { moneyFromCentsOptional } from "../../utils/money.js";
|
|
6
|
+
import { stripNulls } from "../../utils/strip-payload.js";
|
|
7
|
+
const skuPriceSchema = z.object({
|
|
8
|
+
itemId: z.string().min(1).describe("SKU item identifier")
|
|
9
|
+
});
|
|
10
|
+
async function skuPriceHandler({ itemId }) {
|
|
11
|
+
try {
|
|
12
|
+
const price = await getSkuPrice(itemId);
|
|
13
|
+
return object(
|
|
14
|
+
stripNulls({
|
|
15
|
+
item_id: price.itemId,
|
|
16
|
+
list_price: moneyFromCentsOptional(price.listPrice),
|
|
17
|
+
cost_price: moneyFromCentsOptional(price.costPrice),
|
|
18
|
+
base_price: moneyFromCentsOptional(price.basePrice),
|
|
19
|
+
markup: price.markup,
|
|
20
|
+
fixed_prices: Array.isArray(price.fixedPrices) ? price.fixedPrices.map(
|
|
21
|
+
(fixedPrice) => stripNulls({
|
|
22
|
+
min_quantity: fixedPrice.minQuantity,
|
|
23
|
+
trade_policy_id: fixedPrice.tradePolicyId,
|
|
24
|
+
date_range: fixedPrice.dateRange ? {
|
|
25
|
+
from: fixedPrice.dateRange.from,
|
|
26
|
+
to: fixedPrice.dateRange.to
|
|
27
|
+
} : void 0,
|
|
28
|
+
value: moneyFromCentsOptional(fixedPrice.value),
|
|
29
|
+
list_price: moneyFromCentsOptional(fixedPrice.listPrice)
|
|
30
|
+
})
|
|
31
|
+
) : void 0
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
} catch (err) {
|
|
35
|
+
return error(formatVtexError(err, `Failed to fetch SKU price for item ${itemId}`));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
skuPriceHandler,
|
|
40
|
+
skuPriceSchema
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=sku-price.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/vtex/sku-price.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { formatVtexError } from \"../../services/vtex/vtex-api.js\";\nimport { getSkuPrice } from \"../../services/vtex/vtex-pricing.js\";\nimport { moneyFromCentsOptional } from \"../../utils/money.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const skuPriceSchema = z.object({\n itemId: z.string().min(1).describe(\"SKU item identifier\"),\n});\n\nexport async function skuPriceHandler({ itemId }: z.infer<typeof skuPriceSchema>) {\n try {\n const price = await getSkuPrice(itemId);\n\n return object(\n stripNulls({\n item_id: price.itemId,\n list_price: moneyFromCentsOptional(price.listPrice),\n cost_price: moneyFromCentsOptional(price.costPrice),\n base_price: moneyFromCentsOptional(price.basePrice),\n markup: price.markup,\n fixed_prices: Array.isArray(price.fixedPrices)\n ? price.fixedPrices.map((fixedPrice) =>\n stripNulls({\n min_quantity: fixedPrice.minQuantity,\n trade_policy_id: fixedPrice.tradePolicyId,\n date_range: fixedPrice.dateRange\n ? {\n from: fixedPrice.dateRange.from,\n to: fixedPrice.dateRange.to,\n }\n : undefined,\n value: moneyFromCentsOptional(fixedPrice.value),\n list_price: moneyFromCentsOptional(fixedPrice.listPrice),\n })\n )\n : undefined,\n })\n );\n } catch (err) {\n return error(formatVtexError(err, `Failed to fetch SKU price for item ${itemId}`));\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAC5B,SAAS,8BAA8B;AACvC,SAAS,kBAAkB;AAEpB,MAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,qBAAqB;AAC1D,CAAC;AAED,eAAsB,gBAAgB,EAAE,OAAO,GAAmC;AAChF,MAAI;AACF,UAAM,QAAQ,MAAM,YAAY,MAAM;AAEtC,WAAO;AAAA,MACL,WAAW;AAAA,QACT,SAAS,MAAM;AAAA,QACf,YAAY,uBAAuB,MAAM,SAAS;AAAA,QAClD,YAAY,uBAAuB,MAAM,SAAS;AAAA,QAClD,YAAY,uBAAuB,MAAM,SAAS;AAAA,QAClD,QAAQ,MAAM;AAAA,QACd,cAAc,MAAM,QAAQ,MAAM,WAAW,IACzC,MAAM,YAAY;AAAA,UAAI,CAAC,eACrB,WAAW;AAAA,YACT,cAAc,WAAW;AAAA,YACzB,iBAAiB,WAAW;AAAA,YAC5B,YAAY,WAAW,YACnB;AAAA,cACE,MAAM,WAAW,UAAU;AAAA,cAC3B,IAAI,WAAW,UAAU;AAAA,YAC3B,IACA;AAAA,YACJ,OAAO,uBAAuB,WAAW,KAAK;AAAA,YAC9C,YAAY,uBAAuB,WAAW,SAAS;AAAA,UACzD,CAAC;AAAA,QACH,IACA;AAAA,MACN,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,gBAAgB,KAAK,sCAAsC,MAAM,EAAE,CAAC;AAAA,EACnF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { formatVtexError } from "../../services/vtex/vtex-api.js";
|
|
4
|
+
import { updateInventoryQuantity } from "../../services/vtex/vtex-logistics.js";
|
|
5
|
+
const updateInventorySchema = z.object({
|
|
6
|
+
skuId: z.string().min(1).describe("SKU identifier"),
|
|
7
|
+
warehouseId: z.string().min(1).describe("Warehouse identifier"),
|
|
8
|
+
quantity: z.number().int().min(0).describe("Inventory quantity to set"),
|
|
9
|
+
unlimitedQuantity: z.boolean().describe("When true, SKU remains available regardless of stock quantity"),
|
|
10
|
+
dateUtcOnBalanceSystem: z.string().optional().describe("Optional UTC timestamp for inventory update synchronization")
|
|
11
|
+
});
|
|
12
|
+
async function updateInventoryHandler({
|
|
13
|
+
skuId,
|
|
14
|
+
warehouseId,
|
|
15
|
+
quantity,
|
|
16
|
+
unlimitedQuantity,
|
|
17
|
+
dateUtcOnBalanceSystem
|
|
18
|
+
}) {
|
|
19
|
+
try {
|
|
20
|
+
await updateInventoryQuantity(skuId, warehouseId, {
|
|
21
|
+
quantity,
|
|
22
|
+
unlimitedQuantity,
|
|
23
|
+
dateUtcOnBalanceSystem
|
|
24
|
+
});
|
|
25
|
+
return object({
|
|
26
|
+
success: true,
|
|
27
|
+
sku_id: skuId,
|
|
28
|
+
warehouse_id: warehouseId,
|
|
29
|
+
quantity,
|
|
30
|
+
unlimited_quantity: unlimitedQuantity,
|
|
31
|
+
message: "Inventory quantity updated successfully"
|
|
32
|
+
});
|
|
33
|
+
} catch (err) {
|
|
34
|
+
return error(
|
|
35
|
+
formatVtexError(err, `Failed to update inventory quantity for SKU ${skuId} in ${warehouseId}`)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
updateInventoryHandler,
|
|
41
|
+
updateInventorySchema
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=update-inventory.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/vtex/update-inventory.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { formatVtexError } from \"../../services/vtex/vtex-api.js\";\nimport { updateInventoryQuantity } from \"../../services/vtex/vtex-logistics.js\";\n\nexport const updateInventorySchema = z.object({\n skuId: z.string().min(1).describe(\"SKU identifier\"),\n warehouseId: z.string().min(1).describe(\"Warehouse identifier\"),\n quantity: z.number().int().min(0).describe(\"Inventory quantity to set\"),\n unlimitedQuantity: z\n .boolean()\n .describe(\"When true, SKU remains available regardless of stock quantity\"),\n dateUtcOnBalanceSystem: z\n .string()\n .optional()\n .describe(\"Optional UTC timestamp for inventory update synchronization\"),\n});\n\nexport async function updateInventoryHandler({\n skuId,\n warehouseId,\n quantity,\n unlimitedQuantity,\n dateUtcOnBalanceSystem,\n}: z.infer<typeof updateInventorySchema>) {\n try {\n await updateInventoryQuantity(skuId, warehouseId, {\n quantity,\n unlimitedQuantity,\n dateUtcOnBalanceSystem,\n });\n\n return object({\n success: true,\n sku_id: skuId,\n warehouse_id: warehouseId,\n quantity,\n unlimited_quantity: unlimitedQuantity,\n message: \"Inventory quantity updated successfully\",\n });\n } catch (err) {\n return error(\n formatVtexError(err, `Failed to update inventory quantity for SKU ${skuId} in ${warehouseId}`)\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,uBAAuB;AAChC,SAAS,+BAA+B;AAEjC,MAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,gBAAgB;AAAA,EAClD,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,sBAAsB;AAAA,EAC9D,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS,2BAA2B;AAAA,EACtE,mBAAmB,EAChB,QAAQ,EACR,SAAS,+DAA+D;AAAA,EAC3E,wBAAwB,EACrB,OAAO,EACP,SAAS,EACT,SAAS,6DAA6D;AAC3E,CAAC;AAED,eAAsB,uBAAuB;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0C;AACxC,MAAI;AACF,UAAM,wBAAwB,OAAO,aAAa;AAAA,MAChD;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,WAAO,OAAO;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,cAAc;AAAA,MACd;AAAA,MACA,oBAAoB;AAAA,MACpB,SAAS;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,gBAAgB,KAAK,+CAA+C,KAAK,OAAO,WAAW,EAAE;AAAA,IAC/F;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { formatVtexError } from "../../services/vtex/vtex-api.js";
|
|
4
|
+
import { updateInventoryLeadTime } from "../../services/vtex/vtex-logistics.js";
|
|
5
|
+
const updateLeadTimeSchema = z.object({
|
|
6
|
+
skuId: z.string().min(1).describe("SKU identifier"),
|
|
7
|
+
warehouseId: z.string().min(1).describe("Warehouse identifier"),
|
|
8
|
+
leadTime: z.string().min(1).describe("Lead time value for the SKU in VTEX expected format (e.g. 1.00:00:00)")
|
|
9
|
+
});
|
|
10
|
+
async function updateLeadTimeHandler({
|
|
11
|
+
skuId,
|
|
12
|
+
warehouseId,
|
|
13
|
+
leadTime
|
|
14
|
+
}) {
|
|
15
|
+
try {
|
|
16
|
+
await updateInventoryLeadTime(skuId, warehouseId, { leadTime });
|
|
17
|
+
return object({
|
|
18
|
+
success: true,
|
|
19
|
+
sku_id: skuId,
|
|
20
|
+
warehouse_id: warehouseId,
|
|
21
|
+
lead_time: leadTime,
|
|
22
|
+
message: "Lead time updated successfully"
|
|
23
|
+
});
|
|
24
|
+
} catch (err) {
|
|
25
|
+
return error(formatVtexError(err, `Failed to update lead time for SKU ${skuId} in ${warehouseId}`));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
updateLeadTimeHandler,
|
|
30
|
+
updateLeadTimeSchema
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=update-lead-time.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/vtex/update-lead-time.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { formatVtexError } from \"../../services/vtex/vtex-api.js\";\nimport { updateInventoryLeadTime } from \"../../services/vtex/vtex-logistics.js\";\n\nexport const updateLeadTimeSchema = z.object({\n skuId: z.string().min(1).describe(\"SKU identifier\"),\n warehouseId: z.string().min(1).describe(\"Warehouse identifier\"),\n leadTime: z\n .string()\n .min(1)\n .describe(\"Lead time value for the SKU in VTEX expected format (e.g. 1.00:00:00)\"),\n});\n\nexport async function updateLeadTimeHandler({\n skuId,\n warehouseId,\n leadTime,\n}: z.infer<typeof updateLeadTimeSchema>) {\n try {\n await updateInventoryLeadTime(skuId, warehouseId, { leadTime });\n\n return object({\n success: true,\n sku_id: skuId,\n warehouse_id: warehouseId,\n lead_time: leadTime,\n message: \"Lead time updated successfully\",\n });\n } catch (err) {\n return error(formatVtexError(err, `Failed to update lead time for SKU ${skuId} in ${warehouseId}`));\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,uBAAuB;AAChC,SAAS,+BAA+B;AAEjC,MAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,gBAAgB;AAAA,EAClD,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,sBAAsB;AAAA,EAC9D,UAAU,EACP,OAAO,EACP,IAAI,CAAC,EACL,SAAS,uEAAuE;AACrF,CAAC;AAED,eAAsB,sBAAsB;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AACF,GAAyC;AACvC,MAAI;AACF,UAAM,wBAAwB,OAAO,aAAa,EAAE,SAAS,CAAC;AAE9D,WAAO,OAAO;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,WAAW;AAAA,MACX,SAAS;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,WAAO,MAAM,gBAAgB,KAAK,sCAAsC,KAAK,OAAO,WAAW,EAAE,CAAC;AAAA,EACpG;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { formatVtexError } from "../../services/vtex/vtex-api.js";
|
|
4
|
+
import { getInventoryByWarehouse } from "../../services/vtex/vtex-logistics.js";
|
|
5
|
+
import { stripNulls } from "../../utils/strip-payload.js";
|
|
6
|
+
const warehouseInventorySchema = z.object({
|
|
7
|
+
skuId: z.string().min(1).describe("SKU identifier"),
|
|
8
|
+
warehouseId: z.string().min(1).describe("Warehouse identifier")
|
|
9
|
+
});
|
|
10
|
+
async function warehouseInventoryHandler({
|
|
11
|
+
skuId,
|
|
12
|
+
warehouseId
|
|
13
|
+
}) {
|
|
14
|
+
try {
|
|
15
|
+
const inventory = await getInventoryByWarehouse(skuId, warehouseId);
|
|
16
|
+
const normalizedInventory = inventory.map((item) => ({
|
|
17
|
+
sku_id: item.skuId,
|
|
18
|
+
warehouse_id: item.warehouseId,
|
|
19
|
+
total_quantity: item.totalQuantity,
|
|
20
|
+
reserved_quantity: item.reservedQuantity,
|
|
21
|
+
available_quantity: item.availableQuantity,
|
|
22
|
+
is_unlimited: item.isUnlimited,
|
|
23
|
+
keep_selling_after_expiration: item.keepSellingAfterExpiration
|
|
24
|
+
}));
|
|
25
|
+
return object(
|
|
26
|
+
stripNulls({
|
|
27
|
+
sku_id: skuId,
|
|
28
|
+
warehouse_id: warehouseId,
|
|
29
|
+
inventory: normalizedInventory
|
|
30
|
+
})
|
|
31
|
+
);
|
|
32
|
+
} catch (err) {
|
|
33
|
+
return error(
|
|
34
|
+
formatVtexError(err, `Failed to fetch inventory for SKU ${skuId} in warehouse ${warehouseId}`)
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
warehouseInventoryHandler,
|
|
40
|
+
warehouseInventorySchema
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=warehouse-inventory.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/vtex/warehouse-inventory.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { formatVtexError } from \"../../services/vtex/vtex-api.js\";\nimport { getInventoryByWarehouse } from \"../../services/vtex/vtex-logistics.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const warehouseInventorySchema = z.object({\n skuId: z.string().min(1).describe(\"SKU identifier\"),\n warehouseId: z.string().min(1).describe(\"Warehouse identifier\"),\n});\n\nexport async function warehouseInventoryHandler({\n skuId,\n warehouseId,\n}: z.infer<typeof warehouseInventorySchema>) {\n try {\n const inventory = await getInventoryByWarehouse(skuId, warehouseId);\n\n const normalizedInventory = inventory.map((item) => ({\n sku_id: item.skuId,\n warehouse_id: item.warehouseId,\n total_quantity: item.totalQuantity,\n reserved_quantity: item.reservedQuantity,\n available_quantity: item.availableQuantity,\n is_unlimited: item.isUnlimited,\n keep_selling_after_expiration: item.keepSellingAfterExpiration,\n }));\n\n return object(\n stripNulls({\n sku_id: skuId,\n warehouse_id: warehouseId,\n inventory: normalizedInventory,\n })\n );\n } catch (err) {\n return error(\n formatVtexError(err, `Failed to fetch inventory for SKU ${skuId} in warehouse ${warehouseId}`)\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,uBAAuB;AAChC,SAAS,+BAA+B;AACxC,SAAS,kBAAkB;AAEpB,MAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,gBAAgB;AAAA,EAClD,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,sBAAsB;AAChE,CAAC;AAED,eAAsB,0BAA0B;AAAA,EAC9C;AAAA,EACA;AACF,GAA6C;AAC3C,MAAI;AACF,UAAM,YAAY,MAAM,wBAAwB,OAAO,WAAW;AAElE,UAAM,sBAAsB,UAAU,IAAI,CAAC,UAAU;AAAA,MACnD,QAAQ,KAAK;AAAA,MACb,cAAc,KAAK;AAAA,MACnB,gBAAgB,KAAK;AAAA,MACrB,mBAAmB,KAAK;AAAA,MACxB,oBAAoB,KAAK;AAAA,MACzB,cAAc,KAAK;AAAA,MACnB,+BAA+B,KAAK;AAAA,IACtC,EAAE;AAEF,WAAO;AAAA,MACL,WAAW;AAAA,QACT,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,gBAAgB,KAAK,qCAAqC,KAAK,iBAAiB,WAAW,EAAE;AAAA,IAC/F;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isObject } from "./type-guards.js";
|
|
2
|
+
function toSnakeCase(input) {
|
|
3
|
+
return input.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").toLowerCase();
|
|
4
|
+
}
|
|
5
|
+
function toSnakeCaseKeys(value) {
|
|
6
|
+
if (Array.isArray(value)) {
|
|
7
|
+
return value.map((item) => toSnakeCaseKeys(item));
|
|
8
|
+
}
|
|
9
|
+
if (isObject(value)) {
|
|
10
|
+
const convertedEntries = [];
|
|
11
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
12
|
+
convertedEntries.push([toSnakeCase(key), toSnakeCaseKeys(nestedValue)]);
|
|
13
|
+
}
|
|
14
|
+
return Object.fromEntries(convertedEntries);
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
toSnakeCaseKeys
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=case-conversion.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/utils/case-conversion.ts"],
|
|
4
|
+
"sourcesContent": ["import { isObject } from \"./type-guards.js\";\n\nfunction toSnakeCase(input: string): string {\n return input\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .replace(/[\\s-]+/g, \"_\")\n .toLowerCase();\n}\n\nexport function toSnakeCaseKeys(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => toSnakeCaseKeys(item));\n }\n\n if (isObject(value)) {\n const convertedEntries: [string, unknown][] = [];\n\n for (const [key, nestedValue] of Object.entries(value)) {\n convertedEntries.push([toSnakeCase(key), toSnakeCaseKeys(nestedValue)]);\n }\n\n return Object.fromEntries(convertedEntries);\n }\n\n return value;\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,gBAAgB;AAEzB,SAAS,YAAY,OAAuB;AAC1C,SAAO,MACJ,QAAQ,sBAAsB,OAAO,EACrC,QAAQ,WAAW,GAAG,EACtB,YAAY;AACjB;AAEO,SAAS,gBAAgB,OAAyB;AACvD,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAAS,gBAAgB,IAAI,CAAC;AAAA,EAClD;AAEA,MAAI,SAAS,KAAK,GAAG;AACnB,UAAM,mBAAwC,CAAC;AAE/C,eAAW,CAAC,KAAK,WAAW,KAAK,OAAO,QAAQ,KAAK,GAAG;AACtD,uBAAiB,KAAK,CAAC,YAAY,GAAG,GAAG,gBAAgB,WAAW,CAAC,CAAC;AAAA,IACxE;AAEA,WAAO,OAAO,YAAY,gBAAgB;AAAA,EAC5C;AAEA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { moneyFromCentsPrecise, roundMoney } from "./money.js";
|
|
2
|
+
import { normalizeOrderStatus } from "./order-status.js";
|
|
3
|
+
function addMetric(group, key, orderValue) {
|
|
4
|
+
const safeKey = key.trim() || "unknown";
|
|
5
|
+
const existing = group[safeKey] ?? [0, 0];
|
|
6
|
+
existing[0] += 1;
|
|
7
|
+
existing[1] += orderValue;
|
|
8
|
+
group[safeKey] = existing;
|
|
9
|
+
}
|
|
10
|
+
function buildCurrencyMetrics(orders) {
|
|
11
|
+
const metricsByCurrency = {};
|
|
12
|
+
for (const order of orders) {
|
|
13
|
+
const currencyCode = (order.currencyCode ?? "UNKNOWN").trim() || "UNKNOWN";
|
|
14
|
+
const orderValue = moneyFromCentsPrecise(order.totalValue);
|
|
15
|
+
const status = normalizeOrderStatus(String(order.status ?? "unknown"));
|
|
16
|
+
const paymentName = String(order.paymentNames ?? "unknown");
|
|
17
|
+
const salesChannel = String(order.salesChannel ?? "unknown");
|
|
18
|
+
const currencyMetrics = metricsByCurrency[currencyCode] ?? {
|
|
19
|
+
count: 0,
|
|
20
|
+
avg: 0,
|
|
21
|
+
total: 0,
|
|
22
|
+
by_status: {},
|
|
23
|
+
by_payment: {},
|
|
24
|
+
by_channel: {}
|
|
25
|
+
};
|
|
26
|
+
currencyMetrics.count += 1;
|
|
27
|
+
currencyMetrics.total += orderValue;
|
|
28
|
+
addMetric(currencyMetrics.by_status, status, orderValue);
|
|
29
|
+
addMetric(currencyMetrics.by_payment, paymentName, orderValue);
|
|
30
|
+
addMetric(currencyMetrics.by_channel, salesChannel, orderValue);
|
|
31
|
+
currencyMetrics.avg = currencyMetrics.count > 0 ? currencyMetrics.total / currencyMetrics.count : 0;
|
|
32
|
+
metricsByCurrency[currencyCode] = currencyMetrics;
|
|
33
|
+
}
|
|
34
|
+
for (const currencyMetrics of Object.values(metricsByCurrency)) {
|
|
35
|
+
for (const statusMetrics of Object.values(currencyMetrics.by_status)) {
|
|
36
|
+
statusMetrics[1] = roundMoney(statusMetrics[1]);
|
|
37
|
+
}
|
|
38
|
+
for (const paymentMetrics of Object.values(currencyMetrics.by_payment)) {
|
|
39
|
+
paymentMetrics[1] = roundMoney(paymentMetrics[1]);
|
|
40
|
+
}
|
|
41
|
+
for (const channelMetrics of Object.values(currencyMetrics.by_channel)) {
|
|
42
|
+
channelMetrics[1] = roundMoney(channelMetrics[1]);
|
|
43
|
+
}
|
|
44
|
+
currencyMetrics.total = roundMoney(currencyMetrics.total);
|
|
45
|
+
currencyMetrics.avg = roundMoney(currencyMetrics.avg);
|
|
46
|
+
}
|
|
47
|
+
return metricsByCurrency;
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
buildCurrencyMetrics
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=currency.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/utils/currency.ts"],
|
|
4
|
+
"sourcesContent": ["import type { VtexOrderListItem } from \"../services/vtex/vtex-orders.js\";\nimport { moneyFromCentsPrecise, roundMoney } from \"./money.js\";\nimport { normalizeOrderStatus } from \"./order-status.js\";\n\nexport type Breakdown = [number, number];\n\nexport interface CurrencyMetrics {\n count: number;\n avg: number;\n total: number;\n by_status: Record<string, Breakdown>;\n by_payment: Record<string, Breakdown>;\n by_channel: Record<string, Breakdown>;\n}\n\nfunction addMetric(group: Record<string, Breakdown>, key: string, orderValue: number): void {\n const safeKey = key.trim() || \"unknown\";\n const existing = group[safeKey] ?? [0, 0];\n\n existing[0] += 1;\n existing[1] += orderValue;\n\n group[safeKey] = existing;\n}\n\nexport function buildCurrencyMetrics(orders: VtexOrderListItem[]): Record<string, CurrencyMetrics> {\n const metricsByCurrency: Record<string, CurrencyMetrics> = {};\n\n for (const order of orders) {\n const currencyCode = (order.currencyCode ?? \"UNKNOWN\").trim() || \"UNKNOWN\";\n const orderValue = moneyFromCentsPrecise(order.totalValue);\n const status = normalizeOrderStatus(String(order.status ?? \"unknown\"));\n const paymentName = String(order.paymentNames ?? \"unknown\");\n const salesChannel = String(order.salesChannel ?? \"unknown\");\n\n const currencyMetrics = metricsByCurrency[currencyCode] ?? {\n count: 0,\n avg: 0,\n total: 0,\n by_status: {},\n by_payment: {},\n by_channel: {},\n };\n\n currencyMetrics.count += 1;\n currencyMetrics.total += orderValue;\n\n addMetric(currencyMetrics.by_status, status, orderValue);\n addMetric(currencyMetrics.by_payment, paymentName, orderValue);\n addMetric(currencyMetrics.by_channel, salesChannel, orderValue);\n\n currencyMetrics.avg =\n currencyMetrics.count > 0\n ? currencyMetrics.total / currencyMetrics.count\n : 0;\n\n metricsByCurrency[currencyCode] = currencyMetrics;\n }\n\n for (const currencyMetrics of Object.values(metricsByCurrency)) {\n for (const statusMetrics of Object.values(currencyMetrics.by_status)) {\n statusMetrics[1] = roundMoney(statusMetrics[1]);\n }\n\n for (const paymentMetrics of Object.values(currencyMetrics.by_payment)) {\n paymentMetrics[1] = roundMoney(paymentMetrics[1]);\n }\n\n for (const channelMetrics of Object.values(currencyMetrics.by_channel)) {\n channelMetrics[1] = roundMoney(channelMetrics[1]);\n }\n\n currencyMetrics.total = roundMoney(currencyMetrics.total);\n currencyMetrics.avg = roundMoney(currencyMetrics.avg);\n }\n\n return metricsByCurrency;\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,uBAAuB,kBAAkB;AAClD,SAAS,4BAA4B;AAarC,SAAS,UAAU,OAAkC,KAAa,YAA0B;AAC1F,QAAM,UAAU,IAAI,KAAK,KAAK;AAC9B,QAAM,WAAW,MAAM,OAAO,KAAK,CAAC,GAAG,CAAC;AAExC,WAAS,CAAC,KAAK;AACf,WAAS,CAAC,KAAK;AAEf,QAAM,OAAO,IAAI;AACnB;AAEO,SAAS,qBAAqB,QAA8D;AACjG,QAAM,oBAAqD,CAAC;AAE5D,aAAW,SAAS,QAAQ;AAC1B,UAAM,gBAAgB,MAAM,gBAAgB,WAAW,KAAK,KAAK;AACjE,UAAM,aAAa,sBAAsB,MAAM,UAAU;AACzD,UAAM,SAAS,qBAAqB,OAAO,MAAM,UAAU,SAAS,CAAC;AACrE,UAAM,cAAc,OAAO,MAAM,gBAAgB,SAAS;AAC1D,UAAM,eAAe,OAAO,MAAM,gBAAgB,SAAS;AAE3D,UAAM,kBAAkB,kBAAkB,YAAY,KAAK;AAAA,MACzD,OAAO;AAAA,MACP,KAAK;AAAA,MACL,OAAO;AAAA,MACP,WAAW,CAAC;AAAA,MACZ,YAAY,CAAC;AAAA,MACb,YAAY,CAAC;AAAA,IACf;AAEA,oBAAgB,SAAS;AACzB,oBAAgB,SAAS;AAEzB,cAAU,gBAAgB,WAAW,QAAQ,UAAU;AACvD,cAAU,gBAAgB,YAAY,aAAa,UAAU;AAC7D,cAAU,gBAAgB,YAAY,cAAc,UAAU;AAE9D,oBAAgB,MACd,gBAAgB,QAAQ,IACpB,gBAAgB,QAAQ,gBAAgB,QACxC;AAEN,sBAAkB,YAAY,IAAI;AAAA,EACpC;AAEA,aAAW,mBAAmB,OAAO,OAAO,iBAAiB,GAAG;AAC9D,eAAW,iBAAiB,OAAO,OAAO,gBAAgB,SAAS,GAAG;AACpE,oBAAc,CAAC,IAAI,WAAW,cAAc,CAAC,CAAC;AAAA,IAChD;AAEA,eAAW,kBAAkB,OAAO,OAAO,gBAAgB,UAAU,GAAG;AACtE,qBAAe,CAAC,IAAI,WAAW,eAAe,CAAC,CAAC;AAAA,IAClD;AAEA,eAAW,kBAAkB,OAAO,OAAO,gBAAgB,UAAU,GAAG;AACtE,qBAAe,CAAC,IAAI,WAAW,eAAe,CAAC,CAAC;AAAA,IAClD;AAEA,oBAAgB,QAAQ,WAAW,gBAAgB,KAAK;AACxD,oBAAgB,MAAM,WAAW,gBAAgB,GAAG;AAAA,EACtD;AAEA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { moneyFromCents, roundMoney } from "./money.js";
|
|
2
|
+
import { isObject } from "./type-guards.js";
|
|
3
|
+
function toFiniteNumber(value) {
|
|
4
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
5
|
+
}
|
|
6
|
+
function formatDate(isoDate, includeTime) {
|
|
7
|
+
if (typeof isoDate !== "string") return "";
|
|
8
|
+
try {
|
|
9
|
+
const date = new Date(isoDate);
|
|
10
|
+
const year = date.getUTCFullYear();
|
|
11
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
12
|
+
const day = String(date.getUTCDate()).padStart(2, "0");
|
|
13
|
+
if (!includeTime) {
|
|
14
|
+
return `${year}-${month}-${day}`;
|
|
15
|
+
}
|
|
16
|
+
const hours = String(date.getUTCHours()).padStart(2, "0");
|
|
17
|
+
const minutes = String(date.getUTCMinutes()).padStart(2, "0");
|
|
18
|
+
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
19
|
+
} catch {
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function computePaymentsTotalValue(paymentData) {
|
|
24
|
+
if (!isObject(paymentData)) {
|
|
25
|
+
return void 0;
|
|
26
|
+
}
|
|
27
|
+
const transactions = Array.isArray(paymentData.transactions) ? paymentData.transactions : [];
|
|
28
|
+
let total = 0;
|
|
29
|
+
let hasAnyPaymentValue = false;
|
|
30
|
+
for (const transaction of transactions) {
|
|
31
|
+
if (!isObject(transaction)) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const payments = Array.isArray(transaction.payments) ? transaction.payments : [];
|
|
35
|
+
for (const payment of payments) {
|
|
36
|
+
if (!isObject(payment)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const paymentValue = toFiniteNumber(payment.value);
|
|
40
|
+
if (paymentValue === void 0) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
hasAnyPaymentValue = true;
|
|
44
|
+
total += moneyFromCents(paymentValue);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return hasAnyPaymentValue ? roundMoney(total) : void 0;
|
|
48
|
+
}
|
|
49
|
+
function formatOrderDetails(order) {
|
|
50
|
+
const items = Array.isArray(order.items) ? order.items : [];
|
|
51
|
+
const shippingData = isObject(order.shippingData) ? order.shippingData : void 0;
|
|
52
|
+
const paymentData = isObject(order.paymentData) ? order.paymentData : void 0;
|
|
53
|
+
const clientData = isObject(order.clientProfileData) ? order.clientProfileData : void 0;
|
|
54
|
+
const marketingData = isObject(order.marketingData) ? order.marketingData : void 0;
|
|
55
|
+
const formattedItems = items.filter((item) => isObject(item)).map((item) => [
|
|
56
|
+
String(item.id ?? ""),
|
|
57
|
+
String(item.refId ?? ""),
|
|
58
|
+
String(item.name ?? ""),
|
|
59
|
+
Number(item.quantity ?? 0),
|
|
60
|
+
moneyFromCents(item.price),
|
|
61
|
+
moneyFromCents(item.listPrice)
|
|
62
|
+
]);
|
|
63
|
+
const logisticsInfo = Array.isArray(shippingData?.logisticsInfo) ? shippingData.logisticsInfo : [];
|
|
64
|
+
const formattedShipping = logisticsInfo.filter((entry) => isObject(entry)).map((entry) => [
|
|
65
|
+
String(entry.deliveryCompany ?? ""),
|
|
66
|
+
String(entry.shippingEstimate ?? ""),
|
|
67
|
+
formatDate(entry.shippingEstimateDate, false)
|
|
68
|
+
]);
|
|
69
|
+
const transactions = Array.isArray(paymentData?.transactions) ? paymentData.transactions : [];
|
|
70
|
+
const formattedPayments = [];
|
|
71
|
+
for (const transaction of transactions) {
|
|
72
|
+
if (!isObject(transaction)) continue;
|
|
73
|
+
const payments = Array.isArray(transaction.payments) ? transaction.payments : [];
|
|
74
|
+
for (const payment of payments) {
|
|
75
|
+
if (!isObject(payment)) continue;
|
|
76
|
+
formattedPayments.push([
|
|
77
|
+
String(payment.paymentSystemName ?? ""),
|
|
78
|
+
Number(payment.installments ?? 1),
|
|
79
|
+
moneyFromCents(payment.value)
|
|
80
|
+
]);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const firstName = String(clientData?.firstName ?? "");
|
|
84
|
+
const lastName = String(clientData?.lastName ?? "");
|
|
85
|
+
const clientName = `${firstName} ${lastName}`.trim();
|
|
86
|
+
const formatted = {
|
|
87
|
+
id: String(order.orderId ?? order.id ?? ""),
|
|
88
|
+
status: String(order.status ?? ""),
|
|
89
|
+
created: formatDate(order.creationDate, true),
|
|
90
|
+
total: moneyFromCents(order.value),
|
|
91
|
+
items: formattedItems,
|
|
92
|
+
shipping: formattedShipping,
|
|
93
|
+
payments: formattedPayments
|
|
94
|
+
};
|
|
95
|
+
if (order.invoicedDate) {
|
|
96
|
+
formatted.invoiced = formatDate(order.invoicedDate, true);
|
|
97
|
+
}
|
|
98
|
+
if (order.cancelReason) {
|
|
99
|
+
formatted.cancel_reason = String(order.cancelReason);
|
|
100
|
+
}
|
|
101
|
+
if (clientData?.email) {
|
|
102
|
+
formatted.client_email = String(clientData.email);
|
|
103
|
+
}
|
|
104
|
+
if (clientName) {
|
|
105
|
+
formatted.client_name = clientName;
|
|
106
|
+
}
|
|
107
|
+
if (clientData?.phone) {
|
|
108
|
+
formatted.client_phone = String(clientData.phone);
|
|
109
|
+
}
|
|
110
|
+
if (clientData?.documentType) {
|
|
111
|
+
formatted.client_doc_type = String(clientData.documentType);
|
|
112
|
+
}
|
|
113
|
+
if (clientData?.document) {
|
|
114
|
+
formatted.client_doc = String(clientData.document);
|
|
115
|
+
}
|
|
116
|
+
if (marketingData?.utmSource) {
|
|
117
|
+
formatted.utm_source = String(marketingData.utmSource);
|
|
118
|
+
}
|
|
119
|
+
if (marketingData?.utmCampaign) {
|
|
120
|
+
formatted.utm_campaign = String(marketingData.utmCampaign);
|
|
121
|
+
}
|
|
122
|
+
if (marketingData?.coupon) {
|
|
123
|
+
formatted.coupon = String(marketingData.coupon);
|
|
124
|
+
}
|
|
125
|
+
const paymentsTotalValue = computePaymentsTotalValue(paymentData);
|
|
126
|
+
if (paymentsTotalValue !== void 0) {
|
|
127
|
+
formatted.payments_total = paymentsTotalValue;
|
|
128
|
+
const paymentValueDelta = roundMoney(paymentsTotalValue - formatted.total);
|
|
129
|
+
formatted.payment_delta = paymentValueDelta;
|
|
130
|
+
formatted.payment_mismatch = Math.abs(paymentValueDelta) > 0.5;
|
|
131
|
+
}
|
|
132
|
+
return formatted;
|
|
133
|
+
}
|
|
134
|
+
export {
|
|
135
|
+
formatOrderDetails
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=format-order-details.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/utils/format-order-details.ts"],
|
|
4
|
+
"sourcesContent": ["import { moneyFromCents, roundMoney } from \"./money.js\";\nimport { isObject } from \"./type-guards.js\";\n\nfunction toFiniteNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction formatDate(isoDate: unknown, includeTime: boolean): string {\n if (typeof isoDate !== \"string\") return \"\";\n \n try {\n const date = new Date(isoDate);\n const year = date.getUTCFullYear();\n const month = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n const day = String(date.getUTCDate()).padStart(2, \"0\");\n\n if (!includeTime) {\n return `${year}-${month}-${day}`;\n }\n\n const hours = String(date.getUTCHours()).padStart(2, \"0\");\n const minutes = String(date.getUTCMinutes()).padStart(2, \"0\");\n return `${year}-${month}-${day} ${hours}:${minutes}`;\n } catch {\n return \"\";\n }\n}\n\nfunction computePaymentsTotalValue(paymentData: unknown): number | undefined {\n if (!isObject(paymentData)) {\n return undefined;\n }\n\n const transactions = Array.isArray(paymentData.transactions) ? paymentData.transactions : [];\n let total = 0;\n let hasAnyPaymentValue = false;\n\n for (const transaction of transactions) {\n if (!isObject(transaction)) {\n continue;\n }\n\n const payments = Array.isArray(transaction.payments) ? transaction.payments : [];\n for (const payment of payments) {\n if (!isObject(payment)) {\n continue;\n }\n\n const paymentValue = toFiniteNumber(payment.value);\n if (paymentValue === undefined) {\n continue;\n }\n\n hasAnyPaymentValue = true;\n total += moneyFromCents(paymentValue);\n }\n }\n\n return hasAnyPaymentValue ? roundMoney(total) : undefined;\n}\n\ninterface FormattedOrderDetails {\n id: string;\n status: string;\n created: string;\n invoiced?: string;\n total: number;\n cancel_reason?: string;\n client_email?: string;\n client_name?: string;\n client_phone?: string;\n client_doc_type?: string;\n client_doc?: string;\n items: Array<[string, string, string, number, number, number]>; // [id, ref, name, qty, price, list]\n shipping: Array<[string, string, string]>; // [carrier, estimate, delivery_date]\n payments: Array<[string, number, number]>; // [system, installments, value]\n payments_total?: number;\n payment_delta?: number;\n payment_mismatch?: boolean;\n utm_source?: string;\n utm_campaign?: string;\n coupon?: string;\n}\n\nexport function formatOrderDetails(order: Record<string, unknown>): FormattedOrderDetails {\n const items = Array.isArray(order.items) ? order.items : [];\n const shippingData = isObject(order.shippingData) ? order.shippingData : undefined;\n const paymentData = isObject(order.paymentData) ? order.paymentData : undefined;\n const clientData = isObject(order.clientProfileData) ? order.clientProfileData : undefined;\n const marketingData = isObject(order.marketingData) ? order.marketingData : undefined;\n\n // Format items as arrays\n const formattedItems = items\n .filter((item) => isObject(item))\n .map((item): [string, string, string, number, number, number] => [\n String(item.id ?? \"\"),\n String(item.refId ?? \"\"),\n String(item.name ?? \"\"),\n Number(item.quantity ?? 0),\n moneyFromCents(item.price),\n moneyFromCents(item.listPrice),\n ]);\n\n // Format shipping as arrays\n const logisticsInfo = Array.isArray(shippingData?.logisticsInfo) \n ? shippingData.logisticsInfo \n : [];\n \n const formattedShipping = logisticsInfo\n .filter((entry) => isObject(entry))\n .map((entry): [string, string, string] => [\n String(entry.deliveryCompany ?? \"\"),\n String(entry.shippingEstimate ?? \"\"),\n formatDate(entry.shippingEstimateDate, false),\n ]);\n\n // Format payments as arrays\n const transactions = Array.isArray(paymentData?.transactions)\n ? paymentData.transactions\n : [];\n \n const formattedPayments: Array<[string, number, number]> = [];\n \n for (const transaction of transactions) {\n if (!isObject(transaction)) continue;\n \n const payments = Array.isArray(transaction.payments) ? transaction.payments : [];\n \n for (const payment of payments) {\n if (!isObject(payment)) continue;\n \n formattedPayments.push([\n String(payment.paymentSystemName ?? \"\"),\n Number(payment.installments ?? 1),\n moneyFromCents(payment.value),\n ]);\n }\n }\n\n // Build client name\n const firstName = String(clientData?.firstName ?? \"\");\n const lastName = String(clientData?.lastName ?? \"\");\n const clientName = `${firstName} ${lastName}`.trim();\n\n // Build formatted order\n const formatted: FormattedOrderDetails = {\n id: String(order.orderId ?? order.id ?? \"\"),\n status: String(order.status ?? \"\"),\n created: formatDate(order.creationDate, true),\n total: moneyFromCents(order.value),\n items: formattedItems,\n shipping: formattedShipping,\n payments: formattedPayments,\n };\n\n // Optional fields\n if (order.invoicedDate) {\n formatted.invoiced = formatDate(order.invoicedDate, true);\n }\n \n if (order.cancelReason) {\n formatted.cancel_reason = String(order.cancelReason);\n }\n\n if (clientData?.email) {\n formatted.client_email = String(clientData.email);\n }\n\n if (clientName) {\n formatted.client_name = clientName;\n }\n\n if (clientData?.phone) {\n formatted.client_phone = String(clientData.phone);\n }\n\n if (clientData?.documentType) {\n formatted.client_doc_type = String(clientData.documentType);\n }\n\n if (clientData?.document) {\n formatted.client_doc = String(clientData.document);\n }\n\n if (marketingData?.utmSource) {\n formatted.utm_source = String(marketingData.utmSource);\n }\n\n if (marketingData?.utmCampaign) {\n formatted.utm_campaign = String(marketingData.utmCampaign);\n }\n\n if (marketingData?.coupon) {\n formatted.coupon = String(marketingData.coupon);\n }\n\n // Payment validation\n const paymentsTotalValue = computePaymentsTotalValue(paymentData);\n if (paymentsTotalValue !== undefined) {\n formatted.payments_total = paymentsTotalValue;\n \n const paymentValueDelta = roundMoney(paymentsTotalValue - formatted.total);\n formatted.payment_delta = paymentValueDelta;\n formatted.payment_mismatch = Math.abs(paymentValueDelta) > 0.5;\n }\n\n return formatted;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|