299 lines
10 KiB
JavaScript
Executable File
299 lines
10 KiB
JavaScript
Executable File
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const express_1 = require("express");
|
|
const client_1 = require("@prisma/client");
|
|
const multer_1 = __importDefault(require("multer"));
|
|
const router = (0, express_1.Router)();
|
|
const prisma = new client_1.PrismaClient();
|
|
// Configure multer for file uploads
|
|
const upload = (0, multer_1.default)({
|
|
storage: multer_1.default.memoryStorage(),
|
|
limits: { fileSize: 50 * 1024 * 1024 }, // 50MB limit
|
|
fileFilter: (req, file, cb) => {
|
|
if (file.mimetype === 'application/pdf' || file.mimetype === 'application/json') {
|
|
cb(null, true);
|
|
}
|
|
else {
|
|
cb(new Error('Only PDF and JSON files are allowed'));
|
|
}
|
|
},
|
|
});
|
|
// Get all price books
|
|
router.get('/price-books', async (req, res) => {
|
|
try {
|
|
const priceBooks = await prisma.priceBook.findMany({
|
|
include: {
|
|
_count: {
|
|
select: { tables: true, items: true },
|
|
},
|
|
},
|
|
orderBy: { createdAt: 'desc' },
|
|
});
|
|
res.json(priceBooks);
|
|
}
|
|
catch (error) {
|
|
res.status(500).json({ error: 'Failed to fetch price books' });
|
|
}
|
|
});
|
|
// Import price book from JSON
|
|
router.post('/price-books/import-json', upload.single('file'), async (req, res) => {
|
|
try {
|
|
const file = req.file;
|
|
if (!file) {
|
|
return res.status(400).json({ error: 'No file uploaded' });
|
|
}
|
|
const data = JSON.parse(file.buffer.toString('utf-8'));
|
|
// Validate structure
|
|
if (!data.priceBook || !data.tables) {
|
|
return res.status(400).json({ error: 'Invalid JSON structure' });
|
|
}
|
|
// Check if already exists
|
|
const existing = await prisma.priceBook.findUnique({
|
|
where: { code: data.priceBook.code },
|
|
});
|
|
if (existing) {
|
|
return res.status(400).json({ error: `Price book ${data.priceBook.code} already exists` });
|
|
}
|
|
// Create price book
|
|
const priceBook = await prisma.priceBook.create({
|
|
data: {
|
|
code: data.priceBook.code,
|
|
name: data.priceBook.name,
|
|
baseDate: new Date(data.priceBook.baseDate),
|
|
approvedBy: data.priceBook.approvedBy,
|
|
effectiveDate: data.priceBook.effectiveDate ? new Date(data.priceBook.effectiveDate) : null,
|
|
},
|
|
});
|
|
let tablesCount = 0;
|
|
let itemsCount = 0;
|
|
// Create tables and items
|
|
for (const table of data.tables) {
|
|
const priceTable = await prisma.priceTable.create({
|
|
data: {
|
|
priceBookId: priceBook.id,
|
|
tableNumber: table.tableNumber,
|
|
name: table.name,
|
|
unit: table.unit,
|
|
notes: table.notes || null,
|
|
},
|
|
});
|
|
tablesCount++;
|
|
for (const item of table.items) {
|
|
await prisma.priceItem.create({
|
|
data: {
|
|
priceBookId: priceBook.id,
|
|
priceTableId: priceTable.id,
|
|
paragraph: item.paragraph,
|
|
workType: item.workType || item.networkType || item.type || `Таблица ${table.tableNumber}`,
|
|
description: item.description || null,
|
|
priceField1: item.category1Field ?? item.cat1 ?? item.undevelopedField ?? null,
|
|
priceOffice1: item.category1Office ?? item.undevelopedOffice ?? null,
|
|
priceField2: item.category2Field ?? item.cat2 ?? item.builtUpField ?? null,
|
|
priceOffice2: item.category2Office ?? item.builtUpOffice ?? null,
|
|
priceField3: item.category3Field ?? item.cat3 ?? item.industrialField ?? null,
|
|
priceOffice3: item.category3Office ?? item.industrialOffice ?? null,
|
|
priceSimple: item.price ?? item.fieldPrice ?? null,
|
|
attributes: item,
|
|
},
|
|
});
|
|
itemsCount++;
|
|
}
|
|
}
|
|
res.json({
|
|
success: true,
|
|
priceBook: {
|
|
id: priceBook.id,
|
|
code: priceBook.code,
|
|
name: priceBook.name,
|
|
},
|
|
imported: {
|
|
tables: tablesCount,
|
|
items: itemsCount,
|
|
},
|
|
});
|
|
}
|
|
catch (error) {
|
|
console.error('Import error:', error);
|
|
res.status(500).json({ error: error.message || 'Failed to import price book' });
|
|
}
|
|
});
|
|
// Delete price book
|
|
router.delete('/price-books/:id', async (req, res) => {
|
|
try {
|
|
await prisma.priceBook.delete({
|
|
where: { id: req.params.id },
|
|
});
|
|
res.status(204).send();
|
|
}
|
|
catch (error) {
|
|
res.status(400).json({ error: 'Failed to delete price book' });
|
|
}
|
|
});
|
|
// Get all coefficients (for editor, including inactive)
|
|
router.get('/coefficients', async (req, res) => {
|
|
try {
|
|
const { type } = req.query;
|
|
const where = {};
|
|
if (type)
|
|
where.type = String(type);
|
|
const coefficients = await prisma.coefficient.findMany({
|
|
where,
|
|
orderBy: [{ type: 'asc' }, { code: 'asc' }],
|
|
});
|
|
res.json(coefficients);
|
|
}
|
|
catch (error) {
|
|
res.status(500).json({ error: 'Failed to fetch coefficients' });
|
|
}
|
|
});
|
|
// Add coefficient
|
|
router.post('/coefficients', async (req, res) => {
|
|
try {
|
|
const { type, code, name, value, description, conditions } = req.body;
|
|
const coefficient = await prisma.coefficient.create({
|
|
data: {
|
|
type,
|
|
code,
|
|
name,
|
|
value: new client_1.Prisma.Decimal(value),
|
|
description,
|
|
conditions,
|
|
},
|
|
});
|
|
res.status(201).json(coefficient);
|
|
}
|
|
catch (error) {
|
|
res.status(400).json({ error: error.message || 'Failed to create coefficient' });
|
|
}
|
|
});
|
|
// Update coefficient
|
|
router.put('/coefficients/:id', async (req, res) => {
|
|
try {
|
|
const { name, value, description, conditions, isActive } = req.body;
|
|
const coefficient = await prisma.coefficient.update({
|
|
where: { id: req.params.id },
|
|
data: {
|
|
name,
|
|
value: value ? new client_1.Prisma.Decimal(value) : undefined,
|
|
description,
|
|
conditions,
|
|
isActive,
|
|
},
|
|
});
|
|
res.json(coefficient);
|
|
}
|
|
catch (error) {
|
|
res.status(400).json({ error: error.message || 'Failed to update coefficient' });
|
|
}
|
|
});
|
|
// Delete coefficient
|
|
router.delete('/coefficients/:id', async (req, res) => {
|
|
try {
|
|
await prisma.coefficient.delete({
|
|
where: { id: req.params.id },
|
|
});
|
|
res.status(204).send();
|
|
}
|
|
catch (error) {
|
|
res.status(400).json({ error: 'Failed to delete coefficient' });
|
|
}
|
|
});
|
|
// Get all inflation indices (for editor, including inactive)
|
|
router.get('/inflation-indices', async (req, res) => {
|
|
try {
|
|
const indices = await prisma.inflationIndex.findMany({
|
|
orderBy: { effectiveFrom: 'desc' },
|
|
});
|
|
res.json(indices);
|
|
}
|
|
catch (error) {
|
|
res.status(500).json({ error: 'Failed to fetch inflation indices' });
|
|
}
|
|
});
|
|
// Add inflation index
|
|
router.post('/inflation-indices', async (req, res) => {
|
|
try {
|
|
const { baseDate, effectiveFrom, effectiveTo, indexValue, documentRef } = req.body;
|
|
const index = await prisma.inflationIndex.create({
|
|
data: {
|
|
baseDate: new Date(baseDate),
|
|
effectiveFrom: new Date(effectiveFrom),
|
|
effectiveTo: effectiveTo ? new Date(effectiveTo) : null,
|
|
indexValue: new client_1.Prisma.Decimal(indexValue),
|
|
documentRef,
|
|
},
|
|
});
|
|
res.status(201).json(index);
|
|
}
|
|
catch (error) {
|
|
res.status(400).json({ error: error.message || 'Failed to create inflation index' });
|
|
}
|
|
});
|
|
// Update inflation index
|
|
router.put('/inflation-indices/:id', async (req, res) => {
|
|
try {
|
|
const { baseDate, effectiveFrom, effectiveTo, indexValue, documentRef, isActive } = req.body;
|
|
const data = {};
|
|
if (baseDate != null)
|
|
data.baseDate = new Date(baseDate);
|
|
if (effectiveFrom != null)
|
|
data.effectiveFrom = new Date(effectiveFrom);
|
|
if (effectiveTo !== undefined)
|
|
data.effectiveTo = effectiveTo ? new Date(effectiveTo) : null;
|
|
if (indexValue != null)
|
|
data.indexValue = new client_1.Prisma.Decimal(indexValue);
|
|
if (documentRef !== undefined)
|
|
data.documentRef = documentRef;
|
|
if (isActive !== undefined)
|
|
data.isActive = isActive;
|
|
const index = await prisma.inflationIndex.update({
|
|
where: { id: req.params.id },
|
|
data,
|
|
});
|
|
res.json(index);
|
|
}
|
|
catch (error) {
|
|
res.status(400).json({ error: error.message || 'Failed to update inflation index' });
|
|
}
|
|
});
|
|
// Delete inflation index
|
|
router.delete('/inflation-indices/:id', async (req, res) => {
|
|
try {
|
|
await prisma.inflationIndex.delete({
|
|
where: { id: req.params.id },
|
|
});
|
|
res.status(204).send();
|
|
}
|
|
catch (error) {
|
|
res.status(400).json({ error: 'Failed to delete inflation index' });
|
|
}
|
|
});
|
|
// Database stats
|
|
router.get('/stats', async (req, res) => {
|
|
try {
|
|
const [priceBooks, tables, items, coefficients, estimates, sessions] = await Promise.all([
|
|
prisma.priceBook.count(),
|
|
prisma.priceTable.count(),
|
|
prisma.priceItem.count(),
|
|
prisma.coefficient.count(),
|
|
prisma.estimate.count(),
|
|
prisma.chatSession.count(),
|
|
]);
|
|
res.json({
|
|
priceBooks,
|
|
tables,
|
|
items,
|
|
coefficients,
|
|
estimates,
|
|
sessions,
|
|
});
|
|
}
|
|
catch (error) {
|
|
res.status(500).json({ error: 'Failed to fetch stats' });
|
|
}
|
|
});
|
|
exports.default = router;
|
|
//# sourceMappingURL=admin.js.map
|