class EventQuestion(models.Model): _name = 'event.question' _rec_name = 'title' _order = 'sequence,id' _description = 'Event Question' title = fields.Char(required=True, translate=True) event_type_id = fields.Many2one('event.type', 'Event Type', ondelete='cascade') event_id = fields.Many2one('event.event', 'Event', ondelete='cascade') answer_ids = fields.One2many('event.answer', 'question_id', "Answers", required=True, copy=True) sequence = fields.Integer(default=10) is_individual = fields.Boolean( 'Ask each attendee', help= "If True, this question will be asked for every attendee of a reservation. If " "not it will be asked only once and its value propagated to every attendees." ) @api.constrains('event_type_id', 'event_id') def _constrains_event(self): if any(question.event_type_id and question.event_id for question in self): raise UserError( _('Question cannot belong to both the event category and itself.' )) @api.model def create(self, vals): event_id = vals.get('event_id', False) if event_id: event = self.env['event.event'].browse([event_id]) if event.event_type_id.use_questions and event.event_type_id.question_ids: vals['answer_ids'] = vals.get( 'answer_ids', []) + [(0, 0, { 'name': answer.name, 'sequence': answer.sequence, }) for answer in event.event_type_id.question_ids.filtered( lambda question: question.title == vals.get('title')). mapped('answer_ids')] return super(EventQuestion, self).create(vals)
class DigestTip(models.Model): _name = 'digest.tip' _description = 'Digest Tips' _order = 'sequence' sequence = fields.Integer( 'Sequence', default=1, help='Used to display digest tip in email template base on order') user_ids = fields.Many2many('res.users', string='Recipients', help='Users having already received this tip') tip_description = fields.Html('Tip description', translate=html_translate) group_id = fields.Many2one( 'res.groups', string='Authorized Group', default=lambda self: self.env.ref('base.group_user'))
class CashmoveReport(models.Model): _name = "lunch.cashmove.report" _description = 'Cashmoves report' _auto = False _order = "date desc" id = fields.Integer('ID') amount = fields.Float('Amount') date = fields.Date('Date') currency_id = fields.Many2one('res.currency', string='Currency') user_id = fields.Many2one('res.users', string='User') description = fields.Text('Description') def name_get(self): return [(cashmove.id, '%s %s' % (_('Lunch Cashmove'), '#%d' % cashmove.id)) for cashmove in self] def init(self): tools.drop_view_if_exists(self._cr, self._table) self._cr.execute(""" CREATE or REPLACE view %s as ( SELECT lc.id as id, lc.amount as amount, lc.date as date, lc.currency_id as currency_id, lc.user_id as user_id, lc.description as description FROM lunch_cashmove lc UNION ALL SELECT -lol.id as id, -lol.price as amount, lol.date as date, lol.currency_id as currency_id, lol.user_id as user_id, format('Order: %%s x %%s %%s', lol.quantity::text, lp.name, lol.display_toppings) as description FROM lunch_order lol JOIN lunch_product lp ON lp.id = lol.product_id WHERE lol.state in ('ordered', 'confirmed') AND lol.active = True ); """ % self._table)
class RestaurantFloor(models.Model): _name = 'restaurant.floor' _description = 'Restaurant Floor' name = fields.Char( 'Floor Name', required=True, help='An internal identification of the restaurant floor') pos_config_id = fields.Many2one('pos.config', string='Point of Sale') background_image = fields.Binary( 'Background Image', help= 'A background image used to display a floor layout in the point of sale interface' ) background_color = fields.Char( 'Background Color', help= 'The background color of the floor layout, (must be specified in a html-compatible format)', default='rgb(210, 210, 210)') table_ids = fields.One2many('restaurant.table', 'floor_id', string='Tables', help='The list of tables in this floor') sequence = fields.Integer('Sequence', help='Used to sort Floors', default=1) def unlink(self): confs = self.mapped('pos_config_id').filtered( lambda c: c.is_table_management == True) opened_session = self.env['pos.session'].search([ ('config_id', 'in', confs.ids), ('state', '!=', 'closed') ]) if opened_session: error_msg = _( "You cannot remove a floor that is used in a PoS session, close the session(s) first: \n" ) for floor in self: for session in opened_session: if floor in session.config_id.floor_ids: error_msg += _("Floor: %s - PoS Config: %s \n") % ( floor.name, session.config_id.name) if confs: raise UserError(error_msg) return super(RestaurantFloor, self).unlink()
class PeopleRole(models.Model): """ CRM Reveal People Roles for People """ _name = 'crm.reveal.role' _description = 'People Role' name = fields.Char(string='Role Name', required=True, translate=True) reveal_id = fields.Char(required=True) color = fields.Integer(string='Color Index') _sql_constraints = [ ('name_uniq', 'unique (name)', 'Role name already exists!'), ] @api.depends('name') def name_get(self): return [(role.id, role.name.replace('_', ' ').title()) for role in self]
class ResPartner(models.Model): _inherit = 'res.partner' event_count = fields.Integer("Events", compute='_compute_event_count', help="Number of events the partner has participated.") def _compute_event_count(self): self.event_count = 0 if not self.user_has_groups('event.group_event_user'): return for partner in self: partner.event_count = self.env['event.event'].search_count([('registration_ids.partner_id', 'child_of', partner.ids)]) def action_event_view(self): action = self.env.ref('event.action_event_view').read()[0] action['context'] = {} action['domain'] = [('registration_ids.partner_id', 'child_of', self.ids)] return action
class SaleCouponRule(models.Model): _name = 'sale.coupon.rule' _description = "Sales Coupon Rule" rule_date_from = fields.Datetime(string="Start Date", help="Coupon program start date") rule_date_to = fields.Datetime(string="End Date", help="Coupon program end date") rule_partners_domain = fields.Char( string="Based on Customers", help="Coupon program will work for selected customers only") rule_products_domain = fields.Char( string="Based on Products", default=[['sale_ok', '=', True]], help="On Purchase of selected product, reward will be given") rule_min_quantity = fields.Integer( string="Minimum Quantity", default=1, help="Minimum required product quantity to get the reward") rule_minimum_amount = fields.Float( default=0.0, help="Minimum required amount to get the reward") rule_minimum_amount_tax_inclusion = fields.Selection( [('tax_included', 'Tax Included'), ('tax_excluded', 'Tax Excluded')], default="tax_excluded") @api.constrains('rule_date_to', 'rule_date_from') def _check_rule_date_from(self): if any(applicability for applicability in self if applicability.rule_date_to and applicability.rule_date_from and applicability.rule_date_to < applicability.rule_date_from): raise ValidationError( _('The start date must be before the end date')) @api.constrains('rule_minimum_amount') def _check_rule_minimum_amount(self): if self.filtered( lambda applicability: applicability.rule_minimum_amount < 0): raise ValidationError( _('Minimum purchased amount should be greater than 0')) @api.constrains('rule_min_quantity') def _check_rule_min_quantity(self): if not self.rule_min_quantity > 0: raise ValidationError( _('Minimum quantity should be greater than 0'))
class CrmLeadFutureStudent(models.Model): _name = 'crm.lead.future.student' _description = 'Future student from leads' @api.model def _get_selection_gender(self): return self.env['res.partner'].fields_get( allfields=['gender'])['gender']['selection'] crm_lead_id = fields.Many2one(comodel_name="crm.lead", string='Lead', required=True, ondelete='cascade') child_id = fields.Many2one(comodel_name='res.partner', string='Child', domain=[('educational_category', 'in', ('student', 'other'))]) name = fields.Char(string='Child name', required=True) birth_date = fields.Date(string='Birth date') year_birth = fields.Integer(string='Year of birth', compute='_compute_year_birth') course_id = fields.Many2one(comodel_name='education.course', string='Initial school course') gender = fields.Selection(string='Gender', selection=_get_selection_gender) school_id = fields.Many2one(comodel_name='res.partner', string='School', domain=[('educational_category', '=', 'school') ]) academic_year_id = fields.Many2one( comodel_name='education.academic_year', string='Academic year', domain=lambda s: [('date_end', '>', fields.Date.context_today(s))]) @api.onchange('child_id') def onchange_child_id(self): if self.child_id: self.name = self.child_id.name self.birth_date = self.child_id.birthdate_date self.gender = self.child_id.gender @api.multi def _compute_year_birth(self): for student in self.filtered(lambda c: c.birth_date): birth_date = fields.Date.from_string(student.birth_date) student.year_birth = birth_date.year
class EventTypeMail(models.Model): """ Template of event.mail to attach to event.type. Those will be copied upon all events created in that type to ease event creation. """ _name = 'event.type.mail' _description = 'Mail Scheduling on Event Category' event_type_id = fields.Many2one('event.type', string='Event Type', ondelete='cascade', required=True) notification_type = fields.Selection([('mail', 'Mail')], string='Send', default='mail', required=True) interval_nbr = fields.Integer('Interval', default=1) interval_unit = fields.Selection([('now', 'Immediately'), ('hours', 'Hours'), ('days', 'Days'), ('weeks', 'Weeks'), ('months', 'Months')], string='Unit', default='hours', required=True) interval_type = fields.Selection([('after_sub', 'After each registration'), ('before_event', 'Before the event'), ('after_event', 'After the event')], string='Trigger', default="before_event", required=True) template_id = fields.Many2one( 'mail.template', string='Email Template', domain=[('model', '=', 'event.registration')], ondelete='restrict', help= 'This field contains the template of the mail that will be automatically sent' ) @api.model def _get_event_mail_fields_whitelist(self): """ Whitelist of fields that are copied from event_type_mail_ids to event_mail_ids when changing the event_type_id field of event.event """ return [ 'notification_type', 'template_id', 'interval_nbr', 'interval_unit', 'interval_type' ]
class IrModelField(models.Model): _inherit = 'ir.model.fields' tracking = fields.Integer( string="Enable Ordered Tracking", help="If set every modification done to this field is tracked in the chatter. Value is used to order tracking values.", ) def _reflect_field_params(self, field): """ Tracking value can be either a boolean enabling tracking mechanism on field, either an integer giving the sequence. Default sequence is set to 100. """ vals = super(IrModelField, self)._reflect_field_params(field) tracking = getattr(field, 'tracking', None) if tracking is True: tracking = 100 elif tracking is False: tracking = None vals['tracking'] = tracking return vals def _instanciate_attrs(self, field_data): attrs = super(IrModelField, self)._instanciate_attrs(field_data) if attrs and field_data.get('tracking'): attrs['tracking'] = field_data['tracking'] return attrs def unlink(self): """ Delete 'mail.tracking.value's when a module is uninstalled """ if self: query = """ DELETE FROM mail_tracking_value WHERE id IN ( SELECT t.id FROM mail_tracking_value t INNER JOIN mail_message m ON (m.id = t.mail_message_id) INNER JOIN ir_model_fields f ON (t.field = f.name AND m.model = f.model) WHERE f.id IN %s ); """ self.flush() self.env.cr.execute(query, (tuple(self.ids),)) return super(IrModelField, self).unlink()
class DemoFailureWizard(models.TransientModel): _name = 'ir.demo_failure.wizard' _description = 'Demo Failure wizard' failure_ids = fields.One2many('ir.demo_failure', 'wizard_id', readonly=True, string="Demo Installation Failures") failures_count = fields.Integer(compute='_compute_failures_count') @api.depends('failure_ids') def _compute_failures_count(self): for r in self: r.failures_count = len(r.failure_ids) def done(self): # pylint: disable=next-method-called return self.env['ir.module.module'].next()
class res_partner(models.Model): _name = 'res.partner' _inherit = 'res.partner' payment_token_ids = fields.One2many('payment.token', 'partner_id', 'Payment Tokens') payment_token_count = fields.Integer( 'Count Payment Token', compute='_compute_payment_token_count') @api.depends('payment_token_ids') def _compute_payment_token_count(self): payment_data = self.env['payment.token'].read_group( [('partner_id', 'in', self.ids)], ['partner_id'], ['partner_id']) mapped_data = dict([(payment['partner_id'][0], payment['partner_id_count']) for payment in payment_data]) for partner in self: partner.payment_token_count = mapped_data.get(partner.id, 0)
class OpExamRoom(models.Model): _name = "op.exam.room" _description = "Exam Room" name = fields.Char('Name', size=256, required=True) classroom_id = fields.Many2one('op.classroom', 'Classroom', required=True) capacity = fields.Integer('Capacity', required=True) @api.constrains('capacity') def check_capacity(self): if self.capacity < 0: raise ValidationError(_('Enter proper Capacity')) elif self.capacity > self.classroom_id.capacity: raise ValidationError(_('Capacity over Classroom capacity!')) @api.onchange('classroom_id') def onchange_classroom(self): self.capacity = self.classroom_id.capacity
class NewModel(models.Model): _name = 'export.%s' % name _description = 'Export: %s' % name _rec_name = 'value' const = fields.Integer(default=4) value = field @api.multi def name_get(self): return [(record.id, "%s:%s" % (self._name, record.value)) for record in self] @api.model def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): if isinstance(name, pycompat.string_types) and name.split(':')[0] == self._name: record_ids = self._search([('value', operator, int(name.split(':')[1]))], access_rights_uid=name_get_uid) return self.browse(record_ids).name_get() else: return []
class ProductTemplateAttributeLine(models.Model): _inherit = "product.template.attribute.line" _order = "sequence" def _default_sequence(self): # without this function there was a bug when attributes were created # from Product Variants tab. If several attributes were created without pushing the save button # sequence got the same value for their attribute lines. And if there was no lines before # sequence got False for the first attribute num = self.search_count([]) + 1 return num sequence = fields.Integer( "Sequence", help="Determine the display order", required=True, default=_default_sequence, )
class FixedPutAwayStrategy(models.Model): _name = 'stock.fixed.putaway.strat' _order = 'sequence' _description = 'Fixed Putaway Strategy on Location' product_id = fields.Many2one('product.product', 'Product') putaway_id = fields.Many2one('product.putaway', 'Put Away Method', required=True) category_id = fields.Many2one('product.category', 'Product Category') fixed_location_id = fields.Many2one('stock.location', 'Location', required=True) sequence = fields.Integer( 'Priority', help= "Give to the more specialized category, a higher priority to have them in top of the list." )
class ResPartner(models.Model): _inherit = 'res.partner' pos_order_count = fields.Integer( compute='_compute_pos_order', help="The number of point of sales orders related to this customer", groups="point_of_sale.group_pos_user", ) pos_order_ids = fields.One2many('pos.order', 'partner_id', readonly=True) barcode = fields.Char(help="Use a barcode to identify this contact from the Point of Sale.", copy=False) _sql_constraints = [ ('unique_barcode', 'unique(barcode, company_id)', 'This barcode is already assigned to another contact. Please make sure you assign a unique barcode to this contact.'), ] def _compute_pos_order(self): partners_data = self.env['pos.order'].read_group([('partner_id', 'in', self.ids)], ['partner_id'], ['partner_id']) mapped_data = dict([(partner['partner_id'][0], partner['partner_id_count']) for partner in partners_data]) for partner in self: partner.pos_order_count = mapped_data.get(partner.id, 0) @api.model def create_from_ui(self, partner): """ create or modify a partner from the point of sale ui. partner contains the partner's fields. """ # image is a dataurl, get the data after the comma if partner.get('image_1920'): partner['image_1920'] = partner['image_1920'].split(',')[1] partner_id = partner.pop('id', False) if partner_id: # Modifying existing partner self.browse(partner_id).write(partner) else: partner['lang'] = self.env.user.lang partner_id = self.create(partner).id return partner_id def unlink(self): running_sessions = self.env['pos.session'].search([('state', '!=', 'closed')]) if running_sessions: raise UserError( _("You cannot delete contacts while there are active PoS sessions. Close the session(s) %s first.") % ", ".join(session.name for session in running_sessions) ) return super(ResPartner, self).unlink()
class SaleCouponGenerate(models.TransientModel): _name = 'sale.coupon.generate' _description = 'Generate Sales Coupon' nbr_coupons = fields.Integer(string="Number of Coupons", help="Number of coupons", default=1) generation_type = fields.Selection( [('nbr_coupon', 'Number of Coupons'), ('nbr_customer', 'Number of Selected Customers')], default='nbr_coupon') partners_domain = fields.Char(string="Customer", default='[]') def generate_coupon(self): """Generates the number of coupons entered in wizard field nbr_coupons """ program = self.env['sale.coupon.program'].browse( self.env.context.get('active_id')) vals = {'program_id': program.id} if self.generation_type == 'nbr_coupon' and self.nbr_coupons > 0: for count in range(0, self.nbr_coupons): self.env['sale.coupon'].create(vals) if self.generation_type == 'nbr_customer' and self.partners_domain: for partner in self.env['res.partner'].search( safe_eval(self.partners_domain)): vals.update({'partner_id': partner.id}) coupon = self.env['sale.coupon'].create(vals) subject = '%s, a coupon has been generated for you' % ( partner.name) template = self.env.ref( 'sale_coupon.mail_template_sale_coupon', raise_if_not_found=False) if template: template.send_mail(coupon.id, email_values={ 'email_to': partner.email, 'email_from': self.env.user.email or '', 'subject': subject, })
class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' plafond_secu = fields.Float(related='company_id.plafond_secu', string="Plafond de la Securite Sociale", readonly=False) nombre_employes = fields.Integer(related='company_id.nombre_employes', string="Nombre d'employes", readonly=False) cotisation_prevoyance = fields.Float( related='company_id.cotisation_prevoyance', string='Cotisation Patronale Prevoyance', readonly=False) org_ss = fields.Char(related='company_id.org_ss', string="Organisme de securite sociale", readonly=False) conv_coll = fields.Char(related='company_id.conv_coll', string="Convention collective", readonly=False)
class Message(models.Model): _name = "eagle.smsgateway.message" message_id = fields.Integer("SMS ID", ) device = fields.Many2one("eagle.smsgateway.device", "From Device") message = fields.Char("Message") phone_number = fields.Char("To") updated_at = fields.Datetime("Posted at") sent_at = fields.Datetime("Sent at") sms_status = fields.Selection([(1, "Pending"), (2, "Sent"), (3, "Failed")]) created_at = fields.Datetime("created on", default=datetime.datetime.utcnow()) _sql_constraints = [ ('message_id_unique', 'unique(message_id)', 'Message Id Must Be Unique'), ] @api.multi def send_sms(self): for rec in self: body = [{ 'device_id': rec.device_id, 'phone_number': rec.phone_number, 'message': rec.message }] response = rec.device.sms_gateway._make_post('message/send', body) rec.message_id = response[0]["id"] rec.updated_at = response[0]["updated_at"].replace('T', " ") if response[0]["status"] == 'pending': rec.sms_status = 1 return response def get_sms(self): for rec in self: url = 'message/{}'.format(rec.message_id) response = rec.device.sms_gateway._make_get(url) if response["status"] == 'sent': rec.sms_status = 2 rec.sent_at = response["updated_at"].replace('T', " ") if response["status"] == 'failed': rec.sms_status = 3 rec.sent_at = response["updated_at"].replace('T', " ") return response
class DecimalPrecision(models.Model): _name = 'decimal.precision' _description = 'Decimal Precision' name = fields.Char('Usage', index=True, required=True) digits = fields.Integer('Digits', required=True, default=2) _sql_constraints = [ ('name_uniq', 'unique (name)', """Only one value can be defined for each given usage!"""), ] @api.model @tools.ormcache('application') def precision_get(self, application): self.env.cr.execute( 'select digits from decimal_precision where name=%s', (application, )) res = self.env.cr.fetchone() return res[0] if res else 2 @api.model_cr def clear_cache(self): """ Deprecated, use `clear_caches` instead. """ self.clear_caches() @api.model_create_multi def create(self, vals_list): res = super(DecimalPrecision, self).create(vals_list) self.clear_caches() return res @api.multi def write(self, data): res = super(DecimalPrecision, self).write(data) self.clear_caches() return res @api.multi def unlink(self): res = super(DecimalPrecision, self).unlink() self.clear_caches() return res
class ProductTemplate(models.Model): _inherit = ['product.template'] attachment_count = fields.Integer(compute='_compute_attachment_count', string="File") @api.multi def _compute_attachment_count(self): attachment_data = self.env['ir.attachment'].read_group( [('res_model', '=', self._name), ('res_id', 'in', self.ids), ('product_downloadable', '=', True)], ['res_id'], ['res_id']) mapped_data = dict([(data['res_id'], data['res_id_count']) for data in attachment_data]) for product_template in self: product_template.attachment_count = mapped_data.get( product_template.id, 0) @api.multi def action_open_attachments(self): self.ensure_one() return { 'name': _('Digital Attachments'), 'domain': [('res_model', '=', self._name), ('res_id', '=', self.id), ('product_downloadable', '=', True)], '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, 'default_product_downloadable': True}" % (self._name, self.id), 'help': """ <p class="o_view_nocontent_smiling_face">Add attachments for this digital product</p> <p>The attached files are the ones that will be purchased and sent to the customer.</p> """, }
class EagleeduClass(models.Model): _name = 'eagleedu.class' _description = "Class Standard Level" _order = 'sequence' sequence = fields.Integer(string="Sequence", default=0, help="List of Sequence no.") name = fields.Char(string='Class', required=True, help="Enter the Name of the Class") code = fields.Char(string='Code', required=True, help="Enter the Code of the Class") class_id = fields.Many2one('eagleedu.class', string='Class', help="Enter the Name of the Class") class_section_id = fields.Many2one('eagleedu.class_section', string='Section Name', help="Enter the Name of the Section") class_sections_ids = fields.Many2many('eagleedu.class_section', string='Sections Names', help="Enter the Name of the Section") roman_name = fields.Char(string='Roman Name ', help="Enter the Code of the Class") group_division_id = fields.Many2one( 'eagleedu.group_division', string='Group Division', help="Enter the Name of the Group division") group_division_ids = fields.Many2many( 'eagleedu.group_division', string='Groups Divisions', help="Enter the Name of the Group division") subjects_ids = fields.Many2many( 'eagleedu.subject', string='Subjects Names ', help="Enter the Name of the Group division") class_category_id = fields.Many2one( 'eagleedu.class_category', string='Class Category', help="Enter the Name of the Class Category")
class ks_product_slider(models.Model): _name = 'ks_product.multitab_slider' _description = 'This is used for product slider snippet' name = fields.Char(required=True) ks_product_template_slider = fields.Many2many("product.template", string="Items") ks_loop = fields.Boolean("Repeat Products", default=False) ks_auto_slide = fields.Boolean("Automatic Slide", default=True) ks_Speed = fields.Integer("Slide Speed", default=300) ks_item_selection_method = fields.Selection( [('products', 'Products')], string='Slider Type', required=True, default='products') ks_nav_links = fields.Boolean("Navigation Buttons", default=True) ks_product_brand_ids = fields.Many2many('ks_product_manager.ks_brand', string='Brand') ks_product_cat_ids = fields.Many2many('product.public.category', string='Category') ks_product_blogs_ids = fields.Many2many('blog.post', string='Blogs') ks_items_per_slide = fields.Selection([('2', '2'), ('3', '3'), ('4', '4'), ('5', '5')], string='Items Per Slide', required=True, default='4') tabs_line_ids_line = fields.One2many('ks_product.slider_line', 'tabs_line_ids_tabs', 'Product Attributes')
class HrEmployee(models.Model): _inherit = 'hr.employee' center_ids = fields.Many2many(comodel_name='res.partner', string='Education Centers', compute='_compute_center_ids', store=True) tutored_student_ids = fields.One2many( comodel_name='hr.employee.supervised.year', inverse_name='teacher_id', string='Tutored students per year') count_tutored_students = fields.Integer( string='# Tutored students', compute='_compute_count_tutored_students') @api.depends('user_id', 'user_id.school_ids') def _compute_center_ids(self): for employee in self.filtered('user_id'): employee.center_ids = employee.user_id.school_ids @api.depends('tutored_student_ids') def _compute_count_tutored_students(self): for employee in self: employee.count_tutored_students = (len( employee.tutored_student_ids)) @api.multi def button_show_tutored_students(self): self.ensure_one() self = self.with_context(search_default_teacher_id=self.id, default_teacher_id=self.id) action = self.env.ref( 'hr_school.action_hr_employee_supervised_year_form') action_dict = action.read()[0] if action else {} action_dict['context'] = safe_eval(action_dict.get('context', '{}')) action_dict['context'].update({ 'search_default_teacher_id': self.id, 'default_teacher_id': self.id }) domain = expression.AND([[('teacher_id', '=', self.id)], safe_eval(action.domain or '[]')]) action_dict.update({'domain': domain}) return action_dict
class Product(models.Model): _inherit = 'product.product' attachment_count = fields.Integer(compute='_compute_attachment_count', string="File") def _compute_attachment_count(self): for product in self: product.attachment_count = self.env['ir.attachment'].search_count([ '|', ('res_model', '=', 'product.template'), ('res_id', '=', product.product_tmpl_id.id), ('product_downloadable', '=', True), ('res_model', '=', 'product.product'), ('res_id', '=', product.id), ('product_downloadable', '=', True) ]) def action_open_attachments(self): self.ensure_one() return { 'name': _('Digital Attachments'), 'domain': [('product_downloadable', '=', True), '|', '&', ('res_model', '=', 'product.template'), ('res_id', '=', self.product_tmpl_id.id), '&', ('res_model', '=', self._name), ('res_id', '=', self.id)], 'res_model': 'ir.attachment', 'type': 'ir.actions.act_window', 'view_mode': 'kanban,form', 'context': "{'default_res_model': '%s','default_res_id': %d, 'default_product_downloadable': True}" % (self._name, self.id), 'help': """ <p class="o_view_nocontent_smiling_face">Add attachments for this digital product</p> <p>The attached files are the ones that will be purchased and sent to the customer.</p> """, }
class ProductTemplateAttributeValue(models.Model): """Materialized relationship between attribute values and product template generated by the product.template.attribute.line""" _name = "product.template.attribute.value" _order = 'product_attribute_value_id, id' _description = 'Product Attribute Value' name = fields.Char('Value', related="product_attribute_value_id.name") product_attribute_value_id = fields.Many2one( 'product.attribute.value', string='Attribute Value', required=True, ondelete='cascade', index=True) product_tmpl_id = fields.Many2one( 'product.template', string='Product Template', required=True, ondelete='cascade', index=True) attribute_id = fields.Many2one( 'product.attribute', string='Attribute', related="product_attribute_value_id.attribute_id") sequence = fields.Integer('Sequence', related="product_attribute_value_id.sequence") price_extra = fields.Float( string='Attribute Price Extra', default=0.0, digits=dp.get_precision('Product Price'), help="""Price Extra: Extra price for the variant with this attribute value on sale price. eg. 200 price extra, 1000 + 200 = 1200.""") exclude_for = fields.One2many( 'product.template.attribute.exclusion', 'product_template_attribute_value_id', string="Exclude for", relation="product_template_attribute_exclusion", help="""Make this attribute value not compatible with other values of the product or some attribute values of optional and accessory products.""") @api.multi def name_get(self): if not self._context.get('show_attribute', True): # TDE FIXME: not used return super(ProductTemplateAttributeValue, self).name_get() return [(value.id, "%s: %s" % (value.attribute_id.name, value.name)) for value in self] @api.multi def _without_no_variant_attributes(self): return self.filtered(lambda ptav: ptav.attribute_id.create_variant != 'no_variant')
class AccountRegisterPayments(models.TransientModel): _inherit = "account.register.payments" check_amount_in_words = fields.Char(string="Amount in Words") check_manual_sequencing = fields.Boolean( related='journal_id.check_manual_sequencing', readonly=1) # Note: a check_number == 0 means that it will be attributed when the check is printed check_number = fields.Integer( string="Check Number", readonly=True, copy=False, default=0, help= "Number of the check corresponding to this payment. If your pre-printed check are not already numbered, " "you can manage the numbering in the journal configuration page.") @api.onchange('journal_id') def _onchange_journal_id(self): if hasattr(super(AccountRegisterPayments, self), '_onchange_journal_id'): super(AccountRegisterPayments, self)._onchange_journal_id() if self.journal_id.check_manual_sequencing: self.check_number = self.journal_id.check_sequence_id.number_next_actual @api.onchange('amount') def _onchange_amount(self): if hasattr(super(AccountRegisterPayments, self), '_onchange_amount'): super(AccountRegisterPayments, self)._onchange_amount() self.check_amount_in_words = self.currency_id.amount_to_text( self.amount) if self.currency_id else False def _prepare_payment_vals(self, invoices): res = super(AccountRegisterPayments, self)._prepare_payment_vals(invoices) if self.payment_method_id == self.env.ref( 'account_check_printing.account_payment_method_check'): res.update({ 'check_amount_in_words': self.currency_id.amount_to_text(res['amount']) if self.multi else self.check_amount_in_words, }) return res
class Many2ManyChild(models.Model): _name = 'export.many2many.other' _description = 'Export Many to Many Other' # FIXME: orm.py:1161, fix to name_get on m2o field _rec_name = 'value' str = fields.Char() value = fields.Integer() @api.multi def name_get(self): return [(record.id, "%s:%s" % (self._name, record.value)) for record in self] @api.model def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): if isinstance(name, pycompat.string_types) and name.split(':')[0] == self._name: record_ids = self._search([('value', operator, int(name.split(':')[1]))], access_rights_uid=name_get_uid) return self.browse(record_ids).name_get() else: return []
class M2MChange(models.Model): _name = 'test_testing_utilities.e' _description = 'Testing Utilities E' m2m = fields.Many2many('test_testing_utilities.sub2') count = fields.Integer(compute='_m2m_count', inverse='_set_count') @api.depends('m2m') def _m2m_count(self): for r in self: r.count = len(r.m2m) def _set_count(self): for r in self: r.write({ 'm2m': [(0, False, { 'name': str(n) }) for n, v in zip_longest(range(r.count), r.m2m or []) if v is None] })