Fixed bug where could not rent 3-4 and 4-5PM
This commit is contained in:
@@ -273,37 +273,20 @@ router.post("/", authenticateToken, requireVerifiedEmail, async (req, res) => {
|
|||||||
|
|
||||||
// Check for overlapping rentals using datetime ranges
|
// Check for overlapping rentals using datetime ranges
|
||||||
// Note: "active" rentals are stored as "confirmed" with startDateTime in the past
|
// Note: "active" rentals are stored as "confirmed" with startDateTime in the past
|
||||||
|
// Two ranges [A,B] and [C,D] overlap if and only if A < D AND C < B
|
||||||
|
// Here: existing rental [existingStart, existingEnd], new rental [rentalStartDateTime, rentalEndDateTime]
|
||||||
|
// Overlap: existingStart < rentalEndDateTime AND rentalStartDateTime < existingEnd
|
||||||
const overlappingRental = await Rental.findOne({
|
const overlappingRental = await Rental.findOne({
|
||||||
where: {
|
where: {
|
||||||
itemId,
|
itemId,
|
||||||
status: "confirmed",
|
status: "confirmed",
|
||||||
[Op.or]: [
|
startDateTime: { [Op.not]: null },
|
||||||
{
|
endDateTime: { [Op.not]: null },
|
||||||
[Op.and]: [
|
[Op.and]: [
|
||||||
{ startDateTime: { [Op.not]: null } },
|
// existingStart < newEnd (existing rental starts before new one ends)
|
||||||
{ endDateTime: { [Op.not]: null } },
|
{ startDateTime: { [Op.lt]: rentalEndDateTime } },
|
||||||
{
|
// existingEnd > newStart (existing rental ends after new one starts)
|
||||||
[Op.or]: [
|
{ endDateTime: { [Op.gt]: rentalStartDateTime } },
|
||||||
{
|
|
||||||
startDateTime: {
|
|
||||||
[Op.between]: [rentalStartDateTime, rentalEndDateTime],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
endDateTime: {
|
|
||||||
[Op.between]: [rentalStartDateTime, rentalEndDateTime],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[Op.and]: [
|
|
||||||
{ startDateTime: { [Op.lte]: rentalStartDateTime } },
|
|
||||||
{ endDateTime: { [Op.gte]: rentalEndDateTime } },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -1087,6 +1070,27 @@ router.post("/cost-preview", authenticateToken, async (req, res) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for overlapping rentals (same logic as in POST /rentals)
|
||||||
|
// Two ranges overlap if: existingStart < newEnd AND existingEnd > newStart
|
||||||
|
const overlappingRental = await Rental.findOne({
|
||||||
|
where: {
|
||||||
|
itemId,
|
||||||
|
status: "confirmed",
|
||||||
|
startDateTime: { [Op.not]: null },
|
||||||
|
endDateTime: { [Op.not]: null },
|
||||||
|
[Op.and]: [
|
||||||
|
{ startDateTime: { [Op.lt]: rentalEndDateTime } },
|
||||||
|
{ endDateTime: { [Op.gt]: rentalStartDateTime } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (overlappingRental) {
|
||||||
|
return res
|
||||||
|
.status(400)
|
||||||
|
.json({ error: "Item is already booked for these dates" });
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate rental cost using duration calculator
|
// Calculate rental cost using duration calculator
|
||||||
const totalAmount = RentalDurationCalculator.calculateRentalCost(
|
const totalAmount = RentalDurationCalculator.calculateRentalCost(
|
||||||
rentalStartDateTime,
|
rentalStartDateTime,
|
||||||
|
|||||||
@@ -420,6 +420,20 @@ const RentItem: React.FC = () => {
|
|||||||
<i className="bi bi-exclamation-triangle me-2"></i>
|
<i className="bi bi-exclamation-triangle me-2"></i>
|
||||||
{dateValidationError}
|
{dateValidationError}
|
||||||
</div>
|
</div>
|
||||||
|
) : costError ? (
|
||||||
|
<div className="alert alert-danger">
|
||||||
|
<i className="bi bi-exclamation-triangle me-2"></i>
|
||||||
|
{costError}
|
||||||
|
<div className="mt-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-outline-secondary btn-sm"
|
||||||
|
onClick={() => navigate(`/items/${id}`)}
|
||||||
|
>
|
||||||
|
Choose Different Dates
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
) : !rentalDates.startDateTime ||
|
) : !rentalDates.startDateTime ||
|
||||||
!rentalDates.endDateTime ||
|
!rentalDates.endDateTime ||
|
||||||
!getRentalData() ? (
|
!getRentalData() ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user