From 40f8ba0caa70a605be27aa3357d1a9d253661443 Mon Sep 17 00:00:00 2001 From: Nulo Date: Tue, 17 Dec 2024 00:21:49 -0300 Subject: [PATCH] fix: arreglar paginas de productos viejos --- .../routes/id_producto/[id]/+page.server.ts | 66 ++++++++++++------- .../src/routes/id_producto/[id]/+page.svelte | 38 ++++++++++- 2 files changed, 80 insertions(+), 24 deletions(-) diff --git a/sepa/sitio2/src/routes/id_producto/[id]/+page.server.ts b/sepa/sitio2/src/routes/id_producto/[id]/+page.server.ts index 43e6de7..8e2938c 100644 --- a/sepa/sitio2/src/routes/id_producto/[id]/+page.server.ts +++ b/sepa/sitio2/src/routes/id_producto/[id]/+page.server.ts @@ -1,19 +1,14 @@ import { db } from '$lib/server/db'; import type { PageServerLoad } from './$types'; import { banderas, datasets, precios, sucursales } from '$lib/server/db/schema'; -import { and, eq, sql } from 'drizzle-orm'; +import { and, eq, sql, SQL } from 'drizzle-orm'; import { error } from '@sveltejs/kit'; import * as Sentry from '@sentry/sveltekit'; import { formatISO, subDays } from 'date-fns'; import { z } from 'zod'; -export const load: PageServerLoad = async ({ params, setHeaders }) => { - const { success, data } = z.object({ id: z.coerce.bigint() }).safeParse(params); - if (!success) { - return error(400, `Esta URL es inválida`); - } - const id = data.id; - const aWeekAgo = subDays(new Date(), 5); - const preciosQuery = db + +function getProduct(id: bigint, filterDatasetBy: SQL) { + const q = db .select({ id_comercio: precios.id_comercio, id_bandera: precios.id_bandera, @@ -35,7 +30,7 @@ export const load: PageServerLoad = async ({ params, setHeaders }) => { .from(precios) .where( and( - eq(precios.id_producto, BigInt(params.id)), + eq(precios.id_producto, BigInt(id)), sql`${precios.id_dataset} IN ( @@ -44,7 +39,7 @@ FROM datasets d1 JOIN ( SELECT id_comercio, MAX(date) as max_date FROM datasets - WHERE date > ${formatISO(aWeekAgo, { representation: 'date' })} + WHERE ${filterDatasetBy} GROUP BY id_comercio ) d2 ON d1.id_comercio = d2.id_comercio AND d1.date = d2.max_date ORDER BY d1.id_comercio) @@ -68,14 +63,35 @@ ORDER BY d1.id_comercio) eq(banderas.id_bandera, precios.id_bandera) ) ); - const preciosRes = await Sentry.startSpan( + return Sentry.startSpan( { op: 'db.query', - name: preciosQuery.toSQL().sql, + name: q.toSQL().sql, data: { 'db.system': 'postgresql' } // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any, - () => preciosQuery + () => + q.then((x) => + x.map((p) => ({ + ...p, + productos_precio_lista: parseFloat(p.productos_precio_lista ?? '0'), + sucursales_latitud: parseFloat(p.sucursales_latitud ?? '0'), + sucursales_longitud: parseFloat(p.sucursales_longitud ?? '0') + })) + ) + ); +} + +export const load: PageServerLoad = async ({ params, setHeaders }) => { + const { success, data } = z.object({ id: z.coerce.bigint() }).safeParse(params); + if (!success) { + return error(400, `Esta URL es inválida`); + } + const id = data.id; + const aWeekAgo = subDays(new Date(), 5); + const preciosRes = await getProduct( + id, + sql`date > ${formatISO(aWeekAgo, { representation: 'date' })}` ); setHeaders({ @@ -83,16 +99,22 @@ ORDER BY d1.id_comercio) }); if (preciosRes.length == 0) { - return error(404, `Producto ${params.id} no encontrado`); + const preciosOldRes = await getProduct(id, sql`TRUE`); + + if (preciosOldRes.length == 0) { + return error(404, `Producto ${params.id} no encontrado`); + } + + return { + precios: preciosOldRes, + id_producto: id, + old: true + }; } return { - precios: preciosRes.map((p) => ({ - ...p, - productos_precio_lista: parseFloat(p.productos_precio_lista ?? '0'), - sucursales_latitud: parseFloat(p.sucursales_latitud ?? '0'), - sucursales_longitud: parseFloat(p.sucursales_longitud ?? '0') - })), - id_producto: id + precios: preciosRes, + id_producto: id, + old: false }; }; diff --git a/sepa/sitio2/src/routes/id_producto/[id]/+page.svelte b/sepa/sitio2/src/routes/id_producto/[id]/+page.svelte index 6dbe889..edaae31 100644 --- a/sepa/sitio2/src/routes/id_producto/[id]/+page.svelte +++ b/sepa/sitio2/src/routes/id_producto/[id]/+page.svelte @@ -23,6 +23,9 @@ import type { GeoJSON as GeoJSONType } from 'geojson'; import type { DataDrivenPropertyValueSpecification } from 'maplibre-gl'; import Button from '$lib/components/ui/button/button.svelte'; + import { TriangleAlert } from 'lucide-svelte'; + import * as Dialog from '$lib/components/ui/dialog'; + import { differenceInDays } from 'date-fns'; export let data: PageData; @@ -61,8 +64,19 @@ })) }; } - $: geoJSON = generateGeoJSON(data.precios); + $: newest = new Date( + data.precios.sort((a, b) => { + const dateA = b.dataset_date ? new Date(b.dataset_date) : new Date(0); + const dateB = a.dataset_date ? new Date(a.dataset_date) : new Date(0); + return dateA.getTime() - dateB.getTime(); + })[0].dataset_date ?? new Date(0) + ); + + const relativeTimeFormatter = new Intl.RelativeTimeFormat('es-AR', { + style: 'long', + numeric: 'auto' + }); function hoverStateFilter( offValue: number, @@ -86,12 +100,32 @@ > -
+

{data.precios[0].productos_descripcion}

{data.precios.length} precios EAN {data.id_producto} + {#if data.old} + + + + + Precios antiguos + + + + Precios antiguos + + Los datos de esta pagina son de hace al menos {relativeTimeFormatter.format( + -differenceInDays(new Date(), new Date(newest)), + 'days' + )}. Es muy probable que este producto especifico este descontinuado. Revisa las fechas + de cada precio para confirmar. + + + + {/if}