class AccountAnalyticLine(models.Model): _inherit = 'account.analytic.line' _description = 'Analytic Line' _order = 'date desc' amount = fields.Monetary(currency_field='company_currency_id') product_uom_id = fields.Many2one('product.uom', string='Unit of Measure') product_id = fields.Many2one('product.product', string='Product') general_account_id = fields.Many2one('account.account', string='Financial Account', ondelete='restrict', readonly=True, related='move_id.account_id', store=True, domain=[('deprecated', '=', False)]) move_id = fields.Many2one('account.move.line', string='Move Line', ondelete='cascade', index=True) code = fields.Char(size=8) ref = fields.Char(string='Ref.') company_currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True, help='Utility field to express amount currency') currency_id = fields.Many2one('res.currency', related='move_id.currency_id', string='Account Currency', store=True, help="The related account currency if not equal to the company one.", readonly=True) amount_currency = fields.Monetary(related='move_id.amount_currency', store=True, help="The amount expressed in the related account currency if not equal to the company one.", readonly=True) analytic_amount_currency = fields.Monetary(string='Amount Currency', compute="_get_analytic_amount_currency", help="The amount expressed in the related account currency if not equal to the company one.", readonly=True) partner_id = fields.Many2one('res.partner', related='account_id.partner_id', string='Partner', store=True, readonly=True) def _get_analytic_amount_currency(self): for line in self: line.analytic_amount_currency = abs(line.amount_currency) * copysign(1, line.amount) @api.v8 @api.onchange('product_id', 'product_uom_id', 'unit_amount', 'currency_id') def on_change_unit_amount(self): if not self.product_id: return {} result = 0.0 prod_accounts = self.product_id.product_tmpl_id._get_product_accounts() unit = self.product_uom_id account = prod_accounts['expense'] if not unit or self.product_id.uom_po_id.category_id.id != unit.category_id.id: unit = self.product_id.uom_po_id # Compute based on pricetype amount_unit = self.product_id.price_compute('standard_price', uom=unit)[self.product_id.id] amount = amount_unit * self.unit_amount or 0.0 result = self.currency_id.round(amount) * -1 self.amount = result self.general_account_id = account self.product_uom_id = unit @api.model def view_header_get(self, view_id, view_type): context = (self._context or {}) header = False if context.get('account_id', False): analytic_account = self.env['account.analytic.account'].search([('id', '=', context['account_id'])], limit=1) header = _('Entries: ') + (analytic_account.name or '') return header
class SaleOrderTax(models.Model): _name = "sale.order.tax" _description = "Sale Tax" _order = 'sequence' def _compute_base_amount(self): tax_grouped = {} for sale in self.mapped('sale_id'): tax_grouped[sale.id] = sale.get_taxes_values() for tax in self: tax.base = 0.0 if tax.tax_id: key = tax.tax_id.get_grouping_key({ 'tax_id': tax.tax_id.id, 'account_id': tax.account_id.id, 'account_analytic_id': tax.account_analytic_id.id, }) if tax.sale_id and key in tax_grouped[tax.sale_id.id]: tax.base = tax_grouped[tax.sale_id.id][key]['base'] # else: # raise Warning('Tax Base Amount not computable probably due to a change in an underlying tax (%s).', tax.tax_id.name) sale_id = fields.Many2one('sale.order', string='Sale', ondelete='cascade', index=True) name = fields.Char(string='Tax Description', required=True) tax_id = fields.Many2one('account.tax', string='Tax', ondelete='restrict') account_id = fields.Many2one('account.account', string='Tax Account', required=True, domain=[('deprecated', '=', False)]) account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic account') amount = fields.Monetary() manual = fields.Boolean(default=True) sequence = fields.Integer( help="Gives the sequence order when displaying a list of invoice tax.") company_id = fields.Many2one('res.company', string='Company', related='account_id.company_id', store=True, readonly=True) currency_id = fields.Many2one('res.currency', related='sale_id.currency_id', store=True, readonly=True) base = fields.Monetary(string='Base', compute='_compute_base_amount')
class SaleOrder(models.Model): _inherit = "sale.order" margin = fields.Monetary("Margin", compute='_compute_margin', store=True) margin_percent = fields.Float("Margin (%)", compute='_compute_margin', store=True) @api.depends('order_line.margin', 'amount_untaxed') def _compute_margin(self): if not all(self._ids): for order in self: order.margin = sum(order.order_line.mapped('margin')) order.margin_percent = order.amount_untaxed and order.margin / order.amount_untaxed else: self.env["sale.order.line"].flush(['margin']) # On batch records recomputation (e.g. at install), compute the margins # with a single read_group query for better performance. # This isn't done in an onchange environment because (part of) the data # may not be stored in database (new records or unsaved modifications). grouped_order_lines_data = self.env['sale.order.line'].read_group([ ('order_id', 'in', self.ids), ], ['margin', 'order_id'], ['order_id']) mapped_data = { m['order_id'][0]: m['margin'] for m in grouped_order_lines_data } for order in self: order.margin = mapped_data.get(order.id, 0.0) order.margin_percent = order.amount_untaxed and order.margin / order.amount_untaxed
class StockLandedCostLine(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.Monetary('Cost', required=True) split_method = fields.Selection( SPLIT_METHOD, string='Split Method', required=True, help="Equal : Cost will be equally divided.\n" "By Quantity : Cost will be divided according to product's quantity.\n" "By Current cost : Cost will be divided according to product's current cost.\n" "By Weight : Cost will be divided depending on its weight.\n" "By Volume : Cost will be divided depending on its volume.") account_id = fields.Many2one('account.account', 'Account', domain=[('deprecated', '=', False)]) currency_id = fields.Many2one('res.currency', related='cost_id.currency_id') @api.onchange('product_id') def onchange_product_id(self): self.name = self.product_id.name or '' self.split_method = self.product_id.product_tmpl_id.split_method_landed_cost or 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']
class MixedModel(models.Model): _name = 'test_new_api.mixed' number = fields.Float(digits=(10, 2), default=3.14) date = fields.Date() 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() @api.one def _compute_now(self): # this is a non-stored computed field without dependencies self.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.')]
class FloatModel(models.Model): _name = model('float') _description = 'Tests: Base Import Model Float' value = fields.Float() value2 = fields.Monetary() currency_id = fields.Many2one('res.currency')
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")
class Digest(models.Model): _inherit = 'digest.digest' kpi_website_sale_total = fields.Boolean('eCommerce Sales') kpi_website_sale_total_value = fields.Monetary( compute='_compute_kpi_website_sale_total_value') def _compute_kpi_website_sale_total_value(self): if not self.env.user.has_group( 'sales_team.group_sale_salesman_all_leads'): raise AccessError( _("Do not have access, skip this data for user's digest email") ) for record in self: start, end, company = record._get_kpi_compute_parameters() confirmed_website_sales = self.env['sale.order'].search([ ('confirmation_date', '>=', start), ('confirmation_date', '<', end), ('state', 'not in', ['draft', 'cancel', 'sent']), ('team_id.team_type', '=', 'website'), ('company_id', '=', company.id) ]) record.kpi_website_sale_total_value = sum( confirmed_website_sales.mapped('amount_total')) def compute_kpis_actions(self, company, user): res = super(Digest, self).compute_kpis_actions(company, user) res['kpi_website_sale_total'] = 'website.backend_dashboard&menu_id=%s' % self.env.ref( 'website.menu_website_configuration').id return res
class Digest(models.Model): _inherit = 'digest.digest' kpi_all_sale_total = fields.Boolean('All Sales') kpi_all_sale_total_value = fields.Monetary( compute='_compute_kpi_sale_total_value') def _compute_kpi_sale_total_value(self): if not self.env.user.has_group( 'sales_team.group_sale_salesman_all_leads'): raise AccessError( _("Do not have access, skip this data for user's digest email") ) for record in self: start, end, company = record._get_kpi_compute_parameters() all_channels_sales = self.env['sale.report'].read_group( [('confirmation_date', '>=', start), ('confirmation_date', '<', end), ('company_id', '=', company.id)], ['price_total'], ['price_total']) record.kpi_all_sale_total_value = sum([ channel_sale['price_total'] for channel_sale in all_channels_sales ]) def compute_kpis_actions(self, company, user): res = super(Digest, self).compute_kpis_actions(company, user) res['kpi_all_sale_total'] = 'sale.report_all_channels_sales_action&menu_id=%s' % self.env.ref( 'sale.sale_menu_root').id return res
class AccountInvoiceLine(models.Model): _inherit = 'account.invoice.line' _order = 'invoice_id, layout_category_id, sequence, id' @api.depends('price_unit', 'discount', 'invoice_line_tax_ids', 'quantity', 'product_id', 'invoice_id.partner_id', 'invoice_id.currency_id', 'invoice_id.company_id', 'invoice_id.date_invoice') def _compute_total_price(self): for line in self: price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) taxes = line.invoice_line_tax_ids.compute_all( price, line.invoice_id.currency_id, line.quantity, product=line.product_id, partner=line.invoice_id.partner_id) line.price_total = taxes['total_included'] sale_line_ids = fields.Many2many('sale.order.line', 'sale_order_line_invoice_rel', 'invoice_line_id', 'order_line_id', string='Sales Order Lines', readonly=True, copy=False) layout_category_id = fields.Many2one('sale.layout_category', string='Section') layout_category_sequence = fields.Integer(string='Layout Sequence') # TODO: remove layout_category_sequence in master or make it work properly price_total = fields.Monetary(compute='_compute_total_price', string='Total Amount', store=True)
class HrPayslipLine(models.Model): _name = 'hr.payslip.line' _inherit = 'hr.salary.rule' _description = 'Payslip Line' _order = 'contract_id, sequence' slip_id = fields.Many2one('hr.payslip', string='Pay Slip', required=True, ondelete='cascade') salary_rule_id = fields.Many2one('hr.salary.rule', string='Rule', required=True) employee_id = fields.Many2one('hr.employee', string='Employee', required=True) contract_id = fields.Many2one('hr.contract', string='Contract', required=True, index=True) rate = fields.Float(string='Rate (%)', digits=dp.get_precision('Payroll Rate'), default=100.0) amount = fields.Float(digits=dp.get_precision('Payroll')) quantity = fields.Float(digits=dp.get_precision('Payroll'), default=1.0) total = fields.Monetary(compute='_compute_total', string='Total', digits=dp.get_precision('Payroll'), store=True, currency_field='company_currency_id') company_currency_id = fields.Many2one( 'res.currency', related='employee_id.company_id.currency_id', string="Company Currency", readonly=True) @api.depends('quantity', 'amount', 'rate') def _compute_total(self): for line in self: line.total = float(line.quantity) * line.amount * line.rate / 100 @api.model def create(self, values): if 'employee_id' not in values or 'contract_id' not in values: payslip = self.env['hr.payslip'].browse(values.get('slip_id')) values['employee_id'] = values.get('employee_id') or payslip.employee_id.id values['contract_id'] = values.get('contract_id') or payslip.contract_id and payslip.contract_id.id if not values['contract_id']: raise UserError(_('You must set a contract to create a payslip line.')) return super(HrPayslipLine, self).create(values)
class Digest(models.Model): _inherit = 'digest.digest' kpi_account_total_revenue = fields.Boolean('Revenue') kpi_account_total_revenue_value = fields.Monetary(compute='_compute_kpi_account_total_revenue_value') def _compute_kpi_account_total_revenue_value(self): if not self.env.user.has_group('account.group_account_invoice'): raise AccessError(_("Do not have access, skip this data for user's digest email")) for record in self: start, end, company = record._get_kpi_compute_parameters() self._cr.execute(''' SELECT -SUM(line.balance) FROM account_move_line line JOIN account_move move ON move.id = line.move_id JOIN account_account account ON account.id = line.account_id WHERE line.company_id = %s AND line.date >= %s AND line.date < %s AND account.internal_group = 'income' AND move.state = 'posted' ''', [company.id, start, end]) query_res = self._cr.fetchone() record.kpi_account_total_revenue_value = query_res and query_res[0] or 0.0 def _compute_kpis_actions(self, company, user): res = super(Digest, self)._compute_kpis_actions(company, user) res['kpi_account_total_revenue'] = 'account.action_move_out_invoice_type&menu_id=%s' % self.env.ref('account.menu_finance').id return res
class Digest(models.Model): _inherit = 'digest.digest' kpi_pos_total = fields.Boolean('POS Sales') kpi_pos_total_value = fields.Monetary( compute='_compute_kpi_pos_total_value') def _compute_kpi_pos_total_value(self): if not self.env.user.has_group('point_of_sale.group_pos_user'): raise AccessError( _("Do not have access, skip this data for user's digest email") ) for record in self: start, end, company = record._get_kpi_compute_parameters() record.kpi_pos_total_value = sum(self.env['pos.order'].search([ ('date_order', '>=', start), ('date_order', '<', end), ('state', 'not in', ['draft', 'cancel', 'invoiced']), ('company_id', '=', company.id) ]).mapped('amount_total')) def _compute_kpis_actions(self, company, user): res = super(Digest, self)._compute_kpis_actions(company, user) res['kpi_pos_total'] = 'point_of_sale.action_pos_sale_graph&menu_id=%s' % self.env.ref( 'point_of_sale.menu_point_root').id return res
class Digest(models.Model): _inherit = 'digest.digest' kpi_account_total_revenue = fields.Boolean('Revenue') kpi_account_total_revenue_value = fields.Monetary( compute='_compute_kpi_account_total_revenue_value') def _compute_kpi_account_total_revenue_value(self): if not self.env.user.has_group('account.group_account_invoice'): raise AccessError( _("Do not have access, skip this data for user's digest email") ) for record in self: start, end, company = record._get_kpi_compute_parameters() account_moves = self.env['account.move'].read_group( [('journal_id.type', '=', 'sale'), ('company_id', '=', company.id), ('date', '>=', start), ('date', '<', end)], ['journal_id', 'amount'], ['journal_id']) record.kpi_account_total_revenue_value = sum( [account_move['amount'] for account_move in account_moves]) def compute_kpis_actions(self, company, user): res = super(Digest, self).compute_kpis_actions(company, user) res['kpi_account_total_revenue'] = 'account.action_invoice_tree1&menu_id=%s' % self.env.ref( 'account.menu_finance').id return res
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") module_account_3way_match = fields.Boolean( "3-way matching: purchases, receptions and bills") is_installed_sale = fields.Boolean() 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'
class MonetaryCustom(models.Model): _name = 'test_new_api.monetary_custom' _description = 'Monetary Related Custom' monetary_id = fields.Many2one('test_new_api.monetary_base') x_currency_id = fields.Many2one('res.currency', related='monetary_id.base_currency_id') x_amount = fields.Monetary(related='monetary_id.amount')
class ImpuestosLibro(models.Model): _name = "account.move.book.honorarios.tax" def get_monto(self): for t in self: t.amount = t.debit - t.credit tax_id = fields.Many2one('account.tax', string="Impuesto") credit = fields.Monetary(string="Créditos", default=0.00) debit = fields.Monetary(string="Débitos", default=0.00) amount = fields.Monetary(compute="get_monto", string="Monto") currency_id = fields.Many2one( 'res.currency', string='Moneda', default=lambda self: self.env.user.company_id.currency_id, required=True, track_visibility='always') book_id = fields.Many2one('account.move.book.honorarios', string="Libro")
class ComplexModel(models.Model): _name = model('complex') _description = 'Tests: Base Import Model Complex' f = fields.Float() m = fields.Monetary() c = fields.Char() currency_id = fields.Many2one('res.currency') d = fields.Date() dt = fields.Datetime()
class HrEmployee(models.Model): _inherit = 'hr.employee' timesheet_cost = fields.Monetary('Timesheet Cost', currency_field='currency_id', groups="hr.group_hr_user", default=0.0) currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True)
class HrEmployee(models.Model): _inherit = 'hr.employee' # FIXME: this field should be in module hr_timesheet, not sale_timesheet timesheet_cost = fields.Monetary('Timesheet Cost', currency_field='currency_id', default=0.0) currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True)
class ProcessMailsDocumentLines(models.Model): _name = 'mail.message.dte.document.line' document_id = fields.Many2one( 'mail.message.dte.document', string="Documento", ondelete='cascade', ) product_id = fields.Many2one( 'product.product', string="Producto", ) new_product = fields.Char( string='Nuevo Producto', readonly=True, ) description = fields.Char( string='Descripción', readonly=True, ) product_description = fields.Char( string='Descripción Producto', readonly=True, ) quantity = fields.Float( string="Cantidad", readonly=True, ) price_unit = fields.Monetary( string="Precio Unitario", readonly=True, ) price_subtotal = fields.Monetary( string="Total", readonly=True, ) currency_id = fields.Many2one( 'res.currency', string="Moneda", readonly=True, default=lambda self: self.env.user.company_id.currency_id, )
class MonetaryOrder(models.Model): _name = 'test_new_api.monetary_order' _description = 'Sales Order' currency_id = fields.Many2one('res.currency') line_ids = fields.One2many('test_new_api.monetary_order_line', 'order_id') total = fields.Monetary(compute='_compute_total', store=True) @api.depends('line_ids.subtotal') def _compute_total(self): for record in self: record.total = sum(line.subtotal for line in record.line_ids)
class ResPartner(models.Model): """User inherits partner, so we are implicitly adding these fields to User This essentially reproduces the (sad) situation introduced by account. """ _name = 'res.partner' _inherit = 'res.partner' currency_id = fields.Many2one('res.currency', compute='_get_company_currency', readonly=True) monetary = fields.Monetary() # implicitly depends on currency_id as currency_field def _get_company_currency(self): for partner in self: partner.currency_id = partner.sudo().company_id.currency_id
class StockQuant(models.Model): _inherit = 'stock.quant' value = fields.Monetary('Value', compute='_compute_value', groups='stock.group_stock_manager') currency_id = fields.Many2one('res.currency', compute='_compute_value', groups='stock.group_stock_manager') @api.depends('company_id', 'location_id', 'owner_id', 'product_id', 'quantity') def _compute_value(self): """ For standard and AVCO valuation, compute the current accounting valuation of the quants by multiplying the quantity by the standard price. Instead for FIFO, use the quantity times the average cost (valuation layers are not manage by location so the average cost is the same for all location and the valuation field is a estimation more than a real value). """ for quant in self: quant.currency_id = quant.company_id.currency_id # If the user didn't enter a location yet while enconding a quant. if not quant.location_id: quant.value = 0 return if not quant.location_id._should_be_valued() or\ (quant.owner_id and quant.owner_id != quant.company_id.partner_id): quant.value = 0 continue if quant.product_id.cost_method == 'fifo': quantity = quant.product_id.quantity_svl if float_is_zero(quantity, precision_rounding=quant.product_id.uom_id.rounding): quant.value = 0.0 continue average_cost = quant.product_id.with_company(quant.company_id).value_svl / quantity quant.value = quant.quantity * average_cost else: quant.value = quant.quantity * quant.product_id.with_company(quant.company_id).standard_price @api.model def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True): """ This override is done in order for the grouped list view to display the total value of the quants inside a location. This doesn't work out of the box because `value` is a computed field. """ if 'value' not in fields: return super(StockQuant, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy) res = super(StockQuant, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy) for group in res: if group.get('__domain'): quants = self.search(group['__domain']) group['value'] = sum(quant.value for quant in quants) return res
class AccountInvoice(models.Model): _inherit = "account.invoice" _description = "Account Invoice Paid Amounts" paid_amount = fields.Monetary(string='Paid Amount', compute='_compute_paid_amount', store=True, help="The Paid Amount.") @api.depends('residual') def _compute_paid_amount(self): self.paid_amount = 0.0 if self.state != 'draft': self.paid_amount = self.amount_total - self.residual
class GroupOperator(models.Model): _name = 'export.group_operator' _description = 'Export Group Operator' int_sum = fields.Integer(group_operator='sum') int_max = fields.Integer(group_operator='max') float_min = fields.Float(group_operator='min') float_avg = fields.Float(group_operator='avg') float_monetary = fields.Monetary(currency_field='currency_id',group_operator='sum') currency_id = fields.Many2one('res.currency') date_max = fields.Date(group_operator='max') bool_and = fields.Boolean(group_operator='bool_and') bool_or = fields.Boolean(group_operator='bool_or') many2one = fields.Many2one('export.integer') one2many = fields.One2many('export.group_operator.one2many', 'parent_id')
class SaleOrder(models.Model): _inherit = "sale.order" margin = fields.Monetary( compute='_product_margin', help= "It gives profitability by calculating the difference between the Unit Price and the cost.", currency_field='currency_id', digits=dp.get_precision('Product Price'), store=True) @api.depends('order_line.margin') def _product_margin(self): for order in self: order.margin = sum( order.order_line.filtered( lambda r: r.state != 'cancel').mapped('margin'))
class AccountAnalyticLine(models.Model): _name = 'account.analytic.line' _description = 'Analytic Line' _order = 'date desc, id desc' @api.model def _default_user(self): return self.env.context.get('user_id', self.env.user.id) name = fields.Char('Description', required=True) date = fields.Date('Date', required=True, index=True, default=fields.Date.context_today) amount = fields.Monetary('Amount', required=True, default=0.0) unit_amount = fields.Float('Quantity', default=0.0) account_id = fields.Many2one('account.analytic.account', 'Analytic Account', required=True, ondelete='restrict', index=True) partner_id = fields.Many2one('res.partner', string='Partner') user_id = fields.Many2one('res.users', string='User', default=_default_user) tag_ids = fields.Many2many('account.analytic.tag', 'account_analytic_line_tag_rel', 'line_id', 'tag_id', string='Tags', copy=True) company_id = fields.Many2one(related='account_id.company_id', string='Company', store=True, readonly=True) branch_id = fields.Many2one(related='account_id.branch_id', string='Branch', store=True, readonly=True) currency_id = fields.Many2one(related="company_id.currency_id", string="Currency", readonly=True)
class FleetVehicle(models.Model): _inherit = 'fleet.vehicle' def _get_current_company(self): return self.env.user.company_id.id sale_orders = fields.One2many('sale.order', 'vehicle', string='Sales') sales_amount = fields.Monetary(currency_field='currency_id', compute='get_sales', store=False) sales_count = fields.Integer(compute='get_sales', store=False) sale_ok = fields.Boolean(string='Available in Sales', default=True) currency_id = fields.Many2one('res.currency', related='company_id.currency_id', string='Currency') company_id = fields.Many2one('res.company', default=_get_current_company) @api.one @api.depends('sale_orders') def get_sales(self): self.sales_amount = sum(order.amount_total for order in self.sale_orders.filtered( lambda s: s.state in ('sale', 'done'))) self.sales_count = len( self.sale_orders.filtered(lambda s: s.state in ('sale', 'done'))) @api.multi def act_show_sales(self): action = self.env.ref('sale.action_orders') result = { 'name': action.name, 'help': action.help, 'type': action.type, 'view_type': action.view_type, 'view_mode': action.view_mode, 'target': action.target, 'context': action.context, 'res_model': action.res_model, } result['domain'] = "[('id','in',[" + ','.join( map(str, self.sale_orders.ids)) + "])]" return result
class HrExpenseSheetRegisterPaymentWizard(models.TransientModel): _name = "hr.expense.sheet.register.payment.wizard" _description = "Expense Report Register Payment wizard" @api.model def _default_partner_id(self): context = dict(self._context or {}) active_ids = context.get('active_ids', []) expense_sheet = self.env['hr.expense.sheet'].browse(active_ids) return expense_sheet.address_id.id or expense_sheet.employee_id.id and expense_sheet.employee_id.address_home_id.id partner_id = fields.Many2one('res.partner', string='Partner', required=True, default=_default_partner_id) journal_id = fields.Many2one('account.journal', string='Payment Method', required=True, domain=[('type', 'in', ('bank', 'cash'))]) company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', readonly=True, required=True) payment_method_id = fields.Many2one('account.payment.method', string='Payment Type', required=True) amount = fields.Monetary(string='Payment Amount', required=True) currency_id = fields.Many2one( 'res.currency', string='Currency', required=True, default=lambda self: self.env.user.company_id.currency_id) payment_date = fields.Date(string='Payment Date', default=fields.Date.context_today, required=True) communication = fields.Char(string='Memo') hide_payment_method = fields.Boolean( compute='_compute_hide_payment_method', help= "Technical field used to hide the payment method if the selected journal has only one available which is 'manual'" ) @api.one @api.constrains('amount') def _check_amount(self): if not self.amount > 0.0: raise ValidationError( _('The payment amount must be strictly positive.')) @api.one @api.depends('journal_id') def _compute_hide_payment_method(self): if not self.journal_id: self.hide_payment_method = True return journal_payment_methods = self.journal_id.outbound_payment_method_ids self.hide_payment_method = len( journal_payment_methods ) == 1 and journal_payment_methods[0].code == 'manual' @api.onchange('journal_id') def _onchange_journal(self): if self.journal_id: # Set default payment method (we consider the first to be the default one) payment_methods = self.journal_id.outbound_payment_method_ids self.payment_method_id = payment_methods and payment_methods[ 0] or False # Set payment method domain (restrict to methods enabled for the journal and to selected payment type) return { 'domain': { 'payment_method_id': [('payment_type', '=', 'outbound'), ('id', 'in', payment_methods.ids)] } } return {} def _get_payment_vals(self): """ Hook for extension """ return { 'partner_type': 'supplier', 'payment_type': 'outbound', 'partner_id': self.partner_id.id, 'journal_id': self.journal_id.id, 'company_id': self.company_id.id, 'payment_method_id': self.payment_method_id.id, 'amount': self.amount, 'currency_id': self.currency_id.id, 'payment_date': self.payment_date, 'communication': self.communication } @api.multi def expense_post_payment(self): self.ensure_one() context = dict(self._context or {}) active_ids = context.get('active_ids', []) expense_sheet = self.env['hr.expense.sheet'].browse(active_ids) # Create payment and post it payment = self.env['account.payment'].create(self._get_payment_vals()) payment.post() # Log the payment in the chatter body = (_( "A payment of %s %s with the reference <a href='/mail/view?%s'>%s</a> related to your expense %s has been made." ) % (payment.amount, payment.currency_id.symbol, url_encode({ 'model': 'account.payment', 'res_id': payment.id }), payment.name, expense_sheet.name)) expense_sheet.message_post(body=body) # Reconcile the payment and the expense, i.e. lookup on the payable account move lines account_move_lines_to_reconcile = self.env['account.move.line'] for line in payment.move_line_ids + expense_sheet.account_move_id.line_ids: if line.account_id.internal_type == 'payable': account_move_lines_to_reconcile |= line account_move_lines_to_reconcile.reconcile() return {'type': 'ir.actions.act_window_close'}