whereHas('classPackageUnit', fn ($query) => $query->where('unit_id', $unitId)) ->where('class_package_unit_id', $packageUnitId) ->get(); } public function findById(int $id, int $packageUnitId, int $unitId): ClassPackageUnitVariation { return ClassPackageUnitVariation::with('products.product') ->whereHas('classPackageUnit', fn ($query) => $query->where('unit_id', $unitId)) ->where('class_package_unit_id', $packageUnitId) ->findOrFail($id); } public function create(int $packageUnitId, int $unitId, array $data): ClassPackageUnitVariation { $packageUnit = ClassPackageUnit::with('products') ->where('unit_id', $unitId) ->findOrFail($packageUnitId); // sem lista propria a proposta herda os materiais do pacote da unidade $materials = $data['materials'] ?? $this->unitMaterials($packageUnit); unset($data['materials']); // o valor do material nao e editavel, ele acompanha a lista $data['material_value'] = $this->calcMaterialValue($materials); $data['class_package_unit_id'] = $packageUnit->id; $variation = ClassPackageUnitVariation::create($data); $this->syncProducts($variation, $materials); return $variation->load('products.product'); } public function update(int $id, int $packageUnitId, int $unitId, array $data): ClassPackageUnitVariation { $variation = $this->findById($id, $packageUnitId, $unitId); $materials = $data['materials'] ?? null; unset($data['materials']); if ($materials !== null) { $data['material_value'] = $this->calcMaterialValue($materials); } $variation->update($data); if ($materials !== null) { $this->syncProducts($variation, $materials); } return $variation->fresh('products.product'); } public function delete(int $id, int $packageUnitId, int $unitId): bool { $variation = $this->findById($id, $packageUnitId, $unitId); return $variation->delete(); } // Add custom business logic methods here private function calcMaterialValue(array $materials): float { return array_reduce($materials, fn ($carry, $material) => $carry + ($material['quantity'] * $material['price']), 0.0); } private function syncProducts(ClassPackageUnitVariation $variation, array $materials): void { $variation->products()->delete(); foreach ($materials as $material) { $variation->products()->create([ 'product_id' => $material['product_id'], 'quantity' => $material['quantity'], 'price' => $material['price'], ]); } } private function unitMaterials(ClassPackageUnit $packageUnit): array { return $packageUnit->products ->map(fn ($product) => [ 'product_id' => $product->product_id, 'quantity' => $product->quantity, 'price' => (float) $product->price, ]) ->all(); } }