122 lines
4.7 KiB
PHP
122 lines
4.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;
|
|
|
|
public function __construct(
|
|
ClassPreparationContextService $context,
|
|
ClassPreparationRosterService $roster,
|
|
ClassPreparationInventoryService $inventory,
|
|
ClassPreparationCalculatorService $calculator,
|
|
ClassPreparationAdjustmentService $adjustments,
|
|
ClassPreparationLogService $logs
|
|
) {
|
|
$this->context = $context;
|
|
$this->roster = $roster;
|
|
$this->inventory = $inventory;
|
|
$this->calculator = $calculator;
|
|
$this->adjustments = $adjustments;
|
|
$this->logs = $logs;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
private function utcNow(): string
|
|
{
|
|
if (function_exists('utc_now')) {
|
|
return (string) utc_now();
|
|
}
|
|
return now('UTC')->toDateTimeString();
|
|
}
|
|
}
|