feat(MED-131): update analyses on package logic
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { XMLParser } from 'fast-xml-parser';
|
import { XMLParser } from 'fast-xml-parser';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { createAnalysisGroup } from '~/lib/services/analysis-group.service';
|
import { createAnalysisGroup, getAnalysisGroups } from '~/lib/services/analysis-group.service';
|
||||||
import { IMedipostPublicMessageDataParsed } from '~/lib/services/medipost.types';
|
import { IMedipostPublicMessageDataParsed } from '~/lib/services/medipost.types';
|
||||||
import { createAnalysis, createNoDataReceivedEntry, createNoNewDataReceivedEntry, createSyncFailEntry, createSyncSuccessEntry } from '~/lib/services/analyses.service';
|
import { createAnalysis, createNoDataReceivedEntry, createNoNewDataReceivedEntry, createSyncFailEntry, createSyncSuccessEntry } from '~/lib/services/analyses.service';
|
||||||
import { getLastCheckedDate } from '~/lib/services/sync-entries.service';
|
import { getLastCheckedDate } from '~/lib/services/sync-entries.service';
|
||||||
@@ -64,6 +64,8 @@ export default async function syncAnalysisGroups() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const existingAnalysisGroups = await getAnalysisGroups();
|
||||||
|
|
||||||
// SAVE PUBLIC MESSAGE DATA
|
// SAVE PUBLIC MESSAGE DATA
|
||||||
|
|
||||||
const providers = toArray(parsed?.Saadetis?.Teenused.Teostaja);
|
const providers = toArray(parsed?.Saadetis?.Teenused.Teostaja);
|
||||||
@@ -79,6 +81,12 @@ export default async function syncAnalysisGroups() {
|
|||||||
|
|
||||||
const codes: ICode[] = [];
|
const codes: ICode[] = [];
|
||||||
for (const analysisGroup of analysisGroups) {
|
for (const analysisGroup of analysisGroups) {
|
||||||
|
const existingAnalysisGroup = existingAnalysisGroups?.find(({ original_id }) => original_id === analysisGroup.UuringuGruppId);
|
||||||
|
if (existingAnalysisGroup) {
|
||||||
|
console.info(`Analysis group '${analysisGroup.UuringuGruppNimi}' already exists`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// SAVE ANALYSIS GROUP
|
// SAVE ANALYSIS GROUP
|
||||||
const analysisGroupId = await createAnalysisGroup({
|
const analysisGroupId = await createAnalysisGroup({
|
||||||
id: analysisGroup.UuringuGruppId,
|
id: analysisGroup.UuringuGruppId,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import { PackageHeader } from '@/components/package-header';
|
|||||||
import { InfoTooltip } from '@/components/ui/info-tooltip';
|
import { InfoTooltip } from '@/components/ui/info-tooltip';
|
||||||
import { StoreProduct } from '@medusajs/types';
|
import { StoreProduct } from '@medusajs/types';
|
||||||
import type { AnalysisElement } from '~/lib/services/analysis-element.service';
|
import type { AnalysisElement } from '~/lib/services/analysis-element.service';
|
||||||
import { getAnalysisElementOriginalIds } from '@lib/data/products';
|
import { getAnalysisElementOriginalIds } from '@/utils/medusa-product';
|
||||||
|
|
||||||
const CheckWithBackground = () => {
|
const CheckWithBackground = () => {
|
||||||
return (
|
return (
|
||||||
@@ -34,6 +34,24 @@ const CheckWithBackground = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PackageTableHead = async ({ product, nrOfAnalyses }: { product: StoreProduct, nrOfAnalyses: number }) => {
|
||||||
|
const { t, language } = await createI18nServerInstance();
|
||||||
|
const variant = product.variants?.[0];
|
||||||
|
const titleKey = product.title;
|
||||||
|
const price = variant?.calculated_price?.calculated_amount ?? 0;
|
||||||
|
return (
|
||||||
|
<TableHead className="py-2">
|
||||||
|
<PackageHeader
|
||||||
|
title={t(titleKey)}
|
||||||
|
tagColor='bg-cyan'
|
||||||
|
analysesNr={t('product:nrOfAnalyses', { nr: nrOfAnalyses })}
|
||||||
|
language={language}
|
||||||
|
price={price}
|
||||||
|
/>
|
||||||
|
</TableHead>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const ComparePackagesModal = async ({
|
const ComparePackagesModal = async ({
|
||||||
analysisElements,
|
analysisElements,
|
||||||
analysisPackages,
|
analysisPackages,
|
||||||
@@ -43,7 +61,7 @@ const ComparePackagesModal = async ({
|
|||||||
analysisPackages: StoreProduct[];
|
analysisPackages: StoreProduct[];
|
||||||
triggerElement: JSX.Element;
|
triggerElement: JSX.Element;
|
||||||
}) => {
|
}) => {
|
||||||
const { t, language } = await createI18nServerInstance();
|
const { t } = await createI18nServerInstance();
|
||||||
|
|
||||||
const standardPackage = analysisPackages.find(({ metadata }) => metadata?.analysisPackageTier === 'standard')!;
|
const standardPackage = analysisPackages.find(({ metadata }) => metadata?.analysisPackageTier === 'standard')!;
|
||||||
const standardPlusPackage = analysisPackages.find(({ metadata }) => metadata?.analysisPackageTier === 'standard-plus')!;
|
const standardPlusPackage = analysisPackages.find(({ metadata }) => metadata?.analysisPackageTier === 'standard-plus')!;
|
||||||
@@ -53,9 +71,9 @@ const ComparePackagesModal = async ({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const standardPackageAnalyses = await getAnalysisElementOriginalIds([standardPackage]);
|
const standardPackageAnalyses = getAnalysisElementOriginalIds([standardPackage]);
|
||||||
const standardPlusPackageAnalyses = await getAnalysisElementOriginalIds([standardPlusPackage]);
|
const standardPlusPackageAnalyses = getAnalysisElementOriginalIds([standardPlusPackage]);
|
||||||
const premiumPackageAnalyses = await getAnalysisElementOriginalIds([premiumPackage]);
|
const premiumPackageAnalyses = getAnalysisElementOriginalIds([premiumPackage]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog>
|
<Dialog>
|
||||||
@@ -86,25 +104,9 @@ const ComparePackagesModal = async ({
|
|||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead></TableHead>
|
<TableHead></TableHead>
|
||||||
{analysisPackages.map(
|
<PackageTableHead product={standardPackage} nrOfAnalyses={standardPackageAnalyses.length} />
|
||||||
(product) => {
|
<PackageTableHead product={standardPlusPackage} nrOfAnalyses={standardPlusPackageAnalyses.length} />
|
||||||
const variant = product.variants?.[0];
|
<PackageTableHead product={premiumPackage} nrOfAnalyses={premiumPackageAnalyses.length} />
|
||||||
const titleKey = product.title;
|
|
||||||
const price = variant?.calculated_price?.calculated_amount ?? 0;
|
|
||||||
return (
|
|
||||||
<TableHead key={titleKey} className="py-2">
|
|
||||||
<PackageHeader
|
|
||||||
title={t(titleKey)}
|
|
||||||
tagColor='bg-cyan'
|
|
||||||
analysesNr={t('product:nrOfAnalyses', {
|
|
||||||
nr: product?.metadata?.nrOfAnalyses ?? 0,
|
|
||||||
})}
|
|
||||||
language={language}
|
|
||||||
price={price}
|
|
||||||
/>
|
|
||||||
</TableHead>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { cache } from 'react';
|
import { cache } from 'react';
|
||||||
|
|
||||||
import { getAnalysisElementOriginalIds, listProductTypes, listProducts } from "@lib/data/products";
|
import { listProductTypes, listProducts } from "@lib/data/products";
|
||||||
import { listRegions } from '@lib/data/regions';
|
import { listRegions } from '@lib/data/regions';
|
||||||
import { AnalysisElement, getAnalysisElements } from '~/lib/services/analysis-element.service';
|
import { AnalysisElement, getAnalysisElements } from '~/lib/services/analysis-element.service';
|
||||||
|
import { getAnalysisElementOriginalIds } from '@/utils/medusa-product';
|
||||||
|
|
||||||
async function countryCodesLoader() {
|
async function countryCodesLoader() {
|
||||||
const countryCodes = await listRegions().then((regions) =>
|
const countryCodes = await listRegions().then((regions) =>
|
||||||
@@ -33,7 +34,7 @@ async function analysisPackagesLoader() {
|
|||||||
});
|
});
|
||||||
const analysisPackages = response.products;
|
const analysisPackages = response.products;
|
||||||
let analysisElements: AnalysisElement[] = [];
|
let analysisElements: AnalysisElement[] = [];
|
||||||
const analysisElementOriginalIds = await getAnalysisElementOriginalIds(analysisPackages);
|
const analysisElementOriginalIds = getAnalysisElementOriginalIds(analysisPackages);
|
||||||
|
|
||||||
if (analysisElementOriginalIds.length) {
|
if (analysisElementOriginalIds.length) {
|
||||||
analysisElements = await getAnalysisElements({ originalIds: analysisElementOriginalIds });
|
analysisElements = await getAnalysisElements({ originalIds: analysisElementOriginalIds });
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { use, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
@@ -19,11 +19,11 @@ import { handleAddToCart } from '@/lib/services/medusaCart.service';
|
|||||||
|
|
||||||
import { PackageHeader } from './package-header';
|
import { PackageHeader } from './package-header';
|
||||||
import { ButtonTooltip } from './ui/button-tooltip';
|
import { ButtonTooltip } from './ui/button-tooltip';
|
||||||
|
import { getAnalysisElementOriginalIds } from '@/utils/medusa-product';
|
||||||
|
|
||||||
export interface IAnalysisPackage {
|
export interface IAnalysisPackage {
|
||||||
titleKey: string;
|
titleKey: string;
|
||||||
price: number;
|
price: number;
|
||||||
nrOfAnalyses: number | string;
|
|
||||||
tagColor: string;
|
tagColor: string;
|
||||||
descriptionKey: string;
|
descriptionKey: string;
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,8 @@ export default function SelectAnalysisPackage({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const titleKey = analysisPackage.title;
|
const titleKey = analysisPackage.title;
|
||||||
const nrOfAnalyses = analysisPackage?.metadata?.nrOfAnalyses ?? 0;
|
const analysisElementOriginalIds = getAnalysisElementOriginalIds([analysisPackage]);
|
||||||
|
const nrOfAnalyses = analysisElementOriginalIds.length;
|
||||||
const description = analysisPackage.description ?? '';
|
const description = analysisPackage.description ?? '';
|
||||||
const subtitle = analysisPackage.subtitle ?? '';
|
const subtitle = analysisPackage.subtitle ?? '';
|
||||||
const variant = analysisPackage.variants?.[0];
|
const variant = analysisPackage.variants?.[0];
|
||||||
|
|||||||
@@ -9,10 +9,8 @@ export type AnalysisElement = Tables<{ schema: 'medreport' }, 'analysis_elements
|
|||||||
|
|
||||||
export async function getAnalysisElements({
|
export async function getAnalysisElements({
|
||||||
originalIds,
|
originalIds,
|
||||||
ids,
|
|
||||||
}: {
|
}: {
|
||||||
originalIds?: string[];
|
originalIds?: string[];
|
||||||
ids?: number[];
|
|
||||||
}): Promise<AnalysisElement[]> {
|
}): Promise<AnalysisElement[]> {
|
||||||
const query = getSupabaseServerClient()
|
const query = getSupabaseServerClient()
|
||||||
.schema('medreport')
|
.schema('medreport')
|
||||||
@@ -24,11 +22,35 @@ export async function getAnalysisElements({
|
|||||||
query.in('analysis_id_original', [...new Set(originalIds)]);
|
query.in('analysis_id_original', [...new Set(originalIds)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { data: analysisElements, error } = await query;
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(`Failed to get analysis elements: ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return analysisElements ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getAnalysisElementsAdmin({
|
||||||
|
ids,
|
||||||
|
}: {
|
||||||
|
ids?: number[];
|
||||||
|
} = {}): Promise<AnalysisElement[]> {
|
||||||
|
const query = getSupabaseServerAdminClient()
|
||||||
|
.schema('medreport')
|
||||||
|
.from('analysis_elements')
|
||||||
|
.select(`*, analysis_groups(*)`)
|
||||||
|
.order('order', { ascending: true });
|
||||||
|
|
||||||
if (Array.isArray(ids)) {
|
if (Array.isArray(ids)) {
|
||||||
query.in('id', ids);
|
query.in('id', ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data: analysisElements } = await query;
|
const { data: analysisElements, error } = await query;
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(`Failed to get analysis elements: ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
return analysisElements ?? [];
|
return analysisElements ?? [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import { Tables } from '@kit/supabase/database';
|
|||||||
import { createAnalysisGroup } from './analysis-group.service';
|
import { createAnalysisGroup } from './analysis-group.service';
|
||||||
import { getSupabaseServerAdminClient } from '@/packages/supabase/src/clients/server-admin-client';
|
import { getSupabaseServerAdminClient } from '@/packages/supabase/src/clients/server-admin-client';
|
||||||
import { getOrder } from './order.service';
|
import { getOrder } from './order.service';
|
||||||
import { getAnalysisElements } from './analysis-element.service';
|
import { getAnalysisElementsAdmin } from './analysis-element.service';
|
||||||
import { getAnalyses } from './analyses.service';
|
import { getAnalyses } from './analyses.service';
|
||||||
|
|
||||||
const BASE_URL = process.env.MEDIPOST_URL!;
|
const BASE_URL = process.env.MEDIPOST_URL!;
|
||||||
@@ -407,7 +407,7 @@ export async function composeOrderXML({
|
|||||||
orderCreatedAt: Date;
|
orderCreatedAt: Date;
|
||||||
comment?: string;
|
comment?: string;
|
||||||
}) {
|
}) {
|
||||||
const analysisElements = await getAnalysisElements({ ids: orderedAnalysisElementsIds });
|
const analysisElements = await getAnalysisElementsAdmin({ ids: orderedAnalysisElementsIds });
|
||||||
const analyses = await getAnalyses({ ids: orderedAnalysesIds });
|
const analyses = await getAnalyses({ ids: orderedAnalysesIds });
|
||||||
|
|
||||||
const analysisGroups: Tables<{ schema: 'medreport' }, 'analysis_groups'>[] =
|
const analysisGroups: Tables<{ schema: 'medreport' }, 'analysis_groups'>[] =
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { uniqBy } from 'lodash';
|
|||||||
import { Tables } from '@kit/supabase/database';
|
import { Tables } from '@kit/supabase/database';
|
||||||
import { formatDate } from 'date-fns';
|
import { formatDate } from 'date-fns';
|
||||||
import { getAnalyses } from './analyses.service';
|
import { getAnalyses } from './analyses.service';
|
||||||
import { getAnalysisElements } from './analysis-element.service';
|
import { getAnalysisElementsAdmin } from './analysis-element.service';
|
||||||
import { validateMedipostResponse } from './medipost.service';
|
import { validateMedipostResponse } from './medipost.service';
|
||||||
|
|
||||||
const BASE_URL = process.env.MEDIPOST_URL!;
|
const BASE_URL = process.env.MEDIPOST_URL!;
|
||||||
@@ -70,7 +70,7 @@ export async function composeOrderTestResponseXML({
|
|||||||
orderId: string;
|
orderId: string;
|
||||||
orderCreatedAt: Date;
|
orderCreatedAt: Date;
|
||||||
}) {
|
}) {
|
||||||
const analysisElements = await getAnalysisElements({ ids: orderedAnalysisElementsIds });
|
const analysisElements = await getAnalysisElementsAdmin({ ids: orderedAnalysisElementsIds });
|
||||||
const analyses = await getAnalyses({ ids: orderedAnalysesIds });
|
const analyses = await getAnalyses({ ids: orderedAnalysesIds });
|
||||||
|
|
||||||
const analysisGroups: Tables<{ schema: 'medreport' }, 'analysis_groups'>[] =
|
const analysisGroups: Tables<{ schema: 'medreport' }, 'analysis_groups'>[] =
|
||||||
|
|||||||
@@ -85,20 +85,6 @@ export const listProducts = async ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getAnalysisElementOriginalIds = async (products: HttpTypes.StoreProduct[]) => {
|
|
||||||
return products
|
|
||||||
.flatMap(({ metadata }) => {
|
|
||||||
const value = metadata?.analysisElementOriginalIds;
|
|
||||||
try {
|
|
||||||
return JSON.parse(value as string);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Failed to parse analysisElementOriginalIds from analysis package, possibly invalid format", e);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(Boolean) as string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will fetch 100 products to the Next.js cache and sort them based on the sortBy parameter.
|
* This will fetch 100 products to the Next.js cache and sort them based on the sortBy parameter.
|
||||||
* It will then return the paginated products based on the page and limit parameters.
|
* It will then return the paginated products based on the page and limit parameters.
|
||||||
|
|||||||
17
utils/medusa-product.ts
Normal file
17
utils/medusa-product.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export const getAnalysisElementOriginalIds = (products: ({ metadata?: { analysisElementOriginalIds?: string } | null } | null)[]) => {
|
||||||
|
if (!products) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return products
|
||||||
|
.flatMap((product) => {
|
||||||
|
const value = product?.metadata?.analysisElementOriginalIds;
|
||||||
|
try {
|
||||||
|
return JSON.parse(value as string);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to parse analysisElementOriginalIds from analysis package, possibly invalid format", e);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Boolean) as string[];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user