This commit is contained in:
JunBarroga 2024-10-22 11:32:48 +08:00
parent 57ba9ee775
commit 0d6bd655de
3 changed files with 458 additions and 78 deletions

405
index.js
View File

@ -2,6 +2,8 @@ import express from "express";
import bodyParser from "body-parser"; import bodyParser from "body-parser";
import mongoose from "mongoose"; import mongoose from "mongoose";
import cors from "cors"; import cors from "cors";
import atob from "atob";
import dotenv from "dotenv"; import dotenv from "dotenv";
import multer from "multer"; import multer from "multer";
import helmet from "helmet"; import helmet from "helmet";
@ -143,20 +145,41 @@ function sendEmail(req, res, next) {
} }
app.post("/api/send-email/", sendEmail); app.post("/api/send-email/", sendEmail);
const odooClient = new Odoo({ // const odooClient = new Odoo({
url: "https://gis.pivi.com.ph", // url: "http://192.168.50.15:8070",
db: "gis.pivi.com.ph", // db: "gis.pivi.com.ph",
username: "egalang@obanana.com", // username: "egalang@obanana.com",
password: "P@$$w0rd!", // password: "P@$$w0rd!",
}); // });
const odooClient2 = new Odoo({ const odooClient2 = new Odoo({
url: "http://localhost:8069/", url: "http://192.168.50.15:8071",
db: "Paymongo", db: "pos.obanana.com",
username: "mahipe@obanana.com", username: "mahipe@obanana.com",
password: "abcd123", password: "P@$$w0rd!",
}); });
app.get("/get-assets", async (req, res) => { app.get("/get-assets", async (req, res) => {
try { try {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Basic ')) {
return res.status(400).json({ error: 'Authorization header is missing or invalid.' });
}
const base64Credentials = authHeader.split(' ')[1];
const decodedCredentials = atob(base64Credentials);
const [email, password] = decodedCredentials.split(':');
if (!email || !password) {
return res.status(400).json({ error: 'Invalid credentials format.' });
}
// console.log(email,password)
const odooClient = new Odoo({
url: "http://192.168.50.15:8070",
db: "gis.pivi.com.ph",
username: email,
password: password
});
odooClient.connect(async function (err) { odooClient.connect(async function (err) {
if (err) { if (err) {
console.log(err); console.log(err);
@ -346,6 +369,52 @@ app.get("/get-assets", async (req, res) => {
}); });
} else { } else {
images = image; images = image;
const inParams = [];
inParams.push([["related_asset", "!=", false]]);
inParams.push(parseInt(req.query.offset) || 0); //offset
inParams.push(parseInt(req.query.limit) || 0); //Limit
const params1 = [inParams];
odooClient.execute_kw(
"pivi_assets.related",
"search",
params1,
async function (err, ids) {
if (err) {
console.log(err);
return res.status(500).json({
error:
"Search Error: " + err.message,
});
}
if (ids.length === 0) {
return res.json([]); // No assets found
}
// Fetch asset records
const inParamsRead = [];
inParamsRead.push(ids); // IDs
inParamsRead.push([
"id",
"related_asset",
"asset",
]);
const paramsRead = [inParamsRead];
odooClient.execute_kw(
"pivi_assets.related",
"read",
paramsRead,
async function (err2, related) {
if (err2) {
console.log(err2);
return res.status(500).json({
error:
"Read Error: " + err2.message,
});
} else {
let relateds
relateds = related;
const asset = recordsArray.map( const asset = recordsArray.map(
(item) => { (item) => {
@ -369,6 +438,15 @@ app.get("/get-assets", async (req, res) => {
boundId === bound.id boundId === bound.id
) // Compare to the first element of bounds.assets ) // Compare to the first element of bounds.assets
); );
// Find matching bounds based on the numeric part of bounds.assets
const matchedRelated =
relateds.filter(
(related) =>
item.related.some(
(relatedId) =>
relatedId === related.id
)
);
// Find matching images based on data.id == images.res_id // Find matching images based on data.id == images.res_id
const matchedImages = const matchedImages =
@ -383,6 +461,7 @@ app.get("/get-assets", async (req, res) => {
bounds: matchedBounds, bounds: matchedBounds,
data: item, data: item,
images: matchedImages, images: matchedImages,
related: matchedRelated
}; };
} }
); );
@ -402,6 +481,14 @@ app.get("/get-assets", async (req, res) => {
} }
); );
} }
let pendingRequests =
records.length;
}
);
}
);
}
} }
); );
} }
@ -721,8 +808,7 @@ app.get("/get-stages", async (req, res) => {
}); });
app.post('/update-order-state', async (req, res) => { app.post('/update-order-state', async (req, res) => {
const { id, state } = req.body; // Order ID and new state passed in the request body const { id, state } = req.body;
if (!id || !state) { if (!id || !state) {
return res.status(400).json({ error: 'Order ID and state are required.' }); return res.status(400).json({ error: 'Order ID and state are required.' });
} }
@ -735,9 +821,8 @@ app.post('/update-order-state', async (req, res) => {
} }
console.log('Connected to Odoo server.'); console.log('Connected to Odoo server.');
// Search for the order by ID
const inParams = []; const inParams = [];
inParams.push([['id', '=', id]]); // Find the order by its ID inParams.push([['id', '=', id]]);
const params = [inParams]; const params = [inParams];
odooClient2.execute_kw('pos.order', 'search', params, function (err, orderIds) { odooClient2.execute_kw('pos.order', 'search', params, function (err, orderIds) {
@ -750,10 +835,9 @@ app.post('/update-order-state', async (req, res) => {
return res.status(404).json({ error: 'Order not found.' }); return res.status(404).json({ error: 'Order not found.' });
} }
// Update the state of the order
const inParamsUpdate = []; const inParamsUpdate = [];
inParamsUpdate.push(orderIds); // Order IDs to update inParamsUpdate.push(orderIds);
inParamsUpdate.push({ state: state }); // Fields to update inParamsUpdate.push({ state: state });
const paramsUpdate = [inParamsUpdate]; const paramsUpdate = [inParamsUpdate];
odooClient2.execute_kw('pos.order', 'write', paramsUpdate, function (err2, result) { odooClient2.execute_kw('pos.order', 'write', paramsUpdate, function (err2, result) {
@ -775,16 +859,293 @@ app.post('/update-order-state', async (req, res) => {
return res.status(500).json({ error: 'Update Error: ' + error.message }); return res.status(500).json({ error: 'Update Error: ' + error.message });
} }
}); });
app.get("/get-tables", async (req, res) => {
try {
odooClient2.connect(async function (err) {
if (err) {
console.log(err);
return res
.status(500)
.json({ error: "Connection Error: " + err.message });
}
console.log("Connected to Odoo server.");
// Fetch asset IDs
const inParams = [];
inParams.push([["name", "!=", false]]);
inParams.push(parseInt(req.query.offset) || 0);
inParams.push(parseInt(req.query.limit) || 0);
const params = [inParams];
const assets = [];
let recordsArray = [];
function fetchOdooData(model, method, params) { let attributes = [];
let bounds = [];
let images = [];
odooClient2.execute_kw(
"restaurant.table",
"search",
params,
async function (err, ids) {
if (err) {
console.log(err);
return res
.status(500)
.json({ error: "Search Error: " + err.message });
}
if (ids.length === 0) {
return res.json([]); // No assets found
}
// Fetch asset records
const inParamsRead = [];
inParamsRead.push(ids); // IDs
// inParamsRead.push([
// "id",
// "name",
// ]);
const paramsRead = [inParamsRead];
odooClient2.execute_kw(
"restaurant.table",
"read",
paramsRead,
async function (err2, records) {
if (err2) {
console.log(err2);
return res
.status(500)
.json({ error: "Read Error: " + err2.message });
} else {
recordsArray = records;
res.json(recordsArray);
}
let pendingRequests = records.length;
}
);
}
);
});
} catch (error) {
console.error("Error:", error);
res.status(500).json({ error: "Data Fetch Error: " + error.message });
}
});
app.post('/create-asset-bounds', async (req, res) => {
try {
const postData = req.body;
if (!postData || postData.length === 0) {
return res.status(200).json({ error: 'No data provided.' });
}
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Basic ')) {
return res.status(400).json({ error: 'Authorization header is missing or invalid.' });
}
const base64Credentials = authHeader.split(' ')[1];
const decodedCredentials = Buffer.from(base64Credentials, 'base64').toString('ascii'); // safer than `atob`
const [email, password] = decodedCredentials.split(':');
if (!email || !password) {
return res.status(400).json({ error: 'Invalid credentials format.' });
}
const odooClient = new Odoo({
url: "http://192.168.50.15:8070",
db: "gis.pivi.com.ph",
username: email,
password: password
});
odooClient.connect(async function (err) {
if (err) {
console.log(err);
return res.status(500).json({ error: 'Connection Error: ' + err.message });
}
console.log('Connected to Odoo server.');
// Use Promise.all to wait for all async operations to finish
try {
const createdIds = await Promise.all(
postData.map(async (data, index) => {
const { asset, name, longitude, latitude } = data;
if (!asset || !name || !longitude || !latitude) {
throw new Error(`Missing required fields in entry ${index + 1}`);
}
const params = [
{
asset: asset,
name: name,
longitude: longitude,
latitude: latitude,
}
];
// Return a promise for each create operation
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
odooClient.execute_kw(model, method, params, (err, data) => { odooClient.execute_kw('pivi_assets.bounds', 'create', [params], function (err2, id) {
if (err) return reject(err); if (err2) {
resolve(data); console.log('Create Error:', err2);
return reject(new Error('Create Error: ' + err2.message));
}
resolve(id);
}); });
}); });
} })
);
return res.json({ success: true, createdIds });
} catch (error) {
return res.status(500).json({ error: error.message });
}
});
} catch (error) {
console.error('Error:', error);
return res.status(500).json({ error: 'Server Error: ' + error.message });
}
});
app.post('/odoo-webhook', (req, res) => {
const newOrder = req.body;
console.log('New POS order received:', newOrder);
// Process the order data as needed
// For example, send it to a WebSocket, log it, or store it in a database
res.status(200).send('Webhook received');
});
app.delete('/delete-asset-bounds', async (req, res) => {
try {
const assetId = req.query.asset;
console.log(assetId)
if (!assetId) {
return res.status(400).json({ error: 'Asset ID is required.' });
}
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Basic ')) {
return res.status(400).json({ error: 'Authorization header is missing or invalid.' });
}
const base64Credentials = authHeader.split(' ')[1];
const decodedCredentials = atob(base64Credentials);
const [email, password] = decodedCredentials.split(':');
if (!email || !password) {
return res.status(400).json({ error: 'Invalid credentials format.' });
}
// console.log(email,password)
const odooClient = new Odoo({
url: "http://192.168.50.15:8070",
db: "gis.pivi.com.ph",
username: email,
password: password
});
odooClient.connect(function (err) {
if (err) {
console.log(err);
return res.status(500).json({ error: 'Connection Error: ' + err.message });
}
console.log('Connected to Odoo server.');
const inParams = [];
inParams.push([['id', '=', assetId]]);
const searchParamsAsset = [inParams];
// const searchParamsAsset = [
// [['id', '=', assetId]]
// ];
odooClient.execute_kw('pivi_assets.pivi_assets', 'search', searchParamsAsset, function (err2, assetIds) {
if (err2) {
console.log(assetIds+" id")
console.log('Search Error:', err2);
return res.status(500).json({ error: 'Search Asset Error: ' + err2.message });
}
if (assetIds.length === 0) {
return res.status(404).json({ error: 'Asset not found.' });
}
odooClient.execute_kw('pivi_assets.pivi_assets', 'read', [assetIds], function (err3, assets) {
if (err3) {
console.log('Read Error:', err3);
return res.status(500).json({ error: 'Read Error: ' + err3.message });
}
const assetName = assets[0].name;
// const searchParamsBounds = [
// [['asset', '=', assetName]]
// ];
const inParams = [];
inParams.push([['asset', '=', assetName]]);
const searchParamsBounds = [inParams];
odooClient.execute_kw('pivi_assets.bounds', 'search', searchParamsBounds, function (err4, boundIds) {
if (err4) {
console.log('Search Bounds Error:', err4);
return res.status(500).json({ error: 'Search Bounds Error: ' + err4.message });
}
if (boundIds.length === 0) {
return res.status(200).json({ error: 'No bounds found for this asset.' });
}
odooClient.execute_kw('pivi_assets.bounds', 'read', [[boundIds]], function (err5, bounds) {
if (err5) {
console.log('Read Bounds Error:', err5);
return res.status(500).json({ error: 'Read Bounds Error: ' + err5.message });
}
const deletedIds = [];
bounds.forEach((bound, index) => {
const boundId = bound.id;
odooClient.execute_kw('pivi_assets.bounds', 'unlink', [[boundId]], function (err6) {
if (err6) {
console.log('Unlink Error:', err6);
return res.status(500).json({ error: 'Unlink Error: ' + err6.message });
}
deletedIds.push(boundId);
if (deletedIds.length === bounds.length) {
return res.json({ success: true, deletedIds });
}
});
});
});
});
});
});
});
} catch (error) {
console.error('Error:', error);
return res.status(500).json({ error: 'Server Error: ' + error.message });
}
});
// function fetchOdooData(model, method, params) {
// return new Promise((resolve, reject) => {
// odooClient.execute_kw(model, method, params, (err, data) => {
// if (err) return reject(err);
// resolve(data);
// });
// });
// }
/* MONGOOSE SETUP */ /* MONGOOSE SETUP */
const PORT = process.env.PORT || 3002; const PORT = process.env.PORT || 3002;
@ -801,7 +1162,7 @@ const PORT = process.env.PORT || 3002;
// .catch((error) => console.log(`${error} did not connect`)); // .catch((error) => console.log(`${error} did not connect`));
mongoose mongoose
.connect(process.env.MONGO_URL) .connect(process.env.DATABASE_URL)
.then(() => { .then(() => {
app.listen(PORT, () => console.log(`Server Port: ${PORT}`)); app.listen(PORT, () => console.log(`Server Port: ${PORT}`));

18
package-lock.json generated
View File

@ -9,6 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"atob": "^2.1.2",
"axios": "^1.7.4", "axios": "^1.7.4",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"body-parser": "^1.20.2", "body-parser": "^1.20.2",
@ -184,6 +185,18 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
}, },
"node_modules/atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
"license": "(MIT OR Apache-2.0)",
"bin": {
"atob": "bin/atob.js"
},
"engines": {
"node": ">= 4.5.0"
}
},
"node_modules/axios": { "node_modules/axios": {
"version": "1.7.4", "version": "1.7.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
@ -2437,6 +2450,11 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
}, },
"atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
},
"axios": { "axios": {
"version": "1.7.4", "version": "1.7.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",

View File

@ -11,6 +11,7 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"atob": "^2.1.2",
"axios": "^1.7.4", "axios": "^1.7.4",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"body-parser": "^1.20.2", "body-parser": "^1.20.2",