1.5.2
- feat: order confirmation PDF generation with VAT support - feat: order confirmation modal with custom item editing - fix: attendance negative duration clamping and switchProject timing - fix: Quill editor locked to Tahoma 14px, PDF heading sizes - fix: invoice/offer PDF font consistency (Tahoma enforcement) - fix: invoice alert cron improvements - fix: NAS financials manager edge cases - refactor: numbering service with unique sequence constraints Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import prisma from "../config/database";
|
||||
import { generateSharedNumber } from "./numbering.service";
|
||||
import {
|
||||
generateSharedNumber,
|
||||
previewSharedNumber,
|
||||
releaseSharedNumber,
|
||||
} from "./numbering.service";
|
||||
import { NasFileManager } from "./nas-file-manager";
|
||||
|
||||
const nasFileManager = new NasFileManager();
|
||||
@@ -93,9 +97,14 @@ export async function getProject(id: number) {
|
||||
}
|
||||
|
||||
export async function createProject(body: Record<string, any>) {
|
||||
const projectNumber =
|
||||
body.project_number !== undefined && body.project_number !== null
|
||||
? String(body.project_number)
|
||||
: await generateSharedNumber();
|
||||
|
||||
const project = await prisma.projects.create({
|
||||
data: {
|
||||
project_number: body.project_number ? String(body.project_number) : null,
|
||||
project_number: projectNumber,
|
||||
name: body.name ? String(body.name) : null,
|
||||
customer_id: body.customer_id ? Number(body.customer_id) : null,
|
||||
responsible_user_id: body.responsible_user_id
|
||||
@@ -124,8 +133,15 @@ export async function updateProject(id: number, body: Record<string, any>) {
|
||||
const existing = await prisma.projects.findUnique({ where: { id } });
|
||||
if (!existing) return null;
|
||||
|
||||
if (
|
||||
body.project_number !== undefined &&
|
||||
String(body.project_number) !== existing.project_number
|
||||
) {
|
||||
return { error: "Číslo projektu nelze změnit", status: 400 };
|
||||
}
|
||||
|
||||
const data: Record<string, unknown> = { modified_at: new Date() };
|
||||
const strFields = ["project_number", "name", "status", "notes"];
|
||||
const strFields = ["name", "status", "notes"];
|
||||
for (const f of strFields)
|
||||
if (body[f] !== undefined) data[f] = body[f] ? String(body[f]) : null;
|
||||
if (body.customer_id !== undefined)
|
||||
@@ -148,13 +164,14 @@ export async function updateProject(id: number, body: Record<string, any>) {
|
||||
await prisma.projects.update({ where: { id }, data });
|
||||
|
||||
if (
|
||||
existing.name !== data.name &&
|
||||
body.name !== undefined &&
|
||||
existing.name !== body.name &&
|
||||
existing.project_number &&
|
||||
nasFileManager.isConfigured()
|
||||
) {
|
||||
nasFileManager.renameProjectFolder(
|
||||
existing.project_number,
|
||||
String(data.name || ""),
|
||||
String(body.name || ""),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -171,6 +188,12 @@ export async function deleteProject(id: number, deleteFiles: boolean = false) {
|
||||
}
|
||||
|
||||
await prisma.projects.delete({ where: { id } });
|
||||
|
||||
const year = existing.created_at
|
||||
? new Date(existing.created_at).getFullYear()
|
||||
: new Date().getFullYear();
|
||||
await releaseSharedNumber(year);
|
||||
|
||||
return existing;
|
||||
}
|
||||
|
||||
@@ -205,5 +228,5 @@ export async function deleteProjectNote(projectId: number, noteId: number) {
|
||||
}
|
||||
|
||||
export async function getNextProjectNumber() {
|
||||
return generateSharedNumber();
|
||||
return previewSharedNumber();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user