ScheduleController.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Events\SendWebSocketMessageEvent;
  4. use App\Helpers\DateHelper;
  5. use App\Http\Requests\CreateScheduleFromOrderRequest;
  6. use App\Http\Requests\CreateScheduleFromReclamationRequest;
  7. use App\Http\Requests\ExportScheduleRequest;
  8. use App\Http\Requests\UpdateScheduleRequest;
  9. use App\Jobs\ExportScheduleJob;
  10. use App\Jobs\NotifyManagerNewOrderJob;
  11. use App\Jobs\NotifyOrderInScheduleJob;
  12. use App\Models\Dictionary\Area;
  13. use App\Models\Dictionary\District;
  14. use App\Models\Order;
  15. use App\Models\ProductSKU;
  16. use App\Models\Reclamation;
  17. use App\Models\Role;
  18. use App\Models\Schedule;
  19. use App\Models\User;
  20. use Illuminate\Http\Request;
  21. class ScheduleController extends Controller
  22. {
  23. protected array $data = [
  24. 'active' => 'schedule',
  25. 'title' => 'График монтажей',
  26. 'id' => 'schedule',
  27. ];
  28. public function index(Request $request)
  29. {
  30. $this->data['districts'] = District::query()->get()->pluck('name', 'id');
  31. $this->data['areas'] = Area::query()->get()->pluck('name', 'id');
  32. $this->data['brigadiers'] = User::query()->where('role', Role::BRIGADIER)->get()->pluck('name', 'id');
  33. $this->data['weekNumber'] = $request->get('week' ,date('W'));
  34. $weekDates = [
  35. 'mon' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber']),
  36. 'tue' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 2),
  37. 'wed' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 3),
  38. 'thu' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 4),
  39. 'fri' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 5),
  40. 'sat' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 6),
  41. 'sun' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 7),
  42. ];
  43. $this->data['weekDates'] = $weekDates;
  44. $schedules = [];
  45. foreach ($weekDates as $date) {
  46. $schedules[$date] = null;
  47. }
  48. $result = Schedule::query()
  49. ->whereBetween('installation_date', [$weekDates['mon'], $weekDates['sun']])
  50. ->get();
  51. foreach ($result as $schedule) {
  52. $schedules[$schedule->installation_date][] = $schedule;
  53. }
  54. $this->data['schedules'] = $schedules;
  55. return view('schedule.index', $this->data);
  56. }
  57. public function createFromOrder(CreateScheduleFromOrderRequest $request)
  58. {
  59. $validated = $request->validated();
  60. // delete all auto schedules for this order
  61. if(isset($validated['delete_old_records'])) {
  62. Schedule::query()
  63. ->where('order_id', $validated['order_id'])
  64. ->where('source', 'Площадки')
  65. ->where('manual', false)
  66. ->delete();
  67. }
  68. // create all records in schedule
  69. $order = Order::query()
  70. ->where('id', $validated['order_id'])
  71. ->first();
  72. $errors = [];
  73. if(!$order->brigadier_id) $errors[] = 'Не указан бригадир!';
  74. if(!$order->installation_date) $errors[] = 'Не указана дата монтажа!';
  75. if(!$order->install_days) $errors[] = 'Не указан срок монтажа!';
  76. if($errors) {
  77. return redirect()->route('order.show', $order->id)->with(['danger' => $errors]);
  78. }
  79. if(empty($validated['skus'])) {
  80. foreach ($order->products_sku as $psku)
  81. $validated['skus'][] = $psku->id;
  82. }
  83. $mafs = [];
  84. foreach ($validated['skus'] as $skuId) {
  85. $sku = ProductSKU::query()->where('id', $skuId)->first();
  86. if(!isset($mafs[$sku->product->article])) {
  87. $mafs[$sku->product->article] = 1;
  88. } else {
  89. $mafs[$sku->product->article] += 1;
  90. }
  91. }
  92. $mafsText = '';
  93. $mafsCount = 0;
  94. foreach ($mafs as $article => $count) {
  95. $mafsText .= $article . ' - ' . $count . "\r\n";
  96. $mafsCount += $count;
  97. }
  98. $first = true;
  99. for ($iDays = 1; $iDays < $order->install_days + 1; $iDays++) {
  100. $instDate = date('Y-m-d', strtotime('+' . $iDays - 1 . ' days', strtotime($order->installation_date)));
  101. $schedule = Schedule::query()
  102. ->create([
  103. 'order_id' => $validated['order_id'],
  104. 'address_code' => $validated['order_id'],
  105. 'source' => 'Площадки',
  106. 'installation_date' => $instDate,
  107. 'manual' => false,
  108. 'district_id' => $order->district_id,
  109. 'area_id' => $order->area_id,
  110. 'object_address' => $order->object_address,
  111. 'object_type' => $order->objectType->name,
  112. 'mafs' => $mafsText,
  113. 'mafs_count' => $mafsCount,
  114. 'brigadier_id' => $order->brigadier_id,
  115. 'comment' => $validated['comment'],
  116. ]);
  117. if($first && isset($validated['send_notifications'])) {
  118. $first = false;
  119. NotifyOrderInScheduleJob::dispatch($schedule);
  120. }
  121. }
  122. return redirect()->route('schedule.index');
  123. }
  124. public function createFromReclamation(CreateScheduleFromReclamationRequest $request)
  125. {
  126. $validated = $request->validated();
  127. // delete all auto schedules for this order
  128. if(isset($validated['delete_old_records'])) {
  129. Schedule::query()
  130. ->where('address_code', 'РЕКЛ-' . $validated['reclamation_id'])
  131. ->where('source', 'Рекламации')
  132. ->where('manual', false)
  133. ->delete();
  134. }
  135. $reclamation = Reclamation::query()
  136. ->where('id', $validated['reclamation_id'])
  137. ->first();
  138. $order = $reclamation->order;
  139. $mafs = [];
  140. if(empty($validated['skus'])) {
  141. foreach ($reclamation->skus as $sku)
  142. if(!isset($mafs[$sku->product->article])) {
  143. $mafs[$sku->product->article] = 1;
  144. } else {
  145. $mafs[$sku->product->article] += 1;
  146. }
  147. }
  148. $mafsCount = 0;
  149. $mafsText = '';
  150. foreach ($mafs as $article => $count) {
  151. $mafsCount += $count;
  152. $mafsText .= $article . ' - ' . $count . "\r\n";
  153. }
  154. $first = true;
  155. for ($iDays = 1; $iDays < $reclamation->work_days + 1; $iDays++) {
  156. $instDate = date('Y-m-d', strtotime('+' . $iDays - 1 . ' days', strtotime($reclamation->start_work_date)));
  157. $schedule = Schedule::query()
  158. ->create([
  159. 'order_id' => $order->id,
  160. 'address_code' => 'РЕКЛ-' . $validated['reclamation_id'],
  161. 'source' => 'Рекламации',
  162. 'installation_date' => $instDate,
  163. 'manual' => false,
  164. 'district_id' => $order->district_id,
  165. 'area_id' => $order->area_id,
  166. 'object_address' => $order->object_address,
  167. 'object_type' => $reclamation->reason,
  168. 'mafs' => $mafsText,
  169. 'mafs_count' => $mafsCount,
  170. 'brigadier_id' => $reclamation->brigadier_id,
  171. 'comment' => $reclamation->guarantee,
  172. ]);
  173. if($first && isset($validated['send_notifications'])) {
  174. $first = false;
  175. NotifyOrderInScheduleJob::dispatch($schedule);
  176. }
  177. }
  178. return redirect()->route('schedule.index');
  179. }
  180. public function update(UpdateScheduleRequest $request)
  181. {
  182. $validated = $request->validated();
  183. if(isset($validated['id'])) {
  184. Schedule::query()
  185. ->where('id', $validated['id'])
  186. ->update($validated);
  187. $schedule = Schedule::query()->find($validated['id']);
  188. } else {
  189. $schedule = Schedule::query()
  190. ->create([
  191. 'address_code' => $validated['address_code'] ?? '-',
  192. 'installation_date' => $validated['installation_date'],
  193. 'manual' => true,
  194. 'district_id' => $validated['district_id'],
  195. 'area_id' => $validated['area_id'],
  196. 'object_address' => $validated['object_address'],
  197. 'object_type' => $validated['object_type'],
  198. 'mafs' => $validated['mafs'],
  199. 'mafs_count' => $validated['mafs_count'],
  200. 'brigadier_id' => $validated['brigadier_id'],
  201. 'comment' => $validated['comment'],
  202. ]);
  203. }
  204. NotifyOrderInScheduleJob::dispatch($schedule);
  205. return redirect()->back();
  206. }
  207. public function delete(Schedule $schedule)
  208. {
  209. $schedule->delete();
  210. return redirect()->back();
  211. }
  212. public function export(ExportScheduleRequest $request)
  213. {
  214. $startDate = $request->validated()['start_date'];
  215. $endDate = $request->validated()['end_date'];
  216. $schedules = Schedule::query()
  217. ->where('installation_date', '>=', $startDate)
  218. ->where('installation_date', '<=', $endDate)
  219. ->orderBy('installation_date')
  220. ->orderBy('brigadier_id')
  221. ->get();
  222. ExportScheduleJob::dispatch($schedules, $request->user()->id);
  223. return redirect()->route('schedule.index', ['week' => $request->validated()['week']])
  224. ->with(['success' => 'Задача генерации графика создана!']);
  225. }
  226. }