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 ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' module_account_accountant = fields.Boolean(string='Account Accountant') module_l10n_fr_hr_payroll = fields.Boolean(string='French Payroll') module_l10n_be_hr_payroll = fields.Boolean(string='Belgium Payroll') module_l10n_in_hr_payroll = fields.Boolean(string='Indian Payroll')
class Notification(models.Model): _name = 'mail.notification' _table = 'mail_message_res_partner_needaction_rel' _rec_name = 'res_partner_id' _log_access = False _description = 'Message Notifications' mail_message_id = fields.Many2one( 'mail.message', 'Message', index=True, ondelete='cascade', required=True) res_partner_id = fields.Many2one( 'res.partner', 'Needaction Recipient', index=True, ondelete='cascade', required=True) is_read = fields.Boolean('Is Read', index=True) is_email = fields.Boolean('Sent by Email', index=True) email_status = fields.Selection([ ('ready', 'Ready to Send'), ('sent', 'Sent'), ('bounce', 'Bounced'), ('exception', 'Exception')], 'Email Status', default='ready', index=True) @api.model_cr def init(self): self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('mail_notification_res_partner_id_is_read_email_status_mail_message_id',)) if not self._cr.fetchone(): self._cr.execute('CREATE INDEX mail_notification_res_partner_id_is_read_email_status_mail_message_id ON mail_message_res_partner_needaction_rel (res_partner_id, is_read, email_status, mail_message_id)')
class res_company(models.Model): _inherit = "res.company" gengo_private_key = fields.Text(string="Gengo Private Key", copy=False, groups="base.group_system") gengo_public_key = fields.Text(string="Gengo Public Key", copy=False, groups="base.group_user") gengo_comment = fields.Text( string="Comments", groups="base.group_user", help= "This comment will be automatically be enclosed in each an every request sent to Gengo" ) gengo_auto_approve = fields.Boolean( string="Auto Approve Translation ?", groups="base.group_user", default=True, help="Jobs are Automatically Approved by Gengo.") gengo_sandbox = fields.Boolean( string="Sandbox Mode", help= "Check this box if you're using the sandbox mode of Gengo, mainly used for testing purpose." )
class FinancialYearOpeningWizard(models.TransientModel): _name = 'account.financial.year.op' company_id = fields.Many2one(comodel_name='res.company', required=True) opening_move_posted = fields.Boolean(string='Opening Move Posted', compute='_compute_opening_move_posted') opening_date = fields.Date(string='Opening Date', required=True, related='company_id.account_opening_date', help="Date from which the accounting is managed in NobleCRM. It is the date of the opening entry.") fiscalyear_last_day = fields.Integer(related="company_id.fiscalyear_last_day", required=True, help="The last day of the month will be taken if the chosen day doesn't exist.") fiscalyear_last_month = fields.Selection(selection=[(1, 'January'), (2, 'February'), (3, 'March'), (4, 'April'), (5, 'May'), (6, 'June'), (7, 'July'), (8, 'August'), (9, 'September'), (10, 'October'), (11, 'November'), (12, 'December')], related="company_id.fiscalyear_last_month", required=True, help="The last day of the month will be taken if the chosen day doesn't exist.") account_setup_fy_data_done = fields.Boolean(string='Financial year setup marked as done', compute="_compute_setup_marked_done") @api.depends('company_id.account_setup_fy_data_done') def _compute_setup_marked_done(self): for record in self: record.account_setup_fy_data_done = record.company_id.account_setup_fy_data_done @api.depends('company_id.account_opening_move_id') def _compute_opening_move_posted(self): for record in self: record.opening_move_posted = record.company_id.opening_move_posted() def mark_as_done(self): """ Forces fiscal year setup state to 'done'.""" self.company_id.account_setup_fy_data_done = True def unmark_as_done(self): """ Forces fiscal year setup state to 'undone'.""" self.company_id.account_setup_fy_data_done = False
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' expense_alias_prefix = fields.Char('Default Alias Name for Expenses') use_mailgateway = fields.Boolean(string='Let your employees record expenses by email') module_sale_management = fields.Boolean(string="Customer Billing") @api.model def get_values(self): res = super(ResConfigSettings, self).get_values() res.update( expense_alias_prefix=self.env.ref('hr_expense.mail_alias_expense').alias_name, use_mailgateway=self.env['ir.config_parameter'].sudo().get_param('hr_expense.use_mailgateway'), ) return res @api.multi def set_values(self): super(ResConfigSettings, self).set_values() self.env.ref('hr_expense.mail_alias_expense').write({'alias_name': self.expense_alias_prefix}) self.env['ir.config_parameter'].sudo().set_param('hr_expense.use_mailgateway', self.use_mailgateway) @api.onchange('use_mailgateway') def _onchange_use_mailgateway(self): if not self.use_mailgateway: self.expense_alias_prefix = False
class SaleLayoutCategory(models.Model): _name = 'sale.layout_category' _order = 'sequence, id' name = fields.Char('Name', required=True, translate=True) sequence = fields.Integer('Sequence', required=True, default=10) subtotal = fields.Boolean('Add subtotal', default=True) pagebreak = fields.Boolean('Add pagebreak')
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' module_event_sale = fields.Boolean("Tickets") module_website_event_track = fields.Boolean("Tracks and Agenda") module_website_event_questions = fields.Boolean("Registration Survey") module_event_barcode = fields.Boolean("Barcode") module_website_event_sale = fields.Boolean("Online Ticketing")
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' crm_alias_prefix = fields.Char('Default Alias Name for Leads') generate_lead_from_alias = fields.Boolean('Manual Assignation of Emails') group_use_lead = fields.Boolean(string="Leads", implied_group='crm.group_use_lead') module_crm_phone_validation = fields.Boolean("Phone Formatting") module_web_clearbit = fields.Boolean("Customer Autocomplete") def _find_default_lead_alias_id(self): alias = self.env.ref('crm.mail_alias_lead_info', False) if not alias: alias = self.env['mail.alias'].search( [('alias_model_id.model', '=', 'crm.lead'), ('alias_force_thread_id', '=', False), ('alias_parent_model_id.model', '=', 'crm.team'), ('alias_parent_thread_id', '=', False), ('alias_defaults', '=', '{}')], limit=1) return alias @api.onchange('group_use_lead') def _onchange_group_use_lead(self): """ Reset alias / leads configuration if leads are not used """ if not self.group_use_lead: self.generate_lead_from_alias = False @api.onchange('generate_lead_from_alias') def _onchange_generate_lead_from_alias(self): self.crm_alias_prefix = (self.crm_alias_prefix or 'info' ) if self.generate_lead_from_alias else False @api.model def get_values(self): res = super(ResConfigSettings, self).get_values() alias = self._find_default_lead_alias_id() res.update(crm_alias_prefix=alias.alias_name if alias else False, generate_lead_from_alias=self.env['ir.config_parameter']. sudo().get_param('crm.generate_lead_from_alias')) return res @api.multi def set_values(self): super(ResConfigSettings, self).set_values() self.env['ir.config_parameter'].sudo().set_param( 'crm.generate_lead_from_alias', self.generate_lead_from_alias) alias = self._find_default_lead_alias_id() if alias: alias.write({'alias_name': self.crm_alias_prefix}) else: self.env['mail.alias'].with_context( alias_model_name='crm.lead', alias_parent_model_name='crm.team').create( {'alias_name': self.crm_alias_prefix})
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(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'
class MaintenanceStage(models.Model): """ Model for case stages. This models the main stages of a Maintenance Request management flow. """ _name = 'maintenance.stage' _description = 'Maintenance Stage' _order = 'sequence, id' name = fields.Char('Name', required=True, translate=True) sequence = fields.Integer('Sequence', default=20) fold = fields.Boolean('Folded in Maintenance Pipe') done = fields.Boolean('Request Done')
class EventType(models.Model): _inherit = 'event.type' website_track = fields.Boolean('Tracks on Website') website_track_proposal = fields.Boolean('Tracks Proposals on Website') @api.onchange('website_menu') def _onchange_website_menu(self): if not self.website_menu: self.website_track = False self.website_track_proposal = False
class AccountPartnerLedger(models.TransientModel): _inherit = "account.common.partner.report" _name = "account.report.partner.ledger" _description = "Account Partner Ledger" amount_currency = fields.Boolean("With Currency", help="It adds the currency column on report if the currency differs from the company currency.") reconciled = fields.Boolean('Reconciled Entries') def _print_report(self, data): data = self.pre_print_report(data) data['form'].update({'reconciled': self.reconciled, 'amount_currency': self.amount_currency}) return self.env.ref('account.action_report_partnerledger').report_action(self, data=data)
class StockMoveLine(models.Model): _inherit = 'stock.move.line' workorder_id = fields.Many2one('mrp.workorder', 'Work Order') production_id = fields.Many2one('mrp.production', 'Production Order') lot_produced_id = fields.Many2one('stock.production.lot', 'Finished Lot') lot_produced_qty = fields.Float( 'Quantity Finished Product', digits=dp.get_precision('Product Unit of Measure'), help="Informative, not used in matching") done_wo = fields.Boolean( 'Done for Work Order', default=True, help= "Technical Field which is False when temporarily filled in in work order" ) # TDE FIXME: naming done_move = fields.Boolean('Move Done', related='move_id.is_done', store=True) # TDE FIXME: naming def _get_similar_move_lines(self): lines = super(StockMoveLine, self)._get_similar_move_lines() if self.move_id.production_id: finished_moves = self.move_id.production_id.move_finished_ids finished_move_lines = finished_moves.mapped('move_line_ids') lines |= finished_move_lines.filtered( lambda ml: ml.product_id == self.product_id and (ml.lot_id or ml.lot_name) and ml.done_wo == self.done_wo) if self.move_id.raw_material_production_id: raw_moves = self.move_id.raw_material_production_id.move_raw_ids raw_moves_lines = raw_moves.mapped('move_line_ids') raw_moves_lines |= self.move_id.active_move_line_ids lines |= raw_moves_lines.filtered( lambda ml: ml.product_id == self.product_id and (ml.lot_id or ml.lot_name) and ml.done_wo == self.done_wo) return lines @api.multi def write(self, vals): for move_line in self: if move_line.move_id.production_id and 'lot_id' in vals: move_line.production_id.move_raw_ids.mapped('move_line_ids')\ .filtered(lambda r: r.done_wo and not r.done_move and r.lot_produced_id == move_line.lot_id)\ .write({'lot_produced_id': vals['lot_id']}) production = move_line.move_id.production_id or move_line.move_id.raw_material_production_id if production and move_line.state == 'done' and any( field in vals for field in ('lot_id', 'location_id', 'qty_done')): move_line._log_message(production, move_line, 'mrp.track_production_move_template', vals) return super(StockMoveLine, self).write(vals)
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 ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' module_hr_timesheet = fields.Boolean("Timesheets") module_rating_project = fields.Boolean(string="Rating on Tasks") module_project_forecast = fields.Boolean(string="Forecasts") group_subtask_project = fields.Boolean( "Sub-tasks", implied_group="project.group_subtask_project") project_time_mode_id = fields.Many2one( 'product.uom', related='company_id.project_time_mode_id', string='Project Time Unit', help="This will set the unit of measure used in projects and tasks.\n" "If you use the timesheet linked to projects, don't " "forget to setup the right unit of measure in your employees.")
class ProductPricelist(models.Model): _inherit = "product.pricelist" def _default_website(self): return self.env['website'].search([], limit=1) website_id = fields.Many2one('website', string="website", default=_default_website) code = fields.Char(string='E-commerce Promotional Code', groups="base.group_user") selectable = fields.Boolean(help="Allow the end user to choose this price list") def clear_cache(self): # website._get_pl() is cached to avoid to recompute at each request the # list of available pricelists. So, we need to invalidate the cache when # we change the config of website price list to force to recompute. website = self.env['website'] website._get_pl_partner_order.clear_cache(website) @api.model def create(self, data): res = super(ProductPricelist, self).create(data) self.clear_cache() return res @api.multi def write(self, data): res = super(ProductPricelist, self).write(data) self.clear_cache() return res @api.multi def unlink(self): res = super(ProductPricelist, self).unlink() self.clear_cache() return res
class HrEmployee(models.Model): _inherit = "hr.employee" newly_hired_employee = fields.Boolean('Newly hired employee', compute='_compute_newly_hired_employee', search='_search_newly_hired_employee') @api.multi def _compute_newly_hired_employee(self): read_group_result = self.env['hr.applicant'].read_group( [('emp_id', 'in', self.ids), ('job_id.state', '=', 'recruit')], ['emp_id'], ['emp_id']) result = dict((data['emp_id'], data['emp_id_count'] > 0) for data in read_group_result) for record in self: record.newly_hired_employee = result.get(record.id, False) def _search_newly_hired_employee(self, operator, value): applicants = self.env['hr.applicant'].search([('job_id.state', '=', 'recruit')]) return [('id', 'in', applicants.ids)] @api.multi def _broadcast_welcome(self): """ Broadcast the welcome message to all users in the employee company. """ self.ensure_one() IrModelData = self.env['ir.model.data'] channel_all_employees = IrModelData.xmlid_to_object('mail.channel_all_employees') template_new_employee = IrModelData.xmlid_to_object('hr_recruitment.email_template_data_applicant_employee') if template_new_employee: MailTemplate = self.env['mail.template'] body_html = MailTemplate.render_template(template_new_employee.body_html, 'hr.employee', self.id) subject = MailTemplate.render_template(template_new_employee.subject, 'hr.employee', self.id) channel_all_employees.message_post( body=body_html, subject=subject, subtype='mail.mt_comment') return True
class EventType(models.Model): _inherit = 'event.type' @api.model def _get_default_event_ticket_ids(self): product = self.env.ref('event_sale.product_product_event', raise_if_not_found=False) if not product: return False return [(0, 0, { 'name': _('Registration'), 'product_id': product.id, 'price': 0, })] use_ticketing = fields.Boolean('Ticketing') event_ticket_ids = fields.One2many('event.event.ticket', 'event_type_id', string='Tickets', default=_get_default_event_ticket_ids) @api.onchange('name') def _onchange_name(self): if self.name: self.event_ticket_ids.filtered( lambda ticket: ticket.name == _('Registration')).update( {'name': _('Registration for %s') % self.name})
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 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 WebsitePublishedMixin(models.AbstractModel): _name = "website.published.mixin" website_published = fields.Boolean('Visible in Website', copy=False) website_url = fields.Char('Website URL', compute='_compute_website_url', help='The full URL to access the document through the website.') @api.multi def _compute_website_url(self): for record in self: record.website_url = '#' @api.multi def website_publish_button(self): self.ensure_one() if self.env.user.has_group('website.group_website_publisher') and self.website_url != '#': return self.open_website_url() return self.write({'website_published': not self.website_published}) def open_website_url(self): return { 'type': 'ir.actions.act_url', 'url': self.website_url, 'target': 'self', }
class HrPayslipRun(models.Model): _inherit = 'hr.payslip.run' _description = 'Payslip Batches' available_advice = fields.Boolean( string='Made Payment Advice?', help= 'If this box is checked which means that Payment Advice exists for current batch', readonly=False, copy=False) @api.multi def draft_payslip_run(self): super(HrPayslipRun, self).draft_payslip_run() self.write({'available_advice': False}) @api.multi def create_advice(self): for run in self: if run.available_advice: raise UserError( _("Payment advice already exists for %s, 'Set to Draft' to create a new advice." ) % (run.name, )) company = self.env.user.company_id advice = self.env['hr.payroll.advice'].create({ 'batch_id': run.id, 'company_id': company.id, 'name': run.name, 'date': run.date_end, 'bank_id': company.partner_id.bank_ids and company.partner_id.bank_ids[0].bank_id.id or False }) for slip in run.slip_ids: # TODO is it necessary to interleave the calls ? slip.action_payslip_done() if not slip.employee_id.bank_account_id or not slip.employee_id.bank_account_id.acc_number: raise UserError( _('Please define bank account for the %s employee') % (slip.employee_id.name)) payslip_line = self.env['hr.payslip.line'].search( [('slip_id', '=', slip.id), ('code', '=', 'NET')], limit=1) if payslip_line: self.env['hr.payroll.advice.line'].create({ 'advice_id': advice.id, 'name': slip.employee_id.bank_account_id.acc_number, 'ifsc_code': slip.employee_id.bank_account_id.bank_bic or '', 'employee_id': slip.employee_id.id, 'bysal': payslip_line.total }) self.write({'available_advice': True})
class Employee(models.Model): _inherit = "hr.employee" manager = fields.Boolean(string='Is a Manager') medic_exam = fields.Date(string='Medical Examination Date', groups="hr.group_hr_user") place_of_birth = fields.Char('Place of Birth', groups="hr.group_hr_user") children = fields.Integer(string='Number of Children', groups="hr.group_hr_user") vehicle = fields.Char(string='Company Vehicle', groups="hr.group_hr_user") vehicle_distance = fields.Integer( string='Home-Work Dist.', help="In kilometers", groups="hr.group_hr_user") contract_ids = fields.One2many('hr.contract', 'employee_id', string='Contracts') contract_id = fields.Many2one('hr.contract', compute='_compute_contract_id', string='Current Contract', help='Latest contract of the employee') contracts_count = fields.Integer(compute='_compute_contracts_count', string='Contracts') def _compute_contract_id(self): """ get the lastest contract """ Contract = self.env['hr.contract'] for employee in self: employee.contract_id = Contract.search([('employee_id', '=', employee.id)], order='date_start desc', limit=1) def _compute_contracts_count(self): # read_group as sudo, since contract count is displayed on form view contract_data = self.env['hr.contract'].sudo().read_group([('employee_id', 'in', self.ids)], ['employee_id'], ['employee_id']) result = dict((data['employee_id'][0], data['employee_id_count']) for data in contract_data) for employee in self: employee.contracts_count = result.get(employee.id, 0)
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 Product(models.Model): _inherit = 'product.template' membership = fields.Boolean( help='Check if the product is eligible for membership.') membership_date_from = fields.Date( string='Membership Start Date', help='Date from which membership becomes active.') membership_date_to = fields.Date( string='Membership End Date', help='Date until which membership remains active.') _sql_constraints = [ ('membership_date_greater', 'check(membership_date_to >= membership_date_from)', 'Error ! Ending Date cannot be set before Beginning Date.') ] @api.model def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False): if self._context.get('product') == 'membership_product': if view_type == 'form': view_id = self.env.ref( 'membership.membership_products_form').id else: view_id = self.env.ref( 'membership.membership_products_tree').id return super(Product, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)
class MassMailingList(models.Model): """Model of a contact list. """ _name = 'mail.mass_mailing.list' _order = 'name' _description = 'Mailing List' name = fields.Char(string='Mailing List', required=True) active = fields.Boolean(default=True) create_date = fields.Datetime(string='Creation Date') contact_nbr = fields.Integer(compute="_compute_contact_nbr", string='Number of Contacts') # Compute number of contacts non opt-out for a mailing list def _compute_contact_nbr(self): self.env.cr.execute(''' select list_id, count(*) from mail_mass_mailing_contact_list_rel r left join mail_mass_mailing_contact c on (r.contact_id=c.id) where c.opt_out <> true group by list_id ''') data = dict(self.env.cr.fetchall()) for mailing_list in self: mailing_list.contact_nbr = data.get(mailing_list.id, 0)
class RecruitmentStage(models.Model): _name = "hr.recruitment.stage" _description = "Stage of Recruitment" _order = 'sequence' name = fields.Char("Stage name", required=True, translate=True) sequence = fields.Integer( "Sequence", default=10, help="Gives the sequence order when displaying a list of stages.") job_id = fields.Many2one('hr.job', string='Job Specific', ondelete='cascade', help='Specific job that uses this stage. Other jobs will not use this stage.') requirements = fields.Text("Requirements") template_id = fields.Many2one( 'mail.template', "Automated Email", help="If set, a message is posted on the applicant using the template when the applicant is set to the stage.") fold = fields.Boolean( "Folded in Recruitment Pipe", help="This stage is folded in the kanban view when there are no records in that stage to display.") @api.model def default_get(self, fields): if self._context and self._context.get('default_job_id') and not self._context.get('hr_recruitment_stage_mono', False): context = dict(self._context) context.pop('default_job_id') self = self.with_context(context) return super(RecruitmentStage, self).default_get(fields)
class TrackStage(models.Model): _name = 'event.track.stage' _description = 'Track Stage' _order = 'sequence, id' name = fields.Char(string='Stage Name', required=True, translate=True) sequence = fields.Integer(string='Sequence', default=1) mail_template_id = fields.Many2one( 'mail.template', string='Email Template', domain=[('model', '=', 'event.track')], help="If set an email will be sent to the customer when the track reaches this step.") fold = fields.Boolean( string='Folded in Kanban', help='This stage is folded in the kanban view when there are no records in that stage to display.') is_done = fields.Boolean(string='Accepted Stage') is_cancel = fields.Boolean(string='Canceled Stage')
class website_form_model(models.Model): _name = 'ir.model' _inherit = 'ir.model' website_form_access = fields.Boolean( 'Allowed to use in forms', help='Enable the form builder feature for this model.') website_form_default_field_id = fields.Many2one( 'ir.model.fields', 'Field for custom form data', domain="[('model', '=', model), ('ttype', '=', 'text')]", help= "Specify the field which will contain meta and custom form fields datas." ) website_form_label = fields.Char( "Label for form action", help= "Form action label. Ex: crm.lead could be 'Send an e-mail' and project.issue could be 'Create an Issue'." ) def _get_form_writable_fields(self): """ Restriction of "authorized fields" (fields which can be used in the form builders) to fields which have actually been opted into form builders and are writable. By default no field is writable by the form builder. """ included = { field.name for field in self.env['ir.model.fields'].sudo().search([( 'model_id', '=', self.id), ('website_form_blacklisted', '=', False)]) } return { k: v for k, v in self.get_authorized_fields(self.model).items() if k in included } @api.model def get_authorized_fields(self, model_name): """ Return the fields of the given model name as a mapping like method `fields_get`. """ model = self.env[model_name] fields_get = model.fields_get() for key, val in model._inherits.items(): fields_get.pop(val, None) # Unrequire fields with default values default_values = model.default_get(list(fields_get)) for field in [f for f in fields_get if f in default_values]: fields_get[field]['required'] = False # Remove readonly and magic fields MAGIC_FIELDS = models.MAGIC_COLUMNS + [model.CONCURRENCY_CHECK_FIELD] for field in list(fields_get): if fields_get[field]['readonly'] or field in MAGIC_FIELDS: del fields_get[field] return fields_get