98 lines
3.9 KiB
JavaScript
98 lines
3.9 KiB
JavaScript
const http = require('http');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const PORT = process.env.PORT || 3000;
|
||
const DATA_FILE = path.join(__dirname, 'data.json');
|
||
|
||
function readData() {
|
||
try { return JSON.parse(fs.readFileSync(DATA_FILE, 'utf8')); }
|
||
catch (_) { return []; }
|
||
}
|
||
function writeData(arr) { fs.writeFileSync(DATA_FILE, JSON.stringify(arr, null, 2)); }
|
||
|
||
// Mock functions – replace with real integrations later
|
||
function extractRequest(reqBody) {
|
||
// Expect fields: initiator, object, area, termMonths, price (optional)
|
||
return reqBody;
|
||
}
|
||
function getTariffFromSAP(object) {
|
||
// Mock: return 4800 per m2
|
||
return 4800;
|
||
}
|
||
function generateContract(data) {
|
||
const { initiator, object, area, termMonths, price } = data;
|
||
const total = area * price * termMonths;
|
||
return `Договор аренды\nСтороны: ${initiator} и ОЦО ЮС\nОбъект: ${object}\nПлощадь: ${area} м²\nСрок: ${termMonths} мес.\nТариф: ${price} ₸/м²\nСумма: ${total} ₸`;
|
||
}
|
||
function checkCompliance(contract, tariff) {
|
||
const flags = [];
|
||
// Simple rule: price must not be lower than tariff
|
||
const priceMatch = contract.match(/Тариф: (\d+) /);
|
||
if (priceMatch && Number(priceMatch[1]) < tariff) {
|
||
flags.push({ type: 'tariff', message: `Тариф ниже актуального (${priceMatch[1]} < ${tariff})` });
|
||
}
|
||
// Add more checks later
|
||
return flags;
|
||
}
|
||
function compareWithCounterparty(version) {
|
||
// Mock: assume two deviations
|
||
return [{ clause: 'Пункт 3', diff: 'Изменена площадь' }, { clause: 'Пункт 7', diff: 'Срок аренды 12 мес → 24 мес' }];
|
||
}
|
||
|
||
const server = http.createServer(async (req, res) => {
|
||
const url = req.url.split('?')[0];
|
||
// API: create contract from Lotus request (mocked POST /api/contract)
|
||
if (req.method === 'POST' && url === '/api/contract') {
|
||
let body = '';
|
||
req.on('data', chunk => body += chunk);
|
||
req.on('end', () => {
|
||
try {
|
||
const json = JSON.parse(body);
|
||
const requestData = extractRequest(json);
|
||
// validate required fields
|
||
const missing = [];
|
||
['initiator','object','area','termMonths'].forEach(f => { if (!requestData[f]) missing.push(f); });
|
||
if (missing.length) {
|
||
res.writeHead(400, {'Content-Type':'application/json'});
|
||
return res.end(JSON.stringify({error:'Missing fields', missing}));
|
||
}
|
||
// price from request or tariff
|
||
const tariff = getTariffFromSAP(requestData.object);
|
||
const price = requestData.price || tariff;
|
||
const contract = generateContract({ ...requestData, price });
|
||
const flags = checkCompliance(contract, tariff);
|
||
const deviations = requestData.counterpartyVersion ? compareWithCounterparty(requestData.counterpartyVersion) : [];
|
||
const record = { id: Date.now(), request: requestData, contract, tariff, price, flags, deviations };
|
||
const data = readData();
|
||
data.push(record);
|
||
writeData(data);
|
||
res.writeHead(200, {'Content-Type':'application/json'});
|
||
res.end(JSON.stringify({ok:true, record}));
|
||
} catch (e) {
|
||
res.writeHead(500, {'Content-Type':'application/json'});
|
||
res.end(JSON.stringify({error:e.message}));
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
// Serve static files
|
||
let filePath = url === '/' ? '/index.html' : url;
|
||
const fullPath = path.join(__dirname, filePath);
|
||
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
|
||
const ext = path.extname(fullPath);
|
||
const mime = {
|
||
'.html':'text/html',
|
||
'.css':'text/css',
|
||
'.js':'application/javascript',
|
||
'.json':'application/json'
|
||
}[ext] || 'application/octet-stream';
|
||
res.writeHead(200, {'Content-Type': mime + '; charset=utf-8'});
|
||
res.end(fs.readFileSync(fullPath));
|
||
return;
|
||
}
|
||
res.writeHead(404); res.end('Not found');
|
||
});
|
||
|
||
server.listen(PORT, () => console.log('Server listening on port ' + PORT));
|