Restore removed files

This commit is contained in:
2026-01-30 22:24:50 -05:00
parent ac39257a51
commit 89d518b57f
187 changed files with 66365 additions and 316 deletions

View File

@@ -634,7 +634,7 @@ router.post('/upload-image', upload.single('image'), async (req, res) => {
req.file.size = processingResult.finalSize;
// Create URL for the uploaded file - using an absolute URL with domain
// This will generate a URL like: https://tools.acherryontop.com/uploads/products/filename.jpg
// This will generate a URL like: https://acot.site/uploads/products/filename.jpg
const baseUrl = 'https://tools.acherryontop.com';
const imageUrl = `${baseUrl}/uploads/products/${req.file.filename}`;
@@ -1046,17 +1046,21 @@ router.get('/list-uploads', (req, res) => {
// Search products from production database
router.get('/search-products', async (req, res) => {
const { q, company, dateRange } = req.query;
if (!q) {
return res.status(400).json({ error: 'Search term is required' });
const { q, pid, company, dateRange } = req.query;
if (!q && !pid) {
return res.status(400).json({ error: 'Search term or pid is required' });
}
try {
const { connection } = await getDbConnection();
// Build WHERE clause with additional filters
let whereClause = `
let whereClause;
if (pid) {
whereClause = `\n WHERE p.pid = ${connection.escape(Number(pid))}`;
} else {
whereClause = `
WHERE (
p.description LIKE ? OR
p.itemnumber LIKE ? OR
@@ -1064,6 +1068,7 @@ router.get('/search-products', async (req, res) => {
pc1.name LIKE ? OR
s.companyname LIKE ?
)`;
}
// Add company filter if provided
if (company) {
@@ -1122,8 +1127,9 @@ router.get('/search-products', async (req, res) => {
}
}
const isPidSearch = !!pid;
// Special case for wildcard search
const isWildcardSearch = q === '*';
const isWildcardSearch = !isPidSearch && q === '*';
const searchPattern = isWildcardSearch ? '%' : `%${q}%`;
const exactPattern = isWildcardSearch ? '%' : q;
@@ -1183,9 +1189,9 @@ router.get('/search-products', async (req, res) => {
LEFT JOIN current_inventory ci ON p.pid = ci.pid
${whereClause}
GROUP BY p.pid
${isWildcardSearch ? 'ORDER BY p.datein DESC' : `
ORDER BY
CASE
${isPidSearch ? '' : isWildcardSearch ? 'ORDER BY p.datein DESC' : `
ORDER BY
CASE
WHEN p.description LIKE ? THEN 1
WHEN p.itemnumber = ? THEN 2
WHEN p.upc = ? THEN 3
@@ -1195,10 +1201,12 @@ router.get('/search-products', async (req, res) => {
END
`}
`;
// Prepare query parameters based on whether it's a wildcard search
// Prepare query parameters based on search type
let queryParams;
if (isWildcardSearch) {
if (isPidSearch) {
queryParams = [];
} else if (isWildcardSearch) {
queryParams = [
searchPattern, // LIKE for description
searchPattern, // LIKE for itemnumber
@@ -1246,6 +1254,48 @@ router.get('/search-products', async (req, res) => {
}
});
// Get product images for a given PID from production DB
router.get('/product-images/:pid', async (req, res) => {
const pid = parseInt(req.params.pid, 10);
if (!pid || pid <= 0) {
return res.status(400).json({ error: 'Valid PID is required' });
}
try {
const { connection } = await getDbConnection();
const [rows] = await connection.query(
'SELECT iid, type, width, height, `order`, hidden FROM product_images WHERE pid = ? ORDER BY `order` DESC, type',
[pid]
);
// Group by iid and build image URLs using the same logic as the PHP codebase
const typeMap = { 1: 'o', 2: 'l', 3: 't', 4: '100x100', 5: '175x175', 6: '300x300', 7: '600x600', 8: '500x500', 9: '150x150' };
const padded = String(pid).padStart(10, '0');
const pathPrefix = `${padded.substring(0, 4)}/${padded.substring(4, 7)}/`;
const imagesByIid = {};
for (const row of rows) {
const typeName = typeMap[row.type];
if (!typeName) continue;
if (!imagesByIid[row.iid]) {
imagesByIid[row.iid] = { iid: row.iid, order: row.order, hidden: !!row.hidden, sizes: {} };
}
imagesByIid[row.iid].sizes[typeName] = {
width: row.width,
height: row.height,
url: `https://sbing.com/i/products/${pathPrefix}${pid}-${typeName}-${row.iid}.jpg`,
};
}
const images = Object.values(imagesByIid).sort((a, b) => b.order - a.order);
res.json(images);
} catch (error) {
console.error('Error fetching product images:', error);
res.status(500).json({ error: 'Failed to fetch product images' });
}
});
const UPC_SUPPLIER_PREFIX_LEADING_DIGIT = '4';
const UPC_MAX_SEQUENCE = 99999;
const UPC_RESERVATION_TTL = 5 * 60 * 1000; // 5 minutes