Files
alrahma_sunday_school_api/app/Services/ClassPreparation/ClassPreparationService.php
T
2026-06-08 23:30:22 -04:00

153 lines
5.7 KiB
PHP

<?php
namespace App\Services\ClassPreparation;
use App\Models\ClassSection;
class ClassPreparationService
{
private ClassPreparationContextService $context;
private ClassPreparationRosterService $roster;
private ClassPreparationInventoryService $inventory;
private ClassPreparationCalculatorService $calculator;
private ClassPreparationAdjustmentService $adjustments;
private ClassPreparationLogService $logs;
private ClassPreparationAdjustmentWriterService $adjustmentWriter;
private ClassPreparationPrintService $printService;
public function __construct(
ClassPreparationContextService $context,
ClassPreparationRosterService $roster,
ClassPreparationInventoryService $inventory,
ClassPreparationCalculatorService $calculator,
ClassPreparationAdjustmentService $adjustments,
ClassPreparationLogService $logs,
ClassPreparationAdjustmentWriterService $adjustmentWriter,
ClassPreparationPrintService $printService
) {
$this->context = $context;
$this->roster = $roster;
$this->inventory = $inventory;
$this->calculator = $calculator;
$this->adjustments = $adjustments;
$this->logs = $logs;
$this->adjustmentWriter = $adjustmentWriter;
$this->printService = $printService;
}
public function listPrep(?string $schoolYear = null, ?string $semester = null): array
{
$schoolYear = $schoolYear ?: $this->context->getSchoolYear();
$semester = $semester ?: $this->context->getSemester();
$allowed = $this->calculator->getAllowedCategories();
$limitToSemester = $this->context->hasRosterForSemester($schoolYear, $semester);
$classSections = $this->roster->getClassSectionStudentCounts($schoolYear, $semester, $limitToSemester);
$inventoryMap = $this->inventory->buildAvailability($schoolYear, $semester, $limitToSemester, $allowed);
$requiredTotals = array_fill_keys($allowed, 0);
$results = [];
foreach ($classSections as $row) {
$classSectionId = (string) $row->class_section_id;
$studentCount = (int) $row->student_count;
$classLevel = $this->calculator->getClassLevelBySection($classSectionId);
$className = ClassSection::getClassSectionNameBySectionId($classSectionId);
$baseItems = $this->calculator->calculatePrepItems($studentCount, $classLevel, $classSectionId);
[$baseItems, $adjMap] = $this->adjustments->applyAdjustments($baseItems, $classSectionId, $schoolYear);
foreach ($allowed as $cat) {
$requiredTotals[$cat] += (int) ($baseItems[$cat] ?? 0);
}
$oldSnap = $this->logs->getLatestLog($classSectionId, $schoolYear);
$oldPrep = $oldSnap ? (array) ($oldSnap->prep_data ?? []) : [];
$hasChanged = $this->logs->hasPrepChanged($baseItems, $oldPrep);
$results[] = [
'class_section' => $className,
'class_section_id' => $classSectionId,
'student_count' => $studentCount,
'class_level' => $classLevel,
'prep_items' => $baseItems,
'needs_print' => $hasChanged,
'last_printed_at' => $oldSnap?->created_at,
'adjustments' => $adjMap,
];
}
$shortages = [];
foreach ($requiredTotals as $item => $reqQty) {
$have = (int) ($inventoryMap[$item] ?? 0);
if ($have < (int) $reqQty) {
$shortages[$item] = (int) $reqQty - $have;
}
}
return [
'schoolYear' => $schoolYear,
'semester' => $semester,
'results' => $results,
'totals' => $requiredTotals,
'shortages' => $shortages,
];
}
public function markPrinted(string $schoolYear, string $semester, array $classSectionIds): int
{
$limitToSemester = $this->context->hasRosterForSemester($schoolYear, $semester);
$ids = array_values(array_unique(array_filter(array_map('strval', $classSectionIds))));
$now = $this->utcNow();
$count = 0;
foreach ($ids as $classSectionId) {
$studentCount = $this->roster->getStudentCountForSection($schoolYear, $semester, $limitToSemester, $classSectionId);
$classLevel = $this->calculator->getClassLevelBySection($classSectionId);
$className = ClassSection::getClassSectionNameBySectionId($classSectionId) ?? $classSectionId;
$items = $this->calculator->calculatePrepItems($studentCount, $classLevel, $classSectionId);
[$items] = $this->adjustments->applyAdjustments($items, $classSectionId, $schoolYear);
if ($this->logs->createLog($classSectionId, $className, $schoolYear, $items, $now)) {
$count++;
}
}
return $count;
}
public function saveAdjustments(string $classSectionId, string $schoolYear, array $adjustments): int
{
$schoolYear = $schoolYear !== '' ? $schoolYear : $this->context->getSchoolYear();
return $this->adjustmentWriter->saveAdjustments(
$classSectionId,
$schoolYear,
$adjustments,
$this->calculator->getAllowedCategories()
);
}
public function printPrep(string $classSectionId, string $schoolYear, ?string $semester = null): array
{
return $this->printService->printPrep($classSectionId, $schoolYear, $semester);
}
private function utcNow(): string
{
if (function_exists('utc_now')) {
return (string) utc_now();
}
return now('UTC')->toDateTimeString();
}
}