const { Rental, Item, ConditionCheck, User } = require("../models"); const LateReturnService = require("./lateReturnService"); const emailServices = require("./email"); const { isActive } = require("../utils/rentalStatus"); class DamageAssessmentService { /** * Process damage assessment and calculate fees * @param {string} rentalId - Rental ID * @param {Object} damageInfo - Damage assessment information * @param {string} userId - Owner reporting the damage * @returns {Object} - Updated rental with damage fees */ static async processDamageAssessment(rentalId, damageInfo, userId) { const { description, canBeFixed, repairCost, needsReplacement, replacementCost, proofOfOwnership, actualReturnDateTime, imageFilenames = [], } = damageInfo; const rental = await Rental.findByPk(rentalId, { include: [{ model: Item, as: "item" }], }); if (!rental) { throw new Error("Rental not found"); } if (rental.ownerId !== userId) { throw new Error("Only the item owner can report damage"); } if (!isActive(rental)) { throw new Error("Can only assess damage for active rentals"); } // Validate required fields if (!description || description.trim().length === 0) { throw new Error("Damage description is required"); } if (canBeFixed && (!repairCost || repairCost <= 0)) { throw new Error("Repair cost is required when item can be fixed"); } if (needsReplacement && (!replacementCost || replacementCost <= 0)) { throw new Error( "Replacement cost is required when item needs replacement" ); } // Calculate damage fees let damageFees = 0; let feeCalculation = {}; if (needsReplacement) { // Full replacement cost damageFees = parseFloat(replacementCost); feeCalculation = { type: "replacement", amount: damageFees, originalCost: replacementCost, depreciation: 0, }; } else if (canBeFixed && repairCost > 0) { // Repair cost damageFees = parseFloat(repairCost); feeCalculation = { type: "repair", amount: damageFees, repairCost: repairCost, }; } // Process late return if applicable let lateFees = 0; let lateCalculation = null; if (actualReturnDateTime) { const lateReturn = await LateReturnService.processLateReturn( rentalId, actualReturnDateTime, `Item returned damaged: ${description}` ); lateFees = lateReturn.lateCalculation.lateFee; lateCalculation = lateReturn.lateCalculation; } // Create damage assessment record as metadata const damageAssessment = { description, canBeFixed, repairCost: canBeFixed ? parseFloat(repairCost) : null, needsReplacement, replacementCost: needsReplacement ? parseFloat(replacementCost) : null, proofOfOwnership: proofOfOwnership || [], imageFilenames, assessedAt: new Date(), assessedBy: userId, feeCalculation, }; // Update rental const updates = { status: "damaged", damageFees: damageFees, damageAssessment: damageAssessment, }; // Add late fees if applicable if (lateFees > 0) { updates.lateFees = lateFees; updates.actualReturnDateTime = new Date(actualReturnDateTime); } const updatedRental = await rental.update(updates); // Fetch owner and renter user data for email const owner = await User.findByPk(updatedRental.ownerId); const renter = await User.findByPk(updatedRental.renterId); // Send damage report to customer service for review await emailServices.customerService.sendDamageReportToCustomerService( updatedRental, owner, renter, damageAssessment, lateCalculation ); return { rental: updatedRental, damageAssessment, lateCalculation, totalAdditionalFees: damageFees + lateFees, }; } } module.exports = DamageAssessmentService;