orderBy('created_at', 'desc')->get(); } public function findById(int $id): ?ClassPackage { return ClassPackage::with('products')->find($id); } public function create(array $data): ClassPackage { $materials = $data['materials'] ?? []; unset($data['materials']); $data['contract_material_value'] = $this->calcMaterialValue($materials); $package = ClassPackage::create($data); $this->syncMaterials($package, $materials); $this->replicateToAllUnits($package->load('products')); return $package->load('products'); } public function update(int $id, array $data): ?ClassPackage { $package = $this->findById($id); if (!$package) return null; $materials = $data['materials'] ?? null; unset($data['materials']); if ($materials !== null) { $data['contract_material_value'] = $this->calcMaterialValue($materials); } $package->update($data); if ($materials !== null) { $this->syncMaterials($package, $materials); } return $package->fresh('products'); } public function delete(int $id): bool { $package = ClassPackage::find($id); if (!$package) return false; return $package->delete(); } public function replicateToAllUnits(ClassPackage $package): void { Unit::all()->each(function (Unit $unit) use ($package) { $this->unitService->replicateFromBasePackage($unit->id, $package); }); } private function syncMaterials(ClassPackage $package, array $materials): void { $syncData = []; foreach ($materials as $m) { $syncData[$m['product_id']] = [ 'quantity' => $m['quantity'], 'price' => $m['price'], ]; } $package->products()->sync($syncData); } private function calcMaterialValue(array $materials): float { return array_reduce($materials, fn($carry, $m) => $carry + ($m['quantity'] * $m['price']), 0.0); } }