https://github.com/dapi/moysklad
Правильный Ruby-клиент для работы c REST XML API moyslad.ru
https://github.com/dapi/moysklad
Last synced: about 1 year ago
JSON representation
Правильный Ruby-клиент для работы c REST XML API moyslad.ru
- Host: GitHub
- URL: https://github.com/dapi/moysklad
- Owner: dapi
- License: mit
- Created: 2014-11-10T10:24:09.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2024-04-07T16:50:56.000Z (about 2 years ago)
- Last Synced: 2024-10-01T14:46:12.397Z (over 1 year ago)
- Language: Ruby
- Homepage: moysklad.ru
- Size: 563 KB
- Stars: 14
- Watchers: 8
- Forks: 4
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Ruby-клиент для REST XML API Moysklad
[](https://travis-ci.org/dapi/moysklad)
[](https://www.versioneye.com/user/projects/548225818674a4b5b90004dd)
[](https://codeclimate.com/github/dapi/moysklad)
* http://www.rubydoc.info/gems/moysklad
## Особенности
* Модуль разработан согласно принципам SOLID. Легко расширяем.
* Все используемые сущности описаны и структурированы. Например [Good](lib/moysklad/entities/good.rb)
* Любые действия с ресурсами (Create, Read, Update, Delete, List).
* Виртуальные действия с ресурсами (`where`, `findWhere`)
* Автоматическая подгрузка списка если все данные не уместились в один запрос (метод `all`)
* _Кеширование и предзагрузка_ ресурса со всеми записями (используем ресурс как локальную базу)
* Работа с нескольмими аккаунтами склада одновременно (отсуствие глобальных переменных).
* Удобная работа с подресурсами (например справочником свойств товара)
* _Ассоциации_ между сущностями автоматически получают данные по API (`good.features`).
* [Client](lib/moysklad/client.rb) для прямого обращения к API в случае крайней необходимости.
## Установка
Все, как обычно, добавляем в Gemfile:
gem 'moysklad'
## Использование
Создаем благоприятное окружение для работы с API:
```ruby
universe = Moysklad::Universe.build login:'ВАШ ЛОГИН', password:'ВАШ ПАРОЛЬ'
```
### Список элементов.
Например список товаров (`Good`).
```ruby
universe.goods.list
# => [Moysklad::Entities::Good, Moysklad::Entities::Good, ..]
```
Обратите внимание, что список возвращается "как есть" и для работы с ним есть более удобные методы.
Параметры списка.
```ruby
universe.stock.list slotUuid: uuid
```
Страница товаров:
```ruby
page = universe.goods.page
# => Moysklad::Entities::Page
page.total
# => 1280
page.count
# => 1000
page.start
# => 0
# page.items
# =>[Moysklad::Entities::Good, ..]
Есть очень удобная возможность автоматически загрузать ВСЕ товары с учетом пейджирования:
> goods = universe.goods.all
> goods.count
> => 1280
> goods
> => [Moysklad::Entities::Page]
```
### Получить конкретный элемент
```ruby
universe.goods.get $uuid
# => [Moysklad::Entities::Good]
```
### Создаем элемент
Например загрузка заказа покупателя:
```ruby
co = Moysklad::Entities::CustomerOrder.new
co.vatIncluded = true
co.applicable = true
[...]
co.customerOrderPosition = [Moysklad::Entities::CustomerOrderPosition.new]
created_order = universe.customer_orders.create co
# => [Moysklad::Entities::Good]
created_order.uuid
# => uuid нового заказа
```
### Удаляем элемент
```ruby
universe.goods.delete $uuid
```
### Кеширование и предзагрузка
Одной из главных возможностей данного модуля является возможность работать с API как с базой данных,
не выполняя запрос по получению каждого товара по-отдельности, и выдавать данные их кеша.
Класический способ получить данные по товару делает GET запрос каждый раз:
```ruby
universe.goods.get $uuid
# => Client: GET exchange/rest/ms/xml/Good/f24937e7-7ba1-11e4-90a2-8ecb000abf12 {}
# => [Moysklad::Entities::Good]
```
Продвинутый способ вытаскивает все данные сразу и в дальнейшем берет обьекты из кеша:
```ruby
> universe.goods.find $uuid
# => Client: GET exchange/rest/ms/xml/Good/list {:start=>0}
# => Client: GET exchange/rest/ms/xml/Good/list {:start=>1000}
# => [Moysklad::Entities::Good]
```
И в следующий раз API уже не дергается:
```ruby
universe.goods.find $another_uuid
# => [Moysklad::Entities::Good]
```
Это позволяет экономить на прямых запросах к API и избавляет нас от блокирования моимскладом по ограничению количества запросов за еденицу времени.
## Поиск по фильтру
Возвращает список элементов отображенных по фильтру:
```ruby
universe.features.where goodUuid: uuid
# => [Moysklad::Enities::Feature, Moysklad::Enities::Feature]
```
Тоже самое, только возвращается первый элемент или nil:
```ruby
universe.features.findWhere goodUuid: uuid
# => [Moysklad::Enities::Feature]
```
### Список доступных ресурсов:
```ruby
universe.resources_list
# => [:stock, :embedded_entity_metadata, :custom_entity_metadata, :goods, :good_folders, :uoms, :countries,
:features, :custom_entities, :customer_orders, :warehouses, :companies,
:consignments, :my_companies]
```
## Справочники и подресурсы
Доступ к Мойсклад устроен так, что некоторые справочники запрятаны в одной коллекции.
Например если вы хотите получить все виды свойств товаров, то это можно сделать следующим образом.
```ruby
universe.embedded_entity_metadata.subresource_by_name(:GoodFolder).all
# => [Moysklad::Entities::AttributeMetadata, Moysklad::Entities::AttributeMetadata]
```
Или получить конкретное свойство:
```ruby
universe.embedded_entity_metadata.subresource_by_name(:GoodFolder).find uuid
# => Moysklad::Entities::AttributeMetadata
```
## Автоматическая обработка ассоциаций (отношения)
Нравятся `belongs_to` и `has_many` в рельсах? Тут есть почти тоже самое.
```ruby
feature = universe.features.find uuid
feature.good
# Client: GET exchange/rest/ms/xml/Good/f24937e7-7ba1-11e4-90a2-8ecb000abf12 {}
# => [Moysklad::Entities::Good]
```
Пример как получить все данные по товару, включая модификации, свойства и их характеристики:
```ruby
good = universe.goods.find uuid
# Client: GET exchange/rest/ms/xml/Good/f24937e7-7ba1-11e4-90a2-8ecb000abf12 {}
good.features universe
# Client: GET exchange/rest/ms/xml/Feature/list {}
# => [Moysklad::Entities::Feature, ..]
attribute = good.attributes.first
# => [Moysklad::Entities::Attribute, ..]
attribute.is_dictionary?
# => true
```
Получаем вид свойства:
```ruby
attribute.embedded_entity_metadata universe
# Client: GET exchange/rest/ms/xml/Metadata/list {}
# => [Moysklad::Entities::AttributeMetadata]
```
Получаем описание пользовательского справочника к которому принадлежит свойства
```ruby
dictionary = attribute.embedded_entity_metadata(universe).dictionatyMetadata(universe)
# Client: GET exchange/rest/ms/xml/CustomEntityMetadata/uuid {}
# => [Moysklad::Entities::CustomEntityMetadata]
```
Значения всех элементов пользовательского справочника:
```ruby
dictionary.entities(universe)
# => [Moysklad::Entities::CustomEntity, ...]
```
Подробнее смотри в исходниках сущностей.
## Pull Requests
### Добавление новых моделей и ресурсов.
На данный момен в библиотеку добавлено 60% справочников используемых в моемскладе. Я добавляю новые справочники по мере необходимости. Но вы можете это сделать и сами следующим образом.
Например добавляем `Country`.
1. Добавляем в фикстуры пример выгрузки из API для тестирования и отладки:
MS_LOGON=логин MS_PASSWORD=пароль ./scripts/rest.sh Country list > ./spec/fixtures/Country_list.raw
2. Создаем сущность на основе уже существующей, например good.rb
cp ./lib/moysklad/entities/good.rb ./lib/moysklad/entities/country.rb
3. Описываем свойства новой сущности Country.rb в терминах [nokogiri-happymapper](https://github.com/dam5s/happymapper)-а
vi ./lib/moysklad/entities/country.rb
4. Добавляем сущность в requirements
vi ./lib/moysklad/entities.rb
5. Содаем автоматический ресурс (имя ресурса во множественном числе)
vi ./lib/moysklad/resources.rb
6. Делаем spec для сущности и для ресурса.
> vi ./spec/lib/moysklad/resources/countries_spec.rb
> vi ./spec/lib/moysklad/entities/country_spec.rb
7. Проверяем что тесты проходят.
8. Присылаем Pull Request
## Тестирование
> bundle exec guard
## Полезняшки
Скрипт для быстрого доступа к сервисам моего склада
> MS_LOGON=логин MS_PASSWORD=пароль ./script/rest.sh Country list > ./spec/fixtures/Country_list.raw
Если получаете 429 ошибку (too many requests) - лимит обращений по API от одного
аккаунта - 5 или 10 запросов в секунду (в секунду, Карл). Если не превышать его,
все будет хорошо - минутных или часовых лимитов нет.
## HTTP Таймаут
По-умолчанию таймаут равен 120 секунд, но его можно менять через переменную
окружения `MOYSKLAD_HTTP_TIMEOUT`
## Ссылочки
* Картапамяти по API http://www.mindmeister.com/246618635/online-moysklad-ru
* Документация для разработчииков https://support.moysklad.ru/hc/ru/sections/200561443-Разработчикам
* Неплохая схема API в json https://gist.github.com/dapi/22a0790db19a4ff51a37
## Другие биллиотеки
* PHP https://github.com/Tooyz/moysklad
* JavaScript/nodejs https://github.com/wmakeev/moysklad-client
## Присылайте пул-реквесты )
## Авторство
* Данил Письменный (brandymint.ru)