Exemple #1
0
class Module(models.Model):
    _name = 'builder.ir.module.module'

    @api.model
    def _get_categories(self):
        return [(c.name, c.name) for c in self.env['ir.module.category'].search([])]

    name = fields.Char("Technical Name", required=True, select=True)
    category_id = fields.Selection(simple_selection('ir.module.category', 'name') , 'Category')
    shortdesc = fields.Char('Module Name', translate=True, required=True)
    summary = fields.Char('Summary', translate=True)
    description = fields.Text("Description", translate=True)
    description_html = fields.Html(string='Description HTML', sanitize=False)
    author = fields.Char("Author", required=True)
    maintainer = fields.Char('Maintainer')
    contributors = fields.Text('Contributors')
    website = fields.Char("Website")

    version = fields.Char('Version', default='0.1')
    mirror = fields.Text('CodeMirror')

    url = fields.Char('URL')
    sequence = fields.Integer('Sequence')
    # dependencies_id = fields.One2many('programming.module.dependency', 'module_id', 'Dependencies')
    auto_install = fields.Boolean('Automatic Installation',
                                   help='An auto-installable module is automatically installed by the '
                                        'system when all its dependencies are satisfied. '
                                        'If the module has no dependency, it is always installed.')
    license = fields.Selection([
        ('GPL-2', 'GPL Version 2'),
        ('GPL-2 or any later version', 'GPL-2 or later version'),
        ('GPL-3', 'GPL Version 3'),
        ('GPL-3 or any later version', 'GPL-3 or later version'),
        ('AGPL-3', 'Affero GPL-3'),
        ('Other OSI approved licence', 'Other OSI Approved Licence'),
        ('Other proprietary', 'Other Proprietary')
    ], string='License', default='AGPL-3')

    application = fields.Boolean('Application')

    icon_image = fields.Binary(string='Icon')
    icon_image_name = fields.Char('Icon Filename')

    menus_by_module = fields.Text(string='Menus')
    reports_by_module = fields.Text(string='Reports')
    views_by_module = fields.Text(string='Views')
    demo = fields.Boolean('Has Demo Data')

    post_install_action = fields.Reference([
                                    ('builder.ir.actions.act_window', 'Window'),
                                    # ('builder.ir.actions.act_url', 'URL'),
    ], 'After Install Action')

    models_count = fields.Integer("Models Count", compute='_compute_models_count', store=False, search=True)

    dependency_ids = fields.One2many(
        comodel_name='builder.ir.module.dependency',
        inverse_name='module_id',
        string='Dependencies',
        copy=True
    )

    model_ids = fields.One2many('builder.ir.model', 'module_id', 'Models', copy=True)
    view_ids = fields.One2many('builder.ir.ui.view', 'module_id', 'Views', copy=True)
    menu_ids = fields.One2many('builder.ir.ui.menu', 'module_id', 'Menus', copy=True)
    group_ids = fields.One2many('builder.res.groups', 'module_id', 'Groups', copy=True)
    model_access_ids = fields.One2many('builder.ir.model.access', 'module_id', 'ACLs', copy=True)
    rule_ids = fields.One2many('builder.ir.rule', 'module_id', 'Rules', copy=True)
    cron_job_ids = fields.One2many('builder.ir.cron', 'module_id', 'Cron Jobs', copy=True)
    action_ids = fields.One2many('builder.ir.actions.actions', 'module_id', 'Actions', copy=True)
    action_window_ids = fields.One2many('builder.ir.actions.act_window', 'module_id', 'Window Actions', copy=True)
    action_url_ids = fields.One2many('builder.ir.actions.act_url', 'module_id', 'URL Actions', copy=True)
    workflow_ids = fields.One2many('builder.workflow', 'module_id', 'Workflows', copy=True)
    backend_asset_ids = fields.One2many('builder.web.asset', 'module_id', 'Assets', copy=True)

    data_file_ids = fields.One2many('builder.data.file', 'module_id', 'Data Files', copy=True)
    snippet_bookmarklet_url = fields.Char('Link', compute='_compute_snippet_bookmarklet_url')

    @api.model
    def _get_default_author(self):
        return self.env.user.name if self.env.user else None

    _defaults = {
        'author': _get_default_author
    }

    @api.one
    def copy(self, default=None):
        default = dict(default or {})
        default['shortdesc'] = _('%s (copy)') % self.shortdesc
        return super(Module, self).copy(default)

    @api.onchange('shortdesc')
    def _compute_name(self):
        if not self.name and self.shortdesc:
            self.name = self.shortdesc.lower().replace(' ', '_').replace('.', '_')

    @api.one
    @api.depends('name')
    def _compute_snippet_bookmarklet_url(self):
        base_url = self.env['ir.config_parameter'].get_param('web.base.url')
        link = """
javascript:(function(){
    function script(url, callback){
        var new_script = document.createElement('script');
        new_script.src = url + '?__stamp=' + Math.random();
        new_script.onload = new_script.onreadystatechange = callback;
        document.getElementsByTagName('head')[0].appendChild(new_script);
        new_script.type='text/javascript';
    };
    window.odooUrl = '$base_url';
    window.newSnippetUrl = '$base_url/builder/$module/snippet/add';
    script('$base_url/builder/static/src/js/snippet_loader.js');
})();
        """
        self.snippet_bookmarklet_url = Template(link).substitute(base_url=base_url, module=self.name)

    @api.multi
    def dependencies_as_list(self):
        return [str(dep.name) for dep in self.dependency_ids]

    @api.one
    def add_dependency(self, names):
        if not names:
            return

        dependency_obj = self.env['builder.ir.module.dependency']
        if not isinstance(names, list):
            names = [names]

        for name in names:
            if not dependency_obj.search([('module_id', '=', self.id), ('dependency_module_name', '=', name)]).id:
                dependency_obj.create({
                    'module_id': self.id,
                    'type': 'manual',
                    'dependency_module_name': name
                })

    @api.one
    @api.depends('model_ids')
    def _compute_models_count(self):
        self.models_count = len(self.model_ids)

    @api.multi
    def action_base_files(self):
        search = self.env.ref('builder.view_builder_data_file_filter', False)
        return {
            'name': _('Files'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'kanban,tree,form',
            'res_model': 'builder.data.file',
            'views': [(False, 'kanban'),(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            'search_view_id': search.id if search else False,
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_models(self):

        tree_view = self.env.ref('builder.builder_ir_model_tree_view', False)
        form_view = self.env.ref('builder.builder_ir_model_form_view', False)

        return {
            'name': _('Models'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form,diagram',
            'res_model': 'builder.ir.model',
            'views': [(tree_view and tree_view.id or False, 'tree'), (form_view and form_view.id or False, 'form')],
            'view_id': tree_view and tree_view.id,
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_views(self):

        tree_view = self.env.ref('builder.builder_ir_ui_view_tree', False)
        form_view = self.env.ref('builder.builder_ir_ui_view_form', False)

        return {
            'name': _('Views'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.ir.ui.view',
            'views': [(tree_view.id if tree_view else False, 'tree'), (form_view.id if form_view else False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_actions(self):

        return {
            'name': _('Actions'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.ir.actions.act_window',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_menus(self):

        return {
            'name': _('Menus'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.ir.ui.menu',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_groups(self):

        return {
            'name': _('Groups'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.res.groups',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_model_access(self):

        return {
            'name': _('Access Control Rules'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.ir.model.access',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_rules(self):

        return {
            'name': _('Model Rules'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.ir.rule',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_workflows(self):
        return {
            'name': _('Workflows'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.workflow',
            'views': [(False, 'tree'), (False, 'form'), (False, 'diagram')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_config_models(self):

        return {
            'name': _('Configuration Models'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.res.config.settings',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_cron_jobs(self):

        return {
            'name': _('Cron Jobs'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.ir.cron',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_backend_assets(self):

        return {
            'name': _('Backend Assets'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.web.asset',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_website_pages(self):

        return {
            'name': _('Pages'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.website.page',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_website_assets(self):

        return {
            'name': _('Assets'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.website.asset',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_website_themes(self):

        return {
            'name': _('Themes'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.website.theme',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_website_media_item(self):

        return {
            'name': _('Media Manager'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.website.media.item',
            'views': [(False, 'kanban'), (False, 'tree')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_website_menus(self):

        return {
            'name': _('Website Menus'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.website.menu',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }


    @api.multi
    def action_website_snippets(self):

        return {
            'name': _('Snippets'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'builder.website.snippet',
            'views': [(False, 'tree'), (False, 'form')],
            'domain': [('module_id', '=', self.id)],
            # 'target': 'current',
            'context': {
                'default_module_id': self.id
            },
        }

    @api.multi
    def action_diagram(self):

        diagram_view = self.env.ref('builder.view_builder_model_diagram', False)

        return {
            'name': _('UML Diagram'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'diagram',
            'res_model': 'builder.ir.module.module',
            'views': [(diagram_view and diagram_view.id or False, 'diagram'), ],
            'view_id': diagram_view and diagram_view.id,
            'res_id': self.id,
            'target': 'new',
            # 'flags': {'form': {'action_buttons': True, 'options': {'mode': 'edit'}}},
            'context': {
                'default_module_id': self.id,
                'diagram_view': True
            },
        }

    def action_edit_description_html(self, cr, uid, ids, context=None):
        if not len(ids) == 1:
            raise ValueError('One and only one ID allowed for this action')
        url = '/builder/page/designer?model={model}&res_id={id}&enable_editor=1'.format(id=ids[0], model=self._name)
        return {
            'name': _('Edit Template'),
            'type': 'ir.actions.act_url',
            'url': url,
            'target': 'self',
        }

    def import_models(self, model):
        pass

    @api.multi
    def _export_zip(self):
        return self.get_zipped_module()

    @api.multi
    def _export_odoo(self):
        return json.JsonExport(self.env).export(self)

    @api.model
    def _import_odoo(self, importer):
        return json.JsonImport(self.env).build(self, decodestring(importer.file))
class TestModel(models.Model):
    _name = 'test.model'

    _inherit = ['mail.thread']

    _columns = {}  # deprecated columns
    _defaults = {}  # deprecated defaults
    length = fields.Integer()  # Deprecated length by js errors

    name = fields.Char(
        _(u"Näme"),  # Don't need translate
        help=u"My hëlp",
        required=False,
        compute='_compute_name',  # good compute method name
        search='_search_name',  # good search method name
        inverse='_inverse_name',  # good inverse method name
    )

    # Imported openerp.fields use Char (Upper case)
    other_field = fields.char(
        name=_("Other field"),
        copy=True,
        compute='my_method_compute',  # bad compute method name
        search='my_method_search',  # bad search method name
        inverse='my_method_inverse',  # bad inverse method name
    )
    compute_none = fields.Char(compute=None)

    other_field2 = fields.char(
        'Other Field2',
        copy=True,
    )

    # This is a inherit overwrite field then don't should show errors related
    # with creation of fields.
    def method_date(self):
        date = fields.Date.to_string(
            fields.Datetime.context_timestamp(self,
                                              timestamp=fields.Datetime.now())
        )
        return date

    my_ok_field = fields.Float(
        "My correctly named field",
        digits=(6, 6),  # OK: Valid field parameter
        index=True,  # OK: Valid field parameter
        help="My ok field",
    )

    my_ko_field = fields.Float(
        digits_compute=lambda cr: (6, 6),  # Deprecated field parameter
        select=True,  # Deprecated field parameter
        help="My ko field",
        string="My Ko Field",  # String parameter equal to name of variable
    )

    """The name of the variable is equal to the string parameter
    Tested all fields.*"""

    boolean_variable_1 = fields.Boolean(string='Boolean Variable 1',
                                        help="Help")
    boolean_variable_2 = fields.Boolean("Boolean Variable 2", help="Help")

    char_variable_1 = fields.Char(string='Char Variable 1', help="Help")
    char_variable_2 = fields.Char("Char Variable 2", help="Help")

    text_variable_1 = fields.Text(string='Text Variable 1', help="Help")
    text_variable_2 = fields.Text("Text Variable 2", help="Help")

    html_variable_1 = fields.Html(string='Html Variable 1', help="Help")
    html_variable_2 = fields.Html("Html Variable 2", help="Help")

    integer_variable_1 = fields.Integer(string='Integer Variable 1',
                                        help="Help")
    integer_variable_2 = fields.Integer("Integer Variable 2", help="Help")

    float_variable_1 = fields.Float(string='Float Variable 1', help="Help")
    float_variable_2 = fields.Float("Float Variable 2", help="Help")

    date_variable_1 = fields.Date(string='Date Variable 1', help="Help")
    date_variable_2 = fields.Date("Date Variable 2", help="Help")

    date_time_variable_1 = fields.DateTime(string='Date Time Variable 1',
                                           help="Help")
    date_time_variable_2 = fields.DateTime("Date Time Variable 2", help="Help")

    binary_variable_1 = fields.Binary(string='Binary Variable 1', help="Help")
    binary_variable_2 = fields.Binary("Binary Variable 2", help="Help")

    selection_variable_1 = fields.Selection(selection=[('a', 'A')],
                                            string='Selection Variable 1',
                                            help="Help")
    selection_variable_2 = fields.Selection([('a', 'A')],
                                            "Selection Variable 2",
                                            help="Help")

    reference_variable_1 = fields.Reference(selection=[('res.user', 'User')],
                                            string="Reference Variable 1",
                                            help="Help")
    reference_variable_2 = fields.Reference([('res.user', 'User')],
                                            "Reference Variable 2",
                                            help="Help")

    many_2_one_variable_1 = fields.Many2one(comodel_name='res.users',
                                            string='Many 2 One Variable 1',
                                            help="Help")
    many_2_one_variable_2 = fields.Many2one('res.users',
                                            "Many 2 One Variable 2",
                                            help="Help")

    one_2_many_variable_1 = fields.One2many(comodel_name='res.users',
                                            inverse_name='rel_id',
                                            string='One 2 Many Variable 1',
                                            help="Help")
    one_2_many_variable_2 = fields.One2many('res.users',
                                            'rel_id',
                                            "One 2 Many Variable 2",
                                            help="Help")

    many_2_many_variable_1 = fields.Many2many(comodel_name='res.users',
                                              relation='table_name',
                                              column1='col_name',
                                              column2='other_col_name',
                                              string='Many 2 Many Variable 1',
                                              help="Help")
    many_2_many_variable_2 = fields.Many2many('res.users',
                                              'table_name',
                                              'col_name',
                                              'other_col_name',
                                              "Many 2 Many Variable 2",
                                              help="Help")

    field_case_sensitive = fields.Char(
        'Field Case SENSITIVE',
        help="Field case sensitive"
    )

    name_equal_to_string = fields.Float(
        "Name equal to string",
        help="Name Equal To String"
    )

    many_2_one = fields.Many2one(
        'res.users',
        "Many 2 One",
        help="Many 2 one"
    )

    many_2_many = fields.Many2many(
        'res.users',
        'relation',
        'fk_column_from',
        'fk_column_to',
        "Many 2 many",
        help="Many 2 Many"
    )

    def my_method1(self, variable1):
        #  Shouldn't show error of field-argument-translate
        self.my_method2(_('hello world'))

        # Message post without translation function
        self.message_post(subject='Subject not translatable',
                          body='Body not translatable %s' % variable1)
        self.message_post(subject='Subject not translatable %(variable)s' %
                          {'variable': variable1},
                          body='Body not translatable {}'.format(variable1),
                          message_type='notification')
        self.message_post('Body not translatable',
                          'Subject not translatable {a}'.format(a=variable1))
        self.message_post('Body not translatable %s' % variable1,
                          'Subject not translatable %(variable)s' %
                          {'variable': variable1})
        self.message_post('Body not translatable',
                          subject='Subject not translatable')
        self.message_post(body='<h1>%s</h1><p>%s</p>' % (
            _('Paragraph translatable'), 'Paragraph not translatable'))

        # Message post with translation function
        self.message_post(subject=_('Subject translatable'),
                          body=_('Body translatable'))
        self.message_post(_('Body translatable'),
                          _('Subject translatable'))
        self.message_post(_('Body translatable'),
                          subject=_('Subject translatable'))
        self.message_post(_('A CDR has been recovered for %s') % (variable1,))
        self.message_post(_('A CDR has been recovered for %s') % variable1)
        self.message_post(_('Var {a}').format(a=variable1))
        self.message_post(_('Var %(variable)s') % {'variable': variable1})
        self.message_post(subject=_('Subject translatable'),
                          body=_('Body translatable %s') % variable1)
        self.message_post(subject=_('Subject translatable %(variable)s') %
                          {'variable': variable1},
                          message_type='notification')
        self.message_post(_('Body translatable'),
                          _('Subject translatable {a}').format(a=variable1))
        self.message_post(_('Body translatable %s') % variable1,
                          _('Subject translatable %(variable)s') %
                          {'variable': variable1})
        self.message_post('<p>%s</p>' % _('Body translatable'))
        self.message_post(body='<p>%s</p>' % _('Body translatable'))

        # There is no way to know if the variable is translated, then ignoring
        self.message_post(variable1)
        self.message_post(body=variable1 + variable1)
        self.message_post(body=(variable1 + variable1))
        self.message_post(body=variable1 % variable1)
        self.message_post(body=(variable1 % variable1))

        # translation function with variables in the term
        variable2 = variable1
        self.message_post(_('Variable not translatable: %s' % variable1))
        self.message_post(_('Variables not translatable: %s, %s' % (
            variable1, variable2)))
        self.message_post(body=_('Variable not translatable: %s' % variable1))
        self.message_post(body=_('Variables not translatable: %s %s' % (
            variable1, variable2)))
        error_msg = _('Variable not translatable: %s' % variable1)
        error_msg = _('Variables not translatable: %s, %s' % (
            variable1, variable2))
        error_msg = _('Variable not translatable: {}'.format(variable1))
        error_msg = _('Variables not translatable: {}, {variable2}'.format(
            variable1, variable2=variable2))

        # string with parameters without name
        # so you can't change the order in the translation
        _('%s %d') % ('hello', 3)
        _('%s %s') % ('hello', 'world')

        # Valid cases
        _('%(strname)s') % {'strname': 'hello'}
        _('%(strname)s %(intname)d') % {'strname': 'hello', 'intname': 3}
        _('%s') % 'hello'
        _('%d') % 3
        return error_msg

    def my_method2(self, variable2):
        return variable2

    def my_method3(self, cr):
        cr.commit()  # Dangerous use of commit old api
        self.env.cr.commit()  # Dangerous use of commit
        self._cr.commit()  # Dangerous use of commit
        self.cr.commit()  # Dangerous use of commit
        return cr

    def my_method4(self, variable2):
        self.env.cr2.commit()  # This should not be detected
        return variable2

    def my_method5(self, variable2):
        self.env.cr.commit2()  # This should not be detected
        return variable2

    def my_method6(self):
        user_id = 1
        if user_id != 99:
            # Method without translation
            raise UserError('String without translation')

    def my_method7(self):
        user_id = 1
        if user_id != 99:
            # Method with translation
            raise UserError(_('String with translation'))

    def my_method8(self):
        user_id = 1
        if user_id != 99:
            str_error = 'String with translation 2'  # Don't check
            raise UserError(str_error)

    def my_method9(self):
        user_id = 1
        if user_id != 99:
            # Method without translation
            raise UserError("String without translation 2")

    def my_method10(self):
        # A example of built-in raise without parameters
        # Shouldn't show error from lint
        raise ZeroDivisionError
        raise ZeroDivisionError()

    def my_method11(self):
        # A example of built-in raise with parameters
        # Shouldn't show error from lint
        raise ZeroDivisionError("String without translation")
        # raise without class-exception to increase coverage
        raise
        raise "obsolete case"

    def my_method12(self):
        # Should show error
        raise exceptions.Warning(
            'String with params format {p1}'.format(p1='v1'))
        raise exceptions.Warning(
            'qp2w String with params format %(p1)s' % {'p1': 'v1'})

    def my_method13(self):
        # Shouldn't show error
        raise exceptions.Warning(_(
            'String with params format {p1}').format(p1='v1'))
        raise exceptions.Warning(_(
            'String with params format {p1}'.format(p1='v1')))
        raise exceptions.Warning(_(
            'String with params format %(p1)s') % {'p1': 'v1'})
        raise exceptions.Warning(_(
            'String with params format %(p1)s' % {'p1': 'v1'}))

    def old_api_method_alias(self, cursor, user, ids, context=None):  # old api
        pass

    def sql_method(self, ids, cr):
        # Use of query parameters: nothing wrong here
        self._cr.execute(
            'SELECT name FROM account WHERE id IN %s', (tuple(ids),))
        self.env.cr.execute(
            'SELECT name FROM account WHERE id IN %s', (tuple(ids),))
        cr.execute(
            'SELECT name FROM account WHERE id IN %s', (tuple(ids),))
        self.cr.execute(
            'SELECT name FROM account WHERE id IN %s', (tuple(ids),))

    def sql_injection_ignored_cases(self, ids, cr2):
        # This cr.execute2 or cr2.execute should not be detected
        self._cr.execute2(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))
        cr2.execute(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))

        # Ignore when the query is built using private attributes
        self._cr.execute(
            'DELETE FROM %s WHERE id IN %%s' % self._table, (tuple(ids),))

        # Ignore string parsed with "".format() if args are psycopg2.sql.* calls
        query = "SELECT * FROM table"
        # imported from pyscopg2 import sql
        self._cr.execute(
            sql.SQL("""CREATE or REPLACE VIEW {} as ({})""").format(
                sql.Identifier(self._table),
                sql.SQL(query)
            ))
        self._cr.execute(
            sql.SQL("""CREATE or REPLACE VIEW {table} as ({query})""").format(
                table=sql.Identifier(self._table),
                query=sql.SQL(query),
            ))
        # imported from pyscopg2.sql import SQL, Identifier
        self._cr.execute(
            SQL("""CREATE or REPLACE VIEW {} as ({})""").format(
                Identifier(self._table),
                SQL(query),
            ))
        self._cr.execute(
            SQL("""CREATE or REPLACE VIEW {table} as ({query})""").format(
                table=Identifier(self._table),
                query=SQL(query),
            ))
        # imported from pyscopg2 direclty
        self._cr.execute(
            psycopg2.SQL("""CREATE or REPLACE VIEW {} as ({})""").format(
                psycopg2.sql.Identifier(self._table),
                psycopg2.sql.SQL(query),
            ))
        self._cr.execute(
            psycopg2.sql.SQL("""CREATE or REPLACE VIEW {table} as ({query})""").format(
                table=Identifier(self._table),
                query=SQL(query),
            ))
        # Variables build using pyscopg2.sql.* callers
        table = Identifier('table_name')
        sql_query = SQL(query)
        # format params
        self._cr.execute(
            SQL("""CREATE or REPLACE VIEW {} as ({})""").format(
                table,
                sql_query,
            ))
        # format dict
        self._cr.execute(
            SQL("""CREATE or REPLACE VIEW {table} as ({query})""").format(
                table=table,
                query=sql_query,
            ))

    # old api
    def sql_injection_modulo_operator(self, cr, uid, ids, context=None):
        # Use of % operator: risky
        self._cr.execute(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))
        self.env.cr.execute(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))
        cr.execute(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))
        self.cr.execute(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))

        operator = 'WHERE'
        self._cr.execute(
            'SELECT name FROM account %s id IN %%s' % operator, ids)

        var = 'SELECT name FROM account WHERE id IN %s'
        values = ([1, 2, 3, ], )
        self._cr.execute(var % values)

    def sql_injection_executemany(self, ids, cr, v1, v2):
        # Check executemany() as well
        self.cr.executemany(
            'INSERT INTO account VALUES (%s, %s)' % (v1, v2))

    def sql_injection_format(self, ids, cr):
        # Use of .format(): risky
        self.cr.execute(
            'SELECT name FROM account WHERE id IN {}'.format(ids))

    def sql_injection_plus_operator(self, ids, cr):
        # Use of +: risky
        self.cr.execute(
            'SELECT name FROM account WHERE id IN ' + str(tuple(ids)))

        operator = 'WHERE'
        self._cr.execute(
            'SELECT name FROM account ' + operator + ' id IN %s', ids)
        self.cr.execute(
            ('SELECT name FROM account ' + operator + ' id IN (1)'))
        self.cr.execute(
            'SELECT name FROM account ' +
            operator +
            ' id IN %s' % (tuple(ids),))
        self.cr.execute(
            ('SELECT name FROM account ' +
             operator +
             ' id IN %s') % (tuple(ids),))

    def sql_injection_before(self, ids):
        # query built before execute: risky as well

        var = 'SELECT name FROM account WHERE id IN %s' % tuple(ids)
        self._cr.execute(var)

        var[1] = 'SELECT name FROM account WHERE id IN %s' % tuple(ids)
        self._cr.execute(var[1])

    def sql_no_injection_private_attributes(self, _variable, variable):
        # Skip sql-injection using private attributes
        self._cr.execute(
            "CREATE VIEW %s AS (SELECT * FROM res_partner)" % self._table)
        # Real sql-injection cases
        self._cr.execute(
            "CREATE VIEW %s AS (SELECT * FROM res_partner)" % self.table)
        self._cr.execute(
            "CREATE VIEW %s AS (SELECT * FROM res_partner)" % _variable)
        self._cr.execute(
            "CREATE VIEW %s AS (SELECT * FROM res_partner)" % variable)
Exemple #3
0
class cloud_service_api_fournisseur_aws(models.Model):
    _inherit = 'cloud.service.api.fournisseur'

    api_ref = fields.Reference(selection_add=[('cloud.service.api.aws',
                                               'api aws')])
Exemple #4
0
class Task(models.Model):
    _name = 'workflow.task'
    _inherit = ['mail.thread']
    _description = "Workflow Task"

    @api.model
    def _select_objects(self):
        model_obj = self.env['ir.model']
        models = model_obj.search([])
        return [(r.model, r.name) for r in models] + [('', '')]

    name = fields.Char(related='activity_id.name')
    workitem = fields.Many2one(comodel_name='workflow.workitem')
    activity_id = fields.Many2one(comodel_name='workflow.activity',
                                  string='Activity',
                                  required=True)
    description = fields.Text()
    user_id = fields.Many2one(comodel_name='res.users',
                              string='Assigned User',
                              track_visibility='onchange')
    state = fields.Selection([('new', 'Todo'), ('started', 'In progress'),
                              ('closed', 'Closed')],
                             default='new',
                             track_visibility='onchange')
    date_deadline = fields.Date(string="Deadline", track_visibility='onchange')
    date_critical = fields.Date(
        help="""The created task will appear in red in the task tree view
            after this date""")
    date_started = fields.Datetime(string="Started on",
                                   track_visibility='onchange')
    date_closed = fields.Datetime(string="Closed on",
                                  track_visibility='onchange')
    res_type = fields.Selection(selection=_select_objects,
                                string='Type',
                                required=True)
    res_id = fields.Integer(string='ID', required=True)
    ref_object = fields.Reference(string='Objet',
                                  selection=_select_objects,
                                  store=True,
                                  compute='_get_ref_object')
    ref_object_name = fields.Char(search='_search_ref_object',
                                  compute='_dummy_compute',
                                  string="Related object")
    action_ids = fields.One2many(comodel_name='workflow.activity.action',
                                 compute='_get_action_ids')
    pretty_res_type = fields.Char(compute='_get_pretty_res_type')

    def fields_get(self,
                   cr,
                   user,
                   allfields=None,
                   context=None,
                   write_access=True,
                   attributes=None):
        res = super(Task, self).fields_get(cr, user, allfields, context,
                                           write_access, attributes)
        # remove ref_object from searchable field into the advanced search
        # since the field to use is ref_object_name
        if 'ref_object' in res:
            res['ref_object']['searchable'] = False
        return res

    @api.multi
    @api.depends('res_type')
    def _get_pretty_res_type(self):
        for record in self:
            model = self.env['ir.model']\
                .search([('model', '=', record.res_type)])
            record.pretty_res_type = model.name

    def _search_ref_object(self, operator, value):
        self._cr.execute("""SELECT distinct res_type FROM workflow_task""")
        models = self._cr.fetchall()
        all_task_ids = []
        for model in models:
            model = model[0]
            self._cr.execute(
                """SELECT distinct res_id FROM workflow_task
                WHERE res_type=%s""", (model, ))
            mids = [r[0] for r in self._cr.fetchall()]
            if not self.env[model].check_access_rights('read',
                                                       raise_exception=False):
                continue
            ns_result = self.env[model].name_search(name=value,
                                                    operator=operator,
                                                    args=[('id', 'in', mids)])
            obj_ids = [r[0] for r in ns_result]
            tids = self.search([('res_type', '=', model),
                                ('res_id', 'in', obj_ids)])
            all_task_ids.extend(tids._ids)
        return [('id', 'in', all_task_ids)]

    @api.depends('ref_object')
    @api.multi
    def _dummy_compute(self):
        for record in self:
            record.ref_object_name = record.ref_object

    @api.multi
    def _get_action_ids(self):
        for record in self:
            if record.activity_id.use_action_task and\
                    record.activity_id._check_action_security(record.res_type,
                                                              record.res_id):
                record.action_ids = record.activity_id.action_ids

    @api.multi
    def start_task(self):
        for record in self:
            record.date_started = fields.Datetime.now()
            record.state = 'started'
            record.user_id = self.env.uid

    @api.multi
    def close_task(self):
        for record in self:
            record.date_closed = fields.Datetime.now()
            record.state = 'closed'
            record.user_id = False

    @api.depends('res_type', 'res_id')
    @api.one
    def _get_ref_object(self):
        if self.res_type and self.res_id:
            self.ref_object = '%s,%s' % (self.res_type, str(self.res_id))

    @api.model
    def check_base_security(self, res_model, res_ids, mode):
        ima = self.env['ir.model.access']
        ima.check(res_model, mode)
        self.pool[res_model].check_access_rule(self._cr,
                                               self._uid,
                                               res_ids,
                                               mode,
                                               context=self.env.context)

    @api.multi
    def _check_activity_security(self):
        self._cr.execute(
            """SELECT id, res_type, res_id, activity_id FROM workflow_task
               WHERE id = ANY(%s)""", (list(self._ids), ))
        targets = self._cr.dictfetchall()
        res = {}
        for task_dict in targets:
            if not self.pool['workflow.activity'].\
                    _check_action_security(self._cr, self._uid,
                                           [task_dict['activity_id']],
                                           task_dict['res_type'],
                                           task_dict['res_id']):
                res[task_dict['id']] = False
            else:
                res[task_dict['id']] = True
        return res

    @api.multi
    def check(self, mode, values=None):
        """Restricts the access to a workflow task, according to
           referred model.
        """
        res_ids = {}
        if self._ids:
            self._cr.execute(
                """SELECT DISTINCT res_type, res_id FROM
                   workflow_task WHERE id = ANY (%s)""", (list(self._ids), ))
            for rmod, rid in self._cr.fetchall():
                res_ids.setdefault(rmod, set()).add(rid)
        if values:
            if values.get('res_type') and values.get('res_id'):
                res_ids.setdefault(values['res_type'], set())\
                    .add(values['res_id'])

        for model, mids in res_ids.items():
            existing_ids = self.pool[model].exists(self._cr, self._uid, mids)
            self.check_base_security(model, existing_ids, mode)
        if not self._uid == SUPERUSER_ID and\
                not self.env['res.users'].has_group('base.group_user'):
            raise exceptions.AccessError(
                _("Sorry, you are not allowed to access this document."))

    def _search(self,
                cr,
                uid,
                args,
                offset=0,
                limit=None,
                order=None,
                context=None,
                count=False,
                access_rights_uid=None):
        ids = super(Task, self)._search(cr,
                                        uid,
                                        args,
                                        offset=0,
                                        limit=None,
                                        order=order,
                                        context=context,
                                        count=False,
                                        access_rights_uid=access_rights_uid)
        if not ids:
            if count:
                return 0
            return []
        orig_ids = ids
        ids = set(ids)
        cr.execute(
            """SELECT id, res_type, res_id FROM workflow_task
               WHERE id = ANY(%s)""", (list(ids), ))
        targets = cr.dictfetchall()
        model_tasks = {}
        for target_dict in targets:
            if not target_dict['res_type']:
                continue
            # model_tasks = { 'model': { 'res_id': [id1,id2] } }
            model_tasks.setdefault(target_dict['res_type'], {})\
                .setdefault(target_dict['res_id'] or 0, set())\
                .add(target_dict['id'])

        # To avoid multiple queries for each task found, checks are
        # performed in batch as much as possible.
        ima = self.pool.get('ir.model.access')
        for model, targets in model_tasks.iteritems():
            if model not in self.pool:
                continue
            if not ima.check(cr, uid, model, 'read', False):
                # remove all corresponding task ids
                for attach_id in itertools.chain(*targets.values()):
                    ids.remove(attach_id)
                continue  # skip ir.rule processing,these ones are out already

            # filter ids according to what access rules permit
            target_ids = targets.keys()
            allowed_ids = [0] + self.pool[model].search(
                cr, uid, [('id', 'in', target_ids)], context=context)
            disallowed_ids = set(target_ids).difference(allowed_ids)
            for res_id in disallowed_ids:
                for attach_id in targets[res_id]:
                    ids.remove(attach_id)
#         activity_security = self._check_activity_security(cr, uid, ids,
#                                                           context=context)
#         for task_id, res in activity_security.iteritems():
#             if not res:
#                 ids.remove(task_id)
# sort result according to the original sort ordering
        result = [id for id in orig_ids if id in ids]
        ids = super(Task, self)._search(cr,
                                        uid, [('id', 'in', result)],
                                        offset=offset,
                                        limit=limit,
                                        order=order,
                                        context=context,
                                        count=False,
                                        access_rights_uid=access_rights_uid)
        return len(ids) if count else list(ids)

    @api.multi
    def read(self, fields=None, load='_classic_read'):
        self.check('read')
        return super(Task, self).read(fields=fields, load=load)

    @api.multi
    def write(self, vals):
        # If mode is write, it's impossible to start the task
        self.check('read', values=vals)
        return super(Task, self).write(vals)

    @api.multi
    def copy(self, default=None):
        self.check('write')
        return super(Task, self).copy(default=default)

    @api.multi
    def unlink(self):
        self.check('unlink')
        return super(Task, self).unlink()

    @api.model
    @api.returns('self', lambda value: value.id)
    def create(self, values):
        self.check('write', values=values)
        return super(Task, self).create(values)
Exemple #5
0
class NeedSyncLine(models.Model):
    _name = "need.sync.line"
    _description = "Need Sync Line Based"

    name = fields.Char(string="Sync", compute="_get_name")
    need_sync = fields.Many2one(comodel_name="need.sync",
                                string="Need Sync",
                                index=True,
                                ondelete="cascade")
    need_sync_connection = fields.Many2one(comodel_name="need.sync.connection",
                                           string="Connection",
                                           index=True)
    need_sync_date = fields.Datetime(related="need_sync.need_sync_date")
    model = fields.Selection(related="need_sync.model", store=True, index=True)
    res_id = fields.Integer(related="need_sync.res_id", store=True, index=True)
    record = fields.Reference(related="need_sync.record",
                              store=True,
                              index=True)
    sync_needed = fields.Boolean(string="Sync Needed",
                                 compute="_compute_need_sync",
                                 store=True,
                                 index=True,
                                 help="Synchronization Required")
    last_sync_date = fields.Datetime(string="Last Sync Datetime")
    confirmed_date = fields.Datetime(string="Last Confirm Datetime")
    published = fields.Boolean(string="Published", default=True, index=True)

    _sql_constraints = {('connection_need_sync_uniq',
                         'unique(need_sync, need_sync_connection)',
                         'Only one need sync per connection')}

    @api.one
    @api.depends('need_sync.res_id', 'need_sync.model',
                 'need_sync_connection.name')
    def _get_name(self):
        object = self.env[self.need_sync.model].browse(self.need_sync.res_id)
        if object and 'name' in object._fields:
            object_name = object.name
        else:
            object_name = "No object name defined"
        if self.need_sync_connection:
            connection_name = self.need_sync_connection.name
        else:
            connection_name = 'No Connection Name'
        self.name = '%s (%s)' % (object_name, connection_name)

    @api.one
    @api.depends('need_sync.need_sync_date', 'last_sync_date',
                 'confirmed_date', 'published')
    def _compute_need_sync(self):
        if self.published == True:
            if self.need_sync_date > self.last_sync_date:
                self.sync_needed = True
            elif self.need_sync_date and not self.last_sync_date:
                self.sync_needed = True
            elif self.sync_needed == True:
                self.sync_needed = False
        else:
            self.sync_needed = False

    @api.multi
    def _create_need_sync(self, need_sync, need_sync_connection):
        if need_sync and need_sync_connection:
            self.create({
                'need_sync': need_sync.id,
                'need_sync_connection': need_sync_connection.id
            })

    @api.multi
    def map_need_sync(self, model, res_ids, need_sync_connection):

        if isinstance(res_ids, (long, int)):
            res_ids = [res_ids]

        need_sync_lines = self.search([('model', '=', model),
                                       ('res_id', 'in', res_ids),
                                       ('need_sync_connection', '=',
                                        need_sync_connection.id)])

        need_sync_line_res_ids = [x.res_id for x in need_sync_lines]
        create_sync_line_ids = list(set(res_ids) - set(need_sync_line_res_ids))
        if create_sync_line_ids:
            for res_id in create_sync_line_ids:
                need_sync = self.env['need.sync'].search([
                    ('model', '=', model),
                    ('res_id', '=', res_id),
                ])
                self._create_need_sync(need_sync, need_sync_connection)
        return True
class wx_menu(models.Model):

    _name = 'wx.menu'
    _description = u'微信菜单'
    #_order =
    #_inherit = []

    name = fields.Char('名称', )
    left_ids = fields.One2many('wx.menu.item.left', 'menu_id', '左')
    middle_ids = fields.One2many('wx.menu.item.middle', 'menu_id', '中')
    right_ids = fields.One2many('wx.menu.item.right', 'menu_id', '右')
    left = fields.Char('左菜单')
    left_action = fields.Reference(string='动作', selection=MENU_ACTION_OPTION)
    middle = fields.Char('中菜单')
    middle_action = fields.Reference(string='动作', selection=MENU_ACTION_OPTION)
    right = fields.Char('右菜单')
    right_action = fields.Reference(string='动作', selection=MENU_ACTION_OPTION)
    sequence = fields.Integer('Sequence', help="sequence")

    #_defaults = {
    #}
    _order = 'sequence'

    def _get_menu_action(self, name, action):
        if action and action._name == 'wx.action.act_url':
            m_dict = {'type': 'view', 'name': name, 'url': action.url}
        else:
            m_dict = {
                'type': 'click',
                'name': name,
                'key': action and action._name + ',' + str(action.id) or ',0'
            }
        return m_dict

    def _get_menu_item(self, name, action, childs):
        if childs:
            child_list = []
            for child in childs:
                child_dict = self._get_menu_action(child.name, child.action)
                child_list.append(child_dict)
            return {'name': name, 'sub_button': child_list}
        else:
            return self._get_menu_action(name, action)

    @api.one
    def do_active(self):
        buttons = []
        if self.left:
            buttons.append(
                self._get_menu_item(self.left, self.left_action,
                                    self.left_ids))
        if self.middle:
            buttons.append(
                self._get_menu_item(self.middle, self.middle_action,
                                    self.middle_ids))
        if self.right:
            buttons.append(
                self._get_menu_item(self.right, self.right_action,
                                    self.right_ids))
        menu_data = {'button': buttons}
        wxclient.create_menu(menu_data)
class ConnectorCheckpoint(models.Model):
    _name = 'connector.checkpoint'
    _description = 'Connector Checkpoint'

    _inherit = ['mail.thread', 'ir.needaction_mixin']

    @api.model
    def _reference_models(self):
        models = self.env['ir.model'].search([('state', '!=', 'manual')])
        return [(model.model, model.name) for model in models
                if not model.model.startswith('ir.')]

    @api.depends('model_id', 'record_id')
    def _compute_record(self):
        for item in self:
            if not (item.model_id and item.record_id):
                item.record = None
                continue
            item.record = item.model_id.model + ',' + str(item.record_id)

    @api.depends('model_id', 'record_id')
    def _compute_name(self):
        for item in self:
            if item.message:
                item.name = item.message
            else:
                model = self.env[item.model_id.model]
                item.name = model.browse(item.record_id).display_name

    @api.model
    def _search_record(self, operator, value):
        model_model = self.env['ir.model']
        sql = "SELECT DISTINCT model_id FROM connector_checkpoint"
        self.env.cr.execute(sql)
        model_ids = [row[0] for row in self.env.cr.fetchall()]
        models = model_model.browse(model_ids)

        ids = set()
        for model in models:
            model_id = model.id
            model_name = model.model
            model_obj = self.env[model_name]
            results = model_obj.name_search(name=value, operator=operator)
            res_ids = [res[0] for res in results]
            checks = self.search([('model_id', '=', model_id),
                                  ('record_id', 'in', res_ids)])
            ids.update(checks.ids)
        if not ids:
            return [('id', '=', '0')]
        return [('id', 'in', tuple(ids))]

    record = fields.Reference(
        compute='_compute_record',
        selection='_reference_models',
        help="The record to review.",
        readonly=True,
    )
    name = fields.Char(
        compute='_compute_name',
        search='_search_record',
        string='Record Name',
        help="Name of the record to review",
        readonly=True,
    )
    record_id = fields.Integer(string='Record ID',
                               required=False,
                               readonly=True)
    model_id = fields.Many2one(comodel_name='ir.model',
                               string='Model',
                               required=False,
                               readonly=True)
    backend_id = fields.Reference(
        string='Imported from',
        selection='_reference_models',
        readonly=True,
        required=True,
        help="The record has been imported from this backend",
        select=True,
    )
    state = fields.Selection(
        selection=[('need_review', 'Need Review'), ('reviewed', 'Reviewed')],
        string='Status',
        required=True,
        readonly=True,
        default='need_review',
    )
    message = fields.Char(
        string='Message',
        help="Review message",
        readonly=True,
        required=False,
    )

    _sql_constraints = [
        ('required_fields',
         "CHECK (record_id IS NOT NULL OR message IS NOT NULL)",
         _("Provide relation to a record or a message.")),
    ]

    @api.multi
    def reviewed(self):
        return self.write({'state': 'reviewed'})

    @api.multi
    def _subscribe_users(self):
        """ Subscribe all users having the 'Connector Manager' group """
        group = self.env.ref('connector.group_connector_manager')
        if not group:
            return
        users = self.env['res.users'].search([('groups_id', '=', group.id)])
        self.message_subscribe_users(user_ids=users.ids)

    @api.model
    def create(self, vals):
        record = super(ConnectorCheckpoint, self).create(vals)
        record._subscribe_users()
        if record.message:
            msg = record.message
        else:
            msg = _('A %s needs a review.') % record.model_id.name
        record.message_post(
            body=msg,
            subtype='mail.mt_comment',
        )
        return record

    @api.model
    def create_from_name(self,
                         model_name,
                         record_id,
                         backend_model_name,
                         backend_id,
                         message=''):
        model_model = self.env['ir.model']
        model = model_model.search([('model', '=', model_name)], limit=1)
        assert model, "The model %s does not exist" % model_name
        backend = backend_model_name + ',' + str(backend_id)
        return self.create({
            'model_id': model.id,
            'record_id': record_id,
            'backend_id': backend,
            'message': message
        })

    @api.model
    def create_from_message(self, backend_model_name, backend_id, message):
        backend = backend_model_name + ',' + str(backend_id)
        return self.create({'message': message, 'backend_id': backend})

    @api.model
    def _needaction_domain_get(self):
        """ Returns the domain to filter records that require an action
            :return: domain or False is no action
        """
        return [('state', '=', 'need_review')]
Exemple #8
0
class connector_checkpoint(models.Model):
    _name = 'connector.checkpoint'
    _description = 'Connector Checkpoint'

    _inherit = ['mail.thread', 'ir.needaction_mixin']

    def _get_models(self):
        """ All models are allowed as reference, anyway the
        fields.reference are readonly. """
        model_obj = self.env['ir.model'].browse()
        models = model_obj.read(fields=['model', 'name'])
        return [(m['model'], m['name']) for m in models]

    def _get_ref(self):
        res = {}
        for check in self.browse():
            res[check.id] = check.model_id.model + ',' + str(check.record_id)
        return res

    def _get_record_name(self):
        res = {}
        for check in self.browse():
            model_obj = self.env[check.model_id.model].browse(check.record_id)
            res[check.id] = model_obj.name_get()[0][1]
        return res

    def _search_record(self, args):
        ids = set()

        sql = "SELECT DISTINCT model_id FROM connector_checkpoint"
        rows = self.cr.execute(sql).fecthall()
        model_ids = [row[0] for row in rows]

        model_obj = self.evn['ir.model'].browse(model_ids)
        models = model_obj.read(fields=['model'])

        for criteria in args:
            __, operator, value = criteria
            for model in models:
                model_id = model['id']
                model_name = model['model']
                model_obj = self.registry[model_name]
                results = model_obj.name_search(name=value, operator=operator)
                res_ids = [res[0] for res in results]
                check_ids = self.search(self.cr,
                                        self.uid,
                                        args=[('model_id', '=', model_id),
                                              ('record_id', 'in', res_ids)],
                                        context=self.context)

                ids.update(check_ids)

        if not ids:
            return [('id', '=', '0')]

        return [('id', 'in', tuple(ids))]

    record = fields.Reference(compute='_get_ref',
                              type='reference',
                              string='Record',
                              selection=_get_models,
                              help="The record to review.",
                              size=128,
                              readonly=True)

    name = fields.Char(compute='_get_record_name',
                       fnct_search=_search_record,
                       type='char',
                       string='Record Name',
                       help="Name of the record to review",
                       readonly=True)

    record_id = fields.Integer(string='Record ID',
                               required=True,
                               readonly=True)

    model_id = fields.Many2one(comodel_name='ir.model',
                               string='Model',
                               required=True,
                               readonly=True)

    backend_id = fields.Reference(
        string='Imported from',
        selection=_get_models,
        size=128,
        readonly=True,
        required=True,
        help="The record has been imported from this backend",
        select=1)

    state = fields.Selection(selection=[('need_review', 'Need Review'),
                                        ('reviewed', 'Reviewed')],
                             string='Status',
                             required=True,
                             readonly=True)

    _defaults = {
        'state': 'need_review',
    }

    def reviewed(self):
        return self.write({'state': 'reviewed'})

    def _subscribe_users(self, ids):
        """ Subscribe all users having the 'Connector Manager' group """
        group_ref = self.env['ir.model.data'].get_object_reference(
            self.cr, self.uid, 'connector8', 'group_connector_manager')
        if not group_ref:
            return
        group_id = group_ref[1]

        user_ids = self.registry['res.users'].search(
            self.cr,
            self.uid, [('groups_id', '=', group_id)],
            context=self.context)

        self.message_subscribe_users(self.cr,
                                     self.uid,
                                     ids,
                                     user_ids=user_ids,
                                     context=self.context)

    def create(self, vals):
        obj_id = super(connector_checkpoint, self).create(vals)
        self._subscribe_users([obj_id])
        cp = self.browse(obj_id)
        msg = _('A %s needs a review.') % cp.model_id.name
        self.message_post(self.cr,
                          self.uid,
                          obj_id,
                          body=msg,
                          subtype='mail.mt_comment',
                          context=self.context)

        return obj_id

    def create_from_name(self,
                         cr,
                         uid,
                         model_name,
                         record_id,
                         backend_model_name,
                         backend_id,
                         context=None):
        model_obj = self.registry['ir.model']
        model_ids = model_obj.search(cr,
                                     uid, [('model', '=', model_name)],
                                     context=context)

        assert model_ids, "The model %s does not exist" % model_name
        backend = backend_model_name + ',' + str(backend_id)
        return self.create({
            'model_id': model_ids[0],
            'record_id': record_id,
            'backend_id': backend
        })

    def _needaction_domain_get(self, cr, uid, context=None):
        """ Returns the domain to filter records that require an action
            :return: domain or False is no action
        """
        return [('state', '=', 'need_review')]
Exemple #9
0
class automation_task(models.Model):
    _name = "automation.task"
    _description = "Automation Task"
    _order = "id asc"

    name = fields.Char("Name",
                       required=True,
                       readonly=True,
                       states={'draft': [('readonly', False)]})

    state_change = fields.Datetime("State Change",
                                   default=lambda self: util.currentDateTime(),
                                   required=True,
                                   readonly=True,
                                   copy=False)
    state = fields.Selection([("draft", "Draft"), ("queued", "Queued"),
                              ("run", "Running"), ("cancel", "Canceled"),
                              ("failed", "Failed"), ("done", "Done")],
                             required=True,
                             index=True,
                             readonly=True,
                             default="draft",
                             copy=False)

    progress = fields.Float("Progress", readonly=True, compute="_progress")
    error = fields.Text("Error", readonly=True, copy=False)
    owner_id = fields.Many2one("res.users",
                               "Owner",
                               required=True,
                               default=lambda self: self._uid,
                               index=True,
                               readonly=True)
    res_model = fields.Char("Resource Model", index=True, readonly=True)
    res_id = fields.Integer("Resource ID", index=True, readonly=True)
    res_ref = fields.Reference(_list_all_models,
                               string="Resource",
                               compute="_res_ref",
                               readonly=True)
    cron_id = fields.Many2one("ir.cron",
                              "Scheduled Job",
                              index=True,
                              ondelete="set null",
                              copy=False,
                              readonly=True)
    total_logs = fields.Integer("Total Logs", compute="_total_logs")
    total_stages = fields.Integer("Total Stages", compute="_total_stages")
    total_warnings = fields.Integer("Total Warnings",
                                    compute="_total_warnings")

    task_id = fields.Many2one("automation.task", "Task", compute="_task_id")
    after_once_task_id = fields.Many2one(
        "automation.task",
        "Task After (Once)",
        help=
        "Start this task after that task has finished successfully only once",
        readonly=True,
        ondelete="restrict")

    @api.one
    def _task_id(self):
        self.task_id = self

    @api.multi
    def _progress(self):
        res = dict.fromkeys(self.ids, 0.0)
        cr = self._cr

        # search stages
        cr.execute(
            "SELECT id FROM automation_task_stage WHERE task_id IN %s AND parent_id IS NULL",
            (tuple(self.ids), ))

        # get progress
        stage_ids = [r[0] for r in cr.fetchall()]
        for stage in self.env["automation.task.stage"].browse(stage_ids):
            res[stage.task_id.id] = stage.complete_progress

        # assign
        for r in self:
            r.progress = res[r.id]

    @api.one
    def _res_ref(self):
        if self.res_model and self.res_id:
            res = self.env[self.res_model].search_count([("id", "=",
                                                          self.res_id)])
            if res:
                self.res_ref = "%s,%s" % (self.res_model, self.res_id)
            else:
                self.res_ref = None
        else:
            self.res_ref = None

    @api.multi
    def _total_logs(self):
        res = dict.fromkeys(self.ids, 0)
        cr = self._cr
        cr.execute(
            "SELECT task_id, COUNT(*) FROM automation_task_log WHERE task_id IN %s GROUP BY 1",
            (tuple(self.ids), ))
        for task_id, log_count in cr.fetchall():
            res[task_id] = log_count
        for r in self:
            r.total_logs = res[r.id]

    @api.multi
    def _total_warnings(self):
        res = dict.fromkeys(self.ids, 0)
        cr = self._cr
        cr.execute(
            "SELECT task_id, COUNT(*) FROM automation_task_log WHERE pri IN ('a','e','w','x') AND task_id IN %s GROUP BY 1",
            (tuple(self.ids), ))
        for task_id, log_count in cr.fetchall():
            res[task_id] = log_count
        for r in self:
            r.total_warnings = res[r.id]

    @api.multi
    def _total_stages(self):
        res = dict.fromkeys(self.ids, 0)
        cr = self._cr
        cr.execute(
            "SELECT task_id, COUNT(*) FROM automation_task_stage WHERE task_id IN %s GROUP BY 1",
            (tuple(self.ids), ))
        for task_id, stage_count in cr.fetchall():
            res[task_id] = stage_count
        for r in self:
            r.total_stages = res[r.id]

    @api.one
    def _run(self, taskc):
        """" Test Task """
        for stage in range(1, 10):
            taskc.stage("Stage %s" % stage)

            for proc in range(1, 100, 10):
                taskc.log("Processing %s" % stage)
                taskc.progress("Processing %s" % stage, proc)
                time.sleep(1)

            taskc.done()

    @api.multi
    def _stage_count(self):
        self.ensure_one()
        return 10

    def _check_execution_rights(self):
        # check rights
        if self.owner_id.id != self._uid and not self.user_has_groups(
                "automation.group_automation_manager,base.group_system"):
            raise Warning(
                _("Not allowed to start task. You be the owner or an automation manager"
                  ))

    @api.multi
    def action_cancel(self):
        for task in self:
            # check rights
            task._check_execution_rights()
            if task.state == "queued":
                task.state = "cancel"
        return True

    @api.multi
    def action_refresh(self):
        return True

    @api.multi
    def action_reset(self):
        return True

    @api.multi
    def _get_cron_values(self):
        self.ensure_one()
        # new cron entry
        return {
            "name": "Task: %s" % self.name,
            "user_id": SUPERUSER_ID,
            "interval_type": "minutes",
            "interval_number": 1,
            "nextcall": util.currentDateTime(),
            "numbercall": 1,
            "model": self._name,
            "function": "_process_task",
            "args": "(%s,)" % self.id,
            "active": True,
            "priority": 1000 + self.id,
            "task_id": self.id
        }

    @api.multi
    def action_queue(self):

        for task in self:
            # check rights
            task._check_execution_rights()
            if task.state in ("draft", "cancel", "failed", "done"):
                # sudo task
                sudo_task = task.sudo()

                # add cron entry
                sudo_cron = sudo_task.cron_id
                if not sudo_cron:
                    sudo_cron = self.env["ir.cron"].sudo().create(
                        sudo_task._get_cron_values())
                else:
                    sudo_cron.write(sudo_task._get_cron_values())

                # set stages inactive
                self._cr.execute(
                    "DELETE FROM automation_task_stage WHERE task_id=%s",
                    (sudo_task.id, ))

                # set queued
                sudo_task.state = "queued"
                sudo_task.error = None
                sudo_task.cron_id = sudo_cron

                # create secret
                sudo_secret = self.env["automation.task.secret"].sudo()
                if not sudo_secret.search([("task_id", "=", sudo_task.id)]):
                    sudo_secret.create({"task_id": sudo_task.id})

        return True

    @api.model
    def _cleanup_tasks(self):
        # clean up cron tasks
        self._cr.execute(
            "DELETE FROM ir_cron WHERE task_id IS NOT NULL AND NOT active")
        return True

    @api.model
    def _process_task(self, task_id):
        task = self.browse(task_id)
        if task and task.state == "queued":
            try:
                # get options
                if task.res_model and task.res_id:
                    model_obj = self.env[task.res_model]
                    resource = model_obj.browse(task.res_id)
                else:
                    resource = task

                # options

                options = {"stages": 1, "resource": resource}

                # get custom options

                if hasattr(resource, "_run_options"):
                    res_options = getattr(resource, "_run_options")
                    if callable(res_options):
                        res_options = resource._run_options()
                    options.update(res_options)

                stage_count = options["stages"]

                # check if it is a singleton task
                # if already another task run, requeue
                # don't process this task
                if options.get("singleton"):
                    # cleanup
                    self._cr.execute(
                        "DELETE FROM ir_cron WHERE task_id=%s AND id!=%s AND NOT active",
                        (task.id, task.cron_id.id))
                    # check concurrent
                    self._cr.execute(
                        "SELECT MIN(id) FROM automation_task WHERE res_model=%s AND state IN ('queued','run')",
                        (resource._model._name, ))
                    active_task_id = self._cr.fetchone()[0]
                    if active_task_id and active_task_id < task_id:
                        # requeue
                        task.cron_id = self.env["ir.cron"].create(
                            task._get_cron_values())
                        return True

                task_after_once = task.after_once_task_id

                # change task state
                # and commit
                task.write({
                    "state_change": util.currentDateTime(),
                    "state": "run",
                    "error": None
                })
                # commit after start
                self._cr.commit()

                # run task
                taskc = TaskStatus(task, stage_count)
                resource._run(taskc)

                # check fail on errors
                if options.get("fail_on_errors"):
                    if taskc.errors:
                        raise Warning("Task finished with errors")

                # close
                taskc.close()

                # update status
                task.write({
                    "state_change": util.currentDateTime(),
                    "state": "done",
                    "error": None,
                    "after_once_task_id": None
                })

                # commit after finish
                self._cr.commit()

                # queue task after
                if task_after_once:
                    task_after_ref = task_after_once.res_ref
                    if task_after_ref:
                        task_after_ref.action_queue()

            except Exception as e:
                # rollback on error
                self._cr.rollback()
                _logger.exception("Task execution failed")

                error = str(e)
                if not error and hasattr(e, "message"):
                    error = e.message

                if not error:
                    error = "Unexpected error, see logs"

                # write error
                task.write({
                    "state_change": util.currentDateTime(),
                    "state": "failed",
                    "error": error
                })
                self._cr.commit()

        return True
Exemple #10
0
class BudgetBreakdownLine(ChartField, models.Model):
    _name = 'budget.breakdown.line'
    _description = 'Budget Breakdown Lines'

    breakdown_id = fields.Many2one(
        'budget.breakdown',
        string='Budget Breakdown',
        index=True,
        ondelete='cascade',
    )
    chart_view = fields.Selection(
        CHART_VIEW_LIST,
        related='breakdown_id.chart_view',
        string='Budget View',
        store=True,
        readonly=True,
    )
    # References
    budget_plan_id = fields.Reference(
        [
            ('budget.plan.unit', 'Budget Plan - Unit Based'),
            ('budget.plan.invest.asset', 'Budget Plan - Investment Asset'),
        ],
        string='Budget Plan',
        readonly=True,
        ondelete='set null',
    )
    budget_id = fields.Many2one('account.budget',
                                string='Budget Control',
                                readonly=True,
                                ondelete='set null')
    budget_state = fields.Selection(
        [('draft', 'Draft'), ('done', 'Controlled')],
        related='budget_id.state',
        string='Budget Status',
        store=True,
        readnly=True,
    )
    # --
    past_consumed = fields.Float(
        string='Consumed',
        compute='_compute_amount',
        store=True,
        readonly=True,
    )
    future_plan = fields.Float(
        string='Future',
        compute='_compute_amount',
        store=True,
        readonly=True,
    )
    rolling = fields.Float(
        string='Rolling',
        compute='_compute_amount',
        store=True,
        readonly=True,
    )
    released_amount = fields.Float(
        string='Released',
        compute='_compute_amount',
        store=True,
        readonly=True,
    )
    planned_amount = fields.Float(
        string='Planned Amount',
        compute='_compute_amount',
        store=True,
        readonly=True,
    )
    latest_policy_amount = fields.Float(
        string='Latest Policy Amount',
        compute='_compute_amount',
        store=True,
        readonly=True,
    )
    policy_amount = fields.Float(string='Policy Amount', )

    @api.model
    def _get_planned_expense_hook(self, breakdown, budget_plan):
        planned_amount = budget_plan and budget_plan.planned_expense or 0.0
        return planned_amount

    @api.multi
    @api.depends('budget_plan_id', 'budget_id')
    def _compute_amount(self):
        for line in self:
            # From Budget Plan
            budget_plan = line.budget_plan_id
            line.planned_amount = \
                self._get_planned_expense_hook(line.breakdown_id, budget_plan)
            line.latest_policy_amount = line.budget_id and \
                line.budget_id.policy_amount or 0.0
            # From Budget Control
            line.future_plan = line.budget_id.future_plan
            line.past_consumed = line.budget_id.past_consumed
            line.rolling = line.budget_id.rolling
            line.released_amount = line.budget_id.released_amount

    @api.model
    def _change_amount_content(self, breakdown, new_amount):
        BREAKDOWN_LEVEL = {
            'unit_base': 'section_id',  # only 2 types
            'invest_asset': 'org_id',
            'personnel': False,
        }
        title = _('Policy amount change(s)')
        message = '<h3>%s</h3><ul>' % title
        for rec in self:
            field = BREAKDOWN_LEVEL[breakdown.chart_view]
            code = 'NSTDA'
            if field:
                obj = rec[field]
                code = obj.code or obj.name_short or obj.name
            message += _('<li><b>%s</b>: %s → %s</li>') % (
                code,
                '{:,.2f}'.format(rec.policy_amount),
                '{:,.2f}'.format(new_amount),
            )
            message += '</ul>'
        return message

    @api.multi
    def write(self, vals):
        # Grouping by Policy
        if 'policy_amount' in vals:
            for breakdown in self.mapped('breakdown_id'):
                lines = self.filtered(lambda l: l.breakdown_id == breakdown)
                new_amount = vals.get('policy_amount')
                message = lines._change_amount_content(breakdown, new_amount)
            if message:
                breakdown.message_post(body=message)
        return super(BudgetBreakdownLine, self).write(vals)
Exemple #11
0
class NeedSyncConnectionRecordException(models.Model):
    _name = "need.sync.connection.record.exception"
    _description = "Need Sync Connection Records Not synced"

    def _select_models(self):
        return self.env['need.sync.model']._select_models()

    name = fields.Char(string="Sync", compute="_get_name", store=True)

    need_sync_connection = fields.Many2one(comodel_name="need.sync.connection",
                                           string="Connection",
                                           index=True)

    model = fields.Selection(selection=_select_models,
                             string="Model",
                             required=True,
                             index=True)
    res_id = fields.Integer(string='Record ID',
                            index=True,
                            required=True,
                            help="ID of the target record in the database")
    record = fields.Reference(selection=_select_models,
                              string="Record",
                              compute="_get_record",
                              store=True)

    @api.one
    @api.depends('res_id', 'model')
    def _get_record(self):
        if self.res_id and self.model:
            self.record = self.env[str(self.model)].browse(self.res_id)

    @api.one
    @api.depends('res_id', 'model')
    def _get_name(self):
        object = self.env[self.model].browse(self.res_id)
        if object and 'name' in object._fields:
            object_name = object.name
        else:
            object_name = "No object name defined"
        self.name = '%s' % (object_name)

    def unlink(self):
        """
        Recreate related need sync line
        :return: 
        """
        res_ids = []
        for rec in self:
            res_ids.append(rec.res_id)
        need_sync_lines = self.get_need_sync_lines(
            res_ids, self[0].model, self[0].need_sync_connection.id)
        if need_sync_lines:
            need_sync_lines.write({'published': True})
        return super(NeedSyncConnectionRecordException, self).unlink()

    def create(self, values):
        """
        Remove related need sync lines
        :return: 
        """
        if values.get('res_id') and values.get('model') and values.get(
                'need_sync_connection'):
            need_sync_lines = self.get_need_sync_lines(
                values.get('res_id'), values.get('model'),
                values.get('need_sync_connection'))
            if need_sync_lines:
                need_sync_lines.write({'published': False})
        return super(NeedSyncConnectionRecordException, self).create(values)

    @api.model
    def get_need_sync_lines(self, res_ids, model, connection_id):
        if isinstance(res_ids, (long, int)):
            res_ids = [res_ids]

        need_sync_lines = self.env['need.sync.line'].search([
            ('res_id', 'in', res_ids), ('model', '=', model),
            ('need_sync_connection', '=', connection_id)
        ])
        return need_sync_lines
Exemple #12
0
class AccountAnalyticLine(ChartFieldAction, models.Model):
    _inherit = 'account.analytic.line'

    # ChartfieldAction changed account_id = account.account, must change back
    account_id = fields.Many2one('account.analytic.account')
    # Following fields is not mature yet, so we need it to be store=False
    docline_seq = fields.Integer(
        string='Docline Seq',
        compute='_compute_docline_seq',
    )
    document_date = fields.Date(
        string='Document Date',
        compute='_compute_document_date',
    )
    request_emp_id = fields.Many2one(
        'hr.employee',
        string='Requester',
        compute='_compute_document_employee_partner',
    )
    prepare_emp_id = fields.Many2one(
        'hr.employee',
        string='Requester',
        compute='_compute_document_employee_partner',
    )
    approve_emp_id = fields.Many2one(
        'hr.employee',
        string='Requester',
        compute='_compute_document_employee_partner',
    )
    partner_id = fields.Many2one(
        'res.partner',
        string='Partner',
        compute='_compute_document_employee_partner',
    )
    chartfield_id = fields.Reference(
        [
            ('res.section', 'Section'),
            ('res.project', 'Project'),
            ('res.invest.asset', 'Invest Asset'),
            ('res.invest.construction.phase', 'Construction Phase'),
            ('res.personnel.costcenter', 'Personnel'),
        ],
        string='Budget',
        compute='_compute_chartfield',
    )

    @api.multi
    def _compute_docline_seq(self):
        """ Only for PR/PO/SO/EX that we can do at this moment """
        for rec in self:
            if rec.doctype not in ('sale_order', 'purchase_order',
                                   'purchase_request', 'employee_expense'):
                continue
            rec.docline_seq = \
                rec.purchase_line_id.docline_seq or \
                rec.sale_line_id.docline_seq or \
                rec.expense_line_id.docline_seq or \
                rec.purchase_request_line_id.docline_seq
        return True

    @api.multi
    def _compute_document_date(self):
        for rec in self:
            res_model = rec.document_id and rec.document_id._name or False
            if res_model in ['hr.expense.expense']:
                rec.document_date = rec.document_id.create_date
            if res_model in ['sale.order', 'purchase.order']:
                rec.document_date = rec.document_id.date_order
            if res_model in ['purchase.request']:
                create_date = datetime.strptime(rec.document_id.create_date,
                                                '%Y-%m-%d %H:%M:%S')
                rec.document_date = create_date.strftime('%Y-%m-%d')
            if res_model in ['account.invoice']:
                rec.document_date = rec.document_id.date_document
            if res_model in ['stock.picking']:
                rec.document_date = rec.document_id.date
        return True

    @api.multi
    def _compute_document_employee_partner(self):
        """ Only for PR/EX that will have request/prepare/approver user """
        for rec in self:
            # Employee
            if rec.doctype == 'employee_expense':
                rec.request_emp_id = rec.document_id.employee_id
                rec.prepare_emp_id = \
                    rec.document_id.user_id.partner_id.employee_id
                rec.approve_emp_id = \
                    rec.document_id.approver_id.partner_id.employee_id
            if rec.doctype == 'purchase_request':
                rec.request_emp_id = \
                    rec.document_id.requested_by.partner_id.employee_id
                rec.prepare_emp_id = \
                    rec.document_id.responsible_uid.partner_id.employee_id
                rec.approve_emp_id = \
                    rec.document_id.assigned_to.partner_id.employee_id
            # Partner
            res_model = rec.document_id and rec.document_id._name or False
            if res_model in [
                    'hr.expense.expense', 'sale.order', 'purchase.order',
                    'account.invoice', 'stock.picking'
            ]:
                rec.partner_id = rec.document_id.partner_id
        return True

    @api.multi
    def _compute_chartfield(self):
        for rec in self:
            model, res_id = False, False
            if rec.section_id:
                model, res_id = ('res.section', rec.section_id.id)
            if rec.project_id:
                model, res_id = ('res.project', rec.project_id.id)
            if rec.invest_asset_id:
                model, res_id = ('res.invest.asset', rec.invest_asset_id.id)
            if rec.invest_construction_phase_id:
                model, res_id = ('res.invest.construction.phase',
                                 rec.invest_construction_phase_id.id)
            if rec.personnel_costcenter_id:
                model, res_id = ('res.personnel.costcenter',
                                 rec.personnel_costcenter_id.id)
            rec.chartfield_id = '%s,%s' % (model, res_id)
        return True
Exemple #13
0
class AccountMove(models.Model):
    _inherit = 'account.move'

    document = fields.Char(
        string='Document',
        compute='_compute_document',
        store=True,
        readonly=True,
    )
    document_id = fields.Reference(
        REFERENCE_SELECT,
        string='Document',
        compute='_compute_document',
        store=True,
        readonly=True,
    )
    doctype = fields.Selection(
        DOCTYPE_SELECT,
        string='Doctype',
        compute='_compute_document',
        store=True,
        index=True,
        help="Use selection as refer_type in res_doctype",
    )
    date_value = fields.Date(
        string='Value Date',
        compute='_compute_document',
        store=True,
        help="If origin document have value date. Otherwise, use move date",
    )
    invoice_ids = fields.One2many(
        'account.invoice',
        'move_id',
        string='Invoice',
        readonly=True,
    )
    invoice_cancel_ids = fields.One2many(
        'account.invoice',
        'cancel_move_id',
        string='Invoice Cancel',
        readonly=True,
    )
    invoice_clear_prepaid_ids = fields.One2many(
        'account.invoice',
        'clear_prepaid_move_id',
        string='Invoice Clear Prepaid',
        readonly=True,
    )
    voucher_ids = fields.One2many(
        'account.voucher',
        'move_id',
        string='Payment',
        readonly=True,
    )
    voucher_cancel_ids = fields.One2many(
        'account.voucher',
        'cancel_move_id',
        string='Payment Cancel',
        readonly=True,
    )
    voucher_recognize_vat_ids = fields.One2many(
        'account.voucher',
        'recognize_vat_move_id',
        string='Payment Recognize VAT',
        readonly=True,
    )
    bank_receipt_ids = fields.One2many(
        'account.bank.receipt',
        'move_id',
        string='Bank Receipt',
        readonly=True,
    )
    bank_receipt_cancel_ids = fields.One2many(
        'account.bank.receipt',
        'cancel_move_id',
        string='Bank Receipt Cancel',
        readonly=True,
    )
    salary_expense_ids = fields.One2many(
        'hr.salary.expense',
        'move_id',
        string='Salary Expense',
        readonly=True,
    )
    salary_expense_cancel_ids = fields.One2many(
        'hr.salary.expense',
        'cancel_move_id',
        string='Salary Expense Cancel',
        readonly=True,
    )
    expense_rev_ic_ids = fields.One2many(
        'hr.expense.expense',
        'rev_ic_move_id',
        string='IC Revenue',
        readonly=True,
    )
    expense_exp_ic_ids = fields.One2many(
        'hr.expense.expense',
        'exp_ic_move_id',
        string='IC Expense',
        readonly=True,
    )
    account_interface_ids = fields.One2many(
        'interface.account.entry',
        'move_id',
        string='Account Interface',
        readonly=True,
    )

    @api.multi
    @api.depends('invoice_ids.internal_number',
                 'invoice_cancel_ids.internal_number',
                 'invoice_clear_prepaid_ids.internal_number',
                 'voucher_ids.number',
                 'voucher_cancel_ids.number',
                 'voucher_recognize_vat_ids.number',
                 'bank_receipt_ids.name',
                 'bank_receipt_cancel_ids.name',
                 'salary_expense_ids.name',
                 'salary_expense_cancel_ids.name',
                 'expense_rev_ic_ids.number',
                 'expense_exp_ic_ids.number',
                 'account_interface_ids.number',
                 'ref',  # check for stock.picking case, as it has no move_id
                 )
    def _compute_document(self):
        for rec in self:
            document = False
            # Invoice
            if rec.invoice_ids:
                document = rec.invoice_ids[0]
            elif rec.invoice_cancel_ids:
                document = rec.invoice_cancel_ids[0]
            elif rec.invoice_clear_prepaid_ids:
                document = rec.invoice_clear_prepaid_ids[0]
            # Voucher
            elif rec.voucher_ids:
                document = rec.voucher_ids[0]
            elif rec.voucher_cancel_ids:
                document = rec.voucher_cancel_ids[0]
            elif rec.voucher_recognize_vat_ids:
                document = rec.voucher_recognize_vat_ids[0]
            # Bank Receipt
            elif rec.bank_receipt_ids:
                document = rec.bank_receipt_ids[0]
            elif rec.bank_receipt_cancel_ids:
                document = rec.bank_receipt_cancel_ids[0]
            # Salary Expense
            elif rec.salary_expense_ids:
                document = rec.salary_expense_ids[0]
            elif rec.salary_expense_cancel_ids:
                document = rec.salary_expense_cancel_ids[0]
            # Expense IC
            elif rec.expense_rev_ic_ids:
                document = rec.expense_rev_ic_ids[0]
            elif rec.expense_exp_ic_ids:
                document = rec.expense_exp_ic_ids[0]
            # Account Interface
            elif rec.account_interface_ids:
                document = rec.account_interface_ids[0]
            elif rec.ref:  # Last chance for picking, as it not have move_id
                Picking = self.env['stock.picking']
                picking = Picking.search([('name', '=', rec.ref)])
                document = picking and picking[0] or False

            # Assign reference
            if document:
                rec.document_id = '%s,%s' % (document._name, document.id)
                if document._name in ('stock.picking', 'account.bank.receipt'):
                    rec.document = document.name
                elif document._name == 'account.invoice':
                    rec.document = document.internal_number
                else:
                    rec.document = document.number
                rec.doctype = self._get_doctype(document._name, document)
                if 'date_value' in document._fields:
                    rec.date_value = document.date_value
            else:
                rec.doctype = 'adjustment'  # <-- Not related to any doc
            if not rec.date_value:
                rec.date_value = rec.date  # No Value Date, same as date

    @api.model
    def _get_doctype(self, model, document):
        if model == 'account.invoice':
            return INVOICE_DOCTYPE[document.journal_id.type]
        if model == 'account.voucher':
            return VOUCHER_DOCTYPE[document.type]
        if model == 'account.bank.receipt':
            return 'bank_receipt'
        if model == 'hr.expense.expense':
            return 'employee_expense'
        if model == 'hr.salary.expense':
            return 'salary_expense'
        if model == 'stock.picking':
            return PICKING_DOCTYPE[document.picking_type_id.code]
        if model == 'interface.account.entry':
            return 'interface_account'
class ExchangeProvider(models.Model):
    """ Base Model for Transaction engines or external DB's
    Exchange Provider Model. Each specific Exchange Provider can extend the model by adding
    its own fields, using the Exchange Provider_name as a prefix for the new fields.
    Using the required_if_provider='<name>' attribute on fields it is possible
    to have required fields that depend on a specific Exchange Provider.

    Methods that should be added in an Exchange Provider-specific implementation:

     - ``<name>_form_generate_values(self, values)
        reference, amount, currency,
       partner_id=False, partner_values=None, tx_custom_values=None, context=None)``:
       method that generates the values used to render the form button template.
     - ``<name>_get_form_action_url(self,):``: method
       that returns the url of the button form. It is used
       to post some data to the Exchange Provider.
     - ``<name>_compute_fees(self, amount, currency_id, country_id)``:
       computed the fees of the Exchange Provider, using generic fields
       defined on the Exchange Provider model (see fields definition).

    Each Exchange Provider should also define controllers to handle communication between
    Odoo and the Exchange Provider. It generally consists in return urls given to the
    payment form and that the Exchange Provider uses to send the customer back after the
    transaction, with transaction details given as a POST request.
    """

    _name = 'exchange.provider'
    _description = 'Exchange Provider'
    _order = 'sequence'

    @api.model  # collects selection items from provider_xxx modules
    def _get_providers(self):
        return []

    # indirection to ease inheritance
    _provider_selection = lambda self, *args, **kwargs: self._get_providers(
        *args, **kwargs)

    @api.model
    def _compute_external(self):
        if self.environment == "internal":
            return False
        else:
            return True

    name = fields.Char('Name', size=64, required=True)
    sequence = fields.Integer('Sequence', help="Determine the display order")
    provider = fields.Selection(_provider_selection,
                                string='Provider',
                                required=True)
    # TODO provider_model = fields.Many2one('exchange.provider.model', string='Provider Model', required=False)
    ref_provider = fields.Reference(
        [('exchange.account.provider.internal', 'Internal'),
         ('exchange.account.provider.dumy', 'Dumy')], 'Accounts PR')
    # balance = fields.Float(
    #    'Balance Pr', related='ref_provider.balance', readonly=True)
    account_conf_ids = fields.One2many('exchange.config.accounts',
                                       'exchange_provider_id',
                                       string='Account Templates',
                                       required=False)
    connection = fields.Selection(
        [('none', 'No connection'), ('single', 'Singlepoint'),
         ('multiuser', 'Multiple Users'), ('multisys', 'Multiple Accounts')],
        string='Connection Type',
        required=True,
        help="Defines how the provider connected to the Exchange framework."
        "- Single-point connection. Eg. a Clearing account"
        "- Multiple Users connection -> Eg. normal usecase with ext. transaction engine"
        "- Multiple Accounts connection -> One Admin can manage all account")
    singlepoint = fields.Boolean(
        string='Singlepoint Provider',
        readonly=True,  # TODO
        help="if checked the provider is serving only a single"
        " point connection. Eg. a Clearing account")
    environment = fields.Selection([('internal', 'Internal'),
                                    ('test', 'External Test'),
                                    ('prod', 'External Production')],
                                   string='Environment',
                                   required=True)
    is_external = fields.Boolean(compute='_compute_external',
                                 string='External Account')
    test_url = fields.Char('Test URL', required=False)
    test_login = fields.Char('Test Login', size=64, required=False)
    test_secret = fields.Char('Test secret', size=128, required=False)
    asset_class = fields.Char('Asset Class', size=64, required=False)
    active = fields.Boolean('Active?', default=False)
    partner_id = fields.Many2one('res.partner', string='Related Partner')
    currency_ids = fields.One2many('exchange.provider.currency',
                                   'provider_id',
                                   readonly=True,
                                   string='Provided Currencies')
    currency_id = fields.Many2one(
        'exchange.provider.currency',
        'Currency',
        required=False,
        help="Currency used for this Provider Configuration"
        "(only by the module provided currencies are available!)")
    view_template_id = fields.Many2one('ir.ui.view',
                                       'Form Button Template',
                                       required=False)
    """
    registration_view_template_id = fields.Many2one('ir.ui.view', 'Form Template',
                                                     domain=[('type', '=', 'qweb')],
                                                     help="Template for method registration")
    """
    description = fields.Text('Description')
    image = fields.Binary(
        "Image",
        attachment=True,
        help=
        "This field holds the image used for this Exchange Provider, limited to 1024x1024px"
    )
    image_medium = fields.Binary("Medium-sized image",
                                 compute='_compute_images', inverse='_inverse_image_medium', store=True,
                                 attachment=True,
                                 help="Medium-sized image of this Exchange Provider. It is automatically " \
                                      "resized as a 128x128px image, with aspect ratio preserved. " \
                                      "Use this field in form views or some kanban views.")
    image_small = fields.Binary("Small-sized image",
                                compute='_compute_images', inverse='_inverse_image_small', store=True,
                                attachment=True,
                                help="Small-sized image of this Exchange Provider. It is automatically " \
                                     "resized as a 64x64px image, with aspect ratio preserved. " \
                                     "Use this field anywhere a small image is required.")
    pre_msg = fields.Html(
        'Help Message',
        translate=True,
        help='Message displayed to explain and help the payment process.')
    post_msg = fields.Html(
        'Thanks Message',
        help='Message displayed after having done the payment process.')
    pending_msg = fields.Html(
        'Pending Message',
        translate=True,
        help=
        'Message displayed, if order is in pending state after having done the payment process.'
    )
    done_msg = fields.Html(
        'Done Message',
        translate=True,
        help=
        'Message displayed, if order is done successfully after having done the payment process.'
    )
    cancel_msg = fields.Html(
        'Cancel Message',
        translate=True,
        help='Message displayed, if order is cancel during the payment process.'
    )
    error_msg = fields.Html(
        'Error Message',
        translate=True,
        help='Message displayed, if error is occur during the payment process.'
    )
    balance_test = fields.Float(
        'Balance',
        help='Balance of the account that is connected to the test credentials'
    )
    # Fields that are related from exchange.config.settings model
    exch_code = fields.Char('Exchange Code',
                            required=False,
                            size=7,
                            help="Unique Exchange Code (EC)"
                            "First part of the 20 digits Account Code CC BBBB"
                            "CC country code -> DE Germany"
                            "BBBB Exchange code")
    display_balance = fields.Boolean('Everyone can see balances?',
                                     default=True)
    journal_id = fields.Many2one('account.journal',
                                 'Community Journal',
                                 required=False)
    use_account_numbers = fields.Boolean(
        'Use of Account Numbering System',
        default=True,
        help=
        "Use of the 20 digits Account Numbering Code 'CC BBBB DDDDDDDD XXXX-KK'"
    )
    email_sysadmin = fields.Char('Sysadmin mail address')
    # Field that is related to exchange.config.settings model

    _sql_constraints = [('exch_code_name_unique', 'UNIQUE (exch_code, active)',
                         'Exchange code must be unique!')]

    @api.depends('image')
    def _compute_images(self):
        for rec in self:
            rec.image_medium = openerp.tools.image_resize_image_medium(
                rec.image)
            rec.image_small = openerp.tools.image_resize_image_small(rec.image)

    @api.one  # Action connection test via the provider models
    def act_provider_test(self):
        sub_function = "_act_provider_test_" + str(self.provider)
        call_test = getattr(self, sub_function)
        result = call_test()

    @api.one  # get provider_balance from the provider models
    def act_provider_get_balance(self):
        sub_function = "_get_provider_balance_" + str(self.provider)
        call_balance = getattr(self, sub_function)
        result = call_balance()
        self.balance_test = result
Exemple #15
0
class TodoTask(models.Model):
    _inherit = 'todo.task'

    # Relational fields
    stage_id = fields.Many2one('todo.task.stage', 'Stage')
    tag_ids = fields.Many2many(
        'todo.task.tag',
        'todo_task_tag_rel',
        'task_id',
        'tag_id',
        string='Tags',

        # Relational field attributes:
        auto_join=False,
        context="{}",
        domain="[]",
        ondelete='cascade',
    )
    # Dynamic Reference fields:
    refers_to = fields.Reference(
        # Set a selection list, such as:
        # [('res.user', 'User'), ('res.partner', 'Partner')],
        # Or use standard "Referencable Models":
        referencable_models,
        'Refers to',  # string= (title)
    )
    # Related fields:
    stage_state = fields.Selection(
        related='stage_id.state',
        string='Stage State',
        store=True,  # optional
    )

    # Calculated fields:
    stage_fold = fields.Boolean(
        string='Stage Folded?',
        compute='_compute_stage_fold',
        search='_search_stage_fold',
        inverse='_write_stage_fold',
        store=False,  # the default
    )

    @api.one
    @api.depends('stage_id.fold')
    def _compute_stage_fold(self):
        self.stage_fold = self.stage_id.fold

    def _search_stage_fold(self, operator, value):
        return [('stage_id.fold', operator, value)]

    def _write_stage_fold(self):
        self.stage_id.fold = self.stage_fold

    # Constraints
    _sql_constraints = [
        ('todo_task_name_unique', 'UNIQUE (name, user_id, active)',
         'Task title must be unique!')
    ]

    @api.one
    @api.constrains('name')
    def _check_name_size(self):
        if len(self.name) < 5:
            raise ValidationError('Title must have 5 chars!')

    @api.one
    def compute_user_todo_count(self):
        self.user_todo_count = self.search_count([('user_id', '=',
                                                   self.user_id.id)])

    user_todo_count = fields.Interger('User To-Do Count',
                                      compute='compute_user_todo_count')
    effort_estimate = fields.Integer('Effort Estimate')
Exemple #16
0
class TaxExemptionlView(models.Model):
    _name = 'tax.exemption.view'
    _auto = False

    id = fields.Integer(
        string='ID',
        readonly=True,
    )
    move_id = fields.Many2one(
        'account.move',
        string='Move',
        readonly=True,
    )
    taxbranch_id = fields.Many2one(
        'res.taxbranch',
        string='Tax Branch',
        readonly=True,
    )
    date_invoice = fields.Date(
        string='Posting Date',
        readonly=True,
    )
    number_preprint = fields.Char(
        string='Preprint Number',
        readonly=True,
    )
    partner_id = fields.Many2one(
        'res.partner',
        string='Partner',
        readonly=True,
    )
    amount_untaxed = fields.Float(
        string='Subtotal',
        readonly=True,
    )
    amount_tax = fields.Float(
        string='Tax',
        readonly=True,
    )
    source_document_id = fields.Reference(
        [('purchase.order', 'Purchase'),
         ('sale.order', 'Sales'),
         ('hr.expense.expense', 'HR Expense')],
        string='Source Document Ref.',
        readonly=True,
    )
    number = fields.Char(
        string='Document Number',
        readonly=True,
    )
    document_origin = fields.Char(
        string='Document Origin',
        readonly=True,
    )
    validate_user_id = fields.Many2one(
        'res.users',
        string='Validated By',
        readonly=True,
    )

    def _get_sql_view(self):
        sql_view = """
            SELECT ROW_NUMBER() OVER(ORDER BY invoice.move_id) AS id, *
            FROM
                ((SELECT move_id, taxbranch_id, date_invoice, number_preprint,
                         partner_id, amount_untaxed, amount_tax,
                         source_document_id, number, NULL AS document_origin,
                         validate_user_id
                  FROM account_invoice
                  WHERE type IN ('out_invoice', 'out_refund')
                    AND state NOT IN ('draft', 'cancel')
                    AND id NOT IN
                        (SELECT DISTINCT invoice_id FROM account_invoice_tax))
                 UNION ALL
                 (SELECT iae.move_id, iael.taxbranch_id,
                         iael.date AS date_invoice,
                         iae.preprint_number AS number_preprint,
                         iael.partner_id, SUM(iael.debit) AS amount_untaxed,
                         (SELECT ABS(SUM(credit) - SUM(debit))
                          FROM interface_account_entry_line
                          WHERE tax_id IS NOT NULL AND interface_id = iae.id
                          GROUP BY interface_id) AS amount_tax,
                         NULL AS source_document_id, iae.number,
                         iae.name AS document_origin, iae.validate_user_id
                  FROM interface_account_entry iae
                  LEFT JOIN interface_account_entry_line iael
                    ON iae.id = iael.interface_id
                  WHERE iae.type = 'invoice' AND iae.state = 'done' AND
                        iae.id NOT IN
                        (SELECT DISTINCT interface_id
                         FROM interface_account_entry_line
                         WHERE tax_id IS NOT NULL)
                  GROUP BY iae.id, iael.taxbranch_id, iael.date,
                           iael.partner_id)) invoice
        """
        return sql_view

    def init(self, cr):
        tools.drop_view_if_exists(cr, self._table)
        cr.execute("""CREATE OR REPLACE VIEW %s AS (%s)"""
                   % (self._table, self._get_sql_view()))
class BudgetCarryOverLineView(models.Model):
    _name = 'budget.carry.over.line.view'
    _auto = False
    _order = 'name'

    carry_over_id = fields.Many2one(
        'budget.carry.over',
        string='Carry Over',
        readonly=True,
    )
    budget_id = fields.Reference(
        [('res.section', 'Section'),
         ('res.project', 'Project'),
         ('res.invest.asset', 'Asset'),
         ('res.invest.construction.phase', 'Construction'),
         ('res.personnel.costcenter', 'Personnel')],
        string='Document Line',
        compute='_compute_budget_id',
        readonly=True,
    )
    doctype = fields.Selection(
        [('purchase_request', 'Purchase Request'),
         ('sale_order', 'Sales Order'),
         ('purchase_order', 'Purchase Order'),
         ('employee_expense', 'Expense'), ],
        string='Document Type',
        readonly=True,
    )
    name = fields.Char(
        string='Name',
        readonly=True,
    )
    description = fields.Char(
        string='Description',
        readonly=True,
    )
    chartfield_id = fields.Many2one(
        'chartfield.view',
        string='Budget',
        readonly=True,
    )
    chartfield_type = fields.Selection(
        [('sc:', 'Section'),
         ('pj:', 'Project'),
         ('cp:', 'Construction Phase'),
         ('ia:', 'Invest Asset'),
         ('pc:', 'Personnel'), ],
        string='Type',
        related='chartfield_id.type',
    )
    commit_amount = fields.Float(
        string='Commitment',
        readonly=True,
    )

    @api.multi
    def _compute_budget_id(self):
        for rec in self:
            rec.budget_id = '%s,%s' % (rec.chartfield_id.model,
                                       rec.chartfield_id.res_id)

    def _get_sql_view(self):
        sql_view = """
            SELECT id, doctype, carry_over_id,
                commit_amount, name, description, chartfield_id
            FROM budget_carry_over_line
        """
        return sql_view

    def init(self, cr):
        tools.drop_view_if_exists(cr, self._table)
        cr.execute("""CREATE or REPLACE VIEW %s as (%s)""" %
                   (self._table, self._get_sql_view(), ))
Exemple #18
0
class TestModel(models.Model):
    _name = 'test.model'

    _columns = {}  # deprecated columns
    _defaults = {}  # deprecated defaults
    length = fields.Integer()  # Deprecated length by js errors

    name = fields.Char(
        _(u"Näme"),  # Don't need translate
        help=u"My hëlp",
        required=False,
        compute='_compute_name',  # good compute method name
        search='_search_name',  # good search method name
        inverse='_inverse_name',  # good inverse method name
    )

    # Imported openerp.fields use Char (Upper case)
    other_field = fields.char(
        name=_("Other field"),
        copy=True,
        compute='my_method_compute',  # bad compute method name
        search='my_method_search',  # bad search method name
        inverse='my_method_inverse',  # bad inverse method name
    )
    compute_none = fields.Char(compute=None)

    other_field2 = fields.char(
        'Other Field2',
        copy=True,
    )

    # This is a inherit overwrite field then don't should show errors related
    # with creation of fields.
    def method_date(self):
        date = fields.Date.to_string(
            fields.Datetime.context_timestamp(self,
                                              timestamp=fields.Datetime.now())
        )
        return date

    my_ok_field = fields.Float(
        "My correctly named field",
        digits=(6, 6),  # OK: Valid field parameter
        index=True,  # OK: Valid field parameter
        help="My ok field",
    )

    my_ko_field = fields.Float(
        digits_compute=lambda cr: (6, 6),  # Deprecated field parameter
        select=True,  # Deprecated field parameter
        help="My ko field",
        string="My Ko Field",  # String parameter equal to name of variable
    )

    """The name of the variable is equal to the string parameter
    Tested all fields.*"""

    boolean_variable_1 = fields.Boolean(string='Boolean Variable 1',
                                        help="Help")
    boolean_variable_2 = fields.Boolean("Boolean Variable 2", help="Help")

    char_variable_1 = fields.Char(string='Char Variable 1', help="Help")
    char_variable_2 = fields.Char("Char Variable 2", help="Help")

    text_variable_1 = fields.Text(string='Text Variable 1', help="Help")
    text_variable_2 = fields.Text("Text Variable 2", help="Help")

    html_variable_1 = fields.Html(string='Html Variable 1', help="Help")
    html_variable_2 = fields.Html("Html Variable 2", help="Help")

    integer_variable_1 = fields.Integer(string='Integer Variable 1',
                                        help="Help")
    integer_variable_2 = fields.Integer("Integer Variable 2", help="Help")

    float_variable_1 = fields.Float(string='Float Variable 1', help="Help")
    float_variable_2 = fields.Float("Float Variable 2", help="Help")

    date_variable_1 = fields.Date(string='Date Variable 1', help="Help")
    date_variable_2 = fields.Date("Date Variable 2", help="Help")

    date_time_variable_1 = fields.DateTime(string='Date Time Variable 1',
                                           help="Help")
    date_time_variable_2 = fields.DateTime("Date Time Variable 2", help="Help")

    binary_variable_1 = fields.Binary(string='Binary Variable 1', help="Help")
    binary_variable_2 = fields.Binary("Binary Variable 2", help="Help")

    selection_variable_1 = fields.Selection(selection=[('a', 'A')],
                                            string='Selection Variable 1',
                                            help="Help")
    selection_variable_2 = fields.Selection([('a', 'A')],
                                            "Selection Variable 2",
                                            help="Help")

    reference_variable_1 = fields.Reference(selection=[('res.user', 'User')],
                                            string="Reference Variable 1",
                                            help="Help")
    reference_variable_2 = fields.Reference([('res.user', 'User')],
                                            "Reference Variable 2",
                                            help="Help")

    many_2_one_variable_1 = fields.Many2one(comodel_name='res.users',
                                            string='Many 2 One Variable 1',
                                            help="Help")
    many_2_one_variable_2 = fields.Many2one('res.users',
                                            "Many 2 One Variable 2",
                                            help="Help")

    one_2_many_variable_1 = fields.One2many(comodel_name='res.users',
                                            inverse_name='rel_id',
                                            string='One 2 Many Variable 1',
                                            help="Help")
    one_2_many_variable_2 = fields.One2many('res.users',
                                            'rel_id',
                                            "One 2 Many Variable 2",
                                            help="Help")

    many_2_many_variable_1 = fields.Many2many(comodel_name='res.users',
                                              relation='table_name',
                                              column1='col_name',
                                              column2='other_col_name',
                                              string='Many 2 Many Variable 1',
                                              help="Help")
    many_2_many_variable_2 = fields.Many2many('res.users',
                                              'table_name',
                                              'col_name',
                                              'other_col_name',
                                              "Many 2 Many Variable 2",
                                              help="Help")

    field_case_sensitive = fields.Char(
        'Field Case SENSITIVE',
        help="Field case sensitive"
    )

    name_equal_to_string = fields.Float(
        "Name equal to string",
        help="Name Equal To String"
    )

    many_2_one = fields.Many2one(
        'res.users',
        "Many 2 One",
        help="Many 2 one"
    )

    many_2_many = fields.Many2many(
        'res.users',
        'relation',
        'fk_column_from',
        'fk_column_to',
        "Many 2 many",
        help="Many 2 Many"
    )

    # This is a inherit overwrite field then don't should show errors related
    # with creation of fields.
    field_state_overwrite = fields.Selection(
        selection_add=[('new_item', 'New Item')])

    ids = ["parent_id_1", "parent_id_2"]

    def my_method1(self, variable1):
        #  Shouldn't show error of field-argument-translate
        self.my_method2(_('hello world'))

    def my_method2(self, variable2):
        return variable2

    def my_method3(self, cr):
        cr.commit()  # Dangerous use of commit old api
        self.env.cr.commit()  # Dangerous use of commit
        self._cr.commit()  # Dangerous use of commit
        self.cr.commit()  # Dangerous use of commit
        return cr

    def my_method4(self, variable2):
        self.env.cr2.commit()  # This should not be detected
        return variable2

    def my_method5(self, variable2):
        self.env.cr.commit2()  # This should not be detected
        return variable2

    def my_method6(self):
        user_id = 1
        if user_id != 99:
            # Method without translation
            raise UserError('String without translation')

    def my_method7(self):
        user_id = 1
        if user_id != 99:
            # Method with translation
            raise UserError(_('String with translation'))

    def my_method8(self):
        user_id = 1
        if user_id != 99:
            str_error = 'String with translation 2'  # Don't check
            raise UserError(str_error)

    def my_method9(self):
        user_id = 1
        if user_id != 99:
            # Method without translation
            raise UserError("String without translation 2")

    def my_method10(self):
        # A example of built-in raise without parameters
        # Shouldn't show error from lint
        raise ZeroDivisionError
        raise ZeroDivisionError()

    def my_method11(self):
        # A example of built-in raise with parameters
        # Shouldn't show error from lint
        raise ZeroDivisionError("String without translation")
        # raise without class-exception to increase coverage
        raise
        raise "obsolete case"

    def my_method12(self):
        # Should show error
        raise exceptions.Warning(
            'String with params format {p1}'.format(p1='v1'))
        raise exceptions.Warning(
            'qp2w String with params format %(p1)s' % {'p1': 'v1'})

    def my_method13(self):
        # Shouldn't show error
        raise exceptions.Warning(_(
            'String with params format {p1}').format(p1='v1'))
        raise exceptions.Warning(_(
            'String with params format {p1}'.format(p1='v1')))
        raise exceptions.Warning(_(
            'String with params format %(p1)s') % {'p1': 'v1'})
        raise exceptions.Warning(_(
            'String with params format %(p1)s' % {'p1': 'v1'}))

    def old_api_method_alias(self, cursor, user, ids, context=None):  # old api
        pass

    def sql_method(self, ids, cr):
        # Use of query parameters: nothing wrong here
        self._cr.execute(
            'SELECT name FROM account WHERE id IN %s', (tuple(ids),))
        self.env.cr.execute(
            'SELECT name FROM account WHERE id IN %s', (tuple(ids),))
        cr.execute(
            'SELECT name FROM account WHERE id IN %s', (tuple(ids),))
        self.cr.execute(
            'SELECT name FROM account WHERE id IN %s', (tuple(ids),))

    def sql_injection_ignored_cases(self, ids, cr2):
        # This cr.execute2 or cr2.execute should not be detected
        self._cr.execute2(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))
        cr2.execute(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))

        # Ignore when the query is built using private attributes
        self._cr.execute(
            'DELETE FROM %s WHERE id IN %%s' % self._table, (tuple(ids),))

    # old api
    def sql_injection_modulo_operator(self, cr, uid, ids, context=None):
        # Use of % operator: risky
        self._cr.execute(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))
        self.env.cr.execute(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))
        cr.execute(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))
        self.cr.execute(
            'SELECT name FROM account WHERE id IN %s' % (tuple(ids),))

        operator = 'WHERE'
        self._cr.execute(
            'SELECT name FROM account %s id IN %%s' % operator, ids)

        var = 'SELECT name FROM account WHERE id IN %s'
        values = ([1, 2, 3, ], )
        self._cr.execute(var % values)

    def sql_injection_executemany(self, ids, cr, v1, v2):
        # Check executemany() as well
        self.cr.executemany(
            'INSERT INTO account VALUES (%s, %s)' % (v1, v2))

    def sql_injection_format(self, ids, cr):
        # Use of .format(): risky
        self.cr.execute(
            'SELECT name FROM account WHERE id IN {}'.format(ids))

    def sql_injection_plus_operator(self, ids, cr):
        # Use of +: risky
        self.cr.execute(
            'SELECT name FROM account WHERE id IN ' + str(tuple(ids)))

        operator = 'WHERE'
        self._cr.execute(
            'SELECT name FROM account ' + operator + ' id IN %s', ids)
        self.cr.execute(
            ('SELECT name FROM account ' + operator + ' id IN (1)'))
        self.cr.execute(
            'SELECT name FROM account ' +
            operator +
            ' id IN %s' % (tuple(ids),))
        self.cr.execute(
            ('SELECT name FROM account ' +
             operator +
             ' id IN %s') % (tuple(ids),))

    def sql_injection_before(self, ids):
        # query built before execute: risky as well

        var = 'SELECT name FROM account WHERE id IN %s' % tuple(ids)
        self._cr.execute(var)

        var[1] = 'SELECT name FROM account WHERE id IN %s' % tuple(ids)
        self._cr.execute(var[1])
Exemple #19
0
class NeedSync(models.Model):
    _name = "need.sync"
    _description = "Need Sync Base Model"

    def _select_models(self):
        return self.env['need.sync.model']._select_models()

    name = fields.Char(string="Sync", compute="_get_name", store=True)
    model = fields.Selection(selection=_select_models,
                             string="Model",
                             required=True,
                             index=True)
    res_id = fields.Integer(string='Record ID',
                            index=True,
                            required=True,
                            help="ID of the target record in the database")
    record = fields.Reference(selection=_select_models,
                              string="Record",
                              compute="_get_record",
                              store=True,
                              size=128)
    need_sync_date = fields.Datetime(string="Need Sync Datetime")
    sync_lines = fields.One2many(comodel_name="need.sync.line",
                                 inverse_name="need_sync",
                                 string="Sync Lines")

    @api.one
    @api.depends('res_id', 'model')
    def _get_record(self):
        if self.res_id and self.model:
            print self.res_id
            print self.model
            self.record = self.env[str(self.model)].browse(self.res_id)

    @api.one
    @api.depends('res_id', 'model')
    def _get_name(self):
        object = self.env[self.model].browse(self.res_id)
        if object and 'name' in object._fields:
            object_name = object.name
        else:
            object_name = "No object name defined"
        self.name = '%s' % (object_name)

    @api.multi
    def set_need_sync(self, model, res_ids):
        """
        Pass need sync to model and resources
        :param model: need sync on wich model
        :param res: list of resources to set sync
        :return: boolean True or False
        """

        if isinstance(res_ids, (long, int)):
            res_ids = [res_ids]

        # Get list of IDS where a record in need sync exists
        # and a list for creating a need sync record
        need_syncs = self.search([('model', '=', model),
                                  ('res_id', 'in', res_ids)])
        need_syncs.write({'need_sync_date': fields.Datetime.now()})
        # Need sync res_ids list
        need_sync_res_ids = [x.res_id for x in need_syncs]
        create_sync_ids = list(set(res_ids) - set(need_sync_res_ids))
        if create_sync_ids:
            _logger.debug("Create new Need sync records")
            self._create_need_sync(model, create_sync_ids)

    @api.model
    def _create_need_sync(self, model, res_ids):
        if model and res_ids:
            for res_id in res_ids:
                create_need_sync = self.create({
                    'model':
                    model,
                    'res_id':
                    res_id,
                    'need_sync_date':
                    fields.Datetime.now()
                })
                if create_need_sync:
                    for connection_model in self.env[
                            'need.sync.connection.model'].search([
                                ('model', '=', model)
                            ]):
                        self.env['need.sync.line']._auto_create_need_sync(
                            create_need_sync,
                            connection_model.need_sync_connection)
Exemple #20
0
class MailNotification(models.Model):
    _inherit = 'mail.notification'

    record = fields.Reference(
        selection=lambda self: [(m.model, m.name)
                                for m in self.env['ir.model'].search([])],
        compute='_compute_record')
    record_access_link = fields.Char(compute='_compute_record')

    @api.multi
    def _notify_email(self, message_id, force_send=False, user_signature=True):
        if not self.mapped('message_id.subtype_id.template_id'):
            return super(MailNotification,
                         self)._notify_email(message_id,
                                             force_send=force_send,
                                             user_signature=user_signature)
        message_ids = []
        for this in self:
            if not this.mapped('message_id.subtype_id.template_id'):
                super(MailNotification,
                      this)._notify_email(message_id,
                                          force_send=force_send,
                                          user_signature=user_signature)
                continue
            message = this.message_id
            if not this.get_partners_to_email(message):
                continue
            custom_values = {
                'references': message.parent_id.message_id,
                'author_id': message.author_id.id
            }
            if message.res_id and hasattr(self.env[message.model],
                                          'message_get_email_values'):
                message_values = self.env[message.model].browse(
                    message.res_id).message_get_email_values(message)
                # message_get_email_values is guessed to @api.one
                if message_values and isinstance(message_values, list):
                    message_values = message_values[0]
                custom_values.update(message_values)
            message_id = message.subtype_id.template_id.send_mail(this.id)
            if 'mail_message_id' in custom_values:
                custom_values.pop('mail_message_id')
            self.env['mail.mail'].browse(message_id).write(custom_values)
            message_ids.append(message_id)
        return message_ids or True

    @api.multi
    def _compute_record(self):
        for this in self:
            if not this.message_id.model or not this.message_id.res_id:
                continue
            this.record = self.env[this.message_id.model].browse(
                this.message_id.res_id)
            link_html = self.env['mail.mail']._get_partner_access_link(
                self.env['mail.mail'].new({
                    'notification':
                    True,
                    'mail_message_id':
                    this.message_id.id,
                }), this.partner_id)
            for a in etree.HTML(link_html or '<html/>').xpath('//a[@href]'):
                this.record_access_link = a.get('href')
Exemple #21
0
class SriDocumentoElectronico(models.Model):
    _name = 'l10n_ec_sri.documento.electronico'

    @api.multi
    def name_get(self):
        return [(documento.id,
                 '%s %s' % (documento.claveacceso, documento.estado))
                for documento in self]

    @api.model
    def create(self, vals):
        res = super(SriDocumentoElectronico, self).create(vals)
        if not res:
            return

        line = self.env['l10n_ec_sri.documento.electronico.queue.line']
        line.create({
            'queue_id':
            self.env.ref('l10n_ec_sri_ece.documento_electronico_queue').id,
            'documento_electronico_id':
            res.id,
        })

        return res

    @api.multi
    def validate_xsd_schema(self, xml, xsd_path):
        """

        :param xml: xml codificado como utf-8
        :param xsd_path: /dir/archivo.xsd
        :return:
        """
        xsd_path = os.path.join(__file__, "../..", xsd_path)
        xsd_path = os.path.abspath(xsd_path)

        xsd = open(xsd_path)
        schema = e.parse(xsd)
        xsd = e.XMLSchema(schema)

        xml = e.XML(xml)

        try:
            xsd.assertValid(xml)
            return True
        except e.DocumentInvalid:
            return False

    @api.multi
    def modulo11(self, clave):
        digitos = list(clave)
        nro = 6  # cantidad de digitos en cada segmento
        segmentos = [digitos[n:n + nro] for n in range(0, len(digitos), nro)]
        total = 0
        while segmentos:
            segmento = segmentos.pop()
            factor = 7  # numero inicial del mod11
            for s in segmento:
                total += int(s) * factor
                factor -= 1
        mod = 11 - (total % 11)
        if mod == 11:
            mod = 0
        elif mod == 10:
            mod = 1
        return mod

    @api.multi
    def firma_xades_bes(self, xml, p12, clave):
        """
        :param xml: cadena xml
        :param clave: clave en formato base64
        :param p12: archivo p12 en formato base64
        :return:
        """
        jar_path = os.path.join(__file__, "../../src/xadesBes/firma.jar")
        jar_path = os.path.abspath(jar_path)

        cmd = ['java', '-jar', jar_path, xml, p12, clave]

        try:
            subprocess.check_output(cmd)
            sp = subprocess.Popen(cmd,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.STDOUT)
            res = sp.communicate()
            return res[0]
        except subprocess.CalledProcessError as se:
            _logger.exception('FIRMA ELECTRONICA FALLIDA: %s' % se.returncode)
            raise UserError(
                _("Firma electrónica fallida, por favor, "
                  "verifique el archivo y la contraseña"))

    @api.multi
    def process_de(self):
        if self.estado == 'NO ENVIADO':
            self.send_de_backend()
        if self.estado in ('RECIBIDA', 'EN PROCESO'):
            self.receive_de_offline()
        if self.estado in ('DEVUELTA', 'NO AUTORIZADO', 'RECHAZADA'):
            # TODO: NOTIFICAR AL USUARIO.
            pass
        return True

    @api.multi
    def send_de_backend(self):
        """
        Envía el documento electrónico desde el backend
        para evitar demoras en caso de que el SRI se encuentre
        fuera de línea.

        """
        ambiente_id = self.env.user.company_id.ambiente_id
        xml = base64.b64decode(self.xml_file)

        envio = self.send_de_offline(ambiente_id, xml)
        if envio:
            self.write({
                'estado': envio['estado'] or 'NO ENVIADO',
                'mensajes': envio['comprobantes'] or '',
            })
            return True
        else:
            return False

    @api.multi
    def send_de_offline(self, ambiente_id, xml):
        """
        :param ambiente_id: recordset del ambiente
        :param xml: documento xml en base 64
        :return: respuesta del SRI
        """
        client = Client(ambiente_id.recepcioncomprobantes)
        with client.options(raw_response=False):
            response = client.service.validarComprobante(xml)
        return response

    @api.multi
    def receive_de_offline(self):
        ambiente_id = self.env.user.company_id.ambiente_id
        claveacceso = self.claveacceso

        client = Client(ambiente_id.autorizacioncomprobantes)
        with client.options(raw_response=False):
            response = client.service.autorizacionComprobante(claveacceso)
        try:
            autorizaciones = response['autorizaciones']['autorizacion'][0]
        except:
            return False

        autorizacion = OrderedDict([
            ('autorizacion',
             OrderedDict([
                 ('estado', autorizaciones['estado']),
                 ('numeroAutorizacion', autorizaciones['numeroAutorizacion']),
                 ('fechaAutorizacion', {
                     '@class': 'fechaAutorizacion',
                     '#text': str(autorizaciones['fechaAutorizacion'])
                 }),
                 ('ambiente', autorizaciones['ambiente']),
                 ('comprobante',
                  u'<![CDATA[{}]]>'.format(autorizaciones['comprobante'])),
             ]))
        ])
        comprobante = xml.sax.saxutils.unescape(
            xmltodict.unparse(autorizacion))
        self.write({
            'estado':
            autorizaciones['estado'],
            'mensajes':
            autorizaciones['mensajes'],
            'xml_file':
            base64.b64encode(comprobante.encode('utf-8')),
            'fechaautorizacion':
            fields.Datetime.to_string(autorizaciones['fechaAutorizacion']),
        })

        # Enviar correo si el documento es AUTORIZADO.
        if autorizaciones['estado'] == 'AUTORIZADO':
            try:
                sent = self.reference.send_email_de()
                # Si se envía, marcamos la línea como enviada.
                if sent:
                    line_obj = self.env[
                        'l10n_ec_sri.documento.electronico.queue.line']
                    line = line_obj.search(
                        [('documento_electronico_id', '=', self.id)], limit=1)
                    line.sent = True
            except:
                pass
        return True

    @api.multi
    def get_documento_electronico_dict(self, ambiente_id, comprobante_id,
                                       documento, claveacceso, tipoemision,
                                       reference):
        # Generamos el xml en memoria.
        xml = xmltodict.unparse(documento, pretty=False)
        xml = xml.encode('utf8')

        # Validamos el esquema.
        xsd_path = 'src/esquemasXsd/Factura_V_1_1_0.xsd'
        self.validate_xsd_schema(xml, xsd_path)

        firma = self.env.user.company_id.firma_id
        clave = base64.b64encode(firma.clave)
        if not os.path.exists(firma.path):
            firma.write({
                'path': firma.save_sign(firma.p12),
            })
        p12 = base64.b64encode(firma.path)
        xml = self.firma_xades_bes(xml, p12, clave)
        filename = ''.join([claveacceso, '.xml'])

        # Creamos el diccionario del documento electrónico.
        vals = {
            'xml_file': base64.b64encode(xml),
            'xml_filename': filename,
            'estado': 'NO ENVIADO',
            'mensajes': '',
            'ambiente': ambiente_id.ambiente,
            'tipoemision': tipoemision,
            'claveacceso': claveacceso,
            'reference': reference,
            'comprobante_id': comprobante_id.id,
        }
        return vals

    @api.multi
    def get_claveacceso(self, fecha, comprobante, ruc, ambiente_id,
                        establecimiento, puntoemision, secuencial):
        """

        :param fecha: fields.Date
        :param comprobante: código del tipo de comprobante en str zfill(2)
        :param ruc: de la empresa en str
        :param ambiente_id: recordset
        :param comprobante: str
        :param puntoemision: str
        :param secuencial: str
        :return:
        """
        fecha = datetime.strptime(fecha, '%Y-%m-%d')
        data = [
            fecha.strftime('%d%m%Y'),
            str(comprobante),
            str(ruc),
            str(ambiente_id.ambiente),
            str(establecimiento).zfill(3),
            str(puntoemision).zfill(3),
            str(secuencial).zfill(9),
            str(randrange(1, 99999999)).zfill(8),
            '1',
        ]
        try:
            claveacceso = ''.join(data)
            claveacceso += str(self.modulo11(claveacceso))
        except:
            raise UserError(
                _(u"""
                Falta informacion:
                fecha = %s,
                comprobante = %s,
                ruc = %s,
                ambiente = %s,
                establecimiento = %s,
                puntoemision = %s,
                secuencial = %s,
                nro aleatorio = %s,
                Tipo de emisión = %s,
                """ % tuple(data)))
        return claveacceso

    @api.multi
    def _get_reference_models(self):
        records = self.env['ir.model'].search([
            '|', ('model', '=', 'account.invoice'),
            ('model', '=', 'stock.picking')
        ])
        return [(record.model, record.name) for record in records] + [('', '')]

    reference = fields.Reference(string='Reference',
                                 selection='_get_reference_models')

    comprobante_id = fields.Many2one(
        'l10n_ec_sri.comprobante',
        string='Comprobante',
        copy=False,
    )

    tipoemision = fields.Selection(
        [
            ('1', 'Emisión normal'),
            ('2', 'Emisión por indisponibilidad del sistema'),
        ],
        string='Tipo de emisión',
    )

    ambiente = fields.Selection(
        [
            ('1', 'Pruebas'),
            ('2', 'Producción'),
        ],
        string='Ambiente',
    )

    @api.one
    def get_barcode_128(self):
        if self.claveacceso:
            file_data = StringIO.StringIO()
            generate('code128',
                     u'{}'.format(self.claveacceso),
                     writer=ImageWriter(),
                     output=file_data)
            file_data.seek(0)
            self.barcode128 = base64.encodestring(file_data.read())

    claveacceso = fields.Char('Clave de acceso', )
    barcode128 = fields.Binary('Barcode', compute=get_barcode_128)
    fechaautorizacion = fields.Datetime('Fecha y hora de autorización', )
    mensajes = fields.Text('Mensajes', )
    estado = fields.Selection([
        ('NO ENVIADO', 'NO ENVIADO'),  # Documentos fuera de línea.
        ('RECIBIDA', 'RECIBIDA'),
        ('EN PROCESO', 'EN PROCESO'),
        ('DEVUELTA', 'DEVUELTA'),
        ('AUTORIZADO', 'AUTORIZADO'),
        ('NO AUTORIZADO', 'NO AUTORIZADO'),
        ('RECHAZADA', 'RECHAZADA'),
    ])

    xml_file = fields.Binary(
        'Archivo XML',
        attachment=True,
        readonly=True,
    )
    xml_filename = fields.Char('Filename', )
Exemple #22
0
class edi_message(models.Model):
    _name = 'edi.message'
    _inherit = ['mail.thread']
    _description = 'EDI Message'

    name = fields.Char(string="Name", required=True)
    envelope_id = fields.Many2one(comodel_name='edi.envelope', required=False)
    consignor_id = fields.Many2one(
        comodel_name='res.partner',
        required=False,
        string="Consignor",
        help="Consignor - the party sending the goods.")
    consignee_id = fields.Many2one(
        comodel_name='res.partner',
        required=False,
        string="Consignee",
        help="Consignee - the party receiving the goods.")
    sender = fields.Many2one(comodel_name='res.partner',
                             string='Interchange Sender')
    recipient = fields.Many2one(comodel_name='res.partner',
                                string='Interchange Recipient')
    forwarder_id = fields.Many2one(
        comodel_name='res.partner',
        string="Forwarder",
        help=
        "Forwarder - the party planning the transport on behalf of the consignor or consignee."
    )
    carrier_id = fields.Many2one(
        comodel_name='res.partner',
        string="Carrier",
        help="Carrier - the party transporting the goods between two points.")
    body = fields.Binary()
    model = fields.Char(string="Model")
    res_id = fields.Integer()
    to_import = fields.Boolean(default=False)
    to_export = fields.Boolean(default=False)
    route_id = fields.Many2one(comodel_name="edi.route")
    route_type = fields.Selection(selection=[('plain', 'Plain')],
                                  default='plain')
    edi_type = fields.Many2one(comodel_name='edi.message.type',
                               string="Edi Type")
    state = fields.Selection([('progress', 'Progress'), ('sent', 'Sent'),
                              ('received', 'Received'),
                              ('canceled', 'Canceled')],
                             default='progress')

    @api.one
    def draft(self):
        self.state = 'progress'

    @api.one
    def unpack(self):
        try:
            res = self._unpack()
        except ValueError as e:
            id = self.env['mail.message'].create({
                'body':
                _("Route %s type %s Error %s\n" %
                  (self.route_id.name, self.route_type, e)),
                'subject':
                "ValueError",
                'author_id':
                self.env['res.users'].browse(self.env.uid).partner_id.id,
                'res_id':
                self.id,
                'model':
                self._name,
                'type':
                'notification',
            })
            _logger.error(
                'edi.message.unpack(): EDI ValueError Route %s type %s Error %s '
                % (self.route_id.name, self.route_type, e))
            #raise Warning('EDI ValueError in split %s (%s) %s' % (e,id,d))
            self.state = 'canceled'
        except TypeError as e:
            self.env['mail.message'].create({
                'body':
                _("Route %s type %s Error %s\n" %
                  (self.route_id.name, self.route_type, e)),
                'subject':
                "TypeError",
                'author_id':
                self.env['res.users'].browse(self.env.uid).partner_id.id,
                'res_id':
                self.id,
                'model':
                self._name,
                'type':
                'notification',
            })
            _logger.error(
                'edi.message.unpack(): EDI TypeError Route %s type %s Error %s '
                % (self.route_id.name, self.route_type, e))
            #raise Warning('EDI TypeError in split %s' % e)
            self.state = 'canceled'
        except IOError as e:
            self.env['mail.message'].create({
                'body':
                _("Route %s type %s Error %s\n" %
                  (self.route_id.name, self.route_type, e)),
                'subject':
                "IOError",
                'author_id':
                self.env['res.users'].browse(self.env.uid).partner_id.id,
                'res_id':
                self.id,
                'model':
                self._name,
                'type':
                'notification',
            })
            _logger.error(
                'edi.message.unpack(): EDI IOError Route %s type %s Error %s '
                % (self.route_id.name, self.route_type, e))
            #raise Warning('EDI IOError in split %s' % e)
            self.state = 'canceled'
        except Warning as e:
            _logger.error(
                'edi.message.unpack(): EDI Warning Route %s type %s Error %s '
                % (self.route_id.name, self.route_type, e))
            self.state = 'canceled'
        else:
            self.env['mail.message'].create({
                'body':
                _("Route %s type %s %s messages unpacked\n" %
                  (self.route_id.name, self.route_type, self.edi_type.name)),
                'subject':
                "Success",
                'author_id':
                self.env['res.users'].browse(self.env.uid).partner_id.id,
                'res_id':
                self.id,
                'model':
                self._name,
                'type':
                'notification',
            })
            self.state = 'received'

    @api.one
    def _unpack(self):
        pass

    @api.one
    def pack(self):
        try:
            res = self._pack()
        except ValueError as e:
            id = self.env['mail.message'].create({
                'body':
                _("Route %s type %s Value Error %s\n" %
                  (self.route_id.name, self.route_type, e)),
                'subject':
                "ValueError",
                'author_id':
                self.env['res.users'].browse(self.env.uid).partner_id.id,
                'res_id':
                self.id,
                'model':
                self._name,
                'type':
                'notification',
            })
            _logger.error(
                'edi.message.pack(): EDI ValueError Route %s type %s Error %s '
                % (self.route_id.name, self.route_type, e))
            #raise Warning('EDI ValueError in split %s (%s) %s' % (e,id,d))
        except TypeError as e:
            self.env['mail.message'].create({
                'body':
                _("Route %s type %s Type Error %s\n" %
                  (self.route_id.name, self.route_type, e)),
                'subject':
                "TypeError",
                'author_id':
                self.env['res.users'].browse(self.env.uid).partner_id.id,
                'res_id':
                self.id,
                'model':
                self._name,
                'type':
                'notification',
            })
            _logger.error(
                'edi.message.pack(): EDI TypeError Route %s type %s Error %s '
                % (self.route_id.name, self.route_type, e))
            raise
            raise Warning('EDI TypeError in split %s' % e)
        except IOError as e:
            self.env['mail.message'].create({
                'body':
                _("Route %s type %s IOError %s\n" %
                  (self.route_id.name, self.route_type, e)),
                'subject':
                "IOError",
                'author_id':
                self.env['res.users'].browse(self.env.uid).partner_id.id,
                'res_id':
                self.id,
                'model':
                self._name,
                'type':
                'notification',
            })
            _logger.error(
                'edi.message.pack(): EDI IOError Route %s type %s Error %s ' %
                (self.route_id.name, self.route_type, e))
            #raise Warning('EDI IOError in split %s' % e)
        else:
            self.env['mail.message'].create({
                'body':
                _("Route %s type %s %s messages packed\n" %
                  (self.route_id.name, self.route_type, self.edi_type.name)),
                'subject':
                "Success",
                'author_id':
                self.env['res.users'].browse(self.env.uid).partner_id.id,
                'res_id':
                self.id,
                'model':
                self._name,
                'type':
                'notification',
            })

    @api.one
    def _pack(self):
        pass

    def _edi_message_create(self,
                            edi_type=None,
                            obj=None,
                            sender=None,
                            recipient=None,
                            consignee=None,
                            consignor=None,
                            route=None,
                            check_double=True):
        if consignee and obj and edi_type:
            #do not create message if edi type is not listed in consignee
            if not self.env.ref(edi_type).id in consignee.get_edi_types(
                    consignee):
                return None
            if check_double and len(self.env['edi.message'].search(
                [('model', '=', obj._name), ('res_id', '=', obj.id),
                 ('edi_type', '=', self.env.ref(edi_type).id)])) > 0:
                return None
            message = self.env['edi.message'].create({
                'name':
                self.env['ir.sequence'].next_by_id(
                    self.env.ref('edi_route.sequence_edi_message').id),
                'edi_type':
                self.env.ref(edi_type).id,
                'model':
                obj._name,
                'res_id':
                obj.id,
                'route_id':
                route and route.id or self.env.ref('edi_route.main_route').
                id,  #routes.get(edi_type,1),# self.env.ref('edi_route.main_route').id),
                'route_type':
                route and route.route_type
                or self.env.ref('edi_route.main_route').route_type,
                # This is a reply, switch recipient/sender unless we got excplicit parties
                'sender':
                sender and sender.id or obj.unb_recipient.id,
                'recipient':
                recipient and recipient.id or obj.unb_sender.id,
                'consignor_id':
                consignor and consignor.id
                or self.env.ref('base.main_partner').id,
                'consignee_id':
                consignee.id,
            })
            message.pack()
            self.env['mail.message'].create({
                'body':
                _("{type} <a href='/web#model={model}&id={id}'>{message}</a> created\n"
                  ).format(type=self.env.ref(edi_type).name,
                           model=message._name,
                           id=message.id,
                           message=message.name),
                'subject':
                self.env.ref(edi_type).name,
                'author_id':
                self.env['res.users'].browse(self.env.uid).partner_id.id,
                'res_id':
                obj.id,
                'model':
                obj._name,
                'type':
                'notification',
            })
            self.env['mail.message'].create({
                'body':
                _("{type} <a href='/web#model={model}&id={id}'>{message}</a> created\n"
                  ).format(type=self.env.ref(edi_type).name,
                           model=obj._name,
                           id=obj.id,
                           message=obj.name),
                'subject':
                self.env.ref(edi_type).name,
                'author_id':
                self.env['res.users'].browse(self.env.uid).partner_id.id,
                'res_id':
                message.id,
                'model':
                message._name,
                'type':
                'notification',
            })

    @api.one
    def _model_record(self):
        if self.model and self.res_id and self.env[self.model].browse(
                self.res_id):
            self.model_record = self.env[self.model].browse(self.res_id)

    @api.model
    def _reference_models(self):
        models = self.env['ir.model'].search([('state', '!=', 'manual')])
        #        return self.env[self.model].browse(self.res_id)
        return [(model.model, model.name) for model in models
                if not model.model.startswith('ir.')]

    model_record = fields.Reference(string="Record",
                                    selection="_reference_models",
                                    compute="_model_record")
Exemple #23
0
class gdpr_object(models.Model):
    _name = 'gdpr.object'

    @api.one
    def _get_name(self):
        if self.object_id and hasattr(self.object_id, 'name'):
            self.name = self.object_id.name
        elif self.object_id:
            self.name = '%s, %s' % (self.object_id._name, self.object_id.id)
        else:
            self.name = 'gdpr.object, %s' % self.id

    name = fields.Char(string='Name', compute='_get_name')
    gdpr_id = fields.Many2one(string='Inventory',
                              comodel_name='gdpr.inventory')
    object_id = fields.Reference(string='Object',
                                 selection='_reference_models',
                                 compute='_get_object_id',
                                 inverse='_set_object_id',
                                 search='_search_object_id')
    object_model = fields.Char(string='Object Model')
    object_res_id = fields.Integer(string='Object ID')
    partner_id = fields.Many2one(string='Partners', comodel_name='res.partner')
    restricted = fields.Boolean(string='Restricted',
                                help="This record has been restricted.")
    manual = fields.Boolean(string='Manual Action Required',
                            help="This record needs attention.")

    @api.one
    def _get_object_id(self):
        if self.object_model and self.object_res_id:
            self.object_id = self.env[self.object_model].search([
                ('id', '=', self.object_res_id)
            ])

    @api.one
    def _set_object_id(self):
        if self.object_id:
            self.object_res_id = self.object_id.id
            self.object_model = self.object_id._name
        else:
            self.object_res_id = False
            self.object_model = False

    @api.model
    def _search_object_id(self, operator, value):
        _logger.debug('_search_object_id; operator: %s, value: %s' %
                      (operator, value))
        if operator in ('in', 'not in'):
            if operator == 'in':
                op_m = '='
                ao1 = '&'
                ao2 = '|'
            else:
                op_m = '!='
                ao1 = '|'
                ao2 = '&'
            ids = {}
            for v in value:
                m, id = v.split(',')
                if m not in ids:
                    ids[m] = []
                ids[m].append(int(id))
            res = []
            for model in ids:
                if res:
                    res = [ao2] + res
                res += [
                    ao1, ('object_model', op_m, model),
                    ('object_res_id', operator, ids[model])
                ]
        elif value:
            res = [
                '&', ('object_model', operator, value.split(',')[0]),
                ('object_res_id', operator, int(value.split(',')[1]))
            ]
        else:
            res = [
                '&', ('object_model', operator, value),
                ('object_res_id', operator, value)
            ]
        _logger.debug(res)
        return res

    @api.model
    def _reference_models(self):
        models = self.env['ir.model'].search([('state', '!=', 'manual')])
        return [(model.model, model.name) for model in models]
Exemple #24
0
class CenitFlow(models.Model):
    _name = "cenit.flow"
    _inherit = 'cenit.api'

    cenit_model = 'flow'
    cenit_models = 'flows'

    cenitID = fields.Char('Cenit ID')

    namespace = fields.Many2one('cenit.namespace', string='Namespace',
                              ondelete='cascade')

    name = fields.Char('Name', size=64, required=True, unique=True)
    enabled = fields.Boolean('Enabled', default=True)
    event = fields.Many2one("cenit.event", string='Event')
    discard_events = fields.Boolean("Discard events", default=False)

    cron = fields.Many2one('ir.cron', string='Cron rules')
    base_action_rules = fields.Many2many(
        'base.action.rule', string='Action Rule'
    )

    format_ = fields.Selection(
        [
            ('application/json', 'JSON'),
            ('application/EDI-X12', 'EDI')
        ],
        'Format', default='application/json', required=True
    )
    local = fields.Boolean('Bypass Cenit', default=False)
    cenit_translator = fields.Many2one('cenit.translator', "Translator")

    schema = fields.Many2one(
        'cenit.schema', 'Data type', required=True
    )
    data_type = fields.Many2one(
        'cenit.data_type', string='Source data type'
    )
    webhook = fields.Reference(string='Webhook',
                               selection=[('cenit.webhook', 'Plain'), ('cenit.operation', 'Operation')], required=True)
    connection_role = fields.Many2one(
        'cenit.connection.role', string='Connection role'
    )

    @api.depends('webhook')
    def _compute_method(self):
        self.method = self.webhook.method

    method = fields.Char(compute="_compute_method")

    _sql_constraints = [
        ('name_uniq', 'UNIQUE(namespace, name)',
         'The name must be unique for each namespace!')
    ]

    @api.one
    def _get_values(self):
        vals = {
            'namespace': self.namespace.name,
            'name': self.name,
            'active': self.enabled,
            'discard_events': False,
            'data_type_scope': 'All',
        }

        if self.cenitID:
            vals.update({'id': self.cenitID})

        event = {
            "_reference": True,
            "id": self.event.cenitID,
        }
        vals.update({
            'event': event,
            'data_type_scope': 'Event',
        })

        if self.cenit_translator:
            vals.update({
                'translator': {
                    '_reference': True,
                    'id': self.cenit_translator.cenitID,
                }
            })

        if self.schema.cenitID:
            vals.update({
                'custom_data_type': {
                    '_reference': True,
                    'id': self.schema.cenitID
                }
            })

        if self.connection_role:
            vals.update({
                'connection_role': {
                    '_reference': True,
                    'id': self.connection_role.cenitID
                }
            })

        if self.webhook:
            vals.update({
                'webhook': {
                    '_reference': True,
                    'id': self.webhook.cenitID
                }
            })

        return vals

    @api.one
    def _calculate_update(self, values):
        update = {}
        for k, v in values.items():
            if k == "%s" % (self.cenit_models,):
                update = {
                    'cenitID': v[0]['id'],

                }
        return update

    @api.onchange('webhook')
    def on_webhook_changed(self):
        return {
            'value': {
                'connection_role': ""
            },
            "domain": {
                "connection_role": [
                    ('webhooks', 'in', self.webhook.id)
                ]
            }
        }

    @api.onchange('schema')
    def on_schema_changed(self):
        return {
            'value': {
                'data_type': "",
                'event': "",
            },
            "domain": {
                "data_type": [
                    ('schema', '=', self.schema.id),
                    ('enabled', '=', True)
                ],
                'event': [
                    ('schema', '=', self.schema.id)
                ],
            }
        }

    @api.onchange('schema', 'webhook')
    def _on_schema_or_hook_changed(self):
        return {
            'value': {
                'cenit_translator': "",
            },
            'domain': {
                'cenit_translator': [
                    ('schema', 'in', (self.schema.id, False)),
                    ('type_', '=', {'get': 'Import', }.get(self.webhook.method, 'Export'))
                ]
            }
        }

    @api.one
    def _get_direction(self):
        my_url = self.env['ir.config_parameter'].get_param(
            'web.base.url', default=''
        )

        conn = self.connection_role.connections and \
               self.connection_role.connections[0]
        my_conn = conn.url == my_url

        rc = {
            ('get', True): 'send',
            ('put', False): 'send',
            ('post', False): 'send',
            ('delete', False): 'send',
        }.get((self.webhook.method, my_conn), 'receive')

        return rc

    @api.one
    def _get_data_types(self, dt_id):
        dt_pool = self.env['cenit.data_type']

        if self.data_type:
            return self.data_type
        else:
            domain = [('schema', '=', self.schema.id), ('enabled', '=', True), ('id', '=', dt_id)]
            return dt_pool.search(domain)

    @api.model
    def create(self, vals):
        local = (vals.get('cenitID', False) is False) or \
                (self.env.context.get('local'), False)

        if not isinstance(vals['namespace'], int):
            vals['namespace'] = vals['namespace']['id']

        obj = super(CenitFlow, self).create(vals)
        return obj

    @api.model
    def find(self, model, purpose):
        rc = []
        domain = [("schema.slug", "=", model)]
        objs = self.search(domain)
        if objs:
            rc = [x for x in objs if
                  ((x._get_direction()[0] == purpose) and x.enabled)]

        return rc

    @api.one
    def set_receive_execution(self):
        return True

    @api.model
    def receive(self, model, data):
        res = False
        context = self.env.context.copy() or {}
        flows = self.find(model.lower(), 'receive')

        if not flows:
            return res

        data_types = set()
        for flow in flows:
            dts = flow._get_data_types()
            for dt in dts:
                data_types.add(dt)
        for dt in data_types:
            klass = self.env[dt.model.model]

            if flow.format_ == 'application/json':
                action = context.get('action', 'push')
                wh = self.env['cenit.handler']
                context.update({'receive_object': True})

                action = getattr(wh, action, False)
                if action:
                    root = dt.cenit_root
                    res = action(data, root)

            elif flow.format_ == 'application/EDI-X12':
                for edi_document in data:
                    klass.edi_import(edi_document)
                res = True
        return res

    @api.one
    def set_send_execution(self):
        return True

    @api.model
    def send(self, obj, flow_id, dt_id):
        flow = self.browse(flow_id)
        if not (flow and flow.enabled):
            return False

        ws = self.env['cenit.serializer']

        data_types = flow._get_data_types(dt_id)
        if isinstance(data_types, list) and len(data_types) == 1:
            data_types = data_types[0]

        data = None
        if flow.format_ == 'application/json':
            data = []
            for dt in data_types:
                match = dt.ensure_object(obj)
                if isinstance(match, list):
                    match = match[0]
                if match:
                    data.append(ws.serialize(obj, dt))
        elif flow.format_ == 'application/EDI-X12':
            dt = data_types[0]
            if dt.ensure_object(obj):
                data = dt.model.edi_export([obj])

        rc = False
        if data:
            _logger.info("\n\nPushing: %s\n", data)
            rc = flow._send(data)

        return rc

    @api.model
    def send_all(self, id_, dt, domain=list()):
        flow = self.browse(id_)
        dt_ = flow.data_type or dt
        mo = self.env[dt_.model.model]
        _logger.info("Performing search on %s with %s", mo, domain)
        data = []

        query = "SELECT id from %s" % dt.model.model.replace(".", "_")
        for entry in domain:
            query += " WHERE %s%s'%s'" % (entry[0], entry[1], entry[2])

        self.env.cr.execute(query)
        rc = self.env.cr.fetchall()
        objs = mo.browse([x[0] for x in rc])

        if flow.format_ == 'application/json':
            ws = self.env['cenit.serializer']
            for x in objs:
                if dt_.ensure_object(x):
                    data.append(ws.serialize(x, dt_))
        elif flow.format_ == 'application/EDI-X12' and \
                hasattr(mo, 'edi_export'):
            for x in objs:
                if dt_.ensure_object(x):
                    data.append(mo.edi_export(x))

        if data:
            return flow._send(data)
        return False

    @api.one
    def _send(self, data):
        method = "http_post"
        return getattr(self, method)(data)

    @api.one
    def http_post(self, data):
        path = "/%s/%s" % (self.schema.namespace.slug, self.schema.slug,)

        values = data[0]

        rc = False
        try:
            rc = self.post(path, values)
        except Warning as e:
            _logger.exception(e)

        return rc
Exemple #25
0
class IrUiMenu(models.Model):
    _name = 'builder.ir.ui.menu'

    _rec_name = 'complete_name'

    @api.multi
    def get_user_roots(self):
        """ Return all root menu ids visible for the user.

        :return: the root menu ids
        :rtype: list(int)
        """
        menu_domain = [('parent_id', '=', False), ('parent_ref', '=', False)]
        return self.search(menu_domain)

    @api.multi
    def load_menus_root(self):
        menu_roots = self.get_user_roots()
        return {
            'id': False,
            'name': 'root',
            'parent_id': [-1, ''],
            'children': menu_roots,
            'all_menu_ids': [i.id for i in menu_roots],
        }

    def _get_full_name(self, cr, uid, ids, name=None, args=None, context=None):
        if context is None:
            context = {}
        res = {}
        for elmt in self.browse(cr, uid, ids, context=context):
            res[elmt.id] = self._get_one_full_name(elmt)
        return res

    def _get_one_full_name(self, elmt, level=6):
        if level<=0:
            return '...'
        if elmt.parent_id:
            parent_path = self._get_one_full_name(elmt.parent_id, level-1) + MENU_ITEM_SEPARATOR
        else:
            parent_path = ''
        return parent_path + elmt.name

    @api.onchange('parent_ref')
    def onchange_parent_ref(self):
        self.parent_menu_id = False
        if self.parent_ref:
            self.parent_menu_id = self.env['ir.model.data'].xmlid_to_res_id(self.parent_ref)

    @api.onchange('parent_menu_id')
    def onchange_parent_menu_id(self):
        if self.parent_menu_id:
            data = self.env['ir.model.data'].search([('model', '=', 'ir.ui.menu'), ('res_id', '=', self.parent_menu_id.id)])
            self.parent_ref = "{module}.{id}".format(module=data.module, id=data.name) if data.id else False

    @api.onchange('parent_type')
    def onchange_parent_type(self):
        self.parent_ref = False
        self.parent_menu_id = False
        self.parent_id = False

    module_id = fields.Many2one('builder.ir.module.module', 'Module', ondelete='cascade')
    name = fields.Char('Menu', required=True, translate=True)
    xml_id = fields.Char('XML ID', required=True)
    complete_name = fields.Char('Complete Name', compute='_compute_complete_name')
    morder = fields.Integer('Order')
    sequence = fields.Integer('Sequence')
    child_ids = fields.One2many('builder.ir.ui.menu', 'parent_id', 'Child Ids', copy=True)
    # group_ids = fields.Many2many('builder.res.groups', 'builder_ir_ui_menu_group_rel', 'menu_id', 'gid', 'Groups', help="If you have groups, the visibility of this menu will be based on these groups. "\
    #             "If this field is empty, Odoo will compute visibility based on the related object's read access.")
    parent_menu_id = fields.Many2one('ir.ui.menu', 'System Menu', ondelete='set null')
    parent_ref = fields.Char('System Menu Ref', select=True)
    parent_id = fields.Many2one('builder.ir.ui.menu', 'Parent Menu', select=True, ondelete='cascade')
    parent_type = fields.Selection([('module', 'Module'), ('system', 'System')], 'Parent Type')
    parent_left = fields.Integer('Parent Left', select=True)
    parent_right = fields.Integer('Parent Left', select=True)
    action_type = fields.Selection([('module', 'Module'), ('system', 'System')], 'Action Type')
    action_system_ref = fields.Char('Action System Ref')
    action_system = fields.Reference([
                                    ('ir.actions.report.xml', 'ir.actions.report.xml'),
                                    ('ir.actions.act_window', 'ir.actions.act_window'),
                                    ('ir.actions.wizard', 'ir.actions.wizard'),
                                    ('ir.actions.act_url', 'ir.actions.act_url'),
                                    ('ir.actions.server', 'ir.actions.server'),
                                    ('ir.actions.client', 'ir.actions.client'),
    ], 'System Action')

    action_module = fields.Reference([
                                    ('builder.ir.actions.act_window', 'Window'),
                                    # ('builder.ir.actions.act_url', 'URL'),
    ], 'Module Action')

    group_ids = fields.Many2many('builder.res.groups', 'builder_ir_ui_menu_group_rel', 'menu_id', 'gid', string='Groups', help="If this field is empty, the menu applies to all users. Otherwise, the view applies to the users of those groups only.")

    @api.onchange('action_system')
    def onchange_action_system(self):
        if self.action_system:
            model, res_id = self.action_system._name, self.action_system.id
            data = self.env['ir.model.data'].search([('model', '=', model), ('res_id', '=', res_id)])
            self.action_system_ref = "{module}.{id}".format(module=data.module, id=data.name) if data.id else False

            self.name = self.action_system.name
            self.xml_id = "menu_{action}".format(action=self.action_system_ref.replace('.', '_'))

    @api.onchange('action_module')
    def onchange_action_module(self):
        if self.action_module:
            self.name = self.action_module.name
            self.xml_id = "menu_{action}".format(action=self.action_module.xml_id)

    @api.model
    @api.returns('self', lambda value: value.id)
    def create(self, vals):
        if not vals.get('parent_type', False):
            vals['parent_id'] = False
            vals['parent_menu_id'] = False
            vals['parent_ref'] = False

        return super(IrUiMenu, self).create(vals)

    @api.multi
    def write(self, vals):
        if not vals.get('parent_type', self.parent_type):
            vals['parent_id'] = False
            vals['parent_menu_id'] = False
            vals['parent_ref'] = False

        return super(IrUiMenu, self).write(vals)

    @api.one
    def _compute_complete_name(self):
        self.complete_name = self._get_full_name_one()

    @api.multi
    def _get_full_name_one(self, level=6):
        if level <= 0:
            return '...'
        parent_path = ''
        if self.parent_id:
            parent_path = self.parent_id._get_full_name_one(level-1) + MENU_ITEM_SEPARATOR
        elif self.parent_ref:
            if self.parent_menu_id:
                parent_path = '[{name}]'.format(name=self.parent_menu_id.complete_name.encode('utf-8')) + MENU_ITEM_SEPARATOR
            else:
                parent_path = '[{ref}]'.format(ref=self.parent_ref) + MENU_ITEM_SEPARATOR

        try:
            return parent_path + self.name.encode('utf-8')
        except:
            return False

    @api.one
    def name_get(self):
        return self.id, self._get_full_name_one()

    def _rec_message(self, cr, uid, ids, context=None):
        return _('Error ! You can not create recursive Menu.')

    @property
    def real_xml_id(self):
        return self.xml_id if '.' in self.xml_id else '{module}.{xml_id}'.format(module=self.module_id.name, xml_id=self.xml_id)

    _constraints = [
        (osv.osv._check_recursion, _rec_message, ['parent_id'])
    ]
    _defaults = {
        'sequence': 10,
    }
    _order = "morder,id"
    _parent_store = True
class clv_medicament_dispensation_ext(models.Model):
    _name = 'clv_medicament_dispensation_ext'

    name = fields.Char(size=32,
                       string='Dispensation Code',
                       required=False,
                       help='Type in the Code of this dispensation (ext)')
    authorization_code = fields.Char(size=32,
                                     string='Authorization Code',
                                     required=False)
    dispensation_date = fields.Date(string='Dispensation Date', required=False)
    insured_card_code = fields.Char(size=32,
                                    string='Insured Card Code',
                                    required=False)
    insured_name = fields.Char(size=256, string='Insured Name', required=False)
    prescriber_code = fields.Char(size=32,
                                  string='Prescriber Code',
                                  required=False)
    pharmacy_code = fields.Char(size=32,
                                string='Pharmacy Code',
                                required=False)
    pharmacy_name = fields.Char(size=256,
                                string='Pharmacy Name',
                                required=False)
    medicament_code = fields.Integer(string='Medicament Code')
    medicament_description = fields.Char(size=256,
                                         string='Medicament Description',
                                         required=False)
    notes = fields.Text(string='Dispensation Notes')
    # dispenser = fields.Many2one ('res.users', 'Dispenser')
    medicament_ref = fields.Reference([
        ('clv_medicament', 'Medicament'),
    ], 'Medicament Reference')
    medicament = fields.Many2one('clv_medicament',
                                 string='Dispensed Medicament',
                                 required=False,
                                 help='Dispensed Medicament')
    # max_retail_price = fields.Float('Maximum Retail Price')
    pack_quantity = fields.Integer(string='Pack Quantity',
                                   help='Quantity of packs of the medicament')
    # refund_price = fields.Float('Refund Price')
    # total_refund_price = fields.Float('Refund Value', size=32, compute='_total_refund_price', store=False)
    sale_value = fields.Float('Sale Value')
    subsidy_value = fields.Float('Subsidy Value')
    at_sight_value = fields.Float('At Sight Value')
    date_inclusion = fields.Datetime(
        "Inclusion Date",
        required=False,
        readonly=False,
        default=lambda *a: datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    active = fields.Boolean(
        'Active',
        help=
        "If unchecked, it will allow you to hide the dispensation without removing it.",
        default=1)

    _sql_constraints = [
        ('uniq_name', 'unique(name)',
         "Error! The Dispensation (Ext) Code must be unique!"),
    ]

    _order = 'name'
Exemple #27
0
class Cloud_Service_tmpl(models.Model):
    _inherit = 'cloud.service.tmpl'

    instance_de_gestion = fields.Reference(
        selection_add=[('cloud.service.instance.service', '')])
Exemple #28
0
class DobtorTodoListCore(models.Model):
    _name = "dobtor.todolist.core"
    _inherit = ["mail.thread", 'ir.needaction_mixin']
    _description = 'Dobtor Todo List Core'
    state = fields.Selection([(k, v) for k, v in TODO_STATES.items()],
                             'Status',
                             required=True,
                             copy=False,
                             default='todo')
    name = fields.Char(required=True, string="Description")
    creater = fields.Many2one('res.users',
                              'Creater',
                              readonly=True,
                              default=lambda self: self.env.user)
    reviewer_id = fields.Many2one('res.users',
                                  'Reviewer',
                                  default=lambda self: self.env.user)
    user_id = fields.Many2one('res.users', 'Assigned to', required=True)
    hide_button = fields.Boolean(compute='_compute_hide_button')
    recolor = fields.Boolean(compute='_compute_recolor')
    ref_model = fields.Reference(referencable_models, "Refer To", default=None)
    ref_id = fields.Integer(string='ref_id')
    ref_name = fields.Char(string='ref_name')
    parent_model = fields.Reference(referencable_models,
                                    "Parent",
                                    default=None)
    parent_id = fields.Integer(string='parent_id')
    parent_name = fields.Char(string='parent_name')
    partner_id = fields.Many2one('res.partner',
                                 default=lambda self: self.env.user.partner_id)
    date_assign = fields.Datetime('Assigning Date',
                                  select=True,
                                  default=fields.Datetime.now)
    date_complete = fields.Datetime('Complete Date', select=True)
    date_deadline = fields.Datetime("Deadline", select=True)
    planned_hours = fields.Float(string='Planned Hours', default=0)
    out_of_deadline = fields.Boolean("Out of deadline",
                                     default=False,
                                     compute="check_deadline")
    sequence = fields.Integer()

    @api.multi
    def check_deadline(self):
        for record in self:
            if record.date_deadline and record.date_deadline <= fields.Datetime.now(
            ):
                record.out_of_deadline = True
            else:
                record.out_of_deadline = False

    @api.multi
    def _compute_recolor(self):
        for record in self:
            if self.env.user == record.user_id and record.state == 'todo':
                record.recolor = True

    @api.multi
    def _compute_hide_button(self):
        for record in self:
            if self.env.user not in [record.reviewer_id, record.user_id]:
                record.hide_button = True

    @api.multi
    def _compute_reviewer_id(self):
        for record in self:
            record.reviewer_id = record.create_uid

    @api.model
    def _needaction_domain_get(self):
        if self._needaction:
            return [('state', '=', 'todo'), ('user_id', '=', self.env.uid)]
        return []

    @api.multi
    def write(self, vals):
        if 'ref_model' in vals and vals['ref_model']:
            vals['ref_id'] = vals['ref_model'].split(',')[1]
            vals['ref_name'] = vals['ref_model'].split(',')[0]
        if 'parent_model' in vals and vals['parent_model']:
            vals['parent_id'] = vals['parent_model'].split(',')[1]
            vals['parent_name'] = vals['parent_model'].split(',')[0]
        result = super(DobtorTodoListCore, self).write(vals)
        return result

    @api.model
    def create(self, vals):
        print("todo create")
        if 'ref_model' in vals and vals['ref_model']:
            vals['ref_id'] = vals['ref_model'].split(',')[1]
            vals['ref_name'] = vals['ref_model'].split(',')[0]
        if 'parent_model' in vals and vals['parent_model']:
            vals['parent_id'] = vals['parent_model'].split(',')[1]
            vals['parent_name'] = vals['parent_model'].split(',')[0]
        result = super(DobtorTodoListCore, self).create(vals)
        vals = self._add_missing_default_values(vals)
        # task = self.env['project.task'].browse(vals.get('task_id'))
        # task.send_subtask_email(vals['name'], vals['state'], vals['reviewer_id'], vals['user_id'])
        return result

    @api.multi
    def change_state_done(self):
        for record in self:
            record.state = 'done'
            record.date_complete = fields.Datetime.now()

    @api.multi
    def change_state_todo(self):
        for record in self:
            record.state = 'todo'
            record.date_complete = None

    @api.multi
    def change_state_cancelled(self):
        for record in self:
            record.state = 'cancelled'
            record.date_complete = None

    @api.multi
    def change_state_waiting(self):
        for record in self:
            record.state = 'waiting'
            record.date_complete = None

    @api.onchange('user_id')
    def change_user_id(self):
        if self.user_id:
            self.date_assign = fields.Datetime.now()
        else:
            self.date_assign = None
Exemple #29
0
class NeedSync(models.Model):
    _name = "need.sync"
    _description = "Need Sync Base Model"

    def _select_models(self):
        return self.env['need.sync.model']._select_models()

    name = fields.Char(string="Sync", compute="_get_name", store=True)
    model = fields.Selection(selection=_select_models,
                             string="Model",
                             required=True,
                             index=True)
    res_id = fields.Integer(string='Record ID',
                            index=True,
                            required=True,
                            help="ID of the target record in the database")
    record = fields.Reference(selection=_select_models,
                              string="Record",
                              compute="_get_record",
                              store=True,
                              size=128)
    need_sync_date = fields.Datetime(string="Need Sync Datetime")
    sync_lines = fields.One2many(comodel_name="need.sync.line",
                                 inverse_name="need_sync",
                                 string="Sync Lines")

    @api.one
    @api.depends('res_id', 'model')
    def _get_record(self):
        if self.res_id and self.model:
            self.record = self.env[str(self.model)].browse(self.res_id)

    @api.one
    @api.depends('res_id', 'model')
    def _get_name(self):
        object = self.env[self.model].browse(self.res_id)
        if object and 'name' in object._fields:
            object_name = object.name
        else:
            object_name = "No object name defined"
        self.name = '%s' % (object_name)

    @api.model
    def get_model_allowed_connections(self):
        syncmodels = self.env['need.sync.connection.model'].search([
            ('model', '=', self.model), ('auto_create_lines', '=', True)
        ])
        _logger.debug("Sync Model Connnections: %s", syncmodels)
        connections = syncmodels.mapped('need_sync_connection')
        _logger.debug("Sync Connections: %s", connections)
        return connections

    @api.model
    def _autocreate_syncline_connection(self, connection):
        lines = self.sync_lines
        cline = lines.filtered(
            lambda l: l.need_sync_connection.id == connection.id)
        if not cline:
            self.env['need.sync.line'].create({
                'need_sync_connection':
                connection.id,
                'need_sync':
                self.id
            })

    @api.one
    def _autocreate_sync_lines(self):
        if self.model:
            connections = self.get_model_allowed_connections()
            for connection in connections:
                _logger.debug("Autocreate for Conncetion: %s", connection)
                self._autocreate_syncline_connection(connection)

    @api.multi
    def set_need_sync(self, model, res_ids):
        """
        Pass need sync to model and resources
        :param model: need sync on wich model
        :param res: list of resources to set sync
        :return: boolean True or False
        """

        if isinstance(res_ids, (long, int)):
            res_ids = [res_ids]

        # Get list of IDS where a record in need sync exists
        # and a list for creating a need sync record
        need_syncs = self.search([('model', '=', model),
                                  ('res_id', 'in', res_ids)])
        need_syncs.write({'need_sync_date': fields.Datetime.now()})
        # Need sync res_ids list
        need_sync_res_ids = [x.res_id for x in need_syncs]
        create_sync_ids = list(set(res_ids) - set(need_sync_res_ids))

        if create_sync_ids:
            _logger.debug("Create new Need sync records")
            created_need_syncs = self._create_need_sync(model, create_sync_ids)
            need_syncs = need_syncs | created_need_syncs

        # Check if all lines exist for autocreate models
        _logger.debug("Need Syncs Autocreate Check: %s", need_syncs)
        need_syncs._autocreate_sync_lines()

    @api.model
    def _create_need_sync(self, model, res_ids):
        return_need_syncs = self.env['need.sync']
        if model and res_ids:
            for res_id in res_ids:
                create_need_sync = self.create({
                    'model':
                    model,
                    'res_id':
                    res_id,
                    'need_sync_date':
                    fields.Datetime.now()
                })
                _logger.debug("Need Sync Created: %s", create_need_sync)
                return_need_syncs = return_need_syncs | create_need_sync

        return return_need_syncs

    @api.model
    def unlink_records(self, model, res_ids):
        '''
        When calling unlink of a used model record, call this method to remove 
        the linked need syncs.
        :param model: Model
        :param res_ids: List of ids 
        :return: True
        '''
        need_syncs = self.search([('model', '=', model),
                                  ('res_id', 'in', res_ids)])
        if need_syncs:
            need_syncs.unlink()
        return True
class AccountAnalyticReport(models.Model):

    _name = 'account.analytic.report'

    name = fields.Char('Name', required=True)
    template_id = fields.Many2one('account.analytic.report.template',
                                  'Template',
                                  required=True)

    calc_date = fields.Date('Calc date')
    ref_1 = fields.Reference(selection=[('res.company', 'Company'),
                                        ('res.partner.category', 'Farm group')
                                        ],
                             string='Reference')
    from_date_1 = fields.Date('From date')
    to_date_1 = fields.Date('To date')
    milk_1 = fields.Float('Milk')
    total_cows_1 = fields.Integer('Total cows')
    employees_1 = fields.Integer('Total employees')
    total_heifer_1 = fields.Integer('Total heifer')

    ref_2 = fields.Reference(selection=[('res.company', 'Company'),
                                        ('res.partner.category', 'Farm group')
                                        ],
                             string='Reference')
    from_date_2 = fields.Date('From date')
    to_date_2 = fields.Date('To date')
    milk_2 = fields.Float('Milk')
    total_cows_2 = fields.Integer('Total cows')
    employees_2 = fields.Integer('Total employees')
    total_heifer_2 = fields.Integer('Total heifer')

    line_ids = fields.One2many('account.analytic.report.line', 'report_id',
                               'Lines')
    state = fields.Selection([('draft', 'Draft'), ('calc', 'Calculating'),
                              ('calc_done', 'Calculated'), ('done', 'Done'),
                              ('cancel', 'Cancel')],
                             'State',
                             default='draft')

    def _get_company(self):
        return self.env.user.company_id

    company_id = fields.Many2one('res.company',
                                 'Company',
                                 default=_get_company)

    @api.multi
    def _get_companies(self, company_1_2=1):
        self.ensure_one()
        companies = self.env['res.company']
        ref_field = 'ref_%s' % str(company_1_2)
        if not self[ref_field]:
            return companies
        if 'res.company' == str(self[ref_field]._model):
            companies = self[ref_field]
        elif 'res.partner.category' == str(self[ref_field]._model):
            partners = self.env['res.partner'].search([('category_id', '=',
                                                        self[ref_field].id)])
            companies = partners.filtered(lambda partner: partner.farm).mapped(
                'company_id')
        return companies

    @api.multi
    def _set_milk_fields(self):
        self.ensure_one()
        for i in (1, 2):
            from_date = 'from_date_' + str(i)
            to_date = 'to_date_' + str(i)
            companies = self._get_companies(i)
            partner_companies = companies.mapped('partner_id')
            quotas = self.env['output.quota'].search([
                ('farm_id', 'in', partner_companies._ids),
                ('date', '>=', self[from_date]), ('date', '<=', self[to_date])
            ])
            self['milk_' + str(i)] = sum([x.value for x in quotas])

    @api.multi
    def _set_total_cows_fields(self):
        self.ensure_one()
        for i in (1, 2):
            from_date = 'from_date_' + str(i)
            to_date = 'to_date_' + str(i)
            companies = self._get_companies(i)
            partner_companies = companies.mapped('partner_id')
            total_cows = 0
            for partner in partner_companies:
                cow_counts = self.env['cow.count'].search([
                    ('partner_id', '=', partner.id),
                    ('date', '>=', self[from_date]),
                    ('date', '<=', self[to_date])
                ])
                if not cow_counts:
                    continue
                total_count = len(cow_counts)
                heifer_0_3 = sum(cow_counts.mapped('heifer_0_3')) / total_count
                heifer_3_12 = sum(
                    cow_counts.mapped('heifer_3_12')) / total_count
                heifer_plus_12 = sum(
                    cow_counts.mapped('heifer_plus_12')) / total_count
                milk_cow = sum(cow_counts.mapped('milk_cow')) / total_count
                dry_cow = sum(cow_counts.mapped('dry_cow')) / total_count
                total_cows += sum((heifer_0_3, heifer_3_12, heifer_plus_12,
                                   milk_cow, dry_cow))
            self['total_cows_' + str(i)] = total_cows

    @api.multi
    def _set_employee_fields(self):
        self.ensure_one()
        for i in (1, 2):
            from_date = 'from_date_' + str(i)
            to_date = 'to_date_' + str(i)
            companies = self._get_companies(i)
            partner_companies = companies.mapped('partner_id')
            total_employee = 0
            for partner in partner_companies:
                employee_count = self.env['employee.farm.count'].search([
                    ('partner_id', '=', partner.id),
                    ('date', '>=', self[from_date]),
                    ('date', '<=', self[to_date])
                ])
                if not employee_count:
                    continue
                total_count = len(employee_count)
                total_employee += sum(
                    employee_count.mapped('quantity')) / total_count
            self['employees_' + str(i)] = total_employee

    @api.multi
    def _set_total_heifer_fields(self):
        self.ensure_one()
        for i in (1, 2):
            from_date = 'from_date_' + str(i)
            to_date = 'to_date_' + str(i)
            companies = self._get_companies(i)
            partner_companies = companies.mapped('partner_id')
            total_cows = 0
            for partner in partner_companies:
                cow_counts = self.env['cow.count'].search([
                    ('partner_id', '=', partner.id),
                    ('date', '>=', self[from_date]),
                    ('date', '<=', self[to_date])
                ])
                if not cow_counts:
                    continue
                total_count = len(cow_counts)
                heifer_0_3 = sum(cow_counts.mapped('heifer_0_3')) / total_count
                heifer_3_12 = sum(
                    cow_counts.mapped('heifer_3_12')) / total_count
                heifer_plus_12 = sum(
                    cow_counts.mapped('heifer_plus_12')) / total_count
                total_cows += sum((heifer_0_3, heifer_3_12, heifer_plus_12))
            self['total_heifer_' + str(i)] = total_cows

    @api.multi
    def act_button_update_fields(self):
        for report in self:
            report._set_milk_fields()
            report._set_total_cows_fields()
            report._set_employee_fields()
            report._set_total_heifer_fields()
        return True

    @api.one
    def refresh_values(self):
        field = 'val_%s' % str(1)
        for line in self.line_ids:
            companies = self._get_companies(1)
            line.value_1 = sum([line.get_value_1(x) for x in companies])
            companies = self._get_companies(2)
            line.value_2 = sum([line.get_value_2(x) for x in companies])

    @api.multi
    def act_cancel(self):
        self.write({'state': 'cancel'})

    @api.multi
    def act_done(self):
        self.write({'state': 'done'})

    @api.multi
    def calculate(self):
        self.write({
            'state': 'calc',
            'calc_date': time.strftime('%Y-%m-%d %H:%M:%S')
        })
        self.line_ids.unlink()
        for line in self.template_id.line_ids:
            self.env['account.analytic.report.line'].create({
                'report_id':
                self.id,
                'code':
                line.code,
                'sequence':
                line.sequence,
                'name':
                line.name,
                'notes':
                '',
                'template_line_id':
                line.id,
                'css_style':
                line.css_style
            })
        for line in self.line_ids:
            if line.template_line_id.parent_id:
                parent_line = self.env['account.analytic.report.line'].search([
                    ('template_line_id', '=',
                     line.template_line_id.parent_id.id),
                    ('report_id', '=', self.id)
                ])
                line.parent_id = parent_line
        self.refresh_values()
        self.state = 'calc_done'