Files
rentall-app/backend/services/damageAssessmentService.js

145 lines
4.0 KiB
JavaScript

const { Rental, Item, ConditionCheck, User } = require("../models");
const LateReturnService = require("./lateReturnService");
const emailServices = require("./email");
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 (rental.status !== "active") {
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;