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()) 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_start_date(self): 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 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'+';'+date_line+';'+account_number+';'+lib+';'+debit+';'+credit+';'+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)0 and reg.invoice_id.payment_state=='paid' and reg.date_compta==False : _logger.error('CC1') if reg.date_payment and reg.date_payment=self.start_date.date(): down_payment_already_in_accounting=False amount=reg.down_payment_invoice_id.amount_total+reg.balance_invoice_id.amount_total else: amount=reg.balance_invoice_id.amount_total if case_line==3:amount=reg.down_payment_invoice_id.amount_total if case_line==4:amount=reg.balance_invoice_id.amount_total if amount==0: continue 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 if case_line==1: 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 case_line==2: if not down_payment_already_in_accounting: 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 amount=float(reg.balance_invoice_id.amount_total)-float(membership_amount)-float(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 case_line==3: 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 if case_line==4: 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 _logger.error('TOTAL DEBIT '+str(total_debit)+' TOTAL CREDIT '+str(total_credit)) return True 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 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'