Пример #1
0
class AccountTaxTemplatePython(models.Model):
    _inherit = 'account.tax.template'

    amount_type = fields.Selection(selection_add=[('code', 'Python Code')])

    python_compute = fields.Text(
        string='Python Code',
        default="result = price_unit * 0.10",
        help=
        "Compute the amount of the tax by setting the variable 'result'.\n\n"
        ":param base_amount: float, actual amount on which the tax is applied\n"
        ":param price_unit: float\n"
        ":param quantity: float\n"
        ":param product: product.product recordset singleton or None\n"
        ":param partner: res.partner recordset singleton or None")
    python_applicable = fields.Text(
        string='Applicable Code',
        default="result = True",
        help=
        "Determine if the tax will be applied by setting the variable 'result' to True or False.\n\n"
        ":param price_unit: float\n"
        ":param quantity: float\n"
        ":param product: product.product recordset singleton or None\n"
        ":param partner: res.partner recordset singleton or None")

    def _get_tax_vals(self, company, tax_template_to_tax):
        """ This method generates a dictionnary of all the values for the tax that will be created.
        """
        self.ensure_one()
        res = super(AccountTaxTemplatePython,
                    self)._get_tax_vals(company, tax_template_to_tax)
        res['python_compute'] = self.python_compute
        res['python_applicable'] = self.python_applicable
        return res
Пример #2
0
class res_company(models.Model):
    _inherit = "res.company"

    gengo_private_key = fields.Char(string="Gengo Private Key",
                                    copy=False,
                                    groups="base.group_system")
    gengo_public_key = fields.Text(string="Gengo Public Key",
                                   copy=False,
                                   groups="base.group_user")
    gengo_comment = fields.Text(
        string="Comments",
        groups="base.group_user",
        help=
        "This comment will be automatically be enclosed in each an every request sent to Gengo"
    )
    gengo_auto_approve = fields.Boolean(
        string="Auto Approve Translation ?",
        groups="base.group_user",
        default=True,
        help="Jobs are Automatically Approved by Gengo.")
    gengo_sandbox = fields.Boolean(
        string="Sandbox Mode",
        help=
        "Check this box if you're using the sandbox mode of Gengo, mainly used for testing purpose."
    )
Пример #3
0
class ResConfigSettings(models.TransientModel):
    _inherit = 'res.config.settings'

    gengo_private_key = fields.Char(string="Gengo Private Key",
                                    related="company_id.gengo_private_key",
                                    readonly=False)
    gengo_public_key = fields.Text(string="Gengo Public Key",
                                   related="company_id.gengo_public_key",
                                   readonly=False)
    gengo_comment = fields.Text(
        string="Comments",
        related="company_id.gengo_comment",
        help=
        "This comment will be automatically be enclosed in each an every request sent to Gengo"
    )
    gengo_auto_approve = fields.Boolean(
        string="Auto Approve Translation ?",
        related="company_id.gengo_auto_approve",
        readonly=False,
        help="Jobs are Automatically Approved by Gengo.")
    gengo_sandbox = fields.Boolean(
        string="Sandbox Mode",
        related="company_id.gengo_sandbox",
        readonly=False,
        help=
        "Check this box if you're using the sandbox mode of Gengo, mainly used for testing purpose."
    )
Пример #4
0
class AccountingAssertTest(models.Model):
    _name = "accounting.assert.test"
    _description = 'Accounting Assert Test'
    _order = "sequence"

    name = fields.Char(string='Test Name',
                       required=True,
                       index=True,
                       translate=True)
    desc = fields.Text(string='Test Description', index=True, translate=True)
    code_exec = fields.Text(string='Python code',
                            required=True,
                            default=CODE_EXEC_DEFAULT)
    active = fields.Boolean(default=True)
    sequence = fields.Integer(default=10)
Пример #5
0
class test_model(models.Model):
    _name = 'test_converter.test_model'
    _description = 'Test Converter Model'

    char = fields.Char()
    integer = fields.Integer()
    float = fields.Float()
    numeric = fields.Float(digits=(16, 2))
    many2one = fields.Many2one('test_converter.test_model.sub',
                               group_expand='_gbf_m2o')
    binary = fields.Binary(attachment=False)
    date = fields.Date()
    datetime = fields.Datetime()
    selection_str = fields.Selection(
        [
            ('A', u"Qu'il n'est pas arrivé à Toronto"),
            ('B', u"Qu'il était supposé arriver à Toronto"),
            ('C', u"Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"),
            ('D', u"La réponse D"),
        ],
        string=u"Lorsqu'un pancake prend l'avion à destination de Toronto et "
        u"qu'il fait une escale technique à St Claude, on dit:")
    html = fields.Html()
    text = fields.Text()

    # `base` module does not contains any model that implement the functionality
    # `group_expand`; test this feature here...

    @api.model
    def _gbf_m2o(self, subs, domain, order):
        sub_ids = subs._search([], order=order, access_rights_uid=SUPERUSER_ID)
        return subs.browse(sub_ids)
Пример #6
0
class LunchProduct(models.Model):
    """ Products available to order. A product is linked to a specific vendor. """
    _name = 'lunch.product'
    _description = 'Lunch Product'
    _inherit = 'image.mixin'
    _order = 'name'

    name = fields.Char('Product Name', required=True)
    category_id = fields.Many2one('lunch.product.category',
                                  'Product Category',
                                  required=True)
    description = fields.Text('Description')
    price = fields.Float('Price', digits='Account', required=True)
    supplier_id = fields.Many2one('lunch.supplier', 'Vendor', required=True)
    active = fields.Boolean(default=True)

    company_id = fields.Many2one('res.company',
                                 related='supplier_id.company_id',
                                 store=True)
    currency_id = fields.Many2one('res.currency',
                                  related='company_id.currency_id')

    new_until = fields.Date('New Until')
    favorite_user_ids = fields.Many2many('res.users',
                                         'lunch_product_favorite_user_rel',
                                         'product_id', 'user_id')
Пример #7
0
class MrpRouting(models.Model):
    """ Specifies routings of work centers """
    _name = 'mrp.routing'
    _description = 'Routings'

    name = fields.Char('Routing', required=True)
    active = fields.Boolean(
        'Active',
        default=True,
        help=
        "If the active field is set to False, it will allow you to hide the routing without removing it."
    )
    code = fields.Char('Reference',
                       copy=False,
                       default=lambda self: _('New'),
                       readonly=True)
    note = fields.Text('Description')
    operation_ids = fields.One2many('mrp.routing.workcenter',
                                    'routing_id',
                                    'Operations',
                                    copy=True)
    company_id = fields.Many2one('res.company',
                                 'Company',
                                 default=lambda self: self.env.company)

    @api.model
    def create(self, vals):
        if 'code' not in vals or vals['code'] == _('New'):
            vals['code'] = self.env['ir.sequence'].next_by_code(
                'mrp.routing') or _('New')
        return super(MrpRouting, self).create(vals)
Пример #8
0
class Discussion(models.Model):
    _name = 'test_new_api.discussion'
    _description = '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',
                                    context={'active_test': False})
    messages = fields.One2many('test_new_api.message', 'discussion', copy=True)
    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])
Пример #9
0
class grant_badge_wizard(models.TransientModel):
    """ Wizard allowing to grant a badge to a user"""
    _name = 'gamification.badge.user.wizard'
    _description = 'Gamification User Badge Wizard'

    user_id = fields.Many2one("res.users", string='User', required=True)
    badge_id = fields.Many2one("gamification.badge", string='Badge', required=True)
    comment = fields.Text('Comment')

    def action_grant_badge(self):
        """Wizard action for sending a badge to a chosen user"""

        BadgeUser = self.env['gamification.badge.user']

        uid = self.env.uid
        for wiz in self:
            if uid == wiz.user_id.id:
                raise exceptions.UserError(_('You can not grant a badge to yourself.'))

            #create the badge
            BadgeUser.create({
                'user_id': wiz.user_id.id,
                'sender_id': uid,
                'badge_id': wiz.badge_id.id,
                'comment': wiz.comment,
            })._send_badge()

        return True
Пример #10
0
class ConverterTest(models.Model):
    _name = 'web_editor.converter.test'
    _description = 'Web Editor Converter Test'

    # disable translation export for those brilliant field labels and values
    _translate = False

    char = fields.Char()
    integer = fields.Integer()
    float = fields.Float()
    numeric = fields.Float(digits=(16, 2))
    many2one = fields.Many2one('web_editor.converter.test.sub')
    binary = fields.Binary(attachment=False)
    date = fields.Date()
    datetime = fields.Datetime()
    selection_str = fields.Selection(
        [
            ('A', "Qu'il n'est pas arrivé à Toronto"),
            ('B', "Qu'il était supposé arriver à Toronto"),
            ('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"),
            ('D', "La réponse D"),
        ],
        string=u"Lorsqu'un pancake prend l'avion à destination de Toronto et "
        u"qu'il fait une escale technique à St Claude, on dit:")
    html = fields.Html()
    text = fields.Text()
Пример #11
0
class LunchLocation(models.Model):
    _name = 'lunch.location'
    _description = 'Lunch Locations'

    name = fields.Char('Location Name', required=True)
    address = fields.Text('Address')
    company_id = fields.Many2one('res.company',
                                 default=lambda self: self.env.company)
Пример #12
0
class ModuleCategory(models.Model):
    _name = "ir.module.category"
    _description = "Application"
    _order = 'name'

    @api.depends('module_ids')
    def _compute_module_nr(self):
        cr = self._cr
        cr.execute(
            'SELECT category_id, COUNT(*) \
                      FROM ir_module_module \
                     WHERE category_id IN %(ids)s \
                        OR category_id IN (SELECT id \
                                             FROM ir_module_category \
                                            WHERE parent_id IN %(ids)s) \
                     GROUP BY category_id', {'ids': tuple(self.ids)})
        result = dict(cr.fetchall())
        for cat in self.filtered('id'):
            cr.execute('SELECT id FROM ir_module_category WHERE parent_id=%s',
                       (cat.id, ))
            cat.module_nr = sum([result.get(c, 0) for (c, ) in cr.fetchall()],
                                result.get(cat.id, 0))

    name = fields.Char(string='Name',
                       required=True,
                       translate=True,
                       index=True)
    parent_id = fields.Many2one('ir.module.category',
                                string='Parent Application',
                                index=True)
    child_ids = fields.One2many('ir.module.category',
                                'parent_id',
                                string='Child Applications')
    module_nr = fields.Integer(string='Number of Apps',
                               compute='_compute_module_nr')
    module_ids = fields.One2many('ir.module.module',
                                 'category_id',
                                 string='Modules')
    description = fields.Text(string='Description', translate=True)
    sequence = fields.Integer(string='Sequence')
    visible = fields.Boolean(string='Visible', default=True)
    exclusive = fields.Boolean(string='Exclusive')
    xml_id = fields.Char(string='External ID', compute='_compute_xml_id')

    def _compute_xml_id(self):
        xml_ids = defaultdict(list)
        domain = [('model', '=', self._name), ('res_id', 'in', self.ids)]
        for data in self.env['ir.model.data'].sudo().search_read(
                domain, ['module', 'name', 'res_id']):
            xml_ids[data['res_id']].append("%s.%s" %
                                           (data['module'], data['name']))
        for cat in self:
            cat.xml_id = xml_ids.get(cat.id, [''])[0]
Пример #13
0
class KarmaRank(models.Model):
    _name = 'gamification.karma.rank'
    _description = 'Rank based on karma'
    _inherit = 'image.mixin'
    _order = 'karma_min'

    name = fields.Text(string='Rank Name', translate=True, required=True)
    description = fields.Html(
        string='Description',
        translate=html_translate,
        sanitize_attributes=False,
    )
    description_motivational = fields.Html(
        string='Motivational',
        translate=html_translate,
        sanitize_attributes=False,
        help="Motivational phrase to reach this rank")
    karma_min = fields.Integer(string='Required Karma',
                               help='Minimum karma needed to reach this rank')
    user_ids = fields.One2many('res.users',
                               'rank_id',
                               string='Users',
                               help="Users having this rank")

    @api.model_create_multi
    def create(self, values_list):
        res = super(KarmaRank, self).create(values_list)
        users = self.env['res.users'].sudo().search([('karma', '>', 0)])
        users._recompute_rank()
        return res

    def write(self, vals):
        if 'karma_min' in vals:
            previous_ranks = self.env['gamification.karma.rank'].search(
                [], order="karma_min DESC").ids
            low = min(vals['karma_min'], self.karma_min)
            high = max(vals['karma_min'], self.karma_min)

        res = super(KarmaRank, self).write(vals)

        if 'karma_min' in vals:
            after_ranks = self.env['gamification.karma.rank'].search(
                [], order="karma_min DESC").ids
            if previous_ranks != after_ranks:
                users = self.env['res.users'].sudo().search([('karma', '>', 0)
                                                             ])
            else:
                users = self.env['res.users'].sudo().search([
                    ('karma', '>=', low), ('karma', '<=', high)
                ])
            users._recompute_rank()
        return res
Пример #14
0
class ResCountry(models.Model):
    _inherit = 'res.country'

    street_format = fields.Text(
        help="Format to use for streets belonging to this country.\n\n"
        "You can use the python-style string pattern with all the fields of the street "
        "(for example, use '%(street_name)s, %(street_number)s' if you want to display "
        "the street name, followed by a comma and the house number)"
        "\n%(street_name)s: the name of the street"
        "\n%(street_number)s: the house number"
        "\n%(street_number2)s: the door number",
        default='%(street_number)s/%(street_number2)s %(street_name)s',
        required=True)
Пример #15
0
class RecruitmentStage(models.Model):
    _name = "hr.recruitment.stage"
    _description = "Recruitment Stages"
    _order = 'sequence'

    name = fields.Char("Stage Name", required=True, translate=True)
    sequence = fields.Integer(
        "Sequence",
        default=10,
        help="Gives the sequence order when displaying a list of stages.")
    job_ids = fields.Many2many(
        'hr.job',
        string='Job Specific',
        help=
        'Specific jobs that uses this stage. Other jobs will not use this stage.'
    )
    requirements = fields.Text("Requirements")
    template_id = fields.Many2one(
        'mail.template',
        "Email Template",
        help=
        "If set, a message is posted on the applicant using the template when the applicant is set to the stage."
    )
    fold = fields.Boolean(
        "Folded in Kanban",
        help=
        "This stage is folded in the kanban view when there are no records in that stage to display."
    )
    legend_blocked = fields.Char('Red Kanban Label',
                                 default=lambda self: _('Blocked'),
                                 translate=True,
                                 required=True)
    legend_done = fields.Char('Green Kanban Label',
                              default=lambda self: _('Ready for Next Stage'),
                              translate=True,
                              required=True)
    legend_normal = fields.Char('Grey Kanban Label',
                                default=lambda self: _('In Progress'),
                                translate=True,
                                required=True)

    @api.model
    def default_get(self, fields):
        if self._context and self._context.get(
                'default_job_id') and not self._context.get(
                    'hr_recruitment_stage_mono', False):
            context = dict(self._context)
            context.pop('default_job_id')
            self = self.with_context(context)
        return super(RecruitmentStage, self).default_get(fields)
Пример #16
0
class Partner(models.Model):
    _inherit = 'res.partner'
    _check_company_auto = True

    property_stock_customer = fields.Many2one(
        'stock.location', string="Customer Location", company_dependent=True, check_company=True,
        domain="['|', ('company_id', '=', False), ('company_id', '=', allowed_company_ids[0])]",
        help="The stock location used as destination when sending goods to this contact.")
    property_stock_supplier = fields.Many2one(
        'stock.location', string="Vendor Location", company_dependent=True, check_company=True,
        domain="['|', ('company_id', '=', False), ('company_id', '=', allowed_company_ids[0])]",
        help="The stock location used as source when receiving goods from this contact.")
    picking_warn = fields.Selection(WARNING_MESSAGE, 'Stock Picking', help=WARNING_HELP, default='no-message')
    picking_warn_msg = fields.Text('Message for Stock Picking')
Пример #17
0
class Stage(models.Model):
    """ Model for case stages. This models the main stages of a document
        management flow. Main CRM objects (leads, opportunities, project
        issues, ...) will now use only stages, instead of state and stages.
        Stages are for example used to display the kanban view of records.
    """
    _name = "crm.stage"
    _description = "CRM Stages"
    _rec_name = 'name'
    _order = "sequence, name, id"

    @api.model
    def default_get(self, fields):
        """ Hack :  when going from the pipeline, creating a stage with a sales team in
            context should not create a stage for the current Sales Team only
        """
        ctx = dict(self.env.context)
        if ctx.get('default_team_id') and not ctx.get('crm_team_mono'):
            ctx.pop('default_team_id')
        return super(Stage, self.with_context(ctx)).default_get(fields)

    name = fields.Char('Stage Name', required=True, translate=True)
    sequence = fields.Integer('Sequence',
                              default=1,
                              help="Used to order stages. Lower is better.")
    is_won = fields.Boolean('Is Won Stage?')
    requirements = fields.Text(
        'Requirements',
        help=
        "Enter here the internal requirements for this stage (ex: Offer sent to customer). It will appear as a tooltip over the stage's name."
    )
    team_id = fields.Many2one(
        'crm.team',
        string='Sales Team',
        ondelete='set null',
        help=
        'Specific team that uses this stage. Other teams will not be able to see or use this stage.'
    )
    fold = fields.Boolean(
        'Folded in Pipeline',
        help=
        'This stage is folded in the kanban view when there are no records in that stage to display.'
    )

    # This field for interface only
    team_count = fields.Integer('team_count', compute='_compute_team_count')

    def _compute_team_count(self):
        for stage in self:
            stage.team_count = self.env['crm.team'].search_count([])
Пример #18
0
class BaseImportModule(models.TransientModel):
    """ Import Module """
    _name = "base.import.module"
    _description = "Import Module"

    module_file = fields.Binary(string='Module .ZIP file',
                                required=True,
                                attachment=False)
    state = fields.Selection([('init', 'init'), ('done', 'done')],
                             string='Status',
                             readonly=True,
                             default='init')
    import_message = fields.Text()
    force = fields.Boolean(
        string='Force init',
        help=
        "Force init mode even if installed. (will update `noupdate='1'` records)"
    )

    def import_module(self):
        self.ensure_one()
        IrModule = self.env['ir.module.module']
        zip_data = base64.decodestring(self.module_file)
        fp = BytesIO()
        fp.write(zip_data)
        res = IrModule.import_zipfile(fp, force=self.force)
        self.write({'state': 'done', 'import_message': res[0]})
        context = dict(self.env.context, module_name=res[1])
        # Return wizard otherwise it will close wizard and will not show result message to user.
        return {
            'name': 'Import Module',
            'view_mode': 'form',
            'target': 'new',
            'res_id': self.id,
            'res_model': 'base.import.module',
            'type': 'ir.actions.act_window',
            'context': context,
        }

    def action_module_open(self):
        self.ensure_one()
        return {
            'domain': [('name', 'in', self.env.context.get('module_name',
                                                           []))],
            'name': 'Modules',
            'view_mode': 'tree,form',
            'res_model': 'ir.module.module',
            'view_id': False,
            'type': 'ir.actions.act_window',
        }
Пример #19
0
class ProjectTaskType(models.Model):
    _name = 'project.task.type'
    _description = 'Task Stage'
    _order = 'sequence, id'

    def _get_default_project_ids(self):
        default_project_id = self.env.context.get('default_project_id')
        return [default_project_id] if default_project_id else None

    name = fields.Char(string='Stage Name', required=True, translate=True)
    description = fields.Text(translate=True)
    sequence = fields.Integer(default=1)
    project_ids = fields.Many2many('project.project', 'project_task_type_rel', 'type_id', 'project_id', string='Projects',
        default=_get_default_project_ids)
    legend_blocked = fields.Char(
        'Red Kanban Label', default=lambda s: _('Blocked'), translate=True, required=True,
        help='Override the default value displayed for the blocked state for kanban selection, when the task or issue is in that stage.')
    legend_done = fields.Char(
        'Green Kanban Label', default=lambda s: _('Ready for Next Stage'), translate=True, required=True,
        help='Override the default value displayed for the done state for kanban selection, when the task or issue is in that stage.')
    legend_normal = fields.Char(
        'Grey Kanban Label', default=lambda s: _('In Progress'), translate=True, required=True,
        help='Override the default value displayed for the normal state for kanban selection, when the task or issue is in that stage.')
    mail_template_id = fields.Many2one(
        'mail.template',
        string='Email Template',
        domain=[('model', '=', 'project.task')],
        help="If set an email will be sent to the customer when the task or issue reaches this step.")
    fold = fields.Boolean(string='Folded in Kanban',
        help='This stage is folded in the kanban view when there are no records in that stage to display.')
    rating_template_id = fields.Many2one(
        'mail.template',
        string='Rating Email Template',
        domain=[('model', '=', 'project.task')],
        help="If set and if the project's rating configuration is 'Rating when changing stage', then an email will be sent to the customer when the task reaches this step.")
    auto_validation_kanban_state = fields.Boolean('Automatic kanban status', default=False,
        help="Automatically modify the kanban state when the customer replies to the feedback for this stage.\n"
            " * A good feedback from the customer will update the kanban state to 'ready for the new stage' (green bullet).\n"
            " * A medium or a bad feedback will set the kanban state to 'blocked' (red bullet).\n")

    def unlink(self):
        stages = self
        default_project_id = self.env.context.get('default_project_id')
        if default_project_id:
            shared_stages = self.filtered(lambda x: len(x.project_ids) > 1 and default_project_id in x.project_ids.ids)
            tasks = self.env['project.task'].with_context(active_test=False).search([('project_id', '=', default_project_id), ('stage_id', 'in', self.ids)])
            if shared_stages and not tasks:
                shared_stages.write({'project_ids': [(3, default_project_id)]})
                stages = self.filtered(lambda x: x not in shared_stages)
        return super(ProjectTaskType, stages).unlink()
Пример #20
0
class SaleOrderTemplate(models.Model):
    _name = "sale.order.template"
    _description = "Quotation Template"

    def _get_default_require_signature(self):
        return self.env.company.portal_confirmation_sign

    def _get_default_require_payment(self):
        return self.env.company.portal_confirmation_pay

    name = fields.Char('Quotation Template', required=True)
    sale_order_template_line_ids = fields.One2many('sale.order.template.line', 'sale_order_template_id', 'Lines', copy=True)
    note = fields.Text('Terms and conditions', translate=True)
    sale_order_template_option_ids = fields.One2many('sale.order.template.option', 'sale_order_template_id', 'Optional Products', copy=True)
    number_of_days = fields.Integer('Quotation Duration',
        help='Number of days for the validity date computation of the quotation')
    require_signature = fields.Boolean('Online Signature', default=_get_default_require_signature, help='Request a online signature to the customer in order to confirm orders automatically.')
    require_payment = fields.Boolean('Online Payment', default=_get_default_require_payment, help='Request an online payment to the customer in order to confirm orders automatically.')
    mail_template_id = fields.Many2one(
        'mail.template', 'Confirmation Mail',
        domain=[('model', '=', 'sale.order')],
        help="This e-mail template will be sent on confirmation. Leave empty to send nothing.")
    active = fields.Boolean(default=True, help="If unchecked, it will allow you to hide the quotation template without removing it.")
    company_id = fields.Many2one('res.company', string='Company')

    @api.constrains('company_id', 'sale_order_template_line_ids', 'sale_order_template_option_ids')
    def _check_company_id(self):
        for template in self:
            companies = template.mapped('sale_order_template_line_ids.product_id.company_id') | template.mapped('sale_order_template_option_ids.product_id.company_id')
            if len(companies) > 1:
                raise ValidationError(_("Your template cannot contain products from multiple companies."))
            elif companies and companies != template.company_id:
                raise ValidationError((_("Your template contains products from company %s whereas your template belongs to company %s. \n Please change the company of your template or remove the products from other companies.") % (companies.mapped('display_name'), template.company_id.display_name)))

    @api.onchange('sale_order_template_line_ids', 'sale_order_template_option_ids')
    def _onchange_template_line_ids(self):
        companies = self.mapped('sale_order_template_option_ids.product_id.company_id') | self.mapped('sale_order_template_line_ids.product_id.company_id')
        if companies and self.company_id not in companies:
            self.company_id = companies[0]

    def write(self, vals):
        if 'active' in vals and not vals.get('active'):
            template_id = self.env['ir.default'].get('sale.order', 'sale_order_template_id')
            for template in self:
                if template_id and template_id == template.id:
                    raise UserError(_('Before archiving "%s" please select another default template in the settings.') % template.name)
        return super(SaleOrderTemplate, self).write(vals)
Пример #21
0
class HrDepartureWizard(models.TransientModel):
    _name = 'hr.departure.wizard'
    _description = 'Departure Wizard'

    @api.model
    def default_get(self, fields):
        res = super(HrDepartureWizard, self).default_get(fields)
        if (not fields
                or 'employee_id' in fields) and 'employee_id' not in res:
            if self.env.context.get('active_id'):
                res['employee_id'] = self.env.context['active_id']
        return res

    departure_reason = fields.Selection([('fired', 'Fired'),
                                         ('resigned', 'Resigned'),
                                         ('retired', 'Retired')],
                                        string="Departure Reason",
                                        default="fired")
    departure_description = fields.Text(string="Additional Information")
    plan_id = fields.Many2one(
        'hr.plan',
        default=lambda self: self.env['hr.plan'].search([], limit=1))
    employee_id = fields.Many2one('hr.employee',
                                  string='Employee',
                                  required=True)

    def action_register_departure(self):
        employee = self.employee_id
        employee.departure_reason = self.departure_reason
        employee.departure_description = self.departure_description

        if not employee.user_id.partner_id:
            return

        for activity_type in self.plan_id.plan_activity_type_ids:
            self.env['mail.activity'].create({
                'res_id':
                employee.user_id.partner_id.id,
                'res_model_id':
                self.env['ir.model']._get('res.partner').id,
                'activity_type_id':
                activity_type.activity_type_id.id,
                'summary':
                activity_type.summary,
                'user_id':
                activity_type.get_responsible_id(employee).id,
            })
Пример #22
0
class CashmoveReport(models.Model):
    _name = "lunch.cashmove.report"
    _description = 'Cashmoves report'
    _auto = False
    _order = "date desc"

    id = fields.Integer('ID')
    amount = fields.Float('Amount')
    date = fields.Date('Date')
    currency_id = fields.Many2one('res.currency', string='Currency')
    user_id = fields.Many2one('res.users', string='User')
    description = fields.Text('Description')

    def name_get(self):
        return [(cashmove.id,
                 '%s %s' % (_('Lunch Cashmove'), '#%d' % cashmove.id))
                for cashmove in self]

    def init(self):
        tools.drop_view_if_exists(self._cr, self._table)

        self._cr.execute("""
            CREATE or REPLACE view %s as (
                SELECT
                    lc.id as id,
                    lc.amount as amount,
                    lc.date as date,
                    lc.currency_id as currency_id,
                    lc.user_id as user_id,
                    lc.description as description
                FROM lunch_cashmove lc
                UNION ALL
                SELECT
                    -lol.id as id,
                    -lol.price as amount,
                    lol.date as date,
                    lol.currency_id as currency_id,
                    lol.user_id as user_id,
                    format('Order: %%s x %%s %%s', lol.quantity::text, lp.name, lol.display_toppings) as description
                FROM lunch_order lol
                JOIN lunch_product lp ON lp.id = lol.product_id
                WHERE
                    lol.state in ('ordered', 'confirmed')
                    AND lol.active = True
            );
        """ % self._table)
Пример #23
0
class Related(models.Model):
    _name = 'test_new_api.related'
    _description = 'Test New API Related'

    name = fields.Char()
    # related fields with a single field
    related_name = fields.Char(related='name',
                               string='A related on Name',
                               readonly=False)
    related_related_name = fields.Char(related='related_name',
                                       string='A related on a related on Name',
                                       readonly=False)

    message = fields.Many2one('test_new_api.message')
    message_name = fields.Text(related="message.body",
                               related_sudo=False,
                               string='Message Body')
    message_currency = fields.Many2one(related="message.author",
                                       string='Message Author')
Пример #24
0
class SaleOrderTemplateOption(models.Model):
    _name = "sale.order.template.option"
    _description = "Quotation Template Option"
    _check_company_auto = True

    sale_order_template_id = fields.Many2one('sale.order.template', 'Quotation Template Reference', ondelete='cascade',
        index=True, required=True)
    company_id = fields.Many2one('res.company', related='sale_order_template_id.company_id', store=True, index=True)
    name = fields.Text('Description', required=True, translate=True)
    product_id = fields.Many2one(
        'product.product', 'Product', domain=[('sale_ok', '=', True)],
        required=True, check_company=True)
    price_unit = fields.Float('Unit Price', required=True, digits='Product Price')
    discount = fields.Float('Discount (%)', digits='Discount')
    uom_id = fields.Many2one('uom.uom', 'Unit of Measure ', required=True, domain="[('category_id', '=', product_uom_category_id)]")
    product_uom_category_id = fields.Many2one(related='product_id.uom_id.category_id', readonly=True)
    quantity = fields.Float('Quantity', required=True, digits='Product UoS', default=1)

    @api.onchange('product_id')
    def _onchange_product_id(self):
        if not self.product_id:
            return
        product = self.product_id
        self.price_unit = product.list_price
        name = product.name
        if self.product_id.description_sale:
            name += '\n' + self.product_id.description_sale
        self.name = name
        self.uom_id = product.uom_id
        domain = {'uom_id': [('category_id', '=', self.product_id.uom_id.category_id.id)]}
        return {'domain': domain}

    @api.onchange('uom_id')
    def _onchange_product_uom(self):
        if not self.product_id:
            return
        if not self.uom_id:
            self.price_unit = 0.0
            return
        if self.uom_id.id != self.product_id.uom_id.id:
            self.price_unit = self.product_id.uom_id._compute_price(self.price_unit, self.uom_id)
Пример #25
0
class AccountAnalyticGroup(models.Model):
    _name = 'account.analytic.group'
    _description = 'Analytic Categories'
    _parent_store = True
    _rec_name = 'complete_name'

    name = fields.Char(required=True)
    description = fields.Text(string='Description')
    parent_id = fields.Many2one('account.analytic.group', string="Parent", ondelete='cascade', domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]")
    parent_path = fields.Char(index=True)
    children_ids = fields.One2many('account.analytic.group', 'parent_id', string="Childrens")
    complete_name = fields.Char('Complete Name', compute='_compute_complete_name', store=True)
    company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)

    @api.depends('name', 'parent_id.complete_name')
    def _compute_complete_name(self):
        for group in self:
            if group.parent_id:
                group.complete_name = '%s / %s' % (group.parent_id.complete_name, group.name)
            else:
                group.complete_name = group.name
Пример #26
0
class ProductTemplate(models.Model):
    _name = 'product.template'
    _inherit = 'product.template'

    property_account_creditor_price_difference = fields.Many2one(
        'account.account', string="Price Difference Account", company_dependent=True,
        help="This account is used in automated inventory valuation to "\
             "record the price difference between a purchase order and its related vendor bill when validating this vendor bill.")
    purchased_product_qty = fields.Float(compute='_compute_purchased_product_qty', string='Purchased')
    purchase_method = fields.Selection([
        ('purchase', 'On ordered quantities'),
        ('receive', 'On received quantities'),
    ], string="Control Policy", help="On ordered quantities: Control bills based on ordered quantities.\n"
        "On received quantities: Control bills based on received quantities.", default="receive")
    purchase_line_warn = fields.Selection(WARNING_MESSAGE, 'Purchase Order Line', help=WARNING_HELP, required=True, default="no-message")
    purchase_line_warn_msg = fields.Text('Message for Purchase Order Line')

    def _compute_purchased_product_qty(self):
        for template in self:
            template.purchased_product_qty = float_round(sum([p.purchased_product_qty for p in template.product_variant_ids]), precision_rounding=template.uom_id.rounding)

    @api.model
    def get_import_templates(self):
        res = super(ProductTemplate, self).get_import_templates()
        if self.env.context.get('purchase_product_template'):
            return [{
                'label': _('Import Template for Products'),
                'template': '/purchase/static/xls/product_purchase.xls'
            }]
        return res

    def action_view_po(self):
        action = self.env.ref('purchase.action_purchase_order_report_all').read()[0]
        action['domain'] = ['&', ('state', 'in', ['purchase', 'done']), ('product_tmpl_id', 'in', self.ids)]
        action['context'] = {
            'graph_measure': 'qty_ordered',
            'search_default_orders': 1,
            'time_ranges': {'field': 'date_approve', 'range': 'last_365_days'}
        }
        return action
Пример #27
0
class MailTestAlias(models.Model):
    """ This model can be used in tests when umbrella records like projects
    or teams are required. """
    _description = 'Alias Chatter Model'
    _name = 'mail.test'
    _mail_post_access = 'read'
    _inherit = ['mail.thread', 'mail.alias.mixin']

    name = fields.Char()
    description = fields.Text()
    customer_id = fields.Many2one('res.partner', 'Customer')
    alias_id = fields.Many2one('mail.alias', 'Alias', delegate=True)

    def get_alias_model_name(self, vals):
        return vals.get('alias_model', 'mail.test')

    def get_alias_values(self):
        self.ensure_one()
        res = super(MailTestAlias, self).get_alias_values()
        res['alias_force_thread_id'] = self.id
        res['alias_parent_thread_id'] = self.id
        return res
Пример #28
0
class ResumeLine(models.Model):
    _name = 'hr.resume.line'
    _description = "Resumé line of an employee"
    _order = "line_type_id, date_end desc, date_start desc"

    employee_id = fields.Many2one('hr.employee',
                                  required=True,
                                  ondelete='cascade')
    name = fields.Char(required=True)
    date_start = fields.Date(required=True)
    date_end = fields.Date()
    description = fields.Text(string="Description")
    line_type_id = fields.Many2one('hr.resume.line.type', string="Type")

    # Used to apply specific template on a line
    display_type = fields.Selection([('classic', 'Classic')],
                                    string="Display Type",
                                    default='classic')

    _sql_constraints = [
        ('date_check', "CHECK ((date_start <= date_end OR date_end = NULL))",
         "The start date must be anterior to the end date."),
    ]
Пример #29
0
class LunchCashMove(models.Model):
    """ Two types of cashmoves: payment (credit) or order (debit) """
    _name = 'lunch.cashmove'
    _description = 'Lunch Cashmove'
    _order = 'date desc'

    currency_id = fields.Many2one('res.currency', default=lambda self: self.env.company.currency_id)
    user_id = fields.Many2one('res.users', 'User',
                              default=lambda self: self.env.uid)
    date = fields.Date('Date', required=True, default=fields.Date.context_today)
    amount = fields.Float('Amount', required=True)
    description = fields.Text('Description')

    def name_get(self):
        return [(cashmove.id, '%s %s' % (_('Lunch Cashmove'), '#%d' % cashmove.id)) for cashmove in self]

    @api.model
    def get_wallet_balance(self, user, include_config=True):
        result = float_round(sum(move['amount'] for move in self.env['lunch.cashmove.report'].search_read(
            [('user_id', '=', user.id)], ['amount'])), precision_digits=2)
        if include_config:
            result += user.company_id.lunch_minimum_threshold
        return result
Пример #30
0
class MailShortcode(models.Model):
    """ Shortcode
        Canned Responses, allowing the user to defined shortcuts in its message. Should be applied before storing message in database.
        Emoji allowing replacing text with image for visual effect. Should be applied when the message is displayed (only for final rendering).
        These shortcodes are global and are available for every user.
    """

    _name = 'mail.shortcode'
    _description = 'Canned Response / Shortcode'
    source = fields.Char(
        'Shortcut',
        required=True,
        index=True,
        help="The shortcut which must be replaced in the Chat Messages")
    substitution = fields.Text(
        'Substitution',
        required=True,
        index=True,
        help="The escaped html code replacing the shortcut")
    description = fields.Char('Description')
    message_ids = fields.Many2one('mail.message',
                                  string="Messages",
                                  store=False)