Изменение цен заказа пир изменении его составляющих.

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Аватара пользователя
Neuromance
Сообщения: 716
Зарегистрирован: 2011.09.06, 13:04

Изменение цен заказа пир изменении его составляющих.

Сообщение Neuromance »

Всем привет.

Делаю туристический портал.

Имеется много сущностей.
Например, поставщик создает экскурсию, привязывает к ней транспорт, гида, которых пользователь при желании может дозаказать, назначает им цену и другие параметры.
Пользователь выбирает экскурсию, выбирает транспорт, гида и т.д. После этого оформляет заказ.

Заказ(Order) имеет поле cost - стоимость. Это поле расчитывается из разных составляющих заказа(Гидов, транспорта, базовой цены) и для удобства сохраняется в БД.

Вопрос в том, как поддерживать актуальность этого значения cost у заказа.
Сейчас пока сделал так

Код: Выделить всё

  // Изменение модели гида
  
  /**
     * @inheritdoc
     */
    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);
        
        if(!$insert){
            $this->relatedOrderServiceGuideChange();
        }
    }
    
    /**
     *  @inheritdoc
     */
    public function afterDelete()
    {
        parent::afterDelete();
        
        $this->relatedOrderServiceGuideDelete();
    }
    
    /**
     * Список гидов в подзаказах
     * @return array|\backend\modules\order\models\OrderServiceGuide[]
     */
    public function getOrderServiceGuides()
    {
        $serviceTourGuide = $this->serviceTourGuide;
        return OrderServiceGuide::find()
            ->innerJoinWith([
                'orderService' => function($query) use($serviceTourGuide) {
                    $query->andWhere([
                        'service_id' => $serviceTourGuide->service_id,
                    ]);
                }
            ])
            ->andWhere([
                'language_url' => $serviceTourGuide->language_url
            ])
            ->all();
    }
    
    /**
     *  Изменяем связанные гиды в закзах.
     */
    public function relatedOrderServiceGuideChange()
    {
        foreach ($this->getOrderServiceGuides() as $orderServiceGuide){
            $orderServiceGuide->trigger(OrderServiceGuide::EVENT_CHANGE_COST_ORDER_SERVICE_GUIDE);
        }
    }
    
    /**
     *  Удаляем связанные гиды в закзах.
     */
    public function relatedOrderServiceGuideDelete()
    {
        foreach ($this->getOrderServiceGuides() as $orderServiceGuide){
            $orderServiceGuide->delete();
        }
    }
Т.е. при изменении составляющих гида(например цены, валюты и т.д.) должны пересчитываться стоимости всех зависящих от него заказов.
Событие OrderServiceGuide::EVENT_CHANGE_COST_ORDER_SERVICE_GUIDE вызывает пересчет стоимости заказа.

На этапе разработки меня такое решение устраивает. Но, думаю, что если гид будет привязан к сотне или тысяче заказов, то вся эта цепочка событий с поочередным изменением каждой записи заказа выльется в нормальные такие тормоза..

Что тут можно сделать? Из идей есть только еще обновлять значения заказов по крону раз в день. И считать, что изменения, внесенные , например, поставщиком услуги, вступают в силу через день.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Изменение цен заказа пир изменении его составляющих.

Сообщение zelenin »

использовать очереди.
На событие повесить единственный обработчик, отсылающий в rabbitmq (к примеру) тип и id сущности.
Дальше rabbitmq кидает эти данные в обработчик задачи, и обработчик апдейтит.
Это позволит разгрузить основное приложение и позволит менять цены близко к риалтайму.
Ну или крон раз в 5 минут например. Зависит от загрузки. Если периодичность задач в среднем 1 штука в 5 минут, то быстрее крон реализовать. Если 5 в минуту, что вряд ли, то rabbit.
Ответить