ProductionOrderPlanningService.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Services;
  4. use App\Enums\ProductionOrderActivityType;
  5. use App\Models\ProductionOrder;
  6. use App\Models\ProductionOrderDelivery;
  7. use App\Models\ProductionOrderInstallation;
  8. use App\Models\Schedule;
  9. use App\Models\User;
  10. use Illuminate\Support\Facades\DB;
  11. class ProductionOrderPlanningService
  12. {
  13. /** @param array<string, mixed> $data */
  14. public function createDelivery(ProductionOrder $order, array $data, User $actor): ProductionOrderDelivery
  15. {
  16. return DB::transaction(function () use ($order, $data, $actor): ProductionOrderDelivery {
  17. unset($data['nav']);
  18. $delivery = $order->deliveries()->create($data + [
  19. 'created_by' => $actor->id,
  20. 'updated_by' => $actor->id,
  21. ]);
  22. $order->activities()->create([
  23. 'type' => ProductionOrderActivityType::DeliveryScheduled,
  24. 'user_id' => $actor->id,
  25. 'delivery_id' => $delivery->id,
  26. 'message' => 'Заказ добавлен в график доставок.',
  27. ]);
  28. return $delivery;
  29. });
  30. }
  31. /** @param array<string, mixed> $data */
  32. public function updateDelivery(ProductionOrderDelivery $delivery, array $data, User $actor): void
  33. {
  34. unset($data['nav']);
  35. $delivery->update($data + ['updated_by' => $actor->id]);
  36. }
  37. public function deleteDelivery(ProductionOrderDelivery $delivery): void
  38. {
  39. $delivery->delete();
  40. }
  41. /** @param array<string, mixed> $data */
  42. public function createInstallation(ProductionOrder $order, array $data, User $actor): ProductionOrderInstallation
  43. {
  44. return DB::transaction(function () use ($order, $data, $actor): ProductionOrderInstallation {
  45. unset($data['nav']);
  46. $installation = $order->installations()->create($data + [
  47. 'created_by' => $actor->id,
  48. 'updated_by' => $actor->id,
  49. ]);
  50. $order->activities()->create([
  51. 'type' => ProductionOrderActivityType::InstallationScheduled,
  52. 'user_id' => $actor->id,
  53. 'installation_id' => $installation->id,
  54. 'message' => 'Заказ добавлен в график монтажей.',
  55. ]);
  56. $this->syncInstallationSchedules($installation);
  57. return $installation;
  58. });
  59. }
  60. /** @param array<string, mixed> $data */
  61. public function updateInstallation(ProductionOrderInstallation $installation, array $data, User $actor): void
  62. {
  63. DB::transaction(function () use ($installation, $data, $actor): void {
  64. unset($data['nav']);
  65. $installation->update($data + ['updated_by' => $actor->id]);
  66. $this->syncInstallationSchedules($installation);
  67. });
  68. }
  69. public function deleteInstallation(ProductionOrderInstallation $installation): void
  70. {
  71. DB::transaction(function () use ($installation): void {
  72. $installation->schedules()->delete();
  73. $installation->delete();
  74. });
  75. }
  76. private function syncInstallationSchedules(ProductionOrderInstallation $installation): void
  77. {
  78. $installation->schedules()->delete();
  79. $order = $installation->productionOrder()->with('items.catalogItem')->firstOrFail();
  80. $equipment = $order->items
  81. ->groupBy('common_catalog_item_id')
  82. ->map(static function ($items): string {
  83. $article = $items->first()->catalogItem?->article ?? 'Без артикула';
  84. return $article.' - '.$items->count();
  85. })
  86. ->implode("\r\n");
  87. for ($offset = 0; $offset < $installation->installation_days; $offset++) {
  88. Schedule::query()->create([
  89. 'production_order_installation_id' => $installation->id,
  90. 'address_code' => $order->order_number,
  91. 'source' => Schedule::SOURCE_PRODUCTION_ORDER,
  92. 'installation_date' => $installation->installation_date->addDays($offset)->toDateString(),
  93. 'manual' => false,
  94. 'district_id' => null,
  95. 'area_id' => null,
  96. 'object_address' => $order->object_address,
  97. 'object_type' => $order->executionTypeLabel(),
  98. 'mafs' => $equipment,
  99. 'mafs_count' => $order->items->count(),
  100. 'brigadier_id' => $installation->brigadier_id,
  101. 'comment' => $installation->note,
  102. ]);
  103. }
  104. }
  105. }