Files
crm-server/src/services/ai-kurzy/registracie.service.js
richardtekula 12acd68156 refactor: Move course dates from registracie to kurzy table
- Add datumOd and datumDo columns to kurzy table
- Remove datumOd, datumDo, pocetUcastnikov from registracie table
- Update schema, validators, and services accordingly
- Certificate generation now uses course dates
- Migration preserves existing data by copying most recent dates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 12:52:56 +01:00

235 lines
7.1 KiB
JavaScript

import { db } from '../../config/database.js';
import { kurzy, ucastnici, registracie, prilohy } from '../../db/schema.js';
import { and, desc, eq, sql } from 'drizzle-orm';
import { NotFoundError } from '../../utils/errors.js';
export const getAllRegistracie = async (kurzId = null) => {
const conditions = kurzId ? [eq(registracie.kurzId, kurzId)] : [];
const result = await db
.select({
id: registracie.id,
kurzId: registracie.kurzId,
ucastnikId: registracie.ucastnikId,
formaKurzu: registracie.formaKurzu,
fakturaCislo: registracie.fakturaCislo,
fakturaVystavena: registracie.fakturaVystavena,
zaplatene: registracie.zaplatene,
stav: registracie.stav,
poznamka: registracie.poznamka,
createdAt: registracie.createdAt,
kurzNazov: kurzy.nazov,
kurzTyp: kurzy.typKurzu,
kurzDatumOd: kurzy.datumOd,
kurzDatumDo: kurzy.datumDo,
ucastnikMeno: ucastnici.meno,
ucastnikPriezvisko: ucastnici.priezvisko,
ucastnikEmail: ucastnici.email,
ucastnikFirma: ucastnici.firma,
})
.from(registracie)
.leftJoin(kurzy, eq(registracie.kurzId, kurzy.id))
.leftJoin(ucastnici, eq(registracie.ucastnikId, ucastnici.id))
.where(conditions.length > 0 ? and(...conditions) : undefined)
.orderBy(desc(kurzy.datumOd), desc(registracie.createdAt));
return result;
};
export const getRegistraciaById = async (id) => {
const [reg] = await db
.select({
id: registracie.id,
kurzId: registracie.kurzId,
ucastnikId: registracie.ucastnikId,
formaKurzu: registracie.formaKurzu,
fakturaCislo: registracie.fakturaCislo,
fakturaVystavena: registracie.fakturaVystavena,
zaplatene: registracie.zaplatene,
stav: registracie.stav,
poznamka: registracie.poznamka,
createdAt: registracie.createdAt,
kurzNazov: kurzy.nazov,
kurzTyp: kurzy.typKurzu,
ucastnikMeno: ucastnici.meno,
ucastnikPriezvisko: ucastnici.priezvisko,
ucastnikEmail: ucastnici.email,
})
.from(registracie)
.leftJoin(kurzy, eq(registracie.kurzId, kurzy.id))
.leftJoin(ucastnici, eq(registracie.ucastnikId, ucastnici.id))
.where(eq(registracie.id, id))
.limit(1);
if (!reg) {
throw new NotFoundError('Registrácia nenájdená');
}
return reg;
};
export const createRegistracia = async (data) => {
const [newReg] = await db
.insert(registracie)
.values({
kurzId: data.kurzId,
ucastnikId: data.ucastnikId,
formaKurzu: data.formaKurzu || 'prezencne',
fakturaCislo: data.fakturaCislo || null,
fakturaVystavena: data.fakturaVystavena || false,
zaplatene: data.zaplatene || false,
stav: data.stav || 'registrovany',
poznamka: data.poznamka || null,
})
.returning();
return newReg;
};
export const updateRegistracia = async (id, data) => {
await getRegistraciaById(id);
const [updated] = await db
.update(registracie)
.set({
...data,
updatedAt: new Date(),
})
.where(eq(registracie.id, id))
.returning();
return updated;
};
export const deleteRegistracia = async (id) => {
await getRegistraciaById(id);
await db.delete(registracie).where(eq(registracie.id, id));
return { success: true, message: 'Registrácia bola odstránená' };
};
export const getCombinedTableData = async () => {
const result = await db
.select({
id: registracie.id,
ucastnikId: ucastnici.id,
titul: ucastnici.titul,
meno: ucastnici.meno,
priezvisko: ucastnici.priezvisko,
email: ucastnici.email,
telefon: ucastnici.telefon,
firma: ucastnici.firma,
firmaIco: ucastnici.firmaIco,
firmaDic: ucastnici.firmaDic,
firmaIcDph: ucastnici.firmaIcDph,
firmaSidlo: ucastnici.firmaSidlo,
mesto: ucastnici.mesto,
ulica: ucastnici.ulica,
psc: ucastnici.psc,
needsFollowup: ucastnici.needsFollowup,
kurzId: kurzy.id,
kurzNazov: kurzy.nazov,
kurzTyp: kurzy.typKurzu,
kurzFarba: kurzy.farba,
datumOd: kurzy.datumOd,
datumDo: kurzy.datumDo,
formaKurzu: registracie.formaKurzu,
fakturaCislo: registracie.fakturaCislo,
fakturaVystavena: registracie.fakturaVystavena,
zaplatene: registracie.zaplatene,
stav: registracie.stav,
poznamka: registracie.poznamka,
createdAt: registracie.createdAt,
dokumentyCount: sql`(SELECT COUNT(*) FROM prilohy WHERE registracia_id = ${registracie.id})::int`,
hasCertificate: sql`(SELECT COUNT(*) > 0 FROM prilohy WHERE registracia_id = ${registracie.id} AND typ_prilohy = 'certifikat')::boolean`,
})
.from(registracie)
.innerJoin(ucastnici, eq(registracie.ucastnikId, ucastnici.id))
.innerJoin(kurzy, eq(registracie.kurzId, kurzy.id))
.orderBy(desc(kurzy.datumOd), desc(registracie.createdAt));
return result;
};
export const updateField = async (registrationId, field, value) => {
const ucastnikFields = ['titul', 'meno', 'priezvisko', 'email', 'telefon', 'firma', 'firmaIco', 'firmaDic', 'firmaIcDph', 'firmaSidlo', 'mesto', 'ulica', 'psc', 'needsFollowup'];
const registraciaFields = ['formaKurzu', 'fakturaCislo', 'fakturaVystavena', 'zaplatene', 'stav', 'poznamka', 'kurzId'];
const [reg] = await db
.select({ ucastnikId: registracie.ucastnikId })
.from(registracie)
.where(eq(registracie.id, registrationId))
.limit(1);
if (!reg) {
throw new NotFoundError('Registrácia nenájdená');
}
if (ucastnikFields.includes(field)) {
await db
.update(ucastnici)
.set({ [field]: value, updatedAt: new Date() })
.where(eq(ucastnici.id, reg.ucastnikId));
} else if (registraciaFields.includes(field)) {
await db
.update(registracie)
.set({ [field]: value, updatedAt: new Date() })
.where(eq(registracie.id, registrationId));
} else {
throw new Error(`Unknown field: ${field}`);
}
return { success: true };
};
export const getPrilohyByRegistracia = async (registraciaId) => {
const result = await db
.select()
.from(prilohy)
.where(eq(prilohy.registraciaId, registraciaId))
.orderBy(desc(prilohy.createdAt));
return result;
};
export const createPriloha = async (data) => {
const [newPriloha] = await db
.insert(prilohy)
.values({
registraciaId: data.registraciaId,
nazovSuboru: data.nazovSuboru,
typPrilohy: data.typPrilohy || 'ine',
cestaKSuboru: data.cestaKSuboru,
mimeType: data.mimeType || null,
velkostSuboru: data.velkostSuboru || null,
popis: data.popis || null,
})
.returning();
return newPriloha;
};
export const deletePriloha = async (id) => {
const [priloha] = await db
.select()
.from(prilohy)
.where(eq(prilohy.id, id))
.limit(1);
if (!priloha) {
throw new NotFoundError('Príloha nenájdená');
}
await db.delete(prilohy).where(eq(prilohy.id, id));
return { success: true, filePath: priloha.cestaKSuboru };
};
export const getPrilohaById = async (id) => {
const [priloha] = await db
.select()
.from(prilohy)
.where(eq(prilohy.id, id))
.limit(1);
return priloha || null;
};