<?php
function calculateMonthlyPayroll(PDO $pdo, string $employeeId, int $year, int $month): float
{
if ($month < 1 || $month > 12) {
throw new InvalidArgumentException('Month must be between 1 and 12');
}
// Get all active contracts for the employee in this month
$contracts = getActiveContracts($pdo, $employeeId, $year, $month);
$totalAmount = 0.0;
// Calculate previous month for revenue share considerations
$previousMonth = $month - 1;
$previousYear = $year;
if ($previousMonth < 1) {
$previousMonth = 12;
$previousYear = $year - 1;
}
// Process each contract based on role
foreach ($contracts as $contract) {
$roleCategory = $contract['role_category'];
switch ($roleCategory) {
case 'actor':
// Fixed fee installment
if ($contract['fixed_fee_total'] && $contract['filming_duration_months']) {
$totalAmount += $contract['fixed_fee_total'] / $contract['filming_duration_months'];
}
// Calculate revenue share for the previous month
if ($contract['revenue_share_percentage']) {
$revenue = getFilmRevenue($pdo, $contract['film_id'], $previousYear, $previousMonth);
if ($revenue) {
$totalAmount += $revenue * ($contract['revenue_share_percentage'] / 100);
}
}
break;
case 'production_staff':
// Production Staff: Monthly fixed amount only
if ($contract['monthly_amount']) {
$totalAmount += $contract['monthly_amount'];
}
break;
case 'senior_staff':
// Monthly fixed amount
if ($contract['monthly_amount']) {
$totalAmount += $contract['monthly_amount'];
}
// Ongoing revenue share from PREVIOUS month
if ($contract['revenue_share_percentage']) {
$revenue = getFilmRevenue($pdo, $contract['film_id'], $previousYear, $previousMonth);
if ($revenue) {
$totalAmount += $revenue * ($contract['revenue_share_percentage'] / 100);
}
}
break;
}
}
return $totalAmount;
}
// Get active contracts for an employee in a specific month.
function getActiveContracts
(PDO
$pdo, string
$employeeId, int
$year, int
$month): array {
// Calculate the first day of the month for contract validity check
$calculationDate = sprintf('%04d-%02d-01', $year, $month);
$stmt = $pdo->prepare("
SELECT
c.id,
c.fixed_fee_total,
c.monthly_amount,
c.filming_duration_months,
c.revenue_share_percentage,
r.category as role_category,
f.id as film_id
FROM contract c
INNER JOIN role r ON c.role_id = r.id
INNER JOIN film f ON c.film_id = f.id
WHERE c.employee_id = :employee_id
AND c.start_date <= :calculation_date
AND c.end_date >= :calculation_date
AND c.status = 'active'
");
$stmt->execute([
'employee_id' => $employeeId,
'calculation_date' => $calculationDate
]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// Get film revenue for a specific month.
function getFilmRevenue(PDO $pdo, string $filmId, int $year, int $month): ?float
{
$stmt = $pdo->prepare("
SELECT revenue_amount
FROM film_revenue
WHERE film_id = :film_id
AND year = :year
AND month = :month
");
$stmt->execute([
'film_id' => $filmId,
'year' => $year,
'month' => $month
]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result ? (float) $result['revenue_amount'] : null;
}