Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 Laravel 5.x » Добавление-удаление работ в заказе » 28.02.2018 13:00:56

chizernn
Ответов: 1

Версия Laravel: 5.5.32
Версия PHP: 7.2

Делаю приложение по учету заказов компьютерного сервиса. Смысл приложения в кратце следующий. При поступлении техники на ремонт создается заказ, в котором указываются необходимые данные. Это сделано и прекрасно работает.
Затем этот заказ должен изменять мастер, в т.ч. указывая проделанные работы(услуги), их количество и стоимость каждой.
Заказы в БД хранятся в таблице orders (столбцы думаю нет смысла указывать в контексте данного вопроса).
Работы - в таблице services (id, title, price, created_at, updated_at). В столбце price указывается рекомендованная цена на работу.
Эти две таблицы имеют связь многие-ко-многим.
Связующая таблица называется order_service (id, order_id, service_id, amount, price, created_at, updated_at), где amount - количество данной услуги, price - цена (изначально сюда подставляется рекомендованная цена из таблицы services, но по логике приложения ее можно изменить).

Теперь к сути вопроса.
В форме редактирования заказа есть вкладка "Работы", в ней таблица с полями: Название работы, Кол-во, Цена. Здесь должны добавляться,редактироваться и удаляться работы.
QIP_Shot_Screen_004.png
Вопрос, как при сохранении заказа эту таблицу синхронизировать с order_service?
Пробовал приспособить сюда метод sync(). Но он тут не подходит, т.к. у нас может быть несколько строк с одинаковой работой, но разными ценами (т.е. несколько строк в order_service с одинаковыми order_id и service_id). А по логике sync() остается только 1 строка.
Может быть есть какие-то библиотеки или дополнения для laravel, ведь задача не сказать, чтобы редкая.

Код:
app\Http\Controllers\OrdersController.php

    public function update(Request $request, $id)
    {
       //валидация
        $order = Order::find($id);
        $order->update($request->all());
        //другие действия, не относящиеся к сути вопроса
        $order->setServices($request->get('servicesArr')); //работы приходят в виде массива вида servicesArr = [ ['id'=>2, 'amount'=>1, 'price'=>1000], ['id'=>3, 'amount'=>2, 'price'=>500] ]
        return redirect()->route('orders.index');
     }

app\Order.php

//...
    public function setServices($servicesArr)
    {
        if($servicesArr == null) {
            $this->services()->detach();
            return;
        }
        
        foreach ($servicesArr as $service)
        {
            if( //если запись с такой услугой не найдена или у нее другие параметры в таблице(цена, количество), то создаем ее или изменяем
                $this
                ->services()
                ->wherePivot('service_id', $service['id'])
                ->wherePivot('amount', $service['amount'])
                ->wherePivot('price', $service['price'])
                ->get()
                ->count()
                == 0 
            ) {
                $services[ $service['id'] ] = [
                    'amount' => $service['amount'],
                    'price' => $service['price']
                ];
            } else {//иначе(если точно такая же запись уже есть) просто передаем id, при этом в sync() ничего не поменяется
                $services[] = $service['id'];
            }
        }

        $this->services()->sync($services);//синхронизируем
    }

Подвал раздела