From 58e2b8dc81398bc16b8d23e8bba25148450e07f5 Mon Sep 17 00:00:00 2001 From: k4rli Date: Mon, 4 Aug 2025 16:24:28 +0300 Subject: [PATCH] feat(MED-131): send to medipost on montonio callback --- .../montonio-callback/[montonioId]/route.ts | 5 +- lib/services/medipost.service.ts | 55 ++++++++++++++++--- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts b/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts index 15b6348..5fd1284 100644 --- a/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts +++ b/app/home/(user)/(dashboard)/cart/montonio-callback/[montonioId]/route.ts @@ -6,6 +6,7 @@ import { listProductTypes } from "@lib/data/products"; import { placeOrder, retrieveCart } from "@lib/data/cart"; import { createI18nServerInstance } from "~/lib/i18n/i18n.server"; import { createOrder } from '~/lib/services/order.service'; +import { sendOrderToMedipost } from '~/lib/services/medipost.service'; const emailSender = process.env.EMAIL_SENDER; const siteUrl = process.env.NEXT_PUBLIC_SITE_URL!; @@ -93,6 +94,7 @@ const handleOrderToken = async (orderToken: string) => { const analysisPackagesType = productTypes.find(({ metadata }) => metadata?.handle === ANALYSIS_PACKAGES_TYPE_HANDLE); const analysisPackageOrderItem = medusaOrder.items?.find(({ product_type_id }) => product_type_id === analysisPackagesType?.id); return { + medusaOrderId: medusaOrder.id, email: medusaOrder.email, partnerLocationName: analysisPackageOrderItem?.metadata?.partner_location_name as string ?? '', analysisPackageName: analysisPackageOrderItem?.title ?? '', @@ -121,7 +123,7 @@ export async function GET(request: Request) { throw new Error("Order result is missing"); } - const { email, partnerLocationName, analysisPackageName } = orderResult; + const { medusaOrderId, email, partnerLocationName, analysisPackageName } = orderResult; const personName = account.name; if (email && analysisPackageName) { await sendEmail({ email, analysisPackageName, personName, partnerLocationName, language }); @@ -129,6 +131,7 @@ export async function GET(request: Request) { // @TODO send email for separate analyses console.error("Missing email or analysisPackageName", orderResult); } + sendOrderToMedipost({ medusaOrderId }) return Response.redirect(new URL('/home/order', baseUrl)) } catch (error) { console.error("Failed to place order", error); diff --git a/lib/services/medipost.service.ts b/lib/services/medipost.service.ts index d9955a6..3fc0af1 100644 --- a/lib/services/medipost.service.ts +++ b/lib/services/medipost.service.ts @@ -41,12 +41,19 @@ import { getAnalysisElementsAdmin } from './analysis-element.service'; import { getAnalyses } from './analyses.service'; import { retrieveOrder } from '@lib/data/orders'; import { getAccountAdmin } from './account.service'; +import { StoreProduct } from '@medusajs/types'; +import { listProducts } from '@lib/data/products'; +import { listRegions } from '@lib/data/regions'; +import { getAnalysisElementMedusaProductIds } from '@/utils/medusa-product'; const BASE_URL = process.env.MEDIPOST_URL!; const USER = process.env.MEDIPOST_USER!; const PASSWORD = process.env.MEDIPOST_PASSWORD!; const RECIPIENT = process.env.MEDIPOST_RECIPIENT!; +const ANALYSIS_ELEMENT_HANDLE_PREFIX = 'analysis-element-'; +const ANALYSIS_PACKAGE_HANDLE_PREFIX = 'analysis-package-'; + function parseXML(xml: string) { const parser = new XMLParser({ ignoreAttributes: false }); return parser.parse(xml); @@ -630,16 +637,46 @@ export async function sendOrderToMedipost({ }: { medusaOrderId: string; }) { - const medusaOrder = await retrieveOrder(medusaOrderId) - const medreportOrder = await getOrder({ medusaOrderId }); - + const [medusaOrder, medreportOrder, countryCodes] = await Promise.all([ + retrieveOrder(medusaOrderId), + getOrder({ medusaOrderId }), + listRegions(), + ]); + const countryCode = countryCodes[0]!.countries![0]!.iso_2!; const account = await getAccountAdmin({ primaryOwnerUserId: medreportOrder.user_id }); + + let analysisPackageElements: StoreProduct[] = []; + const orderedAnalysisPackages = (medusaOrder?.items ?? []).filter(({ product }) => product?.handle.startsWith(ANALYSIS_PACKAGE_HANDLE_PREFIX)); + const orderedAnalysisElements = (medusaOrder?.items ?? []).filter(({ product }) => product?.handle.startsWith(ANALYSIS_ELEMENT_HANDLE_PREFIX)); - const ANALYSIS_ELEMENT_HANDLE_PREFIX = 'analysis-element-'; - const orderedAnalysisElementsIds = (medusaOrder?.items ?? []) - .filter((item) => item.product?.handle?.startsWith(ANALYSIS_ELEMENT_HANDLE_PREFIX)) - .map((item) => { - const id = Number(item.product?.handle?.replace(ANALYSIS_ELEMENT_HANDLE_PREFIX, '')); + if (orderedAnalysisPackages.length > 0) { + const { response: { products: analysisPackages } } = await listProducts({ + countryCode, + queryParams: { limit: 100, "type_id[0]": orderedAnalysisPackages[0]!.product_type_id! }, + }); + const analysisElementMedusaProductIds = getAnalysisElementMedusaProductIds(analysisPackages); + const { response: { products } } = await listProducts({ + countryCode, + queryParams: { + id: analysisElementMedusaProductIds, + limit: 100, + }, + }); + analysisPackageElements = products; + } + + const analysisPackageElementsIds = analysisPackageElements + .map((product) => { + const id = Number(product?.metadata?.analysisIdOriginal); + if (Number.isNaN(id)) { + return null; + } + return id; + }) + .filter(Boolean) as number[]; + const orderedAnalysisElementsIds = orderedAnalysisElements + .map((line) => { + const id = Number(line.product?.handle?.replace(ANALYSIS_ELEMENT_HANDLE_PREFIX, '')); if (Number.isNaN(id)) { return null; } @@ -653,7 +690,7 @@ export async function sendOrderToMedipost({ lastName: account.last_name ?? '', phone: account.phone ?? '', }, - orderedAnalysisElementsIds, + orderedAnalysisElementsIds: [...analysisPackageElementsIds, ...orderedAnalysisElementsIds], orderedAnalysesIds: [], orderId: medusaOrderId, orderCreatedAt: new Date(medreportOrder.created_at),