Ejemplo n.º 1
0
class BaseLanguageExport(models.TransientModel):
    _name = "base.language.export"

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

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

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

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

        filename = 'new'
        if lang:
            filename = tools.get_iso_codes(lang)
        elif len(mods) == 1:
            filename = mods[0]
        extension = this.format
        if not lang and extension == 'po':
            extension = 'pot'
        name = "%s.%s" % (filename, extension)
        this.write({'state': 'get', 'data': out, 'name': name})
        return {
            'type': 'ir.actions.act_window',
            'res_model': 'base.language.export',
            'view_mode': 'form',
            'view_type': 'form',
            'res_id': this.id,
            'views': [(False, 'form')],
            'target': 'new',
        }
Ejemplo n.º 2
0
class test_model(models.Model):
    _name = 'test_converter.test_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()
    date = fields.Date()
    datetime = fields.Datetime()
    selection = fields.Selection([
        (1, "réponse A"),
        (2, "réponse B"),
        (3, "réponse C"),
        (4, "réponse <D>"),
    ])
    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)
Ejemplo n.º 3
0
class Company(models.Model):
    _inherit = 'res.company'

    po_lead = fields.Float(
        string='Purchase Lead Time',
        required=True,
        help="Margin of error for vendor lead times. When the system "
        "generates Purchase Orders for procuring products, "
        "they will be scheduled that many days earlier "
        "to cope with unexpected vendor delays.",
        default=0.0)

    po_lock = fields.Selection(
        [('edit', 'Allow to edit purchase orders'),
         ('lock', 'Confirmed purchase orders are not editable')],
        string="Purchase Order Modification",
        default="edit",
        help=
        'Purchase Order Modification used when you want to purchase order editable after confirm'
    )

    po_double_validation = fields.Selection(
        [('one_step', 'Confirm purchase orders in one step'),
         ('two_step', 'Get 2 levels of approvals to confirm a purchase order')
         ],
        string="Levels of Approvals",
        default='one_step',
        help="Provide a double validation mechanism for purchases")

    po_double_validation_amount = fields.Monetary(
        string='Double validation amount',
        default=5000,
        help="Minimum amount for which a double validation is required")
Ejemplo n.º 4
0
class ConverterTest(models.Model):
    _name = '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()
    date = fields.Date()
    datetime = fields.Datetime()
    selection = fields.Selection([
        (1, "réponse A"),
        (2, "réponse B"),
        (3, "réponse C"),
        (4, "réponse <D>"),
    ])
    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()
Ejemplo n.º 5
0
class PurchaseRequisitionType(models.Model):
    _name = "purchase.requisition.type"
    _description = "Purchase Agreement 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')
Ejemplo n.º 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 self.env['res.lang'].get_available()

    lang = fields.Selection(_get_languages,
                            string='Language',
                            required=True,
                            default=_default_language)
    overwrite = fields.Boolean(
        'Overwrite Existing Terms',
        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')

    @api.multi
    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'
        return {
            'name': _('Language Pack'),
            'view_type': 'form',
            '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',
        }
Ejemplo n.º 7
0
class ResConfigSettings(models.TransientModel):
    _inherit = 'res.config.settings'

    lock_confirmed_po = fields.Boolean(
        "Lock Confirmed Orders",
        default=lambda self: self.env.user.company_id.po_lock == 'lock')
    po_lock = fields.Selection(related='company_id.po_lock',
                               string="Purchase Order Modification *")
    po_order_approval = fields.Boolean(
        "Order Approval",
        default=lambda self: self.env.user.company_id.po_double_validation ==
        'two_step')
    po_double_validation = fields.Selection(
        related='company_id.po_double_validation',
        string="Levels of Approvals *")
    po_double_validation_amount = fields.Monetary(
        related='company_id.po_double_validation_amount',
        string="Minimum Amount",
        currency_field='company_currency_id')
    company_currency_id = fields.Many2one(
        'res.currency',
        related='company_id.currency_id',
        readonly=True,
        help='Utility field to express amount currency')
    default_purchase_method = fields.Selection(
        [
            ('purchase', 'Ordered quantities'),
            ('receive', 'Delivered 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")
    module_purchase_requisition = fields.Boolean("Purchase Agreements")
    group_warning_purchase = fields.Boolean(
        "Warnings", implied_group='purchase.group_warning_purchase')
    module_stock_dropshipping = fields.Boolean("Dropshipping")
    group_manage_vendor_price = fields.Boolean(
        "Vendor Pricelists",
        implied_group="purchase.group_manage_vendor_price")
    is_installed_sale = fields.Boolean(string="Is the Sale Module Installed")
    group_analytic_account_for_purchases = fields.Boolean(
        'Analytic accounting for purchases',
        implied_group='purchase.group_analytic_accounting')

    @api.multi
    def get_values(self):
        res = super(ResConfigSettings, self).get_values()
        res.update(is_installed_sale=self.env['ir.module.module'].search([(
            'name', '=', 'sale'), ('state', '=', 'installed')]).id)
        return res

    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'
Ejemplo n.º 8
0
class report_paperformat(models.Model):
    _name = "report.paperformat"
    _description = "Allows customization of a report."

    name = fields.Char('Name', required=True)
    default = fields.Boolean('Default paper format ?')
    format = fields.Selection(
        [('A0', 'A0  5   841 x 1189 mm'), ('A1', 'A1  6   594 x 841 mm'),
         ('A2', 'A2  7   420 x 594 mm'), ('A3', 'A3  8   297 x 420 mm'),
         ('A4', 'A4  0   210 x 297 mm, 8.26 x 11.69 inches'),
         ('A5', 'A5  9   148 x 210 mm'), ('A6', 'A6  10  105 x 148 mm'),
         ('A7', 'A7  11  74 x 105 mm'), ('A8', 'A8  12  52 x 74 mm'),
         ('A9', 'A9  13  37 x 52 mm'), ('B0', 'B0  14  1000 x 1414 mm'),
         ('B1', 'B1  15  707 x 1000 mm'), ('B2', 'B2  17  500 x 707 mm'),
         ('B3', 'B3  18  353 x 500 mm'), ('B4', 'B4  19  250 x 353 mm'),
         ('B5', 'B5  1   176 x 250 mm, 6.93 x 9.84 inches'),
         ('B6', 'B6  20  125 x 176 mm'), ('B7', 'B7  21  88 x 125 mm'),
         ('B8', 'B8  22  62 x 88 mm'), ('B9', 'B9  23  33 x 62 mm'),
         ('B10', ':B10    16  31 x 44 mm'), ('C5E', 'C5E 24  163 x 229 mm'),
         ('Comm10E', 'Comm10E 25  105 x 241 mm, U.S. '
          'Common 10 Envelope'), ('DLE', 'DLE 26 110 x 220 mm'),
         ('Executive', 'Executive 4   7.5 x 10 inches, '
          '190.5 x 254 mm'), ('Folio', 'Folio 27  210 x 330 mm'),
         ('Ledger', 'Ledger  28  431.8 x 279.4 mm'),
         ('Legal', 'Legal    3   8.5 x 14 inches, '
          '215.9 x 355.6 mm'),
         ('Letter', 'Letter 2 8.5 x 11 inches, '
          '215.9 x 279.4 mm'), ('Tabloid', 'Tabloid 29 279.4 x 431.8 mm'),
         ('custom', 'Custom')],
        'Paper size',
        default='A4',
        help="Select Proper Paper size")
    margin_top = fields.Float('Top Margin (mm)', default=40)
    margin_bottom = fields.Float('Bottom Margin (mm)', default=20)
    margin_left = fields.Float('Left Margin (mm)', default=7)
    margin_right = fields.Float('Right Margin (mm)', default=7)
    page_height = fields.Integer('Page height (mm)', default=False)
    page_width = fields.Integer('Page width (mm)', default=False)
    orientation = fields.Selection([('Landscape', 'Landscape'),
                                    ('Portrait', 'Portrait')],
                                   'Orientation',
                                   default='Landscape')
    header_line = fields.Boolean('Display a header line', default=False)
    header_spacing = fields.Integer('Header spacing', default=35)
    dpi = fields.Integer('Output DPI', required=True, default=90)
    report_ids = fields.One2many('ir.actions.report',
                                 'paperformat_id',
                                 'Associated reports',
                                 help="Explicitly associated reports")

    @api.constrains('format')
    def _check_format_or_page(self):
        if self.filtered(lambda x: x.format != 'custom' and
                         (x.page_width or x.page_height)):
            raise ValidationError(
                _('Error ! You cannot select a format AND specific page width/height.'
                  ))
Ejemplo n.º 9
0
class account_financial_report(models.Model):
    _name = "account.financial.report"
    _description = "Account Report"

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

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

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

    @api.multi
    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)

    @api.multi
    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)
Ejemplo n.º 11
0
class ProductCategory(models.Model):
    _inherit = 'product.category'

    property_valuation = fields.Selection([
        ('manual_periodic', 'Manual'),
        ('real_time', 'Automated')], string='Inventory Valuation',
        company_dependent=True, copy=True, required=True,
        help="""Manual: The accounting entries to value the inventory are not posted automatically.
        Automated: An accounting entry is automatically created to value the inventory when a product enters or leaves the company.
        """)
    property_cost_method = fields.Selection([
        ('standard', 'Standard Price'),
        ('fifo', 'First In First Out (FIFO)'),
        ('average', 'Average Cost (AVCO)')], string="Costing Method",
        company_dependent=True, copy=True, required=True,
        help="""Standard Price: The products are valued at their standard cost defined on the product.
        Average Cost (AVCO): The products are valued at weighted average cost.
        First In First Out (FIFO): The products are valued supposing those that enter the company first will also leave it first.
        """)
    property_stock_journal = fields.Many2one(
        'account.journal', 'Stock Journal', company_dependent=True,
        help="When doing real-time inventory valuation, this is the Accounting Journal in which entries will be automatically posted when stock moves are processed.")
    property_stock_account_input_categ_id = fields.Many2one(
        'account.account', 'Stock Input Account', company_dependent=True,
        domain=[('deprecated', '=', False)], oldname="property_stock_account_input_categ",
        help="When doing real-time inventory valuation, counterpart journal items for all incoming stock moves will be posted in this account, unless "
             "there is a specific valuation account set on the source location. This is the default value for all products in this category. It "
             "can also directly be set on each product")
    property_stock_account_output_categ_id = fields.Many2one(
        'account.account', 'Stock Output Account', company_dependent=True,
        domain=[('deprecated', '=', False)], oldname="property_stock_account_output_categ",
        help="When doing real-time inventory valuation, counterpart journal items for all outgoing stock moves will be posted in this account, unless "
             "there is a specific valuation account set on the destination location. This is the default value for all products in this category. It "
             "can also directly be set on each product")
    property_stock_valuation_account_id = fields.Many2one(
        'account.account', 'Stock Valuation Account', company_dependent=True,
        domain=[('deprecated', '=', False)],
        help="When real-time inventory valuation is enabled on a product, this account will hold the current value of the products.",)

    @api.onchange('property_cost_method')
    def onchange_property_valuation(self):
        if not self._origin:
            # don't display the warning when creating a product category
            return
        return {
            'warning': {
                'title': _("Warning"),
                'message': _("Changing your cost method is an important change that will impact your inventory valuation. Are you sure you want to make that change?"),
            }
        }
Ejemplo n.º 12
0
class AccountAssetCategory(models.Model):
    _name = 'account.asset.category'
    _description = 'Asset category'

    active = fields.Boolean(default=True)
    name = fields.Char(required=True, index=True, string="Asset Type")
    account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account')
    account_asset_id = fields.Many2one('account.account', string='Asset Account', required=True, domain=[('internal_type','=','other'), ('deprecated', '=', False)], help="Account used to record the purchase of the asset at its original price.")
    account_depreciation_id = fields.Many2one('account.account', string='Depreciation Entries: Asset Account', required=True, domain=[('internal_type','=','other'), ('deprecated', '=', False)], help="Account used in the depreciation entries, to decrease the asset value.")
    account_depreciation_expense_id = fields.Many2one('account.account', string='Depreciation Entries: Expense Account', required=True, domain=[('internal_type','=','other'), ('deprecated', '=', False)], oldname='account_income_recognition_id', help="Account used in the periodical entries, to record a part of the asset as expense.")
    journal_id = fields.Many2one('account.journal', string='Journal', required=True)
    company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env['res.company']._company_default_get('account.asset.category'))
    method = fields.Selection([('linear', 'Linear'), ('degressive', 'Degressive')], string='Computation Method', required=True, default='linear',
        help="Choose the method to use to compute the amount of depreciation lines.\n"
            "  * Linear: Calculated on basis of: Gross Value / Number of Depreciations\n"
            "  * Degressive: Calculated on basis of: Residual Value * Degressive Factor")
    method_number = fields.Integer(string='Number of Depreciations', default=5, help="The number of depreciations needed to depreciate your asset")
    method_period = fields.Integer(string='Period Length', default=1, help="State here the time between 2 depreciations, in months", required=True)
    method_progress_factor = fields.Float('Degressive Factor', default=0.3)
    method_time = fields.Selection([('number', 'Number of Entries'), ('end', 'Ending Date')], string='Time Method', required=True, default='number',
        help="Choose the method to use to compute the dates and number of entries.\n"
           "  * Number of Entries: Fix the number of entries and the time between 2 depreciations.\n"
           "  * Ending Date: Choose the time between 2 depreciations and the date the depreciations won't go beyond.")
    method_end = fields.Date('Ending date')
    prorata = fields.Boolean(string='Prorata Temporis', help='Indicates that the first depreciation entry for this asset have to be done from the purchase date instead of the first of January')
    open_asset = fields.Boolean(string='Auto-confirm Assets', help="Check this if you want to automatically confirm the assets of this category when created by invoices.")
    group_entries = fields.Boolean(string='Group Journal Entries', help="Check this if you want to group the generated entries by categories.")
    type = fields.Selection([('sale', 'Sale: Revenue Recognition'), ('purchase', 'Purchase: Asset')], required=True, index=True, default='purchase')

    @api.onchange('account_asset_id')
    def onchange_account_asset(self):
        if self.type == "purchase":
            self.account_depreciation_id = self.account_asset_id
        elif self.type == "sale":
            self.account_depreciation_expense_id = self.account_asset_id

    @api.onchange('type')
    def onchange_type(self):
        if self.type == 'sale':
            self.prorata = True
            self.method_period = 1
        else:
            self.method_period = 12

    @api.onchange('method_time')
    def _onchange_method_time(self):
        if self.method_time != 'number':
            self.prorata = False
Ejemplo n.º 13
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 below a threshold and prevent sales if not enough stock'
         ),
        ('custom', 'Show product-specific notifications'),
    ],
                                              string='Inventory',
                                              default='never')
    available_threshold = fields.Float(string='Availability Threshold')

    @api.multi
    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
Ejemplo n.º 14
0
class ResPartner(models.Model):
    _inherit = 'res.partner'

    sale_order_count = fields.Integer(compute='_compute_sale_order_count',
                                      string='# of Sales Order')
    sale_order_ids = fields.One2many('sale.order', 'partner_id', 'Sales Order')
    sale_warn = fields.Selection(WARNING_MESSAGE,
                                 'Sales Order',
                                 default='no-message',
                                 help=WARNING_HELP,
                                 required=True)
    sale_warn_msg = fields.Text('Message for Sales Order')

    def _compute_sale_order_count(self):
        sale_data = self.env['sale.order'].read_group(domain=[
            ('partner_id', 'child_of', self.ids)
        ],
                                                      fields=['partner_id'],
                                                      groupby=['partner_id'])
        # read to keep the child/parent relation while aggregating the read_group result in the loop
        partner_child_ids = self.read(['child_ids'])
        mapped_data = dict([(m['partner_id'][0], m['partner_id_count'])
                            for m in sale_data])
        for partner in self:
            # let's obtain the partner id and all its child ids from the read up there
            item = next(p for p in partner_child_ids if p['id'] == partner.id)
            partner_ids = [partner.id] + item.get('child_ids')
            # then we can sum for all the partner's child
            partner.sale_order_count = sum(
                mapped_data.get(child, 0) for child in partner_ids)
Ejemplo n.º 15
0
class ProductPricelist(models.Model):
    _inherit = 'product.pricelist'

    discount_policy = fields.Selection(
        [('with_discount', 'Discount included in the price'),
         ('without_discount', 'Show public price & discount to the customer')],
        default='with_discount')
Ejemplo n.º 16
0
class ModuleDependency(models.Model):
    _name = "ir.module.module.dependency"
    _description = "Module dependency"

    # the dependency name
    name = fields.Char(index=True)

    # the module that depends on it
    module_id = fields.Many2one('ir.module.module', 'Module', ondelete='cascade')

    # the module corresponding to the dependency, and its status
    depend_id = fields.Many2one('ir.module.module', 'Dependency', compute='_compute_depend')
    state = fields.Selection(DEP_STATES, string='Status', compute='_compute_state')

    @api.multi
    @api.depends('name')
    def _compute_depend(self):
        # retrieve all modules corresponding to the dependency names
        names = list(set(dep.name for dep in self))
        mods = self.env['ir.module.module'].search([('name', 'in', names)])

        # index modules by name, and assign dependencies
        name_mod = dict((mod.name, mod) for mod in mods)
        for dep in self:
            dep.depend_id = name_mod.get(dep.name)

    @api.one
    @api.depends('depend_id.state')
    def _compute_state(self):
        self.state = self.depend_id.state or 'unknown'
class HolidaysSummaryEmployee(models.TransientModel):

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

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

    @api.multi
    def print_report(self):
        self.ensure_one()
        [data] = self.read()
        data['emp'] = self.env.context.get('active_ids', [])
        employees = self.env['hr.employee'].browse(data['emp'])
        datas = {'ids': [], 'model': 'hr.employee', 'form': data}
        return self.env.ref(
            'hr_holidays.action_report_holidayssummary').report_action(
                employees, data=datas)
Ejemplo n.º 18
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")
    unicode_source = fields.Char(
        string='Unicode Character',
        help=
        "The source is replaced by this unicode character in the Chat Messages"
    )
    substitution = fields.Text(
        'Substitution',
        required=True,
        index=True,
        help="The escaped html code replacing the shortcut")
    description = fields.Char('Description')
    shortcode_type = fields.Selection([('image', 'Smiley'), ('text', 'Canned Response')], required=True, default='text',
        help="* Smiley are only used for HTML code to display an image "\
             "* Text (default value) is used to substitute text with another text")
Ejemplo n.º 19
0
class BaseModuleUpdate(models.TransientModel):
    _name = "base.module.update"
    _description = "Update Module"

    updated = fields.Integer('Number of modules updated', readonly=True)
    added = fields.Integer('Number of modules added', readonly=True)
    state = fields.Selection([('init', 'init'), ('done', 'done')],
                             'Status',
                             readonly=True,
                             default='init')

    @api.multi
    def update_module(self):
        for this in self:
            updated, added = self.env['ir.module.module'].update_list()
            this.write({'updated': updated, 'added': added, 'state': 'done'})
        return False

    @api.multi
    def action_module_open(self):
        res = {
            'domain': str([]),
            'name': 'Modules',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'ir.module.module',
            'view_id': False,
            'type': 'ir.actions.act_window',
        }
        return res
Ejemplo n.º 20
0
class ModuleExclusion(models.Model):
    _name = "ir.module.module.exclusion"
    _description = "Module exclusion"

    # the exclusion name
    name = fields.Char(index=True)

    # the module that excludes it
    module_id = fields.Many2one('ir.module.module', 'Module', ondelete='cascade')

    # the module corresponding to the exclusion, and its status
    exclusion_id = fields.Many2one('ir.module.module', 'Exclusion Module', compute='_compute_exclusion')
    state = fields.Selection(DEP_STATES, string='Status', compute='_compute_state')

    @api.multi
    @api.depends('name')
    def _compute_exclusion(self):
        # retrieve all modules corresponding to the exclusion names
        names = list(set(excl.name for excl in self))
        mods = self.env['ir.module.module'].search([('name', 'in', names)])

        # index modules by name, and assign dependencies
        name_mod = {mod.name: mod for mod in mods}
        for excl in self:
            excl.exclusion_id = name_mod.get(excl.name)

    @api.one
    @api.depends('exclusion_id.state')
    def _compute_state(self):
        self.state = self.exclusion_id.state or 'unknown'
Ejemplo n.º 21
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
Ejemplo n.º 22
0
class LeadTest(models.Model):
    _name = "base.automation.lead.test"
    _description = "Action Rule Test"

    name = fields.Char(string='Subject', required=True, index=True)
    user_id = fields.Many2one('res.users', string='Responsible')
    state = fields.Selection([('draft', 'New'), ('cancel', 'Cancelled'),
                              ('open', 'In Progress'), ('pending', 'Pending'),
                              ('done', 'Closed')],
                             string="Status",
                             readonly=True,
                             default='draft')
    active = fields.Boolean(default=True)
    partner_id = fields.Many2one('res.partner', string='Partner')
    date_action_last = fields.Datetime(string='Last Action', readonly=True)
    customer = fields.Boolean(related='partner_id.customer',
                              readonly=True,
                              store=True)
    line_ids = fields.One2many('base.automation.line.test', 'lead_id')

    priority = fields.Boolean()
    deadline = fields.Boolean(compute='_compute_deadline', store=True)
    is_assigned_to_admin = fields.Boolean(string='Assigned to admin user')

    @api.depends('priority')
    def _compute_deadline(self):
        for record in self:
            if not record.priority:
                record.deadline = False
            else:
                record.deadline = fields.Datetime.from_string(
                    record.create_date) + relativedelta.relativedelta(days=3)
Ejemplo n.º 23
0
class AccountAccountTag(models.Model):
    _inherit = 'account.account.tag'

    nature = fields.Selection(
        [('D', _('Debitable Account')), ('A', _('Creditable Account'))],
        help='Used in Mexican report of electronic accounting (account nature).'
    )
Ejemplo n.º 24
0
class IrActionsActWindowView(models.Model):
    _name = 'ir.actions.act_window.view'
    _table = 'ir_act_window_view'
    _rec_name = 'view_id'
    _order = 'sequence,id'

    sequence = fields.Integer()
    view_id = fields.Many2one('ir.ui.view', string='View')
    view_mode = fields.Selection(VIEW_TYPES, string='View Type', required=True)
    act_window_id = fields.Many2one('ir.actions.act_window',
                                    string='Action',
                                    ondelete='cascade')
    multi = fields.Boolean(
        string='On Multiple Doc.',
        help=
        "If set to true, the action will not be displayed on the right toolbar of a form view."
    )

    @api.model_cr_context
    def _auto_init(self):
        res = super(IrActionsActWindowView, self)._auto_init()
        tools.create_unique_index(self._cr,
                                  'act_window_view_unique_mode_per_action',
                                  self._table, ['act_window_id', 'view_mode'])
        return res
class AccountReportGeneralLedger(models.TransientModel):
    _inherit = "account.common.account.report"
    _name = "account.report.general.ledger"
    _description = "General Ledger Report"

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

    def _print_report(self, data):
        data = self.pre_print_report(data)
        data['form'].update(self.read(['initial_balance', 'sortby'])[0])
        if data['form'].get(
                'initial_balance') and not data['form'].get('date_from'):
            raise UserError(_("You must define a Start Date"))
        records = self.env[data['model']].browse(data.get('ids', []))
        return self.env.ref(
            'account.action_report_general_ledger').with_context(
                landscape=True).report_action(records, data=data)
Ejemplo n.º 26
0
class ResPartner(models.Model):
    _inherit = 'res.partner'

    l10n_co_document_type = fields.Selection(
        [('rut', 'RUT'), ('id_card', 'Tarjeta de Identidad'),
         ('passport', 'Pasaporte'),
         ('foreign_id_card', 'Cedula de Extranjeria'),
         ('external_id', 'ID del Exterior')],
        string='Document Type',
        help='Indicates to what document the information in here belongs to.')
    l10n_co_verification_code = fields.Char(
        compute='_compute_verification_code',
        string='VC',  # todo remove this field in master
        help=
        'Redundancy check to verify the vat number has been typed in correctly.'
    )

    @api.depends('vat')
    def _compute_verification_code(self):
        multiplication_factors = [
            71, 67, 59, 53, 47, 43, 41, 37, 29, 23, 19, 17, 13, 7, 3
        ]

        for partner in self.filtered(
                lambda partner: partner.vat and partner.country_id == self.env.
                ref('base.co') and len(partner.vat) <= len(
                    multiplication_factors)):
            number = 0
            padded_vat = partner.vat

            while len(padded_vat) < len(multiplication_factors):
                padded_vat = '0' + padded_vat

            # if there is a single non-integer in vat the verification code should be False
            try:
                for index, vat_number in enumerate(padded_vat):
                    number += int(vat_number) * multiplication_factors[index]

                number %= 11

                if number < 2:
                    partner.l10n_co_verification_code = number
                else:
                    partner.l10n_co_verification_code = 11 - number
            except ValueError:
                partner.l10n_co_verification_code = False

    @api.constrains('vat', 'commercial_partner_country_id',
                    'l10n_co_document_type')
    def check_vat(self):
        # check_vat is implemented by base_vat which this localization
        # doesn't directly depend on. It is however automatically
        # installed for Colombia.
        if self.sudo().env.ref('base.module_base_vat').state == 'installed':
            # don't check Colombian partners unless they have RUT (= Colombian VAT) set as document type
            self = self.filtered(lambda partner: partner.country_id != self.env.ref('base.co') or\
                                                 partner.l10n_co_document_type == 'rut')
            return super(ResPartner, self).check_vat()
        else:
            return True
Ejemplo n.º 27
0
class ResourceCalendarLeaves(models.Model):
    _name = "resource.calendar.leaves"
    _description = "Leave Detail"

    name = fields.Char('Reason')
    company_id = fields.Many2one(
        'res.company', related='calendar_id.company_id', string="Company",
        readonly=True, store=True)
    calendar_id = fields.Many2one('resource.calendar', 'Working Hours')
    date_from = fields.Datetime('Start Date', required=True)
    date_to = fields.Datetime('End Date', required=True)
    tz = fields.Selection(
        _tz_get, string='Timezone', default=lambda self: self._context.get('tz') or self.env.user.tz or 'UTC',
        help="Timezone used when encoding the leave. It is used to correctly "
             "localize leave hours when computing time intervals.")
    resource_id = fields.Many2one(
        "resource.resource", 'Resource',
        help="If empty, this is a generic holiday for the company. If a resource is set, the holiday/leave is only for this resource")

    @api.constrains('date_from', 'date_to')
    def check_dates(self):
        if self.filtered(lambda leave: leave.date_from > leave.date_to):
            raise ValidationError(_('Error! leave start-date must be lower then leave end-date.'))

    @api.onchange('resource_id')
    def onchange_resource(self):
        if self.resource_id:
            self.calendar_id = self.resource_id.calendar_id
Ejemplo n.º 28
0
class BaseUpdateTranslations(models.TransientModel):
    _name = 'base.update.translations'

    @api.model
    def _get_languages(self):
        langs = self.env['res.lang'].search([('active', '=', True),
                                             ('translatable', '=', True)])
        return [(lang.code, lang.name) for lang in langs]

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

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

    @api.multi
    def act_update(self):
        this = self[0]
        lang_name = self._get_lang_name(this.lang)
        with contextlib.closing(io.BytesIO()) as buf:
            tools.trans_export(this.lang, ['all'], buf, 'csv', self._cr)
            tools.trans_load_data(self._cr,
                                  buf,
                                  'csv',
                                  this.lang,
                                  lang_name=lang_name)
        return {'type': 'ir.actions.act_window_close'}
Ejemplo n.º 29
0
class Vote(models.Model):
    _name = 'forum.post.vote'
    _description = 'Vote'

    post_id = fields.Many2one('forum.post', string='Post', ondelete='cascade', required=True)
    user_id = fields.Many2one('res.users', string='User', required=True, default=lambda self: self._uid)
    vote = fields.Selection([('1', '1'), ('-1', '-1'), ('0', '0')], string='Vote', required=True, default='1')
    create_date = fields.Datetime('Create Date', index=True, readonly=True)
    forum_id = fields.Many2one('forum.forum', string='Forum', related="post_id.forum_id", store=True)
    recipient_id = fields.Many2one('res.users', string='To', related="post_id.create_uid", store=True)

    def _get_karma_value(self, old_vote, new_vote, up_karma, down_karma):
        _karma_upd = {
            '-1': {'-1': 0, '0': -1 * down_karma, '1': -1 * down_karma + up_karma},
            '0': {'-1': 1 * down_karma, '0': 0, '1': up_karma},
            '1': {'-1': -1 * up_karma + down_karma, '0': -1 * up_karma, '1': 0}
        }
        return _karma_upd[old_vote][new_vote]

    @api.model
    def create(self, vals):
        vote = super(Vote, self).create(vals)

        # own post check
        if vote.user_id.id == vote.post_id.create_uid.id:
            raise UserError(_('Not allowed to vote for its own post'))
        # karma check
        if vote.vote == '1' and not vote.post_id.can_upvote:
            raise KarmaError('Not enough karma to upvote.')
        elif vote.vote == '-1' and not vote.post_id.can_downvote:
            raise KarmaError('Not enough karma to downvote.')

        if vote.post_id.parent_id:
            karma_value = self._get_karma_value('0', vote.vote, vote.forum_id.karma_gen_answer_upvote, vote.forum_id.karma_gen_answer_downvote)
        else:
            karma_value = self._get_karma_value('0', vote.vote, vote.forum_id.karma_gen_question_upvote, vote.forum_id.karma_gen_question_downvote)
        vote.recipient_id.sudo().add_karma(karma_value)
        return vote

    @api.multi
    def write(self, values):
        if 'vote' in values:
            for vote in self:
                # own post check
                if vote.user_id.id == vote.post_id.create_uid.id:
                    raise UserError(_('Not allowed to vote for its own post'))
                # karma check
                if (values['vote'] == '1' or vote.vote == '-1' and values['vote'] == '0') and not vote.post_id.can_upvote:
                    raise KarmaError('Not enough karma to upvote.')
                elif (values['vote'] == '-1' or vote.vote == '1' and values['vote'] == '0') and not vote.post_id.can_downvote:
                    raise KarmaError('Not enough karma to downvote.')

                # karma update
                if vote.post_id.parent_id:
                    karma_value = self._get_karma_value(vote.vote, values['vote'], vote.forum_id.karma_gen_answer_upvote, vote.forum_id.karma_gen_answer_downvote)
                else:
                    karma_value = self._get_karma_value(vote.vote, values['vote'], vote.forum_id.karma_gen_question_upvote, vote.forum_id.karma_gen_question_downvote)
                vote.recipient_id.sudo().add_karma(karma_value)
        res = super(Vote, self).write(values)
        return res
Ejemplo n.º 30
0
class LunchCashMove(models.Model):
    """ Two types of cashmoves: payment (credit) or order (debit) """
    _name = 'lunch.cashmove'
    _description = 'lunch cashmove'

    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,
        help=
        'Can be positive (payment) or negative (order or payment if user wants to get his money back)'
    )
    description = fields.Text('Description',
                              help='Can be an order or a payment')
    order_id = fields.Many2one('lunch.order.line', 'Order', ondelete='cascade')
    state = fields.Selection([('order', 'Order'), ('payment', 'Payment')],
                             'Is an order or a payment',
                             default='payment')

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