Пример #1
0
class PriceRule(models.Model):
    _name = "delivery.price.rule"
    _description = "Delivery Price Rules"
    _order = 'sequence, list_price, id'

    @api.depends('variable', 'operator', 'max_value', 'list_base_price', 'list_price', 'variable_factor')
    def _compute_name(self):
        for rule in self:
            name = 'if %s %s %s then' % (rule.variable, rule.operator, rule.max_value)
            if rule.list_base_price and not rule.list_price:
                name = '%s fixed price %s' % (name, rule.list_base_price)
            elif rule.list_price and not rule.list_base_price:
                name = '%s %s times %s' % (name, rule.list_price, rule.variable_factor)
            else:
                name = '%s fixed price %s plus %s times %s' % (name, rule.list_base_price, rule.list_price, rule.variable_factor)
            rule.name = name

    name = fields.Char(compute='_compute_name')
    sequence = fields.Integer(required=True, default=10)
    carrier_id = fields.Many2one('delivery.carrier', 'Carrier', required=True, ondelete='cascade')

    variable = fields.Selection([('weight', 'Weight'), ('volume', 'Volume'), ('wv', 'Weight * Volume'), ('price', 'Price'), ('quantity', 'Quantity')], required=True, default='weight')
    operator = fields.Selection([('==', '='), ('<=', '<='), ('<', '<'), ('>=', '>='), ('>', '>')], required=True, default='<=')
    max_value = fields.Float('Maximum Value', required=True)
    list_base_price = fields.Float(string='Sale Base Price', digits='Product Price', required=True, default=0.0)
    list_price = fields.Float('Sale Price', digits='Product Price', required=True, default=0.0)
    variable_factor = fields.Selection([('weight', 'Weight'), ('volume', 'Volume'), ('wv', 'Weight * Volume'), ('price', 'Price'), ('quantity', 'Quantity')], 'Variable Factor', required=True, default='weight')
Пример #2
0
class ResCompany(models.Model):
    _inherit = 'res.company'

    payment_acquirer_onboarding_state = fields.Selection(
        [('not_done', "Not done"), ('just_done', "Just done"),
         ('done', "Done")],
        string="State of the onboarding payment acquirer step",
        default='not_done')
    # YTI FIXME: Check if it's really needed on the company. Should be enough on the wizard
    payment_onboarding_payment_method = fields.Selection(
        [
            ('paypal', "PayPal"),
            ('stripe', "Stripe"),
            ('manual', "Manual"),
            ('other', "Other"),
        ],
        string="Selected onboarding payment method")

    @api.model
    def action_open_payment_onboarding_payment_acquirer(self):
        """ Called by onboarding panel above the customer invoice list."""
        # Fail if there are no existing accounts
        self.env.company.get_chart_of_accounts_or_fail()

        action = self.env.ref(
            'payment.action_open_payment_onboarding_payment_acquirer_wizard'
        ).read()[0]
        return action

    def get_account_invoice_onboarding_steps_states_names(self):
        """ Override. """
        steps = super(
            ResCompany,
            self).get_account_invoice_onboarding_steps_states_names()
        return steps + ['payment_acquirer_onboarding_state']
Пример #3
0
class ResConfigSettings(models.TransientModel):
    _inherit = 'res.config.settings'

    lock_confirmed_po = fields.Boolean(
        "Lock Confirmed Orders",
        default=lambda self: self.env.company.po_lock == 'lock')
    po_lock = fields.Selection(related='company_id.po_lock',
                               string="Purchase Order Modification *",
                               readonly=False)
    po_order_approval = fields.Boolean("Purchase Order Approval",
                                       default=lambda self: self.env.company.
                                       po_double_validation == 'two_step')
    po_double_validation = fields.Selection(
        related='company_id.po_double_validation',
        string="Levels of Approvals *",
        readonly=False)
    po_double_validation_amount = fields.Monetary(
        related='company_id.po_double_validation_amount',
        string="Minimum Amount",
        currency_field='company_currency_id',
        readonly=False)
    company_currency_id = fields.Many2one(
        'res.currency',
        related='company_id.currency_id',
        string="Company Currency",
        readonly=True,
        help='Utility field to express amount currency')
    default_purchase_method = fields.Selection(
        [
            ('purchase', 'Ordered quantities'),
            ('receive', 'Received quantities'),
        ],
        string="Bill Control",
        default_model="product.template",
        help="This default value is applied to any new product created. "
        "This can be changed in the product detail form.",
        default="receive")
    group_warning_purchase = fields.Boolean(
        "Purchase Warnings", implied_group='purchase.group_warning_purchase')
    module_account_3way_match = fields.Boolean(
        "3-way matching: purchases, receptions and bills")
    module_purchase_requisition = fields.Boolean("Purchase Agreements")
    module_purchase_product_matrix = fields.Boolean("Purchase Grid Entry")
    po_lead = fields.Float(related='company_id.po_lead', readonly=False)
    use_po_lead = fields.Boolean(
        string="Security Lead Time for Purchase",
        config_parameter='purchase.use_po_lead',
        help=
        "Margin of error for vendor lead times. When the system generates Purchase Orders for reordering products,they will be scheduled that many days earlier to cope with unexpected vendor delays."
    )

    @api.onchange('use_po_lead')
    def _onchange_use_po_lead(self):
        if not self.use_po_lead:
            self.po_lead = 0.0

    def set_values(self):
        super(ResConfigSettings, self).set_values()
        self.po_lock = 'lock' if self.lock_confirmed_po else 'edit'
        self.po_double_validation = 'two_step' if self.po_order_approval else 'one_step'
Пример #4
0
class PaymentToken(models.Model):
    _inherit = 'payment.token'

    authorize_profile = fields.Char(string='Authorize.net Profile ID', help='This contains the unique reference '
                                    'for this partner/payment token combination in the Authorize.net backend')
    provider = fields.Selection(string='Provider', related='acquirer_id.provider', readonly=False)
    save_token = fields.Selection(string='Save Cards', related='acquirer_id.save_token', readonly=False)

    @api.model
    def authorize_create(self, values):
        if values.get('opaqueData') and values.get('encryptedCardData'):
            acquirer = self.env['payment.acquirer'].browse(values['acquirer_id'])
            partner = self.env['res.partner'].browse(values['partner_id'])
            transaction = AuthorizeAPI(acquirer)
            res = transaction.create_customer_profile(partner, values['opaqueData'])
            if res.get('profile_id') and res.get('payment_profile_id'):
                return {
                    'authorize_profile': res.get('profile_id'),
                    'name': values['encryptedCardData'].get('cardNumber'),
                    'acquirer_ref': res.get('payment_profile_id'),
                    'verified': True
                }
            else:
                raise ValidationError(_('The Customer Profile creation in Authorize.NET failed.'))
        else:
            return values
Пример #5
0
class PurchaseRequisitionType(models.Model):
    _name = "purchase.requisition.type"
    _description = "Purchase Requisition Type"
    _order = "sequence"

    name = fields.Char(string='Agreement Type', required=True, translate=True)
    sequence = fields.Integer(default=1)
    exclusive = fields.Selection(
        [('exclusive', 'Select only one RFQ (exclusive)'),
         ('multiple', 'Select multiple RFQ')],
        string='Agreement Selection Type',
        required=True,
        default='multiple',
        help=
        """Select only one RFQ (exclusive):  when a purchase order is confirmed, cancel the remaining purchase order.\n
                    Select multiple RFQ: allows multiple purchase orders. On confirmation of a purchase order it does not cancel the remaining orders"""
    )
    quantity_copy = fields.Selection([('copy', 'Use quantities of agreement'),
                                      ('none', 'Set quantities manually')],
                                     string='Quantities',
                                     required=True,
                                     default='none')
    line_copy = fields.Selection(
        [('copy', 'Use lines of agreement'),
         ('none', 'Do not create RfQ lines automatically')],
        string='Lines',
        required=True,
        default='copy')
Пример #6
0
class BaseLanguageInstall(models.TransientModel):
    _name = "base.language.install"
    _description = "Install Language"

    @api.model
    def _default_language(self):
        """ Display the selected language when using the 'Update Terms' action
            from the language list view
        """
        if self._context.get('active_model') == 'res.lang':
            lang = self.env['res.lang'].browse(self._context.get('active_id'))
            return lang.code
        return False

    @api.model
    def _get_languages(self):
        return [[code, name]
                for code, _, name in self.env['res.lang'].get_available()]

    lang = fields.Selection(_get_languages,
                            string='Language',
                            required=True,
                            default=_default_language)
    overwrite = fields.Boolean(
        'Overwrite Existing Terms',
        default=True,
        help=
        "If you check this box, your customized translations will be overwritten and replaced by the official ones."
    )
    state = fields.Selection([('init', 'init'), ('done', 'done')],
                             string='Status',
                             readonly=True,
                             default='init')

    def lang_install(self):
        self.ensure_one()
        mods = self.env['ir.module.module'].search([('state', '=', 'installed')
                                                    ])
        mods.with_context(overwrite=self.overwrite)._update_translations(
            self.lang)
        self.state = 'done'
        self.env.cr.execute('ANALYZE ir_translation')

        return {
            'name': _('Language Pack'),
            'view_mode': 'form',
            'view_id': False,
            'res_model': 'base.language.install',
            'domain': [],
            'context': dict(self._context, active_ids=self.ids),
            'type': 'ir.actions.act_window',
            'target': 'new',
            'res_id': self.id,
        }

    def reload(self):
        return {
            'type': 'ir.actions.client',
            'tag': 'reload',
        }
Пример #7
0
class BaseLanguageExport(models.TransientModel):
    _name = "base.language.export"
    _description = 'Language Export'

    @api.model
    def _get_languages(self):
        langs = self.env['res.lang'].get_installed()
        return [(NEW_LANG_KEY, _('New Language (Empty translation template)'))] + \
               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, attachment=False)
    state = fields.Selection(
        [('choose', 'choose'),
         ('get', 'get')],  # choose language or get the file
        default='choose')

    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',
            'res_id': this.id,
            'views': [(False, 'form')],
            'target': 'new',
        }
Пример #8
0
class Selection(models.Model):
    _inherit = 'test_new_api.selection'

    state = fields.Selection(selection_add=[('bar', 'Bar'), ('baz', 'Baz')])
    other = fields.Selection('_other_values')

    def _other_values(self):
        return [('baz', 'Baz')]
Пример #9
0
class ResourceCalendarAttendance(models.Model):
    _name = "resource.calendar.attendance"
    _description = "Work Detail"
    _order = 'week_type, dayofweek, hour_from'

    name = fields.Char(required=True)
    dayofweek = fields.Selection([('0', 'Monday'), ('1', 'Tuesday'),
                                  ('2', 'Wednesday'), ('3', 'Thursday'),
                                  ('4', 'Friday'), ('5', 'Saturday'),
                                  ('6', 'Sunday')],
                                 'Day of Week',
                                 required=True,
                                 index=True,
                                 default='0')
    date_from = fields.Date(string='Starting Date')
    date_to = fields.Date(string='End Date')
    hour_from = fields.Float(
        string='Work from',
        required=True,
        index=True,
        help="Start and End time of working.\n"
        "A specific value of 24:00 is interpreted as 23:59:59.999999.")
    hour_to = fields.Float(string='Work to', required=True)
    calendar_id = fields.Many2one("resource.calendar",
                                  string="Resource's Calendar",
                                  required=True,
                                  ondelete='cascade')
    day_period = fields.Selection([('morning', 'Morning'),
                                   ('afternoon', 'Afternoon')],
                                  required=True,
                                  default='morning')
    resource_id = fields.Many2one('resource.resource', 'Resource')
    week_type = fields.Selection([('1', 'Odd week'), ('0', 'Even week')],
                                 'Week Even/Odd',
                                 default=False)
    two_weeks_calendar = fields.Boolean(
        "Calendar in 2 weeks mode", related='calendar_id.two_weeks_calendar')
    display_type = fields.Selection([('line_section', "Section")],
                                    default=False,
                                    help="Technical field for UX purpose.")
    sequence = fields.Integer(
        default=10,
        help=
        "Gives the sequence of this line when displaying the resource calendar."
    )

    @api.onchange('hour_from', 'hour_to')
    def _onchange_hours(self):
        # avoid negative or after midnight
        self.hour_from = min(self.hour_from, 23.99)
        self.hour_from = max(self.hour_from, 0.0)
        self.hour_to = min(self.hour_to, 23.99)
        self.hour_to = max(self.hour_to, 0.0)

        # avoid wrong order
        self.hour_to = max(self.hour_to, self.hour_from)
Пример #10
0
class MailingTraceReport(models.Model):
    _name = 'mailing.trace.report'
    _auto = False
    _description = 'Mass Mailing Statistics'

    # mailing
    name = fields.Char(string='Mass Mail', readonly=True)
    mailing_type = fields.Selection([('mail', 'Mail')],
                                    string='Type',
                                    default='mail',
                                    required=True)
    campaign = fields.Char(string='Mass Mail Campaign', readonly=True)
    scheduled_date = fields.Datetime(string='Scheduled Date', readonly=True)
    state = fields.Selection([('draft', 'Draft'), ('test', 'Tested'),
                              ('done', 'Sent')],
                             string='Status',
                             readonly=True)
    email_from = fields.Char('From', readonly=True)
    # traces
    sent = fields.Integer(readonly=True)
    delivered = fields.Integer(readonly=True)
    opened = fields.Integer(readonly=True)
    replied = fields.Integer(readonly=True)
    clicked = fields.Integer(readonly=True)
    bounced = fields.Integer(readonly=True)

    def init(self):
        """Mass Mail Statistical Report: based on mailing.trace that models the various
        statistics collected for each mailing, and mailing.mailing model that models the
        various mailing performed. """
        tools.drop_view_if_exists(self.env.cr, 'mailing_trace_report')
        self.env.cr.execute("""
            CREATE OR REPLACE VIEW mailing_trace_report AS (
                SELECT
                    min(trace.id) as id,
                    utm_source.name as name,
                    mailing.mailing_type,
                    utm_campaign.name as campaign,
                    trace.scheduled as scheduled_date,
                    mailing.state,
                    mailing.email_from,
                    count(trace.sent) as sent,
                    (count(trace.sent) - count(trace.bounced)) as delivered,
                    count(trace.opened) as opened,
                    count(trace.replied) as replied,
                    count(trace.clicked) as clicked,
                    count(trace.bounced) as bounced
                FROM
                    mailing_trace as trace
                    left join mailing_mailing as mailing ON (trace.mass_mailing_id=mailing.id)
                    left join utm_campaign as utm_campaign ON (mailing.campaign_id = utm_campaign.id)
                    left join utm_source as utm_source ON (mailing.source_id = utm_source.id)
                GROUP BY trace.scheduled, utm_source.name, utm_campaign.name, mailing.mailing_type, mailing.state, mailing.email_from
            )""")
Пример #11
0
class LunchProductCategory(models.Model):
    """ Category of the product such as pizza, sandwich, pasta, chinese, burger... """
    _name = 'lunch.product.category'
    _inherit = 'image.mixin'
    _description = 'Lunch Product Category'

    name = fields.Char('Product Category', required=True)
    company_id = fields.Many2one('res.company', default=lambda self: self.env.company)
    currency_id = fields.Many2one('res.currency', related='company_id.currency_id')
    topping_label_1 = fields.Char('Extra 1 Label', required=True, default='Extras')
    topping_label_2 = fields.Char('Extra 2 Label', required=True, default='Beverages')
    topping_label_3 = fields.Char('Extra 3 Label', required=True, default='Extra Label 3')
    topping_ids_1 = fields.One2many('lunch.topping', 'category_id', domain=[('topping_category', '=', 1)], ondelete='cascade')
    topping_ids_2 = fields.One2many('lunch.topping', 'category_id', domain=[('topping_category', '=', 2)], ondelete='cascade')
    topping_ids_3 = fields.One2many('lunch.topping', 'category_id', domain=[('topping_category', '=', 3)], ondelete='cascade')
    topping_quantity_1 = fields.Selection([
        ('0_more', 'None or More'),
        ('1_more', 'One or More'),
        ('1', 'Only One')], 'Extra 1 Quantity', default='0_more', required=True)
    topping_quantity_2 = fields.Selection([
        ('0_more', 'None or More'),
        ('1_more', 'One or More'),
        ('1', 'Only One')], 'Extra 2 Quantity', default='0_more', required=True)
    topping_quantity_3 = fields.Selection([
        ('0_more', 'None or More'),
        ('1_more', 'One or More'),
        ('1', 'Only One')], 'Extra 3 Quantity', default='0_more', required=True)
    product_count = fields.Integer(compute='_compute_product_count', help="The number of products related to this category")

    def _compute_product_count(self):
        product_data = self.env['lunch.product'].read_group([('category_id', 'in', self.ids)], ['category_id'], ['category_id'])
        data = {product['category_id'][0]: product['category_id_count'] for product in product_data}
        for category in self:
            category.product_count = data.get(category.id, 0)

    @api.model
    def create(self, vals):
        for topping in vals.get('topping_ids_2', []):
            topping[2].update({'topping_category': 2})
        for topping in vals.get('topping_ids_3', []):
            topping[2].update({'topping_category': 3})
        return super(LunchProductCategory, self).create(vals)

    def write(self, vals):
        for topping in vals.get('topping_ids_2', []):
            topping_values = topping[2]
            if topping_values:
                topping_values.update({'topping_category': 2})
        for topping in vals.get('topping_ids_3', []):
            topping_values = topping[2]
            if topping_values:
                topping_values.update({'topping_category': 3})
        return super(LunchProductCategory, self).write(vals)
Пример #12
0
class AccountCashRounding(models.Model):
    """
    In some countries, we need to be able to make appear on an invoice a rounding line, appearing there only because the
    smallest coinage has been removed from the circulation. For example, in Switzerland invoices have to be rounded to
    0.05 CHF because coins of 0.01 CHF and 0.02 CHF aren't used anymore.
    see https://en.wikipedia.org/wiki/Cash_rounding for more details.
    """
    _name = 'account.cash.rounding'
    _description = 'Account Cash Rounding'

    name = fields.Char(string='Name', translate=True, required=True)
    rounding = fields.Float(string='Rounding Precision', required=True,
        help='Represent the non-zero value smallest coinage (for example, 0.05).')
    strategy = fields.Selection([('biggest_tax', 'Modify tax amount'), ('add_invoice_line', 'Add a rounding line')],
        string='Rounding Strategy', default='add_invoice_line', required=True,
        help='Specify which way will be used to round the invoice amount to the rounding precision')
    account_id = fields.Many2one('account.account', string='Account')
    rounding_method = fields.Selection(string='Rounding Method', required=True,
        selection=[('UP', 'UP'), ('DOWN', 'DOWN'), ('HALF-UP', 'HALF-UP')],
        default='HALF-UP', help='The tie-breaking rule used for float rounding operations')
    company_id = fields.Many2one('res.company', related='account_id.company_id')

    @api.constrains('rounding')
    def validate_rounding(self):
        for record in self:
            if record.rounding < 0:
                raise ValidationError(_("Please set a positive rounding value."))

    def round(self, amount):
        """Compute the rounding on the amount passed as parameter.

        :param amount: the amount to round
        :return: the rounded amount depending the rounding value and the rounding method
        """
        return float_round(amount, precision_rounding=self.rounding, rounding_method=self.rounding_method)

    def compute_difference(self, currency, amount):
        """Compute the difference between the base_amount and the amount after rounding.
        For example, base_amount=23.91, after rounding=24.00, the result will be 0.09.

        :param currency: The currency.
        :param amount: The amount
        :return: round(difference)
        """
        difference = self.round(amount) - amount
        return currency.round(difference)

    def _get_profit_account_id(self):
        return self.account_id

    def _get_loss_account_id(self):
        return self.account_id
Пример #13
0
class TemplatePreview(models.TransientModel):
    _inherit = "mail.template"
    _name = "email_template.preview"
    _description = "Email Template Preview"

    @api.model
    def _get_records(self):
        """ Return Records of particular Email Template's Model """
        template_id = self._context.get('template_id')
        default_res_id = self._context.get('default_res_id')
        if not template_id:
            return []
        template = self.env['mail.template'].browse(int(template_id))
        records = self.env[template.model_id.model].search([], order="id desc", limit=10)
        records |= records.browse(default_res_id)
        return records.name_get()

    @api.model
    def _get_languages(self):
        return self.env['res.lang'].get_installed()

    @api.model
    def default_get(self, fields):
        result = super(TemplatePreview, self).default_get(fields)

        template = self._context.get('template_id') and self.env['mail.template'].browse(self._context['template_id']) or False
        if 'res_id' in fields and not result.get('res_id'):
            records = self._get_records()
            result['res_id'] = records and records[0][0] or False  # select first record as a Default
        if template and 'model_id' in fields and not result.get('model_id'):
            result['model_id'] = template.model_id.id
        if template and 'preview_lang' in fields and not result.get('preview_lang') and result.get('res_id'):
            result['preview_lang'] = template.lang and template.generate_email(result['res_id'], ['lang'])['lang'] or template._context.get('lang')
        return result

    res_id = fields.Selection(_get_records, 'Sample Document')
    partner_ids = fields.Many2many('res.partner', string='Recipients')
    attachment_ids = fields.Many2many(string='Attachments', store=False)
    preview_lang = fields.Selection(_get_languages, string='Template Preview Language')

    @api.onchange('res_id', 'preview_lang')
    def on_change_res_id(self):
        if not self.res_id:
            return {}
        mail_values = {}
        if self._context.get('template_id'):
            template = self.env['mail.template'].browse(self._context['template_id'])
            self.name = template.name
            mail_values = template.with_context(template_preview_lang=self.preview_lang).generate_email(self.res_id)
        for field in ['email_from', 'email_to', 'email_cc', 'reply_to', 'subject', 'body_html', 'partner_to', 'partner_ids', 'attachment_ids']:
            setattr(self, field, mail_values.get(field, False))
Пример #14
0
class PaymentWizard(models.TransientModel):
    """ Override for the sale quotation onboarding panel. """

    _inherit = 'payment.acquirer.onboarding.wizard'
    _name = 'sale.payment.acquirer.onboarding.wizard'
    _description = 'Sale Payment acquire onboarding wizard'

    def _get_default_payment_method(self):
        return self.env.company.sale_onboarding_payment_method or 'digital_signature'

    payment_method = fields.Selection(selection_add=[
        ('digital_signature', 'Online signature'),
        ('paypal', "PayPal"),
        ('stripe', "Credit card (via Stripe)"),
        ('other', "Other payment acquirer"),
        ('manual', "Custom payment instructions"),
    ],
                                      default=_get_default_payment_method)

    #

    def _set_payment_acquirer_onboarding_step_done(self):
        """ Override. """
        self.env.company.sudo().set_onboarding_step_done(
            'sale_onboarding_order_confirmation_state')

    def add_payment_methods(self, *args, **kwargs):
        self.env.company.sale_onboarding_payment_method = self.payment_method
        if self.payment_method == 'digital_signature':
            self.env.company.portal_confirmation_sign = True
        if self.payment_method in ('paypal', 'stripe', 'other', 'manual'):
            self.env.company.portal_confirmation_pay = True

        return super(PaymentWizard, self).add_payment_methods(*args, **kwargs)
Пример #15
0
class ResumeLine(models.Model):
    _inherit = 'hr.resume.line'

    display_type = fields.Selection(selection_add=[('course', 'Course')])
    channel_id = fields.Many2one('slide.channel',
                                 string="Course",
                                 readonly=True)
Пример #16
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
Пример #17
0
class BaseUpdateTranslations(models.TransientModel):
    _name = 'base.update.translations'
    _description = 'Update Translations'

    @api.model
    def _get_languages(self):
        return self.env['res.lang'].get_installed()

    lang = fields.Selection(_get_languages, 'Language', required=True)

    @api.model
    def _get_lang_name(self, lang_code):
        lang = self.env['res.lang']._lang_get(lang_code)
        if not lang:
            raise UserError(_('No language with code "%s" exists') % lang_code)
        return lang.name

    def act_update(self):
        this = self[0]
        lang_name = self._get_lang_name(this.lang)
        with tempfile.NamedTemporaryFile() as buf:
            tools.trans_export(this.lang, ['all'], buf, 'po', self._cr)
            context = {'create_empty_translation': True}
            tools.trans_load_data(self._cr,
                                  buf,
                                  'po',
                                  this.lang,
                                  lang_name=lang_name,
                                  context=context)
        return {'type': 'ir.actions.act_window_close'}
Пример #18
0
class FleetVehicleOdometer(models.Model):
    _name = 'fleet.vehicle.odometer'
    _description = 'Odometer log for a vehicle'
    _order = 'date desc'

    name = fields.Char(compute='_compute_vehicle_log_name', store=True)
    date = fields.Date(default=fields.Date.context_today)
    value = fields.Float('Odometer Value', group_operator="max")
    vehicle_id = fields.Many2one('fleet.vehicle', 'Vehicle', required=True)
    unit = fields.Selection(related='vehicle_id.odometer_unit', string="Unit", readonly=True)
    driver_id = fields.Many2one(related="vehicle_id.driver_id", string="Driver", readonly=False)

    @api.depends('vehicle_id', 'date')
    def _compute_vehicle_log_name(self):
        for record in self:
            name = record.vehicle_id.name
            if not name:
                name = str(record.date)
            elif record.date:
                name += ' / ' + str(record.date)
            record.name = name

    @api.onchange('vehicle_id')
    def _onchange_vehicle(self):
        if self.vehicle_id:
            self.unit = self.vehicle_id.odometer_unit
Пример #19
0
class User(models.Model):
    _inherit = ['res.users']

    hours_last_month = fields.Float(related='employee_id.hours_last_month')
    hours_last_month_display = fields.Char(
        related='employee_id.hours_last_month_display')
    attendance_state = fields.Selection(related='employee_id.attendance_state')
    last_check_in = fields.Datetime(
        related='employee_id.last_attendance_id.check_in')
    last_check_out = fields.Datetime(
        related='employee_id.last_attendance_id.check_out')

    def __init__(self, pool, cr):
        """ Override of __init__ to add access rights.
            Access rights are disabled by default, but allowed
            on some specific fields defined in self.SELF_{READ/WRITE}ABLE_FIELDS.
        """
        attendance_readable_fields = [
            'hours_last_month', 'hours_last_month_display', 'attendance_state',
            'last_check_in', 'last_check_out'
        ]
        super(User, self).__init__(pool, cr)
        # duplicate list to avoid modifying the original reference
        type(self).SELF_READABLE_FIELDS = type(
            self).SELF_READABLE_FIELDS + attendance_readable_fields
Пример #20
0
class res_company(models.Model):
    _inherit = "res.company"

    account_check_printing_layout = fields.Selection(string="Check Layout", required=True,
        help="Select the format corresponding to the check paper you will be printing your checks on.\n"
             "In order to disable the printing feature, select 'None'.",
        selection=[
            ('disabled', 'None'),
            ('action_print_check_top', 'check on top'),
            ('action_print_check_middle', 'check in middle'),
            ('action_print_check_bottom', 'check on bottom')
        ],
        default="action_print_check_top")

    account_check_printing_date_label = fields.Boolean('Print Date Label', default=True,
        help="This option allows you to print the date label on the check as per CPA. Disable this if your pre-printed check includes the date label.")

    account_check_printing_multi_stub = fields.Boolean('Multi-Pages Check Stub',
        help="This option allows you to print check details (stub) on multiple pages if they don't fit on a single page.")

    account_check_printing_margin_top = fields.Float('Check Top Margin', default=0.25,
        help="Adjust the margins of generated checks to make it fit your printer's settings.")

    account_check_printing_margin_left = fields.Float('Check Left Margin', default=0.25,
        help="Adjust the margins of generated checks to make it fit your printer's settings.")

    account_check_printing_margin_right = fields.Float('Right Margin', default=0.25,
        help="Adjust the margins of generated checks to make it fit your printer's settings.")
Пример #21
0
class ProductPackaging(models.Model):
    _inherit = 'product.packaging'

    def _get_default_weight_uom(self):
        return self.env['product.template']._get_weight_uom_name_from_ir_config_parameter()

    height = fields.Integer('Height')
    width = fields.Integer('Width')
    length = fields.Integer('Length')
    max_weight = fields.Float('Max Weight', help='Maximum weight shippable in this packaging')
    shipper_package_code = fields.Char('Package Code')
    package_carrier_type = fields.Selection([('none', 'No carrier integration')], string='Carrier', default='none')
    weight_uom_name = fields.Char(string='Weight unit of measure label', compute='_compute_weight_uom_name', default=_get_default_weight_uom)

    _sql_constraints = [
        ('positive_height', 'CHECK(height>=0)', 'Height must be positive'),
        ('positive_width', 'CHECK(width>=0)', 'Width must be positive'),
        ('positive_length', 'CHECK(length>=0)', 'Length must be positive'),
        ('positive_max_weight', 'CHECK(max_weight>=0.0)', 'Max Weight must be positive'),
    ]

    @api.onchange('package_carrier_type')
    def _onchange_carrier_type(self):
        carrier_id = self.env['delivery.carrier'].search([('delivery_type', '=', self.package_carrier_type)], limit=1)
        if carrier_id:
            self.shipper_package_code = carrier_id._get_default_custom_package_code()
        else:
            self.shipper_package_code = False

    def _compute_weight_uom_name(self):
        for packaging in self:
            packaging.weight_uom_name = self.env['product.template']._get_weight_uom_name_from_ir_config_parameter()
Пример #22
0
class MixedModel(models.Model):
    _name = 'test_new_api.mixed'
    _description = 'Test New API Mixed'

    number = fields.Float(digits=(10, 2), default=3.14)
    number2 = fields.Float(digits='New API Precision')
    date = fields.Date()
    moment = fields.Datetime()
    now = fields.Datetime(compute='_compute_now')
    lang = fields.Selection(string='Language', selection='_get_lang')
    reference = fields.Reference(string='Related Document',
        selection='_reference_models')
    comment1 = fields.Html(sanitize=False)
    comment2 = fields.Html(sanitize_attributes=True, strip_classes=False)
    comment3 = fields.Html(sanitize_attributes=True, strip_classes=True)
    comment4 = fields.Html(sanitize_attributes=True, strip_style=True)

    currency_id = fields.Many2one('res.currency', default=lambda self: self.env.ref('base.EUR'))
    amount = fields.Monetary()

    def _compute_now(self):
        # this is a non-stored computed field without dependencies
        for message in self:
            message.now = fields.Datetime.now()

    @api.model
    def _get_lang(self):
        return self.env['res.lang'].get_installed()

    @api.model
    def _reference_models(self):
        models = self.env['ir.model'].sudo().search([('state', '!=', 'manual')])
        return [(model.model, model.name)
                for model in models
                if not model.model.startswith('ir.')]
Пример #23
0
class product_label(models.Model):
    _name = "product.label"
    _description = "Product Label"

    name = fields.Char("Name",
                       required=True,
                       translate=True,
                       help="Name of the sale label")
    font_html_color = fields.Char(
        string='Font Color',
        help=
        "Here you can set a specific HTML color index (e.g. #ff0000) to display the color of product label text."
    )
    html_color = fields.Char(
        string='Color',
        help=
        "Here you can set a specific HTML color index (e.g. #ff0000) to display the color of product label."
    )
    label_style = fields.Selection([('style_1', 'Style 1'),
                                    ('style_2', 'Style 2'),
                                    ('style_3', 'Style 3'),
                                    ('style_4', 'Style 4'),
                                    ('style_5', 'Style 5')],
                                   string="Select the style for label",
                                   required=True,
                                   default='style_1',
                                   readonly=False)
Пример #24
0
class LandedCostLine(models.Model):
    _name = 'stock.landed.cost.lines'
    _description = 'Stock Landed Cost Line'

    name = fields.Char('Description')
    cost_id = fields.Many2one('stock.landed.cost',
                              'Landed Cost',
                              required=True,
                              ondelete='cascade')
    product_id = fields.Many2one('product.product', 'Product', required=True)
    price_unit = fields.Float('Cost', digits='Product Price', required=True)
    split_method = fields.Selection(SPLIT_METHOD,
                                    string='Split Method',
                                    required=True)
    account_id = fields.Many2one('account.account',
                                 'Account',
                                 domain=[('deprecated', '=', False)])

    @api.onchange('product_id')
    def onchange_product_id(self):
        if not self.product_id:
            self.quantity = 0.0
        self.name = self.product_id.name or ''
        self.split_method = self.split_method or 'equal'
        self.price_unit = self.product_id.standard_price or 0.0
        accounts_data = self.product_id.product_tmpl_id.get_product_accounts()
        self.account_id = accounts_data['stock_input']
Пример #25
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()
Пример #26
0
class ResConfigSettings(models.TransientModel):
    _inherit = 'res.config.settings'

    auth_signup_reset_password = fields.Boolean(
        string='Enable password reset from Login page',
        config_parameter='auth_signup.reset_password')
    auth_signup_uninvited = fields.Selection(
        [
            ('b2b', 'On invitation'),
            ('b2c', 'Free sign up'),
        ],
        string='Customer Account',
        default='b2b',
        config_parameter='auth_signup.invitation_scope')
    auth_signup_template_user_id = fields.Many2one(
        'res.users',
        string='Template user for new users created through signup',
        config_parameter='base.template_portal_user_id')

    def open_template_user(self):
        action = self.env.ref('base.action_res_users').read()[0]
        action['res_id'] = literal_eval(
            self.env['ir.config_parameter'].sudo().get_param(
                'base.template_portal_user_id', 'False'))
        action['views'] = [[self.env.ref('base.view_users_form').id, 'form']]
        return action
Пример #27
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)
Пример #28
0
class ResConfigSettings(models.TransientModel):
    _inherit = 'res.config.settings'

    inventory_availability = fields.Selection([
        ('never', 'Sell regardless of inventory'),
        ('always', 'Show inventory on website and prevent sales if not enough stock'),
        ('threshold', 'Show inventory when below the threshold and prevent sales if not enough stock'),
        ('custom', 'Show product-specific notifications'),
    ], string='Inventory Availability', default='never')
    available_threshold = fields.Float(string='Availability Threshold')
    website_warehouse_id = fields.Many2one('stock.warehouse', related='website_id.warehouse_id', domain="[('company_id', '=', website_company_id)]", readonly=False)

    def set_values(self):
        super(ResConfigSettings, self).set_values()
        IrDefault = self.env['ir.default'].sudo()
        IrDefault.set('product.template', 'inventory_availability', self.inventory_availability)
        IrDefault.set('product.template', 'available_threshold', self.available_threshold if self.inventory_availability == 'threshold' else None)

    @api.model
    def get_values(self):
        res = super(ResConfigSettings, self).get_values()
        IrDefault = self.env['ir.default'].sudo()
        res.update(inventory_availability=IrDefault.get('product.template', 'inventory_availability') or 'never',
                   available_threshold=IrDefault.get('product.template', 'available_threshold') or 5.0)
        return res

    @api.onchange('website_company_id')
    def _onchange_website_company_id(self):
        if self.website_warehouse_id.company_id != self.website_company_id:
            return {'value': {'website_warehouse_id': False}}
Пример #29
0
class Notification(models.Model):
    _inherit = 'mail.notification'

    notification_type = fields.Selection(selection_add=[('sms', 'SMS')])
    sms_id = fields.Many2one('sms.sms',
                             string='SMS',
                             index=True,
                             ondelete='set null')
    sms_number = fields.Char('SMS Number')
    failure_type = fields.Selection(selection_add=[(
        'sms_number_missing',
        'Missing Number'), (
            'sms_number_format',
            'Wrong Number Format'), (
                'sms_credit',
                'Insufficient Credit'), ('sms_server', 'Server Error')])
Пример #30
0
class Users(models.Model):
    _inherit = 'res.users'
    harpiyabot_state = fields.Selection(
        [
            ('not_initialized', 'Not initialized'),
            ('onboarding_emoji', 'Onboarding emoji'),
            ('onboarding_attachement', 'Onboarding attachement'),
            ('onboarding_command', 'Onboarding command'),
            ('onboarding_ping', 'Onboarding ping'),
            ('idle', 'Idle'),
            ('disabled', 'Disabled'),
        ],
        string="HarpiyaBot Status",
        readonly=True,
        required=True,
        default="not_initialized"
    )  # keep track of the state: correspond to the code of the last message sent

    def __init__(self, pool, cr):
        """ Override of __init__ to add access rights.
            Access rights are disabled by default, but allowed
            on some specific fields defined in self.SELF_{READ/WRITE}ABLE_FIELDS.
        """
        init_res = super(Users, self).__init__(pool, cr)
        # duplicate list to avoid modifying the original reference
        type(self).SELF_READABLE_FIELDS = type(self).SELF_READABLE_FIELDS + [
            'harpiyabot_state'
        ]
        return init_res