gps tracking stuff

This commit is contained in:
Jake Kasper
2025-08-29 09:10:17 -04:00
parent 8c728d42d4
commit a9f4815f41
3 changed files with 59 additions and 10 deletions

View File

@@ -1008,6 +1008,8 @@ router.get('/logs', async (req, res, next) => {
// @access Private // @access Private
router.post('/logs', validateRequest(applicationLogSchema), async (req, res, next) => { router.post('/logs', validateRequest(applicationLogSchema), async (req, res, next) => {
try { try {
console.log('Create log request received:', JSON.stringify(req.body, null, 2));
const { const {
planId, planId,
lawnSectionId, lawnSectionId,
@@ -1052,6 +1054,18 @@ router.post('/logs', validateRequest(applicationLogSchema), async (req, res, nex
} }
// Create application log // Create application log
console.log('Inserting application log with values:', {
planId,
userId: req.user.id,
lawnSectionId,
equipmentId,
weatherConditions: JSON.stringify(weatherConditions),
gpsTrack: JSON.stringify(gpsTrack),
averageSpeed,
areaCovered,
notes
});
const logResult = await client.query( const logResult = await client.query(
`INSERT INTO application_logs `INSERT INTO application_logs
(plan_id, user_id, lawn_section_id, equipment_id, weather_conditions, (plan_id, user_id, lawn_section_id, equipment_id, weather_conditions,
@@ -1064,8 +1078,10 @@ router.post('/logs', validateRequest(applicationLogSchema), async (req, res, nex
); );
const log = logResult.rows[0]; const log = logResult.rows[0];
console.log('Application log inserted successfully:', log);
// Add products to log // Add products to log
console.log('Adding products to log:', products);
for (const product of products) { for (const product of products) {
const { const {
productId, productId,
@@ -1077,6 +1093,11 @@ router.post('/logs', validateRequest(applicationLogSchema), async (req, res, nex
actualSpeedMph actualSpeedMph
} = product; } = product;
console.log('Inserting product:', {
logId: log.id, productId, userProductId, rateAmount, rateUnit,
actualProductAmount, actualWaterAmount, actualSpeedMph
});
await client.query( await client.query(
`INSERT INTO application_log_products `INSERT INTO application_log_products
(log_id, product_id, user_product_id, rate_amount, rate_unit, (log_id, product_id, user_product_id, rate_amount, rate_unit,
@@ -1085,6 +1106,8 @@ router.post('/logs', validateRequest(applicationLogSchema), async (req, res, nex
[log.id, productId, userProductId, rateAmount, rateUnit, [log.id, productId, userProductId, rateAmount, rateUnit,
actualProductAmount, actualWaterAmount, actualSpeedMph] actualProductAmount, actualWaterAmount, actualSpeedMph]
); );
console.log('Product inserted successfully');
} }
// If this was from a plan, mark the plan as completed // If this was from a plan, mark the plan as completed

View File

@@ -177,7 +177,7 @@ const applicationLogSchema = Joi.object({
actualProductAmount: Joi.number().positive(), actualProductAmount: Joi.number().positive(),
actualWaterAmount: Joi.number().positive(), actualWaterAmount: Joi.number().positive(),
actualSpeedMph: Joi.number().positive() actualSpeedMph: Joi.number().positive()
})).min(1).required() }).or('productId', 'userProductId')).min(1).required()
}); });
// Validation middleware // Validation middleware

View File

@@ -245,30 +245,52 @@ const ApplicationExecutionModal = ({ application, propertyDetails, onClose, onCo
// Validate required fields // Validate required fields
if (!validSectionId) { if (!validSectionId) {
toast.error('No valid section found for this application'); toast.error('No valid section found for this application');
console.error('Invalid section ID:', validSectionId, 'Available sections:', sections);
return; return;
} }
if (!validEquipmentId) { if (!validEquipmentId) {
toast.error('No equipment information found for this application'); toast.error('No equipment information found for this application');
console.error('Invalid equipment ID:', validEquipmentId, 'Plan details:', planDetails);
return; return;
} }
if (validProducts.length === 0) { if (validProducts.length === 0) {
toast.error('No products found for this application'); toast.error('No products found for this application');
console.error('No valid products. Original products:', planDetails?.products, 'Filtered products:', validProducts);
return; return;
} }
// Validate GPS tracking data exists
if (gpsTrack.length === 0) {
console.warn('No GPS tracking data collected');
toast.error('No GPS tracking data was collected. Please ensure location services are enabled.');
return;
}
console.log('All validations passed. GPS points:', gpsTrack.length, 'Total distance:', totalDistance, 'Duration:', duration);
// Prepare GPS track data - ensure all required fields are present and valid
const gpsTrackData = {
points: gpsTrack.map(point => ({
lat: point.lat,
lng: point.lng,
timestamp: point.timestamp,
accuracy: point.accuracy || 0,
speed: point.speed || 0
})),
totalDistance: Math.round(totalDistance * 100) / 100, // Round to 2 decimal places
duration: Math.round(duration), // Duration in seconds
averageSpeed: Math.round(averageSpeed * 100) / 100 // Round to 2 decimal places
};
// Try minimal log data first // Try minimal log data first
const logData = { const logData = {
planId: application.id, planId: application.id,
lawnSectionId: validSectionId, lawnSectionId: validSectionId,
equipmentId: validEquipmentId, equipmentId: validEquipmentId,
gpsTrack: { gpsTrack: gpsTrackData, // Backend expects object format with points array
points: gpsTrack,
totalDistance: totalDistance,
duration: duration
}, // Backend expects object format
averageSpeed: Math.max(averageSpeed, 0.1), // Ensure positive number averageSpeed: Math.max(averageSpeed, 0.1), // Ensure positive number
areaCovered: application.totalSectionArea || application.sectionArea || 0, areaCovered: Math.max(application.totalSectionArea || application.sectionArea || 0, 0.1), // Ensure positive
notes: `Application completed via mobile tracking. Duration: ${Math.round(duration/60)} minutes`, notes: `Application completed via mobile tracking. Duration: ${Math.round(duration/60)} minutes, Distance: ${(totalDistance * 3.28084).toFixed(0)} ft, Points: ${gpsTrack.length}`,
products: validProducts products: validProducts
}; };
@@ -277,12 +299,16 @@ const ApplicationExecutionModal = ({ application, propertyDetails, onClose, onCo
try { try {
// Save the application log to the backend // Save the application log to the backend
await applicationsAPI.createLog(logData); console.log('About to call createLog with data:', JSON.stringify(logData, null, 2));
const response = await applicationsAPI.createLog(logData);
console.log('CreateLog response:', response);
toast.success('Application completed successfully'); toast.success('Application completed successfully');
onComplete(); onComplete();
} catch (error) { } catch (error) {
console.error('Failed to save application log:', error); console.error('Failed to save application log:', error);
toast.error('Failed to save application log'); console.error('Error details:', error.response?.data);
console.error('Full error object:', JSON.stringify(error.response || error, null, 2));
toast.error(`Failed to save application log: ${error.response?.data?.message || error.message}`);
} }
}; };