infoalloggi-monorepo/apps/infoalloggi/src/server/controllers/annunci.controller.ts

427 lines
8.6 KiB
TypeScript

import { TRPCError } from "@trpc/server";
import { env } from "~/env.mjs";
import type {
Annunci,
AnnunciId,
AnnunciUpdate,
} from "~/schemas/public/Annunci";
import type { ServizioServizioId } from "~/schemas/public/Servizio";
import { db } from "~/server/db";
import { AnnuncioObjectWithImages } from "~/server/services/annunci.service";
import { createSrcset } from "~/server/services/imageServer";
// const ratelimit = new RateLimiterHandler({
// windowSize: 10,
// maxRequests: 10,
// analytics: true,
// });
export const getAnnunciListHandler = async (): Promise<
Pick<
Annunci,
"id" | "codice" | "titolo_it" | "comune" | "tipo" | "locatore" | "stato"
>[]
> => {
try {
return await db
.selectFrom("annunci")
.select([
"id",
"codice",
"titolo_it",
"comune",
"tipo",
"locatore",
"stato",
])
.execute();
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore query getAllRaw: ${(e as Error).message}`,
});
}
};
export const getCodici_AnnunciHandler = async (): Promise<string[]> => {
try {
const codici = await db
.selectFrom("annunci")
.select("codice")
.where("annunci.web", "=", true)
.where("stato", "!=", "Sospeso")
.execute();
if (!codici) {
return [];
}
return codici.map((c) => c.codice);
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore query getCodici: ${(e as Error).message}`,
});
}
};
export const getAnnunciByCod = async ({
cod,
}: {
cod: string;
}): Promise<Annunci | null> => {
try {
const annuncio = await db
.selectFrom("annunci")
.selectAll()
.where("annunci.web", "=", true)
.where("codice", "=", cod)
.executeTakeFirst();
if (!annuncio) {
return null;
}
return AnnuncioObjectWithImages<typeof annuncio>(annuncio);
} catch (e) {
throw new TRPCError({
cause: (e as Error).cause,
code: "INTERNAL_SERVER_ERROR",
message: `Errore query getAnnunciByCod: ${(e as Error).message}`,
});
}
};
export const getAnnunciMetaByCod = async ({ cod }: { cod: string }) => {
try {
const annuncio = await db
.selectFrom("annunci")
.select(["titolo_it", "desc_it", "og_url"])
.where("annunci.web", "=", true)
.where("codice", "=", cod)
.executeTakeFirst();
if (!annuncio) {
return null;
}
return {
description: annuncio.desc_it || "",
ogImage: annuncio.og_url || "",
ogUrl: `${env.NEXT_PUBLIC_BASE_URL}/annuncio/${cod}`,
title: annuncio.titolo_it || "",
};
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore query getAnnunciMetaByCod: ${(e as Error).message}`,
});
}
};
export const getAnnunciById_rawImgUrls = async ({
id,
}: {
id: AnnunciId;
}): Promise<Annunci | null> => {
try {
const annuncio = await db
.selectFrom("annunci")
.selectAll()
.where("id", "=", id)
.executeTakeFirst();
if (!annuncio) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Annuncio non trovato",
});
}
return annuncio;
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore query getAnnuncioById : ${(e as Error).message}`,
});
}
};
export type AnnuncioRicercaWPosition = AnnuncioRicerca & {
lat_secondario: string | null;
lon_secondario: string | null;
};
export const get_AnnunciPositionsHandler = async ({
tipologia,
comune,
consegna,
}: {
tipologia?: string;
comune?: string;
consegna?: number;
}): Promise<AnnuncioRicercaWPosition[]> => {
try {
let query = db
.selectFrom("annunci")
.select([
"id",
"codice",
"comune",
"provincia",
"prezzo",
"consegna",
"numero_camere",
"mq",
"tipo",
"titolo_it",
"titolo_en",
"url_immagini",
"modificato_il",
"stato",
"url_video",
"lon_secondario",
"lat_secondario",
])
.where("web", "=", true)
.where("stato", "!=", "Sospeso")
.orderBy("id", "asc");
if (tipologia && tipologia !== "") {
query = query.where("tipo", "=", tipologia);
}
if (comune && comune !== "") {
query = query.where("comune", "like", comune);
}
if (consegna) {
query = query.where("consegna", "=", consegna);
}
const annunci = await query.execute();
if (!annunci) {
return [];
}
for (const annuncio of annunci) {
annuncio.url_immagini = annuncio.url_immagini
? createSrcset(annuncio.url_immagini)
: [];
}
return annunci;
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore query getAnnunciPositions: ${(e as Error).message}`,
});
}
};
export type AnnuncioRicerca = Pick<
Annunci,
| "id"
| "codice"
| "comune"
| "provincia"
| "prezzo"
| "consegna"
| "numero_camere"
| "mq"
| "tipo"
| "titolo_it"
| "titolo_en"
| "url_immagini"
| "modificato_il"
| "stato"
| "url_video"
>;
export const getCursor_AnnunciHandler = async ({
page = 0,
pageSize,
tipologia,
comune,
consegna,
sort,
}: {
page?: number;
pageSize: number;
tipologia?: string;
comune?: string;
consegna?: number;
sort?: "Recenti" | "Prezzo" | "Consegna" | "Mq";
}) => {
try {
let query = db
.selectFrom("annunci")
.select([
"id",
"codice",
"comune",
"provincia",
"prezzo",
"consegna",
"numero_camere",
"mq",
"tipo",
"titolo_it",
"titolo_en",
"url_immagini",
"modificato_il",
"stato",
"url_video",
])
.where("web", "=", true)
.where("stato", "!=", "Sospeso");
if (tipologia && tipologia !== "") {
query = query.where("tipo", "=", tipologia);
}
if (comune && comune !== "") {
query = query.where("comune", "like", comune);
}
if (consegna) {
query = query.where("consegna", "=", consegna);
}
switch (sort) {
case "Recenti":
query = query.orderBy("modificato_il", "desc");
break;
case "Prezzo":
query = query.orderBy("prezzo", "asc");
break;
case "Consegna":
query = query.orderBy("consegna", "asc");
break;
case "Mq":
query = query.orderBy("mq", "asc");
break;
case undefined:
break;
}
query = query.orderBy("id", "asc");
const annunci = await query
.limit(pageSize + 1)
.offset(page * pageSize)
.execute();
const hasMore = annunci.length > pageSize;
if (annunci.length > pageSize) {
annunci.pop(); // Remove the last item if it exceeds the page size
}
for (const annuncio of annunci) {
annuncio.url_immagini = annuncio.url_immagini
? createSrcset(annuncio.url_immagini)
: [];
}
return {
annunci,
hasMore,
};
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore query getWithCursor: ${(e as Error).message}`,
});
}
};
export const getOptions_AnnunciHandler = async () => {
try {
const comuni = await db
.selectFrom("annunci")
.select(["comune", "tipo", "consegna"])
.where("web", "=", true)
.where("stato", "!=", "Sospeso")
.distinct()
.execute();
const results: { comune: string; tipo: string; consegna: number }[] = [];
for (const comune of comuni) {
if (comune.comune && comune.tipo && comune.consegna) {
results.push({
comune: comune.comune,
consegna: comune.consegna,
tipo: comune.tipo,
});
}
}
return results;
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore query getComuni: ${(e as Error).message}`,
});
}
};
export const editAnnuncioHandler = async ({
annuncioId,
data,
}: {
annuncioId: AnnunciId;
data: AnnunciUpdate;
}) => {
try {
await db
.updateTable("annunci")
.set({
...data,
})
.where("id", "=", annuncioId)
.execute();
return true;
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore interno: ${(e as Error).message}`,
});
}
};
export const getProprietarioDataHandler = async ({
annuncioId,
servizioId,
}: {
annuncioId: AnnunciId;
servizioId: ServizioServizioId;
}) => {
try {
const opened_at = await db
.selectFrom("servizio_annunci")
.select("open_contatti_at")
.where("servizio_id", "=", servizioId)
.where("annunci_id", "=", annuncioId)
.executeTakeFirst();
if (!opened_at || !opened_at.open_contatti_at) {
return { opened_at: null, propData: null };
}
const propData = await db
.selectFrom("annunci")
.select([
"codice",
"comune",
"indirizzo",
"civico",
"provincia",
"regione",
"cap",
"lat",
"lon",
"numero",
"locatore",
])
.where("id", "=", annuncioId)
.executeTakeFirstOrThrow();
return { opened_at: opened_at.open_contatti_at, propData };
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore recupero dati proprietario: ${(e as Error).message}`,
});
}
};