linking stuff
This commit is contained in:
@@ -7,6 +7,37 @@ const { calculateApplication } = require('../utils/applicationCalculations');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Helper function to get spreader settings for equipment and product
|
||||
async function getSpreaderSettingsForEquipment(equipmentId, productId, userProductId, userId) {
|
||||
// Get spreader settings for the specific product and equipment combination
|
||||
let query, params;
|
||||
|
||||
if (userProductId) {
|
||||
query = `
|
||||
SELECT pss.*, ue.custom_name as equipment_name, ue.manufacturer, ue.model as equipment_model
|
||||
FROM product_spreader_settings pss
|
||||
JOIN user_equipment ue ON pss.equipment_id = ue.id
|
||||
WHERE pss.user_product_id = $1 AND pss.equipment_id = $2 AND ue.user_id = $3
|
||||
ORDER BY pss.created_at DESC
|
||||
LIMIT 1
|
||||
`;
|
||||
params = [userProductId, equipmentId, userId];
|
||||
} else {
|
||||
query = `
|
||||
SELECT pss.*, ue.custom_name as equipment_name, ue.manufacturer, ue.model as equipment_model
|
||||
FROM product_spreader_settings pss
|
||||
JOIN user_equipment ue ON pss.equipment_id = ue.id
|
||||
WHERE pss.product_id = $1 AND pss.equipment_id = $2 AND ue.user_id = $3
|
||||
ORDER BY pss.created_at DESC
|
||||
LIMIT 1
|
||||
`;
|
||||
params = [productId, equipmentId, userId];
|
||||
}
|
||||
|
||||
const result = await pool.query(query, params);
|
||||
return result.rows[0] || null;
|
||||
}
|
||||
|
||||
// @route GET /api/applications/plans
|
||||
// @desc Get all application plans for current user
|
||||
// @access Private
|
||||
@@ -902,4 +933,67 @@ router.get('/stats', async (req, res, next) => {
|
||||
}
|
||||
});
|
||||
|
||||
// @route GET /api/applications/spreader-settings/:equipmentId/:productId
|
||||
// @desc Get recommended spreader settings for specific equipment and product combination
|
||||
// @access Private
|
||||
router.get('/spreader-settings/:equipmentId/:productId', async (req, res, next) => {
|
||||
try {
|
||||
const { equipmentId, productId } = req.params;
|
||||
const { isUserProduct } = req.query; // Indicates if productId refers to user_products table
|
||||
|
||||
// Verify equipment belongs to user
|
||||
const equipmentCheck = await pool.query(
|
||||
'SELECT id, custom_name, manufacturer, model FROM user_equipment WHERE id = $1 AND user_id = $2',
|
||||
[equipmentId, req.user.id]
|
||||
);
|
||||
|
||||
if (equipmentCheck.rows.length === 0) {
|
||||
throw new AppError('Equipment not found', 404);
|
||||
}
|
||||
|
||||
const equipment = equipmentCheck.rows[0];
|
||||
|
||||
// Get spreader settings
|
||||
const spreaderSetting = await getSpreaderSettingsForEquipment(
|
||||
parseInt(equipmentId),
|
||||
isUserProduct === 'true' ? null : parseInt(productId),
|
||||
isUserProduct === 'true' ? parseInt(productId) : null,
|
||||
req.user.id
|
||||
);
|
||||
|
||||
if (!spreaderSetting) {
|
||||
return res.json({
|
||||
success: true,
|
||||
data: {
|
||||
hasSettings: false,
|
||||
message: 'No spreader settings found for this equipment and product combination',
|
||||
equipment: {
|
||||
id: equipment.id,
|
||||
name: equipment.custom_name || `${equipment.manufacturer} ${equipment.model}`.trim()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
hasSettings: true,
|
||||
setting: {
|
||||
id: spreaderSetting.id,
|
||||
settingValue: spreaderSetting.setting_value,
|
||||
rateDescription: spreaderSetting.rate_description,
|
||||
notes: spreaderSetting.notes
|
||||
},
|
||||
equipment: {
|
||||
id: equipment.id,
|
||||
name: equipment.custom_name || `${equipment.manufacturer} ${equipment.model}`.trim()
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -182,6 +182,43 @@ router.get('/', async (req, res, next) => {
|
||||
}
|
||||
});
|
||||
|
||||
// @route GET /api/equipment/spreaders
|
||||
// @desc Get all spreader equipment for current user (for product spreader settings)
|
||||
// @access Private
|
||||
router.get('/spreaders', async (req, res, next) => {
|
||||
try {
|
||||
const result = await pool.query(
|
||||
`SELECT ue.id, ue.custom_name, ue.manufacturer, ue.model, ue.spreader_type,
|
||||
ue.capacity_lbs, ue.spread_width, ec.name as category_name
|
||||
FROM user_equipment ue
|
||||
LEFT JOIN equipment_categories ec ON ue.category_id = ec.id
|
||||
WHERE ue.user_id = $1
|
||||
AND ue.is_active = true
|
||||
AND (ec.name ILIKE '%spreader%' OR ue.spreader_type IS NOT NULL)
|
||||
ORDER BY ue.custom_name, ue.manufacturer, ue.model`,
|
||||
[req.user.id]
|
||||
);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
spreaders: result.rows.map(item => ({
|
||||
id: item.id,
|
||||
name: item.custom_name || `${item.manufacturer} ${item.model}`.trim(),
|
||||
manufacturer: item.manufacturer,
|
||||
model: item.model,
|
||||
spreaderType: item.spreader_type,
|
||||
capacityLbs: item.capacity_lbs ? parseFloat(item.capacity_lbs) : null,
|
||||
spreadWidth: item.spread_width ? parseFloat(item.spread_width) : null,
|
||||
categoryName: item.category_name
|
||||
}))
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
// @route GET /api/equipment/:id
|
||||
// @desc Get single equipment item
|
||||
// @access Private
|
||||
|
||||
@@ -351,6 +351,26 @@ router.post('/user', validateRequest(userProductSchema), async (req, res, next)
|
||||
if (spreaderSettings && Array.isArray(spreaderSettings) && productType === 'granular') {
|
||||
// Add spreader settings for this user product
|
||||
for (const setting of spreaderSettings) {
|
||||
// Check if equipment exists and belongs to user if equipmentId is provided
|
||||
if (setting.equipmentId) {
|
||||
const equipmentCheck = await pool.query(
|
||||
'SELECT id FROM user_equipment WHERE id = $1 AND user_id = $2',
|
||||
[setting.equipmentId, req.user.id]
|
||||
);
|
||||
|
||||
if (equipmentCheck.rows.length === 0) {
|
||||
throw new AppError(`Equipment with id ${setting.equipmentId} not found`, 404);
|
||||
}
|
||||
|
||||
await pool.query(
|
||||
`INSERT INTO product_spreader_settings
|
||||
(user_product_id, equipment_id, setting_value, rate_description, notes)
|
||||
VALUES ($1, $2, $3, $4, $5)`,
|
||||
[userProduct.id, setting.equipmentId, setting.settingValue,
|
||||
setting.rateDescription, setting.notes]
|
||||
);
|
||||
} else {
|
||||
// Fall back to legacy brand/model approach
|
||||
await pool.query(
|
||||
`INSERT INTO product_spreader_settings
|
||||
(user_product_id, spreader_brand, spreader_model, setting_value, rate_description, notes)
|
||||
@@ -360,6 +380,7 @@ router.post('/user', validateRequest(userProductSchema), async (req, res, next)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
@@ -412,17 +433,27 @@ router.get('/user/:id', validateParams(idParamSchema), async (req, res, next) =>
|
||||
|
||||
const userProduct = result.rows[0];
|
||||
|
||||
// Get spreader settings for this user product
|
||||
// Get spreader settings for this user product with equipment details
|
||||
let spreaderSettings = [];
|
||||
const settingsResult = await pool.query(
|
||||
`SELECT * FROM product_spreader_settings
|
||||
WHERE user_product_id = $1
|
||||
ORDER BY spreader_brand, spreader_model NULLS LAST, setting_value`,
|
||||
`SELECT pss.*, ue.custom_name as equipment_name, ue.manufacturer, ue.model as equipment_model,
|
||||
ue.spreader_type, ue.capacity_lbs
|
||||
FROM product_spreader_settings pss
|
||||
LEFT JOIN user_equipment ue ON pss.equipment_id = ue.id
|
||||
WHERE pss.user_product_id = $1
|
||||
ORDER BY ue.custom_name NULLS LAST, pss.spreader_brand, pss.spreader_model NULLS LAST, pss.setting_value`,
|
||||
[userProductId]
|
||||
);
|
||||
|
||||
spreaderSettings = settingsResult.rows.map(row => ({
|
||||
id: row.id,
|
||||
equipmentId: row.equipment_id,
|
||||
equipmentName: row.equipment_name,
|
||||
equipmentManufacturer: row.manufacturer,
|
||||
equipmentModel: row.equipment_model,
|
||||
equipmentType: row.spreader_type,
|
||||
equipmentCapacity: row.capacity_lbs ? parseFloat(row.capacity_lbs) : null,
|
||||
// Legacy fields
|
||||
spreaderBrand: row.spreader_brand,
|
||||
spreaderModel: row.spreader_model,
|
||||
settingValue: row.setting_value,
|
||||
|
||||
@@ -91,8 +91,10 @@ const userProductSchema = Joi.object({
|
||||
// Spreader settings for granular products
|
||||
spreaderSettings: Joi.array().items(
|
||||
Joi.object({
|
||||
id: Joi.number().optional(), // For frontend temporary IDs
|
||||
spreaderBrand: Joi.string().max(100).required(),
|
||||
id: Joi.number().optional(), // For existing settings
|
||||
equipmentId: Joi.number().integer().positive().optional(), // Link to user_equipment
|
||||
// Legacy fields for backward compatibility
|
||||
spreaderBrand: Joi.string().max(100).optional(),
|
||||
spreaderModel: Joi.alternatives().try(
|
||||
Joi.string().max(100).allow(''),
|
||||
Joi.allow(null)
|
||||
@@ -106,7 +108,7 @@ const userProductSchema = Joi.object({
|
||||
Joi.string().allow(''),
|
||||
Joi.allow(null)
|
||||
).optional()
|
||||
})
|
||||
}).or('equipmentId', 'spreaderBrand') // Must have either equipment reference or brand
|
||||
).optional()
|
||||
});
|
||||
|
||||
|
||||
14
database/migrations/link_spreader_settings_to_equipment.sql
Normal file
14
database/migrations/link_spreader_settings_to_equipment.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
-- Link spreader settings to actual user equipment instead of storing text
|
||||
-- This allows better integration and recommendations
|
||||
|
||||
-- Add equipment reference to product_spreader_settings
|
||||
ALTER TABLE product_spreader_settings
|
||||
ADD COLUMN IF NOT EXISTS equipment_id INTEGER REFERENCES user_equipment(id) ON DELETE CASCADE;
|
||||
|
||||
-- Create index for the new relationship
|
||||
CREATE INDEX IF NOT EXISTS idx_product_spreader_settings_equipment ON product_spreader_settings(equipment_id);
|
||||
|
||||
-- We'll keep the old columns for backward compatibility during transition
|
||||
-- They can be removed later once all data is migrated
|
||||
|
||||
SELECT 'Added equipment reference to spreader settings!' as migration_status;
|
||||
Reference in New Issue
Block a user