⬆️ ⬇️

ERP development on tryton: Part 3

Work with modules of the company (company), counterparties (party), product (product) and warehouse (stock).





Part 1: Install tryotnd, query structure, work with the database

Part 2: Method Structure, Working with Users and Groups, Installing Modules

Part 3: Work with modules of the company (company), contractors (party), product (product) and warehouse (stock).



1. An example of installing modules



We have as the first iteration set the task to ensure the work of the warehouse. So let's install the appropriate module.

')

After downloading and unpacking the stock module, it will not be possible to install it, since dependencies must be installed for the module to work. To get the list of module dependencies, there is the ir.module.dependencies method, but it returns one ir.module.dependencies dependency; I could not get a list of the required modules right away through this method.



The model.ir.module.module.read method returns the dependencies field, but there are only id modules needed. You can again use these methods to get the names of these modules. Although it will be easier to open tryton.cfg, which is in the root of the module and in the depends section, look at the modules you need. For a warehouse it is company, currency, ir, party, product. The party module in the dependencies indicated by the company. Download and install the necessary modules.



After installation, system.server.listMethods returns 625 more methods to the model class. Below is a schematic representation of the new methods:







Now consider these methods in more detail.



2. API of working with modules





All classes have 6 basic methods: create, delete, fields_get, search, read, write. Below I will write them for the main classes of modules.

2.1. Company module API


Method nameOptionsDescription
model.company.company.search[user_id, cookie, [], start, end, null, {}]Returns a slice of the id list of existing companies (id [start: end]).
model.company.company.fields_get[user_id, cookie, [], {}]Returns a list of fields available to the company.
model.company.company.read[user_id, cookie, list_of_company_ids, list_of_field_names, {}]Returns the values ​​of the specified fields of the specified companies.
model.company.company.create[user_id, cookie, [{field_name: field_data, field_name: field_data, ...}], {}]To create a company, the minimum is to set the name field.
model.company.company.delete[user_id, cookie, list_delete_company_ids, {}]Removes users by id.
model.company.company.write[user_id, cookie, list_update_company_ids, [{field_name: field_data, field_name: field_data, ...}], {}]Changes user field values ​​by id.




The company module has a secondary employee class that allows you to create employees. To assign employees, you need to change the field more employable with the company.



2.2. API module party (contractors)




Method nameOptionsDescription
model.party.party.search[user_id, cookie, [], start, end, null, {}]Returns a slice of the list of existing contractors' id (id [start: end]).
model.party.party.fields_get[user_id, cookie, [], {}]Returns the list of fields available for the counterparty.
model.party.party.read[user_id, cookie, list_of_party_ids, list_of_field_names, {}]Returns the values ​​of the specified fields of the specified counterparties.
model.party.party.create[user_id, cookie, [{field_name: field_data, field_name: field_data, ...}], {}]To create an account, at a minimum it is necessary to set the name field.
model.party.party.delete[user_id, cookie, list_delete_party_ids, {}]Removes counterparties by id.
model.party.party.write[user_id, cookie, list_update_party_ids, [{field_name: field_data, field_name: field_data, ...}], {}]Changes counterparty field values ​​by id.




The counterparty module has a secondary address class that allows you to create addresses and assign them to counterparties. The same class is used in the warehouse module.



2.3. Product module API


Method nameOptionsDescription
model.product.product.search[user_id, cookie, [], start, end, null, {}]Returns a snapshot of the id list of existing products (id [start: end]).
model.product.product.fields_get[user_id, cookie, [], {}]Returns a list of available fields.
model.product.product.read[user_id, cookie, list_of_product_ids, list_of_field_names, {}]Returns the values ​​of the specified fields of the specified products.
model.product.product.create[user_id, cookie, [{field_name: field_data, field_name: field_data, ...}], {}]To create a product, at a minimum it is necessary to set the field name, list_price, cost_price, default_uom.
model.product.product.delete[user_id, cookie, list_delete_product_ids, {}]Removes products by id.
model.product.product.write[user_id, cookie, list_update_product_ids, [{field_name: field_data, field_name: field_data, ...}], {}]Changes product field values ​​by id.




There are similar product.template methods that do the same thing as product.product .

You also need to pay attention to the mandatory field default_uom, which indicates the unit of measurement of the goods. To work with units, use the class product.uom . Appropriately, in order to get a list of available units of measurement, you can use the model.product.uom.search, model.product.uom.read .



List id with names uom
idTitle
oneThing
2Kilogram
3Gram
fourCarat
fiveLb
6Ounce
7Second
eightMinute
9Hour
tenWorking day
elevenDay
12Meter
13Kilometer
14centimeter
15Millimeter
sixteenFoot
17Yard
18Inch
nineteenMile
20Cubic meter
21Liter
22Cubic centimeter
23Cubic inch
24Cubic foot
25Gallon
26Square meter
27Square centimeter
28Ar
29Hectare
thirtySquare inch
31Square foot
32Square yard






An example of how to get existing units
 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. Category API


For all major classes, you can create a hierarchical categorization. To create a hierarchy, use the parent field in which the parent id is specified.



Method nameOptionsDescription
model. *. category.search[user_id, cookie, [], start, end, null, {}]Returns a snapshot of the id list of existing categories (id [start: end]).
model. *. category.fields_get[user_id, cookie, [], {}]Returns a list of fields available to a category.
model. *. category.read[user_id, cookie, list_of_category_ids, list_of_field_names, {}]Returns the values ​​of the specified fields of the specified categories.
model. *. category.create[user_id, cookie, [{field_name: field_data, field_name: field_data, ...}], {}]To create a category, the minimum is necessary to set the name field.
model. *. category.delete[user_id, cookie, list_delete_category_ids, {}]Removes categories by id.
model. *. category.write[user_id, cookie, list_update_category_ids, [{field_name: field_data, field_name: field_data, ...}], {}]Changes category field values ​​by id.




2.5. API module stock (warehouse)


It took a lot of time to understand that to work with warehouse documents, you need to use any user other than admin, and besides, you need to bind it to the company (specify the company field), otherwise you will receive a UserError in response.



The warehouse module has 5 types of documents:

  1. stock.shipment.in - document delivery of goods to the warehouse from the supplier.
  2. stock.shipment.in.return - document return goods to the supplier.
  3. stock.shipment.internal - document of internal movement between warehouses.
  4. stock.shipment.out - document shipment of goods from the warehouse to the buyer.
  5. stock.shipment.out.return - document return of goods from the buyer.




Below is a diagram for a visual understanding of the movement of goods through warehouses:







For several physical warehouses, it is necessary either to duplicate a warehouse with delivery and shipment areas, or to make several storage areas.



Below is the API for working with warehouse documents, instead of the asterisk we substitute the class of the desired document, for example model.stock.shipment.in.search .



Method nameOptionsDescription
model. *. search[user_id, cookie, [], start, end, null, {}]Returns a snapshot of the id list of existing documents (id [start: end]).
model. *. fields_get[user_id, cookie, [], {}]Returns a list of available document fields.
model. *. read[user_id, cookie, list_of_shipment_ids, list_of_field_names, {}]Returns the values ​​of the specified fields of the specified documents.
model. *. create[user_id, cookie, [{field_name: field_data, field_name: field_data, ...}], {}]Create a document.
model. *. delete[user_id, cookie, list_delete_shipment_ids, {}]Deletes a document by id.
model. *. write[user_id, cookie, list_update_shipment_ids, [{field_name: field_data, field_name: field_data, ...}], {}]Changes document field values ​​by id.
model. *. wait[user_id, cookie, list_shipment_ids, {}]Changes the state of the document in the wait by id.
model. *. done[user_id, cookie, list_shipment_ids, {}]Changes the state of the document in completed by id.




The warehouse module has a secondary location class for working directly with warehouses, rather than moving goods through warehouses and zones.



Here is an example of the parameters for the model.stock.shipment.in.create method [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}], {}] . Pay attention to "unit_price": {"decimal": "12.000", "__class__": "Decimal"}, if you specify in the query "unit_price": 12.000, the request will not be executed, because the warehouse module will not be able to convert the number it needs to the Decimal class. This behavior is noticed only in the fields that are responsible for the price.



Delivery documents stock.shipment.in have two states - draft (draft), done (done). The remaining documents have three states - draft (draft), wait (wait), done (done). The status of the documents affects the reports on the balances of goods and warehouses. If the document has a draft state, then the product specified in it is not displayed in the reports. If the document is in the wait state, then in the reports the goods are in the warehouse from which the movement / shipment is being made. If the document is in the done state, then the item in the report is in the warehouse where the transfer / shipment is made.



The warehouse module has a report of the balance of products at a specific warehouse / delivery-shipment zone - wizard.stock.products_by_locations. For receiving reports the main wizard class is used. Using the create method, a query to the database is created and written to the database, the execute method executes the query and the result is recorded in the database, the delete method deletes the query and the results from the database.



Method nameOptionsDescription
wizard.stock.products_by_locations.create[user_id, cookie, [], {}]Creates a query for a product report in stock. The method returns the report 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]}]Fulfills request. You must specify the date on which the calculation of balances and warehouse id will be made.
wizard.stock.products_by_locations.delete[user_id, cookie, wizard_id, {}]Deletes the report by id.

Source: https://habr.com/ru/post/224907/



All Articles