costco-grocery-list/backend/models/store.model.js

144 lines
3.7 KiB
JavaScript

const pool = require("../db/pool");
// Get all available stores
exports.getAllStores = async () => {
const result = await pool.query(
`SELECT id, name, default_zones, created_at
FROM stores
ORDER BY name ASC`
);
return result.rows;
};
// Get store by ID
exports.getStoreById = async (storeId) => {
const result = await pool.query(
`SELECT id, name, default_zones, created_at
FROM stores
WHERE id = $1`,
[storeId]
);
return result.rows[0];
};
// Get stores for a specific household
exports.getHouseholdStores = async (householdId) => {
const result = await pool.query(
`SELECT
s.id,
s.name,
s.default_zones,
hs.is_default,
hs.added_at
FROM stores s
JOIN household_stores hs ON s.id = hs.store_id
WHERE hs.household_id = $1
ORDER BY hs.is_default DESC, s.name ASC`,
[householdId]
);
return result.rows;
};
// Add store to household
exports.addStoreToHousehold = async (householdId, storeId, isDefault = false) => {
// If setting as default, unset other defaults
if (isDefault) {
await pool.query(
`UPDATE household_stores
SET is_default = FALSE
WHERE household_id = $1`,
[householdId]
);
}
const result = await pool.query(
`INSERT INTO household_stores (household_id, store_id, is_default)
VALUES ($1, $2, $3)
ON CONFLICT (household_id, store_id)
DO UPDATE SET is_default = $3
RETURNING household_id, store_id, is_default`,
[householdId, storeId, isDefault]
);
return result.rows[0];
};
// Remove store from household
exports.removeStoreFromHousehold = async (householdId, storeId) => {
await pool.query(
`DELETE FROM household_stores
WHERE household_id = $1 AND store_id = $2`,
[householdId, storeId]
);
};
// Set default store for household
exports.setDefaultStore = async (householdId, storeId) => {
// Unset all defaults
await pool.query(
`UPDATE household_stores
SET is_default = FALSE
WHERE household_id = $1`,
[householdId]
);
// Set new default
await pool.query(
`UPDATE household_stores
SET is_default = TRUE
WHERE household_id = $1 AND store_id = $2`,
[householdId, storeId]
);
};
// Create new store (system admin only)
exports.createStore = async (name, defaultZones) => {
const result = await pool.query(
`INSERT INTO stores (name, default_zones)
VALUES ($1, $2)
RETURNING id, name, default_zones, created_at`,
[name, JSON.stringify(defaultZones)]
);
return result.rows[0];
};
// Update store (system admin only)
exports.updateStore = async (storeId, updates) => {
const { name, default_zones } = updates;
const result = await pool.query(
`UPDATE stores
SET
name = COALESCE($1, name),
default_zones = COALESCE($2, default_zones)
WHERE id = $3
RETURNING id, name, default_zones, created_at`,
[name, default_zones ? JSON.stringify(default_zones) : null, storeId]
);
return result.rows[0];
};
// Delete store (system admin only, only if not in use)
exports.deleteStore = async (storeId) => {
// Check if store is in use
const usage = await pool.query(
`SELECT COUNT(*) as count FROM household_stores WHERE store_id = $1`,
[storeId]
);
if (parseInt(usage.rows[0].count) > 0) {
throw new Error('Cannot delete store that is in use by households');
}
await pool.query('DELETE FROM stores WHERE id = $1', [storeId]);
};
// Check if household has store
exports.householdHasStore = async (householdId, storeId) => {
const result = await pool.query(
`SELECT 1 FROM household_stores
WHERE household_id = $1 AND store_id = $2`,
[householdId, storeId]
);
return result.rows.length > 0;
};