from odoo import fields, models,api,_
from odoo.exceptions import UserError, ValidationError, Warning
from datetime import datetime,date
import os,secrets
import decimal
import base64
import logging
import json
_logger = logging.getLogger(__name__)

code_journal='IN'
date_compta=fields.datetime.now()
total_debit=total_credit=0
no_mvt=1


class AccountingFileWizard(models.TransientModel):
    _name = 'accounting.file.wizard'
    _description = 'accounting file wizard'

    start_date=fields.Datetime('start date',required=True,default=lambda self: self._compute_start_date())
    end_date=fields.Datetime('end date',required=True,default=lambda self: self._compute_end_date())

    debug_mode=fields.Boolean('debug mode',default=True)
    export_donation_lines=fields.Boolean('export donation lines',default=True)
    export_membership_lines=fields.Boolean('export_membership_lines',default=True)
    export_event_lines=fields.Boolean('export_event_lines',default=True)
    export_booking_event_lines=fields.Boolean('export_booking_event_lines',default=True)
    export_out_refund_lines=fields.Boolean('export_out_refund_lines',default=True)
    export_end_of_stay_lines=fields.Boolean('export_end_of_stay_lines',default=True)
    

    def _compute_end_date(self):

        date_today=fields.Date.context_today(self)
        return date_today

    def _compute_start_date(self):

        date_today=fields.Date.context_today(self)
        return datetime(date_today.year,date_today.month,1)
        # date_max=[]
        # #recherche de la date d'export d'écriture la plus récente
        # query="select max(date_compta) as date_compta from donation_donation"
        # self._cr.execute(query)
        # query_res = self._cr.dictfetchall()
        # for r in query_res:
        #     d_date_compta=r['date_compta']
        #     if d_date_compta: date_max.append(d_date_compta)
        
        # query="select max(date_compta) as date_compta from kalachakra_membership"
        # self._cr.execute(query)
        # query_res = self._cr.dictfetchall()
        # for r in query_res:
        #     m_date_compta=r['date_compta']
        #     if m_date_compta: date_max.append(m_date_compta)
        
        # query="select max(date_compta) as date_compta from event_registration"
        # self._cr.execute(query)
        # query_res = self._cr.dictfetchall()
        # for r in query_res:
        #     e_date_compta=r['date_compta']
        #     if e_date_compta: date_max.append(e_date_compta)
        
        
        # if date_max: return max(date_max)
        # else: return fields.Date.context_today(self)
        


    #accounting_date=fields.Date(string='Accounting date',required=True)

    def action_create_accounting_file(self):
        global total_debit
        global total_credit
        total_debit=0
        total_credit=0

        
        #     donation=self.env['donation.donation'].search([])
        #     for d in donation:
        #         d.date_compta=False
        #     membership=self.env['kalachakra.membership'].search([])
        #     for m in membership:
        #         m.date_compta=False
        #     reg=self.env['event.registration'].search([])
        #     for r in reg:
        #         r.date_compta=False
        #         r.date_compta_down_payment=False
        #     invoices=self.env['account.move'].search([])
        #     for i in invoices:
        #         i.date_compta_out_refund=False
        #         i.date_compta=False
        # return True

        tmstp=secrets.token_hex(16)
        filename='/tmp/accounting_file_'+tmstp+'.csv'
        f = open(filename, "a",encoding="cp1252")

        
        #N° mouvement 1-5
        #Code du journal "IN" 6-7
        #Date 8-17 (10 cars) ex:01/04/2022
        #N° de compte 18-23 (6 cars)
        #Libellé 24- (12+ 13 cars) 12:Initial prénom+nom 13:lib evt exemple :E Meurinne Besoins cent 
        #Débit ex: 200,00
        #Crédit ex : 200,00
        #N° de pièce: ref transaction , ex: txD-457
        
        
        fic_line='"N° mouvement;Code du journal;Date;N° de compte;Libellé;Débit;Crédit;N° de pièce'+'"'+"\n"
        #fic_line=fic_line.encode(encoding="cp1252",errors='ignore')
        f.write(fic_line)
        
        
        if self.export_donation_lines:self.donation_lines(f)
        if self.export_membership_lines:self.membership_lines(f)
        if self.export_event_lines:self.event_lines(f)
        if self.export_booking_event_lines:self.booking_event_lines(f)
        if self.export_out_refund_lines:self.out_refund_lines(f)
        if self.export_end_of_stay_lines:self.end_of_stay_lines(f)
        fic_line="TOTAL_DEBIT="+str(total_debit)+ " TOTAL CREDIT="+str(total_credit)
        #fic_line=fic_line.encode(encoding="cp1252",errors='ignore')
        f.write(fic_line)
        
        f.close
        f = open(filename, "rb")
        data = f.read()
        #raise UserError('gg'+f.read())
        vals={} 
        vals['accounting_file']=base64.encodebytes(data)
        vals['document_fname']='export_comptable.csv'
        vals['exported_date']=fields.Date.context_today(self)
        vals['start_date']=self.start_date
        vals['end_date']=self.end_date
        res=self.env['accounting.file'].create(vals)
        f.close
        os.unlink(filename)

        #display account deposit
        return {
        'name': 'Account deposit form',
        'view_type': 'form',
        'view_mode': 'form',
        'res_model': 'accounting.file',
        'res_id': int(res.id),
        'type': 'ir.actions.act_window',
        'target': 'current'
        }


    def _accounting_line(self,no_mvt,date_line,account_number,lib,debit,credit,lib_piece):
                         
        
        str_line='"'+str(no_mvt)+';'+'IN'+';'+str(date_line)+';'+str(account_number)+';'+str(lib)+';'+str(debit)+';'+str(credit)+';'+str(lib_piece)+'"'+'\n'
        return str_line
    
    def donation_lines(self,f):
        global total_debit
        global total_credit
        global no_mvt
        #écritures pour les dons validés (donc payés), non déjà exportés
        donation=self.env['donation.donation'].search([('date_compta','=',False),('state','=','done')])
        #raise UserError(donation)
        for d in donation:
            date_payment=d.donation_date
            #recherche de la date de paiement du don
            trans=self.env['payment.transaction'].search([('donation_ids','in',d.id),('state','=','done')],limit=1)
            if trans : date_payment=trans.date.date()

            #if datetime(d.donation_date.year, d.donation_date.month, d.donation_date.day)<self.start_date:continue
            if date_payment<self.start_date.date():continue
            if date_payment>self.end_date.date():continue
            date_payment=self._date_format(date_payment)
            #on ne prend pas en compte les dons liés à une retraite
            #car traité avec les retraites
            if d.invoice_id: continue
            if not self.debug_mode: d.date_compta=date_compta
            #if not d.payment_mode_id: raise UserError(_("no payment mode found for donation %r ",donation.number))
            #if not d.payment_mode_id.fixed_journal_id: raise UserError(_("no account found for payment mode  %r",d.payment_mode_id.name))
            account_debit_number=self._file_format(str(d.payment_mode_id.fixed_journal_id.default_account_id.code),6)
            if d.transaction_id.acquirer_id.name=='Paypal':
                
                account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','Paypal')]).fixed_journal_id.default_account_id.code),6)
            
            firstname=d.partner_id.firstname
            name=d.partner_id.name
            if not name : name='N/A'
            if not firstname: firstname=' '
            lib1=firstname[0]+' '+name
            
            lib1=self._file_format(lib1,12)
            #lib1=lib1[11]
            
            date_line=self._date_format(d.donation_date)
            if trans : date_line=self._date_format(str(trans.date.year)+'-'+str(trans.date.month)+'-'+str(trans.date.day))
            #recherche de la transaction
            lib_piece=self._file_format(d.number,20)
            pt=self.env['payment.transaction'].search([('donation_ids','in',d.id)],limit=1)
            if pt: lib_piece=pt.reference
            
            for line in d.line_ids:
                affectation=line.product_id.name
                amount=line.amount
                #if not line.product_id.property_account_income_id: raise UserError(_("no credit account found for product  %r",line.product_id.name))
                account_credit_number=self._file_format(line.product_id.property_account_income_id.code,6)
                
                break
            #credit line
            lib2=self._file_format(affectation,13)
            lib=lib1+' '+lib2
            debit=''
            credit=str(amount)
            total_credit+=amount
            account_number=account_credit_number
            
            fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
            f.write(fic_line)
            no_mvt+=1
            #debit line
            debit=str(amount)
            credit=''
            account_number=account_debit_number
            fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
            f.write(fic_line)
            total_debit+=amount
            no_mvt+=1
        return no_mvt
    def membership_lines(self,f):
        global total_debit
        global total_credit
        global no_mvt
        #écritures pour les ADHESIONS réglées non déjà exportés
        membership=self.env['kalachakra.membership'].search([('date_compta','=',False),('state','=','done')])
        for m in membership:
           
            if datetime(m.start_date.year,m.start_date.month,m.start_date.day)<self.start_date:continue
            if datetime(m.start_date.year,m.start_date.month,m.start_date.day)>self.end_date:continue
            if not self.debug_mode: m.date_compta=date_compta
            #on ne prend pas en compte les adhésions liés à une retraite
            #car traité avec les retraites
            if m.balance_invoice_id: continue
            if m.invoice_id:
                reg=self.env['event.registration'].search([('invoice_id','=',int(m.invoice_id))])
                if reg:
                    if reg.event_id.booking_event:continue
            #si adhésion pas liée à une facture ou à une transaction, on ne prend pas
            if not m.invoice_id and not m.transaction_id : continue
            
            if m.transaction_id.acquirer_id.name=='Paypal':
                
                account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','Paypal')]).fixed_journal_id.default_account_id.code),6)
            else:
                account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','CB')]).fixed_journal_id.default_account_id.code),6)

            
            if m.invoice_id:
                #if not m.invoice_id.payment_mode_id.fixed_journal_id: raise UserError(_("no account found for payment mode  %r",d.payment_mode_id.name))
                #account_debit_number=self._file_format(str(m.invoice_id.payment_mode_id.fixed_journal_id.default_account_id.code),6)
                account_debit_number=self._payment_account_number(m.invoice_id)           
            firstname=m.partner_id.firstname
            name=m.partner_id.name
            if not name : name='N/A'
            if not firstname: firstname=' '
            lib1=firstname[0]+' '+name
            lib1=self._file_format(lib1,12)
            date_line=self._date_format(m.start_date)
            amount=m.amount
            #if not m.product_id.property_account_income_id: raise UserError(_("no credit account found for product %r",m.product_id.name))  
            account_credit_number=self._file_format('756100',6)
            affectation=m.product_id.name

            #lib pièce
            if m.transaction_id:
                lib_piece=self._file_format(m.transaction_id.reference,20)
            elif m.invoice_id:
                lib_piece=self._file_format(m.invoice_id.name,20)
            else:
                lib_piece=self._file_format(m.partner_id.name,20)

            #credit line
            lib2=self._file_format(affectation,13)
            lib=lib1+' '+lib2
            debit=''
            credit=str(amount)
            account_number=account_credit_number
            fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
            f.write(fic_line)
            no_mvt+=1
            total_credit+=amount
            #debit line
            debit=str(amount)
            credit=''
            account_number=account_debit_number
            fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
            f.write(fic_line)
            no_mvt+=1
            total_debit+=amount
        return no_mvt
    def event_lines(self,f):
        global total_debit
        global total_credit
        global no_mvt
        
        #écritures pour les inscriptions évts hors RETRAITES avec facture payée non déjà exportés
        
        
        registration=self.env['event.registration'].search([('date_compta','=',False),('payment_status','=','paid'),('event_id.booking_event','=',False),('event_id.individual_booking_event','=',False)])
        
        if registration:
            for reg in registration:
               
                
                if reg.date_payment and reg.date_payment<self.start_date.date(): continue
                if reg.date_payment and reg.date_payment>self.end_date.date(): continue
                membership_credit_line=False
                membership_amount=0
                if not self.debug_mode: reg.date_compta=date_compta
                #if not reg.invoice_id.payment_mode_id.fixed_journal_id: raise UserError(_("no account found for payment mode %r",reg.invoice_id.payment_mode_id))
                #account_debit_number=self._file_format(str(reg.invoice_id.payment_mode_id.fixed_journal_id.default_account_id.code),6)
                account_debit_number=self._payment_account_number(reg.invoice_id)
                if not reg.invoice_id.payment_mode_id :
                    account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','Espèces')]).fixed_journal_id.default_account_id.code),6)
                trans=self.env['payment.transaction'].search([('invoice_ids','in',reg.invoice_id.id),('state','=','done')],limit=1)
                if trans:
                    if trans.acquirer_id.name=='Paypal':
                
                        account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','Paypal')]).fixed_journal_id.default_account_id.code),6)

                firstname=reg.partner_id.firstname
                name=reg.partner_id.name
                if not name : name='N/A'
                if not firstname: firstname=' '
                lib1=firstname[0]+' '+name
                lib1=self._file_format(lib1,12)
                #date du paiement
                
                #if self._payment_date_date(reg.invoice_id):continue
                date_line=self._date_format(reg.date_payment)
                
                if reg.invoice_id.amount_total==0: continue
                if reg.invoice_id.payment_state!='paid': continue
                amount=reg.invoice_id.amount_total
                #if not reg.event_id.participation_product_id: raise UserError(_("no credit account found for product %r",reg.event_id.participation_product_id.name))
                account_credit_number=self._file_format(reg.event_id.participation_product_id.property_account_income_id.code,6)
                if not reg.event_id.participation_product_id.property_account_income_id.code:
                    account_credit_number=self._file_format('754700',6)
                affectation=reg.event_id.participation_product_id.name

                #recherche d'une l'adhésion
                membership_credit_line=False
                membership=self.env['kalachakra.membership'].search([('invoice_id','=',int(reg.invoice_id))])
                if membership:
                    membership_credit_line=True
                    membership_amount=membership.amount

                #si facture liée à une transaction:
                trans=self.env['payment.transaction'].search([('invoice_ids','in',reg.invoice_id.id),('state','=','done')],limit=1)
                if trans:
                    lib_piece=self._file_format(trans.reference,20)
                else:
                    lib_piece=self._file_format(reg.invoice_id.name,20)
                #credit line
                lib2=self._file_format(affectation,13)
                lib=lib1+' '+lib2
                debit=''
                credit=str(amount-membership_amount)
                account_number=account_credit_number
                fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
                f.write(fic_line)
                no_mvt+=1
                total_credit+=amount
                #debit line
                debit=str(amount-membership_amount)
                credit=''
                account_number=account_debit_number
                fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
                f.write(fic_line)
                no_mvt+=1
                total_debit+=amount
        return no_mvt
    def end_of_stay_lines(self,f):
        global total_debit
        global total_credit
        global no_mvt

        registration=self.env['event.registration'].search([])
        
        for reg in registration:
            if not reg.end_of_stay_invoice_id:continue
            if reg.end_of_stay_invoice_id.date_compta_end_of_stay:continue
            if not reg.date_payment_end_of_stay:continue
            if reg.date_payment_end_of_stay and reg.date_payment_end_of_stay<self.start_date.date(): continue
            if reg.date_payment_end_of_stay and reg.date_payment_end_of_stay>self.end_date.date(): continue

            account_debit_number=self._file_format(str(reg.end_of_stay_invoice_id.payment_mode_id.fixed_journal_id.default_account_id.code),6)
            trans=self.env['payment.transaction'].search([('invoice_ids','in',reg.end_of_stay_invoice_id.id),('state','=','done')],limit=1)
            if trans and trans.acquirer_id.name=='Paypal':
        
                account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','Paypal')]).fixed_journal_id.default_account_id.code),6)
            
            if trans and trans.acquirer_id.name=='Paiement par carte bancaire':
        
                account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','CB')]).fixed_journal_id.default_account_id.code),6)

            account_credit_number=self._file_format('170000',6)
        
            firstname=reg.partner_id.firstname
            name=reg.partner_id.name
            if not name : name='N/A'
            if not firstname: firstname=' '
            lib1=firstname[0]+' '+name
            lib1=self._file_format(lib1,12)
            lib2=self._file_format(reg.event_id.booking_product_id.name,13)
            lib=lib1+' '+lib2

            #recherche de l'adhésion
            membership_credit_line=False
            membership=self.env['kalachakra.membership'].search([('invoice_id','=',int(reg.end_of_stay_invoice_id.id))])
            membership_amount=0
            if membership:
                membership_credit_line=True
                membership_amount=membership.amount
            
            #recherche de dons
            donation_credit_line=False
            donation_amount=0
            donations=donation_booking=self.env['donation.donation'].search([('invoice_id','=',int(reg.end_of_stay_invoice_id.id))])
            if donations:
                donation_credit_line=True
                for d in donations:
                    donation_amount+=d.amount_total
            date_line=self._payment_date(reg.end_of_stay_invoice_id)
            
            #écriture de débit
            if not self.debug_mode: reg.date_compta_end_of_stay=date_compta
            
            amount=reg.end_of_stay_invoice_id.amount_total
            if amount==0: continue
            debit=str(amount)
            credit=''
            lib_piece=self._file_format(reg.end_of_stay_invoice_id.name,20)
            account_number=account_debit_number
            fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
            f.write(fic_line)
            no_mvt+=1
            total_debit+=amount
            #écriture de crédit
            debit=''
            credit=str(amount-membership_amount-donation_amount)
            account_number=account_credit_number
            fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
            f.write(fic_line)
            no_mvt+=1
            total_credit+=amount
            
            if membership_credit_line:
                    debit=''
                    credit=str(membership_amount)
                    account_number=self._file_format('756100',6)
                    fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
                    f.write(fic_line)
                    no_mvt=no_mvt+1
                    total_credit+=membership_amount
                
            if donation_credit_line:
                for d in donations :
                    debit=''
                    amount=d.amount_total
                    credit=str(amount)
                    account_number=account_credit_number
                    fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
                    f.write(fic_line)
                    no_mvt=no_mvt+1
                    total_credit+=amount

    def booking_event_lines(self,f):
        global total_debit
        global total_credit
        global no_mvt
        #écritures pour les inscription aux RETRAITES avec facture acomptes payés + factures soldes payés non déjà exporté
        registration=self.env['event.registration'].search([])
        membership_amount=0
        donation_amount=0
        membership_credit_line=False
        donation_credit_line=False
        
        #if not reg.event_id.participation_product_id.property_account_income_id: raise UserError(_("no credit account found for product %r",reg.event_id.participation_product_id.name))
        account_credit_number=self._file_format('170000',6)
        
        for reg in registration:
            if reg.event_id.booking_event:
                    
                #si pas de facture d'acompte et facture payée:
                if reg.invoice_id.amount_total>0 and reg.invoice_id.payment_state=='paid' and reg.date_compta==False :
                    
                    if reg.date_payment and reg.date_payment<self.start_date.date(): continue
                    if reg.date_payment and reg.date_payment>self.end_date.date(): continue
                    self.booking_invoice_lines(f,reg)
                    
                #si facture d'acompte payée et pas encore exporté
                if reg.down_payment_invoice_id.payment_state=='paid' and not reg.date_compta_down_payment:
                    
                    if reg.date_payment_down_payment and reg.date_payment_down_payment>=self.start_date.date():
                        self.booking_down_payment_invoice_lines(f,reg)
                
                #si solde payée pas exporté :
                if reg.balance_invoice_id.payment_state=='paid' and not reg.date_compta:
                    
                    if reg.date_payment_balance and reg.date_payment_balance>=self.start_date.date():
                        self.booking_balance_invoice_lines(f,reg)

                


        _logger.error('TOTAL DEBIT '+str(total_debit)+' TOTAL CREDIT '+str(total_credit))
        
        return True

    def booking_balance_invoice_lines(self,f,reg) :
        global total_debit
        global total_credit
        global no_mvt

        membership_amount=0
        donation_amount=0
        membership_credit_line=False
        donation_credit_line=False
        
        #if not reg.event_id.participation_product_id.property_account_income_id: raise UserError(_("no credit account found for product %r",reg.event_id.participation_product_id.name))
        account_credit_number=self._file_format('170000',6)
        
        firstname=reg.partner_id.firstname
        name=reg.partner_id.name
        if not name : name='N/A'
        if not firstname: firstname=' '
        lib1=firstname[0]+' '+name
        lib1=self._file_format(lib1,12)
        lib2=self._file_format(reg.event_id.booking_product_id.name,13)
        lib=lib1+' '+lib2

        if not self.debug_mode: reg.date_compta=date_compta
        down_payment=False
        balance_payment=True
        #if not reg.balance_invoice_id.payment_mode_id.fixed_journal_id: raise UserError(_("no account found payment mode %r",reg.balance_invoice_id.payment_mode_id.name))
        #account_debit_number=self._file_format(str(reg.down_payment_invoice_id.payment_mode_id.fixed_journal_id.default_account_id.code),6)
        # trans=self.env['payment.transaction'].search([('invoice_ids','in',reg.down_payment_invoice_id.id),('state','=','done')],limit=1)
        # if trans and trans.acquirer_id.name=='Paypal': account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','Paypal')]).fixed_journal_id.default_account_id.code),6)
        # if trans and trans.acquirer_id.name=='Paiement par carte bancaire': account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','CB')]).fixed_journal_id.default_account_id.code),6)
        # if not trans:
        account_debit_number=''
        for p in reg.balance_invoice_id.payment_ids:
            account_debit_number=self._file_format(str(self.env['account.journal'].search([('id','=',int(p.journal_id))]).default_account_id.code),6)
            break

        date_line=self._payment_date(reg.balance_invoice_id)
        
        
        #recherche de l'adhésion
        membership_credit_line=False
        membership=self.env['kalachakra.membership'].search([('date_compta','=',False),('balance_invoice_id','=',int(reg.balance_invoice_id))])
        if membership:
            membership_credit_line=True
            membership_amount=membership.amount
        
        #recherche de dons
        donation_credit_line=False
        donations=donation_booking=self.env['donation.donation'].search([('date_compta','=',False),('invoice_id','=',int(reg.balance_invoice_id))])
        if donations:
            donation_credit_line=True
            for d in donations:
                donation_amount+=donations.amount_total
        trans=self.env['payment.transaction'].search([('state','=','done'),('invoice_ids','in',reg.balance_invoice_id.id)],limit=1)
        if trans:
            lib_piece=self._file_format(trans.reference,20)
        else:           
            lib_piece=self._file_format(reg.balance_invoice_id.name,20)
        
        amount=reg.balance_invoice_id.amount_total
        if amount==0: return False
        credit=''
        debit=str(amount)
        account_number=account_debit_number
        fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
        f.write(fic_line)
        no_mvt=no_mvt+1
        total_debit+=amount

        if not amount: amount=0
        amount=reg.balance_invoice_id.amount_total-membership_amount-donation_amount
        debit=''
        credit=str(amount)
        account_number=account_credit_number
        fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
        f.write(fic_line)
        no_mvt=no_mvt+1
        total_credit+=amount

        if membership_credit_line:
            debit=''
            credit=str(membership_amount)
            account_number=self._file_format('756100',6)
            fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
            f.write(fic_line)
            no_mvt=no_mvt+1
            total_credit+=membership_amount
        
        if donation_credit_line:
            for d in donations :
                debit=''
                amount=d.amount_total
                credit=str(amount)
                account_number=account_credit_number
                fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
                f.write(fic_line)
                no_mvt=no_mvt+1
                total_credit+=amount

        



    def booking_down_payment_invoice_lines(self,f,reg):
        global total_debit
        global total_credit
        global no_mvt

        membership_amount=0
        donation_amount=0
        membership_credit_line=False
        donation_credit_line=False
        
        #if not reg.event_id.participation_product_id.property_account_income_id: raise UserError(_("no credit account found for product %r",reg.event_id.participation_product_id.name))
        account_credit_number=self._file_format('170000',6)
        
        firstname=reg.partner_id.firstname
        name=reg.partner_id.name
        if not name : name='N/A'
        if not firstname: firstname=' '
        lib1=firstname[0]+' '+name
        lib1=self._file_format(lib1,12)
        lib2=self._file_format(reg.event_id.booking_product_id.name,13)
        lib=lib1+' '+lib2

        if not self.debug_mode: reg.date_compta_down_payment=date_compta
        down_payment=True
        balance_payment=False
        donation_credit_line=False
        membership_credit_line=False
        #if not reg.down_payment_invoice_id.payment_mode_id.fixed_journal_id: raise UserError(_("no account found payment mode %r",reg.down_payment_invoice_id.payment_mode_id.name))
        account_debit_number=self._file_format(str(reg.down_payment_invoice_id.payment_mode_id.fixed_journal_id.default_account_id.code),6)
        trans=self.env['payment.transaction'].search([('invoice_ids','in',reg.down_payment_invoice_id.id),('state','=','done')],limit=1)
        if trans and trans.acquirer_id.name=='Paypal': account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','Paypal')]).fixed_journal_id.default_account_id.code),6)
        if trans and trans.acquirer_id.name=='Paiement par carte bancaire': account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','CB')]).fixed_journal_id.default_account_id.code),6)
        amount=reg.down_payment_invoice_id.amount_total
        
        date_line=self._date_format(reg.date_payment_down_payment)
        
        trans=self.env['payment.transaction'].search([('state','=','done'),('invoice_ids','in',reg.down_payment_invoice_id.id)],limit=1)
        if trans:
            lib_piece=self._file_format(trans.reference,20)
        else:
         
            lib_piece=self._file_format(reg.down_payment_invoice_id.name,20)
        
        amount=reg.down_payment_invoice_id.amount_total

        if amount==0: return False
        credit=''
        debit=str(amount)
        account_number=account_debit_number
        fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
        f.write(fic_line)
        no_mvt=no_mvt+1
        total_debit+=amount


        #credit(s) line(s)
        #participation credit line
        if not amount: amount=0
        amount=reg.down_payment_invoice_id.amount_total
        debit=''
        credit=str(amount)
        account_number=account_credit_number
        fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
        f.write(fic_line)
        no_mvt=no_mvt+1
        total_credit+=amount






    def booking_invoice_lines(self,f,reg):

        global total_debit
        global total_credit
        global no_mvt

        #_logger.error('acompte:'+str(reg.down_payment_invoice_id.payment_state)+' solde :'+str(reg.balance_invoice_id.payment_state)+' date_compta'+str(reg.date_compta)+' date_compta_down_payment:'+str(reg.date_compta_down_payment))
        membership_amount=0
        donation_amount=0
        membership_credit_line=False
        donation_credit_line=False
        
        #if not reg.event_id.participation_product_id.property_account_income_id: raise UserError(_("no credit account found for product %r",reg.event_id.participation_product_id.name))
        account_credit_number=self._file_format('170000',6)
        
        firstname=reg.partner_id.firstname
        name=reg.partner_id.name
        if not name : name='N/A'
        if not firstname: firstname=' '
        lib1=firstname[0]+' '+name
        lib1=self._file_format(lib1,12)
        lib2=self._file_format(reg.event_id.booking_product_id.name,13)
        lib=lib1+' '+lib2

        if not self.debug_mode: reg.date_compta=date_compta
        case_line=1
        down_payment=False
        balance_payment=False
        #if not reg.invoice_id.payment_mode_id.fixed_journal_id: raise UserError(_("no account found payment mode %r",reg.invoice_id.payment_mode_id.name))
        account_debit_number=self._file_format(str(reg.invoice_id.payment_mode_id.fixed_journal_id.default_account_id.code),6)
        trans=self.env['payment.transaction'].search([('invoice_ids','in',reg.invoice_id.id),('state','=','done')],limit=1)
        if trans and trans.acquirer_id.name=='Paypal':
    
            account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','Paypal')]).fixed_journal_id.default_account_id.code),6)
        
        if trans and trans.acquirer_id.name=='Paiement par carte bancaire':
    
            account_debit_number=self._file_format(str(self.env['account.payment.mode'].search([('name','=','CB')]).fixed_journal_id.default_account_id.code),6)

        #recherche de l'adhésion
        membership_credit_line=False
        membership=self.env['kalachakra.membership'].search([('invoice_id','=',int(reg.invoice_id))])
        if membership:
            membership_credit_line=True
            membership_amount=membership.amount
        
        #recherche de dons
        donation_credit_line=False
        donations=donation_booking=self.env['donation.donation'].search([('invoice_id','=',int(reg.invoice_id))])
        if donations:
            donation_credit_line=True
            for d in donations:
                donation_amount+=d.amount_total
        
        
        date_line=self._date_format(reg.date_payment)
        
        trans=self.env['payment.transaction'].search([('state','=','done'),('invoice_ids','in',reg.invoice_id.id)],limit=1)
        if trans:
                    lib_piece=self._file_format(trans.reference,20)
        else:
            lib_piece=self._file_format(reg.invoice_id.name,20)
            
        
        
        #debit line
        amount=reg.invoice_id.amount_total
        
        if amount==0: return False
        credit=''
        debit=str(amount)
        account_number=account_debit_number
        fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
        f.write(fic_line)
        no_mvt=no_mvt+1
        total_debit+=amount


        #credit(s) line(s)
        #participation credit line
        if not amount: amount=0
        
        amount=amount-membership_amount-donation_amount
        debit=''
        credit=str(amount)
        account_number=account_credit_number
        fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
        f.write(fic_line)
        no_mvt=no_mvt+1
        total_credit+=amount
           
        if membership_credit_line:
            debit=''
            credit=str(membership_amount)
            account_number=self._file_format('756100',6)
            fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
            f.write(fic_line)
            no_mvt=no_mvt+1
            total_credit+=membership_amount
        
        if donation_credit_line:
            for d in donations :
                debit=''
                amount=d.amount_total
                credit=str(amount)
                account_number=account_credit_number
                fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
                f.write(fic_line)
                no_mvt=no_mvt+1
                total_credit+=amount


    def out_refund_lines(self,f):
        global total_debit
        global total_credit
        global no_mvt
    #écritures pour les avoirs pas encore utilisés ou payés mais jamais passé en compta
        out_refund_invoices=self.env['account.move'].search([('move_type','=','out_refund'),('state','=','posted'),('payment_state','=','not_paid'),('date_compta','=',False),('date_compta_out_refund','=',False)])
        for invoice in out_refund_invoices:
            if invoice.invoice_date<self.start_date.date(): continue
            if invoice.invoice_date>self.end_date.date(): continue
            if not self.debug_mode: invoice.date_compta_out_refund=date_compta
            firstname=invoice.partner_id.firstname
            name=invoice.partner_id.name
            if not name : name='N/A'
            if not firstname: firstname=' '
            lib1=firstname[0]+' '+name
            lib1=self._file_format(lib1,12)
            
            lines=self.env['account.move.line'].search([('move_id','=',int(invoice.id))],limit=1)
            if lines:
                
                lib2=self._file_format(lines.name,13)
            else:
                lib2=''
            lib=lib1+' '+lib2
            
            lib_piece=self._file_format(invoice.name,20)
            #écriture de débit
            amount=invoice.amount_total
            account_debit_number='170000'
            date_line=self._date_format(invoice.invoice_date)
            if amount==0: continue
            debit=str(amount)
            credit=''
            account_number=account_debit_number
            fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
            f.write(fic_line)
            no_mvt+=1
            total_debit+=amount
            #écriture de crédit
            debit=''
            credit=str(amount)
            account_credit_number='170000'

            account_number=account_credit_number
            fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
            f.write(fic_line)
            no_mvt+=1
            total_credit+=amount


        #écritures pour les avoirs qui ont été utilisés
        #écriture Débit 411000 – Crédit 170000
        out_refund_invoices=self.env['account.move'].search([('move_type','=','out_refund'),('payment_state','=','paid'),('date_compta','=',False)])
        
        for invoice in out_refund_invoices:
                #_logger.error(invoice.id)
                if not self.debug_mode: invoice.date_compta=date_compta
                firstname=invoice.partner_id.firstname
                name=invoice.partner_id.name
                #_logger.error(name)
                if not name : name='N/A'
                if not firstname: firstname=' '
                lib1=firstname[0]+' '+name
                lib1=self._file_format(lib1,12)
                
                lib2=''
                reg=self.env['event.registration'].search(['|',('invoice_id','=',int(invoice.out_invoice_id)),('balance_invoice_id','=',int(invoice.out_invoice_id))])
                
                if reg:    
                    lib2=self._file_format(reg.event_id.name,13)
                else:
                    lib2=self._file_format(invoice.payment_reference,13)

            
                lib=lib1+' '+lib2
                if reg:
                    lib_piece=self._file_format(invoice.out_invoice_id.name,20)
                else :
                    lib_piece=self._file_format(invoice.name,20)
                    
                
                #écriture de débit
                amount=invoice.amount_total              
                account_debit_number='170000'
              
                #date du paiement
                #_logger.error(self._payment_date_ok(invoice.out_invoice_id))
                if not self._payment_date_ok(invoice):continue
                date_line=self._payment_date(invoice)
                

                if amount==0: continue
                debit=str(amount)
                credit=''
                account_number=account_debit_number
                fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
                f.write(fic_line)
                no_mvt+=1
                total_debit+=amount
                #écriture de crédit
                debit=''
                credit=str(amount)
                if invoice.out_invoice_id:
                    account_credit_number='170000'
                else:
                    account_credit_number= self._payment_account_number(invoice)
                account_number=account_credit_number
                fic_line=self._accounting_line(no_mvt,date_line,account_number,lib,debit,credit,lib_piece)
                f.write(fic_line)
                no_mvt+=1
                total_credit+=amount

    


    def _file_format(self,data,nbcars):
        if data:
            if len(data)>nbcars:
                return data[0:nbcars]
            else:
                return data
        else:
            return ''

    def _payment_(self,move_id):
        if move_id.invoice_payments_widget:
            payment_info=json.loads(move_id.invoice_payments_widget)
            if payment_info:
                if datetime.strptime(payment_info['content'][0]['date'],'%Y-%m-%d')>self.start_date:
                    return False
            
            else:
                return True
        else:return True

    def _payment_date_ok(self,move):
        if move.invoice_payments_widget:
            payment_info=json.loads(move.invoice_payments_widget)
            
            if payment_info:
                #_logger.error(payment_info['content'][0]['date'])
                if datetime.strptime(payment_info['content'][0]['date'],'%Y-%m-%d')>=self.start_date:
                    return True
            
            else:
                return False
        else:
            return False

    def _payment_date(self,move_id):
        if move_id.invoice_payments_widget:
            payment_info=json.loads(move_id.invoice_payments_widget)
            if payment_info:
                return self._date_format(payment_info['content'][0]['date'])
            #   
            
            else:
                return 'False'
        else:return 'False'
    
    def _payment_account_number(self,move_id):
        if move_id.invoice_payments_widget:
            payment_info=json.loads(move_id.invoice_payments_widget)
            
        
            if payment_info:

                account_payment_id=payment_info['content'][0]['account_payment_id']
                
                #payment_mode_id.fixed_journal_id.default_account_id.code
                account_number=self.env['account.payment'].search([('id','=',int(account_payment_id))]).journal_id.default_account_id.code
                
                return account_number
            
            else:
                return ''
        else:return ''

    def _date_format(self,data):
        #_logger.error('date='+str(data))
        if data:
            r=str(data).split('-')
            if len(r[2])==1:r[2]='0'+r[2]
            if len(r[1])==1:r[1]='0'+r[1]
            
            return r[2]+'/'+r[1]+'/'+r[0]
        else:
            return 'False' 

