Разработка ERP на tryton: Часть 3

в 12:04, , рубрики: ERP, ERP-системы, python, tryton, метки: , ,

Работа с модулями компании (company), контрагентами (party), товаров (product) и склада (stock).


Часть 1: Установка tryotnd, структура запросов, работа с БД
Часть 2: Структура методов, работа с пользователями и группами, установка модулей
Часть 3: Работа с модулями компании (company), контрагентами (party), товаров (product) и склада (stock).
Часть 4: Работа с модулем продаж (sale)
Часть 5: Работа с модулем планирование производственных ресурсов (mpr)

1. Пример установки модулей

У нас в качестве первой итерации поставили задание обеспечить работу склада. Так что займемся установкой соответсвующего модуля.

После скачивания и распаковки модуля stock, установить его не получится, так как для работы модуля необходимо установить зависимости. Для получения списка зависимостей модуля есть метод ir.module.dependencies, но он возвращает одну неудоволтворенную зависимость, получить сразу список необходимых модулей через этот метод у меня не получилось.

Метод model.ir.module.module.read возвращает поле dependencies, но там только id необходимых модулей. Можно опять воспользоваться эти методом, что б получить имена этих модулей. Хотя проще будет открыть tryton.cfg, который находится в корне модуля и в разделе depends, посмотреть нужные модули. Для склада это — company, currency, ir, party, product. У модуля party в зависимостях указано еще company. Скачиваем и устанавливаем нужные модули.

После установки system.server.listMethods возвращает в классе model на 625 методов больше. Ниже схематическое представление новых методов:

Разработка ERP на tryton: Часть 3

Теперь рассмотрим эти методы более детально.

2. API работы с модулями

У всех классов есть 6 основных методов: create, delete, fields_get, search, read, write. Ниже я расспишу их для основных классов модулей.

2.1. API модуля company

Название метода Параметры Описание
model.company.company.search [user_id, cookie, [], start, end, null, {}] Возвращает срез списка id существующих компаний(id[start:end]).
model.company.company.fields_get [user_id, cookie, [], {}] Возвращает список имеющихся у компании полей.
model.company.company.read [user_id, cookie, list_of_company_ids, list_of_field_names, {}] Возвращает значения заданных полей заданных компаний.
model.company.company.create [user_id, cookie, [{field_name: field_data, field_name: field_data, ...}], {}] Создать компанию, минимум необходимо задать поле name.
model.company.company.delete [user_id, cookie, list_delete_company_ids, {}] Удаляет пользователей по id.
model.company.company.write [user_id, cookie, list_update_company_ids, [{field_name: field_data, field_name: field_data, ...}], {}] Изменяет значения полей пользователей по id.

У модуля компании есть второстепенный класс employee, который позволяет создавать сотрудников. Для назначения сотрудников надо изменить поле employее у компании.

2.2. API модуля party(контрагенты)
Название метода Параметры Описание
model.party.party.search [user_id, cookie, [], start, end, null, {}] Возвращает срез списка id существующих контрагентов(id[start:end]).
model.party.party.fields_get [user_id, cookie, [], {}] Возвращает список имеющихся у контрагента полей.
model.party.party.read [user_id, cookie, list_of_party_ids, list_of_field_names, {}] Возвращает значения заданных полей заданных контрагентов.
model.party.party.create [user_id, cookie, [{field_name: field_data, field_name: field_data, ...}], {}] Создать контрагента, минимум необходимо задать поле name.
model.party.party.delete [user_id, cookie, list_delete_party_ids, {}] Удаляет контрагентов по id.
model.party.party.write [user_id, cookie, list_update_party_ids, [{field_name: field_data, field_name: field_data, ...}], {}] Изменяет значения полей контрагентов по id.

У модуля контрагентов есть второстепенный класс address, который позволяет создавать адреса и назначать их контрагентам. Этот же класс используется в модуле склада.

2.3. API модуля product

Название метода Параметры Описание
model.product.product.search [user_id, cookie, [], start, end, null, {}] Возвращает срез списка id существующих продуктов(id[start:end]).
model.product.product.fields_get [user_id, cookie, [], {}] Возвращает список имеющихся у продукта полей.
model.product.product.read [user_id, cookie, list_of_product_ids, list_of_field_names, {}] Возвращает значения заданных полей заданных продуктов.
model.product.product.create [user_id, cookie, [{field_name: field_data, field_name: field_data, ...}], {}] Создать продукт, минимум необходимо задать поле name, list_price, cost_price, default_uom.
model.product.product.delete [user_id, cookie, list_delete_product_ids, {}] Удаляет продукты по id.
model.product.product.write [user_id, cookie, list_update_product_ids, [{field_name: field_data, field_name: field_data, ...}], {}] Изменяет значения полей продуктов по id.

Есть еще аналогичные методы product.template, которые делают тоже самое что и product.product.
Также необходимо обратить внимание на обязательное поле default_uom, в котором указывается единица измерения товара. Для работы с единицами измерения используется класс product.uom. Соотвественно для того, чтобы получить список имеющихся единиц измерения можно воспользоваться методами model.product.uom.search, model.product.uom.read.

Список id с названиями uom

id Название
1 Штука
2 Килограмм
3 Грамм
4 Карат
5 Фунт
6 Унция
7 Секунда
8 Минута
9 Час
10 Рабочий день
11 День
12 Метр
13 Километр
14 сантиметр
15 Миллиметр
16 Фут
17 Ярд
18 Дюйм
19 Миля
20 Кубический метр
21 Литр
22 Кубический сантиметр
23 Кубический дюйм
24 Кубический фут
25 Галлон
26 Квадратный метр
27 Квадратный сантиметр
28 Ар
29 Гектар
30 Квадратный дюйм
31 Квадратный фут
32 Квадратный ярд

Пример, как получить существующие единицы измерения

import json
import requests

url = 'http://localhost:8000/try'
id = 1
methodname = 'common.server.login'
params = ('test', 'test')
request = json.dumps({
                'id': id,
                'method': methodname,
                'params': params,
                })

r = requests.post(url, data=request)

user_id, cookie = r.json()['result']
print user_id, cookie


id = 2
methodname = 'model.product.uom.search'
params = [user_id, cookie, [], 0, 1000, None, {}]

request = json.dumps({
                'id': id,
                'method': methodname,
                'params': params,
                })

r = requests.post(url, data=request)
print request
uom= r.json()['result']

id = 4
methodname = 'model.product.uom.read'
params = (user_id, cookie, uom, ['name'], {})

request = json.dumps({
                'id': id,
                'method': methodname,
                'params': params,
                })

r = requests.post(url, data=request)
print r.json()['result']

2.4. API работы с категориями

Для всех основных классов можно создавать иерархическую категоризацию. Для создания иерархии используется поле parent, в котором указывается id родителя.

Название метода Параметры Описание
model.*.category.search [user_id, cookie, [], start, end, null, {}] Возвращает срез списка id существующих ктегорий(id[start:end]).
model.*.category.fields_get [user_id, cookie, [], {}] Возвращает список имеющихся у категории полей.
model.*.category.read [user_id, cookie, list_of_category_ids, list_of_field_names, {}] Возвращает значения заданных полей заданных категорий.
model.*.category.create [user_id, cookie, [{field_name: field_data, field_name: field_data, ...}], {}] Создать категорию, минимум необходимо задать поле name.
model.*.category.delete [user_id, cookie, list_delete_category_ids, {}] Удаляет категории по id.
model.*.category.write [user_id, cookie, list_update_category_ids, [{field_name: field_data, field_name: field_data, ...}], {}] Изменяет значения полей категорий по id.
2.5. API модуля stock (склад)

Очень много времени ушло на понимание того, что для работы со складскими документами надо использовать любого пользователя, кроме admin, и к тому же его необходимо привязать к компании (указать поле company), иначе будете в response получать UserError.

У модуля склада есть 5 типов докуметов:

  1. stock.shipment.in — документ поставки товара на склад от поставщика.
  2. stock.shipment.in.return — документ возврата товара поставщику.
  3. stock.shipment.internal — документ внутренего перемещения между складами.
  4. stock.shipment.out — документ отгрузки товара со склада покупателю.
  5. stock.shipment.out.return — документ возврата товара от покупателя.

Ниже представлена схема, для наглядного понимания движения товаров по складам:

Разработка ERP на tryton: Часть 3

Для нескольких физических складов надо либо дублировать товарный склад с зонами поставки и отгрузки, либо делать несколько зон хранения.

Ниже представлено API по работе с докуметами склада, вместо звёздочки подставляем класс нужного документа, к примеру model.stock.shipment.in.search.

Название метода Параметры Описание
model.*.search [user_id, cookie, [], start, end, null, {}] Возвращает срез списка id существующих документов(id[start:end]).
model.*.fields_get [user_id, cookie, [], {}] Возвращает список имеющихся у документов полей.
model.*.read [user_id, cookie, list_of_shipment_ids, list_of_field_names, {}] Возвращает значения заданных полей заданных документов.
model.*.create [user_id, cookie, [{field_name: field_data, field_name: field_data, ...}], {}] Создать документ.
model.*.delete [user_id, cookie, list_delete_shipment_ids, {}] Удаляет документ по id.
model.*.write [user_id, cookie, list_update_shipment_ids, [{field_name: field_data, field_name: field_data, ...}], {}] Изменяет значения полей документов по id.
model.*.wait [user_id, cookie, list_shipment_ids, {}] Меняет состояние документа в ожидание по id.
model.*.done [user_id, cookie, list_shipment_ids, {}] Меняет состояние документа в выполнено по id.

У модуля склада есть второстепенный класс location для работы непосредственно со складами, а не движением товаров по складам и зонам.

Вот пример параметров для метода model.stock.shipment.in.create [user_id, cookie, [{"company": 1, "incoming_moves": [["create", [{"to_location": 1, "product": 1, "from_location": 5, "company": 1, "unit_price": {"decimal": "12.000", "__class__": "Decimal"}, "currency": 123, "uom": 2, "quantity": 90.0}]]], "warehouse": 4, "supplier": 1}], {}]. Обратите внимание на «unit_price»: {«decimal»: «12.000», "__class__": «Decimal»}, если задать в запросе «unit_price»: 12.000, то запрос не выполнится, так как модуль склада не сможет переобразовать число нужный ему в класс Decimal. Такое поведение замечено только в полях, которые отвечают за цену.

У документов поставки stock.shipment.in, есть два состояния — draft (черновик), done (выполнено). У остальных документов три состояние — draft (черновик), wait (ожидание), done (выполнено). Состояние документов влияет на отчеты об остатках по товарам и складам. Если у документа состояние draft, то товар указаный в нём не отображается в отчетах. Если документ в состоянии wait, то в отчетах товар находится на складе с которого делается перемещение/отгрузка. Если документ в состоянии done, то товар в отчет находится на складе на который делается перемещение/отгрузка.

У модуля склада есть отчет остатка продукци на конкретном складе/зоне поставки-отгрузки — wizard.stock.products_by_locations. Для получения отчетов используется главный класс wizard. С помощью метода create создаётся запрос к БД и записывается в БД, метод execute выполняет запрос и результат записывается в бд, метод delete удаляет из БД запрос и результаты его выполнения.

Название метода Параметры Описание
wizard.stock.products_by_locations.create [user_id, cookie, [], {}] Создаёт запрос для отчета по продуктам на складе. Метод возвращает id отчета.
wizard.stock.products_by_locations.execute [user_id, cookie, wizard_id, {«start»: {«forecast_date»: {«month»: number_of_month, "__class__": «date», «day»: number_of_day, «year»: number_of_year}}}, «open», { «active_id»: warehouse_id, «active_model»: «stock.location», «active_ids»: [warehouse_ids]}] Выполняет запрос. Необходимо указать дату, на которую будет произведен расчет остатков и id склада.
wizard.stock.products_by_locations.delete [user_id, cookie, wizard_id, {}] Удаляет отчет по id.

Автор: clutcher

Источник

Поделиться

* - обязательные к заполнению поля