Установка этого модуля, должна упрощать интеграцию 1С в ваш сайт.
Модуль содержит набор интерфейсов, которые необходимо реализовать, чтобы получить возможность обмениваться товарами и документами с 1С. Предполагается, что у Вас есть 1С:Предприятие 8, Управление торговлей", редакция 11.3, версия 11.3.2 на платформе 8.3.9.2033. Если у вас версия конфигурации ниже, то скорее всего модуль все равно будет работать, т.к. по большей части, обмен с сайтами сильно не меняется в 1С от версии к версии.
После подключения модуля к вашему проекту, вы можете получить доступ к текущей документации по ссылке /exchange/article/index
Подключение модуля =1. Подключаем пакет через компосер
composer require carono/yii2-1c-exchange
2. Подключаем модуль в конфиге приложения
'modules' => [ 'exchange' => [ 'class' => \carono\exchange1c\ExchangeModule::class ] ]
3. Если используете apache как веб сервер, не забудьте создать и настроить .htaccess в web директории
Свойства модуля обмена =Свойство | По умолчанию | Описание |
productClass | null | Класс для продукта |
offerClass | null | Класс для предложения |
documentClass | null | Класс для документа (заказа) |
groupClass | null | Класс для группы продуктов |
partnerClass | null | Класс контрагента (пользователя/клиента) |
warehouseClass | null | Класс для склада (не используется, может быть удалён) |
exchangeDocuments | false | Обмен заказами |
debug | false | Режим отладки, данные сохраняются в tmpDir |
useZip | true | Использовать архивы при обмене, если доступны |
tmpDir | @runtime/1c_exchange | Папка для временных файлов |
validateModelOnSave | false | При сохранении товара, используем валидацию или нет (может быть удалено) |
timeLimit | 1800 | Время выполнения скрипта (set_time_limit) |
memoryLimit | null | Ограничение памяти при обмене (memory_limit) |
bootstrapUrlRule | true | Автоматически подключать правило для роутинга 1c_exchange.php |
appendRule | false | Добавлять правило роутинга в конец |
auth | null | Фукнция для авторизации |
1. Устанавливаем 1С:Предприятие 8 Управление торговлей, Управление торговлей", редакция 11.3, версия 11.3.2 (магнитная ссылка), платформа 8.3.9.2033 (и выше)
Настройки будут производиться на демо версии.
2. Переходим в настройки синхронизации данных, через пункт НСИ и администрирование, или через поиск
3. Переходим в узлы обмена с сайтами
4. Создаём новый узел, и заполняем данные
Авторизация в модуле реализована через поведение \yii\filters\auth\HttpBasicAuth
'modules' => [ 'exchange' => [ 'class' => \carono\exchange1c\ExchangeModule::class, 'auth' => function ($username, $password) { if ($user = \app\models\User::findByUsername($username)) { if ($user->validatePassword($password)) { return $user; } } return false; } ] ],
Настройка модуля, указываем класс модели работы группы
[ 'exchange' => [ 'class' => \carono\exchange1c\ExchangeModule::class, 'groupClass' => \app\models\Group::class, ] ]
Миграция, создаём группу, для хранения продукции, должна быть древовидная структура с неограниченной вложенностью, рекомендуется использовать nested sets , но для примера используем более простой пример
$this->createTable('{{%group}}', [ 'id' => $this->primaryKey(), 'name' => $this->string()->comment('Наименование группы'), 'parent_id' => $this->integer()->comment('Родительская группа'), 'accounting_id' => $this->string()->comment('Код в 1С')->unique(), ]);
Список интерфейсов, которые необходимо реализовать здесь
createTree1c =В функции createTree1c нам требуется реализовать создаение всего дерева продуктов родитель->потомок. Метод вызывается только один раз перед началом импорта, поэтому в этой функции нужно создать всё дерево групп полностью.
<?php /** * This class is generated using the package carono/codegen */ namespace app\models; use carono\exchange1c\interfaces\GroupInterface; /** * This is the model class for table "group". */ class Group extends base\Group implements GroupInterface { /** * Возвращаем имя поля в базе данных, в котором хранится ID из 1с * * @return string */ public static function getIdFieldName1c() { return 'accounting_id'; } /** * Создание дерева групп * в параметр передаётся массив всех групп (import.xml > Классификатор > Группы) * $groups[0]->parent - родительская группа * $groups[0]->children - дочерние группы * * @param \Zenwalker\CommerceML\Model\Group[] $groups * @return void */ public static function createTree1c($groups) { foreach ($groups as $group) { self::createByML($group); if ($children = $group->getChildren()) { self::createTree1c($children); } } } /** * Создаём группу по модели группы CommerceML * проверяем все дерево родителей группы, если родителя нет в базе - создаём * * @param \Zenwalker\CommerceML\Model\Group $group * @return Group|array|null */ public static function createByML(\Zenwalker\CommerceML\Model\Group $group) { /** * @var \Zenwalker\CommerceML\Model\Group $parent */ if (!$model = Group::findOne(['accounting_id' => $group->id])) { $model = new self; $model->accounting_id = $group->id; } $model->name = $group->name; if ($parent = $group->getParent()) { $parentModel = self::createByML($parent); $model->parent_id = $parentModel->id; unset($parentModel); } else { $model->parent_id = null; } $model->save(); return $model; } }
Протестировать вашу реализацию, можно здесь
productClass Модель продукта =Продукт - моделью продукта является сам товар, картинки, его свойства и реквизиты, но не остаток или цена.
Для тех разработчиков, которые не очень хорошо знакомы с концепцией хранения данных в 1С, нужно дополнительно пояснение. В 1С существуют продукты и предложения. Продукт эта сама сущность товара, предложение, это то что можно продать, т.е. предложения и учавствуют в продажах.
Пример:
Туфли лабутены Модель X - это продукт, у него есть картинки, различные реквизиты (производитель, цвет, материал и т.д.), которые присущи данному продукту.
Туфли лабутены Модель X, размер 32, за 20000р - это предложение, от одного продукта может быть несколько предложений, с разными характеристиками, такими как размер, и разными ценами, на каждое предложение может быть свой остаток.
Добавляем в настройки модуля вашу модель для продукта 'productClass' => \app\models\Product::class
[ 'exchange' => [ 'class' => \carono\exchange1c\ExchangeModule::class, 'groupClass' => \app\models\Group::class, 'productClass' => \app\models\Product::class, ] ]
В вашей модели имплементируем интерфейс carono\exchange1c\interfaces\ProductInterface
setRequisite1c =Установка реквизитов для продукта. Список резвизитов находится в import.xml > Каталог > Товары > Товар > ЗначенияРеквизитов > ЗначениеРеквизита
Для хранения реквизитов, потребуется таблица реквизитов, а также сводная таблица продут+реквизит+значение
public function setRequisite1c($name, $value) { if (!$requisite = Requisite::findOne(['name' => $name])) { $requisite = new Requisite(); $requisite->name = $name; $requisite->save(); } $this->addPivot($requisite, PvProductRequisite::class, ['value' => $value]); }setGroup1c =
Установка группы, где находится продукт. Все группы у вас уже должны быть сохранены в базе, т.к. ранее вызывался метод \carono\exchange1c\interfaces\GroupInterface::createTree1c, и все дерево групп уже создано Вами, а значит можно не проверять на существование группы.
public function setGroup1c($group) { $id = Group::find()->select(['id'])->andWhere(['accounting_id' => $group->id])->scalar(); $this->updateAttributes(['group_id' => $id]); }createProperties1c =
Функция вызывается один раз при импорте, в ней необходимо создать все свойста и значения свойств.
/** * @param PropertyCollection $properties * @return mixed */ public static function createProperties1c($properties) { /** * @var \Zenwalker\CommerceML\Model\Property $property */ foreach ($properties as $property) { $propertyModel = Property::createByMl($property); foreach ($property->getAvailableValues() as $value) { if (!$propertyValue = PropertyValue::findOne(['accounting_id' => $value->id])) { $propertyValue = new PropertyValue(); $propertyValue->name = (string)$value->Значение; $propertyValue->property_id = $propertyModel->id; $propertyValue->accounting_id = (string)$value->ИдЗначения; $propertyValue->save(); unset($propertyValue); } } } }
setProperty1c =
Свойство продукта и значение свойства являются отдельными сущностями, поэтому их нужно хранить в отдельных таблицах, а значения и продукт хранить в сводной таблице.
Все свойства уже должны быть заполнены, т.к. ранее выполнялся createProperties1c($properties), поэтому можем искать свойства и значения по id.
Значение свойства могут быть как отдельной сущностью, так и простым значением, поэтому есть в xml есть поле ИдЗначения значит нужно искать в таблице со значениями, иначе должно быть просто строка или число.
* в этой фукнции используется трейт из пакета carono/yii2-migrate
/** * $property - Свойство товара (import.xml > Классификатор > Свойства > Свойство) * $property->value - Разыменованное значение (string) (import.xml > Классификатор > Свойства > Свойство > Значение) * $property->getValueModel() - Данные по значению, Ид значения, и т.д (import.xml > Классификатор > Свойства > Свойство > ВариантыЗначений > Справочник) * * @param MlProperty $property * @return void */ public function setProperty1c($property) { $propertyModel = Property::findOne(['accounting_id' => $property->id]); $propertyValue = $property->getValueModel(); if ($propertyAccountingId = (string)$propertyValue->ИдЗначения) { $value = PropertyValue::findOne(['accounting_id' => $propertyAccountingId]); $attributes = ['property_value_id' => $value->id]; } else { $attributes = ['value' => $propertyValue->value]; } $this->addPivot($propertyModel, PvProductProperty::class, $attributes); }
addImage1c =
В этой фукнции мы получаем абсолютный путь до картинки и название изрбражения (для alt аттрибута)
* в этой фукнции используются трейт из пакета carono/yii2-migrate и управление файлами из carono/yii2-file-upload
/** * @param string $path * @param string $caption * @return mixed */ public function addImage1c($path, $caption) { if (!$this->getImages()->andWhere(['md5' => md5_file($path)])->exists()) { $this->addPivot(FileUpload::startUpload($path)->process(), PvProductImage::class, ['caption' => $caption]); } }getGroup1c =
Получаем группу, где находится текущий продукт, группа должна наследовать интерфейс \carono\exchange1c\interfaces\GroupInterface
/** * @return GroupInterface */ public function getGroup1c() { return $this->group; }getOffer1c =
В эту фукнцию отправляется xml данные предложения из файла, необходимо создать или найти вашу модель предложения (интерфейс \carono\exchange1c\interfaces\OfferInterface) и вернуть в результате.
/** * @param \Zenwalker\CommerceML\Model\Offer $offer * @return OfferInterface */ public function getOffer1c($offer) { $offerModel = Offer::createByMl($offer); $offerModel->product_id = $this->id; if ($offerModel->getDirtyAttributes()) { $offerModel->save(); } return $offerModel; }Пример парсинга предложения
class Offer extends BaseOffer implements OfferInterface { /** * @param MlOffer $offer * @return Offer */ public static function createByMl($offer) { if (!$offerModel = self::findOne(['accounting_id' => $offer->id])) { $offerModel = new self; $offerModel->name = (string)$offer->name; $offerModel->accounting_id = (string)$offer->id; } $offerModel->remnant = (string)$offer->Количество; return $offerModel; } }createModel1c =
В этой фукнции мы должны найти или создать новый продукт и вернуть вашу модель.
/** * @param \Zenwalker\CommerceML\Model\Product $product * @return self */ public static function createModel1c($product) { if (!$model = Product::findOne(['accounting_id' => $product->id])) { $model = new Product(); $model->accounting_id = $product->id; } $model->name = $product->name; $model->description = (string)$product->Описание; $model->article = (string)$product->Артикул; $model->save(); return $model; }offerClass Модель предложения =
Предложение - модель товара, которая учавствует в продажах, у нее есть остаток и набор цен
Добавляем в настройки модуля вашу модель для предложения 'offerClass' => \app\models\Offer::class
[ 'exchange' => [ 'class' => \carono\exchange1c\ExchangeModule::class, 'groupClass' => \app\models\Group::class, 'productClass' => \app\models\Product::class, 'offerClass' => \app\models\Offer::class, ] ]
В вашей модели имплементируем интерфейс carono\exchange1c\interfaces\OfferInterface
getGroup1c =Здесь нам необходимо получить группу, где находится предложение. Берем её через связь с продуктом.
* Вероятно в будущем будет заменено на getProduct1c()
/** * @return GroupInterface */ public function getGroup1c() { return $this->product->group; }createPriceTypes1c =
В этом методе необходимо создать все типы цен, фукнция вызывается один раз. Тип цены содержит название (розничная, оптовая и др.), а так же название валюты.
/** * @param $types * @return void */ public static function createPriceTypes1c($types) { foreach ($types as $type) { PriceType::createByMl($type); } }
Пример реализации создания типа
class PriceType extends BasePriceType { /** * @param Simple $type * @return PriceType */ public static function createByMl($type) { if (!$priceType = self::findOne(['accounting_id' => $type->id])) { $priceType = new self; $priceType->accounting_id = $type->id; } $priceType->name = $type->name; $priceType->currency = (string)$type->Валюта; if ($priceType->getDirtyAttributes()) { $priceType->save(); } return $priceType; } }setPrice1c =
Цена является отдельной сущностью, поэтому должна храниться в отдельной таблице, а с предложением должна быть связана через сводную таблицу.
/** * offers.xml > ПакетПредложений > Предложения > Предложение > Цены * * Цена товара, * К $price можно обратиться как к массиву, чтобы получить список цен (Цены > Цена) * $price->type - тип цены (offers.xml > ПакетПредложений > ТипыЦен > ТипЦены) * * @param \Zenwalker\CommerceML\Model\Price $price * @return void */ public function setPrice1c($price) { $priceType = PriceType::findOne(['accounting_id' => $price->getType()->id]); $priceModel = Price::createByMl($price, $this, $priceType); $this->addPivot($priceModel, PvOfferPrice::class); }
Пример создания цены
class Price extends BasePrice { /** * @param MlPrice $price * @param Offer $offer * @param PriceType $type * @return Price */ public static function createByMl($price, $offer, $type) { if (!$priceModel = $offer->getPrices()->andWhere(['type_id' => $type->id])->one()) { $priceModel = new self(); } $priceModel->value = $price->cost; $priceModel->performance = $price->performance; $priceModel->currency = $price->currency; $priceModel->rate = $price->rate; $priceModel->type_id = $type->id; $priceModel->save(); return $priceModel; } }setSpecification1c =
Характеристики для предложения являются отдельной сущностью и должны соединятся через сводную таблицу.
/** * offers.xml > ПакетПредложений > Предложения > Предложение > ХарактеристикиТовара > ХарактеристикаТовара * * Характеристики товара * $name - Наименование * $value - Значение * * @param \Zenwalker\CommerceML\Model\Simple $specification * @return void */ public function setSpecification1c($specification) { $specificationModel = Specification::createByMl($specification); $this->addPivot($specificationModel, PvOfferSpecification::class, ['value' => (string)$specification->Значение]); }
Пример парсинга характеристики
class Specification extends BaseSpecification { public static function createByMl($specification) { if (!$specificationModel = self::findOne(['accounting_id' => $specification->id])) { $specificationModel = new self; $specificationModel->name = $specification->name; $specificationModel->accounting_id = $specification->id; $specificationModel->save(); } return $specificationModel; } }partnerClass Модель пользователя =
Данный интерфейс на данный момент требуется только для работы обмена документов. Единственное что нужно реализовать, это общий метод public function getExportFields1c, который описывает поля для сериализации в xml при обмене. Необходимо возвращать массив, где ключ, это тег в xml, а значение - ваши данные. Все поддерживаемые стандартом данные можно найти в спецификации, исчерпывающую информацию лучше смотреть в xsd файлах, для этого потребуется visual studio, т.к. в официальных pdf файлах присутствуют неточности. Чуть подробнее о методе можно почитать здесь
Добавляем в настройки модуля вашу модель для предложения 'partnerClass' => \app\models\Partner::class
[ 'exchange' => [ 'class' => \carono\exchange1c\ExchangeModule::class, 'groupClass' => \app\models\Group::class, 'productClass' => \app\models\Product::class, 'offerClass' => \app\models\Offer::class, 'partnerClass' => \app\models\Partner::class, ] ]
В вашей модели имплементируем интерфейс carono\exchange1c\interfaces\PartnerInterface
public function getExportFields1c($context = null) { return [ 'Ид' => 'id', 'Наименование' => 'username', 'ПолноеНаименование' => 'full_name', 'Фамилия' => 'surname', 'Имя' => 'name', ]; }documentClass Модель документа =
Документ в 1С, он же заказ на сайте. У документа дожны быть связи на предложения через сводную таблицу. Суммы желательно указывать и в сводной таблице и в самом заказе, чтобы не расчитывать её в динамике т.к. цена на предложение может поменятся и клиенту в итоге поступит счет на другую сумму.
Добавляем в настройки модуля вашу модель для предложения 'documentClass' => \app\models\Document::class
[ 'exchange' => [ 'class' => \carono\exchange1c\ExchangeModule::class, 'groupClass' => \app\models\Group::class, 'productClass' => \app\models\Product::class, 'offerClass' => \app\models\Offer::class, 'partnerClass' => \app\models\Partner::class, 'documentClass' => \app\models\Document::class, ] ]
В вашей модели имплементируем интерфейс carono\exchange1c\interfaces\DocumentInterface
Получение всех подготовленных документов (заказов). В этой функции необходимо возвращать все документы, которые готовы для импорта в 1С.
Необходимо обратить внимение, 1С заменит существующие документы, если при следующем импорте они будут в этой фукнции, поэтому по завершению импорта, необходимо выставлять флаг или менять статус, чтобы при повторном импорте этих документов уже небыло. Это значит, что если вы создали документы в 1С, начали с ними работать, двигать по статусам или наполнять данными, то при следующем импорте, они перезапишутся и придется всё начинать сначала. Как обновлять уже экспортированные данные, можно почитать в разделе с событиями.
/** * @return DocumentInterface[] */ public static function findDocuments1c() { return self::find()->andWhere(['status_id' => 2])->all(); }getOffers1c =
Получаем все предложения, которые были добавлены в этот документ (заказ)
/** * @return OfferInterface[] */ public function getOffers1c() { return $this->offers; }getRequisites1c =
Еще сам не уверен где эта фукнция используется, пока не обязательно к заполнению.
getPartner1c =Необходимо вернуть пользователя, который сделал заказ, класс должен имплементировать \carono\exchange1c\interfaces\PartnerInterface
/** * Получаем контрагента у документа * * @return PartnerInterface */ public function getPartner1c() { return $this->user; }warehouseClass Модель склада =
На данный момент не используется
getExportFields1c =Объекты, которые создаются в 1С, имеют интерфейс \carono\exchange1c\interfaces\ExportFieldsInterface с этим методом. В этом методе мы должны вернуть массив, который сериализуется в xml для 1С. Ключ массива, это название тега в xml.
Значение может иметь разные типы, аналогично с функцией fields для rest api.
string - передаём название аттрибута, если такого аттрибута нет, вернется эта строка
Closure - передаём фукцнию function($model)
array - с помощью массива можно кастомизировать xml, или когда требуется создать несколько элементов. В таком массиве есть несколько зарезервированных ключей: @content - тело тега, @name - имя тега, @attributes - массив аттрибутов.
Все значения обрабатываются рекурсивно, поэтому можно составлять сложные структуры.
Входной параметр $context - это контекст, в рамках которого необходимо сериализовать объект, например для предложения, контектом будет заказ.
Пример сериализации для контрагента в документе.
public function getExportFields1c($context = null) { return [ 'Ид' => 'id', 'Наименование' => 'login', 'ПолноеНаименование' => 'full_name', 'Фамилия' => 'surname', 'Имя' => 'name', 'Контакты' => [ [ '@name' => 'Контакт', 'Тип' => 'Почта', 'Значение' => $this->email, ], [ '@name' => 'Контакт', 'Тип' => 'ТелефонРабочий', 'Значение' => $this->phone, ], ], ]; }
Результат
<Контрагенты> <Контрагент> <Ид>13</Ид> <Наименование>info@carono.ru</Наименование> <ПолноеНаименование>Иванов Иван Иванович</ПолноеНаименование> <Контакт> <Тип>Почта</КонтактВид> <Значение>info@carono.ru</Значение> </Контакт> <Контакт> <Тип>ТелефонРабочий</КонтактВид> <Значение>+8(908)123-45-67</Значение> </Контакт> </Контрагент> </Контрагенты>getIdFieldName1c =
У всех сущностей в 1С имеется уникальный идентификатор Ид, необходимо вернуть название поля, в котором будет хранится это значение.
/** * Возвращаем имя поля в базе данных, в котором хранится ID из 1с * * @return string */ public static function getIdFieldName1c() { return 'accounting_id'; }setRaw1cData =
Если по каким то причинам файлы import.xml или offers.xml были модифицированы
и какие то данные не попадают в парсер, в самом начале вызывается данный метод, в
$object и $cml можно получить все данные для ручного парсинга.
К сожалению на данный момент, не все сущности проходят этот метод.
Описание протокола обмена =Источник: http://v8.1c.ru/edi/edi_stnd/131/
Данный открытый протокол разработан компаниями "1С" и "1С-Битрикс".
Протокол используется штатной процедурой обмена коммерческими данными между системой "1С:Предприятие", с одной стороны, и системой управления сайтом, с другой стороны.
Функционально обмен делится на два блока:
Первый блок обеспечивает публикацию на сайте каталога номенклатурных позиций и данных. Второй блок необходим для передачи с сайта в систему "1С:Предприятие" информации о заказах интернет-магазина, и дальнейшую синхронизацию статусов и параметров заказов.
В обоих случаях инициатором обмена выступает система "1С:Предприятие". Обмен электронными документами осуществляется в соответствии с правилами и форматами, описанными в стандарте CommerceML 2.
При инициализации взаимодействия устанавливается HTTP соединение. Система "1С:Предприятие" запрашивает у сайта необходимые параметры, такие, как максимальный объем пакета, поддержка сжатия и др.. На основании этих данных система 1С:Предприятие формирует XML сообщения и передает их на сайт.
Данные для публикации на сайте выгружаются одним пакетом.
Выгрузка данных начинается с того, что система "1С:Предприятие" отправляет http-запрос следующего вида:
http://<сайт>/<путь> /1c_exchange.php?type=catalog&mode=checkauth.
В ответ система управления сайтом передает системе «1С:Предприятие» три строки (используется разделитель строк "\n"):
Примечание. Все последующие запросы к системе управления сайтом со стороны "1С:Предприятия" содержат в заголовке запроса имя и значение Cookie.
Далее следует запрос следующего вида:
http://<сайт>/<путь> /1c_exchange.php?type=catalog&mode=init
В ответ система управления сайтом передает две строки:
1. zip=yes, если сервер поддерживает обмен в zip-формате - в этом случае на следующем шаге файлы должны быть упакованы в zip-формате
или
zip=no - в этом случае на следующем шаге файлы не упаковываются и передаются каждый по отдельности.
2. file_limit=<число>, где <число> - максимально допустимый размер файла в байтах для передачи за один запрос. Если системе "1С:Предприятие" понадобится передать файл большего размера, его следует разделить на фрагменты.
Затем "1С:Предприятие" запросами с параметрами вида
http://<сайт>/<путь> /1c_exchange.php?type=catalog&mode=file&filename=<имя файла>
выгружает на сайт файлы обмена в формате CommerceML 2, посылая содержимое файла или его части в виде POST.
В случае успешной записи файла система управления сайтом выдает строку "success".
На последнем шаге по запросу из "1С:Предприятия" производится пошаговая загрузка данных по запросу с параметрами вида http://<сайт>/<путь> /1c_exchange.php?type=catalog&mode=import&filename=<имя файла>
Во время загрузки система управления сайтом может отвечать в одном из следующих вариантов.
1. Если в первой строке содержится слово "progress" - это означает необходимость послать тот же запрос еще раз. В этом случае во второй строке будет возвращен текущий статус обработки, объем загруженных данных, статус импорта и т.д.
2. Если в ответ передается строка со словом "success", то это будет означать сообщение об успешном окончании обработки файла.
Примечание. Если в ходе какого-либо запроса произошла ошибка, то в первой строке ответа системы управления сайтом будет содержаться слово "failure", а в следующих строках - описание ошибки, произошедшей в процессе обработки запроса.
Если произошла необрабатываемая ошибка уровня ядра продукта или sql-запроса, то будет возвращен html-код.
Сведения о товарах в формате XML.
Сведения о ценах в формате XML.
Заказы, оформленные на сайте, загружаются в систему "1С:Предприятие".
Последовательность действий при работе с заказом
1. Заказ оформляется на сайте
2. При передаче в систему "1С:Предприятие" в заказе устанавливается категория "Заказ с сайта".
При формировании заказа в системе "1С:Предприятие" записываются номер и дата заказа, с которыми он оформлен на сайте. Поиск контрагента осуществляется по ИНН или наименованию, в зависимости от указанных настроек.
3. При загрузке заказа производится поиск договора с контрагентом. Договор ищется среди существующих договоров с клиентом, с признаком ведения взаиморасчетов по заказам (по указанной в настройках загрузки Организации). Если не находится ни один договор, то создается новый.
4. При загрузке заказа загружаются все его свойства, переданные с сайта. Свойства ищутся в системе "1С:Предприятие" по наименованию. Если с таким наименованием свойства нет, то заводится новое свойство со значениями типа строка или число.
5. Заказ может модифицироваться в системе "1С:Предприятие", при этом его изменения будут выгружаться на сайт
6. Если заказ оплачивается или отгружается в системе "1С:Предприятие", то состояния заказа по оплате и по отгрузке выгружаются на сайт только при полном выполнении операции (полной оплате и полной отгрузке). До этого момента заказ считается не оплаченным и не отгруженным.
7. При попытке в системе "1С:Предприятие" изменить заказ, по которому произведена оплата или отгрузка, заказ на сайт не загрузится как измененный. При этом пользователь получит об этом сообщение.
8. После каждой выгрузка заказа на сайт, на стороне сайта определяются значения его категорий (ссылка на категории). Эти значения устанавливаются в системе "1С:Предприятие" так, как они присвоены заказу на сайте
Выгрузка данных начинается с того, что система "1С:Предприятие" отправляет http-запрос следующего вида:
http://<сайт>/<путь> /1c_exchange.php?type=sale&mode=checkauth.
В ответ система управления сайтом передает системе «1С:Предприятие» три строки (используется разделитель строк "\n"):
Примечание. Все последующие запросы к системе управления сайтом со стороны "1С:Предприятия" содержат в заголовке запроса имя и значение Cookie.
Далее следует запрос следующего вида:
http://<сайт>/<путь> /1c_exchange.php?type=sale&mode=init
В ответ система управления сайтом передает две строки:
1. zip=yes, если сервер поддерживает обмен в zip-формате - в этом случае на следующем шаге файлы должны быть упакованы в zip-формате
или
zip=no - в этом случае на следующем шаге файлы не упаковываются и передаются каждый по отдельности.
2. file_limit=<число>, где <число> - максимально допустимый размер файла в байтах для передачи за один запрос. Если системе "1С:Предприятие" понадобится передать файл большего размера, его следует разделить на фрагменты.
Затем на сайт отправляется запрос вида
http://<сайт>/<путь> /1c_exchange.php?type=sale&mode=query.
Сайт передает сведения о заказах в формате CommerceML 2. В случае успешного получения и записи заказов "1С:Предприятие" передает на сайт запрос вида
http://<сайт>/<путь> /1c_exchange.php?type=sale&mode=success
Затем система "1С:Предприятие" отправляет на сайт запрос вида
http://<сайт>/<путь> /1c_exchange.php?type=sale&mode=file&filename=<имя файла>,
который загружает на сервер файл обмена, посылая содержимое файла в виде POST.
В случае успешной записи файла система управления сайтом передает строку со словом "success". Дополнительно на следующих строчках могут содержаться замечания по загрузке.
Примечание. Если в ходе какого-либо запроса произошла ошибка, то в первой строке ответа системы управления сайтом будет содержаться слово "failure", а в следующих строках - описание ошибки, произошедшей в процессе обработки запроса.
Если произошла необрабатываемая ошибка уровня ядра продукта или sql-запроса, то будет возвращен html-код.
Заказ на сайт в формате XML.
Заказ с сайта в формате XML.
Представленный протокол используется для интеграции системы "1С:Предприятие" с системами "1С-Битрикс: Управление сайтом", "UMI.CMS" и другими.
Тестирование и поиск ошибок =Раздел находится в разработке
События модуля =beforeUpdateProduct
Событие перед началом парсинга продукта
afterUpdateProduct
Событие после парсинга продукта
beforeUpdateOffer
Событие перед началом парсинга предложения
afterUpdateOffer
Событие после парсинга предложения
beforeProductSync
Событие перед началом парсинга всех продуктов
afterProductSync
Событие после парсинга всех продуктов
beforeOfferSync
Событие перед началом парсинга всех предложений
afterOfferSync
Событие после парсинга всех предложений
afterFinishUploadFile
Событие, которое вызывается после загрузки архива или xml файла от 1С на ваш сайт
afterExportOrders
Событие после формирования заказов из вашего сайта для 1С, в этом методе предлагается вам реализовать смену статусов или указания флага, чтобы исключить повторную выгрузку документов, т.к. они заменят те, что были загружены ранее.
Comments