diff --git a/mirzaev/skillparts/system/config/web.php.example b/mirzaev/skillparts/system/config/web.php.example index 82d1c6b..06ea121 100644 --- a/mirzaev/skillparts/system/config/web.php.example +++ b/mirzaev/skillparts/system/config/web.php.example @@ -86,11 +86,13 @@ $config = [ 'modules' => [ 'exchange' => [ 'class' => 'carono\exchange1c\ExchangeModule', + 'exchangeDocuments' => true, + 'validateModelOnSave' => true, 'groupClass' => 'app\models\SupplyGroup', 'productClass' => 'app\models\Supply', 'offerClass' => 'app\models\SupplyEdgeProduct', 'partnerClass' => 'app\models\Account', - 'documentClass' => 'app\models\Purchase', + 'documentClass' => 'app\models\Order', 'auth' => function ($mail, $pswd) { // Необходимо уничтожить AccountForm // return (new \app\models\AccountForm())->authentication($mail, $pswd); diff --git a/mirzaev/skillparts/system/models/Order.php b/mirzaev/skillparts/system/models/Order.php index 2779396..1c7e149 100644 --- a/mirzaev/skillparts/system/models/Order.php +++ b/mirzaev/skillparts/system/models/Order.php @@ -5,33 +5,43 @@ declare(strict_types=1); namespace app\models; use yii; -use yii\web\User as Account; -use app\models\traits\SearchByEdge; +use app\models\Account; +use app\models\Product; +use app\models\SupplyEdgeProduct; +use app\models\traits\Xml2Array; -use Exception; +use carono\exchange1c\interfaces\OfferInterface; +use carono\exchange1c\interfaces\ProductInterface; +use carono\exchange1c\controllers\ApiController; + +use exception; /** - * Заказ + * Поставка (выгрузка товаров от поставщиков) * - * @see Account Заказчик - * @see Supply Поставки для заказа + * Представляет собой предложения от поставщиков которые добавляются + * в универсальные лоты товаров в асспортименте магазина + * + * @see Product Продукт (туда добавляются поставки) */ -class Order extends Document +class Supply extends Product implements ProductInterface, OfferInterface { - use SearchByEdge; + use Xml2Array; /** - * Поставки для записи + * Количество + * + * Используется при выводе в корзине */ - public array $supplies; + public int $amnt = 0; /** * Имя коллекции */ public static function collectionName(): string { - return 'order'; + return 'supply'; } /** @@ -42,7 +52,10 @@ class Order extends Document return array_merge( parent::attributes(), [ - 'stts' + 'cost', + 'onec', + 'oemn', + 'ocid' ] ); } @@ -55,7 +68,10 @@ class Order extends Document return array_merge( parent::attributeLabels(), [ - 'stts' => 'Статус' + 'cost' => 'Стоимость (cost)', + 'onec' => 'Данные 1С', + 'oemn' => 'OEM-номера', + 'ocid' => 'Идентификатор 1C (ocid)' ] ); } @@ -68,302 +84,492 @@ class Order extends Document return array_merge( parent::rules(), [ - [ - 'stts', - 'string', - 'message' => '{attribute} должен быть строкой' - ], - [ - 'stts', - 'default', - 'value' => 'preparing' - ] + // [ + // [ + // 'oemn' + // ], + // 'arrayValidator', + // 'message' => '{attribute} должен быть массивом.' + // ] ] ); } /** - * Подключение к аккаунту + * После сохранения */ - public function connect(Account $account): ?AccountEdgeOrder + public function afterSave($data, $vars): void { - // Запись ребра: АККАУНТ -> ЗАКАЗ - return AccountEdgeOrder::write($account->id, $this->readId(), 'current') ?? throw new Exception('Не удалось инициализировать ребро: АККАУНТ -> ЗАКАЗ'); + if (AccountEdgeSupply::searchByVertex(yii::$app->user->id, $this->readId())) { + // Ребро: "АККАУНТ -> ПОСТАВКА" уже существует + + } else { + // Ребра не существует + + // Запись ребра: АККАУНТ -> ПОСТАВКА + (new AccountEdgeSupply)->write(yii::$app->user->id, $this->readId(), 'import'); + } } /** - * Запись товара - * - * $supply = [ Supply $supply, int $amount = 1 ] - * - * @param Supply|array $supply Поставка - * @param Account $trgt Заказчик - * - * @return int Количество записанных поставок - * - * @todo Создать параметр разделителя для администрации + * Запись реквизитов из 1С */ - public function writeSupply(Supply|string|array $supply, Account $trgt = null): int + public function setRequisite1c($name, $value): mixed { - // Инициализация - $trgt ?? $trgt = yii::$app->user ?? throw new Exception('Не удалось инициализировать заказчика'); - - if ($supply instanceof Supply) { - // Передана инстанция класса поставки или второй элемент массива не является числом - - // Унификация входных данных - $supply = [$supply->catn => 1]; - } - - if (is_null($this->_key)) { - // Корзина не инициализирована - - // Инициализация - if (!$this->save()) { - // Инициализация заказа не удалась - - throw new Exception('Ошибка при записи заказа в базу данных'); - } - - // Инициализация ребра: АККАУНТ -> ЗАКАЗ - if (!AccountEdgeOrder::write($trgt->readId(), $this->readId(), 'create')) { - // Инициализация не удалась - - throw new Exception('Ошибка при записи ребра от аккаунта до заказа в базу данных'); - } - } - - // Инициализация - $amount = 0; - - foreach (is_array($supply) ? $supply : [$supply => 1] as $supply_raw => $amount_raw) { - // Перебор поставок - - for ($i = 0; $i < $amount_raw; $i++) { - // Создание рёбер соразмерно запросу (добавление нескольких продуктов в корзину) - - // Запись ребра: ЗАКАЗ -> ПОСТАВКА - if (!$supply_model = Supply::searchByCatn($supply_raw) or !OrderEdgeSupply::write($this->readId(), $supply_model->readId(), 'write')) { - // Поставка не найдена или запись ребра не удалась - - continue; - } else { - // Ребро создано (товар подключен к заказу) - - // Постинкрементация счётчика добавленных товаров - $amount++; - - // Запись в журнал - $this->journal('write', ['target' => $supply_model->readId()]); - } - } - } - - if ($amount === 0) { - // Отправка уведомления - self::notification('Неудачная попытка добавить товар в корзину'); - } else if ($amount === 1) { - // Отправка уведомления - self::notification('Товар ' . $supply_model->catn . ' добавлен в корзину'); - } else { - // Отправка уведомления - self::notification('Добавлено ' . $amount . ' товаров в корзину'); - } - - return $amount; + return true; } /** - * Удаление поставки - * - * @param Supply|string|array $supply Товары - * - * @return int Количество удалённых рёбер + * Запись группы из 1С */ - public function deleteSupply(Supply|string|array $supply): int + public function setGroup1c($group): mixed { - // Инициализация - $amount = 0; + // Чтение группы + // if ($group = SupplyGroup::readByOcid($group->id)) { + // // Запись ребра: ПОСТАВКА => ГРУППА ПОСТАВОК + // return static::writeEdgeBetweenGroup(static::collectionName() . '/' . $this->_key, $group->collectionName() . '/' . $group->_key); + // } - if ($supply instanceof Supply) { - // Передана инстанция класса поставки или второй элемент массива не является числом - - // Унификация входных данных - $supply = [$supply->catn => 1]; - } - - foreach (is_array($supply) ? $supply : [$supply => 1] as $catn => $amount_raw) { - // Перебор товаров - - if ($supply = Supply::searchByCatn($catn)) { - foreach (OrderEdgeSupply::searchByVertex($this->readId(), $supply->readId(), limit: $amount_raw) as $edge) { - // Перебор рёбер до продукта (если товаров в заказе несколько) - - // Удаление - $edge->delete(); - - // Запись в журнал - $this->journal('delete', ['target' => $supply->readId()]); - - // Постинкрементация счётчика удалённых рёбер - $amount++; - } - } - } - - if ($amount === 0) { - // Отправка уведомления - self::notification('Неудачная попытка удалить товар из корзины'); - } else if ($amount === 1) { - // Отправка уведомления - self::notification('Товар ' . $supply->catn . ' удалён из корзины'); - } else { - // Отправка уведомления - self::notification('Удалено ' . $amount . ' товаров из корзины'); - } - - return $amount; + return true; } /** - * Поиск заказа + * Поиск через связь с аккаунтом + * + * @param string|null $id Идентификатор пользователя + * @param string|array|null $select Запрашиваемые значения */ - public static function search(Account $account = null, string $type = 'current', int $limit = 1, int $page = 1, string $select = null): self|array|null + public static function searchByAccount(string|null $id = null, string|array|null $select = null, int|null $limit = 10): array { - // Инициализация - $account or $account = yii::$app->user ?? throw new Exception('Не удалось инициализировать пользователя'); + isset($id) ?: $id = yii::$app->user->id ?? throw new Exception('Не найден идентификатор'); - // Генерация сдвига по запрашиваемым данным (пагинация) - $offset = $limit * ($page - 1); - - if (strcasecmp($type, 'all') !== 0) { - // Если не указан параметр поиска всех заказов - - $where_type = [ - 'account_edge_order.type' => $type - ]; - } else { - $where_type = []; - } - - $return = self::searchByEdge( + return self::searchByEdge( from: 'account', - to: 'order', - subquery_where: [ - [ - 'account._id' => $account->id - ], - $where_type - ], - foreach: ['edge' => 'account_edge_order'], - where: 'edge._to == order._id', - limit: $limit, - offset: $offset, - sort: ['DESC'], - select: $select, - direction: 'INBOUND' - ); - - return $limit === 1 ? $return[0] ?? null : $return; - } - - /** - * Поиск содержимого заказа - * - * @todo В будущем возможно заказ не только поставок реализовать - */ - public function content(int $limit = 1, int $page = 1): Supply|array|null - { - // Генерация сдвига по запрашиваемым данным (пагинация) - $offset = $limit * ($page - 1); - - // Поиск рёбер: ЗАКАЗ -> ПОСТАВКА - $supplies = Supply::searchByEdge( - from: 'order', to: 'supply', - edge: 'order_edge_supply', subquery_where: [ [ - 'order._id' => $this->readId() + 'account._id' => $id ] ], - foreach: ['edge' => 'order_edge_supply'], - where: 'edge._to == supply._id', - limit: $limit, - offset: $offset, - direction: 'INBOUND' + where: 'supply._id == account_edge_supply[0]._to AND supply.onec["ЗначенияСвойств"] != null', + select: $select, + limit: $limit ); - - // Инициализация реестра дубликатов - $registry = []; - - // Подсчёт и перестройка массива для очистки от дубликатов - foreach ($supplies as $key => &$supply) { - // Перебор поставок - - if (in_array($supply->catn, $registry)) { - // Если данная поставка найдена в реестре - - // Удаление - unset($supplies[$key]); - - // Пропуск итерации - continue; - } - - // Инициализация - $amount = 0; - - // Повторный перебор для поиска дубликатов - foreach ($supplies as &$supply4check) { - if ($supply == $supply4check) { - // Найден дубликат - - // Постинкрементация счётчика - $amount++; - - // Запись в реестр - $registry[] = $supply4check->catn; - } - } - - // Запись количества для заказа - $supply->amnt = $amount; - } - - // Поиск стоимости для каждой поставки - foreach ($supplies as $key => &$supply) { - // Перебор поставок - - // Чтение стоимости - $cost = $supply->readCost(); - - if ($cost < 1) { - // Если стоимость равна нулю (явная ошибка) - - // Удаление из базы данных - $this->deleteSupply($supply->readId()); - - // Удаление из списка - unset($supplies[$key]); - - // Пропуск итерации - continue; - } - - // Запись цены - $supply->cost = $cost['ЦенаЗаЕдиницу'] . ' ' . $cost['Валюта']; - } - - return $supplies; } /** - * Отправка уведомления + * Запись данных свойств по UUID 1C + * + * Ищет записанные свойства из 1C по их идентификатору и добавляет к ним + * недостающие данные. Это костыль оставшийся от реляционных баз данных + * + * @todo Понять что может храниться внутри "$model->onec['ЗначенияСвойств']['ЗначенияСвойства']" и переписать */ - public static function notification(string $text, string|null $type = Notification::TYPE_NOTICE): Notification|array|null + public static function createProperties1c($properties, Account|null $account = null): void { - // Отправка - return Notification::_write($text, type: $type); + // Инициализация + $account ?? $account = yii::$app->user->identity; + $models = self::searchByAccount($account->readId()); + $properties = self::xml2array($properties->xml); + + $account->on(ApiController::EVENT_AFTER_OFFER_SYNC, self::afterImport1c()); + + foreach ($models as $model) { + // Перебор записей + + // Инициализация + $changes = false; + $transit = $model->onec; + + foreach ($model->onec['ЗначенияСвойств'] as $attribute_name => $attribute_value) { + // Перебор аттрибутов + + foreach ($properties as $property) { + // Перебор свойств + + if (is_array($attribute_value) && is_array($property) && $attribute_value['Ид'] === $property['Ид']) { + // Совпадение идентификаторов + + // Объединение данных + $transit['ЗначенияСвойств'][$attribute_name] = array_merge($attribute_value, $property, $transit['ЗначенияСвойств'][$attribute_name]); + + // Запись индикатора наличия изменений + $changes = true; + } else { + // Объединение данных + $transit['ЗначенияСвойств'][$attribute_name] = $property; + } + } + } + + if ($changes) { + // Если указано, что записаны изменения + + // Настройка ($transit нужен из-за особенностей __set()) + $model->onec = $transit; + + foreach ($model->onec['ЗначенияСвойств'] as $property) { + // Перебор всех свойств + + if (is_array($property)) { + // if ($property['Ид'] === $account->opts['import_sections_oem']) { + // // Если идентификатор свойства совпадает с указанным в настройках свойства хранящего OEM номера + + // Настройка + $model->catn = $property['Значение']; + // } + } + } + + // Запись + $model->save(); + } + } + } + + /** + * Запись параметров из 1С + */ + public function setProperty1c($property): mixed + { + return true; + } + + /** + * Запись изображений из 1С + * + * @todo Добавить параметры в админ-панель + * Запретить доступ к изображениям + */ + public function addImage1c($path, $caption): bool + { + // Инициализация + $i = 0; + + if (!file_exists(YII_PATH_PUBLIC . $catalog = '/img/supplies/' . $this->_key)) { + // Директория для изображений продукта не найдена + + if (!mkdir(YII_PATH_PUBLIC . $catalog, 0775, true)) { + // не удалось записать директорию + + return false; + }; + } + + foreach ($this->imgs ?? [] as $image) { + // Перебор имеющихся изображений + + if ($path === $image['sorc']) { + // Изображение уже записано на сервер + + return true; + } + } + + // Инициализация + $urn = basename($path); + + // Запись + copy($path, $path_local = YII_PATH_PUBLIC . $catalog . '/' . $urn); + + // Запись свойства + $this->imgs = array_merge( + $this->imgs ?? [], + [ + [ + 'dscr' => $caption, + 'path' => $path_local, + 'sorc' => $path + ] + ] + ); + + // Отправка в базу данных + return $this->update(); + } + + /** + * Запись ребра (предложения от поставок к продуктам) из 1С + * + * @todo Разобраться зачем нужно возвращать SupplyEdgeProduct + * Вернуть создание карточек, но только по условиям (загрузка от админа, например) + */ + public function getOffer1c($offer): SupplyEdgeProduct + { + if (empty($this->catn)) { + // Не передан каталожный номер + + // Разработчику библеотеки надо дать по жопе + return new SupplyEdgeProduct; + } + + if ( + !yii::$app->user->isGuest + && yii::$app->user->identity->agnt + && (yii::$app->user->identity->type === 'administrator' + || yii::$app->user->identity->type === 'moderator') + ) { + // Пользователь аутентифицирован и авторизован + + // Инициализация п̸̨͇͑͋͠р̷̬̂́̀̊о̸̜̯̹̅͒͘͝д̴̨̨̨̟̈́̆у̴̨̭̮̠́͋̈́к̴̭͊̋̎т̵̛̣͈̔̐͆а̵̨͖͑ + $product = self::initEmpty($this->catn); + + if (!is_array($product)) { + // Создался только один товар и вернулся в виде модели + + $product = [$product]; + } + + if (is_array($this->oemn)) { + // Значение OEM было инициализировано + + foreach ($this->oemn as $oem) { + // Перебор артикулов из массива ОЕМ-номеров + + // Инициализация и запись + $product[] = self::initEmpty($oem); + } + } + + foreach ($product as $product) { + // Перебор всех инициализированных продуктов + + if ($this->catn !== $product->catn) { + // Каталожные номера не соответствуют друг другу + + continue; + } + + // Код ниже скорее всего устарел + + if (SupplyEdgeProduct::searchByVertex($this->readId(), $product->readId())) { + // Ребро уже существует + + continue; + } + + // Запись ребра: ПОСТАВКА -> ПРОДУКТ + $return = (new SupplyEdgeProduct)->write( + $this->readId(), + $product->readId(), + 'connect', + [ + 'onec' => self::xml2array($offer->xml) + ] + ); + } + } + + // Возвращает последнее сохранённое ребро + // Надо будет с этим разобраться + return $return ?? new SupplyEdgeProduct(); + } + + /** + * Запись продукта из 1С (поставка) + * + * @see Supply + * + * @todo Понять что может храниться внутри "$model->onec['ЗначенияСвойств']['ЗначенияСвойства']" и переписать + * Разобраться и создать возможность загрузки от лица другого аккаунта + */ + public static function createModel1c($product): ?self + { + // Инициализация + $model = self::searchByOcid($id = (string) $product->Ид) ?? new self; + $account ?? $account = yii::$app->user->identity; + + // Настройка + $model->ocid = $id ?? null; + $model->catn = (string) $product->Артикул; + $model->dscr = (string) $product->Описание; + $model->onec = self::xml2array($product->xml); + + if (isset($model->onec['ЗначенияСвойств'])) { + // Свойства инициализированы + + foreach ($model->onec['ЗначенияСвойств'] as $property) { + // Перебор всех свойств + + if (is_array($property)) { + if (!empty($account->opts['import_sections_oem']) && $property['Ид'] === $account->opts['import_sections_oem']) { + // Если идентификатор свойства совпадает с указанным в настройках свойства хранящего OEM номера + + // Настройка + $model->oemn = array_merge(self::searchOemn($property['Значение']), self::searchOemn((string) $product->Артикул)); + } + } + } + } + + // Запись + if ($model->save()) { + // Поставка успешно сохранена + + return $model; + } + + return null; + } + + /** + * @param mixed|null $context + * @return array + */ + public function getExportFields1c($context = null) { + return $this->onec; + } + + /** + * Инициализация продукта + * + * @param string $catn Артикул, каталожный номер + */ + public static function initEmpty(string $catn): Product|array + { + $oemn = self::searchOemn($catn); + + if (count($oemn) === 1) { + // Передан только один артикул + + if ($model = Product::searchByCatn($catn)) { + // Продукт уже существует + + return $model; + } + + // Запись пустого продукта + return Product::writeEmpty($catn); + } + + // Инициализация + $models = []; + + foreach ($oemn as $catn) { + // Перебор всех найденных артикулов + + if ($model = Product::searchByCatn($catn)) { + // Продукт уже существует + + continue; + } + + // Запись + if ($model = Product::writeEmpty($catn)) { + // Записано + + // Запись в массив сохранённых моделей + $models[] = $model; + } + } + + return $models; + } + + /** + * Поиск OEM номеров + * + * @param string $oemn Необработанная строка с OEM-номерами + * @param string $delimiters Разделители + * + * @todo НЕ ЗАБЫТЬ СДЕЛАТЬ НАСТРОЙКУ РАЗДЕЛИТЕЛЕЙ + * + * @return array OEM-номера + */ + public static function searchOemn(string $oemn, string $delimiters = '\s\+\/,'): array + { + // Инициализация + $catn = []; + + // Конвертация + preg_match_all("/[^$delimiters]+/", $oemn, $catn); + + return $catn[0]; + } + + /** + * Запись цены из 1С + */ + public function setPrice1c($price) + { + } + + /** + * @param $types + * @return void + */ + public static function createPriceTypes1c($types) { + } + + /** + * offers.xml > ПакетПредложений > Предложения > Предложение > ХарактеристикиТовара > ХарактеристикаТовара + * + * Характеристики товара + * $name - Наименование + * $value - Значение + * + * @param \Zenwalker\CommerceML\Model\Simple $specification + * @return void + */ + public function setSpecification1c($specification) { + + } + + /** + * Запись данных на случай ошибки при экспорте из 1С + */ + public function setRaw1cData($cml, $object): bool + { + return true; + } + + /** + * Поиск по идентификатору из 1С + * + * @param string $ocid Идентификатор из 1С + * + * @return Supply|null + */ + public static function searchByOcid(string $ocid): ?Supply + { + return static::findOne([static::getIdFieldName1c() => $ocid]); + } + + /** + * Чтение группы из 1С + */ + public function getGroup1c(): ?SupplyGroup + { + return new SupplyGroup(); + } + + /** + * Чтение названия поля в котором хранится идентификатор из 1С + */ + public static function getIdFieldName1c(): string + { + return 'ocid'; + } + + /** + * Поиск по OEM-номерам + * + * @todo Реализовать с помощью LIKE + */ + public static function searchByOemn(): array + { + return []; + } + + /** + * Прочитать стоимость + */ + public function readCost(Product $product = null): array + { + if (isset($product)) { + return SupplyEdgeProduct::searchByVertex($this->readId(), $product->readId(), type: 'connect', limit: 1)['onec']['Цены']['Цена']; + } + + return SupplyEdgeProduct::search($this->readId(), type: 'connect', limit: 1)['onec']['Цены']['Цена']; } } diff --git a/mirzaev/skillparts/system/models/Product.php b/mirzaev/skillparts/system/models/Product.php index 0b3945c..126a4dd 100644 --- a/mirzaev/skillparts/system/models/Product.php +++ b/mirzaev/skillparts/system/models/Product.php @@ -9,9 +9,10 @@ use yii\web\UploadedFile; use yii\imagine\Image; use app\models\traits\SearchByEdge; -use Exception; use moonland\phpexcel\Excel; +use Exception; + /** * Продукт (в ассортименте магазина) * diff --git a/mirzaev/skillparts/system/models/Purchase.php b/mirzaev/skillparts/system/models/Purchase.php deleted file mode 100644 index a88584f..0000000 --- a/mirzaev/skillparts/system/models/Purchase.php +++ /dev/null @@ -1,66 +0,0 @@ -andWhere(['status_id' => 2])->all(); - } - - /** - * @return OfferInterface[] - */ - public function getOffers1c(): mixed - { - return true; - } - - public function getRequisites1c(): mixed - { - return true; - } - - /** - * Получаем контрагента у документа - * - * @return PartnerInterface - */ - public function getPartner1c(): Account - { - // !!!!!!!!!!!!!!!!!!! - return $this->user ?? new Account; - } - - public function getExportFields1c($context = null) - { - return []; - } - - /** - * Возвращаем имя поля в базе данных, в котором хранится ID из 1с - * - * @return string - */ - public static function getIdFieldName1c() - { - return 'onec["Ид"]'; - } - - public function setRaw1cData($cml, $object): void - { - } -} diff --git a/mirzaev/skillparts/system/models/PurchaseEdgeSupply.php b/mirzaev/skillparts/system/models/PurchaseEdgeSupply.php deleted file mode 100644 index 487a1c8..0000000 --- a/mirzaev/skillparts/system/models/PurchaseEdgeSupply.php +++ /dev/null @@ -1,13 +0,0 @@ - 'Стоимость (cost)', 'onec' => 'Данные 1С', + 'oemn' => 'OEM-номера', 'ocid' => 'Идентификатор 1C (ocid)' ] ); @@ -410,12 +412,45 @@ class Supply extends Product implements ProductInterface return null; } + /** + * @param $types + * @return void + */ + public static function createPriceTypes1c($types) { + return 100; + } + + /** + * offers.xml > ПакетПредложений > Предложения > Предложение > ХарактеристикиТовара > ХарактеристикаТовара + * + * Характеристики товара + * $name - Наименование + * $value - Значение + * + * @param \Zenwalker\CommerceML\Model\Simple $specification + * @return void + */ + public function setSpecification1c($specification) { + + } + + /** + * @param mixed|null $context + * @return array + */ + public function getExportFields1c($context = null) { + return [ + 'Ид' => 'ocid', + 'Наименование' => 'catn' + ]; + } + /** * Инициализация продукта * * @param string $catn Артикул, каталожный номер */ - public static function initEmpty(string $catn): self|array + public static function initEmpty(string $catn): Product|array { $oemn = self::searchOemn($catn); diff --git a/mirzaev/skillparts/system/models/SupplyGroup.php b/mirzaev/skillparts/system/models/SupplyGroup.php index fb56e23..0f2dc92 100644 --- a/mirzaev/skillparts/system/models/SupplyGroup.php +++ b/mirzaev/skillparts/system/models/SupplyGroup.php @@ -4,10 +4,11 @@ declare(strict_types=1); namespace app\models; +use carono\exchange1c\interfaces\GroupInterface; /** * Группировка поставок */ -class SupplyGroup extends ProductGroup +class SupplyGroup extends ProductGroup implements GroupInterface { /** * Имя коллекции @@ -16,4 +17,9 @@ class SupplyGroup extends ProductGroup { return 'supply_group'; } + + + public static function createTree1c($groups): Document|null { + return null; + } } diff --git a/mirzaev/skillparts/system/models/traits/SearchByEdge.php b/mirzaev/skillparts/system/models/traits/SearchByEdge.php index 6d51a34..1065b9b 100644 --- a/mirzaev/skillparts/system/models/traits/SearchByEdge.php +++ b/mirzaev/skillparts/system/models/traits/SearchByEdge.php @@ -22,13 +22,13 @@ trait SearchByEdge string $from, string $to, string|null $edge = null, + string $direction = 'ANY', int|null $limit = 10, int|null $offset = 0, array $sort = ['ASC'], string|array $subquery_where = [], array $foreach = [], string|array $where = [], - string $direction = 'ANY', array|null $let = [], string|array $select = null, callable|null $handle = null, @@ -41,7 +41,8 @@ trait SearchByEdge ->in($edge ?? $from . '_edge_' . $to) ->where($subquery_where); - $subquery = $subquery->select($edge ?? $from . '_edge_' . $to) + $subquery = $subquery + ->select($edge ?? $from . '_edge_' . $to) ->createCommand(); $query = static::find() diff --git a/mirzaev/skillparts/system/views/cart/index.php b/mirzaev/skillparts/system/views/cart/index.php index 17345f7..9a74f08 100644 --- a/mirzaev/skillparts/system/views/cart/index.php +++ b/mirzaev/skillparts/system/views/cart/index.php @@ -36,7 +36,7 @@ $supply->catn