Create initial stock moves with proteus on a remote server

Hi,

We use Tryton 5.6 to manage our stocks. We planned to migrate to Tryton 6.0 with a clean database. So i made some proteus scripts to import specific data (product, lots, stocks). I’m using a postgresql database to store temporary data’s.

I’m following this procedure to set initial stock levels from postgresql database: Setup — trytond_stock latest documentation

When doing such stock moves, Tryton is raising a warning about “Moves without Origin”. I need some help to bypass the warning message. The way to do this is retrieve the warning key and store it to ignore. But with XML-RPC exception is only returning a code and a string, so i have to generate manually the same key to avoid the warning.

Got an error when doing

movesw = sorted(filter(no_origin, moves))

TypeError: ‘<’ not supported between instances of ‘stock.move’ and ‘stock.move’

Thanks for your help and suggestions. One “solution” would be to use my script on my server and avoid to use xml_rpc.
Could we imagine an easier way to bypass warning with proteus ?

Here’s my code:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import datetime
from decimal import Decimal
import hashlib
import psycopg2

from proteus import Model
from proteus import config as pconfig

TODAY = datetime.date.today()

def import_stock(config):
    Location = Model.get('stock.location')
    Lot = Model.get('stock.lot')
    Product = Model.get('product.product')
    ProductUom = Model.get('product.uom')
    Move = Model.get('stock.move')
    Company = Model.get('company.company')
    company, = Company.find()
    supplier_loc, = Location.find([('code', '=', 'SUP')])

    try:
        conn = psycopg2.connect(database='tryton_import', user='tryton',
                password='xxxxxx', host='postgresqlsrv', port='5432')
    except psycopg2.OperationalError as e:
        print("Unable to connect to DB!").format(e)
    cursor = conn.cursor()

    cursor.execute("""SELECT location_name,
                    product_code,
                    product_name,
                    lot_number,
                    quantity,
                    uom,
                    uom_code
                   FROM tryton_stock
                   where quantity > 0
                   ORDER BY 1""")
    stocks = cursor.fetchall()
    moves = []
    for stock in stocks:
        uom, = ProductUom.find([('name', '=', stock[5])])
        try:
            product, = Product.find([('code', '=', stock[1])])
            if product.default_uom != uom:
                print('Product UOM different %s : %s' % (stock[1], stock[6]))
                continue
        except(ValueError):
            print('Product not found %s' % stock[1])
            continue
        try:
            location, = Location.find([('name', '=', stock[0])])
        except(ValueError):
            print('Location not found %s' % stock[0])
            continue
        try:
            lot, = Lot.find([('number', '=', stock[3])])
        except(ValueError):
            print('Lot not found %s' % stock[3])
            continue
        move = Move()
        move.product = product
        move.lot = lot
        move.from_location = supplier_loc
        move.to_location = location
        move.currency = company.currency
        move.effective_date = TODAY
        move.quantity = stock[4]
        move.unit_price = Decimal('0')  # TODO get price
        moves.append(move)
    Move.save(moves)
    User = Model.get('res.user')
    admin_user, = User.find([('login', '=', 'admin')])

	# generate key following https://hg.tryton.org/modules/stock/file/tip/move.py#l871
    types = {'customer', 'supplier'}

    def no_origin(move):
        return ((move.from_location.type in types)
            ^ (move.to_location.type in types)
                and not move.origin)
    movesw = sorted(filter(no_origin, moves))

    warning_name = '%s.done' % hashlib.md5(
                str(movesw).encode('utf-8')).hexdigest()

    Model.get('res.user.warning')(user=admin_user,
        name=warning_name, always=True).save()
    Move.click(moves, 'do')

    cursor.close()
    conn.close()


def main():
    config = pconfig.set_xmlrpc(
        'http://admin:xxxxxx@172.16.99.1:8000/tryton60/')
    import_stock(config)


if __name__ == '__main__':
    main()

I solve a first problem:

Model class in Proteus has not __lt__implemented.

proteus: 7ab46d3e2b4d /proteus/init.py#l792

...
    def __lt__(self, other):
        if isinstance(other, Model):
            return ((self.__class__.__name__, self.id)
                  < (other.__class__.__name__, other.id))
        return NotImplemented
...

Anyway, the key generated in my script is not the same as the warning key, so i still get an error and my moves are not done.

I think the problem is in str(movesw) because __str__ of a list display the __repr__ of the content. But the __repr__ of Proteus Model and Trytond Model are not the same.
Indeed I think we should use something like '|'.join(map(str, records)) in Warning.format to be more generic (see Format warning name indepentently of the platform (#10672) · Issues · Tryton / Tryton · GitLab).

Thanks @ced, it’s working now :grinning: I’ll open another issue to add __lt__ to proteus.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.