diff --git a/addons/account/account.py b/addons/account/account.py
index b0394d91901..883d4bc94f7 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -36,18 +36,6 @@ from tools.misc import currency
import mx.DateTime
from mx.DateTime import RelativeDateTime, now, DateTime, localtime
-class account_cash_discount(osv.osv):
- _name = "account.cash.discount"
- _description = "Cash Discount" #A reduction in the price of an item for sale allowed if payment is made within a stipulated period.
- _columns = {
- 'name': fields.char('Name', size=32),
- 'date': fields.date('Date', required=True),
- 'discount': fields.float('Discount (%)', digits=(16,2)),
- 'payment_id': fields.many2one('account.payment.term','Associated Payment Term'),
- }
-account_cash_discount()
-
-
class account_payment_term(osv.osv):
_name = "account.payment.term"
_description = "Payment Term"
@@ -56,7 +44,7 @@ class account_payment_term(osv.osv):
'active': fields.boolean('Active'),
'note': fields.text('Description'),
'line_ids': fields.one2many('account.payment.term.line', 'payment_id', 'Terms'),
- 'cash_discount_ids': fields.one2many('account.cash.discount', 'payment_id', 'Cash Discount'),
+ 'cash_discount_ids': fields.one2many('account.cash.discount', 'payment_id', 'Cash Discounts'),
}
_defaults = {
'active': lambda *a: 1,
@@ -105,6 +93,18 @@ class account_payment_term_line(osv.osv):
account_payment_term_line()
+class account_cash_discount(osv.osv):
+ _name = "account.cash.discount"
+ _description = "Cash Discount" #A reduction in the price if payment is made within a stipulated period.
+ _columns = {
+ 'name': fields.char('Name', size=32),
+ 'date': fields.date('Date', required=True),
+ 'discount': fields.float('Discount (%)',required=True),
+ 'payment_id': fields.many2one('account.payment.term','Associated Payment Term'),
+ }
+account_cash_discount()
+
+
class account_account_type(osv.osv):
_name = "account.account.type"
_description = "Account Type"
diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml
index b980cad2531..fed1961babd 100644
--- a/addons/account/account_invoice_view.xml
+++ b/addons/account/account_invoice_view.xml
@@ -137,7 +137,7 @@
-
+
diff --git a/addons/account/invoice.py b/addons/account/invoice.py
index dff8ca71c7d..0f943b6c995 100644
--- a/addons/account/invoice.py
+++ b/addons/account/invoice.py
@@ -507,7 +507,6 @@ class account_invoice_line(osv.osv):
if partner_id:
lang=self.pool.get('res.partner').read(cr, uid, [partner_id])[0]['lang']
context={'lang': lang}
- print context
res = self.pool.get('product.product').browse(cr, uid, product, context=context)
result = {'price_unit': res.list_price, 'invoice_line_tax_id':map(lambda x: x.id, res.taxes_id)}
if not name:
diff --git a/addons/l10n_ch/dta/__init__.py b/addons/l10n_ch/dta/__init__.py
index 95bad3db042..0e6297f151e 100755
--- a/addons/l10n_ch/dta/__init__.py
+++ b/addons/l10n_ch/dta/__init__.py
@@ -25,6 +25,6 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
-
+import dta
import dta_wizard
import invoice
diff --git a/addons/l10n_ch/dta/dta.py b/addons/l10n_ch/dta/dta.py
index 9f159f9051f..70889e34296 100644
--- a/addons/l10n_ch/dta/dta.py
+++ b/addons/l10n_ch/dta/dta.py
@@ -30,9 +30,30 @@ from osv import osv,fields
class account_dta(osv.osv):
_name = "account.dta"
- _description = "DTA Management"
+ _description = "DTA History"
_columns = {
'name': fields.binary('DTA file', readonly=True),
- 'note': fields.text('Error log'),
+ 'dta_line_ids': fields.one2many('account.dta.line','dta_id','DTA lines', readonly=True),
+ 'note': fields.text('Creation log', readonly=True),
+ 'bank': fields.many2one('res.partner.bank','Bank', readonly=True),
+ 'date': fields.date('Creation Date', readonly=True),
+ 'user_id': fields.many2one('res.users','User', readonly=True),
}
account_dta()
+
+class account_dta_line(osv.osv):
+ _name = "account.dta.line"
+ _description = "DTA line"
+ _columns = {
+ 'name' : fields.many2one('account.invoice','Invoice'),
+ 'partner_id' : fields.many2one('res.partner','Partner'),
+ 'due_date' : fields.date('Due date'),
+ 'cashdisc_date' : fields.date('Cash Discount date'),
+ 'amount_to_pay' : fields.float('Amount to pay'),
+ 'amount_invoice': fields.float('Invoiced Amount'),
+ 'amount_cashdisc': fields.float('Cash Discount Amount'),
+ 'dta_id': fields.many2one('account.dta','Associated DTA', required=True, ondelete='cascade'),
+ }
+account_dta_line()
+
+
diff --git a/addons/l10n_ch/dta/dta_demo.xml b/addons/l10n_ch/dta/dta_demo.xml
index 6af4284168c..e439ce84bef 100644
--- a/addons/l10n_ch/dta/dta_demo.xml
+++ b/addons/l10n_ch/dta/dta_demo.xml
@@ -22,6 +22,23 @@
+
+ V11 invoice
+ 54150
+ 1
+
+
+
+
+
+
+ Dummy product
+ 54150
+ 1
+
+
+
+
DTA invoice
2bpaid
@@ -41,23 +58,6 @@
-
- V11 invoice
- 54150
- 1
-
-
-
-
-
-
- Dummy product
- 54150
- 1
-
-
-
-
diff --git a/addons/l10n_ch/dta/dta_view.xml b/addons/l10n_ch/dta/dta_view.xml
index 0a47e1270f7..680060275e6 100644
--- a/addons/l10n_ch/dta/dta_view.xml
+++ b/addons/l10n_ch/dta/dta_view.xml
@@ -14,6 +14,7 @@
+
account.invoice.form
account.invoice
@@ -36,5 +37,65 @@
+
+
+
+ account.dta.line.tree
+ account.dta.line
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ account.dta.form
+ account.dta
+ form
+
+
+
+
+
+
+ account.dta.tree
+ account.dta
+ tree
+
+
+
+
+
+
+
+
+
+
+ account.dta
+ ir.actions.act_window
+ account.dta
+ form
+ tree,form
+
+
+
+
+
+
diff --git a/addons/l10n_ch/dta/dta_wizard.py b/addons/l10n_ch/dta/dta_wizard.py
index 602e5c35a8a..bde7be06104 100644
--- a/addons/l10n_ch/dta/dta_wizard.py
+++ b/addons/l10n_ch/dta/dta_wizard.py
@@ -56,12 +56,20 @@ ask_fields = {
'selection':_bank_get,
'required': True,
},
+}
-# 'city' : {
-# 'string':'Bank city',
-# 'type':'char',
-# },
-
+check_form = """
+
+"""
+check_fields = {
+ 'dta_line_ids' : {
+ 'string':'DTA lines',
+ 'type':'one2many',
+ 'relation':'account.dta.line',
+ },
}
@@ -81,13 +89,11 @@ res_fields = {
'required':True,
'readonly':True,
},
-
'note' : {'string':'Log','type':'text'}
-
}
-def _get_fields(self,cr,uid,data,context):
+def _get_bank(self,cr,uid,data,context):
pool = pooler.get_pool(cr.dbname)
user = pool.get('res.users').browse(cr,uid,[uid])[0]
company= user.company_id
@@ -95,8 +101,50 @@ def _get_fields(self,cr,uid,data,context):
if company.partner_id.bank_ids:
bank = company.partner_id.bank_ids[0]
return {'bank':bank.bank_name,'bank_iban':bank.iban or ''} # 'city':'',
+
return {}
+def _cleaning(self,cr,uid,data,context):
+ pool = pooler.get_pool(cr.dbname)
+ pool.get('account.dta').unlink(cr, uid, [ line[1] for line in data['form']['dta_line_ids'] ])
+ return {}
+
+
+def _get_dta_lines(self,cr,uid,data,context):
+ pool = pooler.get_pool(cr.dbname)
+ dta_line_obj = pool.get('account.dta.line')
+ lines=[]
+
+ id_dta= pool.get('account.dta').create(cr,uid,{
+ 'bank':data['form']['bank'],
+ 'date':time.strftime('%Y-%m-%d'),
+ 'user_id':uid,
+ })
+
+
+ for i in pool.get('account.invoice').browse(cr,uid,data['ids']):
+ if i.dta_state != '2bpaid' or i.state in ['draft','cancel','paid']:
+ continue
+
+ discount = i.payment_term and i.payment_term.cash_discount_ids and i.payment_term.cash_discount_ids[0] or False
+ if discount and time.strftime('%Y-%m-%d') <= discount.date :
+ amount_to_pay = i.amount_total*(1-discount.discount)
+ else :
+ amount_to_pay = i.amount_total
+
+ lines.append(dta_line_obj.create(cr,uid,{
+ 'name':i.id,
+ 'partner_id':i.partner_id.id,
+ 'due_date':i.date_due,
+ 'cashdisc_date': discount and discount.date,
+ 'amount_to_pay': amount_to_pay,
+ 'amount_invoice':i.amount_total,
+ 'amount_cashdisc': discount and i.amount_total*(1-discount.discount),
+ 'dta_id': id_dta,
+ }))
+
+ return {'dta_line_ids': lines}
+
def c_ljust(s, size):
"""
check before calling ljust
@@ -148,8 +196,8 @@ def _create_dta(self,cr,uid,data,context):
# cree des gt836
creation_date= time.strftime('%y%m%d')
- log=''
- skip=''
+ err_log=''
+ std_log=''
dta=''
valeur=''
pool = pooler.get_pool(cr.dbname)
@@ -157,27 +205,40 @@ def _create_dta(self,cr,uid,data,context):
bank_name= bank.name or ''
bank_iban = bank.iban or ''
if not bank_name and bank_iban :
- log= log +'\nBank account not well defined.'
+ err_log= err_log +'\nBank account not well defined.'
user = pool.get('res.users').browse(cr,uid,[uid])[0]
company= user.company_id
co_addr= company.partner_id.address[0]
company_dta = company.dta_number or ''
if not company.dta_number :
- log= log +'\nNo dta number for the company.'
+ err_log= err_log +'\nNo dta number for the company.'
company_iban = company.partner_id and company.partner_id.bank_ids and company.partner_id.bank_ids[0]\
and company.partner_id.bank_ids[0].iban or ''
if not company_iban :
- log= log +'\nNo iban number for the company.'
+ err_log= err_log +'\nNo iban number for the company.'
inv_obj = pool.get('account.invoice')
+ dta_line_obj = pool.get('account.dta.line')
seq= 1
amount_tot= 0
- for i in inv_obj.browse(cr,uid,data['ids']):
- if i.dta_state != '2bpaid' or i.state in ['draft','cancel','paid']:
- skip= skip +'\n Invoice '+ (i.number or '??')+ ' ignored.'
- continue
+
+
+ for dtal in dta_line_obj.browse(cr,uid,[ line[1] for line in data['form']['dta_line_ids'] ]):
+
+ i = dtal.name #dta_line.name = invoice's id
+
+ std_log = std_log + '''
+--
+ Invoice : %s
+ Partner : %s
+ Invoice amount : %d
+ Amount Paid : %d
+''' % (i.name, i.partner_id.name,i.amount_total, dtal.amount_to_pay )
+
+ if dtal.cashdisc_date:
+ std_log = std_log + " Cash Discount : %d if paid before %s" % (dtal.amount_cashdisc, dtal.cashdisc_date)
number = i.number or ''
currency = i.currency_id.code or ''
@@ -198,52 +259,51 @@ def _create_dta(self,cr,uid,data,context):
partner_city= ''
partner_zip= ''
partner_country= ''
- log= log +'\nNo address for the invoice partner.'
+ err_log= err_log +'\nNo address for the invoice partner.'
if not partner_bank_account:
- log= log +'\nNo bank account for the invoice partner. (invoice '+ (i.number or '??')+')'
+ err_log= err_log +'\nNo bank account for the invoice partner. (invoice '+ (i.number or '??')+')'
#header
try:
hdr= header('000000','',creation_date,company_iban,'idfi',seq,'836','0') # TODO id_file
except Exception,e :
- log= log +'\n'+ str(e)
+ err_log= err_log +'\n'+ str(e)
#raise
# segment 01:
try:
dta = dta + segment_01(hdr,company_dta ,
- number,company_iban,valeur,currency,str(i.amount_total))
+ number,company_iban,valeur,currency,str(dtal.amount_to_pay))
except Exception,e :
- log= log +'\n'+ str(e)
+ err_log= err_log +'\n'+ str(e)
#raise
# adresse donneur d'ordre
try:
dta = dta + segment_02(company.name,co_addr.street,co_addr.zip,co_addr.city,country,cours='')
except Exception,e :
- log= log +'\n'+ str(e)
+ err_log= err_log +'\n'+ str(e)
#raise
# donnees de la banque
try:
dta = dta + segment_03(bank_name,'',bank_iban)
except Exception,e :
- log= log +'\n'+ str(e)
+ err_log= err_log +'\n'+ str(e)
#raise
# adresse du beneficiaire
try:
dta = dta + segment_04(partner_name,partner_street,partner_zip,partner_city,partner_country,cours='')
except Exception,e :
- log= log +'\n'+ str(e)
+ err_log= err_log +'\n'+ str(e)
#raise
# communication & reglement des frais
try:
dta = dta + segment_05(motif='I',ref1='',ref2=i.reference or '',ref3='',format='0') #FIXME : motif
except Exception,e :
- log= log +'\n'+ str(e)
+ err_log= err_log +'\n'+ str(e)
#raise
-
- amount_tot += i.amount_total
+ amount_tot += dtal.amount_to_pay
inv_obj.write(cr,uid,[i.id],{'dta_state':'paid'})
seq += 1
@@ -254,24 +314,43 @@ def _create_dta(self,cr,uid,data,context):
dta = dta + total(header('000000','',creation_date,company_iban,str(uid),seq,'890','0')\
, str(amount_tot))
except Exception,e :
- log= log +'\n'+ str(e)
+ err_log= err_log +'\n'+ str(e)
#raise
- log = log and log +'\nCORRUPTED FILE !'or 'DONE'
- return {'note':log+skip, 'dta': b64encode(dta)}
+
+ err_log = err_log and 'CORRUPTED FILE !\n'+err_log or 'OK'
+
+ err_log = err_log + '\nParsed DTA lines :\n' + std_log
+ pool.get('account.dta').write(cr,uid,[dtal.dta_id.id],{'note':err_log,'name':b64encode(dta)})
+
+ return {'note':err_log, 'dta': b64encode(dta)}
class wizard_dta_create(wizard.interface):
states = {
'init' : {
- 'actions' : [_get_fields],
+ 'actions' : [_get_bank],
'result' : {'type' : 'form',
'arch' : ask_form,
'fields' : ask_fields,
- 'state' : [('end', 'Cancel'),('creation', 'Yes') ]}
+ 'state' : [('end', 'Cancel'),('check', 'Yes') ]}
},
+ 'check':{
+ 'actions' : [_get_dta_lines],
+ 'result' : {'type' : 'form',
+ 'arch' : check_form,
+ 'fields' : check_fields,
+ 'state' : [('clean', 'Cancel'),('creation', 'Yes') ]}
+ },
+
+ 'clean':{
+ 'actions' : [_cleaning],
+ 'result' : {'type' : 'state',
+ 'state' : 'end',}
+ },
+
'creation' : {
'actions' : [_create_dta],
'result' : {'type' : 'form',
diff --git a/addons/l10n_ch/v11/v11_import.py b/addons/l10n_ch/v11/v11_import.py
index 1f6a83c0dab..cafa83b30e4 100644
--- a/addons/l10n_ch/v11/v11_import.py
+++ b/addons/l10n_ch/v11/v11_import.py
@@ -24,6 +24,12 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
+
+
+# TODO : accepter les ligne meme si le payement est trop bas
+# definir un try-catch ligne 221 et re-raiser si l'on le souhaite
+
+
import pooler
import time
import wizard
@@ -92,7 +98,8 @@ def _v11_parsing(self, cr, uid, data, context):
total={}
total_compute= 0
rec_list=[]
- log=''
+ err_log=''
+ std_log=''
nb_err=0
# v11 parsing :
@@ -132,14 +139,14 @@ def _v11_parsing(self, cr, uid, data, context):
'line_number': str(lnb),
}
- total_compute+= int(record['montant'])
+ total_compute+= float(record['montant'])
rec_list.append( record )
lnb+=1
line=""
# check the amounts :
- if not total_compute == int(total['tot_montant']):
+ if not total_compute == float(total['tot_montant']):
return {'note': 'Incorrect total amount V11 file, import aborted.' }
@@ -163,15 +170,15 @@ def _v11_parsing(self, cr, uid, data, context):
try:
invoice_id= invoice_obj.search(cr,uid,[ ('number','=',int(rec['invoice_ref'])) ])[0]
except:
- log = log + '\n * No invoice with invoice number '+ rec['invoice_ref'].lstrip('0') + '.\n line : '+rec['line']
+ err_log = err_log + '\n * No invoice with invoice number '+ rec['invoice_ref'].lstrip('0') + '.\n line : '+rec['line_number']
nb_err+=1
continue
- invoice = invoice_obj.browse(cr, uid, invoice_id)
+ i = invoice_obj.browse(cr, uid, invoice_id)
try:
- acc1 = invoice.partner_id.property_account_receivable[0]
+ acc1 = i.partner_id.property_account_receivable[0]
except:
- log = log + '\n * invoice with number '+ rec['invoice_ref'].lstrip('0') +' has no partner !'+ '\n line : '+rec['line']
+ err_log = err_log + '\n * invoice with number '+ rec['invoice_ref'].lstrip('0') +' has no partner !'+ '\n line : '+rec['line_number']
nb_err+=1
continue
@@ -187,7 +194,7 @@ def _v11_parsing(self, cr, uid, data, context):
'credit': rec['montant'],
'account_id': acc1,
'move_id': move_id,
- 'partner_id': invoice.partner_id.id,
+ 'partner_id': i.partner_id.id,
'date': time.strftime('%Y-%m-%d'),
'period_id': period_id,
'journal_id': data['form']['journal_id']
@@ -199,52 +206,67 @@ def _v11_parsing(self, cr, uid, data, context):
'credit': 0,
'account_id': acc2,
'move_id': move_id,
- 'partner_id': invoice.partner_id.id,
+ 'partner_id': i.partner_id.id,
'date': time.strftime('%Y-%m-%d'),
'period_id': period_id,
'journal_id': data['form']['journal_id']
})
- account_move_lines = invoice.move_line_id_payment_get(cr,uid,[invoice.id])
+ account_move_lines = i.move_line_id_payment_get(cr,uid,[i.id])
if not account_move_lines:
raise Exception("No moves associated to invoice number "+ rec['invoice_ref'].lstrip('0'))
account_move_lines.append(line_id )
- pool.get('account.move.line').reconcile(cr,uid,account_move_lines,
- writeoff_acc_id=0,
- writeoff_journal_id=0,
- writeoff_period_id= 0,
- )
+
+ pool.get('account.move.line').reconcile(cr,uid,account_move_lines,
+ writeoff_acc_id=0,
+ writeoff_journal_id=0,
+ writeoff_period_id= 0,
+ )
cr.commit()
+ std_log = std_log + """
+--
+ Invoice : %s
+ Date Due : %s
+ Amount received : %.2f
+ """%(i.name, i.date_due or 'undefined', float(rec['montant']))
+ if i.payment_term and i.payment_term.cash_discount_ids and i.payment_term.cash_discount_ids[0]:
+ if discount and rec['date_remise'] <= discount.date :
+ amount_to_pay = i.amount_total*(1-discount.discount)
+ else :
+ amount_to_pay = i.amount_total
+
+ std_log = std_log + " Amount expected : %d"% amount_to_pay
+
except osv.except_osv, e:
cr.rollback()
nb_err+=1
if e.value.startswith('You have to provide an account for the write off entry !'):
- log= log +'\n * Line '+rec['line_number'] +', invoice '+rec['invoice_ref'].lstrip('0')+\
+ err_log= err_log +'\n * Line '+rec['line_number'] +', invoice '+rec['invoice_ref'].lstrip('0')+\
' : Amount mismatch for invoice '+ rec['invoice_ref'].lstrip('0')+\
- '( expected amount: '+str(invoice.amount_total)+' got :'+rec['montant'].lstrip('0')+\
+ '( expected amount: '+str(i.amount_total)+' got :'+rec['montant'].lstrip('0')+\
').'
else:
- log= log +'\n * Line '+rec['line_number'] +', invoice '+rec['invoice_ref'].lstrip('0')+\
+ err_log= err_log +'\n * Line '+rec['line_number'] +', invoice '+rec['invoice_ref'].lstrip('0')+\
' : '+str(e.value)
#raise # REMOVEME
except Exception, e:
cr.rollback()
nb_err+=1
- log= log +'\n * Line '+rec['line_number'] +', invoice '+rec['invoice_ref'].lstrip('0')+\
+ err_log= err_log +'\n * Line '+rec['line_number'] +', invoice '+rec['invoice_ref'].lstrip('0')+\
' : '+str(e)
#raise # REMOVEME
except :
cr.rollback()
nb_err+=1
- log= log +'\n * Line '+rec['line_number'] +', invoice '+rec['invoice_ref'].lstrip('0')+' : Reconciliation Error.'
+ err_log= err_log +'\n * Line '+rec['line_number'] +', invoice '+rec['invoice_ref'].lstrip('0')+' : Reconciliation Error.'
#raise
- log= log + '\n\n --' +'\nNumber of parsed lines : '+ str(len(rec_list)) +'\nNumber of error : '+ str(nb_err)
+ err_log= err_log + '\n\n --' +'\nNumber of parsed lines : '+ str(len(rec_list)) +'\nNumber of error : '+ str(nb_err)
- return {'note':log,'journal_id': data['form']['journal_id'], 'v11': data['form']['v11']}
+ return {'note':err_log+ std_log,'journal_id': data['form']['journal_id'], 'v11': data['form']['v11']}
# def _init(self, cr, uid, data, context):