Allow copy down on empty cells, tweaks to dates on dashboards, new route for warehouse locations
This commit is contained in:
@@ -1439,6 +1439,41 @@ router.get('/search-products', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Current warehouse locations for a batch of pids — a single-table read kept
|
||||
// deliberately tiny. Added for the email app's printable count sheet: shelf
|
||||
// locations move after putaway, so the sheet pulls them LIVE at print time
|
||||
// instead of trusting its receipt mirror's snapshot. GET = authenticated-only,
|
||||
// same as the other read endpoints here.
|
||||
router.get('/product-locations', async (req, res) => {
|
||||
const pids = String(req.query.pids || '')
|
||||
.split(',')
|
||||
.map(Number)
|
||||
.filter((n) => Number.isInteger(n) && n > 0);
|
||||
if (pids.length === 0) {
|
||||
return res.status(400).json({ error: 'pids (comma-separated positive integers) is required' });
|
||||
}
|
||||
if (pids.length > 1000) {
|
||||
return res.status(400).json({ error: 'Too many pids (max 1000)' });
|
||||
}
|
||||
|
||||
try {
|
||||
const { connection } = await getDbConnection();
|
||||
const [rows] = await connection.query(
|
||||
`SELECT pid, location FROM products WHERE pid IN (${pids.map((p) => connection.escape(p)).join(',')})`
|
||||
);
|
||||
// Empty-string locations (unshelved products) are omitted rather than sent
|
||||
// as '' so callers can treat presence as "has a shelf location".
|
||||
const locations = {};
|
||||
for (const row of rows) {
|
||||
if (row.location) locations[row.pid] = row.location;
|
||||
}
|
||||
res.json({ locations });
|
||||
} catch (error) {
|
||||
console.error('Error fetching product locations:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch product locations' });
|
||||
}
|
||||
});
|
||||
|
||||
// Shared SELECT for product queries (matches search-products fields)
|
||||
const PRODUCT_SELECT = `
|
||||
SELECT
|
||||
|
||||
Reference in New Issue
Block a user