ClassPackageService.php 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <?php
  2. namespace App\Services;
  3. use App\Models\ClassPackage;
  4. use App\Models\Unit;
  5. use Illuminate\Database\Eloquent\Collection;
  6. class ClassPackageService
  7. {
  8. public function __construct(
  9. protected ClassPackageUnitService $unitService,
  10. ) {}
  11. public function getAll(): Collection
  12. {
  13. return ClassPackage::with('products')->orderBy('created_at', 'desc')->get();
  14. }
  15. public function findById(int $id): ?ClassPackage
  16. {
  17. return ClassPackage::with('products')->find($id);
  18. }
  19. public function create(array $data): ClassPackage
  20. {
  21. $materials = $data['materials'] ?? [];
  22. unset($data['materials']);
  23. $data['contract_material_value'] = $this->calcMaterialValue($materials);
  24. $package = ClassPackage::create($data);
  25. $this->syncMaterials($package, $materials);
  26. $this->replicateToAllUnits($package->load('products'));
  27. return $package->load('products');
  28. }
  29. public function update(int $id, array $data): ?ClassPackage
  30. {
  31. $package = $this->findById($id);
  32. if (!$package) return null;
  33. $materials = $data['materials'] ?? null;
  34. unset($data['materials']);
  35. if ($materials !== null) {
  36. $data['contract_material_value'] = $this->calcMaterialValue($materials);
  37. }
  38. $package->update($data);
  39. if ($materials !== null) {
  40. $this->syncMaterials($package, $materials);
  41. }
  42. return $package->fresh('products');
  43. }
  44. public function delete(int $id): bool
  45. {
  46. $package = ClassPackage::find($id);
  47. if (!$package) return false;
  48. return $package->delete();
  49. }
  50. public function replicateToAllUnits(ClassPackage $package): void
  51. {
  52. Unit::all()->each(function (Unit $unit) use ($package) {
  53. $this->unitService->replicateFromBasePackage($unit->id, $package);
  54. });
  55. }
  56. private function syncMaterials(ClassPackage $package, array $materials): void
  57. {
  58. $syncData = [];
  59. foreach ($materials as $m) {
  60. $syncData[$m['product_id']] = [
  61. 'quantity' => $m['quantity'],
  62. 'price' => $m['price'],
  63. ];
  64. }
  65. $package->products()->sync($syncData);
  66. }
  67. private function calcMaterialValue(array $materials): float
  68. {
  69. return array_reduce($materials, fn($carry, $m) => $carry + ($m['quantity'] * $m['price']), 0.0);
  70. }
  71. }