from odoo import models, fields, api from dateutil.relativedelta import relativedelta from datetime import date,datetime,timedelta import logging _logger = logging.getLogger(__name__) class kalachakra_membership(models.Model): _name = 'kalachakra.membership' _description = 'manage membership' partner_id = fields.Many2one( 'res.partner', string='partner', required=True, index=True, track_visibility='onchange', ondelete='restrict' ) email=fields.Char(related='partner_id.email') firstname=fields.Char(string='firstname', related='partner_id.firstname',translate=True) def _default_product_id(self): membership_product=self.env['product.product'].sudo().search([('membership_product','=',True)],limit=1) if not membership_product: raise UserError(_('No membership product, please add one')) return membership_product.id product_id=fields.Many2one('product.product',required=True,string='membership product',default=_default_product_id,domain="[('membership_product','=',True)]") start_date=fields.Date('start date',required=True,default=lambda self: fields.Date.today()) invoice_id=fields.Many2one('account.move','invoice') balance_invoice_id=fields.Many2one('account.move','balance invoice') transaction_id=fields.Many2one('payment.transaction','payment transaction') payment_state=fields.Selection(string='payment_state',selection=[('paid', 'paid'), ('not paid', 'not paid')]) payment_mode_id = fields.Many2one( "account.payment.mode", string="Payment Mode", #domain="[('company_id', '=', company_id)]", copy=False, tracking=True ) # @api.depends('state', 'invoice_id') # def _compute_payment_state(self): # for rec in self: # rec.payment_state='not paid' # #adhesion via page d'ahésion # if rec.state=='done':rec.payment_state='paid' # if rec.state=='draft':rec.payment_state='not paid' # #adhésion via isncription à l'événement # if rec.invoice_id: # if rec.invoice_id.payment_state=='paid': # #raise Warning(rec.invoice_id.payment_state) # rec.payment_state='paid' # rec.state='done' # else:rec.payment_state='not paid' def _default_end_date(self): end_date=datetime.now()+relativedelta(years=1) return end_date end_date=fields.Date('end date',default=_default_end_date) alert_mail_date=fields.Date('alert mail date') state=fields.Selection(string='state',selection=[('draft', 'draft'), ('done', 'done')],default='draft',compute='_compute_membership_state',inverse='_inverse_membership_state', store=True) currency_id = fields.Many2one( "res.currency", string="Currency", required=True, tracking=True, ondelete="restrict", default=lambda self: self.env.company.currency_id, ) amount = fields.Monetary( string="Amount", currency_field="currency_id", tracking=True, ) date_compta=fields.Datetime('date import',default=False) @api.depends('invoice_id.payment_state','balance_invoice_id.payment_state','transaction_id.state') def _compute_membership_state(self): for m in self: if m.invoice_id and not m.balance_invoice_id: if m.invoice_id.payment_state=='paid': m.payment_state='paid' m.state='done' else: m.payment_state='not paid' m.state='draft' if m.balance_invoice_id: if m.balance_invoice_id.payment_state=='paid': m.payment_state='paid' m.state='done' else: m.payment_state='not paid' m.state='draft' if m.transaction_id: if m.transaction_id.state=='done': if m.state!='done': m.payment_state='paid' m.state='done' m.email_confirmation() m.update_membership() def _inverse_membership_state(self): for m in self: m.update_membership() @api.onchange('product_id') def onchange_product_id(self): if self.product_id: self.amount = self.product_id.list_price @api.onchange('product_id') def onchange_product_id(self): if self.product_id: self.amount = self.product_id.list_price def _get_payment_type(self, tokenize=False): self.ensure_one() return 'form_save' if tokenize else 'form' def _create_payment_transaction(self, vals): '''Similar to self.env['payment.transaction'].create(vals) but the values are filled with the current membership fields (e.g. the partner or the currency). :param vals: The values to create a new payment.transaction. :return: The newly created payment.transaction record. ''' # Ensure the currencies are the same. currency = self[0].currency_id # if any(so.pricelist_id.currency_id != currency for so in self): # raise ValidationError(_('A transaction can\'t be linked to sales orders having different currencies.')) # Ensure the partner are the same. partner = self[0].partner_id if any(so.partner_id != partner for so in self): raise ValidationError(_('A transaction can\'t be linked to sales orders having different partners.')) # Try to retrieve the acquirer. However, fallback to the token's acquirer. acquirer_id = vals.get('acquirer_id') acquirer = False payment_token_id = vals.get('payment_token_id') if payment_token_id: payment_token = self.env['payment.token'].sudo().browse(payment_token_id) # Check payment_token/acquirer matching or take the acquirer from token if acquirer_id: acquirer = self.env['payment.acquirer'].browse(acquirer_id) if payment_token and payment_token.acquirer_id != acquirer: raise ValidationError(_('Invalid token found! Token acquirer %s != %s') % ( payment_token.acquirer_id.name, acquirer.name)) if payment_token and payment_token.partner_id != partner: raise ValidationError(_('Invalid token found! Token partner %s != %s') % ( payment_token.partner.name, partner.name)) else: acquirer = payment_token.acquirer_id # Check an acquirer is there. if not acquirer_id and not acquirer: raise ValidationError(_('A payment acquirer is required to create a transaction.')) if not acquirer: acquirer = self.env['payment.acquirer'].browse(acquirer_id) # Check a journal is set on acquirer. if not acquirer.journal_id: raise ValidationError(_('A journal must be specified for the acquirer %s.', acquirer.name)) if not acquirer_id and acquirer: vals['acquirer_id'] = acquirer.id vals.update({ 'amount': sum(self.mapped('amount')), 'currency_id': currency.id, 'partner_id': partner.id, 'membership_ids': [(6, 0, self.ids)], 'type': self[0]._get_payment_type(vals.get('type')=='form_save'), }) transaction = self.env['payment.transaction'].create(vals) # Process directly if payment_token if transaction.payment_token_id: transaction.s2s_do_transaction() return transaction def update_membership(self): member=self.env['kalachakra.membership'].search([('partner_id','=', int(self.partner_id)),('end_date','>=',datetime.now()),('state','=','done')]) if member : self.partner_id.member_status='member' else :self.partner_id.member_status='not member' if self.partner_id.super_member: self.partner_id.member_status='super member' return True def bulk_update_membership(self): members=self.env['kalachakra.membership'].search([('end_date','<',datetime.now())]) for m in members: m.update_membership() def bulk_mail_end_membership(self): date_30=date.today()+relativedelta(months=1) members=self.env['kalachakra.membership'].search([('alert_mail_date','=',False),('end_date','<=',date_30),('end_date','>=',date.today())]) for m in members: m.alert_mail_date=date.today() mail_template = self.env['mail.template'].search([('name','=','end_membership')]) mail_template.email_to = self.partner_id.email #mail_template.send_mail(m.id,False) _logger.error(m.partner_id.name+' '+str(m.end_date)) def email_confirmation(self): mail_template = self.env['mail.template'].search([('name','=','confirmation_membership')]) mail_template.email_to = self.partner_id.email #mail_template.with_context({'end_date':self.end_date}).send_mail(self.id,False) mail_template.send_mail(self.id,False) return True def write(self,vals): res=super(kalachakra_membership, self).write(vals) self.update_membership() return True @api.model def create(self,vals): res=super(kalachakra_membership, self).create(vals) res.update_membership() return res def update_amount(self): members=self.env['kalachakra.membership'].search([]) for m in members: m.amount=45 m.state='done' def unlink(self): for rec in self: if rec.partner_id.super_member==False: rec.partner_id.member_status='not member' super(kalachakra_membership, rec).unlink() def bulk_updatepayment_state(self): memberships=self.env['kalachakra.membership'].search([]) for m in memberships: if m.invoice_id.payment_state=='paid': m.payment_state='paid' m.state='done' else: m.payment_state='not paid' m.state='draft' def bulk_remove_draft_membership(self): payment_transaction=self.env['payment.transaction'].search([('state','=','draft')]) if payment_transaction: for p in payment_transaction: if p.membership_ids: for m in p.membership_ids: #on ne supprime que les adhesion brouillons if m.state=='draft': today=date.today() b_date = date(m.create_date.year,m.create_date.month, m.create_date.day) #b_date = date(2022,8, 12) e_date = date(today.year,today.month, today.day) diff=e_date-b_date _logger.error("errK2-diff days="+str(diff.days)) if diff.days>15:self.env['kalachakra.membership'].search([('id','=',int(d.id))]).unlink() #on supprime également les adhésions brouillon de plus de 15 jours non lié à une retraite, donc sans facture members=self.env['kalachakra.membership'].search([('state','=','draft')]) if members: for m in members: if not m.invoice_id: today=date.today() b_date = date(m.create_date.year,m.create_date.month, m.create_date.day) e_date = date(today.year,today.month, today.day) diff=e_date-b_date _logger.error("errK2-diff days m="+str(diff.days)) if diff.days>15:self.env['kalachakra.membership'].search([('id','=',int(m.id))]).unlink()