class ResPartner(models.Model): _inherit = "res.partner" partner_latitude = fields.Float(string='Geo Latitude', digits=(16, 5)) partner_longitude = fields.Float(string='Geo Longitude', digits=(16, 5)) date_localization = fields.Date(string='Geolocation Date') @classmethod def _geo_localize(cls, apikey, street='', zip='', city='', state='', country=''): search = geo_query_address(street=street, zip=zip, city=city, state=state, country=country) result = geo_find(search, apikey) if result is None: search = geo_query_address(city=city, state=state, country=country) result = geo_find(search, apikey) return result @api.multi def geo_localize(self): # We need country names in English below apikey = self.env['ir.config_parameter'].sudo().get_param('google.api_key_geocode') for partner in self.with_context(lang='en_US'): result = partner._geo_localize(apikey, partner.street, partner.zip, partner.city, partner.state_id.name, partner.country_id.name) if result: partner.write({ 'partner_latitude': result[0], 'partner_longitude': result[1], 'date_localization': fields.Date.context_today(partner) }) return True
class HrContract(models.Model): """ Employee contract allows to add different values in fields. Fields are used in salary rule computation. """ _inherit = 'hr.contract' tds = fields.Float(string='TDS', digits=dp.get_precision('Payroll'), help='Amount for Tax Deduction at Source') driver_salay = fields.Boolean( string='Driver Salary', help='Check this box if you provide allowance for driver') medical_insurance = fields.Float( string='Medical Insurance', digits=dp.get_precision('Payroll'), help='Deduction towards company provided medical insurance') voluntary_provident_fund = fields.Float( string='Voluntary Provident Fund (%)', digits=dp.get_precision('Payroll'), help= 'VPF is a safe option wherein you can contribute more than the PF ceiling of 12% that has been mandated by the government and VPF computed as percentage(%)' ) house_rent_allowance_metro_nonmetro = fields.Float( string='House Rent Allowance (%)', digits=dp.get_precision('Payroll'), help= 'HRA is an allowance given by the employer to the employee for taking care of his rental or accommodation expenses for metro city it is 50% and for non metro 40%. \nHRA computed as percentage(%)' ) supplementary_allowance = fields.Float(string='Supplementary Allowance', digits=dp.get_precision('Payroll'))
class RestaurantTable(models.Model): _name = 'restaurant.table' name = fields.Char('Table Name', required=True, help='An internal identification of a table') floor_id = fields.Many2one('restaurant.floor', string='Floor') shape = fields.Selection([('square', 'Square'), ('round', 'Round')], string='Shape', required=True, default='square') position_h = fields.Float('Horizontal Position', default=10, help="The table's horizontal position from the left side to the table's center, in pixels") position_v = fields.Float('Vertical Position', default=10, help="The table's vertical position from the top to the table's center, in pixels") width = fields.Float('Width', default=50, help="The table's width in pixels") height = fields.Float('Height', default=50, help="The table's height in pixels") seats = fields.Integer('Seats', default=1, help="The default number of customer served at this table.") color = fields.Char('Color', help="The table's color, expressed as a valid 'background' CSS property value") active = fields.Boolean('Active', default=True, help='If false, the table is deactivated and will not be available in the point of sale') @api.model def create_from_ui(self, table): """ create or modify a table from the point of sale UI. table contains the table's fields. If it contains an id, it will modify the existing table. It then returns the id of the table. """ if table.get('floor_id'): table['floor_id'] = table['floor_id'][0] table_id = table.pop('id', False) if table_id: self.browse(table_id).write(table) else: table_id = self.create(table).id return table_id
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()
class Product(models.Model): _inherit = "product.product" website_price = fields.Float('Website price', compute='_website_price', digits=dp.get_precision('Product Price')) website_public_price = fields.Float('Website public price', compute='_website_price', digits=dp.get_precision('Product Price')) website_price_difference = fields.Boolean('Website price difference', compute='_website_price') def _website_price(self): qty = self._context.get('quantity', 1.0) partner = self.env.user.partner_id current_website = self.env['website'].get_current_website() pricelist = current_website.get_current_pricelist() company_id = current_website.company_id context = dict(self._context, pricelist=pricelist.id, partner=partner) self2 = self.with_context(context) if self._context != context else self ret = self.env.user.has_group('sale.group_show_price_subtotal') and 'total_excluded' or 'total_included' for p, p2 in pycompat.izip(self, self2): taxes = partner.property_account_position_id.map_tax(p.sudo().taxes_id.filtered(lambda x: x.company_id == company_id)) p.website_price = taxes.compute_all(p2.price, pricelist.currency_id, quantity=qty, product=p2, partner=partner)[ret] price_without_pricelist = taxes.compute_all(p.list_price, pricelist.currency_id)[ret] p.website_price_difference = False if float_is_zero(price_without_pricelist - p.website_price, precision_rounding=pricelist.currency_id.rounding) else True p.website_public_price = taxes.compute_all(p2.lst_price, quantity=qty, product=p2, partner=partner)[ret] @api.multi def website_publish_button(self): self.ensure_one() return self.product_tmpl_id.website_publish_button()
class HrContract(models.Model): _inherit = 'hr.contract' car_id = fields.Many2one('fleet.vehicle', string='Company Car', domain=lambda self: self._get_available_cars_domain(), default=lambda self: self.env['fleet.vehicle'].search([('driver_id', '=', self.employee_id.address_home_id.id)], limit=1), track_visibility="onchange", help="Employee's company car.") car_atn = fields.Float(compute='_compute_car_atn_and_costs', string='ATN Company Car', store=True) company_car_total_depreciated_cost = fields.Float(compute='_compute_car_atn_and_costs', store=True) available_cars_amount = fields.Integer(compute='_compute_available_cars_amount', string='Number of available cars') new_car = fields.Boolean('Request a new car') new_car_model_id = fields.Many2one('fleet.vehicle.model', string="Model", domain=lambda self: self._get_possible_model_domain()) max_unused_cars = fields.Integer(compute='_compute_max_unused_cars') @api.depends('car_id', 'new_car', 'new_car_model_id', 'car_id.total_depreciated_cost', 'car_id.atn', 'new_car_model_id.default_atn', 'new_car_model_id.default_total_depreciated_cost', 'car_id.co2_fee', 'car_id.log_contracts', 'car_id.log_contracts.state', # YTI TODO: Store total_depreciated_costs on 'car_id.log_contracts.recurring_cost_amount_depreciated') # the fleet vehicle to avoid these dependencies def _compute_car_atn_and_costs(self): for contract in self: if not contract.new_car and contract.car_id: contract.car_atn = contract.car_id.atn contract.company_car_total_depreciated_cost = contract.car_id.total_depreciated_cost elif contract.new_car and contract.new_car_model_id: contract.car_atn = contract.new_car_model_id.default_atn contract.company_car_total_depreciated_cost = contract.new_car_model_id.default_total_depreciated_cost @api.depends('name') def _compute_available_cars_amount(self): for contract in self: contract.available_cars_amount = self.env['fleet.vehicle'].search_count([('driver_id', '=', False)]) @api.depends('name') def _compute_max_unused_cars(self): params = self.env['ir.config_parameter'].sudo() max_unused_cars = params.get_param('l10n_be_hr_payroll_fleet.max_unused_cars', default=1000) for contract in self: contract.max_unused_cars = int(max_unused_cars) @api.onchange('employee_id') def _onchange_employee_id(self): super(HrContract, self)._onchange_employee_id() self.car_id = self.env['fleet.vehicle'].search([('driver_id', '=', self.employee_id.address_home_id.id)], limit=1) return {'domain': {'car_id': self._get_available_cars_domain()}} @api.onchange('transport_mode') def _onchange_transport_mode(self): super(HrContract, self)._onchange_transport_mode() if self.transport_mode != 'company_car': self.car_id = False self.new_car_model_id = False def _get_available_cars_domain(self): return ['|', ('driver_id', '=', False), ('driver_id', '=', self.employee_id.address_home_id.id)] def _get_possible_model_domain(self): return [('can_be_requested', '=', True)]
class RepairFee(models.Model): _name = 'mrp.repair.fee' _description = 'Repair Fees Line' repair_id = fields.Many2one( 'mrp.repair', 'Repair Order Reference', index=True, ondelete='cascade', required=True) name = fields.Char('Description', index=True, required=True) product_id = fields.Many2one('product.product', 'Product') product_uom_qty = fields.Float('Quantity', digits=dp.get_precision('Product Unit of Measure'), required=True, default=1.0) price_unit = fields.Float('Unit Price', required=True) product_uom = fields.Many2one('product.uom', 'Product Unit of Measure', required=True) price_subtotal = fields.Float('Subtotal', compute='_compute_price_subtotal', digits=0) tax_id = fields.Many2many('account.tax', 'repair_fee_line_tax', 'repair_fee_line_id', 'tax_id', 'Taxes') invoice_line_id = fields.Many2one('account.invoice.line', 'Invoice Line', copy=False, readonly=True) invoiced = fields.Boolean('Invoiced', copy=False, readonly=True) @api.one @api.depends('price_unit', 'repair_id', 'product_uom_qty', 'product_id') def _compute_price_subtotal(self): taxes = self.tax_id.compute_all(self.price_unit, self.repair_id.pricelist_id.currency_id, self.product_uom_qty, self.product_id, self.repair_id.partner_id) self.price_subtotal = taxes['total_excluded'] @api.onchange('repair_id', 'product_id', 'product_uom_qty') def onchange_product_id(self): """ On change of product it sets product quantity, tax account, name, uom of product, unit price and price subtotal. """ if not self.product_id: return partner = self.repair_id.partner_id pricelist = self.repair_id.pricelist_id if partner and self.product_id: self.tax_id = partner.property_account_position_id.map_tax(self.product_id.taxes_id, self.product_id, partner).ids if self.product_id: self.name = self.product_id.display_name self.product_uom = self.product_id.uom_id.id warning = False if not pricelist: warning = { 'title': _('No Pricelist!'), 'message': _('You have to select a pricelist in the Repair form !\n Please set one before choosing a product.')} else: price = pricelist.get_product_price(self.product_id, self.product_uom_qty, partner) if price is False: warning = { 'title': _('No valid pricelist line found !'), 'message': _("Couldn't find a pricelist line matching this product and quantity.\nYou have to change either the product, the quantity or the pricelist.")} else: self.price_unit = price if warning: return {'warning': warning}
class ImLivechatReportOperator(models.Model): """ Livechat Support Report on the Operator """ _name = "im_livechat.report.operator" _description = "Livechat Support Report" _order = 'livechat_channel_id, partner_id' _auto = False partner_id = fields.Many2one('res.partner', 'Operator', readonly=True) livechat_channel_id = fields.Many2one('im_livechat.channel', 'Channel', readonly=True) nbr_channel = fields.Integer('# of Sessions', readonly=True, group_operator="sum", help="Number of conversation") channel_id = fields.Many2one('mail.channel', 'Conversation', readonly=True) start_date = fields.Datetime('Start Date of session', readonly=True, help="Start date of the conversation") time_to_answer = fields.Float( 'Time to answer', digits=(16, 2), readonly=True, group_operator="avg", help="Average time to give the first answer to the visitor") duration = fields.Float('Average duration', digits=(16, 2), readonly=True, group_operator="avg", help="Duration of the conversation (in seconds)") @api.model_cr def init(self): # Note : start_date_hour must be remove when the read_group will allow grouping on the hour of a datetime. Don't forget to change the view ! tools.drop_view_if_exists(self.env.cr, 'im_livechat_report_operator') self.env.cr.execute(""" CREATE OR REPLACE VIEW im_livechat_report_operator AS ( SELECT row_number() OVER () AS id, P.id as partner_id, L.id as livechat_channel_id, count(C.id) as nbr_channel, C.id as channel_id, C.create_date as start_date, EXTRACT('epoch' FROM (max((SELECT (max(M.create_date)) FROM mail_message M JOIN mail_message_mail_channel_rel R ON (R.mail_message_id = M.id) WHERE R.mail_channel_id = C.id))-C.create_date)) as duration, EXTRACT('epoch' from ((SELECT min(M.create_date) FROM mail_message M, mail_message_mail_channel_rel R WHERE M.author_id=P.id AND R.mail_channel_id = C.id AND R.mail_message_id = M.id)-(SELECT min(M.create_date) FROM mail_message M, mail_message_mail_channel_rel R WHERE M.author_id IS NULL AND R.mail_channel_id = C.id AND R.mail_message_id = M.id))) as time_to_answer FROM im_livechat_channel_im_user O JOIN res_users U ON (O.user_id = U.id) JOIN res_partner P ON (U.partner_id = P.id) LEFT JOIN im_livechat_channel L ON (L.id = O.channel_id) LEFT JOIN mail_channel C ON (C.livechat_channel_id = L.id) GROUP BY P.id, L.id, C.id, C.create_date ) """)
class SaleQuoteOption(models.Model): _name = "sale.quote.option" _description = "Quotation Option" template_id = fields.Many2one('sale.quote.template', 'Quotation Template Reference', ondelete='cascade', index=True, required=True) name = fields.Text('Description', required=True, translate=True) product_id = fields.Many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True) layout_category_id = fields.Many2one('sale.layout_category', string='Section') website_description = fields.Html('Option Description', translate=html_translate, sanitize_attributes=False) price_unit = fields.Float('Unit Price', required=True, digits=dp.get_precision('Product Price')) discount = fields.Float('Discount (%)', digits=dp.get_precision('Discount')) uom_id = fields.Many2one('product.uom', 'Unit of Measure ', required=True) quantity = fields.Float('Quantity', required=True, digits=dp.get_precision('Product UoS'), default=1) @api.onchange('product_id') def _onchange_product_id(self): if not self.product_id: return product = self.product_id self.price_unit = product.list_price self.website_description = product.product_tmpl_id.quote_description self.name = product.name self.uom_id = product.uom_id domain = { 'uom_id': [('category_id', '=', self.product_id.uom_id.category_id.id)] } return {'domain': domain} @api.onchange('uom_id') def _onchange_product_uom(self): if not self.product_id: return if not self.uom_id: self.price_unit = 0.0 return if self.uom_id.id != self.product_id.uom_id.id: self.price_unit = self.product_id.uom_id._compute_price( self.price_unit, self.uom_id)
class ResCompany(models.Model): _inherit = 'res.company' plafond_secu = fields.Float(string='Plafond de la Securite Sociale', digits=dp.get_precision('Payroll')) nombre_employes = fields.Integer(string='Nombre d\'employes') cotisation_prevoyance = fields.Float( string='Cotisation Patronale Prevoyance', digits=dp.get_precision('Payroll')) org_ss = fields.Char(string='Organisme de securite sociale') conv_coll = fields.Char(string='Convention collective')
class PurchaseRequisitionLine(models.Model): _name = "purchase.requisition.line" _description = "Purchase Requisition Line" _rec_name = 'product_id' product_id = fields.Many2one('product.product', string='Product', domain=[('purchase_ok', '=', True)], required=True) product_uom_id = fields.Many2one('product.uom', string='Product Unit of Measure') product_qty = fields.Float(string='Quantity', digits=dp.get_precision('Product Unit of Measure')) price_unit = fields.Float(string='Unit Price', digits=dp.get_precision('Product Price')) qty_ordered = fields.Float(compute='_compute_ordered_qty', string='Ordered Quantities') requisition_id = fields.Many2one('purchase.requisition', string='Purchase Agreement', ondelete='cascade') company_id = fields.Many2one('res.company', related='requisition_id.company_id', string='Company', store=True, readonly=True, default= lambda self: self.env['res.company']._company_default_get('purchase.requisition.line')) account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account') schedule_date = fields.Date(string='Scheduled Date') move_dest_id = fields.Many2one('stock.move', 'Downstream Move') @api.multi @api.depends('requisition_id.purchase_ids.state') def _compute_ordered_qty(self): for line in self: total = 0.0 for po in line.requisition_id.purchase_ids.filtered(lambda purchase_order: purchase_order.state in ['purchase', 'done']): for po_line in po.order_line.filtered(lambda order_line: order_line.product_id == line.product_id): if po_line.product_uom != line.product_uom_id: total += po_line.product_uom._compute_quantity(po_line.product_qty, line.product_uom_id) else: total += po_line.product_qty line.qty_ordered = total @api.onchange('product_id') def _onchange_product_id(self): if self.product_id: self.product_uom_id = self.product_id.uom_id self.product_qty = 1.0 if not self.account_analytic_id: self.account_analytic_id = self.requisition_id.account_analytic_id if not self.schedule_date: self.schedule_date = self.requisition_id.schedule_date @api.multi def _prepare_purchase_order_line(self, name, product_qty=0.0, price_unit=0.0, taxes_ids=False): self.ensure_one() requisition = self.requisition_id return { 'name': name, 'product_id': self.product_id.id, 'product_uom': self.product_id.uom_po_id.id, 'product_qty': product_qty, 'price_unit': price_unit, 'taxes_id': [(6, 0, taxes_ids)], 'date_planned': requisition.schedule_date or fields.Date.today(), 'account_analytic_id': self.account_analytic_id.id, 'move_dest_ids': self.move_dest_id and [(4, self.move_dest_id.id)] or [] }
class FleetVehicleLogFuel(models.Model): _name = 'fleet.vehicle.log.fuel' _description = 'Fuel log for vehicles' _inherits = {'fleet.vehicle.cost': 'cost_id'} @api.model def default_get(self, default_fields): res = super(FleetVehicleLogFuel, self).default_get(default_fields) service = self.env.ref('fleet.type_service_refueling', raise_if_not_found=False) res.update({ 'date': fields.Date.context_today(self), 'cost_subtype_id': service and service.id or False, 'cost_type': 'fuel' }) return res liter = fields.Float() price_per_liter = fields.Float() purchaser_id = fields.Many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]") inv_ref = fields.Char('Invoice Reference', size=64) vendor_id = fields.Many2one('res.partner', 'Vendor', domain="[('supplier','=',True)]") notes = fields.Text() cost_id = fields.Many2one('fleet.vehicle.cost', 'Cost', required=True, ondelete='cascade') # we need to keep this field as a related with store=True because the graph view doesn't support # (1) to address fields from inherited table # (2) fields that aren't stored in database cost_amount = fields.Float(related='cost_id.amount', string='Amount', store=True) @api.onchange('vehicle_id') def _onchange_vehicle(self): if self.vehicle_id: self.odometer_unit = self.vehicle_id.odometer_unit self.purchaser_id = self.vehicle_id.driver_id.id @api.onchange('liter', 'price_per_liter', 'amount') def _onchange_liter_price_amount(self): # need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not # make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per # liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead # of 3.0/2=1.5) # If there is no change in the result, we return an empty dict to prevent an infinite loop due to the 3 intertwine # onchange. And in order to verify that there is no change in the result, we have to limit the precision of the # computation to 2 decimal liter = float(self.liter) price_per_liter = float(self.price_per_liter) amount = float(self.amount) if liter > 0 and price_per_liter > 0 and round(liter * price_per_liter, 2) != amount: self.amount = round(liter * price_per_liter, 2) elif amount > 0 and liter > 0 and round(amount / liter, 2) != price_per_liter: self.price_per_liter = round(amount / liter, 2) elif amount > 0 and price_per_liter > 0 and round(amount / price_per_liter, 2) != liter: self.liter = round(amount / price_per_liter, 2)
class HrContractAdvandageTemplate(models.Model): _name = 'hr.contract.advantage.template' _description = "Employee's Advantage on Contract" name = fields.Char('Name', required=True) code = fields.Char('Code', required=True) lower_bound = fields.Float( 'Lower Bound', help="Lower bound authorized by the employer for this advantage") upper_bound = fields.Float( 'Upper Bound', help="Upper bound authorized by the employer for this advantage") default_value = fields.Float('Default value for this advantage')
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' plafond_secu = fields.Float(related='company_id.plafond_secu', string="Plafond de la Securite Sociale") nombre_employes = fields.Integer(related='company_id.nombre_employes', string="Nombre d'employes") cotisation_prevoyance = fields.Float( related='company_id.cotisation_prevoyance', string='Cotisation Patronale Prevoyance') org_ss = fields.Char(related='company_id.org_ss', string="Organisme de securite sociale") conv_coll = fields.Char(related='company_id.conv_coll', string="Convention collective")
class Company(models.Model): _inherit = "res.company" l10n_ch_isr_preprinted_account = fields.Boolean( string='Preprinted account', compute='_compute_l10n_ch_isr', inverse='_set_l10n_ch_isr') l10n_ch_isr_preprinted_bank = fields.Boolean( string='Preprinted bank', compute='_compute_l10n_ch_isr', inverse='_set_l10n_ch_isr') l10n_ch_isr_print_bank_location = fields.Boolean( string='Print bank location', default=False, help= 'Boolean option field indicating whether or not the alternate layout (the one printing bank name and address) must be used when generating an ISR.' ) l10n_ch_isr_scan_line_left = fields.Float( string='Scan line horizontal offset (mm)', compute='_compute_l10n_ch_isr', inverse='_set_l10n_ch_isr') l10n_ch_isr_scan_line_top = fields.Float( string='Scan line vertical offset (mm)', compute='_compute_l10n_ch_isr', inverse='_set_l10n_ch_isr') def _compute_l10n_ch_isr(self): get_param = self.env['ir.config_parameter'].sudo().get_param for company in self: company.l10n_ch_isr_preprinted_account = bool( get_param('l10n_ch.isr_preprinted_account', default=False)) company.l10n_ch_isr_preprinted_bank = bool( get_param('l10n_ch.isr_preprinted_bank', default=False)) company.l10n_ch_isr_scan_line_top = float( get_param('l10n_ch.isr_scan_line_top', default=0)) company.l10n_ch_isr_scan_line_left = float( get_param('l10n_ch.isr_scan_line_left', default=0)) def _set_l10n_ch_isr(self): set_param = self.env['ir.config_parameter'].sudo().set_param for company in self: set_param("l10n_ch.isr_preprinted_account", company.l10n_ch_isr_preprinted_account) set_param("l10n_ch.isr_preprinted_bank", company.l10n_ch_isr_preprinted_bank) set_param("l10n_ch.isr_scan_line_top", company.l10n_ch_isr_scan_line_top) set_param("l10n_ch.isr_scan_line_left", company.l10n_ch_isr_scan_line_left)
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.Float(compute='_compute_total', string='Total', digits=dp.get_precision('Payroll'), store=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 ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' po_lead = fields.Float(related='company_id.po_lead') use_po_lead = fields.Boolean( string="Security Lead Time for Purchase", oldname='default_new_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 get_values(self): res = super(ResConfigSettings, self).get_values() res.update(use_po_lead=self.env['ir.config_parameter'].sudo(). get_param('purchase.use_po_lead')) return res def set_values(self): super(ResConfigSettings, self).set_values() self.env['ir.config_parameter'].sudo().set_param( 'purchase.use_po_lead', self.use_po_lead)
class CashBox(models.TransientModel): _register = False name = fields.Char(string='Reason', required=True) # Attention, we don't set a domain, because there is a journal_type key # in the context of the action amount = fields.Float(string='Amount', digits=0, required=True) @api.multi def run(self): context = dict(self._context or {}) active_model = context.get('active_model', False) active_ids = context.get('active_ids', []) records = self.env[active_model].browse(active_ids) return self._run(records) @api.multi def _run(self, records): for box in self: for record in records: if not record.journal_id: raise UserError(_("Please check that the field 'Journal' is set on the Bank Statement")) if not record.journal_id.company_id.transfer_account_id: raise UserError(_("Please check that the field 'Transfer Account' is set on the company.")) box._create_bank_statement_line(record) return {} @api.one def _create_bank_statement_line(self, record): if record.state == 'confirm': raise UserError(_("You cannot put/take money in/out for a bank statement which is closed.")) values = self._calculate_values_for_statement_line(record) return record.write({'line_ids': [(0, False, values)]})
class AccountTaxTemplate(models.Model): """ Add fields used to define some brazilian taxes """ _inherit = 'account.tax.template' tax_discount = fields.Boolean(string='Discount this Tax in Prince', help="Mark it for (ICMS, PIS e etc.).") base_reduction = fields.Float(string='Redution', digits=0, required=True, help="Um percentual decimal em % entre 0-1.", default=0) amount_mva = fields.Float(string='MVA Percent', digits=0, required=True, help="Um percentual decimal em % entre 0-1.", default=0)
class Stage(models.Model): """ Model for case stages. This models the main stages of a document management flow. Main CRM objects (leads, opportunities, project issues, ...) will now use only stages, instead of state and stages. Stages are for example used to display the kanban view of records. """ _name = "crm.stage" _description = "Stage of case" _rec_name = 'name' _order = "sequence, name, id" @api.model def default_get(self, fields): """ Hack : when going from the pipeline, creating a stage with a sales team in context should not create a stage for the current sales channel only """ ctx = dict(self.env.context) if ctx.get('default_team_id') and not ctx.get('crm_team_mono'): ctx.pop('default_team_id') return super(Stage, self.with_context(ctx)).default_get(fields) name = fields.Char('Stage Name', required=True, translate=True) sequence = fields.Integer('Sequence', default=1, help="Used to order stages. Lower is better.") probability = fields.Float( 'Probability (%)', required=True, default=10.0, help= "This percentage depicts the default/average probability of the Case for this stage to be a success" ) on_change = fields.Boolean( 'Change Probability Automatically', help= "Setting this stage will change the probability automatically on the opportunity." ) requirements = fields.Text( 'Requirements', help= "Enter here the internal requirements for this stage (ex: Offer sent to customer). It will appear as a tooltip over the stage's name." ) team_id = fields.Many2one( 'crm.team', string='Team', ondelete='set null', help= 'Specific team that uses this stage. Other teams will not be able to see or use this stage.' ) legend_priority = fields.Text( 'Priority Management Explanation', translate=True, help= 'Explanation text to help users using the star and priority mechanism on stages or issues that are in this stage.' ) fold = fields.Boolean( 'Folded in Pipeline', help= 'This stage is folded in the kanban view when there are no records in that stage to display.' )
class PurchaseOrderLine(models.Model): _inherit = 'purchase.order.line' qty_received = fields.Float(compute='_compute_qty_received', string="Received Qty", store=True, compute_sudo=True) def _compute_qty_received(self): super(PurchaseOrderLine, self)._compute_qty_received() for line in self.filtered(lambda x: x.move_ids and x.product_id.id not in x.move_ids.mapped('product_id').ids): bom = self.env['mrp.bom']._bom_find(product=line.product_id, company_id=line.company_id.id) if bom and bom.type == 'phantom': line.qty_received = line._get_bom_delivered(bom=bom) def _get_bom_delivered(self, bom=False): self.ensure_one() # In the case of a kit, we need to check if all components are shipped. Since the BOM might # have changed, we don't compute the quantities but verify the move state. if bom: moves = self.move_ids.filtered( lambda m: m.picking_id and m.picking_id.state != 'cancel') bom_delivered = all([move.state == 'done' for move in moves]) if bom_delivered: return self.product_qty else: return 0.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")
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]
class HrPayrollAdviceLine(models.Model): ''' Bank Advice Lines ''' _name = 'hr.payroll.advice.line' _description = 'Bank Advice Lines' advice_id = fields.Many2one('hr.payroll.advice', string='Bank Advice') name = fields.Char('Bank Account No.', required=True) ifsc_code = fields.Char(string='IFSC Code') employee_id = fields.Many2one('hr.employee', string='Employee', required=True) bysal = fields.Float(string='By Salary', digits=dp.get_precision('Payroll')) debit_credit = fields.Char(string='C/D', default='C') company_id = fields.Many2one('res.company', related='advice_id.company_id', string='Company', store=True) ifsc = fields.Boolean(related='advice_id.neft', string='IFSC') @api.onchange('employee_id') def onchange_employee_id(self): self.name = self.employee_id.bank_account_id.acc_number self.ifsc_code = self.employee_id.bank_account_id.bank_bic or ''
class StockMove(models.Model): _inherit = 'stock.move' def _default_uom(self): uom_categ_id = self.env.ref('product.product_uom_categ_kgm').id return self.env['product.uom'].search( [('category_id', '=', uom_categ_id), ('factor', '=', 1)], limit=1) weight = fields.Float(compute='_cal_move_weight', digits=dp.get_precision('Stock Weight'), store=True) weight_uom_id = fields.Many2one( 'product.uom', string='Weight Unit of Measure', required=True, readonly=True, help= "Unit of Measure (Unit of Measure) is the unit of measurement for Weight", default=_default_uom) @api.depends('product_id', 'product_uom_qty', 'product_uom') def _cal_move_weight(self): for move in self.filtered( lambda moves: moves.product_id.weight > 0.00): move.weight = (move.product_qty * move.product_id.weight) def _get_new_picking_values(self): vals = super(StockMove, self)._get_new_picking_values() vals['carrier_id'] = self.sale_line_id.order_id.carrier_id.id return vals
class FleetVehicleLogServices(models.Model): _name = 'fleet.vehicle.log.services' _inherits = {'fleet.vehicle.cost': 'cost_id'} _description = 'Services for vehicles' @api.model def default_get(self, default_fields): res = super(FleetVehicleLogServices, self).default_get(default_fields) service = self.env.ref('fleet.type_service_service_8', raise_if_not_found=False) res.update({ 'date': fields.Date.context_today(self), 'cost_subtype_id': service and service.id or False, 'cost_type': 'services' }) return res purchaser_id = fields.Many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]") inv_ref = fields.Char('Invoice Reference') vendor_id = fields.Many2one('res.partner', 'Vendor', domain="[('supplier','=',True)]") # we need to keep this field as a related with store=True because the graph view doesn't support # (1) to address fields from inherited table and (2) fields that aren't stored in database cost_amount = fields.Float(related='cost_id.amount', string='Amount', store=True) notes = fields.Text() cost_id = fields.Many2one('fleet.vehicle.cost', 'Cost', required=True, ondelete='cascade') @api.onchange('vehicle_id') def _onchange_vehicle(self): if self.vehicle_id: self.odometer_unit = self.vehicle_id.odometer_unit self.purchaser_id = self.vehicle_id.driver_id.id
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
class LunchOrderLineLucky(models.TransientModel): _name = 'lunch.order.line.lucky' def _default_supplier(self): suppliers_obj = self.env['lunch.product'].search([]).mapped("supplier") return [(4, supplier.id) for supplier in suppliers_obj] product_id = fields.Many2one('lunch.product', 'Product', store=True) supplier_ids = fields.Many2many(comodel_name='res.partner', string='Vendor', domain=lambda self: [("id", "in", self.env['lunch.product'].search([]).mapped("supplier").ids)]) is_max_budget = fields.Boolean("I'm not feeling rich", help="Enable this option to set a maximal budget for your lucky order.", store=True) max_budget = fields.Float('Max Budget', store=True) @api.multi def random_pick(self): """ To pick a random product from the selected suppliers, and create an order with this one """ self.ensure_one() if self.is_max_budget: products_obj = self.env['lunch.product'].search([('supplier', "in", self.supplier_ids.ids), ('price', '<=', self.max_budget)]) else: products_obj = self.env['lunch.product'].search([('supplier', "in", self.supplier_ids.ids)]) if len(products_obj) != 0: random_product_obj = self.env['lunch.product'].browse([random.choice(products_obj.ids)]) order_line = self.env['lunch.order.line'].create({ 'product_id': random_product_obj.id, 'order_id': self._context['active_id'] }) else: raise UserError(_('No product is matching your request. Now you will starve to death.'))
class Company(models.Model): _inherit = 'res.company' manufacturing_lead = fields.Float( 'Manufacturing Lead Time', default=0.0, required=True, help="Security days for each manufacturing operation.")
class SaleReport(models.Model): _inherit = 'sale.report' margin = fields.Float('Margin') def _select(self): return super(SaleReport, self)._select( ) + ", SUM(l.margin / COALESCE(cr.rate, 1.0)) AS margin"