CREATE TABLE leases ( id INT PRIMARY KEY, unit_id INT, weekly_rent DECIMAL(10,2), start_date DATE, end_date DATE, total_free_weeks INT DEFAULT 0 ); CREATE TABLE rent_free_weeks ( id INT PRIMARY KEY, lease_id INT, week_start_date DATE, week_end_date DATE, reason VARCHAR(50) -- 'promotional', 'move-in special' ); Step 1 – Calculate Adjusted Rent function calculateAdjustedMonthlyRent($weeklyRent, $totalWeeks, $freeWeeks, $paymentFrequency = 'monthly') { $payableWeeks = $totalWeeks - $freeWeeks; $totalLeaseValue = $weeklyRent * $payableWeeks; if ($paymentFrequency === 'monthly') { $totalMonths = ceil($totalWeeks / 4.33); // average weeks per month return round($totalLeaseValue / $totalMonths, 2); }

return $invoices; } If you must skip specific weeks (e.g., for reporting), calculate prorated monthly amounts:

From a coding perspective, this creates a challenge: How do you calculate monthly invoices when the tenant isn't paying for certain weeks?

function getMonthlyAmountWithSpecificFreeWeeks($leaseId, $year, $month) { $weeksInMonth = getWeeksInMonth($year, $month); $freeWeeksInMonth = countFreeWeeksForPeriod($leaseId, $year, $month); $payableWeeks = $weeksInMonth - $freeWeeksInMonth; $weeklyRent = getWeeklyRent($leaseId); return $payableWeeks * $weeklyRent; } Prorated First/Last Months If a lease starts mid‑week or mid‑month, free weeks must be prorated. Use DateTime with careful boundary checks: