class HrDepartment(models.Model): _inherit = 'hr.department' new_applicant_count = fields.Integer( compute='_compute_new_applicant_count', string='New Applicant') new_hired_employee = fields.Integer(compute='_compute_recruitment_stats', string='New Hired Employee') expected_employee = fields.Integer(compute='_compute_recruitment_stats', string='Expected Employee') @api.multi def _compute_new_applicant_count(self): applicant_data = self.env['hr.applicant'].read_group( [('department_id', 'in', self.ids), ('stage_id.sequence', '<=', '1')], ['department_id'], ['department_id']) result = dict((data['department_id'][0], data['department_id_count']) for data in applicant_data) for department in self: department.new_applicant_count = result.get(department.id, 0) @api.multi def _compute_recruitment_stats(self): job_data = self.env['hr.job'].read_group( [('department_id', 'in', self.ids)], ['no_of_hired_employee', 'no_of_recruitment', 'department_id'], ['department_id']) new_emp = dict((data['department_id'][0], data['no_of_hired_employee']) for data in job_data) expected_emp = dict( (data['department_id'][0], data['no_of_recruitment']) for data in job_data) for department in self: department.new_hired_employee = new_emp.get(department.id, 0) department.expected_employee = expected_emp.get(department.id, 0)
class hr_expense_approval(models.Model): ''' 功能:配置费用报销的审批流程 ''' _name = 'hr.expense.approval' level=fields.Integer(string='审批等级') group_id=fields.Many2one('res.groups',string='审批组') max_amount=fields.Integer(string='最大审批额度')
class plm_document_relation(models.Model): _name = 'plm.document.relation' _inherit = 'plm.document.relation' parent_preview = fields.Binary (related="parent_id.preview", string=_("Preview"), store=False) parent_state = fields.Selection(related="parent_id.state", string=_("Status"), store=False) parent_revision = fields.Integer (related="parent_id.revisionid", string=_("Revision"), store=False) child_preview = fields.Binary (related="child_id.preview", string=_("Preview"), store=False) child_state = fields.Selection(related="child_id.state", string=_("Status"), store=False) child_revision = fields.Integer (related="child_id.revisionid", string=_("Revision"), store=False)
class SaasClient(models.AbstractModel): _name = 'saas_base.client' users_len = fields.Integer('Count users', readonly=True) max_users = fields.Char('Max users allowed', readonly=True) file_storage = fields.Integer('File storage (MB)', readonly=True) db_storage = fields.Integer('DB storage (MB)', readonly=True) total_storage_limit = fields.Integer('Total storage limit (MB)', readonly=True, default=0) expiration_datetime = fields.Datetime('Expiration', track_visibility='onchange') trial = fields.Boolean('Trial', help='indication of trial clients', default=False, readonly=True)
class sale_order_line(models.Model): ''' 功能:增加产品分类id,用来排序 ''' _inherit = 'sale.order.line' # saas报价单使用 categ_id = fields.Many2one('product.category', string='产品分类') categ_count = fields.Integer(string='分类数') categ_rowcount = fields.Integer(string='分类合并行数') add_td = fields.Boolean(string='是否增加TD') must_choose = fields.Boolean(string='是否必选') _order = 'order_id desc,categ_id ,must_choose desc,sequence, id'
class HrEquipmentCategory(models.Model): _name = 'hr.equipment.category' _inherits = {"mail.alias": "alias_id"} _inherit = ['mail.thread'] _description = 'Asset Category' @api.one @api.depends('equipment_ids') def _compute_fold(self): self.fold = False if self.equipment_count else True name = fields.Char('Category Name', required=True, translate=True) user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange', default=lambda self: self.env.uid) color = fields.Integer('Color Index') note = fields.Text('Comments', translate=True) equipment_ids = fields.One2many('hr.equipment', 'category_id', string='Equipments', copy=False) equipment_count = fields.Integer(string="Equipment", compute='_compute_equipment_count') maintenance_ids = fields.One2many('hr.equipment.request', 'category_id', copy=False) maintenance_count = fields.Integer(string="Maintenance", compute='_compute_maintenance_count') alias_id = fields.Many2one( 'mail.alias', 'Alias', ondelete='cascade', required=True, help="Email alias for this equipment category. New emails will automatically " "create new maintenance request for this equipment category.") fold = fields.Boolean(string='Folded in Maintenance Pipe', compute='_compute_fold', store=True) @api.multi def _compute_equipment_count(self): equipment_data = self.env['hr.equipment'].read_group([('category_id', 'in', self.ids)], ['category_id'], ['category_id']) mapped_data = dict([(m['category_id'][0], m['category_id_count']) for m in equipment_data]) for category in self: category.equipment_count = mapped_data.get(category.id, 0) @api.multi def _compute_maintenance_count(self): maintenance_data = self.env['hr.equipment.request'].read_group([('category_id', 'in', self.ids)], ['category_id'], ['category_id']) mapped_data = dict([(m['category_id'][0], m['category_id_count']) for m in maintenance_data]) for category in self: category.maintenance_count = mapped_data.get(category.id, 0) @api.model def create(self, vals): self = self.with_context(alias_model_name='hr.equipment.request', alias_parent_model_name=self._name) category_id = super(HrEquipmentCategory, self).create(vals) category_id.alias_id.write({'alias_parent_thread_id': category_id.id, 'alias_defaults': {'category_id': category_id.id}}) return category_id @api.multi def unlink(self): for category in self: if category.equipment_ids or category.maintenance_ids: raise UserError(_("You cannot delete an equipment category containing equipments or maintenance requests.")) res = super(HrEquipmentCategory, self).unlink() return res
class wx_product_line(models.Model): _name = 'wx.product.line' wx_product_id = fields.Many2one('wx.product', '微信商品') wx_product_state = fields.Selection(string='微信商品状态', related='wx_product_id.state') product_product_id = fields.Integer(string='产品规格ID') spec_name = fields.Char(string='规格名称') spec_value = fields.Char(string='属性') wx_quantity = fields.Integer(string='微信库存量') wx_quantity_offset = fields.Integer(string='库存偏移量', default=0) wx_lst_price = fields.Float(string='公开价格', digits=(16, 2)) # sales_range = fields.Selection([('online', '线上'), ('offline', '线下')], string='销售范围') _order = 'product_product_id'
class ImLivechatChannelRule(models.Model): """ Channel Rules Rules defining access to the channel (countries, and url matching). It also provide the 'auto pop' option to open automatically the conversation. """ _name = 'im_livechat.channel.rule' _description = 'Channel Rules' _order = 'sequence asc' regex_url = fields.Char('URL Regex', help="Regular expression identifying the web page on which the rules will be applied.") action = fields.Selection([('display_button', 'Display the button'), ('auto_popup', 'Auto popup'), ('hide_button', 'Hide the button')], string='Action', required=True, default='display_button', help="* Select 'Display the button' to simply display the chat button on the pages.\n"\ "* Select 'Auto popup' for to display the button, and automatically open the conversation window.\n"\ "* Select 'Hide the button' to hide the chat button on the pages.") auto_popup_timer = fields.Integer('Auto popup timer', default=0, help="Delay (in seconds) to automatically open the converssation window. Note : the selected action must be 'Auto popup', otherwise this parameter will not be take into account.") channel_id = fields.Many2one('im_livechat.channel', 'Channel', help="The channel of the rule") country_ids = fields.Many2many('res.country', 'im_livechat_channel_country_rel', 'channel_id', 'country_id', 'Country', help="The actual rule will match only for this country. So if you set select 'Belgium' and 'France' and you set the action to 'Hide Buttun', this 2 country will not be see the support button for the specified URL. This feature requires GeoIP installed on your server.") sequence = fields.Integer('Matching order', default=10, help="Given the order to find a matching rule. If 2 rules are matching for the given url/country, the one with the lowest sequence will be chosen.") def match_rule(self, channel_id, url, country_id=False): """ determine if a rule of the given channel match with the given url :param channel_id : the identifier of the channel_id :param url : the url to match with a rule :param country_id : the identifier of the country :returns the rule that match the given condition. False otherwise. :rtype : im_livechat.channel.rule """ def _match(rules): for rule in rules: if re.search(rule.regex_url, url): return rule return False # first, search the country specific rules (the first match is returned) if country_id: # don't include the country in the research if geoIP is not installed domain = [('country_ids', 'in', [country_id]), ('channel_id', '=', channel_id)] rule = _match(self.search(domain)) if rule: return rule # second, fallback on the rules without country domain = [('country_ids', '=', False), ('channel_id', '=', channel_id)] return _match(self.search(domain))
class hr_department(models.Model): _inherit = 'hr.department' @api.multi def _compute_leave_count(self): Holiday = self.env['hr.holidays'] today_date = datetime.datetime.utcnow().date() today_start = today_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT) # get the midnight of the current utc day today_end = (today_date + relativedelta(hours=23, minutes=59, seconds=59)).strftime(DEFAULT_SERVER_DATETIME_FORMAT) leave_data = Holiday.read_group( [('department_id', 'in', self.ids), ('state', '=', 'confirm'), ('type', '=', 'remove')], ['department_id'], ['department_id']) allocation_data = Holiday.read_group( [('department_id', 'in', self.ids), ('state', '=', 'confirm'), ('type', '=', 'add')], ['department_id'], ['department_id']) absence_data = Holiday.read_group( [('department_id', 'in', self.ids), ('state', 'not in', ['cancel', 'refuse']), ('date_from', '<=', today_end), ('date_to', '>=', today_start), ('type', '=', 'remove')], ['department_id'], ['department_id']) res_leave = dict((data['department_id'][0], data['department_id_count']) for data in leave_data) res_allocation = dict((data['department_id'][0], data['department_id_count']) for data in allocation_data) res_absence = dict((data['department_id'][0], data['department_id_count']) for data in absence_data) for department in self: department.leave_to_approve_count = res_leave.get(department.id, 0) department.allocation_to_approve_count = res_allocation.get(department.id, 0) department.absence_of_today = res_absence.get(department.id, 0) @api.multi def _compute_total_employee(self): emp_data = self.env['hr.employee'].read_group([('department_id', 'in', self.ids)], ['department_id'], ['department_id']) result = dict((data['department_id'][0], data['department_id_count']) for data in emp_data) for department in self: department.total_employee = result.get(department.id, 0) absence_of_today = fields.Integer( compute='_compute_leave_count', string='Absence by Today') leave_to_approve_count = fields.Integer( compute='_compute_leave_count', string='Leave to Approve') allocation_to_approve_count = fields.Integer( compute='_compute_leave_count', string='Allocation to Approve') total_employee = fields.Integer( compute='_compute_total_employee', string='Total Employee')
class EmbeddedSlide(models.Model): """ Embedding in third party websites. Track view count, generate statistics. """ _name = 'slide.embed' _description = 'Embedded Slides View Counter' _rec_name = 'slide_id' slide_id = fields.Many2one('slide.slide', string="Presentation", required=True, select=1, ondelete='cascade') url = fields.Char('Third Party Website URL', required=True) count_views = fields.Integer('# Views', default=1) def add_embed_url(self, slide_id, url): schema = urlparse(url) baseurl = schema.netloc embeds = self.search([('url', '=', baseurl), ('slide_id', '=', int(slide_id))], limit=1) if embeds: embeds.count_views += 1 else: embeds = self.create({ 'slide_id': slide_id, 'url': baseurl, }) return embeds.count_views
class plm_description(models.Model): _name = "plm.description" _description = "PLM Descriptions" name = fields.Char(_('Note to Description'), size=128) description = fields.Char(_('Standard Description'), size=128) description_en = fields.Char(_('Description English'), size=128) umc1 = fields.Char(_('UM / Feature 1'), size=32, help=_("Allow to specify a unit measure or a label for the feature.")) fmt1 = fields.Char(_('Format Feature 1'), size=32, help=_("Allow to represent the measure: %s%s allow to build um and value, %s builds only value, none builds only value.")) umc2 = fields.Char(_('UM / Feature 2'), size=32, help=_("Allow to specify a unit measure or a label for the feature.")) fmt2 = fields.Char(_('Format Feature 2'), size=32, help=_("Allow to represent the measure: %s%s allow to build um and value, %s builds only value, none builds only value.")) umc3 = fields.Char(_('UM / Feature 3'), size=32, help=_("Allow to specify a unit measure or a label for the feature.")) fmt3 = fields.Char(_('Format Feature 3'), size=32, help=_("Allow to represent the measure: %s%s allow to build um and value, %s builds only value, none builds only value.")) fmtend = fields.Char(_('Format Feature Composed'), size=32, help=_("Allow to represent a normalized composition of technical features : %s%s allows to build chained values.")) unitab = fields.Char(_('Normative Rule'), size=32, help=_("Specify normative rule (UNI, ISO, DIN...). It will be queued to build the product description.")) sequence = fields.Integer(_('Sequence'), help=_("Assign the sequence order when displaying a list of product categories.")) _defaults = { 'description': lambda *a: False, 'fmt1': lambda *a: False, 'fmt2': lambda *a: False, 'fmt3': lambda *a: False, 'fmtend': lambda *a: False, 'unitab': lambda *a: False, }
class ProductTemplate(models.Model): _inherit = 'product.template' track_service = fields.Selection([('manual', 'Manually set quantities on order')], string='Track Service', default='manual') @api.multi @api.depends('product_variant_ids.sales_count') def _sales_count(self): for product in self: product.sales_count = sum([p.sales_count for p in product.product_variant_ids]) @api.multi def action_view_sales(self): self.ensure_one() action = self.env.ref('sale.action_product_sale_list') product_ids = self.product_variant_ids.ids return { 'name': action.name, 'help': action.help, 'type': action.type, 'view_type': action.view_type, 'view_mode': action.view_mode, 'target': action.target, 'context': "{'search_default_product_id': " + ','.join(map(str, product_ids)) + ", 'default_product_id': " + str(product_ids[0]) + "}", 'res_model': action.res_model, 'domain': action.domain, } sales_count = fields.Integer(compute='_sales_count', string='# Sales') invoice_policy = fields.Selection( [('order', 'Ordered quantities'), ('delivery', 'Delivered quantities'), ('cost', 'Invoice based on time and material')], string='Invoicing Policy', default='order')
class AccountInvoiceLine(models.Model): _inherit = 'account.invoice.line' saas_portal_client_id = fields.Many2one( 'saas_portal.client', string='SaaS client', help= 'reference to the SaaS client if this invoice line is created for a SaaS product' ) plan_id = fields.Many2one('saas_portal.plan', related='product_id.plan_id', readonly=True) period = fields.Integer(string='Subscription period', help='subsciption period in days', readonly=True, default=0) state = fields.Selection(related='invoice_id.state', readonly=True) @api.model def create(self, vals): product_obj = self.env['product.product'].browse( vals.get('product_id')) attribute_value_obj = product_obj.attribute_value_ids.filtered( lambda r: r.attribute_id.saas_code == 'SUBSCRIPTION_PERIOD') period = attribute_value_obj and int( attribute_value_obj[0].saas_code_value) or 0 vals.update({'period': period}) return super(AccountInvoiceLine, self).create(vals)
class ResPartnerIDtype(models.Model): _name = 'res.partner.idtype' _description = 'Identificacion Tipo de Documento' _order = 'sequence' name = fields.Char(required=True) code = fields.Char(required=True) sequence = fields.Integer() active = fields.Boolean(default=True) note = fields.Text() on_company = fields.Boolean( string=u'On Company?', default=True, help="Id type for use on Company" ) on_contact = fields.Boolean( string=u'On Contact?', default=True, help="Id type for use on Contacts" ) on_merchant = fields.Boolean( string=u'On Merchants?', default=True, help="Id type for use on Merchants" )
class product_product(models.Model): _inherit = 'product.product' attachment_count = fields.Integer(compute='_compute_attachment_count', string="File") @api.multi def _compute_attachment_count(self): IrAttachment = self.env['ir.attachment'] for product in self: product.attachment_count = IrAttachment.search_count([ ('res_model', '=', product._name), ('res_id', 'in', product.ids) ]) @api.multi def action_open_attachments(self): self.ensure_one() return { 'name': _('Digital Attachments'), 'domain': [('res_model', '=', self._name), ('res_id', '=', self.id)], 'res_model': 'ir.attachment', 'type': 'ir.actions.act_window', 'view_mode': 'kanban,form', 'view_type': 'form', 'context': "{'default_res_model': '%s','default_res_id': %d}" % (self._name, self.id), }
class plm_relation_line(models.Model): _name = 'mrp.bom.line' _inherit = 'mrp.bom.line' _order = "itemnum" @api.one def _get_child_bom_lines(self): """ If the BOM line refers to a BOM, return the ids of the child BOM lines """ bom_obj = self.env['mrp.bom'] for bom_line in self: bom_id = bom_obj._bom_find( product_tmpl_id=bom_line.product_id.product_tmpl_id.id, product_id=bom_line.product_id.id, bomType=bom_line.type) if bom_id: child_bom = bom_obj.browse(bom_id) for childBomLine in child_bom.bom_line_ids: childBomLine._get_child_bom_lines() self.child_line_ids = [x.id for x in child_bom.bom_line_ids] else: self.child_line_ids = False state = fields.Selection (related="product_id.state", string=_("Status"), help=_("The status of the product in its LifeCycle."), store=False) engineering_revision = fields.Integer (related="product_id.engineering_revision", string=_("Revision"), help=_("The revision of the product."), store=False) description = fields.Text (related="product_id.description", string=_("Description"), store=False) weight_net = fields.Float (related="product_id.weight", string=_("Weight Net"), store=False) child_line_ids = fields.One2many ("mrp.bom.line",compute=_get_child_bom_lines,string=_("BOM lines of the referred bom"))
class OpLibraryCardType(models.Model): _name = 'op.library.card.type' _description = 'Library Card Type' name = fields.Char('Name', size=256, required=True) allow_book = fields.Integer('No of Books Allowed', size=10, required=True) duration = fields.Integer('Duration', help='Duration in terms of Number of Lead Days', required=True) penalty_amt_per_day = fields.Float('Penalty Amount per Day', required=True) @api.constrains('allow_book', 'duration', 'penalty_amt_per_day') def check_details(self): if self.allow_book < 0 or self.duration < 0.0 or \ self.penalty_amt_per_day < 0.0: raise ValidationError('Enter proper value')
class EventAnswer(models.Model): _name = 'event.answer' _order = 'sequence,id' name = fields.Char('Answer', required=True, translate=True) question_id = fields.Many2one('event.question', required=True, ondelete='cascade') sequence = fields.Integer(default=10)
class OpHostelRoomAllocation(models.Model): _name = 'op.hostel.room' hostel_id = fields.Many2one('op.hostel', 'Hostel', required=True) name = fields.Many2one('op.room', 'Room', required=True) student_ids = fields.Many2many('res.partner', string='Allocated Students') students_per_room = fields.Integer('Students per Room', required=True) rent = fields.Float('Rent') allocated_date = fields.Date('Allocated Date', default=fields.Date.today()) @api.constrains('students_per_room') def check_capacity(self): if self.students_per_room <= 0: raise ValidationError("Enter proper Student Per Room") @api.onchange('hostel_id') def onchange_hostel(self): if self.hostel_id: self.name = False @api.onchange('name') def onchange_name(self): if self.name: self.students_per_room = self.name.capacity @api.one @api.constrains('student_ids', 'students_per_room') def _check_student_capacity(self): if len(self.student_ids) > self.students_per_room: raise ValidationError('Room capacity Over')
class account_bank_statement_line(models.Model): _inherit = "account.bank.statement.line" mercury_card_number = fields.Char( string='Card Number', help='The last 4 numbers of the card used to pay') mercury_prefixed_card_number = fields.Char( string='Card Number', compute='_compute_prefixed_card_number', help='The card number used for the payment.') mercury_card_brand = fields.Char( string='Card Brand', help='The brand of the payment card (e.g. Visa, AMEX, ...)') mercury_card_owner_name = fields.Char(string='Card Owner Name', help='The name of the card owner') mercury_ref_no = fields.Char( string='Mercury reference number', help='Payment reference number from Mercury Pay') mercury_record_no = fields.Char( string='Mercury record number', help='Payment record number from Mercury Pay') mercury_invoice_no = fields.Integer(string='Mercury invoice number', help='Invoice number from Mercury Pay') @api.one def _compute_prefixed_card_number(self): if self.mercury_card_number: self.mercury_prefixed_card_number = "********" + self.mercury_card_number else: self.mercury_prefixed_card_number = ""
class product_cate(models.Model): ''' 产品内部分类: ''' _inherit = 'product.category' third_id=fields.Integer(string='第三方分类ID') @api.model def cate_import(self,list_value): ''' 功能:导入第三方系统的产品分类 :param list_value: :param source_code: 第三方编码,可以是数据库名称 :return: ''' list_sort=sorted(list_value,key=lambda k:k["parent_id"]) for vals in list_sort: cate_value={} cate_value['third_id']=vals['third_id'] cate_value['name']=vals['name'] p_category_obj=self.env['product.category'] parent_id=vals['parent_id'] exist_category=p_category_obj.search([('third_id','=',vals['third_id'])]) if len(exist_category)==0: if int(parent_id)!=0: exist_parent_category=p_category_obj.search([('third_id','=',parent_id)]) if len(exist_parent_category)>0: cate_value['parent_id']=exist_parent_category[0].id p_category_obj.create(cate_value) else: exist_category.write(cate_value)
class Project(models.Model): _inherit = "project.project" @api.one @api.depends('percentage_satisfaction_task') def _compute_percentage_satisfaction_project(self): self.percentage_satisfaction_project = self.percentage_satisfaction_task @api.one @api.depends('tasks.rating_ids.rating') def _compute_percentage_satisfaction_task(self): activity = self.tasks.rating_get_grades() self.percentage_satisfaction_task = activity['great'] * 100 / sum( activity.values()) if sum(activity.values()) else -1 percentage_satisfaction_task = fields.Integer( compute='_compute_percentage_satisfaction_task', string='% Happy', store=True, default=-1) percentage_satisfaction_project = fields.Integer( compute="_compute_percentage_satisfaction_project", string="% Happy", store=True, default=-1) is_visible_happy_customer = fields.Boolean( string="Customer Satisfaction", default=False, help= "Display informations about rating of the project on kanban and form view. This buttons will only be displayed if at least a rating exists." ) @api.multi def action_view_task_rating(self): """ return the action to see all the rating about the tasks of the project """ action = self.env['ir.actions.act_window'].for_xml_id( 'rating', 'action_view_rating') return dict(action, domain=[('rating', '!=', -1), ('res_id', 'in', self.tasks.ids), ('res_model', '=', 'project.task')]) @api.multi def action_view_all_rating(self): """ return the action to see all the rating about the all sort of activity of the project (tasks, issues, ...) """ return self.action_view_task_rating()
class event_type(models.Model): """ Event Type """ _name = 'event.type' _description = 'Event Type' name = fields.Char('Event Type', required=True, translate=True) default_reply_to = fields.Char('Reply To') default_registration_min = fields.Integer( 'Default Minimum Registration', default=0, help= "It will select this default minimum value when you choose this event") default_registration_max = fields.Integer( 'Default Maximum Registration', default=0, help= "It will select this default maximum value when you choose this event")
class report_plm_files_partner(models.Model): _name = "report.plm_files.partner" _description = "Files details by Partners" _auto = False name = fields.Char(_('Year'), size=64, required=False, readonly=True) file_size = fields.Integer(_('File Size'), readonly=True) nbr = fields.Integer(_('# of Files'), readonly=True) partner = fields.Char(_('Partner'), size=64, readonly=True) month = fields.Selection([('01', _('January')), ('02', _('February')), ('03', _('March')), ('04', _('April')), ('05', _('May')), ('06', _('June')), ('07', _('July')), ('08', _('August')), ('09', _('September')), ('10', _('October')), ('11', _('November')), ('12', _('December'))], _('Month'), readonly=True)
class RecruitmentDegree(models.Model): _name = "hr.recruitment.degree" _description = "Degree of Recruitment" _sql_constraints = [ ('name_uniq', 'unique (name)', 'The name of the Degree of Recruitment must be unique!') ] name = fields.Char("Degree", required=True, translate=True) sequence = fields.Integer("Sequence", default=1, help="Gives the sequence order when displaying a list of degrees.")
class OpScholarshipType(models.Model): _name = 'op.scholarship.type' name = fields.Char('Name', size=64, required=True) amount = fields.Integer('Amount') @api.constrains('amount') def check_amount(self): if self.amount <= 0: raise ValidationError('Enter proper Amount')
class HrDepartment(models.Model): _inherit = 'hr.department' def _compute_expense_to_approve(self): expense_data = self.env['hr.expense'].read_group([('department_id', 'in', self.ids), ('state', '=', 'submit')], ['department_id'], ['department_id']) result = dict((data['department_id'][0], data['department_id_count']) for data in expense_data) for department in self: department.expense_to_approve_count = result.get(department.id, 0) expense_to_approve_count = fields.Integer(compute='_compute_expense_to_approve', string='Expenses to Approve')
class MailMessageSubtype(models.Model): """ Class holding subtype definition for messages. Subtypes allow to tune the follower subscription, allowing only some subtypes to be pushed on the Wall. """ _name = 'mail.message.subtype' _description = 'Message subtypes' _order = 'sequence, id' name = fields.Char( 'Message Type', required=True, translate=True, help='Message subtype gives a more precise type on the message, ' 'especially for system notifications. For example, it can be ' 'a notification related to a new record (New), or to a stage ' 'change in a process (Stage change). Message subtypes allow to ' 'precisely tune the notifications the user want to receive on its wall.' ) description = fields.Text( 'Description', translate=True, help='Description that will be added in the message posted for this ' 'subtype. If void, the name will be added instead.') internal = fields.Boolean( 'Internal Only', help= 'Messages with internal subtypes will be visible only by employees, aka members of base_user group' ) parent_id = fields.Many2one( 'mail.message.subtype', string='Parent', ondelete='set null', help= 'Parent subtype, used for automatic subscription. This field is not ' 'correctly named. For example on a project, the parent_id of project ' 'subtypes refers to task-related subtypes.') relation_field = fields.Char( 'Relation field', help='Field used to link the related model to the subtype model when ' 'using automatic subscription on a related document. The field ' 'is used to compute getattr(related_document.relation_field).') res_model = fields.Char( 'Model', help= "Model the subtype applies to. If False, this subtype applies to all models." ) default = fields.Boolean('Default', default=True, help="Activated by default when subscribing.") sequence = fields.Integer('Sequence', default=1, help="Used to order subtypes.") hidden = fields.Boolean('Hidden', help="Hide the subtype in the follower options")
class OpClassroom(models.Model): _name = 'op.classroom' name = fields.Char('Name', size=16, required=True) code = fields.Char('Code', size=4, required=True) course_id = fields.Many2one('op.course', 'Course', required=True) capacity = fields.Integer(string='No of Person') facilities = fields.One2many('op.facility.line', 'classroom_id', string='Facility Lines') asset_line = fields.One2many('op.asset', 'asset_id', 'Asset')
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 channel', 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)") def init(self, cr): # 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(cr, 'im_livechat_report_operator') 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 ) """)