Пример #1
0
class BaseModuleUninstall(models.TransientModel):
    _name = "base.module.uninstall"
    _description = "Module Uninstallation"

    show_all = fields.Boolean()
    module_id = fields.Many2one('ir.module.module',
                                string="Module",
                                required=True,
                                domain=[
                                    ('state', 'in',
                                     ['installed', 'to upgrade', 'to install'])
                                ])
    module_ids = fields.Many2many('ir.module.module',
                                  string="Impacted modules",
                                  compute='_compute_module_ids')
    model_ids = fields.Many2many('ir.model',
                                 string="Impacted data models",
                                 compute='_compute_model_ids')

    def _get_modules(self):
        """ Return all the modules impacted by self. """
        return self.module_id.downstream_dependencies(self.module_id)

    @api.depends('module_id', 'show_all')
    def _compute_module_ids(self):
        for wizard in self:
            modules = wizard._get_modules()
            wizard.module_ids = modules if wizard.show_all else modules.filtered(
                'application')

    def _get_models(self):
        """ Return the models (ir.model) to consider for the impact. """
        return self.env['ir.model'].search([('transient', '=', False)])

    @api.depends('module_ids')
    def _compute_model_ids(self):
        ir_models = self._get_models()
        ir_models_xids = ir_models._get_external_ids()
        for wizard in self:
            if wizard.module_id:
                module_names = set(wizard._get_modules().mapped('name'))

                # find the models that have all their XIDs in the given modules
                def lost(model):
                    return all(
                        xid.split('.')[0] in module_names
                        for xid in ir_models_xids.get(model.id, ()))

                self.model_ids = ir_models.filtered(lost).sorted('name')

    @api.onchange('module_id')
    def _onchange_module_id(self):
        # if we select a technical module, show technical modules by default
        if not self.module_id.application:
            self.show_all = True

    @api.multi
    def action_uninstall(self):
        modules = self.mapped('module_id')
        return modules.button_immediate_uninstall()
Пример #2
0
class GroupsImplied(models.Model):
    _inherit = 'res.groups'

    implied_ids = fields.Many2many('res.groups', 'res_groups_implied_rel', 'gid', 'hid',
        string='Inherits', help='Users of this group automatically inherit those groups')
    trans_implied_ids = fields.Many2many('res.groups', string='Transitively inherits',
        compute='_compute_trans_implied')

    @api.depends('implied_ids.trans_implied_ids')
    def _compute_trans_implied(self):
        # Compute the transitive closure recursively. Note that the performance
        # is good, because the record cache behaves as a memo (the field is
        # never computed twice on a given group.)
        for g in self:
            g.trans_implied_ids = g.implied_ids | g.mapped('implied_ids.trans_implied_ids')

    @api.model
    def create(self, values):
        user_ids = values.pop('users', None)
        group = super(GroupsImplied, self).create(values)
        if user_ids:
            # delegate addition of users to add implied groups
            group.write({'users': user_ids})
        return group

    @api.multi
    def write(self, values):
        res = super(GroupsImplied, self).write(values)
        if values.get('users') or values.get('implied_ids'):
            # add all implied groups (to all users of each group)
            for group in self:
                vals = {'users': list(pycompat.izip(repeat(4), group.with_context(active_test=False).users.ids))}
                super(GroupsImplied, group.trans_implied_ids).write(vals)
        return res
Пример #3
0
class Discussion(models.Model):
    _name = 'test_new_api.discussion'

    name = fields.Char(
        string='Title',
        required=True,
        help="General description of what this discussion is about.")
    moderator = fields.Many2one('res.users')
    categories = fields.Many2many('test_new_api.category',
                                  'test_new_api_discussion_category',
                                  'discussion', 'category')
    participants = fields.Many2many('res.users')
    messages = fields.One2many('test_new_api.message', 'discussion')
    message_concat = fields.Text(string='Message concatenate')
    important_messages = fields.One2many('test_new_api.message',
                                         'discussion',
                                         domain=[('important', '=', True)])
    very_important_messages = fields.One2many(
        'test_new_api.message',
        'discussion',
        domain=lambda self: self._domain_very_important())
    emails = fields.One2many('test_new_api.emailmessage', 'discussion')
    important_emails = fields.One2many('test_new_api.emailmessage',
                                       'discussion',
                                       domain=[('important', '=', True)])

    def _domain_very_important(self):
        """Ensure computed O2M domains work as expected."""
        return [("important", "=", True)]

    @api.onchange('name')
    def _onchange_name(self):
        # test onchange modifying one2many field values
        if self.env.context.get('generate_dummy_message'
                                ) and self.name == '{generate_dummy_message}':
            # update body of existings messages and emails
            for message in self.messages:
                message.body = 'not last dummy message'
            for message in self.important_messages:
                message.body = 'not last dummy message'
            # add new dummy message
            message_vals = self.messages._add_missing_default_values({
                'body':
                'dummy message',
                'important':
                True
            })
            self.messages |= self.messages.new(message_vals)
            self.important_messages |= self.messages.new(message_vals)

    @api.onchange('moderator')
    def _onchange_moderator(self):
        self.participants |= self.moderator

    @api.onchange('messages')
    def _onchange_messages(self):
        self.message_concat = "\n".join(
            ["%s:%s" % (m.name, m.body) for m in self.messages])
Пример #4
0
class account_financial_report(models.Model):
    _name = "account.financial.report"
    _description = "Account Report"

    @api.multi
    @api.depends('parent_id', 'parent_id.level')
    def _get_level(self):
        '''Returns a dictionary with key=the ID of a record and value = the level of this  
           record in the tree structure.'''
        for report in self:
            level = 0
            if report.parent_id:
                level = report.parent_id.level + 1
            report.level = level

    def _get_children_by_order(self):
        '''returns a recordset of all the children computed recursively, and sorted by sequence. Ready for the printing'''
        res = self
        children = self.search([('parent_id', 'in', self.ids)], order='sequence ASC')
        if children:
            for child in children:
                res += child._get_children_by_order()
        return res

    name = fields.Char('Report Name', required=True, translate=True)
    parent_id = fields.Many2one('account.financial.report', 'Parent')
    children_ids = fields.One2many('account.financial.report', 'parent_id', 'Account Report')
    sequence = fields.Integer('Sequence')
    level = fields.Integer(compute='_get_level', string='Level', store=True)
    type = fields.Selection([
        ('sum', 'View'),
        ('accounts', 'Accounts'),
        ('account_type', 'Account Type'),
        ('account_report', 'Report Value'),
        ], 'Type', default='sum')
    account_ids = fields.Many2many('account.account', 'account_account_financial_report', 'report_line_id', 'account_id', 'Accounts')
    account_report_id = fields.Many2one('account.financial.report', 'Report Value')
    account_type_ids = fields.Many2many('account.account.type', 'account_account_financial_report_type', 'report_id', 'account_type_id', 'Account Types')
    sign = fields.Selection([(-1, 'Reverse balance sign'), (1, 'Preserve balance sign')], 'Sign on Reports', required=True, default=1,
                            help='For accounts that are typically more debited than credited and that you would like to print as negative amounts in your reports, you should reverse the sign of the balance; e.g.: Expense account. The same applies for accounts that are typically more credited than debited and that you would like to print as positive amounts in your reports; e.g.: Income account.')
    display_detail = fields.Selection([
        ('no_detail', 'No detail'),
        ('detail_flat', 'Display children flat'),
        ('detail_with_hierarchy', 'Display children with hierarchy')
        ], 'Display details', default='detail_flat')
    style_overwrite = fields.Selection([
        (0, 'Automatic formatting'),
        (1, 'Main Title 1 (bold, underlined)'),
        (2, 'Title 2 (bold)'),
        (3, 'Title 3 (bold, smaller)'),
        (4, 'Normal Text'),
        (5, 'Italic Text (smaller)'),
        (6, 'Smallest Text'),
        ], 'Financial Report Style', default=0,
        help="You can set up here the format you want this record to be displayed. If you leave the automatic formatting, it will be computed based on the financial reports hierarchy (auto-computed field 'level').")
Пример #5
0
class StockAgeingWizard(models.TransientModel):

    _name = 'stock.ageing.wizard'
    _description = 'Wizard that opens the stock ageing'

    company_id = fields.Many2one('res.company',
                                 string="Company",
                                 default=lambda self: self.env.user.company_id)
    branch_id = fields.Many2one(
        'res.branch',
        string="Branch",
        default=lambda self: self.env.user.default_branch_id)
    warehouse_ids = fields.Many2many("stock.warehouse", string="Warehouse")
    location_ids = fields.Many2many("stock.location",
                                    string='Location',
                                    domain="[('usage', '=', 'internal')]")
    product_category_ids = fields.Many2many("product.category",
                                            string="Product Category")
    product_ids = fields.Many2many('product.product',
                                   string='Product',
                                   domain="[('type', '=', 'product')]")
    period_length = fields.Integer(string='Period Length (days)', default=30)
    date = fields.Datetime(string="Date",
                           help="Choose a date to get the inventory ageing "
                           "report",
                           default=fields.Datetime.now())

    @api.multi
    def print_report(self):
        """
        To get the Stock Ageing report and print the report
        @return : return stock ageing report
        """
        datas = {'ids': self._context.get('active_ids', [])}
        res = self.read([
            'company_id', 'branch_id', 'warehouse_ids', 'location_ids',
            'product_category_ids', 'product_ids', 'period_length', 'date'
        ])
        for ageing_dict in res:
            res = res and res[0] or {}
            res['company_id'] = ageing_dict['company_id'] and\
                ageing_dict['company_id'][0] or False
            res['branch_id'] = ageing_dict['branch_id'] and \
                ageing_dict['branch_id'][0] or False
            res['warehouse_id'] = ageing_dict['warehouse_ids']
            res['location_id'] = ageing_dict['location_ids']
            res['product_category_id'] = ageing_dict['product_category_ids']
            res['product_id'] = ageing_dict['product_ids']
            res['period_length'] = ageing_dict['period_length'] or False
            res['date'] = ageing_dict['date'] or False
            datas['form'] = res
            return self.env.ref(
                'stock_ageing_report.action_stock_ageing_report'
                '').report_action(self, data=datas)
Пример #6
0
class WizIndentLine(models.TransientModel):
    _name = 'wiz.indent.line'
    _description = "Wizard Indent Line"

    @api.depends('purchase_indent_line_id',
                 'purchase_indent_line_id.product_qty',
                 'purchase_indent_line_id.requisition_qty')
    @api.multi
    def _compute_get_rem_qty(self):
        for line_id in self:
            remaining_qty = 0.0
            if line_id.purchase_indent_line_id:
                remaining_qty = \
                    line_id.purchase_indent_line_id.product_qty - \
                    line_id.purchase_indent_line_id.requisition_qty
            line_id.remaining_qty = remaining_qty

    purchase_indent_ids = fields.Many2many('purchase.indent',
                                           string='Purchase Indent')
    name = fields.Text(string='Description', required=True)
    sequence = fields.Integer(string='Sequence', default=10)
    product_qty = fields.Float(string='Quantity',
                               digits=dp.get_precision('Discount'))
    expected_date = fields.Datetime(string='Expected Date', index=True)
    product_uom = fields.Many2one('product.uom',
                                  string='Product Unit of Measure')
    product_id = fields.Many2one('product.product',
                                 string='Product',
                                 domain=[('purchase_ok', '=', True)],
                                 change_default=True,
                                 required=True)
    requisition_qty = fields.Float(string="Requisition Quantity",
                                   digits=dp.get_precision('Discount'))
    wizard_indent_id = fields.Many2one('wiz.requisition.request',
                                       'Wiz Requisition Request')

    partner_id = fields.Many2one('res.partner', string='Partner')
    price_unit = fields.Float(string='Unit Price',
                              digits=dp.get_precision('Product Price'))
    taxes_id = fields.Many2many(
        'account.tax',
        string='Taxes',
        domain=['|', ('active', '=', False), ('active', '=', True)])
    purchase_indent_line_id = fields.Many2one('purchase.indent.line',
                                              string="Indent Line Ref")
    remaining_qty = fields.Float(compute='_compute_get_rem_qty',
                                 string='Remaining Quantity',
                                 store=True)
    order_type = fields.Selection(related='wizard_indent_id.order_type',
                                  string='Order Type')
Пример #7
0
class MultiLine(models.Model):
    _name = 'test_new_api.multi.line'

    multi = fields.Many2one('test_new_api.multi', ondelete='cascade')
    name = fields.Char()
    partner = fields.Many2one('res.partner')
    tags = fields.Many2many('test_new_api.multi.tag')
Пример #8
0
class BaseLanguageExport(models.TransientModel):
    _name = "base.language.export"

    @api.model
    def _get_languages(self):
        langs = self.env['res.lang'].search([('translatable', '=', True)])
        return [(NEW_LANG_KEY, _('New Language (Empty translation template)'))] + \
               [(lang.code, lang.name) for lang in langs]

    name = fields.Char('File Name', readonly=True)
    lang = fields.Selection(_get_languages,
                            string='Language',
                            required=True,
                            default=NEW_LANG_KEY)
    format = fields.Selection([('csv', 'CSV File'), ('po', 'PO File'),
                               ('tgz', 'TGZ Archive')],
                              string='File Format',
                              required=True,
                              default='csv')
    modules = fields.Many2many('ir.module.module',
                               'rel_modules_langexport',
                               'wiz_id',
                               'module_id',
                               string='Apps To Export',
                               domain=[('state', '=', 'installed')])
    data = fields.Binary('File', readonly=True)
    state = fields.Selection(
        [('choose', 'choose'),
         ('get', 'get')],  # choose language or get the file
        default='choose')

    @api.multi
    def act_getfile(self):
        this = self[0]
        lang = this.lang if this.lang != NEW_LANG_KEY else False
        mods = sorted(this.mapped('modules.name')) or ['all']

        with contextlib.closing(io.BytesIO()) as buf:
            tools.trans_export(lang, mods, buf, this.format, self._cr)
            out = base64.encodestring(buf.getvalue())

        filename = 'new'
        if lang:
            filename = tools.get_iso_codes(lang)
        elif len(mods) == 1:
            filename = mods[0]
        extension = this.format
        if not lang and extension == 'po':
            extension = 'pot'
        name = "%s.%s" % (filename, extension)
        this.write({'state': 'get', 'data': out, 'name': name})
        return {
            'type': 'ir.actions.act_window',
            'res_model': 'base.language.export',
            'view_mode': 'form',
            'view_type': 'form',
            'res_id': this.id,
            'views': [(False, 'form')],
            'target': 'new',
        }
Пример #9
0
class BaseLanguageInstall(models.TransientModel):

    _inherit = "base.language.install"

    website_ids = fields.Many2many('website', string='Websites to translate')

    @api.model
    def default_get(self, fields):
        defaults = super(BaseLanguageInstall, self).default_get(fields)
        website_id = self._context.get('params', {}).get('website_id')
        if website_id:
            if 'website_ids' not in defaults:
                defaults['website_ids'] = []
            defaults['website_ids'].append(website_id)
        return defaults

    @api.multi
    def lang_install(self):
        action = super(BaseLanguageInstall, self).lang_install()
        lang = self.env['res.lang'].search([('code', '=', self.lang)], limit=1)
        if self.website_ids and lang:
            self.website_ids.write({'language_ids': [(4, lang.id)]})
        params = self._context.get('params', {})
        if 'url_return' in params:
            return {
                'url': params['url_return'].replace('[lang]', self.lang),
                'type': 'ir.actions.act_url',
                'target': 'self'
            }
        return action
Пример #10
0
class Tags(models.Model):
    _name = "forum.tag"
    _description = "Forum Tag"
    _inherit = ['mail.thread', 'website.seo.metadata']

    name = fields.Char('Name', required=True)
    create_uid = fields.Many2one('res.users', string='Created by', readonly=True)
    forum_id = fields.Many2one('forum.forum', string='Forum', required=True)
    post_ids = fields.Many2many(
        'forum.post', 'forum_tag_rel', 'forum_tag_id', 'forum_id',
        string='Posts', domain=[('state', '=', 'active')])
    posts_count = fields.Integer('Number of Posts', compute='_get_posts_count', store=True)

    _sql_constraints = [
        ('name_uniq', 'unique (name, forum_id)', "Tag name already exists !"),
    ]

    @api.multi
    @api.depends("post_ids.tag_ids", "post_ids.state")
    def _get_posts_count(self):
        for tag in self:
            tag.posts_count = len(tag.post_ids)

    @api.model
    def create(self, vals):
        forum = self.env['forum.forum'].browse(vals.get('forum_id'))
        if self.env.user.karma < forum.karma_tag_create:
            raise KarmaError(_('Not enough karma to create a new Tag'))
        return super(Tags, self.with_context(mail_create_nolog=True, mail_create_nosubscribe=True)).create(vals)
class AccountReportGeneralLedger(models.TransientModel):
    _inherit = "account.common.account.report"
    _name = "account.report.general.ledger"
    _description = "General Ledger Report"

    initial_balance = fields.Boolean(
        string='Include Initial Balances',
        help=
        'If you selected date, this field allow you to add a row to display the amount of debit/credit/balance that precedes the filter you\'ve set.'
    )
    sortby = fields.Selection([('sort_date', 'Date'),
                               ('sort_journal_partner', 'Journal & Partner')],
                              string='Sort by',
                              required=True,
                              default='sort_date')
    journal_ids = fields.Many2many('account.journal',
                                   'account_report_general_ledger_journal_rel',
                                   'account_id',
                                   'journal_id',
                                   string='Journals',
                                   required=True)

    def _print_report(self, data):
        data = self.pre_print_report(data)
        data['form'].update(self.read(['initial_balance', 'sortby'])[0])
        if data['form'].get(
                'initial_balance') and not data['form'].get('date_from'):
            raise UserError(_("You must define a Start Date"))
        records = self.env[data['model']].browse(data.get('ids', []))
        return self.env.ref(
            'account.action_report_general_ledger').with_context(
                landscape=True).report_action(records, data=data)
Пример #12
0
class AccountInvoiceLine(models.Model):
    _inherit = 'account.invoice.line'
    _order = 'invoice_id, layout_category_id, sequence, id'

    @api.depends('price_unit', 'discount', 'invoice_line_tax_ids', 'quantity',
                 'product_id', 'invoice_id.partner_id',
                 'invoice_id.currency_id', 'invoice_id.company_id',
                 'invoice_id.date_invoice')
    def _compute_total_price(self):
        for line in self:
            price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
            taxes = line.invoice_line_tax_ids.compute_all(
                price,
                line.invoice_id.currency_id,
                line.quantity,
                product=line.product_id,
                partner=line.invoice_id.partner_id)
            line.price_total = taxes['total_included']

    sale_line_ids = fields.Many2many('sale.order.line',
                                     'sale_order_line_invoice_rel',
                                     'invoice_line_id',
                                     'order_line_id',
                                     string='Sales Order Lines',
                                     readonly=True,
                                     copy=False)
    layout_category_id = fields.Many2one('sale.layout_category',
                                         string='Section')
    layout_category_sequence = fields.Integer(string='Layout Sequence')
    # TODO: remove layout_category_sequence in master or make it work properly
    price_total = fields.Monetary(compute='_compute_total_price',
                                  string='Total Amount',
                                  store=True)
Пример #13
0
class StockImmediateTransfer(models.TransientModel):
    _name = 'stock.immediate.transfer'
    _description = 'Immediate Transfer'

    pick_ids = fields.Many2many('stock.picking', 'stock_picking_transfer_rel')

    def process(self):
        pick_to_backorder = self.env['stock.picking']
        pick_to_do = self.env['stock.picking']
        for picking in self.pick_ids:
            # If still in draft => confirm and assign
            if picking.state == 'draft':
                picking.action_confirm()
                if picking.state != 'assigned':
                    picking.action_assign()
                    if picking.state != 'assigned':
                        raise UserError(
                            _("Could not reserve all requested products. Please use the \'Mark as Todo\' button to handle the reservation manually."
                              ))
            for move in picking.move_lines:
                for move_line in move.move_line_ids:
                    move_line.qty_done = move_line.product_uom_qty
            if picking._check_backorder():
                pick_to_backorder |= picking
                continue
            pick_to_do |= picking
        # Process every picking that do not require a backorder, then return a single backorder wizard for every other ones.
        if pick_to_do:
            pick_to_do.action_done()
        if pick_to_backorder:
            return pick_to_backorder.action_generate_backorder_wizard()
        return False
Пример #14
0
class WebsiteResPartner(models.Model):
    _name = 'res.partner'
    _inherit = [
        'res.partner', 'website.seo.metadata', 'website.published.mixin'
    ]

    def _default_website(self):
        default_website_id = self.env.ref('website.default_website')
        return [default_website_id.id] if default_website_id else None

    website_description = fields.Html('Website Partner Full Description',
                                      strip_style=True)
    website_short_description = fields.Text(
        'Website Partner Short Description')
    website_ids = fields.Many2many('website',
                                   'website_partner_pub_rel',
                                   'website_id',
                                   'partner_id',
                                   string='Websites',
                                   copy=False,
                                   default=_default_website,
                                   help='List of websites in which '
                                   'Partner will published.')

    @api.multi
    def _compute_website_url(self):
        super(WebsiteResPartner, self)._compute_website_url()
        for partner in self:
            partner.website_url = "/partners/%s" % slug(partner)
class HolidaysSummaryEmployee(models.TransientModel):

    _name = 'hr.holidays.summary.employee'
    _description = 'HR Leaves Summary Report By Employee'

    date_from = fields.Date(string='From',
                            required=True,
                            default=lambda *a: time.strftime('%Y-%m-01'))
    emp = fields.Many2many('hr.employee',
                           'summary_emp_rel',
                           'sum_id',
                           'emp_id',
                           string='Employee(s)')
    holiday_type = fields.Selection([('Approved', 'Approved'),
                                     ('Confirmed', 'Confirmed'),
                                     ('both', 'Both Approved and Confirmed')],
                                    string='Select Leave Type',
                                    required=True,
                                    default='Approved')

    @api.multi
    def print_report(self):
        self.ensure_one()
        [data] = self.read()
        data['emp'] = self.env.context.get('active_ids', [])
        employees = self.env['hr.employee'].browse(data['emp'])
        datas = {'ids': [], 'model': 'hr.employee', 'form': data}
        return self.env.ref(
            'hr_holidays.action_report_holidayssummary').report_action(
                employees, data=datas)
Пример #16
0
class MaintenanceTeam(models.Model):
    _name = 'maintenance.team'
    _description = 'Maintenance Teams'

    name = fields.Char(required=True, translate=True)
    member_ids = fields.Many2many('res.users', 'maintenance_team_users_rel', string="Team Members")
    color = fields.Integer("Color Index", default=0)
    request_ids = fields.One2many('maintenance.request', 'maintenance_team_id', copy=False)
    equipment_ids = fields.One2many('maintenance.equipment', 'maintenance_team_id', copy=False)

    # For the dashboard only
    todo_request_ids = fields.One2many('maintenance.request', string="Requests", copy=False, compute='_compute_todo_requests')
    todo_request_count = fields.Integer(string="Number of Requests", compute='_compute_todo_requests')
    todo_request_count_date = fields.Integer(string="Number of Requests Scheduled", compute='_compute_todo_requests')
    todo_request_count_high_priority = fields.Integer(string="Number of Requests in High Priority", compute='_compute_todo_requests')
    todo_request_count_block = fields.Integer(string="Number of Requests Blocked", compute='_compute_todo_requests')
    todo_request_count_unscheduled = fields.Integer(string="Number of Requests Unscheduled", compute='_compute_todo_requests')

    @api.one
    @api.depends('request_ids.stage_id.done')
    def _compute_todo_requests(self):
        self.todo_request_ids = self.request_ids.filtered(lambda e: e.stage_id.done==False)
        self.todo_request_count = len(self.todo_request_ids)
        self.todo_request_count_date = len(self.todo_request_ids.filtered(lambda e: e.schedule_date != False))
        self.todo_request_count_high_priority = len(self.todo_request_ids.filtered(lambda e: e.priority == '3'))
        self.todo_request_count_block = len(self.todo_request_ids.filtered(lambda e: e.kanban_state == 'blocked'))
        self.todo_request_count_unscheduled = len(self.todo_request_ids.filtered(lambda e: not e.schedule_date))

    @api.one
    @api.depends('equipment_ids')
    def _compute_equipment(self):
        self.equipment_count = len(self.equipment_ids)
Пример #17
0
class ProductAttributevalue(models.Model):
    _name = "product.attribute.value"
    _order = 'sequence, attribute_id, id'

    name = fields.Char('Value', required=True, translate=True)
    sequence = fields.Integer('Sequence', help="Determine the display order")
    attribute_id = fields.Many2one('product.attribute', 'Attribute', ondelete='cascade', required=True)
    product_ids = fields.Many2many('product.product', string='Variants', readonly=True)
    price_extra = fields.Float(
        'Attribute Price Extra', compute='_compute_price_extra', inverse='_set_price_extra',
        default=0.0, digits=dp.get_precision('Product Price'),
        help="Price Extra: Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.")
    price_ids = fields.One2many('product.attribute.price', 'value_id', 'Attribute Prices', readonly=True)

    _sql_constraints = [
        ('value_company_uniq', 'unique (name,attribute_id)', 'This attribute value already exists !')
    ]

    @api.one
    def _compute_price_extra(self):
        if self._context.get('active_id'):
            price = self.price_ids.filtered(lambda price: price.product_tmpl_id.id == self._context['active_id'])
            self.price_extra = price.price_extra
        else:
            self.price_extra = 0.0

    def _set_price_extra(self):
        if not self._context.get('active_id'):
            return

        AttributePrice = self.env['product.attribute.price']
        prices = AttributePrice.search([('value_id', 'in', self.ids), ('product_tmpl_id', '=', self._context['active_id'])])
        updated = prices.mapped('value_id')
        if prices:
            prices.write({'price_extra': self.price_extra})
        else:
            for value in self - updated:
                AttributePrice.create({
                    'product_tmpl_id': self._context['active_id'],
                    'value_id': value.id,
                    'price_extra': self.price_extra,
                })

    @api.multi
    def name_get(self):
        if not self._context.get('show_attribute', True):  # TDE FIXME: not used
            return super(ProductAttributevalue, self).name_get()
        return [(value.id, "%s: %s" % (value.attribute_id.name, value.name)) for value in self]

    @api.multi
    def unlink(self):
        linked_products = self.env['product.product'].with_context(active_test=False).search([('attribute_value_ids', 'in', self.ids)])
        if linked_products:
            raise UserError(_('The operation cannot be completed:\nYou are trying to delete an attribute value with a reference on a product variant.'))
        return super(ProductAttributevalue, self).unlink()

    @api.multi
    def _variant_name(self, variable_attributes):
        return ", ".join([v.name for v in self if v.attribute_id in variable_attributes])
Пример #18
0
class ResCountryGroup(models.Model):
    _inherit = 'res.country.group'

    pricelist_ids = fields.Many2many('product.pricelist',
                                     'res_country_group_pricelist_rel',
                                     'res_country_group_id',
                                     'pricelist_id',
                                     string='Pricelists')
Пример #19
0
class Partner(models.Model):

    _inherit = 'res.partner'

    website_tag_ids = fields.Many2many('res.partner.tag',
                                       'res_partner_res_partner_tag_rel',
                                       'partner_id',
                                       'tag_id',
                                       string='Website tags')
Пример #20
0
class RepairFee(models.Model):
    _name = 'mrp.repair.fee'
    _description = 'Repair Fees Line'

    repair_id = fields.Many2one(
        'mrp.repair', 'Repair Order Reference',
        index=True, ondelete='cascade', required=True)
    name = fields.Char('Description', index=True, required=True)
    product_id = fields.Many2one('product.product', 'Product')
    product_uom_qty = fields.Float('Quantity', digits=dp.get_precision('Product Unit of Measure'), required=True, default=1.0)
    price_unit = fields.Float('Unit Price', required=True)
    product_uom = fields.Many2one('product.uom', 'Product Unit of Measure', required=True)
    price_subtotal = fields.Float('Subtotal', compute='_compute_price_subtotal', digits=0)
    tax_id = fields.Many2many('account.tax', 'repair_fee_line_tax', 'repair_fee_line_id', 'tax_id', 'Taxes')
    invoice_line_id = fields.Many2one('account.invoice.line', 'Invoice Line', copy=False, readonly=True)
    invoiced = fields.Boolean('Invoiced', copy=False, readonly=True)

    @api.one
    @api.depends('price_unit', 'repair_id', 'product_uom_qty', 'product_id')
    def _compute_price_subtotal(self):
        taxes = self.tax_id.compute_all(self.price_unit, self.repair_id.pricelist_id.currency_id, self.product_uom_qty, self.product_id, self.repair_id.partner_id)
        self.price_subtotal = taxes['total_excluded']

    @api.onchange('repair_id', 'product_id', 'product_uom_qty')
    def onchange_product_id(self):
        """ On change of product it sets product quantity, tax account, name,
        uom of product, unit price and price subtotal. """
        if not self.product_id:
            return

        partner = self.repair_id.partner_id
        pricelist = self.repair_id.pricelist_id

        if partner and self.product_id:
            self.tax_id = partner.property_account_position_id.map_tax(self.product_id.taxes_id, self.product_id, partner).ids
        if self.product_id:
            self.name = self.product_id.display_name
            self.product_uom = self.product_id.uom_id.id

        warning = False
        if not pricelist:
            warning = {
                'title': _('No Pricelist!'),
                'message':
                    _('You have to select a pricelist in the Repair form !\n Please set one before choosing a product.')}
        else:
            price = pricelist.get_product_price(self.product_id, self.product_uom_qty, partner)
            if price is False:
                warning = {
                    'title': _('No valid pricelist line found !'),
                    'message':
                        _("Couldn't find a pricelist line matching this product and quantity.\nYou have to change either the product, the quantity or the pricelist.")}
            else:
                self.price_unit = price
        if warning:
            return {'warning': warning}
Пример #21
0
class CountryGroup(models.Model):
    _description = "Country Group"
    _name = 'res.country.group'

    name = fields.Char(required=True, translate=True)
    country_ids = fields.Many2many('res.country',
                                   'res_country_res_country_group_rel',
                                   'res_country_group_id',
                                   'res_country_id',
                                   string='Countries')
Пример #22
0
class PurchaseRequisitionLine(models.Model):
    _inherit = 'purchase.requisition.line'

    purchase_indent_line_id = fields.Many2one('purchase.indent.line',
                                              'Purchase Indent Line Ref')
    purchase_indent_ids = fields.Many2many('purchase.indent',
                                           string='Purchase Indent')
    branch_id = fields.Many2one(related='requisition_id.branch_id',
                                string='Branch',
                                store=True)
Пример #23
0
class Users(models.Model):

    _inherit = "res.users"

    @api.model
    def branch_default_get(self, user):
        if not user:
            user = self._uid
        branch_id = self.env['res.users'].browse(user).default_branch_id
        if not branch_id:
            branch_id = \
                self.env['res.users'].browse(user).company_id.branch_id
        return branch_id

    @api.model
    def _get_branch(self):
        return self.env.user.default_branch_id

    @api.model
    def _get_default_branch(self):
        return self.branch_default_get(self._uid)

    def _branches_count(self):
        return self.env['res.branch'].sudo().search_count([])

    branch_ids = fields.Many2many('res.branch',
                                  'res_branch_users_rel',
                                  'user_id',
                                  'branch_id',
                                  'Branches', default=_get_branch,
                                  domain="[('company_id','=',company_id)]")
    default_branch_id = fields.Many2one('res.branch', 'Default branch',
                                        default=_get_branch,
                                        domain="[('company_id','=',company_id)"
                                               "]")
    branches_count = fields.Integer(
        compute='_compute_branches_count',
        string="Number of Companies", default=_branches_count)

    # To do : Check with all base module test cases
    # @api.multi
    # @api.constrains('default_branch_id', 'branch_ids')
    # def _check_branches(self):
    #     for user in self:
    #         if user.branch_ids \
    #                 and user.default_branch_id not in user.branch_ids:
    #             raise ValidationError(_('The selected Default Branch (%s) '
    #                                     'is not in the Branches!') % (
    #                 user.default_branch_id.name))

    @api.multi
    def _compute_branches_count(self):
        branches_count = self._branches_count()
        for user in self:
            user.branches_count = branches_count
Пример #24
0
class MailActivityType(models.Model):
    """ Activity Types are used to categorize activities. Each type is a different
    kind of activity e.g. call, mail, meeting. An activity can be generic i.e.
    available for all models using activities; or specific to a model in which
    case res_model_id field should be used. """
    _name = 'mail.activity.type'
    _description = 'Activity Type'
    _rec_name = 'name'
    _order = 'sequence, id'

    name = fields.Char('Name', required=True, translate=True)
    summary = fields.Char('Summary', translate=True)
    sequence = fields.Integer('Sequence', default=10)
    days = fields.Integer(
        '# Days',
        default=0,
        help=
        'Number of days before executing the action. It allows to plan the action deadline.'
    )
    icon = fields.Char('Icon', help="Font awesome icon e.g. fa-tasks")
    res_model_id = fields.Many2one(
        'ir.model',
        'Model',
        index=True,
        help='Specify a model if the activity should be specific to a model'
        ' and not available when managing activities for other models.')
    next_type_ids = fields.Many2many('mail.activity.type',
                                     'mail_activity_rel',
                                     'activity_id',
                                     'recommended_id',
                                     string='Recommended Next Activities')
    previous_type_ids = fields.Many2many('mail.activity.type',
                                         'mail_activity_rel',
                                         'recommended_id',
                                         'activity_id',
                                         string='Preceding Activities')
    category = fields.Selection(
        [('default', 'Other')],
        default='default',
        string='Category',
        help=
        'Categories may trigger specific behavior like opening calendar view')
Пример #25
0
class PosConfig(models.Model):
    _inherit = 'pos.config'

    iface_splitbill = fields.Boolean(
        string='Bill Splitting',
        help='Enables Bill Splitting in the Point of Sale.')
    iface_printbill = fields.Boolean(
        string='Bill Printing',
        help='Allows to print the Bill before payment.')
    iface_orderline_notes = fields.Boolean(
        string='Orderline Notes', help='Allow custom notes on Orderlines.')
    floor_ids = fields.One2many(
        'restaurant.floor',
        'pos_config_id',
        string='Restaurant Floors',
        help='The restaurant floors served by this point of sale.')
    printer_ids = fields.Many2many('restaurant.printer',
                                   'pos_config_printer_rel',
                                   'config_id',
                                   'printer_id',
                                   string='Order Printers')
    is_table_management = fields.Boolean('Table Management')
    is_order_printer = fields.Boolean('Order Printers')
    module_pos_restaurant = fields.Boolean(default=True)

    @api.onchange('iface_tipproduct')
    def _onchange_tipproduct(self):
        if self.iface_tipproduct:
            self.tip_product_id = self.env.ref(
                'point_of_sale.product_product_tip', False)
        else:
            self.tip_product_id = False

    @api.onchange('module_pos_restaurant')
    def _onchange_module_pos_restaurant(self):
        if not self.module_pos_restaurant:
            self.update({
                'iface_printbill': False,
                'iface_splitbill': False,
                'iface_tipproduct': False,
                'is_order_printer': False,
                'is_table_management': False,
                'iface_orderline_notes': False
            })

    @api.onchange('is_table_management')
    def _onchange_is_table_management(self):
        if not self.is_table_management:
            self.floor_ids = [(5, 0, 0)]

    @api.onchange('is_order_printer')
    def _onchange_is_order_printer(self):
        if not self.is_order_printer:
            self.printer_ids = [(5, 0, 0)]
Пример #26
0
class BlogTag(models.Model):
    _name = 'blog.tag'
    _description = 'Blog Tag'
    _inherit = ['website.seo.metadata']
    _order = 'name'

    name = fields.Char('Name', required=True, translate=True)
    post_ids = fields.Many2many('blog.post', string='Posts')

    _sql_constraints = [
        ('name_uniq', 'unique (name)', "Tag name already exists !"),
    ]
Пример #27
0
class AccountCommonReport(models.TransientModel):
    _name = "account.common.report"
    _description = "Account Common Report"
    _inherit = ['ir.branch.company.mixin']

    company_id = fields.Many2one('res.company',
                                 string='Company',
                                 readonly=True,
                                 default=lambda self: self.env.user.company_id)
    journal_ids = fields.Many2many(
        'account.journal',
        string='Journals',
        required=True,
        default=lambda self: self.env['account.journal'].search([]))
    date_from = fields.Date(string='Start Date')
    date_to = fields.Date(string='End Date')
    target_move = fields.Selection([
        ('posted', 'All Posted Entries'),
        ('all', 'All Entries'),
    ],
                                   string='Target Moves',
                                   required=True,
                                   default='posted')

    def _build_contexts(self, data):
        result = {}
        result['journal_ids'] = 'journal_ids' in data['form'] and data['form'][
            'journal_ids'] or False
        result['state'] = 'target_move' in data['form'] and data['form'][
            'target_move'] or ''
        result['date_from'] = data['form']['date_from'] or False
        result['date_to'] = data['form']['date_to'] or False
        result['branch_id'] = data['form']['branch_id'] or False
        result['strict_range'] = True if result['date_from'] else False
        return result

    def _print_report(self, data):
        raise NotImplementedError()

    @api.multi
    def check_report(self):
        self.ensure_one()
        data = {}
        data['ids'] = self.env.context.get('active_ids', [])
        data['model'] = self.env.context.get('active_model', 'ir.ui.menu')
        data['form'] = self.read([
            'date_from', 'date_to', 'journal_ids', 'target_move', 'branch_id'
        ])[0]
        used_context = self._build_contexts(data)
        data['form']['used_context'] = dict(used_context,
                                            lang=self.env.context.get('lang')
                                            or 'en_US')
        return self._print_report(data)
Пример #28
0
class ProductTemplate(models.Model):
    _inherit = "product.template"

    optional_product_ids = fields.Many2many(
        'product.template',
        'product_optional_rel',
        'src_id',
        'dest_id',
        string='Optional Products',
        help="Optional Products are suggested "
        "whenever the customer hits *Add to Cart* (cross-sell strategy, "
        "e.g. for computers: warranty, software, etc.).")
Пример #29
0
class ProductCategory(models.Model):
    _inherit = 'product.category'

    route_ids = fields.Many2many(
        'stock.location.route', 'stock_location_route_categ', 'categ_id', 'route_id', 'Routes',
        domain=[('product_categ_selectable', '=', True)])
    removal_strategy_id = fields.Many2one(
        'product.removal', 'Force Removal Strategy',
        help="Set a specific removal strategy that will be used regardless of the source location for this product category")
    total_route_ids = fields.Many2many(
        'stock.location.route', string='Total routes', compute='_compute_total_route_ids',
        readonly=True)

    @api.one
    def _compute_total_route_ids(self):
        category = self
        routes = self.route_ids
        while category.parent_id:
            category = category.parent_id
            routes |= category.route_ids
        self.total_route_ids = routes
Пример #30
0
class TrackTag(models.Model):
    _name = "event.track.tag"
    _description = 'Track Tag'
    _order = 'name'

    name = fields.Char('Tag')
    track_ids = fields.Many2many('event.track', string='Tracks')
    color = fields.Integer(string='Color Index', default=10)

    _sql_constraints = [
        ('name_uniq', 'unique (name)', "Tag name already exists !"),
    ]