Connectors mailing list archives
connectors@odoo-community.org
Browse archives
Re: Help with the framework 'connector'
byHi Cyrille,
Have you tried by removing the AbstractModel and put the `external_id` field definition on the `trello.project.binding` object ?
Regards,
--
Quentin
Hi,
I’m trying to build a Trello connector, using the connector v 11.0 module. I’m having some trouble with using the binding object. I built a backend, a binding, linked to the backend and extended the 'project.project' model with classic inheritance. The binding is also linked to the 'project.project' model with many-to-one relationship.
class TrelloProjectBackend(models.Model):
_name='trello.project.backend'
_description='Trello Project Backend'
_inherit='trello.abstract.backend'
@api.model
def read_projects(self, client):
#getting unique backend reference
backend = self.get_unique_backend(backend_type='project')
with backend.work_on(model_name='trello.project.backend') as work:
adapter = work.component(usage='backend.adapter')
binder = work.component(usage='project.binder')
bindings = self.env['trello.project.binding']
projects = self.env['project.project']
work.projects_data = adapter.read(client=client)
stages_data = []
for project_data in work.projects_data:
new_project = projects.create({
'name': project_data.name,
'board_url': project_data.url,
'desc': project_data.description,
'is_linked_to_trello': True,
})
new_binding = bindings.create({
'odoo_id': new_project.id,
'backend_id': backend.id,
'external_id': project_data.id,
'sync_date': datetime.datetime.now(),
})
binder.bind(external_id=project_data.id, binding=new_binding.id)
stages_data.append({'project_id': new_project.id, 'stages_data': project_data.all_lists()})
self.env['trello.stage.backend'].push_stages(data=stages_data)
logging.debug("getting binder data")
b_1 = binder.to_internal(project_data.id, unwrap=False)
b_2 = binder.to_internal(project_data.id, unwrap=True)
logging.debug("bindings for unwrap False: {}".format(b_1.__repr__()))
logging.debug("bindings for unwrap True: {}".format(b_2.__repr__()))
class TrelloAbstractBinding(models.AbstractModel):
_name='trello.abstract.binding'
_inherit='external.binding'
external_id=fields.Integer('ID in Trello')
class TrelloProjectBinding(models.Model):
_name='trello.project.binding'
_inherit='trello.abstract.binding'
_inherits={'project.project': 'odoo_id'}
odoo_id=fields.Many2one(
comodel_name='project.project',
string='Project',
required=True,
ondelete='cascade',
)
backend_id=fields.Many2one(
comodel_name='trello.project.backend',
string='Project Binding',
required=True,
ondelete='restrict',
)
_sql_constraints = [
('project_uniq', 'unique(backend_id, odoo_id)', 'Project with same ID already exists.')
]
class TrelloProject(models.Model):
_inherit='project.project'
desc=fields.Text('Description')
board_url=fields.Text('Trello Board URL', readonly=True)
is_linked_to_trello=fields.Boolean(default=False, readonly=True)
@api.model
def import_projects(self):
client = self.env.user.get_trello_client()
self.env['trello.project.backend'].read_projects(client=client)
I built a test scenario, to check if the building of new record from imported data is correctly executed :
class TestTrelloProjectBackend(TransactionCase):
def setUp(self, *args, **kwargs):
super(TestTrelloProjectBackend, self).setUp(*args, **kwargs)
@mock.patch('trello.TrelloClient')
@mock.patch('trello.Board')
@mock.patch('trello.List')
@mock.patch('trello.Card')
def test_read_projects(self, mock_trello_card, mock_trello_list, mock_trello_board, mock_trello_client):
trello_backend = self.env['trello.project.backend'].create({})
mock_trello_card.id = '789'
mock_trello_card.name = 'Mock Card Name'
mock_trello_card.due = '2019-01-30T12:40:37.123Z'
mock_trello_list.id = '456'
mock_trello_list.name = 'Mock List Name'
mock_trello_list.closed = False
mock_trello_list.pos = 2
mock_trello_list.list_cards.return_value = [mock_trello_card]
mock_trello_card.parent = mock_trello_list
mock_trello_board.id = '123'
mock_trello_board.name = 'Mock Board Name'
mock_trello_board.description = 'A mocked object to replace board object from py-trello library'
mock_trello_board.closed = False
mock_trello_board.url = 'http://fake.url.org/mockboardid'
mock_trello_board.all_lists.return_value = [mock_trello_list]
mock_trello_list.board = mock_trello_board
mock_trello_client.list_boards.return_value = [mock_trello_board]
trello_backend.read_projects(mock_trello_client)
mock_trello_client.list_boards.assert_called_once_with()
new_project = self.env['project.project'].search([('name','=','Mock Board Name')])
new_project.ensure_one()
self.assertEqual(new_project.name, 'Mock Board Name')
self.assertEqual(new_project.board_url, 'http://fake.url.org/mockboardid')
self.assertEqual(new_project.desc, 'A mocked object to replace board object from py-trello library')
The test fails with the following error :
ERROR
======================================================================
ERROR: test_read_projects (odoo.addons.connector_trello.tests.test_trello_project_backend.TestTrelloProjectBackend)
Traceback (most recent call last):
` File "/usr/lib/python3/dist-packages/mock/mock.py", line 1305, in patched
` return func(*args, **keywargs)
` File "/home/cyrille/odoo/addons-dev/connector_trello/tests/test_trello_project_backend.py", line 42, in test_read_projects
` trello_backend.read_projects(mock_trello_client)
` File "/home/cyrille/odoo/addons-dev/connector_trello/models/backends/trello_project_backend.py", line 57, in read_projects
` b_1 = binder.to_internal(project_data.id, unwrap=False)
` File "/home/cyrille/odoo/addons-ext/connector/components/binder.py", line 53, in to_internal
` (self._backend_field, '=', self.backend_record.id)]
` File "/opt/odoo/odoo/odoo/models.py", line 1480, in search
` res = self._search(args, offset=offset, limit=limit, order=order, count=count)
` File "/opt/odoo/odoo/odoo/models.py", line 3773, in _search
` query = self._where_calc(args)
` File "/opt/odoo/odoo/odoo/models.py", line 3563, in _where_calc
` e = expression.expression(domain, self)
` File "/opt/odoo/odoo/odoo/osv/expression.py", line 668, in __init__
` self.parse()
` File "/opt/odoo/odoo/odoo/osv/expression.py", line 846, in parse
` raise ValueError("Invalid field %r in leaf %r" % (left, str(leaf)))
` ValueError: Invalid field 'external_id' in leaf "<osv.ExtendedLeaf: ('external_id', '=', '123') on trello_project_backend (ctx: )>"
I can’t figure out what is wrong with the 'external_id' field.
I don’t know if it is linked to my problem, but I have this warning I can’t understand :
WARNING db_odoo_test_1 odoo.models: trello.task.backend.write() with unknown fields: external_id, sync_date
There is no external_id and sync_date fields in the backends, but maybe it should.
Thanks for reading,
Sincerely,
Cyrille (La LibreRie)
lalibrerie-solidaire.org
Python/Odoo developper
_______________________________________________
Mailing-List: https://odoo-community.org/groups/connectors-30
Post to: mailto:connectors@odoo-community.org
Unsubscribe: https://odoo-community.org/groups?unsubscribe
--
Quentin THEURET
Amaris