aggiornamenti vari. prima di VITE
This commit is contained in:
27
src/server/config/database-sqlsrv.js.off
Normal file
27
src/server/config/database-sqlsrv.js.off
Normal file
@@ -0,0 +1,27 @@
|
||||
require("dotenv").config();
|
||||
const { Sequelize } = require("sequelize");
|
||||
|
||||
const sequelize = new Sequelize(process.env.DB_DATABASE_SQLSRVTEST, process.env.DB_USERNAME_SQLSRVTEST, process.env.DB_PASSWORD_SQLSRVTEST, {
|
||||
host: process.env.DB_HOST_SQLSRVTEST || "localhost",
|
||||
port: process.env.DB_PORT_SQLSRVTEST || 1433,
|
||||
dialect: "mssql",
|
||||
dialectOptions: {
|
||||
options: {
|
||||
encrypt: false, // Cambia a true se usi SSL
|
||||
},
|
||||
},
|
||||
logging: false, // Disabilita il logging delle query
|
||||
});
|
||||
|
||||
async function testConnection() {
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
console.log("Connessione al database riuscita!");
|
||||
} catch (error) {
|
||||
console.error("Errore nella connessione al database:", error);
|
||||
}
|
||||
}
|
||||
|
||||
testConnection();
|
||||
|
||||
module.exports = sequelize;
|
||||
460
src/server/controllers/articleController.js
Normal file
460
src/server/controllers/articleController.js
Normal file
@@ -0,0 +1,460 @@
|
||||
const axios = require('axios');
|
||||
|
||||
const server_constants = require('../tools/server_constants');
|
||||
|
||||
const shared_consts = require('../tools/shared_nodejs');
|
||||
|
||||
const SERVER_A_URL = process.env.SERVER_A_URL || "http://IP_DI_SERVER_A:3000";
|
||||
const API_KEY = process.env.API_KEY_MSSQL;
|
||||
|
||||
// Funzione per ottenere i dati
|
||||
const getArticlesSales = async () => {
|
||||
try {
|
||||
const query = `
|
||||
SELECT
|
||||
a.IdArticolo, a.Titolo, a.DataPubblicazione, a.Ean13 AS isbn,
|
||||
a.IdCollana, y.DescrizioneCollana, i2.DescrArgomento, a.ListaArgomenti,
|
||||
a.Pagine, a.IdTipoFormato, a.Misure,
|
||||
COALESCE(o.totVen, 0) as totVen, COALESCE(u.totFat, 0) as totFat,
|
||||
COALESCE(p.rank3M, 0) as rank3M, COALESCE(t.fatrank3M, 0) as fatrank3M,
|
||||
COALESCE(q.rank6M, 0) as rank6M, COALESCE(r.rank1Y, 0) as rank1Y,
|
||||
COALESCE(t.fat3mesi, 0) as fatLast3M, COALESCE(p.venduti3mesi, 0) as vLast3M,
|
||||
COALESCE(q.venduti6mesi, 0) as vLast6M, COALESCE(r.venduti1anno, 0) as vLastY,
|
||||
s.ultimoOrdine as dataUltimoOrdine
|
||||
FROM T_WEB_Articoli a
|
||||
LEFT JOIN (SELECT CodArticoloGM, SUM(Qta) as totVen FROM T_WEB_Ordini GROUP BY CodArticoloGM) o
|
||||
ON a.IdArticolo = o.CodArticoloGM
|
||||
LEFT JOIN (SELECT CodArticolo, SUM(TRY_CAST(Qta AS INT)) as totFat FROM T_WEB_ArticoliFatturati WHERE ISNUMERIC(Qta) = 1 GROUP BY CodArticolo) u
|
||||
ON a.IdArticolo = u.CodArticolo
|
||||
WHERE a.IdStatoProdotto IS NOT NULL
|
||||
ORDER BY totVen DESC;
|
||||
`;
|
||||
|
||||
const response = await axios.post(SERVER_A_URL + '/query', { query }, {
|
||||
headers: { 'x-api-key': API_KEY }
|
||||
});
|
||||
|
||||
return response.data || [];
|
||||
|
||||
} catch (error) {
|
||||
console.error("Errore nel recupero degli articoli:", error);
|
||||
throw new Error("Errore nel recupero degli articoli venduti.");
|
||||
}
|
||||
};
|
||||
|
||||
// Endpoint per ottenere i dati in formato JSON
|
||||
exports.getArticlesSalesHandler = async (req, res) => {
|
||||
try {
|
||||
const data = await getArticlesSales();
|
||||
if (!data.length) return res.status(404).json({ message: "Nessun articolo trovato." });
|
||||
res.json(data);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
// Endpoint per esportare i dati come file JSON
|
||||
exports.exportArticlesSalesByJSON = async (req, res) => {
|
||||
try {
|
||||
const data = await getArticlesSales();
|
||||
if (!data.length) return res.status(404).json({ message: "Nessun articolo trovato." });
|
||||
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
res.setHeader("Content-Disposition", `attachment; filename="ranking_articles_${new Date().toISOString().split('T')[0]}.json"`);
|
||||
res.json(data);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
const formatDate = (dateValue) => {
|
||||
const date = new Date(dateValue);
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const year = date.getFullYear();
|
||||
return `${day}/${month}/${year}`;
|
||||
};
|
||||
|
||||
const getTableContent = async (options) => {
|
||||
try {
|
||||
// Verifica se la tabella esiste
|
||||
const checkTableQuery = `SELECT COUNT(*) as tableExists FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '${options.nameTable}'`;
|
||||
const checkResponse = await axios.post(SERVER_A_URL + '/query', { query: checkTableQuery }, {
|
||||
headers: { 'x-api-key': API_KEY }
|
||||
});
|
||||
if (!checkResponse.data || checkResponse.data.length === 0 || checkResponse.data[0].tableExists === 0) {
|
||||
return `La tabella '${options.nameTable}' non esiste.`;
|
||||
}
|
||||
|
||||
// Recupera le colonne della tabella principale dal catalogo
|
||||
const columnsQuery = `SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '${options.nameTable}'`;
|
||||
const columnsResponse = await axios.post(SERVER_A_URL + '/query', { query: columnsQuery }, {
|
||||
headers: { 'x-api-key': API_KEY }
|
||||
});
|
||||
const tableColumns = columnsResponse.data.map(col => col.COLUMN_NAME);
|
||||
|
||||
// Mappatura per unire i campi (ID e Descrizione)
|
||||
const mergedMapping = {
|
||||
"IdStatoProdotto": "DescrizioneStatoProdotto",
|
||||
"IdTipologia": "DescrizioneTipologia",
|
||||
"IdTipoFormato": "DescrizioneFormato",
|
||||
"IdCollana": "DescrizioneCollana",
|
||||
"ListaArgomenti": "DescrArgomento",
|
||||
"ListaAutori": "AutoriCompleti",
|
||||
"IdMarchioEditoriale": "CasaEditrice",
|
||||
};
|
||||
|
||||
// Costruisce la query per recuperare i record
|
||||
let dataQuery = "";
|
||||
|
||||
let columnsToShow = 'T.*';
|
||||
if (options.fieldGM) {
|
||||
columnsToShow = 'T.' + options.fieldGM;
|
||||
}
|
||||
|
||||
if (options.nameTable.toLowerCase() === 't_web_articoli') {
|
||||
if (true) {
|
||||
dataQuery = `
|
||||
SELECT TOP ${options.numrec}
|
||||
${columnsToShow}
|
||||
` + (options.campispeciali ? `
|
||||
,f.DescrizioneStatoProdotto
|
||||
,i.DescrizioneTipologia
|
||||
,n.DescrizioneFormato
|
||||
,y.DescrizioneCollana
|
||||
,z.AutoriCompleti
|
||||
,i2.DescrArgomento
|
||||
,z3.CasaEditrice` : ``) + (options.showQtaDisponibile ? ` ,q.QtaDisponibile ` : ``) +
|
||||
` FROM T_WEB_Articoli T
|
||||
JOIN(
|
||||
SELECT IdArticolo, MAX(DataOra) AS data
|
||||
FROM T_WEB_Articoli
|
||||
GROUP BY IdArticolo
|
||||
) b ON T.IdArticolo = b.IdArticolo AND T.DataOra = b.data `
|
||||
+ (options.campispeciali ?
|
||||
` LEFT JOIN(
|
||||
SELECT e.IdStatoProdotto, e.Descrizione as DescrizioneStatoProdotto
|
||||
FROM T_WEB_StatiProdotto e
|
||||
JOIN(
|
||||
SELECT IdStatoProdotto, MAX(DataOra) as data1
|
||||
FROM T_WEB_StatiProdotto
|
||||
GROUP BY IdStatoProdotto
|
||||
) c ON e.IdStatoProdotto = c.IdStatoProdotto AND e.DataOra = c.data1
|
||||
) f ON T.IdStatoProdotto = f.IdStatoProdotto
|
||||
LEFT JOIN(
|
||||
SELECT g.IdTipologia, g.Descrizione as DescrizioneTipologia
|
||||
FROM T_WEB_Tipologie g
|
||||
JOIN(
|
||||
SELECT IdTipologia, MAX(DataOra) as data1
|
||||
FROM T_WEB_Tipologie
|
||||
GROUP BY IdTipologia
|
||||
) h ON g.IdTipologia = h.IdTipologia AND g.DataOra = h.data1
|
||||
) i ON T.IdTipologia = i.IdTipologia
|
||||
LEFT JOIN(
|
||||
SELECT l.IdTipoFormato, l.Descrizione as DescrizioneFormato
|
||||
FROM T_WEB_TipiFormato l
|
||||
JOIN(
|
||||
SELECT IdTipoFormato, MAX(DataOra) as data1
|
||||
FROM T_WEB_TipiFormato
|
||||
GROUP BY IdTipoFormato
|
||||
) m ON l.IdTipoFormato = m.IdTipoFormato AND l.DataOra = m.data1
|
||||
) n ON T.IdTipoFormato = n.IdTipoFormato
|
||||
LEFT JOIN(
|
||||
SELECT v.IdCollana, v.Descrizione as DescrizioneCollana
|
||||
FROM T_WEB_Collane v
|
||||
INNER JOIN(
|
||||
SELECT IdCollana, MAX(ID) as MaxID
|
||||
FROM T_WEB_Collane
|
||||
GROUP BY IdCollana
|
||||
) x ON v.IdCollana = x.IdCollana AND v.ID = x.MaxID
|
||||
) y ON T.IdCollana = y.IdCollana
|
||||
LEFT JOIN(
|
||||
SELECT g2.IdArgomento, g2.Descrizione as DescrArgomento
|
||||
FROM T_WEB_Argomenti g2
|
||||
INNER JOIN(
|
||||
SELECT IdArgomento, MAX(DataOra) as data12
|
||||
FROM T_WEB_Argomenti
|
||||
GROUP BY IdArgomento
|
||||
) h ON g2.IdArgomento = h.IdArgomento AND g2.DataOra = h.data12
|
||||
) i2 ON T.ListaArgomenti = i2.IdArgomento
|
||||
LEFT JOIN(
|
||||
SELECT
|
||||
T1.IdArticolo,
|
||||
STUFF((
|
||||
SELECT ',' + ISNULL(A2.AutoreCompleto, '')
|
||||
FROM(
|
||||
SELECT CAST('<root><x>' + REPLACE(T1.ListaAutori, ',', '</x><x>') + '</x></root>' AS XML) AS DataXML
|
||||
) X
|
||||
CROSS APPLY X.DataXML.nodes('/root/x') AS A(x)
|
||||
CROSS APPLY(
|
||||
SELECT TRY_CAST(LTRIM(RTRIM(A.x.value('.', 'VARCHAR(100)'))) AS INT) AS AutoreID
|
||||
) CA
|
||||
JOIN(
|
||||
SELECT a.IdAutore, CONCAT(a.Nome, ' ', a.Cognome) AS AutoreCompleto
|
||||
FROM T_WEB_Autori a
|
||||
JOIN(
|
||||
SELECT IdAutore, MAX(DataOra) AS maxData
|
||||
FROM T_WEB_Autori
|
||||
GROUP BY IdAutore
|
||||
) aa ON a.IdAutore = aa.IdAutore AND a.DataOra = aa.maxData
|
||||
) A2 ON CA.AutoreID = A2.IdAutore
|
||||
FOR XML PATH(''), TYPE
|
||||
).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS AutoriCompleti
|
||||
FROM T_WEB_Articoli T1
|
||||
GROUP BY T1.IdArticolo, T1.ListaAutori
|
||||
) z ON T.IdArticolo = z.IdArticolo
|
||||
LEFT JOIN(
|
||||
SELECT a3.IdMarchioEditoriale, a3.Descrizione as CasaEditrice
|
||||
FROM T_WEB_MarchiEditoriali a3
|
||||
JOIN(
|
||||
SELECT IdMarchioEditoriale, MAX(DataOra) as maxData
|
||||
FROM T_WEB_MarchiEditoriali
|
||||
GROUP BY IdMarchioEditoriale
|
||||
) aa3 ON a3.IdMarchioEditoriale = aa3.IdMarchioEditoriale AND a3.DataOra = aa3.maxData
|
||||
) z3 ON T.IdMarchioEditoriale = z3.IdMarchioEditoriale `
|
||||
: ``)
|
||||
+ (options.showQtaDisponibile ?
|
||||
` LEFT JOIN(
|
||||
SELECT o.Codice, o.QtaDisponibile
|
||||
FROM T_WEB_Disponibile o
|
||||
JOIN(
|
||||
SELECT Codice, MAX(DataOra) as data1
|
||||
FROM T_WEB_Disponibile
|
||||
GROUP BY Codice
|
||||
) p ON o.Codice = p.Codice AND o.DataOra = p.data1
|
||||
) q ON T.IdArticolo = q.Codice` : ``)
|
||||
} else {
|
||||
dataQuery += `
|
||||
SELECT TOP ${options.numrec}
|
||||
T.*
|
||||
FROM T_WEB_Articoli T
|
||||
JOIN(
|
||||
SELECT IdArticolo, MAX(DataOra) AS data
|
||||
FROM T_WEB_Articoli
|
||||
GROUP BY IdArticolo
|
||||
) b ON T.IdArticolo = b.IdArticolo AND T.DataOra = b.data
|
||||
`;
|
||||
}
|
||||
} else {
|
||||
dataQuery = `SELECT TOP ${options.numrec} * FROM ${options.nameTable} `;
|
||||
}
|
||||
if (options.where && options.where.trim() !== "") {
|
||||
dataQuery += ` WHERE ${options.where} `;
|
||||
}
|
||||
|
||||
// Esegue la query per recuperare i dati
|
||||
console.log('dataQuery', dataQuery);
|
||||
const dataResponse = await axios.post(SERVER_A_URL + '/query', { query: dataQuery }, {
|
||||
headers: { 'x-api-key': API_KEY }
|
||||
});
|
||||
const records = dataResponse.data;
|
||||
if (!records || records.length === 0) {
|
||||
return `Nessun record trovato nella tabella '${options.nameTable}'.`;
|
||||
}
|
||||
|
||||
// Determina quali colonne visualizzare.
|
||||
let displayColumns;
|
||||
if (options.nameTable.toLowerCase() === 't_web_articoli') {
|
||||
// Usa tutte le proprietà del record, escludendo le colonne dei campi uniti (quelle usate per il merge)
|
||||
displayColumns = Object.keys(records[0]).filter(col => !Object.values(mergedMapping).includes(col));
|
||||
} else {
|
||||
displayColumns = tableColumns;
|
||||
}
|
||||
|
||||
// Funzione per ottenere il valore da visualizzare, fondendo i campi se presente nella mappatura
|
||||
const getDisplayValue = (record, col) => {
|
||||
let value = record[col] ?? 'NULL';
|
||||
// Format date solo se il nome della colonna indica una data/ora
|
||||
if ((col.toLowerCase().includes("data") || col.toLowerCase().includes("ora")) && value !== 'NULL') {
|
||||
if (value.includes(',')) {
|
||||
// Se ci sono più valori separati da virgola, formatta ciascuno se è una data valida
|
||||
value = value.split(',')
|
||||
.map(item => {
|
||||
const trimmed = item.trim();
|
||||
const parsed = Date.parse(trimmed);
|
||||
return !isNaN(parsed) ? formatDate(trimmed) : trimmed;
|
||||
})
|
||||
.join(', ');
|
||||
} else {
|
||||
const parsed = Date.parse(value);
|
||||
if (!isNaN(parsed)) {
|
||||
value = formatDate(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mergedMapping[col]) {
|
||||
return `${record[mergedMapping[col]] || ''} (${value})`;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
// Costruisce l'output HTML
|
||||
let output = "";
|
||||
if (options.outhtml) {
|
||||
if (records.length === 1) {
|
||||
// Se c'è un solo record, visualizza una lista di chiavi e valori
|
||||
const record = records[0];
|
||||
output += `
|
||||
< table border = '1' style = "border-collapse: collapse; width: 50%;" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="padding: 8px; background-color: #f2f2f2;">Campo</th>
|
||||
<th style="padding: 8px; background-color: #f2f2f2;">Valore</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
displayColumns.forEach(column => {
|
||||
output += `
|
||||
<tr>
|
||||
<td style="padding: 8px;">${column}</td>
|
||||
<td style="padding: 8px;">${getDisplayValue(record, column)}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
output += `
|
||||
</tbody>
|
||||
</table >
|
||||
`;
|
||||
} else {
|
||||
// Se ci sono più record, visualizza una tabella con intestazioni
|
||||
output += "<table border='1' style='border-collapse: collapse; width: 100%;'><thead><tr>";
|
||||
displayColumns.forEach(column => {
|
||||
output += `< th style = "padding: 8px; background-color: #f2f2f2;" > ${column}</th > `;
|
||||
});
|
||||
output += "</tr></thead><tbody>";
|
||||
records.forEach(record => {
|
||||
output += "<tr>";
|
||||
displayColumns.forEach(column => {
|
||||
output += `< td style = "padding: 8px;" > ${getDisplayValue(record, column)}</td > `;
|
||||
});
|
||||
output += "</tr>";
|
||||
});
|
||||
output += "</tbody></table>";
|
||||
}
|
||||
} else {
|
||||
// solo dati
|
||||
output = {};
|
||||
|
||||
if (options.fieldGM) {
|
||||
if (records && records.length === 1) {
|
||||
output[options.fieldGM] = records[0][options.fieldGM];
|
||||
}
|
||||
} else {
|
||||
output = [];
|
||||
records.forEach(record => {
|
||||
let myrec = {}
|
||||
|
||||
displayColumns.forEach(column => {
|
||||
myrec[column] = `${getDisplayValue(record, column)} `;
|
||||
});
|
||||
output.push(myrec)
|
||||
});
|
||||
}
|
||||
}
|
||||
return output;
|
||||
|
||||
} catch (error) {
|
||||
console.error("Errore nel recupero della tabella: ", error.message);
|
||||
if (options.outhtml) {
|
||||
output = `
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Errore nel Recupero della Tabella ${options.nameTable}</title>
|
||||
<style>
|
||||
body {
|
||||
font - family: Arial, sans-serif;
|
||||
background-color: #f7f7f7;
|
||||
color: #333;
|
||||
padding: 20px;
|
||||
}
|
||||
.error-container {
|
||||
background - color: #ffe6e6;
|
||||
border: 1px solid #ff4d4d;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
}
|
||||
.error-title {
|
||||
font - size: 24px;
|
||||
font-weight: bold;
|
||||
color: #d8000c;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.error-message {
|
||||
font - size: 16px;
|
||||
white-space: pre-wrap;
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="error-container">
|
||||
<div class="error-title">Errore nel Recupero della Tabella ${options.nameTable} con query: ${options.where}</div>
|
||||
<div class="error-message">
|
||||
${error.response.data.error || error.stack || error.message}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
}
|
||||
return output;
|
||||
// throw new Error("Errore nel recupero della tabella.");
|
||||
}
|
||||
};
|
||||
|
||||
// Endpoint per mostrare i dati della tabella
|
||||
exports.viewTable = async (req, res) => {
|
||||
try {
|
||||
const options = req.body.options;
|
||||
const tableContent = await getTableContent(options);
|
||||
|
||||
let out = {};
|
||||
|
||||
if (options.outhtml) {
|
||||
out = `
|
||||
<h2>Tabella: ${options.nameTable}</h2>
|
||||
${tableContent}
|
||||
`
|
||||
} else {
|
||||
out = tableContent;
|
||||
}
|
||||
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, data: out });
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error: ', error);
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, error });
|
||||
}
|
||||
};
|
||||
|
||||
// Endpoint per mostrare i dati della tabella
|
||||
exports.queryTable = async (req, res) => {
|
||||
try {
|
||||
const options = req.body.options;
|
||||
const tableContent = await getTableContent(options);
|
||||
|
||||
let out = {};
|
||||
|
||||
if (options.outhtml) {
|
||||
out = `
|
||||
<h2>Tabella: ${options.nameTable}</h2>
|
||||
${tableContent}
|
||||
`
|
||||
} else {
|
||||
out = tableContent;
|
||||
}
|
||||
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, data: out });
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error: ', error);
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, error });
|
||||
}
|
||||
};
|
||||
@@ -313,6 +313,84 @@ module.exports.replaceProductImgToImageFile = async function (abilitaserver) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {Object} Article
|
||||
* @property {bigint} Id
|
||||
* @property {number} IdArticolo
|
||||
* @property {string} Ean13
|
||||
* @property {string} Titolo
|
||||
* @property {string} ListaAutori
|
||||
* @property {string} ListaArgomenti
|
||||
* @property {number} IdStatoProdotto
|
||||
* @property {number} PrezzoIvato
|
||||
* @property {number} IdMarchioEditoriale
|
||||
* @property {number} IdCollana
|
||||
* @property {Date} DataPubblicazione
|
||||
* @property {number} IdTipologia
|
||||
* @property {number} IdTipoFormato
|
||||
* @property {string} Misure
|
||||
* @property {string} Pagine
|
||||
* @property {string} Sottotitolo
|
||||
* @property {string} Durata
|
||||
* @property {string} Numero
|
||||
* @property {string} Edizione
|
||||
* @property {string} Ristampa
|
||||
* @property {Date} DataInizioCampagna
|
||||
* @property {Date} DataFineCampagna
|
||||
* @property {number} ScontoCampagna
|
||||
* @property {number} PrezzoIvatoScontatoCampagna
|
||||
* @property {Date} DataOra
|
||||
* @property {boolean} Enabled
|
||||
* @property {number} IDTagGruppo
|
||||
* @property {string} Utente
|
||||
* @property {number} PercIva
|
||||
* @property {number} IdTitoloOriginale
|
||||
* @property {boolean} EnabledAlFresco
|
||||
* @property {number} CodEdizione
|
||||
* @property {string} FasciaEta
|
||||
* @property {string} DescrizioneStatoProdotto
|
||||
* @property {string} DescrizioneTipologia
|
||||
* @property {string} DescrizioneFormato
|
||||
* @property {string} DescrizioneCollana
|
||||
* @property {string} DescrArgomento
|
||||
* @property {string} AutoriCompleti
|
||||
* @property {string} CasaEditrice
|
||||
*/
|
||||
|
||||
/**
|
||||
* Aggiorna il prodotto basandosi su un articolo
|
||||
* @param {Article} article - Dati dell'articolo da aggiornare
|
||||
* @param {boolean} creanew
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
module.exports.aggiornaProductFromGMArticle = async function (article, creanew) {
|
||||
|
||||
const ProductInfo = this;
|
||||
|
||||
try {
|
||||
if (article) {
|
||||
// cerca se esiste sul db locale
|
||||
|
||||
let findrec = this.find({ sku: article.IdArticolo }).lean();
|
||||
if (findrec) {
|
||||
// Articolo Trovato !
|
||||
} else {
|
||||
// articolo inesistente, lo vuoi creare ?
|
||||
if (creanew) {
|
||||
findrec = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (findrec) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error('Error aggiornaProductFromGMArticle:', err);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.correggiProductTypes = async function () {
|
||||
const ProductInfo = this;
|
||||
const bulkOps = [];
|
||||
|
||||
@@ -241,9 +241,12 @@ sendNotifSchema.statics.getDescrAndLinkByRecNotif = async function (recnotif, us
|
||||
tag = 'newhosp';
|
||||
tablerec = 'myhosps';
|
||||
}
|
||||
let eventobj = await tools.getAnnuncioForTelegram(recnotif.myrectableorig, tablerec, mydescr, userorig, true);
|
||||
// newdescr = eventobj.descrperNotif;
|
||||
recnotif.textcontent_Telegram = eventobj.newdescrtelegram;
|
||||
if (recnotif.myrectableorig) {
|
||||
let eventobj = await tools.getAnnuncioForTelegram(recnotif.myrectableorig, tablerec, mydescr, userorig, true);
|
||||
recnotif.textcontent_Telegram = eventobj.newdescrtelegram;
|
||||
} else {
|
||||
recnotif.textcontent_Telegram = newdescr;
|
||||
}
|
||||
recnotif.linkaddTelegram = '';
|
||||
} else if (recnotif.typedir === shared_consts.TypeNotifs.TYPEDIR_EVENTS) {
|
||||
recnotif.openUrl = shared_consts.getDirectoryByTable(shared_consts.TABLES_MYBACHECAS, true) + myidrec;
|
||||
|
||||
@@ -1062,9 +1062,11 @@ router.post('/import', authenticate, async (req, res) => {
|
||||
if (!recmacro.isbn) {
|
||||
recmacro.isbn = recrankingisbn.isbn;
|
||||
}
|
||||
// Se Pagine non sono state settate
|
||||
if ((!recmacro.Pagine || recmacro.Pagine === 0) && recrankingisbn.Pagine)
|
||||
recmacro.Pagine = recrankingisbn.Pagine;
|
||||
|
||||
// Se misure non sono state settate
|
||||
if (!recmacro.misure && recrankingisbn.misure) {
|
||||
recmacro.misure = recrankingisbn.misure;
|
||||
}
|
||||
@@ -1194,12 +1196,12 @@ router.post('/import', authenticate, async (req, res) => {
|
||||
|
||||
productInfo.name = productInfo.name.replace(/ - Usato$| - Nuovo$| - Epub$| - Ebook$| - Mobi$| - DVD$| - Streaming$| - Download$/, "");
|
||||
|
||||
const recrankingisbn = await ImportaIsbn.findOne({ sku: product.sku }).lean();
|
||||
|
||||
let reccateg = null;
|
||||
|
||||
if (product.categories) {
|
||||
// Verifica prima se questa categoria è stata aggiornata !
|
||||
const recrankingisbn = await ImportaIsbn.findOne({ sku: product.sku }).lean();
|
||||
if (recrankingisbn && recrankingisbn.DescrArgomento) {
|
||||
|
||||
if (tools.isArray(recrankingisbn.ListaArgomenti) && recrankingisbn.ListaArgomenti.length > 1) {
|
||||
@@ -1346,7 +1348,6 @@ router.post('/import', authenticate, async (req, res) => {
|
||||
product.active = true;
|
||||
}
|
||||
|
||||
|
||||
// Update ProductInfo
|
||||
let risrecInfo = await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: productInfo }, { new: true, upsert: true });
|
||||
if (risrecInfo) {
|
||||
@@ -1427,6 +1428,23 @@ router.post('/import', authenticate, async (req, res) => {
|
||||
variazione.quantita = arrvariazioni[ind].quantita;
|
||||
}
|
||||
|
||||
// *** CONTROLLA SE AGGIORNARE O MENO DETERMINATI CAMPI CHE SONO STATI GIA' SETTATI
|
||||
if (recrankingisbn) {
|
||||
if (product.misure !== recrankingisbn.misure && recrankingisbn.misure) {
|
||||
product.misure = recrankingisbn.misure;
|
||||
}
|
||||
if (product.formato !== recrankingisbn.formato && recrankingisbn.formato) {
|
||||
product.formato = recrankingisbn.formato;
|
||||
}
|
||||
if (product.Pagine !== recrankingisbn.Pagine && recrankingisbn.Pagine) {
|
||||
product.Pagine = recrankingisbn.Pagine;
|
||||
}
|
||||
if (product.Edizione !== recrankingisbn.Edizione && recrankingisbn.Edizione) {
|
||||
product.Edizione = recrankingisbn.Edizione;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
variazione.active = true; // ++ ??
|
||||
variazione.versione = versione;
|
||||
variazione.versione = versione;
|
||||
|
||||
15
src/server/router/articleRoutes.js
Normal file
15
src/server/router/articleRoutes.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const express = require("express");
|
||||
const { getArticlesSalesHandler, exportArticlesSalesByJSON, viewTable, queryTable } = require("../controllers/articleController");
|
||||
const { authenticate } = require("../middleware/authenticate");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.post("/articles-sales", authenticate, getArticlesSalesHandler);
|
||||
|
||||
router.post("/export-articles-sales-json", authenticate, exportArticlesSalesByJSON);
|
||||
|
||||
router.post("/view-table", authenticate, viewTable);
|
||||
router.post("/query", authenticate, queryTable);
|
||||
|
||||
|
||||
module.exports = router;
|
||||
@@ -703,7 +703,7 @@ router.post('/getobj', authenticate_noerror, async (req, res) => {
|
||||
res.status(200).send({ code: server_constants.RIS_CODE_OK, data: ris });
|
||||
|
||||
} catch (e) {
|
||||
console.error(`ERROR getobj ${cmd}: `, e.message);
|
||||
console.error(`ERROR getobj`, e.message);
|
||||
res.status(200).send({ code: server_constants.RIS_CODE_OK, data: [] });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -938,7 +938,7 @@ module.exports = {
|
||||
if (user.lastid_newstosent !== id_newstosent.toString()) {
|
||||
// console.log('@@@@@ COMPARE DIVERSI: lastid', user.lastid_newstosent, 'idsent', id_newstosent.toString());
|
||||
|
||||
if (process.env.DEBUG)
|
||||
if (process.env.VITE_DEBUG)
|
||||
await tools.snooze(5000);
|
||||
|
||||
// Send Email to the User
|
||||
|
||||
@@ -142,6 +142,7 @@ myLoad().then(ris => {
|
||||
const mygoods_router = require('./router/mygoods_router');
|
||||
const mygen_router = require('./router/mygen_router');
|
||||
const aitools_router = require('./router/aitools_router');
|
||||
const article_router = require('./router/articleRoutes');
|
||||
|
||||
const { MyEvent } = require('./models/myevent');
|
||||
|
||||
@@ -262,6 +263,7 @@ myLoad().then(ris => {
|
||||
app.use('/mygoods', mygoods_router);
|
||||
app.use('/mygen', mygen_router);
|
||||
app.use('/aitools', aitools_router);
|
||||
app.use('/apisqlsrv', article_router);
|
||||
|
||||
|
||||
mystart();
|
||||
@@ -302,7 +304,7 @@ async function mystart() {
|
||||
}
|
||||
|
||||
mycron();
|
||||
if (!process.env.DEBUG) {
|
||||
if (!process.env.VITE_DEBUG) {
|
||||
mycron();
|
||||
}
|
||||
}
|
||||
@@ -427,14 +429,14 @@ function testmsgwebpush() {
|
||||
// Cron every X minutes
|
||||
cron.schedule('*/1 * * * *', () => {
|
||||
// console.log('Running Cron Job');
|
||||
// if (!process.env.DEBUG) {
|
||||
// if (!process.env.VITE_DEBUG) {
|
||||
mycron();
|
||||
// }
|
||||
});
|
||||
|
||||
// Cron every X minutes
|
||||
cron.schedule('*/60 * * * *', async () => {
|
||||
if (!process.env.DEBUG) {
|
||||
if (!process.env.VITE_DEBUG) {
|
||||
mycron_30min();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1653,7 +1653,7 @@ class Telegram {
|
||||
|
||||
let risp = '';
|
||||
const id = msg.chat.id;
|
||||
let testo = msg.text.toLowerCase().trim();
|
||||
let testo = msg.text?.toLowerCase()?.trim();
|
||||
testo = testo.replace('!', '');
|
||||
testo = testo.replace('?', '');
|
||||
testo = testo.replace('é', 'è');
|
||||
@@ -1778,9 +1778,9 @@ class Telegram {
|
||||
rec.user.index + ']: ' + rec.user.name + ' ' + rec.user.surname +
|
||||
'\nUsername: ' + rec.user.username + '\n' + 'Email: ' +
|
||||
rec.user.email + '\nLang: ' + rec.user.lang + tools.ACAPO;
|
||||
risp += 'Num Invitati: ' + myrec.numinvitati + tools.ACAPO;
|
||||
risp += 'Num Invitati Attivi: ' + myrec.numinvitatiattivi +
|
||||
tools.ACAPO;
|
||||
risp += 'Invitato da ' + rec.user.aportador_solidario + tools.ACAPO;
|
||||
risp += 'Username Telegram ' + rec.user.profile.username_telegram + tools.ACAPO;
|
||||
risp += 'Telegram ID ' + rec.user.profile.teleg_id + tools.ACAPO;
|
||||
} else {
|
||||
risp = 'Ancora non ti sei Attivato sul BOT';
|
||||
}
|
||||
@@ -2838,7 +2838,7 @@ class Telegram {
|
||||
|
||||
async setUsernameInvitante(msg) {
|
||||
try {
|
||||
let mymsg = msg.text?.toString().trim().toLowerCase();
|
||||
let mymsg = msg.text?.toString()?.trim().toLowerCase();
|
||||
|
||||
let nomeapp = tools.getNomeAppByIdApp(this.idapp);
|
||||
|
||||
@@ -3065,7 +3065,7 @@ class Telegram {
|
||||
texttosend = await this.getNextZoom(msg);
|
||||
}
|
||||
|
||||
const cmd = texttosend.toLowerCase();
|
||||
const cmd = texttosend?.toLowerCase();
|
||||
|
||||
if (usersall) {
|
||||
if (this.isSelMenu(msg, cmd, 'INDIETRO')) {
|
||||
@@ -3324,7 +3324,7 @@ class Telegram {
|
||||
}
|
||||
|
||||
const rec = this.getRecInMem(msg);
|
||||
let testo = msg.text?.toLowerCase().trim();
|
||||
let testo = msg.text?.toLowerCase()?.trim();
|
||||
|
||||
status = this.getstatus(rec);
|
||||
if (testo === Menu.EXIT_TELEGRAM) {
|
||||
@@ -3388,7 +3388,7 @@ class Telegram {
|
||||
rec.chatId = msg.chat.id;
|
||||
rec.messageId = msg.message_id;
|
||||
rec.msgall_status = StatusMSGALL.CONFIRM;
|
||||
const cmd = rec?.msgtosent?.toString().toLowerCase() ?? '';
|
||||
const cmd = rec?.msgtosent?.toString()?.toLowerCase() ?? '';
|
||||
let achi = this.getDestinStr(msg, rec.msgall_achi, rec);
|
||||
let domanda = '';
|
||||
if (rec.msgall_domanda) {
|
||||
@@ -3733,7 +3733,7 @@ class Telegram {
|
||||
for (const recdb of recuser.menuDb) {
|
||||
if (recdb.active_mem) {
|
||||
if (recdb.idapp === idapp && recdb.lang === lang &&
|
||||
recdb.label.toLowerCase() === testo) {
|
||||
recdb.label?.toLowerCase() === testo) {
|
||||
if (recdb.type === shared_consts.BOTTYPE_TEXT) {
|
||||
return recdb.value;
|
||||
} else if (recdb.type === shared_consts.BOTTYPE_LINK) {
|
||||
@@ -3774,7 +3774,7 @@ class Telegram {
|
||||
for (const recdb of recuser.menuDb) {
|
||||
if (recdb.active_mem) {
|
||||
if (recdb.idapp === idapp && recdb.lang === lang &&
|
||||
recdb.label.toLowerCase() === testo) {
|
||||
recdb.label?.toLowerCase() === testo) {
|
||||
if (recdb.type === shared_consts.BOTTYPE_MARKDOWN) {
|
||||
return 'Markdown'
|
||||
} else {
|
||||
|
||||
@@ -5041,11 +5041,14 @@ module.exports = {
|
||||
descrcontent = '';
|
||||
}
|
||||
|
||||
mystr += `${icon} <strong>${title}</strong>`;
|
||||
if (acapo) {
|
||||
mystr += `\n`;
|
||||
} else {
|
||||
mystr += `: `;
|
||||
if (title && icon) {
|
||||
mystr += `${icon} <strong>${title}</strong>`;
|
||||
|
||||
if (acapo) {
|
||||
mystr += `\n`;
|
||||
} else {
|
||||
mystr += `: `;
|
||||
}
|
||||
}
|
||||
if (descrcontent) {
|
||||
mystr += `${descrcontent}\n`;
|
||||
@@ -5410,7 +5413,7 @@ module.exports = {
|
||||
out += `<strong>${myrec.descr}</strong>\n\n`;
|
||||
|
||||
if (datastr)
|
||||
out += this.addRowTelegram('✨', 'Data Evento', datastr, true, true);
|
||||
out += this.addRowTelegram('', '', datastr, true, true);
|
||||
|
||||
if (cat)
|
||||
out += this.addRowTelegram('⭐️', 'Categoria', cat, true, true);
|
||||
@@ -5424,7 +5427,7 @@ module.exports = {
|
||||
// descrcontent = '<span size="3"><b>Prova Pao</b> Ciaooo</span>';
|
||||
|
||||
if (descrcontent)
|
||||
out += this.addRowTelegram('📝', 'Descrizione ' + newdescr, descrcontent, true, true);
|
||||
out += this.addRowTelegram('', '', '📝 ' + descrcontent, true, true);
|
||||
|
||||
const localita = this.getComuniEProvinceByRec(myrec);
|
||||
|
||||
|
||||
@@ -1181,6 +1181,11 @@ module.exports = {
|
||||
COMMUNITY_ACCOUNT: 2,
|
||||
},
|
||||
|
||||
CmdQueryMs: {
|
||||
GET: 0,
|
||||
SET: 1,
|
||||
},
|
||||
|
||||
// Download, DVD, Epub, Mobi, Nuovo, PDF, Streaming, Usato
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user