mirror of
https://github.com/OCA/account-reconcile.git
synced 2025-01-20 12:27:39 +02:00
autopep8
This commit is contained in:
@@ -82,4 +82,4 @@ many offices.
|
|||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
'application': True,
|
'application': True,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,8 +177,8 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
mkey, mvalue = matcher
|
mkey, mvalue = matcher
|
||||||
omkey, omvalue = opposite_matcher
|
omkey, omvalue = opposite_matcher
|
||||||
assert mkey == omkey, ("A matcher %s is compared with a matcher %s, "
|
assert mkey == omkey, ("A matcher %s is compared with a matcher %s, "
|
||||||
" the _matchers and _opposite_matchers are probably wrong" %
|
" the _matchers and _opposite_matchers are probably wrong" %
|
||||||
(mkey, omkey))
|
(mkey, omkey))
|
||||||
if not isinstance(mvalue, (list, tuple)):
|
if not isinstance(mvalue, (list, tuple)):
|
||||||
mvalue = mvalue,
|
mvalue = mvalue,
|
||||||
if not isinstance(omvalue, (list, tuple)):
|
if not isinstance(omvalue, (list, tuple)):
|
||||||
@@ -194,7 +194,7 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
they are candidate for a reconciliation.
|
they are candidate for a reconciliation.
|
||||||
"""
|
"""
|
||||||
opp_matchers = self._opposite_matchers(cr, uid, rec, opposite_move_line,
|
opp_matchers = self._opposite_matchers(cr, uid, rec, opposite_move_line,
|
||||||
context=context)
|
context=context)
|
||||||
for matcher in matchers:
|
for matcher in matchers:
|
||||||
try:
|
try:
|
||||||
opp_matcher = opp_matchers.next()
|
opp_matcher = opp_matchers.next()
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ Reconcile rules with transaction_ref
|
|||||||
'depends': ['account_advanced_reconcile'],
|
'depends': ['account_advanced_reconcile'],
|
||||||
'data': ['easy_reconcile_view.xml'],
|
'data': ['easy_reconcile_view.xml'],
|
||||||
'demo': [],
|
'demo': [],
|
||||||
'test': [], # To be ported or migrate to unit tests or scenarios
|
'test': [], # To be ported or migrate to unit tests or scenarios
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'images': []
|
'images': []
|
||||||
}
|
}
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from openerp.osv import orm
|
from openerp.osv import orm
|
||||||
|
|
||||||
|
|
||||||
class easy_reconcile_advanced_transaction_ref(orm.TransientModel):
|
class easy_reconcile_advanced_transaction_ref(orm.TransientModel):
|
||||||
|
|
||||||
@@ -35,10 +35,10 @@ class easy_reconcile_advanced_transaction_ref(orm.TransientModel):
|
|||||||
return not (move_line.get('transaction_ref') and
|
return not (move_line.get('transaction_ref') and
|
||||||
move_line.get('partner_id'))
|
move_line.get('partner_id'))
|
||||||
|
|
||||||
def _matchers(self, cr, uid, rec, move_line, context=None):
|
def _matchers(self, cr, uid, rec, move_line, context=None):
|
||||||
return (('partner_id', move_line['partner_id']),
|
return (('partner_id', move_line['partner_id']),
|
||||||
('ref', move_line['transaction_ref'].lower().strip()))
|
('ref', move_line['transaction_ref'].lower().strip()))
|
||||||
|
|
||||||
def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
|
def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
|
||||||
yield ('partner_id', move_line['partner_id'])
|
yield ('partner_id', move_line['partner_id'])
|
||||||
yield ('ref', (move_line['transaction_ref'] or '').lower().strip())
|
yield ('ref', (move_line['transaction_ref'] or '').lower().strip())
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ from openerp.osv import orm
|
|||||||
class easy_reconcile_advanced(orm.AbstractModel):
|
class easy_reconcile_advanced(orm.AbstractModel):
|
||||||
|
|
||||||
_inherit = 'easy.reconcile.advanced'
|
_inherit = 'easy.reconcile.advanced'
|
||||||
|
|
||||||
def _base_columns(self, rec):
|
def _base_columns(self, rec):
|
||||||
""" Mandatory columns for move lines queries
|
""" Mandatory columns for move lines queries
|
||||||
An extra column aliased as ``key`` should be defined
|
An extra column aliased as ``key`` should be defined
|
||||||
@@ -43,4 +43,4 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
'account_id',
|
'account_id',
|
||||||
'move_id',
|
'move_id',
|
||||||
'transaction_ref')
|
'transaction_ref')
|
||||||
return ["account_move_line.%s" % col for col in aml_cols]
|
return ["account_move_line.%s" % col for col in aml_cols]
|
||||||
|
|||||||
@@ -36,4 +36,3 @@ class account_easy_reconcile_method(orm.Model):
|
|||||||
'Advanced. Partner and Transaction Ref. vs Ref.'),
|
'Advanced. Partner and Transaction Ref. vs Ref.'),
|
||||||
]
|
]
|
||||||
return methods
|
return methods
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from operator import itemgetter, attrgetter
|
|||||||
|
|
||||||
|
|
||||||
class easy_reconcile_base(orm.AbstractModel):
|
class easy_reconcile_base(orm.AbstractModel):
|
||||||
|
|
||||||
"""Abstract Model for reconciliation methods"""
|
"""Abstract Model for reconciliation methods"""
|
||||||
|
|
||||||
_name = 'easy.reconcile.base'
|
_name = 'easy.reconcile.base'
|
||||||
@@ -112,9 +113,9 @@ class easy_reconcile_base(orm.AbstractModel):
|
|||||||
sums = reduce(
|
sums = reduce(
|
||||||
lambda line, memo:
|
lambda line, memo:
|
||||||
dict((key, value + memo[key])
|
dict((key, value + memo[key])
|
||||||
for key, value
|
for key, value
|
||||||
in line.iteritems()
|
in line.iteritems()
|
||||||
if key in keys), lines)
|
if key in keys), lines)
|
||||||
|
|
||||||
debit, credit = sums['debit'], sums['credit']
|
debit, credit = sums['debit'], sums['credit']
|
||||||
writeoff_amount = round(debit - credit, precision)
|
writeoff_amount = round(debit - credit, precision)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ from openerp.tools.translate import _
|
|||||||
|
|
||||||
|
|
||||||
class easy_reconcile_options(orm.AbstractModel):
|
class easy_reconcile_options(orm.AbstractModel):
|
||||||
|
|
||||||
"""Options of a reconciliation profile
|
"""Options of a reconciliation profile
|
||||||
|
|
||||||
Columns shared by the configuration of methods
|
Columns shared by the configuration of methods
|
||||||
@@ -45,21 +46,21 @@ class easy_reconcile_options(orm.AbstractModel):
|
|||||||
('newest_debit', 'Date of most recent debit')]
|
('newest_debit', 'Date of most recent debit')]
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'write_off': fields.float('Write off allowed'),
|
'write_off': fields.float('Write off allowed'),
|
||||||
'account_lost_id': fields.many2one(
|
'account_lost_id': fields.many2one(
|
||||||
'account.account', 'Account Lost'),
|
'account.account', 'Account Lost'),
|
||||||
'account_profit_id': fields.many2one(
|
'account_profit_id': fields.many2one(
|
||||||
'account.account', 'Account Profit'),
|
'account.account', 'Account Profit'),
|
||||||
'journal_id': fields.many2one(
|
'journal_id': fields.many2one(
|
||||||
'account.journal', 'Journal'),
|
'account.journal', 'Journal'),
|
||||||
'date_base_on': fields.selection(
|
'date_base_on': fields.selection(
|
||||||
_get_rec_base_date,
|
_get_rec_base_date,
|
||||||
required=True,
|
required=True,
|
||||||
string='Date of reconciliation'),
|
string='Date of reconciliation'),
|
||||||
'filter': fields.char('Filter', size=128),
|
'filter': fields.char('Filter', size=128),
|
||||||
'analytic_account_id': fields.many2one(
|
'analytic_account_id': fields.many2one(
|
||||||
'account.analytic.account', 'Analytic Account',
|
'account.analytic.account', 'Analytic Account',
|
||||||
help="Analytic account for the write-off"),
|
help="Analytic account for the write-off"),
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
@@ -81,31 +82,32 @@ class account_easy_reconcile_method(orm.Model):
|
|||||||
return [
|
return [
|
||||||
('easy.reconcile.simple.name', 'Simple. Amount and Name'),
|
('easy.reconcile.simple.name', 'Simple. Amount and Name'),
|
||||||
('easy.reconcile.simple.partner', 'Simple. Amount and Partner'),
|
('easy.reconcile.simple.partner', 'Simple. Amount and Partner'),
|
||||||
('easy.reconcile.simple.reference', 'Simple. Amount and Reference'),
|
('easy.reconcile.simple.reference',
|
||||||
]
|
'Simple. Amount and Reference'),
|
||||||
|
]
|
||||||
|
|
||||||
def _get_rec_method(self, cr, uid, context=None):
|
def _get_rec_method(self, cr, uid, context=None):
|
||||||
return self._get_all_rec_method(cr, uid, context=None)
|
return self._get_all_rec_method(cr, uid, context=None)
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'name': fields.selection(
|
'name': fields.selection(
|
||||||
_get_rec_method, 'Type', required=True),
|
_get_rec_method, 'Type', required=True),
|
||||||
'sequence': fields.integer(
|
'sequence': fields.integer(
|
||||||
'Sequence',
|
'Sequence',
|
||||||
required=True,
|
required=True,
|
||||||
help="The sequence field is used to order "
|
help="The sequence field is used to order "
|
||||||
"the reconcile method"),
|
"the reconcile method"),
|
||||||
'task_id': fields.many2one(
|
'task_id': fields.many2one(
|
||||||
'account.easy.reconcile',
|
'account.easy.reconcile',
|
||||||
string='Task',
|
string='Task',
|
||||||
required=True,
|
required=True,
|
||||||
ondelete='cascade'),
|
ondelete='cascade'),
|
||||||
'company_id': fields.related('task_id','company_id',
|
'company_id': fields.related('task_id', 'company_id',
|
||||||
relation='res.company',
|
relation='res.company',
|
||||||
type='many2one',
|
type='many2one',
|
||||||
string='Company',
|
string='Company',
|
||||||
store=True,
|
store=True,
|
||||||
readonly=True),
|
readonly=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
@@ -240,9 +242,9 @@ class account_easy_reconcile(orm.Model):
|
|||||||
all_ml_partial_ids += ml_partial_ids
|
all_ml_partial_ids += ml_partial_ids
|
||||||
|
|
||||||
reconcile_ids = find_reconcile_ids(
|
reconcile_ids = find_reconcile_ids(
|
||||||
'reconcile_id', all_ml_rec_ids)
|
'reconcile_id', all_ml_rec_ids)
|
||||||
partial_ids = find_reconcile_ids(
|
partial_ids = find_reconcile_ids(
|
||||||
'reconcile_partial_id', all_ml_partial_ids)
|
'reconcile_partial_id', all_ml_partial_ids)
|
||||||
|
|
||||||
self.pool.get('easy.reconcile.history').create(
|
self.pool.get('easy.reconcile.history').create(
|
||||||
cr,
|
cr,
|
||||||
@@ -260,10 +262,10 @@ class account_easy_reconcile(orm.Model):
|
|||||||
task.
|
task.
|
||||||
"""
|
"""
|
||||||
raise osv.except_osv(
|
raise osv.except_osv(
|
||||||
_('Error'),
|
_('Error'),
|
||||||
_('There is no history of reconciled '
|
_('There is no history of reconciled '
|
||||||
'items on the task: %s.') % rec.name)
|
'items on the task: %s.') % rec.name)
|
||||||
|
|
||||||
def _open_move_line_list(sefl, cr, uid, move_line_ids, name, context=None):
|
def _open_move_line_list(sefl, cr, uid, move_line_ids, name, context=None):
|
||||||
return {
|
return {
|
||||||
'name': name,
|
'name': name,
|
||||||
@@ -275,19 +277,19 @@ class account_easy_reconcile(orm.Model):
|
|||||||
'nodestroy': True,
|
'nodestroy': True,
|
||||||
'target': 'current',
|
'target': 'current',
|
||||||
'domain': unicode([('id', 'in', move_line_ids)]),
|
'domain': unicode([('id', 'in', move_line_ids)]),
|
||||||
}
|
}
|
||||||
|
|
||||||
def open_unreconcile(self, cr, uid, ids, context=None):
|
def open_unreconcile(self, cr, uid, ids, context=None):
|
||||||
""" Open the view of move line with the unreconciled move lines
|
""" Open the view of move line with the unreconciled move lines
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assert len(ids) == 1 , \
|
assert len(ids) == 1, \
|
||||||
"You can only open entries from one profile at a time"
|
"You can only open entries from one profile at a time"
|
||||||
|
|
||||||
obj_move_line = self.pool.get('account.move.line')
|
obj_move_line = self.pool.get('account.move.line')
|
||||||
res = {}
|
res = {}
|
||||||
for task in self.browse(cr, uid, ids, context=context):
|
for task in self.browse(cr, uid, ids, context=context):
|
||||||
line_ids = obj_move_line.search(
|
line_ids = obj_move_line.search(
|
||||||
cr, uid,
|
cr, uid,
|
||||||
[('account_id', '=', task.account.id),
|
[('account_id', '=', task.account.id),
|
||||||
('reconcile_id', '=', False),
|
('reconcile_id', '=', False),
|
||||||
@@ -301,13 +303,13 @@ class account_easy_reconcile(orm.Model):
|
|||||||
""" Open the view of move line with the unreconciled move lines
|
""" Open the view of move line with the unreconciled move lines
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assert len(ids) == 1 , \
|
assert len(ids) == 1, \
|
||||||
"You can only open entries from one profile at a time"
|
"You can only open entries from one profile at a time"
|
||||||
|
|
||||||
obj_move_line = self.pool.get('account.move.line')
|
obj_move_line = self.pool.get('account.move.line')
|
||||||
res = {}
|
res = {}
|
||||||
for task in self.browse(cr, uid, ids, context=context):
|
for task in self.browse(cr, uid, ids, context=context):
|
||||||
line_ids = obj_move_line.search(
|
line_ids = obj_move_line.search(
|
||||||
cr, uid,
|
cr, uid,
|
||||||
[('account_id', '=', task.account.id),
|
[('account_id', '=', task.account.id),
|
||||||
('reconcile_id', '=', False),
|
('reconcile_id', '=', False),
|
||||||
@@ -322,7 +324,7 @@ class account_easy_reconcile(orm.Model):
|
|||||||
"""
|
"""
|
||||||
if isinstance(rec_id, (tuple, list)):
|
if isinstance(rec_id, (tuple, list)):
|
||||||
assert len(rec_id) == 1, \
|
assert len(rec_id) == 1, \
|
||||||
"Only 1 id expected"
|
"Only 1 id expected"
|
||||||
rec_id = rec_id[0]
|
rec_id = rec_id[0]
|
||||||
rec = self.browse(cr, uid, rec_id, context=context)
|
rec = self.browse(cr, uid, rec_id, context=context)
|
||||||
if not rec.last_history:
|
if not rec.last_history:
|
||||||
@@ -335,7 +337,7 @@ class account_easy_reconcile(orm.Model):
|
|||||||
"""
|
"""
|
||||||
if isinstance(rec_id, (tuple, list)):
|
if isinstance(rec_id, (tuple, list)):
|
||||||
assert len(rec_id) == 1, \
|
assert len(rec_id) == 1, \
|
||||||
"Only 1 id expected"
|
"Only 1 id expected"
|
||||||
rec_id = rec_id[0]
|
rec_id = rec_id[0]
|
||||||
rec = self.browse(cr, uid, rec_id, context=context)
|
rec = self.browse(cr, uid, rec_id, context=context)
|
||||||
if not rec.last_history:
|
if not rec.last_history:
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from openerp.tools.translate import _
|
|||||||
|
|
||||||
|
|
||||||
class easy_reconcile_history(orm.Model):
|
class easy_reconcile_history(orm.Model):
|
||||||
|
|
||||||
""" Store an history of the runs per profile
|
""" Store an history of the runs per profile
|
||||||
Each history stores the list of reconciliations done"""
|
Each history stores the list of reconciliations done"""
|
||||||
|
|
||||||
@@ -40,39 +41,39 @@ class easy_reconcile_history(orm.Model):
|
|||||||
move_line_ids = []
|
move_line_ids = []
|
||||||
for reconcile in history.reconcile_ids:
|
for reconcile in history.reconcile_ids:
|
||||||
move_line_ids += [line.id
|
move_line_ids += [line.id
|
||||||
for line
|
for line
|
||||||
in reconcile.line_id]
|
in reconcile.line_id]
|
||||||
result[history.id]['reconcile_line_ids'] = move_line_ids
|
result[history.id]['reconcile_line_ids'] = move_line_ids
|
||||||
|
|
||||||
move_line_ids = []
|
move_line_ids = []
|
||||||
for reconcile in history.reconcile_partial_ids:
|
for reconcile in history.reconcile_partial_ids:
|
||||||
move_line_ids += [line.id
|
move_line_ids += [line.id
|
||||||
for line
|
for line
|
||||||
in reconcile.line_partial_ids]
|
in reconcile.line_partial_ids]
|
||||||
result[history.id]['partial_line_ids'] = move_line_ids
|
result[history.id]['partial_line_ids'] = move_line_ids
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'easy_reconcile_id': fields.many2one(
|
'easy_reconcile_id': fields.many2one(
|
||||||
'account.easy.reconcile', 'Reconcile Profile', readonly=True),
|
'account.easy.reconcile', 'Reconcile Profile', readonly=True),
|
||||||
'date': fields.datetime('Run date', readonly=True),
|
'date': fields.datetime('Run date', readonly=True),
|
||||||
'reconcile_ids': fields.many2many(
|
'reconcile_ids': fields.many2many(
|
||||||
'account.move.reconcile',
|
'account.move.reconcile',
|
||||||
'account_move_reconcile_history_rel',
|
'account_move_reconcile_history_rel',
|
||||||
string='Reconciliations', readonly=True),
|
string='Reconciliations', readonly=True),
|
||||||
'reconcile_partial_ids': fields.many2many(
|
'reconcile_partial_ids': fields.many2many(
|
||||||
'account.move.reconcile',
|
'account.move.reconcile',
|
||||||
'account_move_reconcile_history_partial_rel',
|
'account_move_reconcile_history_partial_rel',
|
||||||
string='Partial Reconciliations', readonly=True),
|
string='Partial Reconciliations', readonly=True),
|
||||||
'reconcile_line_ids':
|
'reconcile_line_ids':
|
||||||
fields.function(
|
fields.function(
|
||||||
_reconcile_line_ids,
|
_reconcile_line_ids,
|
||||||
string='Reconciled Items',
|
string='Reconciled Items',
|
||||||
type='many2many',
|
type='many2many',
|
||||||
relation='account.move.line',
|
relation='account.move.line',
|
||||||
readonly=True,
|
readonly=True,
|
||||||
multi='lines'),
|
multi='lines'),
|
||||||
'partial_line_ids':
|
'partial_line_ids':
|
||||||
fields.function(
|
fields.function(
|
||||||
_reconcile_line_ids,
|
_reconcile_line_ids,
|
||||||
@@ -81,14 +82,14 @@ class easy_reconcile_history(orm.Model):
|
|||||||
relation='account.move.line',
|
relation='account.move.line',
|
||||||
readonly=True,
|
readonly=True,
|
||||||
multi='lines'),
|
multi='lines'),
|
||||||
'company_id': fields.related('easy_reconcile_id','company_id',
|
'company_id': fields.related('easy_reconcile_id', 'company_id',
|
||||||
relation='res.company',
|
relation='res.company',
|
||||||
type='many2one',
|
type='many2one',
|
||||||
string='Company',
|
string='Company',
|
||||||
store=True,
|
store=True,
|
||||||
readonly=True),
|
readonly=True),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def _open_move_lines(self, cr, uid, history_id, rec_type='full', context=None):
|
def _open_move_lines(self, cr, uid, history_id, rec_type='full', context=None):
|
||||||
""" For an history record, open the view of move line with
|
""" For an history record, open the view of move line with
|
||||||
@@ -99,7 +100,7 @@ class easy_reconcile_history(orm.Model):
|
|||||||
:return: action to open the move lines
|
:return: action to open the move lines
|
||||||
"""
|
"""
|
||||||
assert rec_type in ('full', 'partial'), \
|
assert rec_type in ('full', 'partial'), \
|
||||||
"rec_type must be 'full' or 'partial'"
|
"rec_type must be 'full' or 'partial'"
|
||||||
|
|
||||||
history = self.browse(cr, uid, history_id, context=context)
|
history = self.browse(cr, uid, history_id, context=context)
|
||||||
|
|
||||||
@@ -122,7 +123,7 @@ class easy_reconcile_history(orm.Model):
|
|||||||
'nodestroy': True,
|
'nodestroy': True,
|
||||||
'target': 'current',
|
'target': 'current',
|
||||||
'domain': unicode([('id', 'in', move_line_ids)]),
|
'domain': unicode([('id', 'in', move_line_ids)]),
|
||||||
}
|
}
|
||||||
|
|
||||||
def open_reconcile(self, cr, uid, history_ids, context=None):
|
def open_reconcile(self, cr, uid, history_ids, context=None):
|
||||||
""" For an history record, open the view of move line
|
""" For an history record, open the view of move line
|
||||||
@@ -136,7 +137,7 @@ class easy_reconcile_history(orm.Model):
|
|||||||
assert len(history_ids) == 1, "only 1 ID is accepted"
|
assert len(history_ids) == 1, "only 1 ID is accepted"
|
||||||
history_ids = history_ids[0]
|
history_ids = history_ids[0]
|
||||||
return self._open_move_lines(
|
return self._open_move_lines(
|
||||||
cr, uid, history_ids, rec_type='full', context=None)
|
cr, uid, history_ids, rec_type='full', context=None)
|
||||||
|
|
||||||
def open_partial(self, cr, uid, history_ids, context=None):
|
def open_partial(self, cr, uid, history_ids, context=None):
|
||||||
""" For an history record, open the view of move line
|
""" For an history record, open the view of move line
|
||||||
@@ -150,4 +151,4 @@ class easy_reconcile_history(orm.Model):
|
|||||||
assert len(history_ids) == 1, "only 1 ID is accepted"
|
assert len(history_ids) == 1, "only 1 ID is accepted"
|
||||||
history_ids = history_ids[0]
|
history_ids = history_ids[0]
|
||||||
return self._open_move_lines(
|
return self._open_move_lines(
|
||||||
cr, uid, history_ids, rec_type='partial', context=None)
|
cr, uid, history_ids, rec_type='partial', context=None)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class easy_reconcile_simple(AbstractModel):
|
|||||||
count = 0
|
count = 0
|
||||||
res = []
|
res = []
|
||||||
while (count < len(lines)):
|
while (count < len(lines)):
|
||||||
for i in xrange(count+1, len(lines)):
|
for i in xrange(count + 1, len(lines)):
|
||||||
writeoff_account_id = False
|
writeoff_account_id = False
|
||||||
if lines[count][self._key_field] != lines[i][self._key_field]:
|
if lines[count][self._key_field] != lines[i][self._key_field]:
|
||||||
break
|
break
|
||||||
@@ -51,7 +51,7 @@ class easy_reconcile_simple(AbstractModel):
|
|||||||
credit_line = lines[count]
|
credit_line = lines[count]
|
||||||
debit_line = lines[i]
|
debit_line = lines[i]
|
||||||
check = True
|
check = True
|
||||||
elif lines[i]['credit'] > 0 and lines[count]['debit'] > 0:
|
elif lines[i]['credit'] > 0 and lines[count]['debit'] > 0:
|
||||||
credit_line = lines[i]
|
credit_line = lines[i]
|
||||||
debit_line = lines[count]
|
debit_line = lines[count]
|
||||||
check = True
|
check = True
|
||||||
|
|||||||
@@ -19,15 +19,15 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
{'name' : 'Invoices Reference',
|
{'name': 'Invoices Reference',
|
||||||
'version' : '1.0',
|
'version': '1.0',
|
||||||
'author' : 'Camptocamp',
|
'author': 'Camptocamp',
|
||||||
'maintainer': 'Camptocamp',
|
'maintainer': 'Camptocamp',
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
'category': 'category',
|
'category': 'category',
|
||||||
'complexity': "easy",
|
'complexity': "easy",
|
||||||
'depends' : ['account',
|
'depends': ['account',
|
||||||
],
|
],
|
||||||
'description': """
|
'description': """
|
||||||
Invoices Reference
|
Invoices Reference
|
||||||
==================
|
==================
|
||||||
@@ -143,4 +143,4 @@ Information propagated to the move lines:
|
|||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ class account_move(orm.Model):
|
|||||||
if invoice:
|
if invoice:
|
||||||
assert isinstance(invoice, orm.browse_record)
|
assert isinstance(invoice, orm.browse_record)
|
||||||
invoice_obj = self.pool['account.invoice']
|
invoice_obj = self.pool['account.invoice']
|
||||||
ref = invoice_obj._ref_from_invoice(cr, uid, invoice, context=context)
|
ref = invoice_obj._ref_from_invoice(
|
||||||
|
cr, uid, invoice, context=context)
|
||||||
vals = vals.copy()
|
vals = vals.copy()
|
||||||
vals['ref'] = ref
|
vals['ref'] = ref
|
||||||
move_id = super(account_move, self).\
|
move_id = super(account_move, self).\
|
||||||
|
|||||||
@@ -40,4 +40,4 @@ Needs `statement_voucher_killer`
|
|||||||
'test': [],
|
'test': [],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'auto_install': True,
|
'auto_install': True,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ from openerp.addons.account_statement_base_completion.statement import ErrorTooM
|
|||||||
|
|
||||||
|
|
||||||
class AccountStatementCompletionRule(Model):
|
class AccountStatementCompletionRule(Model):
|
||||||
|
|
||||||
"""Add a rule based on transaction ID"""
|
"""Add a rule based on transaction ID"""
|
||||||
|
|
||||||
_inherit = "account.statement.completion.rule"
|
_inherit = "account.statement.completion.rule"
|
||||||
@@ -64,15 +65,20 @@ class AccountStatementCompletionRule(Model):
|
|||||||
raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more than '
|
raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more than '
|
||||||
'one partner for account number "%s".') % (st_line['name'], st_line['ref'], partner_acc_number))
|
'one partner for account number "%s".') % (st_line['name'], st_line['ref'], partner_acc_number))
|
||||||
if len(ids) == 1:
|
if len(ids) == 1:
|
||||||
partner = res_bank_obj.browse(cr, uid, ids[0], context=context).partner_id
|
partner = res_bank_obj.browse(
|
||||||
|
cr, uid, ids[0], context=context).partner_id
|
||||||
res['partner_id'] = partner.id
|
res['partner_id'] = partner.id
|
||||||
st_vals = st_obj.get_values_for_line(cr,
|
st_vals = st_obj.get_values_for_line(cr,
|
||||||
uid,
|
uid,
|
||||||
profile_id=st_line['profile_id'],
|
profile_id=st_line[
|
||||||
master_account_id=st_line['master_account_id'],
|
'profile_id'],
|
||||||
partner_id=res.get('partner_id', False),
|
master_account_id=st_line[
|
||||||
|
'master_account_id'],
|
||||||
|
partner_id=res.get(
|
||||||
|
'partner_id', False),
|
||||||
line_type=st_line['type'],
|
line_type=st_line['type'],
|
||||||
amount=st_line['amount'] if st_line['amount'] else 0.0,
|
amount=st_line['amount'] if st_line[
|
||||||
|
'amount'] else 0.0,
|
||||||
context=context)
|
context=context)
|
||||||
res.update(st_vals)
|
res.update(st_vals)
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -30,14 +30,20 @@ class bankaccount_completion(common.TransactionCase):
|
|||||||
def prepare(self):
|
def prepare(self):
|
||||||
self.company_a = self.browse_ref('base.main_company')
|
self.company_a = self.browse_ref('base.main_company')
|
||||||
self.profile_obj = self.registry("account.statement.profile")
|
self.profile_obj = self.registry("account.statement.profile")
|
||||||
self.account_bank_statement_obj = self.registry("account.bank.statement")
|
self.account_bank_statement_obj = self.registry(
|
||||||
self.account_bank_statement_line_obj = self.registry("account.bank.statement.line")
|
"account.bank.statement")
|
||||||
self.completion_rule_id = self.ref('account_statement_bankaccount_completion.bank_statement_completion_rule_10')
|
self.account_bank_statement_line_obj = self.registry(
|
||||||
self.journal_id = self.registry("ir.model.data").get_object_reference(self.cr, self. uid, "account", "bank_journal")[1]
|
"account.bank.statement.line")
|
||||||
|
self.completion_rule_id = self.ref(
|
||||||
|
'account_statement_bankaccount_completion.bank_statement_completion_rule_10')
|
||||||
|
self.journal_id = self.registry("ir.model.data").get_object_reference(
|
||||||
|
self.cr, self. uid, "account", "bank_journal")[1]
|
||||||
self.partner_id = self.ref('base.main_partner')
|
self.partner_id = self.ref('base.main_partner')
|
||||||
# Create the profile
|
# Create the profile
|
||||||
self.account_id = self.registry("ir.model.data").get_object_reference(self.cr, self.uid, "account", "a_recv")[1]
|
self.account_id = self.registry("ir.model.data").get_object_reference(
|
||||||
self.journal_id = self.registry("ir.model.data").get_object_reference(self.cr, self. uid, "account", "bank_journal")[1]
|
self.cr, self.uid, "account", "a_recv")[1]
|
||||||
|
self.journal_id = self.registry("ir.model.data").get_object_reference(
|
||||||
|
self.cr, self. uid, "account", "bank_journal")[1]
|
||||||
self.profile_id = self.profile_obj.create(self.cr, self.uid, {
|
self.profile_id = self.profile_obj.create(self.cr, self.uid, {
|
||||||
"name": "TEST",
|
"name": "TEST",
|
||||||
"commission_account_id": self.account_id,
|
"commission_account_id": self.account_id,
|
||||||
@@ -77,15 +83,20 @@ class bankaccount_completion(common.TransactionCase):
|
|||||||
|
|
||||||
def test_00(self):
|
def test_00(self):
|
||||||
"""Test complete partner_id from bank account number
|
"""Test complete partner_id from bank account number
|
||||||
|
|
||||||
Test the automatic completion of the partner_id based on the account number associated to the
|
Test the automatic completion of the partner_id based on the account number associated to the
|
||||||
statement line
|
statement line
|
||||||
"""
|
"""
|
||||||
self.prepare()
|
self.prepare()
|
||||||
statement_line = self.account_bank_statement_line_obj.browse(self.cr, self.uid, self.statement_line_id)
|
statement_line = self.account_bank_statement_line_obj.browse(
|
||||||
|
self.cr, self.uid, self.statement_line_id)
|
||||||
# before import, the
|
# before import, the
|
||||||
self.assertFalse(statement_line.partner_id, "Partner_id must be blank before completion")
|
self.assertFalse(
|
||||||
statement_obj = self.account_bank_statement_obj.browse(self.cr, self.uid, self.statement_id)
|
statement_line.partner_id, "Partner_id must be blank before completion")
|
||||||
|
statement_obj = self.account_bank_statement_obj.browse(
|
||||||
|
self.cr, self.uid, self.statement_id)
|
||||||
statement_obj.button_auto_completion()
|
statement_obj.button_auto_completion()
|
||||||
statement_line = self.account_bank_statement_line_obj.browse(self.cr, self.uid, self.statement_line_id)
|
statement_line = self.account_bank_statement_line_obj.browse(
|
||||||
self.assertEquals(self.partner_id, statement_line.partner_id['id'], "Missing expected partner id after completion")
|
self.cr, self.uid, self.statement_line_id)
|
||||||
|
self.assertEquals(self.partner_id, statement_line.partner_id[
|
||||||
|
'id'], "Missing expected partner id after completion")
|
||||||
|
|||||||
@@ -65,13 +65,13 @@
|
|||||||
],
|
],
|
||||||
'demo': [],
|
'demo': [],
|
||||||
'test': [
|
'test': [
|
||||||
'test/partner.yml',
|
'test/partner.yml',
|
||||||
'test/invoice.yml',
|
'test/invoice.yml',
|
||||||
'test/supplier_invoice.yml',
|
'test/supplier_invoice.yml',
|
||||||
'test/completion_test.yml'
|
'test/completion_test.yml'
|
||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#################################################################################
|
##########################################################################
|
||||||
# #
|
# #
|
||||||
# Copyright (C) 2011 Akretion & Camptocamp
|
# Copyright (C) 2011 Akretion & Camptocamp
|
||||||
# Author : Sébastien BEAU, Joel Grand-Guillaume #
|
# Author : Sébastien BEAU, Joel Grand-Guillaume #
|
||||||
@@ -17,13 +17,14 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License #
|
# You should have received a copy of the GNU Affero General Public License #
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
# #
|
# #
|
||||||
#################################################################################
|
##########################################################################
|
||||||
|
|
||||||
from openerp.osv.orm import Model
|
from openerp.osv.orm import Model
|
||||||
from openerp.osv import fields
|
from openerp.osv import fields
|
||||||
|
|
||||||
|
|
||||||
class res_partner(Model):
|
class res_partner(Model):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Add a bank label on the partner so that we can use it to match
|
Add a bank label on the partner so that we can use it to match
|
||||||
this partner when we found this in a statement line.
|
this partner when we found this in a statement line.
|
||||||
@@ -32,7 +33,7 @@ class res_partner(Model):
|
|||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'bank_statement_label': fields.char('Bank Statement Label', size=100,
|
'bank_statement_label': fields.char('Bank Statement Label', size=100,
|
||||||
help="Enter the various label found on your bank statement separated by a ; If "
|
help="Enter the various label found on your bank statement separated by a ; If "
|
||||||
"one of this label is include in the bank statement line, the partner will be automatically "
|
"one of this label is include in the bank statement line, the partner will be automatically "
|
||||||
"filled (as long as you use this method/rules in your statement profile)."),
|
"filled (as long as you use this method/rules in your statement profile)."),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,10 +40,12 @@ _logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class ErrorTooManyPartner(Exception):
|
class ErrorTooManyPartner(Exception):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
New Exception definition that is raised when more than one partner is matched by
|
New Exception definition that is raised when more than one partner is matched by
|
||||||
the completion rule.
|
the completion rule.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
@@ -55,6 +57,7 @@ class ErrorTooManyPartner(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class AccountStatementProfil(orm.Model):
|
class AccountStatementProfil(orm.Model):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Extend the class to add rules per profile that will match at least the partner,
|
Extend the class to add rules per profile that will match at least the partner,
|
||||||
but it could also be used to match other values as well.
|
but it could also be used to match other values as well.
|
||||||
@@ -100,7 +103,8 @@ class AccountStatementProfil(orm.Model):
|
|||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
if not calls:
|
if not calls:
|
||||||
calls = self._get_rules(cr, uid, line['profile_id'], context=context)
|
calls = self._get_rules(
|
||||||
|
cr, uid, line['profile_id'], context=context)
|
||||||
rule_obj = self.pool.get('account.statement.completion.rule')
|
rule_obj = self.pool.get('account.statement.completion.rule')
|
||||||
|
|
||||||
for call in calls:
|
for call in calls:
|
||||||
@@ -116,6 +120,7 @@ class AccountStatementProfil(orm.Model):
|
|||||||
|
|
||||||
|
|
||||||
class AccountStatementCompletionRule(orm.Model):
|
class AccountStatementCompletionRule(orm.Model):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This will represent all the completion method that we can have to
|
This will represent all the completion method that we can have to
|
||||||
fullfill the bank statement lines. You'll be able to extend them in you own module
|
fullfill the bank statement lines. You'll be able to extend them in you own module
|
||||||
@@ -134,9 +139,12 @@ class AccountStatementCompletionRule(orm.Model):
|
|||||||
List of available methods for rules. Override this to add you own.
|
List of available methods for rules. Override this to add you own.
|
||||||
"""
|
"""
|
||||||
return [
|
return [
|
||||||
('get_from_ref_and_invoice', 'From line reference (based on customer invoice number)'),
|
('get_from_ref_and_invoice',
|
||||||
('get_from_ref_and_supplier_invoice', 'From line reference (based on supplier invoice number)'),
|
'From line reference (based on customer invoice number)'),
|
||||||
('get_from_label_and_partner_field', 'From line label (based on partner field)'),
|
('get_from_ref_and_supplier_invoice',
|
||||||
|
'From line reference (based on supplier invoice number)'),
|
||||||
|
('get_from_label_and_partner_field',
|
||||||
|
'From line label (based on partner field)'),
|
||||||
('get_from_label_and_partner_name', 'From line label (based on partner name)')]
|
('get_from_label_and_partner_name', 'From line label (based on partner name)')]
|
||||||
|
|
||||||
def __get_functions(self, cr, uid, context=None):
|
def __get_functions(self, cr, uid, context=None):
|
||||||
@@ -272,7 +280,8 @@ class AccountStatementCompletionRule(orm.Model):
|
|||||||
[('bank_statement_label', '!=', False)])
|
[('bank_statement_label', '!=', False)])
|
||||||
line_ids = context.get('line_ids', [])
|
line_ids = context.get('line_ids', [])
|
||||||
for partner in partner_obj.browse(cr, uid, partner_ids, context=context):
|
for partner in partner_obj.browse(cr, uid, partner_ids, context=context):
|
||||||
vals = '|'.join(re.escape(x.strip()) for x in partner.bank_statement_label.split(';'))
|
vals = '|'.join(re.escape(x.strip())
|
||||||
|
for x in partner.bank_statement_label.split(';'))
|
||||||
or_regex = ".*%s.*" % vals
|
or_regex = ".*%s.*" % vals
|
||||||
sql = ("SELECT id from account_bank_statement_line"
|
sql = ("SELECT id from account_bank_statement_line"
|
||||||
" WHERE id in %s"
|
" WHERE id in %s"
|
||||||
@@ -292,11 +301,15 @@ class AccountStatementCompletionRule(orm.Model):
|
|||||||
res['partner_id'] = found_partner[0].id
|
res['partner_id'] = found_partner[0].id
|
||||||
st_vals = st_obj.get_values_for_line(cr,
|
st_vals = st_obj.get_values_for_line(cr,
|
||||||
uid,
|
uid,
|
||||||
profile_id=st_line['profile_id'],
|
profile_id=st_line[
|
||||||
master_account_id=st_line['master_account_id'],
|
'profile_id'],
|
||||||
partner_id=found_partner[0].id,
|
master_account_id=st_line[
|
||||||
|
'master_account_id'],
|
||||||
|
partner_id=found_partner[
|
||||||
|
0].id,
|
||||||
line_type=False,
|
line_type=False,
|
||||||
amount=st_line['amount'] if st_line['amount'] else 0.0,
|
amount=st_line['amount'] if st_line[
|
||||||
|
'amount'] else 0.0,
|
||||||
context=context)
|
context=context)
|
||||||
res.update(st_vals)
|
res.update(st_vals)
|
||||||
return res
|
return res
|
||||||
@@ -320,7 +333,8 @@ class AccountStatementCompletionRule(orm.Model):
|
|||||||
res = {}
|
res = {}
|
||||||
# We memoize allowed partner
|
# We memoize allowed partner
|
||||||
if not context.get('partner_memoizer'):
|
if not context.get('partner_memoizer'):
|
||||||
context['partner_memoizer'] = tuple(self.pool['res.partner'].search(cr, uid, []))
|
context['partner_memoizer'] = tuple(
|
||||||
|
self.pool['res.partner'].search(cr, uid, []))
|
||||||
if not context['partner_memoizer']:
|
if not context['partner_memoizer']:
|
||||||
return res
|
return res
|
||||||
st_obj = self.pool.get('account.bank.statement.line')
|
st_obj = self.pool.get('account.bank.statement.line')
|
||||||
@@ -335,7 +349,8 @@ class AccountStatementCompletionRule(orm.Model):
|
|||||||
SELECT id, regexp_matches(%s, regexp_replace(name,'([\.\^\$\*\+\?\(\)\[\{\\\|])', %s, 'g'), 'i') AS name_match FROM res_partner
|
SELECT id, regexp_matches(%s, regexp_replace(name,'([\.\^\$\*\+\?\(\)\[\{\\\|])', %s, 'g'), 'i') AS name_match FROM res_partner
|
||||||
WHERE id IN %s) AS res_patner_matcher
|
WHERE id IN %s) AS res_patner_matcher
|
||||||
WHERE name_match IS NOT NULL"""
|
WHERE name_match IS NOT NULL"""
|
||||||
cr.execute(sql, (st_line['name'], r"\\\1", context['partner_memoizer']))
|
cr.execute(
|
||||||
|
sql, (st_line['name'], r"\\\1", context['partner_memoizer']))
|
||||||
result = cr.fetchall()
|
result = cr.fetchall()
|
||||||
if not result:
|
if not result:
|
||||||
return res
|
return res
|
||||||
@@ -347,14 +362,17 @@ class AccountStatementCompletionRule(orm.Model):
|
|||||||
st_vals = st_obj.get_values_for_line(cr,
|
st_vals = st_obj.get_values_for_line(cr,
|
||||||
uid,
|
uid,
|
||||||
profile_id=st_line['profile_id'],
|
profile_id=st_line['profile_id'],
|
||||||
master_account_id=st_line['master_account_id'],
|
master_account_id=st_line[
|
||||||
|
'master_account_id'],
|
||||||
partner_id=res['partner_id'],
|
partner_id=res['partner_id'],
|
||||||
line_type=False,
|
line_type=False,
|
||||||
amount=st_line['amount'] if st_line['amount'] else 0.0,
|
amount=st_line['amount'] if st_line[
|
||||||
|
'amount'] else 0.0,
|
||||||
context=context)
|
context=context)
|
||||||
res.update(st_vals)
|
res.update(st_vals)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
class AccountStatement(orm.Model):
|
class AccountStatement(orm.Model):
|
||||||
_inherit = "account.bank.statement"
|
_inherit = "account.bank.statement"
|
||||||
|
|
||||||
@@ -364,17 +382,18 @@ class AccountStatement(orm.Model):
|
|||||||
line_without_account = line_obj.search(cr, uid, [
|
line_without_account = line_obj.search(cr, uid, [
|
||||||
['statement_id', '=', stat_id],
|
['statement_id', '=', stat_id],
|
||||||
['account_id', '=', False],
|
['account_id', '=', False],
|
||||||
], context=context)
|
], context=context)
|
||||||
if line_without_account:
|
if line_without_account:
|
||||||
stat = self.browse(cr, uid, stat_id, context=context)
|
stat = self.browse(cr, uid, stat_id, context=context)
|
||||||
raise orm.except_orm(_('User error'),
|
raise orm.except_orm(_('User error'),
|
||||||
_('You should fill all account on the line of the'
|
_('You should fill all account on the line of the'
|
||||||
' statement %s')%stat.name)
|
' statement %s') % stat.name)
|
||||||
return super(AccountStatement, self).button_confirm_bank(
|
return super(AccountStatement, self).button_confirm_bank(
|
||||||
cr, uid, ids, context=context)
|
cr, uid, ids, context=context)
|
||||||
|
|
||||||
|
|
||||||
class AccountStatementLine(orm.Model):
|
class AccountStatementLine(orm.Model):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Add sparse field on the statement line to allow to store all the
|
Add sparse field on the statement line to allow to store all the
|
||||||
bank infos that are given by a bank/office. You can then add you own in your
|
bank infos that are given by a bank/office. You can then add you own in your
|
||||||
@@ -424,7 +443,8 @@ class AccountStatementLine(orm.Model):
|
|||||||
if line.get('already_completed'):
|
if line.get('already_completed'):
|
||||||
return {}
|
return {}
|
||||||
# Ask the rule
|
# Ask the rule
|
||||||
vals = profile_obj._find_values_from_rules(cr, uid, rules, line, context)
|
vals = profile_obj._find_values_from_rules(
|
||||||
|
cr, uid, rules, line, context)
|
||||||
if vals:
|
if vals:
|
||||||
vals['id'] = line['id']
|
vals['id'] = line['id']
|
||||||
return vals
|
return vals
|
||||||
@@ -434,15 +454,16 @@ class AccountStatementLine(orm.Model):
|
|||||||
"""Return writeable by SQL columns"""
|
"""Return writeable by SQL columns"""
|
||||||
statement_line_obj = self.pool['account.bank.statement.line']
|
statement_line_obj = self.pool['account.bank.statement.line']
|
||||||
model_cols = statement_line_obj._columns
|
model_cols = statement_line_obj._columns
|
||||||
avail = [k for k, col in model_cols.iteritems() if not hasattr(col, '_fnct')]
|
avail = [
|
||||||
|
k for k, col in model_cols.iteritems() if not hasattr(col, '_fnct')]
|
||||||
keys = [k for k in statement_store[0].keys() if k in avail]
|
keys = [k for k in statement_store[0].keys() if k in avail]
|
||||||
# add sparse fields..
|
# add sparse fields..
|
||||||
if include_serializable:
|
if include_serializable:
|
||||||
for k, col in model_cols.iteritems():
|
for k, col in model_cols.iteritems():
|
||||||
if k in statement_store[0].keys() and \
|
if k in statement_store[0].keys() and \
|
||||||
isinstance(col, fields.sparse) and \
|
isinstance(col, fields.sparse) and \
|
||||||
col.serialization_field not in keys and \
|
col.serialization_field not in keys and \
|
||||||
col._type == 'char':
|
col._type == 'char':
|
||||||
keys.append(col.serialization_field)
|
keys.append(col.serialization_field)
|
||||||
keys.sort()
|
keys.sort()
|
||||||
return keys
|
return keys
|
||||||
@@ -472,7 +493,8 @@ class AccountStatementLine(orm.Model):
|
|||||||
"""
|
"""
|
||||||
statement_line_obj = self.pool['account.bank.statement.line']
|
statement_line_obj = self.pool['account.bank.statement.line']
|
||||||
model_cols = statement_line_obj._columns
|
model_cols = statement_line_obj._columns
|
||||||
sparse_fields = dict([(k, col) for k, col in model_cols.iteritems() if isinstance(col, fields.sparse) and col._type == 'char'])
|
sparse_fields = dict([(k, col) for k, col in model_cols.iteritems() if isinstance(
|
||||||
|
col, fields.sparse) and col._type == 'char'])
|
||||||
values = []
|
values = []
|
||||||
for statement in statement_store:
|
for statement in statement_store:
|
||||||
to_json_k = set()
|
to_json_k = set()
|
||||||
@@ -480,7 +502,8 @@ class AccountStatementLine(orm.Model):
|
|||||||
for k, col in sparse_fields.iteritems():
|
for k, col in sparse_fields.iteritems():
|
||||||
if k in st_copy:
|
if k in st_copy:
|
||||||
to_json_k.add(col.serialization_field)
|
to_json_k.add(col.serialization_field)
|
||||||
serialized = st_copy.setdefault(col.serialization_field, {})
|
serialized = st_copy.setdefault(
|
||||||
|
col.serialization_field, {})
|
||||||
serialized[k] = st_copy[k]
|
serialized[k] = st_copy[k]
|
||||||
for k in to_json_k:
|
for k in to_json_k:
|
||||||
st_copy[k] = simplejson.dumps(st_copy[k])
|
st_copy[k] = simplejson.dumps(st_copy[k])
|
||||||
@@ -493,13 +516,16 @@ class AccountStatementLine(orm.Model):
|
|||||||
does not exist"""
|
does not exist"""
|
||||||
statement_line_obj = self.pool['account.bank.statement.line']
|
statement_line_obj = self.pool['account.bank.statement.line']
|
||||||
statement_line_obj.check_access_rule(cr, uid, [], 'create')
|
statement_line_obj.check_access_rule(cr, uid, [], 'create')
|
||||||
statement_line_obj.check_access_rights(cr, uid, 'create', raise_exception=True)
|
statement_line_obj.check_access_rights(
|
||||||
cols = self._get_available_columns(statement_store, include_serializable=True)
|
cr, uid, 'create', raise_exception=True)
|
||||||
|
cols = self._get_available_columns(
|
||||||
|
statement_store, include_serializable=True)
|
||||||
statement_store = self._prepare_manyinsert(statement_store, cols)
|
statement_store = self._prepare_manyinsert(statement_store, cols)
|
||||||
tmp_vals = (', '.join(cols), ', '.join(['%%(%s)s' % i for i in cols]))
|
tmp_vals = (', '.join(cols), ', '.join(['%%(%s)s' % i for i in cols]))
|
||||||
sql = "INSERT INTO account_bank_statement_line (%s) VALUES (%s);" % tmp_vals
|
sql = "INSERT INTO account_bank_statement_line (%s) VALUES (%s);" % tmp_vals
|
||||||
try:
|
try:
|
||||||
cr.executemany(sql, tuple(self._serialize_sparse_fields(cols, statement_store)))
|
cr.executemany(
|
||||||
|
sql, tuple(self._serialize_sparse_fields(cols, statement_store)))
|
||||||
except psycopg2.Error as sql_err:
|
except psycopg2.Error as sql_err:
|
||||||
cr.rollback()
|
cr.rollback()
|
||||||
raise osv.except_osv(_("ORM bypass error"),
|
raise osv.except_osv(_("ORM bypass error"),
|
||||||
@@ -526,6 +552,7 @@ class AccountStatementLine(orm.Model):
|
|||||||
|
|
||||||
|
|
||||||
class AccountBankStatement(orm.Model):
|
class AccountBankStatement(orm.Model):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
We add a basic button and stuff to support the auto-completion
|
We add a basic button and stuff to support the auto-completion
|
||||||
of the bank statement once line have been imported or manually fullfill.
|
of the bank statement once line have been imported or manually fullfill.
|
||||||
@@ -556,11 +583,13 @@ class AccountBankStatement(orm.Model):
|
|||||||
context=context)['completion_logs']
|
context=context)['completion_logs']
|
||||||
log = log if log else ""
|
log = log if log else ""
|
||||||
|
|
||||||
completion_date = datetime.datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
completion_date = datetime.datetime.now().strftime(
|
||||||
|
DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
message = (_("%s Bank Statement ID %s has %s/%s lines completed by %s \n%s\n%s\n") %
|
message = (_("%s Bank Statement ID %s has %s/%s lines completed by %s \n%s\n%s\n") %
|
||||||
(completion_date, stat_id, number_imported, number_line, user_name,
|
(completion_date, stat_id, number_imported, number_line, user_name,
|
||||||
error_msg, log))
|
error_msg, log))
|
||||||
self.write(cr, uid, [stat_id], {'completion_logs': message}, context=context)
|
self.write(
|
||||||
|
cr, uid, [stat_id], {'completion_logs': message}, context=context)
|
||||||
|
|
||||||
body = (_('Statement ID %s auto-completed for %s/%s lines completed') %
|
body = (_('Statement ID %s auto-completed for %s/%s lines completed') %
|
||||||
(stat_id, number_imported, number_line)),
|
(stat_id, number_imported, number_line)),
|
||||||
@@ -581,14 +610,16 @@ class AccountBankStatement(orm.Model):
|
|||||||
profile_obj = self.pool.get('account.statement.profile')
|
profile_obj = self.pool.get('account.statement.profile')
|
||||||
compl_lines = 0
|
compl_lines = 0
|
||||||
stat_line_obj.check_access_rule(cr, uid, [], 'create')
|
stat_line_obj.check_access_rule(cr, uid, [], 'create')
|
||||||
stat_line_obj.check_access_rights(cr, uid, 'create', raise_exception=True)
|
stat_line_obj.check_access_rights(
|
||||||
|
cr, uid, 'create', raise_exception=True)
|
||||||
for stat in self.browse(cr, uid, ids, context=context):
|
for stat in self.browse(cr, uid, ids, context=context):
|
||||||
msg_lines = []
|
msg_lines = []
|
||||||
ctx = context.copy()
|
ctx = context.copy()
|
||||||
ctx['line_ids'] = tuple((x.id for x in stat.line_ids))
|
ctx['line_ids'] = tuple((x.id for x in stat.line_ids))
|
||||||
b_profile = stat.profile_id
|
b_profile = stat.profile_id
|
||||||
rules = profile_obj._get_rules(cr, uid, b_profile, context=context)
|
rules = profile_obj._get_rules(cr, uid, b_profile, context=context)
|
||||||
profile_id = b_profile.id # Only for perfo even it gains almost nothing
|
# Only for perfo even it gains almost nothing
|
||||||
|
profile_id = b_profile.id
|
||||||
master_account_id = b_profile.receivable_account_id
|
master_account_id = b_profile.receivable_account_id
|
||||||
master_account_id = master_account_id.id if master_account_id else False
|
master_account_id = master_account_id.id if master_account_id else False
|
||||||
res = False
|
res = False
|
||||||
@@ -606,17 +637,20 @@ class AccountBankStatement(orm.Model):
|
|||||||
except Exception, exc:
|
except Exception, exc:
|
||||||
msg_lines.append(repr(exc))
|
msg_lines.append(repr(exc))
|
||||||
error_type, error_value, trbk = sys.exc_info()
|
error_type, error_value, trbk = sys.exc_info()
|
||||||
st = "Error: %s\nDescription: %s\nTraceback:" % (error_type.__name__, error_value)
|
st = "Error: %s\nDescription: %s\nTraceback:" % (
|
||||||
|
error_type.__name__, error_value)
|
||||||
st += ''.join(traceback.format_tb(trbk, 30))
|
st += ''.join(traceback.format_tb(trbk, 30))
|
||||||
_logger.error(st)
|
_logger.error(st)
|
||||||
if res:
|
if res:
|
||||||
# stat_line_obj.write(cr, uid, [line.id], vals, context=ctx)
|
# stat_line_obj.write(cr, uid, [line.id], vals, context=ctx)
|
||||||
try:
|
try:
|
||||||
stat_line_obj._update_line(cr, uid, res, context=context)
|
stat_line_obj._update_line(
|
||||||
|
cr, uid, res, context=context)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
msg_lines.append(repr(exc))
|
msg_lines.append(repr(exc))
|
||||||
error_type, error_value, trbk = sys.exc_info()
|
error_type, error_value, trbk = sys.exc_info()
|
||||||
st = "Error: %s\nDescription: %s\nTraceback:" % (error_type.__name__, error_value)
|
st = "Error: %s\nDescription: %s\nTraceback:" % (
|
||||||
|
error_type.__name__, error_value)
|
||||||
st += ''.join(traceback.format_tb(trbk, 30))
|
st += ''.join(traceback.format_tb(trbk, 30))
|
||||||
_logger.error(st)
|
_logger.error(st)
|
||||||
# we can commit as it is not needed to be atomic
|
# we can commit as it is not needed to be atomic
|
||||||
|
|||||||
@@ -23,22 +23,26 @@ from openerp.tests import common
|
|||||||
import time
|
import time
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
name_completion_case = namedtuple("name_completion_case", ["partner_name", "line_label", "should_match"])
|
name_completion_case = namedtuple(
|
||||||
|
"name_completion_case", ["partner_name", "line_label", "should_match"])
|
||||||
NAMES_COMPLETION_CASES = [
|
NAMES_COMPLETION_CASES = [
|
||||||
name_completion_case("Acsone", "Line for Acsone SA", True),
|
name_completion_case("Acsone", "Line for Acsone SA", True),
|
||||||
name_completion_case("Acsone", "Line for Acsone", True),
|
name_completion_case("Acsone", "Line for Acsone", True),
|
||||||
name_completion_case("Acsone", "Acsone for line", True),
|
name_completion_case("Acsone", "Acsone for line", True),
|
||||||
name_completion_case("acsone", "Acsone for line", True),
|
name_completion_case("acsone", "Acsone for line", True),
|
||||||
name_completion_case("Acsone SA", "Line for Acsone SA test", True),
|
name_completion_case("Acsone SA", "Line for Acsone SA test", True),
|
||||||
name_completion_case("Ac..ne", "Acsone for line", False),
|
name_completion_case("Ac..ne", "Acsone for line", False),
|
||||||
name_completion_case("é@|r{}", "Acsone é@|r{} for line", True),
|
name_completion_case("é@|r{}", "Acsone é@|r{} for line", True),
|
||||||
name_completion_case("Acsone", "A..one for line", False),
|
name_completion_case("Acsone", "A..one for line", False),
|
||||||
name_completion_case("A.one SA", "A.one SA for line", True),
|
name_completion_case("A.one SA", "A.one SA for line", True),
|
||||||
name_completion_case("Acsone SA", "Line for Acsone ([^a-zA-Z0-9 -]) SA test", False),
|
name_completion_case(
|
||||||
name_completion_case("Acsone ([^a-zA-Z0-9 -]) SA", "Line for Acsone ([^a-zA-Z0-9 -]) SA test", True),
|
"Acsone SA", "Line for Acsone ([^a-zA-Z0-9 -]) SA test", False),
|
||||||
name_completion_case(r"Acsone (.^$*+?()[{\| -]\) SA", r"Line for Acsone (.^$*+?()[{\| -]\) SA test", True),
|
name_completion_case(
|
||||||
name_completion_case("Acšone SA", "Line for Acšone SA test", True),
|
"Acsone ([^a-zA-Z0-9 -]) SA", "Line for Acsone ([^a-zA-Z0-9 -]) SA test", True),
|
||||||
]
|
name_completion_case(
|
||||||
|
r"Acsone (.^$*+?()[{\| -]\) SA", r"Line for Acsone (.^$*+?()[{\| -]\) SA test", True),
|
||||||
|
name_completion_case("Acšone SA", "Line for Acšone SA test", True),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class base_completion(common.TransactionCase):
|
class base_completion(common.TransactionCase):
|
||||||
@@ -48,8 +52,10 @@ class base_completion(common.TransactionCase):
|
|||||||
self.company_a = self.browse_ref('base.main_company')
|
self.company_a = self.browse_ref('base.main_company')
|
||||||
self.profile_obj = self.registry("account.statement.profile")
|
self.profile_obj = self.registry("account.statement.profile")
|
||||||
self.partner_obj = self.registry("res.partner")
|
self.partner_obj = self.registry("res.partner")
|
||||||
self.account_bank_statement_obj = self.registry("account.bank.statement")
|
self.account_bank_statement_obj = self.registry(
|
||||||
self.account_bank_statement_line_obj = self.registry("account.bank.statement.line")
|
"account.bank.statement")
|
||||||
|
self.account_bank_statement_line_obj = self.registry(
|
||||||
|
"account.bank.statement.line")
|
||||||
self.journal_id = self.ref("account.bank_journal")
|
self.journal_id = self.ref("account.bank_journal")
|
||||||
self.partner_id = self.ref('base.main_partner')
|
self.partner_id = self.ref('base.main_partner')
|
||||||
self.account_id = self.ref("account.a_recv")
|
self.account_id = self.ref("account.a_recv")
|
||||||
@@ -60,7 +66,8 @@ class base_completion(common.TransactionCase):
|
|||||||
Test the automatic completion of the partner_id based if the name of the partner appears in
|
Test the automatic completion of the partner_id based if the name of the partner appears in
|
||||||
the statement line label
|
the statement line label
|
||||||
"""
|
"""
|
||||||
self.completion_rule_id = self.ref('account_statement_base_completion.bank_statement_completion_rule_3')
|
self.completion_rule_id = self.ref(
|
||||||
|
'account_statement_base_completion.bank_statement_completion_rule_3')
|
||||||
# Create the profile
|
# Create the profile
|
||||||
self.profile_id = self.profile_obj.create(self.cr, self.uid, {
|
self.profile_id = self.profile_obj.create(self.cr, self.uid, {
|
||||||
"name": "TEST",
|
"name": "TEST",
|
||||||
@@ -77,21 +84,26 @@ class base_completion(common.TransactionCase):
|
|||||||
})
|
})
|
||||||
|
|
||||||
for case in NAMES_COMPLETION_CASES:
|
for case in NAMES_COMPLETION_CASES:
|
||||||
self.partner_obj.write(self.cr, self.uid, self.partner_id, {'name': case.partner_name})
|
self.partner_obj.write(
|
||||||
|
self.cr, self.uid, self.partner_id, {'name': case.partner_name})
|
||||||
statement_line_id = self.account_bank_statement_line_obj.create(self.cr, self.uid, {
|
statement_line_id = self.account_bank_statement_line_obj.create(self.cr, self.uid, {
|
||||||
'amount': 1000.0,
|
'amount': 1000.0,
|
||||||
'name': case.line_label,
|
'name': case.line_label,
|
||||||
'ref': 'My ref',
|
'ref': 'My ref',
|
||||||
'statement_id': self.statement_id,
|
'statement_id': self.statement_id,
|
||||||
})
|
})
|
||||||
statement_line = self.account_bank_statement_line_obj.browse(self.cr, self.uid, statement_line_id)
|
statement_line = self.account_bank_statement_line_obj.browse(
|
||||||
self.assertFalse(statement_line.partner_id, "Partner_id must be blank before completion")
|
self.cr, self.uid, statement_line_id)
|
||||||
statement_obj = self.account_bank_statement_obj.browse(self.cr, self.uid, self.statement_id)
|
self.assertFalse(
|
||||||
|
statement_line.partner_id, "Partner_id must be blank before completion")
|
||||||
|
statement_obj = self.account_bank_statement_obj.browse(
|
||||||
|
self.cr, self.uid, self.statement_id)
|
||||||
statement_obj.button_auto_completion()
|
statement_obj.button_auto_completion()
|
||||||
statement_line = self.account_bank_statement_line_obj.browse(self.cr, self.uid, statement_line_id)
|
statement_line = self.account_bank_statement_line_obj.browse(
|
||||||
|
self.cr, self.uid, statement_line_id)
|
||||||
if case.should_match:
|
if case.should_match:
|
||||||
self.assertEquals(self.partner_id, statement_line.partner_id['id'],
|
self.assertEquals(self.partner_id, statement_line.partner_id['id'],
|
||||||
"Missing expected partner id after completion (partner_name: %s, line_name: %s)" % (case.partner_name, case.line_label))
|
"Missing expected partner id after completion (partner_name: %s, line_name: %s)" % (case.partner_name, case.line_label))
|
||||||
else:
|
else:
|
||||||
self.assertNotEquals(self.partner_id, statement_line.partner_id['id'],
|
self.assertNotEquals(self.partner_id, statement_line.partner_id['id'],
|
||||||
"Partner id should be empty after completion(partner_name: %s, line_name: %s)" % (case.partner_name, case.line_label))
|
"Partner id should be empty after completion(partner_name: %s, line_name: %s)" % (case.partner_name, case.line_label))
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
'depends': [
|
'depends': [
|
||||||
'account_statement_ext',
|
'account_statement_ext',
|
||||||
'account_statement_base_completion'
|
'account_statement_base_completion'
|
||||||
],
|
],
|
||||||
'description': """
|
'description': """
|
||||||
This module brings basic methods and fields on bank statement to deal with
|
This module brings basic methods and fields on bank statement to deal with
|
||||||
the importation of different bank and offices. A generic abstract method is defined and an
|
the importation of different bank and offices. A generic abstract method is defined and an
|
||||||
@@ -58,12 +58,12 @@
|
|||||||
""",
|
""",
|
||||||
'website': 'http://www.camptocamp.com',
|
'website': 'http://www.camptocamp.com',
|
||||||
'data': [
|
'data': [
|
||||||
"wizard/import_statement_view.xml",
|
"wizard/import_statement_view.xml",
|
||||||
"statement_view.xml",
|
"statement_view.xml",
|
||||||
],
|
],
|
||||||
'test': [],
|
'test': [],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,12 +28,15 @@ try:
|
|||||||
except:
|
except:
|
||||||
raise Exception(_('Please install python lib xlrd'))
|
raise Exception(_('Please install python lib xlrd'))
|
||||||
|
|
||||||
|
|
||||||
def float_or_zero(val):
|
def float_or_zero(val):
|
||||||
""" Conversion function used to manage
|
""" Conversion function used to manage
|
||||||
empty string into float usecase"""
|
empty string into float usecase"""
|
||||||
return float(val) if val else 0.0
|
return float(val) if val else 0.0
|
||||||
|
|
||||||
|
|
||||||
class FileParser(BankStatementImportParser):
|
class FileParser(BankStatementImportParser):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Generic abstract class for defining parser for .csv, .xls or .xlsx file format.
|
Generic abstract class for defining parser for .csv, .xls or .xlsx file format.
|
||||||
"""
|
"""
|
||||||
@@ -48,7 +51,7 @@ class FileParser(BankStatementImportParser):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
super(FileParser, self).__init__(parse_name, **kwargs)
|
super(FileParser, self).__init__(parse_name, **kwargs)
|
||||||
if ftype in ('csv', 'xls' ,'xlsx'):
|
if ftype in ('csv', 'xls', 'xlsx'):
|
||||||
self.ftype = ftype[0:3]
|
self.ftype = ftype[0:3]
|
||||||
else:
|
else:
|
||||||
raise except_osv(_('User Error'),
|
raise except_osv(_('User Error'),
|
||||||
@@ -64,8 +67,8 @@ class FileParser(BankStatementImportParser):
|
|||||||
self.keys_to_validate = self.conversion_dict.keys()
|
self.keys_to_validate = self.conversion_dict.keys()
|
||||||
self.fieldnames = header
|
self.fieldnames = header
|
||||||
self._datemode = 0 # used only for xls documents,
|
self._datemode = 0 # used only for xls documents,
|
||||||
# 0 means Windows mode (1900 based dates).
|
# 0 means Windows mode (1900 based dates).
|
||||||
# Set in _parse_xls, from the contents of the file
|
# Set in _parse_xls, from the contents of the file
|
||||||
|
|
||||||
def _custom_format(self, *args, **kwargs):
|
def _custom_format(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
@@ -161,8 +164,10 @@ class FileParser(BankStatementImportParser):
|
|||||||
" value: %s \n \n"
|
" value: %s \n \n"
|
||||||
" \n Please check the line with ref: %s"
|
" \n Please check the line with ref: %s"
|
||||||
" \n \n Detail: %s") % (rule,
|
" \n \n Detail: %s") % (rule,
|
||||||
line.get(rule, _('Missing')),
|
line.get(
|
||||||
line.get('ref', line),
|
rule, _('Missing')),
|
||||||
|
line.get(
|
||||||
|
'ref', line),
|
||||||
repr(err)))
|
repr(err)))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@@ -173,7 +178,8 @@ class FileParser(BankStatementImportParser):
|
|||||||
"\n Please check the line with ref %s:"
|
"\n Please check the line with ref %s:"
|
||||||
"\n \n Detail: %s") % (line.get(rule, _('Missing')),
|
"\n \n Detail: %s") % (line.get(rule, _('Missing')),
|
||||||
rule,
|
rule,
|
||||||
line.get('ref', line),
|
line.get(
|
||||||
|
'ref', line),
|
||||||
repr(err)))
|
repr(err)))
|
||||||
return result_set
|
return result_set
|
||||||
|
|
||||||
@@ -186,7 +192,8 @@ class FileParser(BankStatementImportParser):
|
|||||||
for rule in conversion_rules:
|
for rule in conversion_rules:
|
||||||
if conversion_rules[rule] == datetime.datetime:
|
if conversion_rules[rule] == datetime.datetime:
|
||||||
try:
|
try:
|
||||||
t_tuple = xlrd.xldate_as_tuple(line[rule], self._datemode)
|
t_tuple = xlrd.xldate_as_tuple(
|
||||||
|
line[rule], self._datemode)
|
||||||
line[rule] = datetime.datetime(*t_tuple)
|
line[rule] = datetime.datetime(*t_tuple)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
raise except_osv(_("Date format is not valid"),
|
raise except_osv(_("Date format is not valid"),
|
||||||
@@ -195,8 +202,10 @@ class FileParser(BankStatementImportParser):
|
|||||||
" value: %s"
|
" value: %s"
|
||||||
"\n Please check the line with ref: %s"
|
"\n Please check the line with ref: %s"
|
||||||
"\n \n Detail: %s") % (rule,
|
"\n \n Detail: %s") % (rule,
|
||||||
line.get(rule, _('Missing')),
|
line.get(
|
||||||
line.get('ref', line),
|
rule, _('Missing')),
|
||||||
|
line.get(
|
||||||
|
'ref', line),
|
||||||
repr(err)))
|
repr(err)))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@@ -207,7 +216,8 @@ class FileParser(BankStatementImportParser):
|
|||||||
"\n Please check the line with ref %s:"
|
"\n Please check the line with ref %s:"
|
||||||
"\n \n Detail: %s") % (line.get(rule, _('Missing')),
|
"\n \n Detail: %s") % (line.get(rule, _('Missing')),
|
||||||
rule,
|
rule,
|
||||||
line.get('ref', line),
|
line.get(
|
||||||
|
'ref', line),
|
||||||
repr(err)))
|
repr(err)))
|
||||||
return result_set
|
return result_set
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ except:
|
|||||||
|
|
||||||
|
|
||||||
class GenericFileParser(FileParser):
|
class GenericFileParser(FileParser):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Standard parser that use a define format in csv or xls to import into a
|
Standard parser that use a define format in csv or xls to import into a
|
||||||
bank statement. This is mostely an example of how to proceed to create a new
|
bank statement. This is mostely an example of how to proceed to create a new
|
||||||
@@ -38,7 +39,8 @@ class GenericFileParser(FileParser):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parse_name, ftype='csv', **kwargs):
|
def __init__(self, parse_name, ftype='csv', **kwargs):
|
||||||
super(GenericFileParser, self).__init__(parse_name, ftype=ftype, **kwargs)
|
super(GenericFileParser, self).__init__(
|
||||||
|
parse_name, ftype=ftype, **kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parser_for(cls, parser_name):
|
def parser_for(cls, parser_name):
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ def UnicodeDictReader(utf8_data, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
class BankStatementImportParser(object):
|
class BankStatementImportParser(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Generic abstract class for defining parser for different files and
|
Generic abstract class for defining parser for different files and
|
||||||
format to import in a bank statement. Inherit from it to create your
|
format to import in a bank statement. Inherit from it to create your
|
||||||
@@ -125,10 +126,10 @@ class BankStatementImportParser(object):
|
|||||||
:return: dict of vals that represent additional infos for the statement
|
:return: dict of vals that represent additional infos for the statement
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
'name': self.statement_name or '/',
|
'name': self.statement_name or '/',
|
||||||
'balance_start': self.balance_start,
|
'balance_start': self.balance_start,
|
||||||
'balance_end_real': self.balance_end,
|
'balance_end_real': self.balance_end,
|
||||||
'date': self.statement_date or datetime.now()
|
'date': self.statement_date or datetime.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_st_line_vals(self, line, *args, **kwargs):
|
def get_st_line_vals(self, line, *args, **kwargs):
|
||||||
@@ -221,7 +222,7 @@ def itersubclasses(cls, _seen=None):
|
|||||||
|
|
||||||
def new_bank_statement_parser(profile, *args, **kwargs):
|
def new_bank_statement_parser(profile, *args, **kwargs):
|
||||||
"""Return an instance of the good parser class based on the given profile.
|
"""Return an instance of the good parser class based on the given profile.
|
||||||
|
|
||||||
:param profile: browse_record of import profile.
|
:param profile: browse_record of import profile.
|
||||||
:return: class instance for given profile import type.
|
:return: class instance for given profile import type.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ class AccountStatementProfil(Model):
|
|||||||
help="Tic that box to automatically launch the completion "
|
help="Tic that box to automatically launch the completion "
|
||||||
"on each imported file using this profile."),
|
"on each imported file using this profile."),
|
||||||
'last_import_date': fields.datetime("Last Import Date"),
|
'last_import_date': fields.datetime("Last Import Date"),
|
||||||
# we remove deprecated as it floods logs in standard/warning level sob...
|
# we remove deprecated as it floods logs in standard/warning level
|
||||||
|
# sob...
|
||||||
'rec_log': fields.text('log', readonly=True), # Deprecated
|
'rec_log': fields.text('log', readonly=True), # Deprecated
|
||||||
'import_type': fields.selection(
|
'import_type': fields.selection(
|
||||||
__get_import_type_selection,
|
__get_import_type_selection,
|
||||||
@@ -57,8 +58,8 @@ class AccountStatementProfil(Model):
|
|||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'import_type': 'generic_csvxls_so'
|
'import_type': 'generic_csvxls_so'
|
||||||
}
|
}
|
||||||
|
|
||||||
def _write_extra_statement_lines(
|
def _write_extra_statement_lines(
|
||||||
self, cr, uid, parser, result_row_list, profile, statement_id, context):
|
self, cr, uid, parser, result_row_list, profile, statement_id, context):
|
||||||
@@ -91,7 +92,7 @@ class AccountStatementProfil(Model):
|
|||||||
context=context)
|
context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
#Deprecated remove on V8
|
# Deprecated remove on V8
|
||||||
def prepare_statetement_lines_vals(self, *args, **kwargs):
|
def prepare_statetement_lines_vals(self, *args, **kwargs):
|
||||||
return self.prepare_statement_lines_vals(*args, **kwargs)
|
return self.prepare_statement_lines_vals(*args, **kwargs)
|
||||||
|
|
||||||
@@ -121,11 +122,13 @@ class AccountStatementProfil(Model):
|
|||||||
else:
|
else:
|
||||||
# This is awfully slow...
|
# This is awfully slow...
|
||||||
periods = self.pool.get('account.period').find(cr, uid,
|
periods = self.pool.get('account.period').find(cr, uid,
|
||||||
dt=values.get('date'),
|
dt=values.get(
|
||||||
|
'date'),
|
||||||
context=context)
|
context=context)
|
||||||
values['period_id'] = periods[0]
|
values['period_id'] = periods[0]
|
||||||
period_memoizer[date] = periods[0]
|
period_memoizer[date] = periods[0]
|
||||||
values = statement_line_obj._add_missing_default_values(cr, uid, values, context)
|
values = statement_line_obj._add_missing_default_values(
|
||||||
|
cr, uid, values, context)
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def prepare_statement_vals(self, cr, uid, profile_id, result_row_list,
|
def prepare_statement_vals(self, cr, uid, profile_id, result_row_list,
|
||||||
@@ -160,14 +163,14 @@ class AccountStatementProfil(Model):
|
|||||||
prof_obj = self.pool['account.statement.profile']
|
prof_obj = self.pool['account.statement.profile']
|
||||||
if not profile_id:
|
if not profile_id:
|
||||||
raise osv.except_osv(_("No Profile!"),
|
raise osv.except_osv(_("No Profile!"),
|
||||||
_("You must provide a valid profile to import a bank statement!"))
|
_("You must provide a valid profile to import a bank statement!"))
|
||||||
prof = prof_obj.browse(cr, uid, profile_id, context=context)
|
prof = prof_obj.browse(cr, uid, profile_id, context=context)
|
||||||
|
|
||||||
parser = new_bank_statement_parser(prof, ftype=ftype)
|
parser = new_bank_statement_parser(prof, ftype=ftype)
|
||||||
res = []
|
res = []
|
||||||
for result_row_list in parser.parse(file_stream):
|
for result_row_list in parser.parse(file_stream):
|
||||||
statement_id = self._statement_import(cr, uid, ids, prof, parser,
|
statement_id = self._statement_import(cr, uid, ids, prof, parser,
|
||||||
file_stream, ftype=ftype, context=context)
|
file_stream, ftype=ftype, context=context)
|
||||||
res.append(statement_id)
|
res.append(statement_id)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -199,7 +202,8 @@ class AccountStatementProfil(Model):
|
|||||||
_("Column %s you try to import is not "
|
_("Column %s you try to import is not "
|
||||||
"present in the bank statement line!") % col)
|
"present in the bank statement line!") % col)
|
||||||
|
|
||||||
statement_vals = self.prepare_statement_vals(cr, uid, prof.id, result_row_list, parser, context)
|
statement_vals = self.prepare_statement_vals(
|
||||||
|
cr, uid, prof.id, result_row_list, parser, context)
|
||||||
statement_id = statement_obj.create(cr, uid,
|
statement_id = statement_obj.create(cr, uid,
|
||||||
statement_vals,
|
statement_vals,
|
||||||
context=context)
|
context=context)
|
||||||
@@ -214,7 +218,8 @@ class AccountStatementProfil(Model):
|
|||||||
context)
|
context)
|
||||||
statement_store.append(values)
|
statement_store.append(values)
|
||||||
# Hack to bypass ORM poor perfomance. Sob...
|
# Hack to bypass ORM poor perfomance. Sob...
|
||||||
statement_line_obj._insert_lines(cr, uid, statement_store, context=context)
|
statement_line_obj._insert_lines(
|
||||||
|
cr, uid, statement_store, context=context)
|
||||||
|
|
||||||
self._write_extra_statement_lines(
|
self._write_extra_statement_lines(
|
||||||
cr, uid, parser, result_row_list, prof, statement_id, context)
|
cr, uid, parser, result_row_list, prof, statement_id, context)
|
||||||
@@ -222,7 +227,8 @@ class AccountStatementProfil(Model):
|
|||||||
start_bal = statement_obj.read(
|
start_bal = statement_obj.read(
|
||||||
cr, uid, statement_id, ['balance_start'], context=context)
|
cr, uid, statement_id, ['balance_start'], context=context)
|
||||||
start_bal = start_bal['balance_start']
|
start_bal = start_bal['balance_start']
|
||||||
statement_obj.write(cr, uid, [statement_id], {'balance_start': start_bal})
|
statement_obj.write(
|
||||||
|
cr, uid, [statement_id], {'balance_start': start_bal})
|
||||||
|
|
||||||
attachment_data = {
|
attachment_data = {
|
||||||
'name': 'statement file',
|
'name': 'statement file',
|
||||||
@@ -235,7 +241,8 @@ class AccountStatementProfil(Model):
|
|||||||
|
|
||||||
# If user ask to launch completion at end of import, do it!
|
# If user ask to launch completion at end of import, do it!
|
||||||
if prof.launch_import_completion:
|
if prof.launch_import_completion:
|
||||||
statement_obj.button_auto_completion(cr, uid, [statement_id], context)
|
statement_obj.button_auto_completion(
|
||||||
|
cr, uid, [statement_id], context)
|
||||||
|
|
||||||
# Write the needed log infos on profile
|
# Write the needed log infos on profile
|
||||||
self.write_logs_after_import(cr, uid, prof.id,
|
self.write_logs_after_import(cr, uid, prof.id,
|
||||||
@@ -245,11 +252,12 @@ class AccountStatementProfil(Model):
|
|||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
error_type, error_value, trbk = sys.exc_info()
|
error_type, error_value, trbk = sys.exc_info()
|
||||||
st = "Error: %s\nDescription: %s\nTraceback:" % (error_type.__name__, error_value)
|
st = "Error: %s\nDescription: %s\nTraceback:" % (
|
||||||
|
error_type.__name__, error_value)
|
||||||
st += ''.join(traceback.format_tb(trbk, 30))
|
st += ''.join(traceback.format_tb(trbk, 30))
|
||||||
#TODO we should catch correctly the exception with a python
|
# TODO we should catch correctly the exception with a python
|
||||||
#Exception and only re-catch some special exception.
|
# Exception and only re-catch some special exception.
|
||||||
#For now we avoid re-catching error in debug mode
|
# For now we avoid re-catching error in debug mode
|
||||||
if config['debug_mode']:
|
if config['debug_mode']:
|
||||||
raise
|
raise
|
||||||
raise osv.except_osv(_("Statement import error"),
|
raise osv.except_osv(_("Statement import error"),
|
||||||
|
|||||||
@@ -31,8 +31,10 @@ class test_coda_import(common.TransactionCase):
|
|||||||
def prepare(self):
|
def prepare(self):
|
||||||
self.company_a = self.browse_ref('base.main_company')
|
self.company_a = self.browse_ref('base.main_company')
|
||||||
self.profile_obj = self.registry("account.statement.profile")
|
self.profile_obj = self.registry("account.statement.profile")
|
||||||
self.account_bank_statement_obj = self.registry("account.bank.statement")
|
self.account_bank_statement_obj = self.registry(
|
||||||
# create the 2009 fiscal year since imported coda file reference statement lines in 2009
|
"account.bank.statement")
|
||||||
|
# create the 2009 fiscal year since imported coda file reference
|
||||||
|
# statement lines in 2009
|
||||||
self.fiscalyear_id = self._create_fiscalyear("2011", self.company_a.id)
|
self.fiscalyear_id = self._create_fiscalyear("2011", self.company_a.id)
|
||||||
|
|
||||||
self.account_id = self.ref("account.a_recv")
|
self.account_id = self.ref("account.a_recv")
|
||||||
@@ -71,15 +73,18 @@ class test_coda_import(common.TransactionCase):
|
|||||||
'input_statement': base64.b64encode(content),
|
'input_statement': base64.b64encode(content),
|
||||||
'file_name': os.path.basename(file_name),
|
'file_name': os.path.basename(file_name),
|
||||||
})
|
})
|
||||||
res = self.import_wizard_obj.import_statement(self.cr, self.uid, wizard_id)
|
res = self.import_wizard_obj.import_statement(
|
||||||
statement_id = self.account_bank_statement_obj.search(self.cr, self.uid, eval(res['domain']))
|
self.cr, self.uid, wizard_id)
|
||||||
|
statement_id = self.account_bank_statement_obj.search(
|
||||||
|
self.cr, self.uid, eval(res['domain']))
|
||||||
return self.account_bank_statement_obj.browse(self.cr, self.uid, statement_id)[0]
|
return self.account_bank_statement_obj.browse(self.cr, self.uid, statement_id)[0]
|
||||||
|
|
||||||
def test_simple_xls(self):
|
def test_simple_xls(self):
|
||||||
"""Test import from xls
|
"""Test import from xls
|
||||||
"""
|
"""
|
||||||
self.prepare()
|
self.prepare()
|
||||||
file_name = self._filename_to_abs_filename(os.path.join("..", "data", "statement.xls"))
|
file_name = self._filename_to_abs_filename(
|
||||||
|
os.path.join("..", "data", "statement.xls"))
|
||||||
statement = self._import_file(file_name)
|
statement = self._import_file(file_name)
|
||||||
self._validate_imported_satement(statement)
|
self._validate_imported_satement(statement)
|
||||||
|
|
||||||
@@ -87,7 +92,8 @@ class test_coda_import(common.TransactionCase):
|
|||||||
"""Test import from csv
|
"""Test import from csv
|
||||||
"""
|
"""
|
||||||
self.prepare()
|
self.prepare()
|
||||||
file_name = self._filename_to_abs_filename(os.path.join("..", "data", "statement.csv"))
|
file_name = self._filename_to_abs_filename(
|
||||||
|
os.path.join("..", "data", "statement.csv"))
|
||||||
statement = self._import_file(file_name)
|
statement = self._import_file(file_name)
|
||||||
self._validate_imported_satement(statement)
|
self._validate_imported_satement(statement)
|
||||||
|
|
||||||
|
|||||||
@@ -37,11 +37,13 @@ class CreditPartnerStatementImporter(orm.TransientModel):
|
|||||||
context = {}
|
context = {}
|
||||||
res = {}
|
res = {}
|
||||||
if (context.get('active_model', False) == 'account.statement.profile' and
|
if (context.get('active_model', False) == 'account.statement.profile' and
|
||||||
context.get('active_ids', False)):
|
context.get('active_ids', False)):
|
||||||
ids = context['active_ids']
|
ids = context['active_ids']
|
||||||
assert len(ids) == 1, 'You cannot use this on more than one profile !'
|
assert len(
|
||||||
|
ids) == 1, 'You cannot use this on more than one profile !'
|
||||||
res['profile_id'] = ids[0]
|
res['profile_id'] = ids[0]
|
||||||
other_vals = self.onchange_profile_id(cr, uid, [], res['profile_id'], context=context)
|
other_vals = self.onchange_profile_id(
|
||||||
|
cr, uid, [], res['profile_id'], context=context)
|
||||||
res.update(other_vals.get('value', {}))
|
res.update(other_vals.get('value', {}))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -72,21 +74,21 @@ class CreditPartnerStatementImporter(orm.TransientModel):
|
|||||||
res = {}
|
res = {}
|
||||||
if profile_id:
|
if profile_id:
|
||||||
c = self.pool.get("account.statement.profile").browse(
|
c = self.pool.get("account.statement.profile").browse(
|
||||||
cr, uid, profile_id, context=context)
|
cr, uid, profile_id, context=context)
|
||||||
res = {'value':
|
res = {'value':
|
||||||
{'partner_id': c.partner_id and c.partner_id.id or False,
|
{'partner_id': c.partner_id and c.partner_id.id or False,
|
||||||
'journal_id': c.journal_id and c.journal_id.id or False,
|
'journal_id': c.journal_id and c.journal_id.id or False,
|
||||||
'receivable_account_id': c.receivable_account_id and c.receivable_account_id.id or False,
|
'receivable_account_id': c.receivable_account_id and c.receivable_account_id.id or False,
|
||||||
'force_partner_on_bank': c.force_partner_on_bank,
|
'force_partner_on_bank': c.force_partner_on_bank,
|
||||||
'balance_check': c.balance_check,
|
'balance_check': c.balance_check,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _check_extension(self, filename):
|
def _check_extension(self, filename):
|
||||||
(__, ftype) = os.path.splitext(filename)
|
(__, ftype) = os.path.splitext(filename)
|
||||||
if not ftype:
|
if not ftype:
|
||||||
#We do not use osv exception we do not want to have it logged
|
# We do not use osv exception we do not want to have it logged
|
||||||
raise Exception(_('Please use a file with an extention'))
|
raise Exception(_('Please use a file with an extention'))
|
||||||
return ftype
|
return ftype
|
||||||
|
|
||||||
@@ -99,18 +101,19 @@ class CreditPartnerStatementImporter(orm.TransientModel):
|
|||||||
ftype = self._check_extension(importer.file_name)
|
ftype = self._check_extension(importer.file_name)
|
||||||
context['file_name'] = importer.file_name
|
context['file_name'] = importer.file_name
|
||||||
sid = self.pool.get(
|
sid = self.pool.get(
|
||||||
'account.statement.profile').multi_statement_import(
|
'account.statement.profile').multi_statement_import(
|
||||||
cr,
|
cr,
|
||||||
uid,
|
uid,
|
||||||
False,
|
False,
|
||||||
importer.profile_id.id,
|
importer.profile_id.id,
|
||||||
importer.input_statement,
|
importer.input_statement,
|
||||||
ftype.replace('.', ''),
|
ftype.replace('.', ''),
|
||||||
context=context
|
context=context
|
||||||
)
|
)
|
||||||
model_obj = self.pool.get('ir.model.data')
|
model_obj = self.pool.get('ir.model.data')
|
||||||
action_obj = self.pool.get('ir.actions.act_window')
|
action_obj = self.pool.get('ir.actions.act_window')
|
||||||
action_id = model_obj.get_object_reference(cr, uid, 'account', 'action_bank_statement_tree')[1]
|
action_id = model_obj.get_object_reference(
|
||||||
|
cr, uid, 'account', 'action_bank_statement_tree')[1]
|
||||||
res = action_obj.read(cr, uid, action_id)
|
res = action_obj.read(cr, uid, action_id)
|
||||||
res['domain'] = res['domain'][:-1] + ",('id', 'in', %s)]" % sid
|
res['domain'] = res['domain'][:-1] + ",('id', 'in', %s)]" % sid
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class wizard_cancel_statement(orm.TransientModel):
|
|||||||
'Show reconcile warning',
|
'Show reconcile warning',
|
||||||
help='This is a hidden field set with a default in the context '
|
help='This is a hidden field set with a default in the context '
|
||||||
'to choose between two different warning messages in the view.'
|
'to choose between two different warning messages in the view.'
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def do_cancel_button(self, cr, uid, ids, context=None):
|
def do_cancel_button(self, cr, uid, ids, context=None):
|
||||||
|
|||||||
@@ -34,14 +34,14 @@
|
|||||||
This module brings commission support to bank statement imports. It computes the sum of a commission
|
This module brings commission support to bank statement imports. It computes the sum of a commission
|
||||||
field on each transaction and creates a statement entry for it.
|
field on each transaction and creates a statement entry for it.
|
||||||
""",
|
""",
|
||||||
'website': 'http://www.camptocamp.com',
|
'website': 'http://www.camptocamp.com',
|
||||||
'data': [
|
'data': [
|
||||||
"statement_view.xml",
|
"statement_view.xml",
|
||||||
"import_statement_view.xml",
|
"import_statement_view.xml",
|
||||||
],
|
],
|
||||||
'test': [],
|
'test': [],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ class AccountStatementProfil(orm.Model):
|
|||||||
"""
|
"""
|
||||||
global_commission_amount = 0
|
global_commission_amount = 0
|
||||||
for row in parser.result_row_list:
|
for row in parser.result_row_list:
|
||||||
global_commission_amount += float_or_zero(row.get('commission_amount', '0.0'))
|
global_commission_amount += float_or_zero(
|
||||||
|
row.get('commission_amount', '0.0'))
|
||||||
if not global_commission_amount:
|
if not global_commission_amount:
|
||||||
return
|
return
|
||||||
partner_id = profile.partner_id and profile.partner_id.id or False
|
partner_id = profile.partner_id and profile.partner_id.id or False
|
||||||
@@ -56,7 +57,7 @@ class CreditPartnerStatementImporter(orm.TransientModel):
|
|||||||
'commission_account_id': fields.many2one('account.account',
|
'commission_account_id': fields.many2one('account.account',
|
||||||
'Commission account'),
|
'Commission account'),
|
||||||
'commission_analytic_id': fields.many2one('account.analytic.account',
|
'commission_analytic_id': fields.many2one('account.analytic.account',
|
||||||
'Commission analytic account'),
|
'Commission analytic account'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def onchange_profile_id(self, cr, uid, ids, profile_id, context=None):
|
def onchange_profile_id(self, cr, uid, ids, profile_id, context=None):
|
||||||
@@ -64,7 +65,7 @@ class CreditPartnerStatementImporter(orm.TransientModel):
|
|||||||
cr, uid, ids, profile_id, context=context)
|
cr, uid, ids, profile_id, context=context)
|
||||||
if profile_id:
|
if profile_id:
|
||||||
c = self.pool.get("account.statement.profile").browse(
|
c = self.pool.get("account.statement.profile").browse(
|
||||||
cr, uid, profile_id, context=context)
|
cr, uid, profile_id, context=context)
|
||||||
res['value']['commission_account_id'] = \
|
res['value']['commission_account_id'] = \
|
||||||
c.commission_account_id and c.commission_account_id.id or False
|
c.commission_account_id and c.commission_account_id.id or False
|
||||||
res['value']['commission_a'] = \
|
res['value']['commission_a'] = \
|
||||||
|
|||||||
@@ -22,4 +22,3 @@
|
|||||||
|
|
||||||
from . import partner
|
from . import partner
|
||||||
from . import statement
|
from . import statement
|
||||||
|
|
||||||
|
|||||||
@@ -37,13 +37,12 @@
|
|||||||
'website': 'http://www.akretion.com/',
|
'website': 'http://www.akretion.com/',
|
||||||
'depends': ['account_statement_base_completion'],
|
'depends': ['account_statement_base_completion'],
|
||||||
'data': [
|
'data': [
|
||||||
'partner_view.xml',
|
'partner_view.xml',
|
||||||
'statement_view.xml',
|
'statement_view.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'security/ir_rule.xml',
|
'security/ir_rule.xml',
|
||||||
],
|
],
|
||||||
'demo': [],
|
'demo': [],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'active': False,
|
'active': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,10 +26,12 @@ from openerp.addons.account_statement_base_completion.statement import ErrorTooM
|
|||||||
|
|
||||||
|
|
||||||
class ErrorTooManyLabel(Exception):
|
class ErrorTooManyLabel(Exception):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
New Exception definition that is raised when more than one label is matched
|
New Exception definition that is raised when more than one label is matched
|
||||||
by the completion rule.
|
by the completion rule.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
@@ -38,6 +40,7 @@ class ErrorTooManyLabel(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class AccountBankSatement(orm.Model):
|
class AccountBankSatement(orm.Model):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
We add a basic button and stuff to support the auto-completion
|
We add a basic button and stuff to support the auto-completion
|
||||||
of the bank statement once line have been imported or manually fullfill.
|
of the bank statement once line have been imported or manually fullfill.
|
||||||
@@ -76,7 +79,7 @@ class AccountStatementCompletionRule(orm.Model):
|
|||||||
...}
|
...}
|
||||||
"""
|
"""
|
||||||
st_obj = self.pool.get('account.bank.statement')
|
st_obj = self.pool.get('account.bank.statement')
|
||||||
statement = st_obj.browse(cr, uid, st_line['statement_id'][0],
|
statement = st_obj.browse(cr, uid, st_line['statement_id'][0],
|
||||||
context=context)
|
context=context)
|
||||||
res = {}
|
res = {}
|
||||||
if not context.get('label_memorizer'):
|
if not context.get('label_memorizer'):
|
||||||
@@ -114,6 +117,7 @@ class AccountStatementCompletionRule(orm.Model):
|
|||||||
|
|
||||||
|
|
||||||
class AccountStatementLabel(orm.Model):
|
class AccountStatementLabel(orm.Model):
|
||||||
|
|
||||||
"""Create a new class to map an account statement label to a partner
|
"""Create a new class to map an account statement label to a partner
|
||||||
and a specific account
|
and a specific account
|
||||||
"""
|
"""
|
||||||
@@ -125,7 +129,7 @@ class AccountStatementLabel(orm.Model):
|
|||||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||||
'label': fields.char('Bank Statement Label', size=100),
|
'label': fields.char('Bank Statement Label', size=100),
|
||||||
'account_id': fields.many2one('account.account', 'Account',
|
'account_id': fields.many2one('account.account', 'Account',
|
||||||
required = True,
|
required=True,
|
||||||
help='Account corresponding to the label '
|
help='Account corresponding to the label '
|
||||||
'for a given partner'),
|
'for a given partner'),
|
||||||
'company_id': fields.related('account_id', 'company_id',
|
'company_id': fields.related('account_id', 'company_id',
|
||||||
@@ -139,7 +143,7 @@ class AccountStatementLabel(orm.Model):
|
|||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'company_id': lambda s,cr,uid,c:
|
'company_id': lambda s, cr, uid, c:
|
||||||
s.pool.get('res.company')._company_default_get(cr, uid,
|
s.pool.get('res.company')._company_default_get(cr, uid,
|
||||||
'account.statement.label',
|
'account.statement.label',
|
||||||
context=c),
|
context=c),
|
||||||
|
|||||||
@@ -28,14 +28,14 @@
|
|||||||
'depends': [
|
'depends': [
|
||||||
'account_statement_base_completion',
|
'account_statement_base_completion',
|
||||||
'account_voucher'
|
'account_voucher'
|
||||||
],
|
],
|
||||||
'description': """
|
'description': """
|
||||||
This module is only needed when using account_statement_base_completion with voucher in order adapt the view correctly.
|
This module is only needed when using account_statement_base_completion with voucher in order adapt the view correctly.
|
||||||
""",
|
""",
|
||||||
'website': 'http://www.camptocamp.com',
|
'website': 'http://www.camptocamp.com',
|
||||||
'init_xml': [],
|
'init_xml': [],
|
||||||
'update_xml': [
|
'update_xml': [
|
||||||
"statement_view.xml",
|
"statement_view.xml",
|
||||||
],
|
],
|
||||||
'demo_xml': [],
|
'demo_xml': [],
|
||||||
'test': [],
|
'test': [],
|
||||||
@@ -43,4 +43,4 @@
|
|||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,4 +22,4 @@
|
|||||||
import statement
|
import statement
|
||||||
import report
|
import report
|
||||||
import account
|
import account
|
||||||
import voucher
|
import voucher
|
||||||
|
|||||||
@@ -28,15 +28,17 @@ from openerp.addons.report_webkit import webkit_report
|
|||||||
class BankStatementWebkit(report_sxw.rml_parse):
|
class BankStatementWebkit(report_sxw.rml_parse):
|
||||||
|
|
||||||
def __init__(self, cr, uid, name, context):
|
def __init__(self, cr, uid, name, context):
|
||||||
super(BankStatementWebkit, self).__init__(cr, uid, name, context=context)
|
super(BankStatementWebkit, self).__init__(
|
||||||
|
cr, uid, name, context=context)
|
||||||
self.pool = pooler.get_pool(self.cr.dbname)
|
self.pool = pooler.get_pool(self.cr.dbname)
|
||||||
self.cursor = self.cr
|
self.cursor = self.cr
|
||||||
|
|
||||||
company = self.pool.get('res.users').browse(
|
company = self.pool.get('res.users').browse(
|
||||||
self.cr, uid, uid, context=context).company_id
|
self.cr, uid, uid, context=context).company_id
|
||||||
header_report_name = ' - '.join((_('BORDEREAU DE REMISE DE CHEQUES'),
|
header_report_name = ' - '.join((_('BORDEREAU DE REMISE DE CHEQUES'),
|
||||||
company.name, company.currency_id.name))
|
company.name, company.currency_id.name))
|
||||||
footer_date_time = self.formatLang(str(datetime.today())[:19], date_time=True)
|
footer_date_time = self.formatLang(
|
||||||
|
str(datetime.today())[:19], date_time=True)
|
||||||
self.localcontext.update({
|
self.localcontext.update({
|
||||||
'cr': cr,
|
'cr': cr,
|
||||||
'uid': uid,
|
'uid': uid,
|
||||||
@@ -50,7 +52,8 @@ class BankStatementWebkit(report_sxw.rml_parse):
|
|||||||
('--header-left', header_report_name),
|
('--header-left', header_report_name),
|
||||||
('--header-spacing', '2'),
|
('--header-spacing', '2'),
|
||||||
('--footer-left', footer_date_time),
|
('--footer-left', footer_date_time),
|
||||||
('--footer-right', ' '.join((_('Page'), '[page]', _('of'), '[topage]'))),
|
('--footer-right',
|
||||||
|
' '.join((_('Page'), '[page]', _('of'), '[topage]'))),
|
||||||
('--footer-line',),
|
('--footer-line',),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@@ -58,11 +61,11 @@ class BankStatementWebkit(report_sxw.rml_parse):
|
|||||||
def _get_bank_statement_data(self, statement):
|
def _get_bank_statement_data(self, statement):
|
||||||
statement_obj = self.pool.get('account.bank.statement.line')
|
statement_obj = self.pool.get('account.bank.statement.line')
|
||||||
statement_line_ids = statement_obj.search(
|
statement_line_ids = statement_obj.search(
|
||||||
self.cr,
|
self.cr,
|
||||||
self.uid,
|
self.uid,
|
||||||
[('statement_id', '=', statement.id)])
|
[('statement_id', '=', statement.id)])
|
||||||
statement_lines = statement_obj.browse(
|
statement_lines = statement_obj.browse(
|
||||||
self.cr, self.uid, statement_line_ids)
|
self.cr, self.uid, statement_line_ids)
|
||||||
return statement_lines
|
return statement_lines
|
||||||
|
|
||||||
webkit_report.WebKitParser('report.bank_statement_webkit',
|
webkit_report.WebKitParser('report.bank_statement_webkit',
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ def fixed_write(self, cr, uid, ids, vals, context=None):
|
|||||||
I will do it when I have time."""
|
I will do it when I have time."""
|
||||||
res = super(stat_mod.account_bank_statement, self).write(cr, uid, ids,
|
res = super(stat_mod.account_bank_statement, self).write(cr, uid, ids,
|
||||||
vals, context=context)
|
vals, context=context)
|
||||||
if ids: # will be false for an new empty bank statement
|
if ids: # will be false for an new empty bank statement
|
||||||
cr.execute("UPDATE account_bank_statement_line"
|
cr.execute("UPDATE account_bank_statement_line"
|
||||||
" SET sequence = account_bank_statement_line.id + 1"
|
" SET sequence = account_bank_statement_line.id + 1"
|
||||||
" where statement_id in %s", (tuple(ids),))
|
" where statement_id in %s", (tuple(ids),))
|
||||||
@@ -40,6 +40,7 @@ stat_mod.account_bank_statement.write = fixed_write
|
|||||||
|
|
||||||
|
|
||||||
class AccountStatementProfile(Model):
|
class AccountStatementProfile(Model):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
A Profile will contain all infos related to the type of
|
A Profile will contain all infos related to the type of
|
||||||
bank statement, and related generated entries. It defines the
|
bank statement, and related generated entries. It defines the
|
||||||
@@ -57,20 +58,20 @@ class AccountStatementProfile(Model):
|
|||||||
'partner_id': fields.many2one(
|
'partner_id': fields.many2one(
|
||||||
'res.partner',
|
'res.partner',
|
||||||
'Bank/Payment Office partner',
|
'Bank/Payment Office partner',
|
||||||
help="Put a partner if you want to have it on the "
|
help="Put a partner if you want to have it on the "
|
||||||
"commission move (and optionaly on the counterpart "
|
"commission move (and optionaly on the counterpart "
|
||||||
"of the intermediate/banking move if you tick the "
|
"of the intermediate/banking move if you tick the "
|
||||||
"corresponding checkbox)."),
|
"corresponding checkbox)."),
|
||||||
|
|
||||||
'journal_id': fields.many2one(
|
'journal_id': fields.many2one(
|
||||||
'account.journal',
|
'account.journal',
|
||||||
'Financial journal to use for transaction',
|
'Financial journal to use for transaction',
|
||||||
required=True),
|
required=True),
|
||||||
|
|
||||||
'commission_account_id': fields.many2one(
|
'commission_account_id': fields.many2one(
|
||||||
'account.account',
|
'account.account',
|
||||||
'Commission account',
|
'Commission account',
|
||||||
required=True),
|
required=True),
|
||||||
|
|
||||||
'commission_analytic_id': fields.many2one(
|
'commission_analytic_id': fields.many2one(
|
||||||
'account.analytic.account',
|
'account.analytic.account',
|
||||||
@@ -110,16 +111,18 @@ class AccountStatementProfile(Model):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
_constraints = [
|
_constraints = [
|
||||||
(_check_partner, "You need to put a partner if you tic the 'Force partner on bank move'!", []),
|
(_check_partner,
|
||||||
|
"You need to put a partner if you tic the 'Force partner on bank move'!", []),
|
||||||
]
|
]
|
||||||
|
|
||||||
_sql_constraints = [
|
_sql_constraints = [
|
||||||
('name_uniq', 'unique (name, company_id)', 'The name of the bank statement must be unique !')
|
('name_uniq', 'unique (name, company_id)',
|
||||||
|
'The name of the bank statement must be unique !')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AccountBankStatement(Model):
|
class AccountBankStatement(Model):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
We improve the bank statement class mostly for :
|
We improve the bank statement class mostly for :
|
||||||
- Removing the period and compute it from the date of each line.
|
- Removing the period and compute it from the date of each line.
|
||||||
@@ -140,7 +143,8 @@ class AccountBankStatement(Model):
|
|||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
period_obj = self.pool.get('account.period')
|
period_obj = self.pool.get('account.period')
|
||||||
periods = period_obj.find(cr, uid, dt=context.get('date'), context=context)
|
periods = period_obj.find(
|
||||||
|
cr, uid, dt=context.get('date'), context=context)
|
||||||
return periods and periods[0] or False
|
return periods and periods[0] or False
|
||||||
|
|
||||||
def _default_profile(self, cr, uid, context=None):
|
def _default_profile(self, cr, uid, context=None):
|
||||||
@@ -155,7 +159,8 @@ class AccountBankStatement(Model):
|
|||||||
user_obj = self.pool.get('res.users')
|
user_obj = self.pool.get('res.users')
|
||||||
profile_obj = self.pool.get('account.statement.profile')
|
profile_obj = self.pool.get('account.statement.profile')
|
||||||
user = user_obj.browse(cr, uid, uid, context=context)
|
user = user_obj.browse(cr, uid, uid, context=context)
|
||||||
profile_ids = profile_obj.search(cr, uid, [('company_id', '=', user.company_id.id)], context=context)
|
profile_ids = profile_obj.search(
|
||||||
|
cr, uid, [('company_id', '=', user.company_id.id)], context=context)
|
||||||
|
|
||||||
return profile_ids[0] if profile_ids else False
|
return profile_ids[0] if profile_ids else False
|
||||||
|
|
||||||
@@ -219,11 +224,11 @@ class AccountBankStatement(Model):
|
|||||||
},
|
},
|
||||||
readonly=True),
|
readonly=True),
|
||||||
'period_id': fields.many2one(
|
'period_id': fields.many2one(
|
||||||
'account.period',
|
'account.period',
|
||||||
'Period',
|
'Period',
|
||||||
required=False,
|
required=False,
|
||||||
readonly=False,
|
readonly=False,
|
||||||
invisible=True),
|
invisible=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
@@ -236,7 +241,8 @@ class AccountBankStatement(Model):
|
|||||||
need it."""
|
need it."""
|
||||||
if 'profile_id' in vals:
|
if 'profile_id' in vals:
|
||||||
profile_obj = self.pool.get('account.statement.profile')
|
profile_obj = self.pool.get('account.statement.profile')
|
||||||
profile = profile_obj.browse(cr, uid, vals['profile_id'], context=context)
|
profile = profile_obj.browse(
|
||||||
|
cr, uid, vals['profile_id'], context=context)
|
||||||
vals['journal_id'] = profile.journal_id.id
|
vals['journal_id'] = profile.journal_id.id
|
||||||
return super(AccountBankStatement, self
|
return super(AccountBankStatement, self
|
||||||
).create(cr, uid, vals, context=context)
|
).create(cr, uid, vals, context=context)
|
||||||
@@ -319,12 +325,12 @@ class AccountBankStatement(Model):
|
|||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
res = super(AccountBankStatement, self)._prepare_move_line_vals(
|
res = super(AccountBankStatement, self)._prepare_move_line_vals(
|
||||||
cr, uid, st_line, move_id, debit, credit,
|
cr, uid, st_line, move_id, debit, credit,
|
||||||
currency_id=currency_id,
|
currency_id=currency_id,
|
||||||
amount_currency=amount_currency,
|
amount_currency=amount_currency,
|
||||||
account_id=account_id,
|
account_id=account_id,
|
||||||
analytic_id=analytic_id,
|
analytic_id=analytic_id,
|
||||||
partner_id=partner_id, context=context)
|
partner_id=partner_id, context=context)
|
||||||
ctx = context.copy()
|
ctx = context.copy()
|
||||||
ctx['company_id'] = st_line.company_id.id
|
ctx['company_id'] = st_line.company_id.id
|
||||||
period_id = self._get_period(cr, uid, st_line.date, context=ctx)
|
period_id = self._get_period(cr, uid, st_line.date, context=ctx)
|
||||||
@@ -362,16 +368,19 @@ class AccountBankStatement(Model):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
year = self.pool.get('account.period').browse(
|
year = self.pool.get('account.period').browse(
|
||||||
cr, uid, self._get_period(cr, uid, date)).fiscalyear_id.id
|
cr, uid, self._get_period(cr, uid, date)).fiscalyear_id.id
|
||||||
profile = self.pool.get('account.statement.profile').browse(cr, uid, profile_id)
|
profile = self.pool.get(
|
||||||
|
'account.statement.profile').browse(cr, uid, profile_id)
|
||||||
c = {'fiscalyear_id': year}
|
c = {'fiscalyear_id': year}
|
||||||
obj_seq = self.pool.get('ir.sequence')
|
obj_seq = self.pool.get('ir.sequence')
|
||||||
journal_sequence_id = (profile.journal_id.sequence_id and
|
journal_sequence_id = (profile.journal_id.sequence_id and
|
||||||
profile.journal_id.sequence_id.id or False)
|
profile.journal_id.sequence_id.id or False)
|
||||||
if journal_sequence_id:
|
if journal_sequence_id:
|
||||||
st_number = obj_seq.next_by_id(cr, uid, journal_sequence_id, context=c)
|
st_number = obj_seq.next_by_id(
|
||||||
|
cr, uid, journal_sequence_id, context=c)
|
||||||
else:
|
else:
|
||||||
st_number = obj_seq.next_by_code(cr, uid, 'account.bank.statement', context=c)
|
st_number = obj_seq.next_by_code(
|
||||||
|
cr, uid, 'account.bank.statement', context=c)
|
||||||
if profile.bank_statement_prefix:
|
if profile.bank_statement_prefix:
|
||||||
st_number = profile.bank_statement_prefix + st_number
|
st_number = profile.bank_statement_prefix + st_number
|
||||||
return st_number
|
return st_number
|
||||||
@@ -393,7 +402,8 @@ class AccountBankStatement(Model):
|
|||||||
if not self.check_status_condition(cr, uid, st.state, journal_type=j_type):
|
if not self.check_status_condition(cr, uid, st.state, journal_type=j_type):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.balance_check(cr, uid, st.id, journal_type=j_type, context=context)
|
self.balance_check(
|
||||||
|
cr, uid, st.id, journal_type=j_type, context=context)
|
||||||
if (not st.journal_id.default_credit_account_id) \
|
if (not st.journal_id.default_credit_account_id) \
|
||||||
or (not st.journal_id.default_debit_account_id):
|
or (not st.journal_id.default_debit_account_id):
|
||||||
raise osv.except_osv(_('Configuration Error!'),
|
raise osv.except_osv(_('Configuration Error!'),
|
||||||
@@ -402,8 +412,9 @@ class AccountBankStatement(Model):
|
|||||||
if not st.name == '/':
|
if not st.name == '/':
|
||||||
st_number = st.name
|
st_number = st.name
|
||||||
else:
|
else:
|
||||||
# Begin Changes
|
# Begin Changes
|
||||||
st_number = self._get_st_number_period_profile(cr, uid, st.date, st.profile_id.id)
|
st_number = self._get_st_number_period_profile(
|
||||||
|
cr, uid, st.date, st.profile_id.id)
|
||||||
# End Changes
|
# End Changes
|
||||||
for line in st.move_line_ids:
|
for line in st.move_line_ids:
|
||||||
if line.state != 'valid':
|
if line.state != 'valid':
|
||||||
@@ -420,16 +431,19 @@ class AccountBankStatement(Model):
|
|||||||
" journal on the '%s' journal!") % st.journal_id.name)
|
" journal on the '%s' journal!") % st.journal_id.name)
|
||||||
if not st_line.amount:
|
if not st_line.amount:
|
||||||
continue
|
continue
|
||||||
st_line_number = self.get_next_st_line_number(cr, uid, st_number, st_line, context)
|
st_line_number = self.get_next_st_line_number(
|
||||||
|
cr, uid, st_number, st_line, context)
|
||||||
self.create_move_from_st_line(cr, uid, st_line.id,
|
self.create_move_from_st_line(cr, uid, st_line.id,
|
||||||
company_currency_id,
|
company_currency_id,
|
||||||
st_line_number,
|
st_line_number,
|
||||||
context)
|
context)
|
||||||
except osv.except_osv, exc:
|
except osv.except_osv, exc:
|
||||||
msg = "Line ID %s with ref %s had following error: %s" % (st_line.id, st_line.ref, exc.value)
|
msg = "Line ID %s with ref %s had following error: %s" % (
|
||||||
|
st_line.id, st_line.ref, exc.value)
|
||||||
errors_stack.append(msg)
|
errors_stack.append(msg)
|
||||||
except Exception, exc:
|
except Exception, exc:
|
||||||
msg = "Line ID %s with ref %s had following error: %s" % (st_line.id, st_line.ref, str(exc))
|
msg = "Line ID %s with ref %s had following error: %s" % (
|
||||||
|
st_line.id, st_line.ref, str(exc))
|
||||||
errors_stack.append(msg)
|
errors_stack.append(msg)
|
||||||
if errors_stack:
|
if errors_stack:
|
||||||
msg = u"\n".join(errors_stack)
|
msg = u"\n".join(errors_stack)
|
||||||
@@ -439,7 +453,8 @@ class AccountBankStatement(Model):
|
|||||||
{'name': st_number,
|
{'name': st_number,
|
||||||
'balance_end_real': st.balance_end},
|
'balance_end_real': st.balance_end},
|
||||||
context=context)
|
context=context)
|
||||||
body = _('Statement %s confirmed, journal items were created.') % st_number
|
body = _(
|
||||||
|
'Statement %s confirmed, journal items were created.') % st_number
|
||||||
self.message_post(cr, uid, [st.id],
|
self.message_post(cr, uid, [st.id],
|
||||||
body,
|
body,
|
||||||
context=context)
|
context=context)
|
||||||
@@ -515,7 +530,8 @@ class AccountBankStatement(Model):
|
|||||||
as 'customer' or 'supplier'.
|
as 'customer' or 'supplier'.
|
||||||
"""
|
"""
|
||||||
account_id = False
|
account_id = False
|
||||||
ltype = self.get_type_for_counterpart(cr, uid, amount, partner_id=partner_id)
|
ltype = self.get_type_for_counterpart(
|
||||||
|
cr, uid, amount, partner_id=partner_id)
|
||||||
if ltype == 'supplier':
|
if ltype == 'supplier':
|
||||||
account_id = account_payable
|
account_id = account_payable
|
||||||
else:
|
else:
|
||||||
@@ -574,13 +590,14 @@ class AccountBankStatement(Model):
|
|||||||
if not profile_id:
|
if not profile_id:
|
||||||
return {}
|
return {}
|
||||||
import_config = self.pool.get("account.statement.profile").browse(
|
import_config = self.pool.get("account.statement.profile").browse(
|
||||||
cr, uid, profile_id, context=context)
|
cr, uid, profile_id, context=context)
|
||||||
journal_id = import_config.journal_id.id
|
journal_id = import_config.journal_id.id
|
||||||
return {'value': {'journal_id': journal_id,
|
return {'value': {'journal_id': journal_id,
|
||||||
'balance_check': import_config.balance_check}}
|
'balance_check': import_config.balance_check}}
|
||||||
|
|
||||||
|
|
||||||
class AccountBankStatementLine(Model):
|
class AccountBankStatementLine(Model):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Override to compute the period from the date of the line, add a method to retrieve
|
Override to compute the period from the date of the line, add a method to retrieve
|
||||||
the values for a line from the profile. Override the on_change method to take care of
|
the values for a line from the profile. Override the on_change method to take care of
|
||||||
@@ -663,7 +680,7 @@ class AccountBankStatementLine(Model):
|
|||||||
# on profile
|
# on profile
|
||||||
if profile_id and master_account_id is None:
|
if profile_id and master_account_id is None:
|
||||||
profile = self.pool.get("account.statement.profile").browse(
|
profile = self.pool.get("account.statement.profile").browse(
|
||||||
cr, uid, profile_id, context=context)
|
cr, uid, profile_id, context=context)
|
||||||
if profile.receivable_account_id:
|
if profile.receivable_account_id:
|
||||||
res['account_id'] = profile.receivable_account_id.id
|
res['account_id'] = profile.receivable_account_id.id
|
||||||
# We return general as default instead of get_type_for_counterpart
|
# We return general as default instead of get_type_for_counterpart
|
||||||
@@ -684,7 +701,8 @@ class AccountBankStatementLine(Model):
|
|||||||
receiv_account = part.property_account_receivable.id
|
receiv_account = part.property_account_receivable.id
|
||||||
# If no value, look on the default company property
|
# If no value, look on the default company property
|
||||||
if not pay_account or not receiv_account:
|
if not pay_account or not receiv_account:
|
||||||
receiv_account, pay_account = obj_stat.get_default_pay_receiv_accounts(cr, uid, context=None)
|
receiv_account, pay_account = obj_stat.get_default_pay_receiv_accounts(
|
||||||
|
cr, uid, context=None)
|
||||||
account_id, comp_line_type = obj_stat.get_account_and_type_for_counterpart(cr, uid, amount,
|
account_id, comp_line_type = obj_stat.get_account_and_type_for_counterpart(cr, uid, amount,
|
||||||
receiv_account, pay_account,
|
receiv_account, pay_account,
|
||||||
partner_id=partner_id)
|
partner_id=partner_id)
|
||||||
@@ -702,8 +720,10 @@ class AccountBankStatementLine(Model):
|
|||||||
obj_stat = self.pool.get('account.bank.statement')
|
obj_stat = self.pool.get('account.bank.statement')
|
||||||
if not partner_id:
|
if not partner_id:
|
||||||
return {}
|
return {}
|
||||||
line_type = obj_stat.get_type_for_counterpart(cr, uid, 0.0, partner_id=partner_id)
|
line_type = obj_stat.get_type_for_counterpart(
|
||||||
res_type = self.onchange_type(cr, uid, ids, partner_id, line_type, profile_id, context=context)
|
cr, uid, 0.0, partner_id=partner_id)
|
||||||
|
res_type = self.onchange_type(
|
||||||
|
cr, uid, ids, partner_id, line_type, profile_id, context=context)
|
||||||
if res_type['value'] and res_type['value'].get('account_id', False):
|
if res_type['value'] and res_type['value'].get('account_id', False):
|
||||||
return {'value': {'type': line_type,
|
return {'value': {'type': line_type,
|
||||||
'account_id': res_type['value']['account_id'],
|
'account_id': res_type['value']['account_id'],
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ class AccountVoucher(Model):
|
|||||||
"""If period not in context, take it from the move lines"""
|
"""If period not in context, take it from the move lines"""
|
||||||
if not context.get('period_id') and context.get('move_line_ids'):
|
if not context.get('period_id') and context.get('move_line_ids'):
|
||||||
res = self.pool.get('account.move.line').browse(
|
res = self.pool.get('account.move.line').browse(
|
||||||
cr, uid, context.get('move_line_ids'), context=context)[0].period_id.id
|
cr, uid, context.get('move_line_ids'), context=context)[0].period_id.id
|
||||||
context['period_id'] = res
|
context['period_id'] = res
|
||||||
elif context.get('date'):
|
elif context.get('date'):
|
||||||
periods = self.pool.get('account.period').find(
|
periods = self.pool.get('account.period').find(
|
||||||
cr, uid, dt=context['date'], context=context)
|
cr, uid, dt=context['date'], context=context)
|
||||||
if periods:
|
if periods:
|
||||||
context['period_id'] = periods[0]
|
context['period_id'] = periods[0]
|
||||||
return super(AccountVoucher, self)._get_period(cr, uid, context)
|
return super(AccountVoucher, self)._get_period(cr, uid, context)
|
||||||
|
|||||||
@@ -36,18 +36,19 @@ if not hasattr(std_pos_session, '_prepare_bank_statement'):
|
|||||||
# This change has been proposed for merging to fix lp:125375
|
# This change has been proposed for merging to fix lp:125375
|
||||||
def mp_prepare_bank_statement(self, cr, uid, pos_config, journal, context=None):
|
def mp_prepare_bank_statement(self, cr, uid, pos_config, journal, context=None):
|
||||||
bank_values = {
|
bank_values = {
|
||||||
'journal_id' : journal.id,
|
'journal_id': journal.id,
|
||||||
'user_id' : uid,
|
'user_id': uid,
|
||||||
'company_id' : pos_config.shop_id.company_id.id
|
'company_id': pos_config.shop_id.company_id.id
|
||||||
}
|
}
|
||||||
return bank_values
|
return bank_values
|
||||||
|
|
||||||
def mp_create(self, cr, uid, values, context=None):
|
def mp_create(self, cr, uid, values, context=None):
|
||||||
context = context or {}
|
context = context or {}
|
||||||
config_id = values.get('config_id', False) or context.get('default_config_id', False)
|
config_id = values.get('config_id', False) or context.get(
|
||||||
|
'default_config_id', False)
|
||||||
if not config_id:
|
if not config_id:
|
||||||
raise osv.except_osv( _('Error!'),
|
raise osv.except_osv(_('Error!'),
|
||||||
_("You should assign a Point of Sale to your session."))
|
_("You should assign a Point of Sale to your session."))
|
||||||
|
|
||||||
# journal_id is not required on the pos_config because it does not
|
# journal_id is not required on the pos_config because it does not
|
||||||
# exists at the installation. If nothing is configured at the
|
# exists at the installation. If nothing is configured at the
|
||||||
@@ -57,35 +58,42 @@ if not hasattr(std_pos_session, '_prepare_bank_statement'):
|
|||||||
pos_config = jobj.browse(cr, uid, config_id, context=context)
|
pos_config = jobj.browse(cr, uid, config_id, context=context)
|
||||||
context.update({'company_id': pos_config.shop_id.company_id.id})
|
context.update({'company_id': pos_config.shop_id.company_id.id})
|
||||||
if not pos_config.journal_id:
|
if not pos_config.journal_id:
|
||||||
jid = jobj.default_get(cr, uid, ['journal_id'], context=context)['journal_id']
|
jid = jobj.default_get(
|
||||||
|
cr, uid, ['journal_id'], context=context)['journal_id']
|
||||||
if jid:
|
if jid:
|
||||||
jobj.write(cr, uid, [pos_config.id], {'journal_id': jid}, context=context)
|
jobj.write(
|
||||||
|
cr, uid, [pos_config.id], {'journal_id': jid}, context=context)
|
||||||
else:
|
else:
|
||||||
raise osv.except_osv( _('error!'),
|
raise osv.except_osv(_('error!'),
|
||||||
_("Unable to open the session. You have to assign a sale journal to your point of sale."))
|
_("Unable to open the session. You have to assign a sale journal to your point of sale."))
|
||||||
|
|
||||||
# define some cash journal if no payment method exists
|
# define some cash journal if no payment method exists
|
||||||
if not pos_config.journal_ids:
|
if not pos_config.journal_ids:
|
||||||
journal_proxy = self.pool.get('account.journal')
|
journal_proxy = self.pool.get('account.journal')
|
||||||
cashids = journal_proxy.search(cr, uid, [('journal_user', '=', True), ('type','=','cash')], context=context)
|
cashids = journal_proxy.search(
|
||||||
|
cr, uid, [('journal_user', '=', True), ('type', '=', 'cash')], context=context)
|
||||||
if not cashids:
|
if not cashids:
|
||||||
cashids = journal_proxy.search(cr, uid, [('type', '=', 'cash')], context=context)
|
cashids = journal_proxy.search(
|
||||||
|
cr, uid, [('type', '=', 'cash')], context=context)
|
||||||
if not cashids:
|
if not cashids:
|
||||||
cashids = journal_proxy.search(cr, uid, [('journal_user','=',True)], context=context)
|
cashids = journal_proxy.search(
|
||||||
|
cr, uid, [('journal_user', '=', True)], context=context)
|
||||||
jobj.write(cr, uid, [pos_config.id], {'journal_ids': [(6,0, cashids)]})
|
|
||||||
|
|
||||||
|
jobj.write(
|
||||||
|
cr, uid, [pos_config.id], {'journal_ids': [(6, 0, cashids)]})
|
||||||
|
|
||||||
pos_config = jobj.browse(cr, uid, config_id, context=context)
|
pos_config = jobj.browse(cr, uid, config_id, context=context)
|
||||||
bank_statement_ids = []
|
bank_statement_ids = []
|
||||||
for journal in pos_config.journal_ids:
|
for journal in pos_config.journal_ids:
|
||||||
bank_values = self._prepare_bank_statement(cr, uid, pos_config, journal, context)
|
bank_values = self._prepare_bank_statement(
|
||||||
statement_id = self.pool.get('account.bank.statement').create(cr, uid, bank_values, context=context)
|
cr, uid, pos_config, journal, context)
|
||||||
|
statement_id = self.pool.get('account.bank.statement').create(
|
||||||
|
cr, uid, bank_values, context=context)
|
||||||
bank_statement_ids.append(statement_id)
|
bank_statement_ids.append(statement_id)
|
||||||
|
|
||||||
values.update({
|
values.update({
|
||||||
'name' : pos_config.sequence_id._next(),
|
'name': pos_config.sequence_id._next(),
|
||||||
'statement_ids' : [(6, 0, bank_statement_ids)],
|
'statement_ids': [(6, 0, bank_statement_ids)],
|
||||||
'config_id': config_id
|
'config_id': config_id
|
||||||
})
|
})
|
||||||
return super(std_pos_session, self).create(cr, uid, values, context=context)
|
return super(std_pos_session, self).create(cr, uid, values, context=context)
|
||||||
@@ -111,7 +119,8 @@ class pos_session(orm.Model):
|
|||||||
profile_obj = self.pool.get('account.statement.profile')
|
profile_obj = self.pool.get('account.statement.profile')
|
||||||
user = user_obj.browse(cr, uid, uid, context=context)
|
user = user_obj.browse(cr, uid, uid, context=context)
|
||||||
defaults = self.pool['account.bank.statement'].default_get(cr, uid,
|
defaults = self.pool['account.bank.statement'].default_get(cr, uid,
|
||||||
['profile_id', 'period_id'],
|
['profile_id',
|
||||||
|
'period_id'],
|
||||||
context=context)
|
context=context)
|
||||||
profile_ids = profile_obj.search(cr, uid,
|
profile_ids = profile_obj.search(cr, uid,
|
||||||
[('company_id', '=', user.company_id.id),
|
[('company_id', '=', user.company_id.id),
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
'depends': [
|
'depends': [
|
||||||
'account_statement_ext',
|
'account_statement_ext',
|
||||||
'account_voucher'
|
'account_voucher'
|
||||||
],
|
],
|
||||||
'description': """
|
'description': """
|
||||||
This module is deprecated. It was only needed when using account_bank_statement_ext with voucher in order to compute the period
|
This module is deprecated. It was only needed when using account_bank_statement_ext with voucher in order to compute the period
|
||||||
correctly. This is mainly because with account_bank_statement_ext, the period is computed for each line.
|
correctly. This is mainly because with account_bank_statement_ext, the period is computed for each line.
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
'website': 'http://www.camptocamp.com',
|
'website': 'http://www.camptocamp.com',
|
||||||
'init_xml': [],
|
'init_xml': [],
|
||||||
'update_xml': [
|
'update_xml': [
|
||||||
"statement_voucher_view.xml",
|
"statement_voucher_view.xml",
|
||||||
],
|
],
|
||||||
'demo_xml': [],
|
'demo_xml': [],
|
||||||
'test': [],
|
'test': [],
|
||||||
@@ -48,5 +48,5 @@
|
|||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ class AccountVoucher(Model):
|
|||||||
context = {}
|
context = {}
|
||||||
if not context.get('period_id') and context.get('move_line_ids'):
|
if not context.get('period_id') and context.get('move_line_ids'):
|
||||||
res = self.pool.get('account.move.line').browse(
|
res = self.pool.get('account.move.line').browse(
|
||||||
cr, uid, context.get('move_line_ids'), context=context)[0].period_id.id
|
cr, uid, context.get('move_line_ids'), context=context)[0].period_id.id
|
||||||
context['period_id'] = res
|
context['period_id'] = res
|
||||||
elif context.get('date'):
|
elif context.get('date'):
|
||||||
periods = self.pool.get('account.period').find(
|
periods = self.pool.get('account.period').find(
|
||||||
cr, uid, dt=context['date'], context=context)
|
cr, uid, dt=context['date'], context=context)
|
||||||
if periods:
|
if periods:
|
||||||
context['period_id'] = periods[0]
|
context['period_id'] = periods[0]
|
||||||
return super(AccountVoucher, self)._get_period(cr, uid, context)
|
return super(AccountVoucher, self)._get_period(cr, uid, context)
|
||||||
|
|||||||
@@ -19,4 +19,3 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
'website': 'http://www.akretion.com/',
|
'website': 'http://www.akretion.com/',
|
||||||
'depends': [
|
'depends': [
|
||||||
'account_voucher',
|
'account_voucher',
|
||||||
],
|
],
|
||||||
'data': [
|
'data': [
|
||||||
'statement_view.xml',
|
'statement_view.xml',
|
||||||
],
|
],
|
||||||
'demo': [],
|
'demo': [],
|
||||||
|
|||||||
@@ -46,4 +46,4 @@
|
|||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,4 +19,3 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
from . import ofx_parser
|
from . import ofx_parser
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ try:
|
|||||||
except:
|
except:
|
||||||
raise Exception(_('Please install python lib ofxparse'))
|
raise Exception(_('Please install python lib ofxparse'))
|
||||||
|
|
||||||
|
|
||||||
class OfxParser(BankStatementImportParser):
|
class OfxParser(BankStatementImportParser):
|
||||||
|
|
||||||
"""Class for defining parser for OFX file format."""
|
"""Class for defining parser for OFX file format."""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -110,4 +112,3 @@ class OfxParser(BankStatementImportParser):
|
|||||||
'ref': line.get('ref', '/'),
|
'ref': line.get('ref', '/'),
|
||||||
'label': line.get('label', ''),
|
'label': line.get('label', ''),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
from openerp.osv import fields, orm
|
from openerp.osv import fields, orm
|
||||||
|
|
||||||
|
|
||||||
class AccountStatementProfil(orm.Model):
|
class AccountStatementProfil(orm.Model):
|
||||||
_inherit = "account.statement.profile"
|
_inherit = "account.statement.profile"
|
||||||
|
|
||||||
@@ -30,6 +31,6 @@ class AccountStatementProfil(orm.Model):
|
|||||||
"""
|
"""
|
||||||
selection = super(AccountStatementProfil, self
|
selection = super(AccountStatementProfil, self
|
||||||
)._get_import_type_selection(cr, uid,
|
)._get_import_type_selection(cr, uid,
|
||||||
context=context)
|
context=context)
|
||||||
selection.append(('ofx_so', _('OFX - Open Financial Exchange')))
|
selection.append(('ofx_so', _('OFX - Open Financial Exchange')))
|
||||||
return selection
|
return selection
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ from openerp.osv import fields, orm, osv
|
|||||||
|
|
||||||
|
|
||||||
class AccountStatementProfile(orm.Model):
|
class AccountStatementProfile(orm.Model):
|
||||||
_inherit = "account.statement.profile"
|
_inherit = "account.statement.profile"
|
||||||
_columns = {
|
_columns = {
|
||||||
'one_move': fields.boolean(
|
'one_move': fields.boolean(
|
||||||
'Group Journal Items',
|
'Group Journal Items',
|
||||||
@@ -36,6 +36,7 @@ class AccountStatementProfile(orm.Model):
|
|||||||
"for the refunds and one for the payments.")
|
"for the refunds and one for the payments.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class account_bank_statement(orm.Model):
|
class account_bank_statement(orm.Model):
|
||||||
_inherit = "account.bank.statement"
|
_inherit = "account.bank.statement"
|
||||||
|
|
||||||
@@ -49,52 +50,54 @@ class account_bank_statement(orm.Model):
|
|||||||
'period_id': period_id,
|
'period_id': period_id,
|
||||||
'date': st_line.statement_id.date,
|
'date': st_line.statement_id.date,
|
||||||
'name': st_line.ref,
|
'name': st_line.ref,
|
||||||
})
|
})
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _prepare_move(self, cr, uid, st_line, st_line_number, context=None):
|
def _prepare_move(self, cr, uid, st_line, st_line_number, context=None):
|
||||||
res = super(account_bank_statement, self).\
|
res = super(account_bank_statement, self).\
|
||||||
_prepare_move(cr, uid, st_line, st_line_number, context=context)
|
_prepare_move(cr, uid, st_line, st_line_number, context=context)
|
||||||
res.update({
|
res.update({
|
||||||
'ref': st_line.statement_id.name,
|
'ref': st_line.statement_id.name,
|
||||||
'name': st_line.statement_id.name,
|
'name': st_line.statement_id.name,
|
||||||
'date': st_line.statement_id.date,
|
'date': st_line.statement_id.date,
|
||||||
})
|
})
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def create_move_from_st_line(self, cr, uid, st_line_id, company_currency_id,
|
def create_move_from_st_line(self, cr, uid, st_line_id, company_currency_id,
|
||||||
st_line_number, context=None):
|
st_line_number, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
context['from_parent_object'] = True #For compability with module account_constraints
|
# For compability with module account_constraints
|
||||||
|
context['from_parent_object'] = True
|
||||||
account_move_obj = self.pool.get('account.move')
|
account_move_obj = self.pool.get('account.move')
|
||||||
account_bank_statement_line_obj = self.pool.get('account.bank.statement.line')
|
account_bank_statement_line_obj = self.pool.get(
|
||||||
|
'account.bank.statement.line')
|
||||||
st_line = account_bank_statement_line_obj.browse(cr, uid, st_line_id,
|
st_line = account_bank_statement_line_obj.browse(cr, uid, st_line_id,
|
||||||
context=context)
|
context=context)
|
||||||
st = st_line.statement_id
|
st = st_line.statement_id
|
||||||
|
|
||||||
if st.profile_id.one_move:
|
if st.profile_id.one_move:
|
||||||
if not context.get('move_id'):
|
if not context.get('move_id'):
|
||||||
move_vals = self._prepare_move(cr, uid, st_line, st_line_number, context=context)
|
move_vals = self._prepare_move(
|
||||||
context['move_id'] = account_move_obj.create(cr, uid, move_vals, context=context)
|
cr, uid, st_line, st_line_number, context=context)
|
||||||
self.create_move_line_from_st_line(cr, uid, context['move_id'],
|
context['move_id'] = account_move_obj.create(
|
||||||
st_line_id, company_currency_id,
|
cr, uid, move_vals, context=context)
|
||||||
context=context)
|
self.create_move_line_from_st_line(cr, uid, context['move_id'],
|
||||||
|
st_line_id, company_currency_id,
|
||||||
|
context=context)
|
||||||
return context['move_id']
|
return context['move_id']
|
||||||
else:
|
else:
|
||||||
return super(account_bank_statement, self).create_move_from_st_line(cr, uid, st_line_id,
|
return super(account_bank_statement, self).create_move_from_st_line(cr, uid, st_line_id,
|
||||||
company_currency_id,
|
company_currency_id,
|
||||||
st_line_number,
|
st_line_number,
|
||||||
context=context)
|
context=context)
|
||||||
|
|
||||||
def create_move_line_from_st_line(self, cr, uid, move_id, st_line_id,
|
def create_move_line_from_st_line(self, cr, uid, move_id, st_line_id,
|
||||||
company_currency_id, context=None):
|
company_currency_id, context=None):
|
||||||
"""Create the account move line from the statement line.
|
"""Create the account move line from the statement line.
|
||||||
|
|
||||||
:param int/long move_id: ID of the account.move
|
:param int/long move_id: ID of the account.move
|
||||||
:param int/long st_line_id: ID of the account.bank.statement.line to create the move line from.
|
:param int/long st_line_id: ID of the account.bank.statement.line to create the move line from.
|
||||||
:param int/long company_currency_id: ID of the res.currency of the company
|
:param int/long company_currency_id: ID of the res.currency of the company
|
||||||
@@ -104,23 +107,26 @@ class account_bank_statement(orm.Model):
|
|||||||
context = {}
|
context = {}
|
||||||
res_currency_obj = self.pool.get('res.currency')
|
res_currency_obj = self.pool.get('res.currency')
|
||||||
account_move_line_obj = self.pool.get('account.move.line')
|
account_move_line_obj = self.pool.get('account.move.line')
|
||||||
account_bank_statement_line_obj = self.pool.get('account.bank.statement.line')
|
account_bank_statement_line_obj = self.pool.get(
|
||||||
st_line = account_bank_statement_line_obj.browse(cr, uid, st_line_id, context=context)
|
'account.bank.statement.line')
|
||||||
|
st_line = account_bank_statement_line_obj.browse(
|
||||||
|
cr, uid, st_line_id, context=context)
|
||||||
st = st_line.statement_id
|
st = st_line.statement_id
|
||||||
|
|
||||||
context.update({'date': st_line.date})
|
context.update({'date': st_line.date})
|
||||||
acc_cur = ((st_line.amount<=0) and st.journal_id.default_debit_account_id) or st_line.account_id
|
acc_cur = ((st_line.amount <= 0)
|
||||||
|
and st.journal_id.default_debit_account_id) or st_line.account_id
|
||||||
|
|
||||||
context.update({
|
context.update({
|
||||||
'res.currency.compute.account': acc_cur,
|
'res.currency.compute.account': acc_cur,
|
||||||
})
|
})
|
||||||
amount = res_currency_obj.compute(cr, uid, st.currency.id,
|
amount = res_currency_obj.compute(cr, uid, st.currency.id,
|
||||||
company_currency_id,
|
company_currency_id,
|
||||||
st_line.amount,
|
st_line.amount,
|
||||||
context=context)
|
context=context)
|
||||||
|
|
||||||
bank_move_vals = self._prepare_bank_move_line(cr, uid, st_line, move_id, amount,
|
bank_move_vals = self._prepare_bank_move_line(cr, uid, st_line, move_id, amount,
|
||||||
company_currency_id, context=context)
|
company_currency_id, context=context)
|
||||||
return account_move_line_obj.create(cr, uid, bank_move_vals, context=context)
|
return account_move_line_obj.create(cr, uid, bank_move_vals, context=context)
|
||||||
|
|
||||||
def _valid_move(self, cr, uid, move_id, context=None):
|
def _valid_move(self, cr, uid, move_id, context=None):
|
||||||
@@ -129,7 +135,6 @@ class account_bank_statement(orm.Model):
|
|||||||
move_obj.post(cr, uid, [move_id], context=context)
|
move_obj.post(cr, uid, [move_id], context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _prepare_transfer_move_line_vals(self, cr, uid, st, name, amount, move_id, context=None):
|
def _prepare_transfer_move_line_vals(self, cr, uid, st, name, amount, move_id, context=None):
|
||||||
"""
|
"""
|
||||||
Prepare the dict of values to create the transfer move lines.
|
Prepare the dict of values to create the transfer move lines.
|
||||||
@@ -157,7 +162,6 @@ class account_bank_statement(orm.Model):
|
|||||||
}
|
}
|
||||||
return vals
|
return vals
|
||||||
|
|
||||||
|
|
||||||
def create_move_transfer_lines(self, cr, uid, move, st, context=None):
|
def create_move_transfer_lines(self, cr, uid, move, st, context=None):
|
||||||
move_line_obj = self.pool.get('account.move.line')
|
move_line_obj = self.pool.get('account.move.line')
|
||||||
move_id = move.id
|
move_id = move.id
|
||||||
@@ -165,11 +169,11 @@ class account_bank_statement(orm.Model):
|
|||||||
payment = 0.0
|
payment = 0.0
|
||||||
transfer_lines = []
|
transfer_lines = []
|
||||||
transfer_line_ids = []
|
transfer_line_ids = []
|
||||||
#Calculate the part of the refund amount and the payment amount
|
# Calculate the part of the refund amount and the payment amount
|
||||||
for move_line in move.line_id:
|
for move_line in move.line_id:
|
||||||
refund -= move_line.debit
|
refund -= move_line.debit
|
||||||
payment += move_line.credit
|
payment += move_line.credit
|
||||||
#Create 2 Transfer lines or One global tranfer line
|
# Create 2 Transfer lines or One global tranfer line
|
||||||
if st.profile_id.split_transfer_line:
|
if st.profile_id.split_transfer_line:
|
||||||
if refund:
|
if refund:
|
||||||
transfer_lines.append(['Refund Transfer', refund])
|
transfer_lines.append(['Refund Transfer', refund])
|
||||||
@@ -180,15 +184,15 @@ class account_bank_statement(orm.Model):
|
|||||||
if amount:
|
if amount:
|
||||||
transfer_lines.append(['Transfer', amount])
|
transfer_lines.append(['Transfer', amount])
|
||||||
for transfer_line in transfer_lines:
|
for transfer_line in transfer_lines:
|
||||||
vals = self._prepare_transfer_move_line_vals(cr, uid, st,
|
vals = self._prepare_transfer_move_line_vals(cr, uid, st,
|
||||||
transfer_line[0],
|
transfer_line[0],
|
||||||
transfer_line[1],
|
transfer_line[1],
|
||||||
move_id,
|
move_id,
|
||||||
context=context)
|
context=context)
|
||||||
transfer_line_ids.append(move_line_obj.create(cr, uid, vals, context=context))
|
transfer_line_ids.append(
|
||||||
|
move_line_obj.create(cr, uid, vals, context=context))
|
||||||
return transfer_line_ids
|
return transfer_line_ids
|
||||||
|
|
||||||
|
|
||||||
def button_confirm_bank(self, cr, uid, ids, context=None):
|
def button_confirm_bank(self, cr, uid, ids, context=None):
|
||||||
st_line_obj = self.pool.get('account.bank.statement.line')
|
st_line_obj = self.pool.get('account.bank.statement.line')
|
||||||
move_obj = self.pool.get('account.move')
|
move_obj = self.pool.get('account.move')
|
||||||
@@ -200,12 +204,13 @@ class account_bank_statement(orm.Model):
|
|||||||
if st.profile_id.one_move and context.get('move_id', False):
|
if st.profile_id.one_move and context.get('move_id', False):
|
||||||
move_id = context['move_id']
|
move_id = context['move_id']
|
||||||
move = move_obj.browse(cr, uid, move_id, context=context)
|
move = move_obj.browse(cr, uid, move_id, context=context)
|
||||||
transfe_line_ids = self.create_move_transfer_lines(cr, uid, move, st, context=context)
|
transfe_line_ids = self.create_move_transfer_lines(
|
||||||
|
cr, uid, move, st, context=context)
|
||||||
self._valid_move(cr, uid, move_id, context=context)
|
self._valid_move(cr, uid, move_id, context=context)
|
||||||
lines_ids = [x.id for x in st.line_ids]
|
lines_ids = [x.id for x in st.line_ids]
|
||||||
st_line_obj.write(cr, uid, lines_ids,
|
st_line_obj.write(cr, uid, lines_ids,
|
||||||
{'move_ids': [(4, move_id, False)]},
|
{'move_ids': [(4, move_id, False)]},
|
||||||
context=context)
|
context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def button_cancel(self, cr, uid, ids, context=None):
|
def button_cancel(self, cr, uid, ids, context=None):
|
||||||
@@ -216,10 +221,8 @@ class account_bank_statement(orm.Model):
|
|||||||
if move.state != 'draft':
|
if move.state != 'draft':
|
||||||
move.button_cancel(context=context)
|
move.button_cancel(context=context)
|
||||||
move.unlink(context=context)
|
move.unlink(context=context)
|
||||||
st.write({'state':'draft'}, context=context)
|
st.write({'state': 'draft'}, context=context)
|
||||||
else:
|
else:
|
||||||
super(account_bank_statement, self).button_cancel(cr, uid, ids,
|
super(account_bank_statement, self).button_cancel(cr, uid, ids,
|
||||||
context=context)
|
context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Account Statement Regex Account Completion addon
|
|||||||
and update account to use in the bank statement line with the specified account.
|
and update account to use in the bank statement line with the specified account.
|
||||||
""",
|
""",
|
||||||
"data": ['statement_view.xml',
|
"data": ['statement_view.xml',
|
||||||
],
|
],
|
||||||
"demo": [],
|
"demo": [],
|
||||||
"test": [],
|
"test": [],
|
||||||
"active": False,
|
"active": False,
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import re
|
|||||||
|
|
||||||
|
|
||||||
class AccountStatementCompletionRule(Model):
|
class AccountStatementCompletionRule(Model):
|
||||||
|
|
||||||
"""Add a rule to complete account based on a regular expression"""
|
"""Add a rule to complete account based on a regular expression"""
|
||||||
|
|
||||||
_inherit = "account.statement.completion.rule"
|
_inherit = "account.statement.completion.rule"
|
||||||
|
|||||||
@@ -36,14 +36,17 @@ ACC_NUMBER = "BE38733040385372"
|
|||||||
class test_regex_account_completion(common.TransactionCase):
|
class test_regex_account_completion(common.TransactionCase):
|
||||||
|
|
||||||
def prepare(self):
|
def prepare(self):
|
||||||
self.account_bank_statement_obj = self.registry("account.bank.statement")
|
self.account_bank_statement_obj = self.registry(
|
||||||
self.account_bank_statement_line_obj = self.registry("account.bank.statement.line")
|
"account.bank.statement")
|
||||||
|
self.account_bank_statement_line_obj = self.registry(
|
||||||
|
"account.bank.statement.line")
|
||||||
self.account_id = self.ref('account.a_expense')
|
self.account_id = self.ref('account.a_expense')
|
||||||
# create the completion rule
|
# create the completion rule
|
||||||
rule_vals = {'function_to_call': 'set_account',
|
rule_vals = {'function_to_call': 'set_account',
|
||||||
'regex': '^My statement',
|
'regex': '^My statement',
|
||||||
'account_id': self.account_id}
|
'account_id': self.account_id}
|
||||||
completion_rule_id = self.registry("account.statement.completion.rule").create(self.cr, self.uid, rule_vals)
|
completion_rule_id = self.registry(
|
||||||
|
"account.statement.completion.rule").create(self.cr, self.uid, rule_vals)
|
||||||
|
|
||||||
# Create the profile
|
# Create the profile
|
||||||
journal_id = self.ref("account.bank_journal")
|
journal_id = self.ref("account.bank_journal")
|
||||||
@@ -83,9 +86,14 @@ class test_regex_account_completion(common.TransactionCase):
|
|||||||
"""Test the automatic completion on account
|
"""Test the automatic completion on account
|
||||||
"""
|
"""
|
||||||
self.prepare()
|
self.prepare()
|
||||||
statement_obj = self.account_bank_statement_obj.browse(self.cr, self.uid, self.statement_id)
|
statement_obj = self.account_bank_statement_obj.browse(
|
||||||
|
self.cr, self.uid, self.statement_id)
|
||||||
statement_obj.button_auto_completion()
|
statement_obj.button_auto_completion()
|
||||||
statement_line1 = self.account_bank_statement_line_obj.browse(self.cr, self.uid, self.statement_line1_id)
|
statement_line1 = self.account_bank_statement_line_obj.browse(
|
||||||
self.assertEquals(self.account_id, statement_line1.account_id.id, "The account should be the account of the completion")
|
self.cr, self.uid, self.statement_line1_id)
|
||||||
statement_line2 = self.account_bank_statement_line_obj.browse(self.cr, self.uid, self.statement_line2_id)
|
self.assertEquals(self.account_id, statement_line1.account_id.id,
|
||||||
self.assertNotEqual(self.account_id, statement_line2.account_id.id, "The account should be not the account of the completion")
|
"The account should be the account of the completion")
|
||||||
|
statement_line2 = self.account_bank_statement_line_obj.browse(
|
||||||
|
self.cr, self.uid, self.statement_line2_id)
|
||||||
|
self.assertNotEqual(self.account_id, statement_line2.account_id.id,
|
||||||
|
"The account should be not the account of the completion")
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
'depends': [
|
'depends': [
|
||||||
'account_statement_base_completion',
|
'account_statement_base_completion',
|
||||||
'base_transaction_id'
|
'base_transaction_id'
|
||||||
],
|
],
|
||||||
'description': """
|
'description': """
|
||||||
Add a completion method based on transaction ID providen by the bank/office.
|
Add a completion method based on transaction ID providen by the bank/office.
|
||||||
|
|
||||||
@@ -44,8 +44,8 @@
|
|||||||
'website': 'http://www.camptocamp.com',
|
'website': 'http://www.camptocamp.com',
|
||||||
'init_xml': [],
|
'init_xml': [],
|
||||||
'update_xml': [
|
'update_xml': [
|
||||||
"statement_view.xml",
|
"statement_view.xml",
|
||||||
"data.xml",
|
"data.xml",
|
||||||
],
|
],
|
||||||
'demo_xml': [],
|
'demo_xml': [],
|
||||||
'test': [
|
'test': [
|
||||||
@@ -58,4 +58,4 @@
|
|||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': True,
|
'auto_install': True,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,14 @@ from openerp.addons.account_statement_base_completion.statement import ErrorTooM
|
|||||||
|
|
||||||
|
|
||||||
class AccountStatementCompletionRule(Model):
|
class AccountStatementCompletionRule(Model):
|
||||||
|
|
||||||
"""Add a rule based on transaction ID"""
|
"""Add a rule based on transaction ID"""
|
||||||
|
|
||||||
_inherit = "account.statement.completion.rule"
|
_inherit = "account.statement.completion.rule"
|
||||||
|
|
||||||
def _get_functions(self, cr, uid, context=None):
|
def _get_functions(self, cr, uid, context=None):
|
||||||
res = super(AccountStatementCompletionRule, self)._get_functions(
|
res = super(AccountStatementCompletionRule, self)._get_functions(
|
||||||
cr, uid, context=context)
|
cr, uid, context=context)
|
||||||
res += [
|
res += [
|
||||||
('get_from_transaction_id_and_so',
|
('get_from_transaction_id_and_so',
|
||||||
'Match Sales Order using transaction ID'),
|
'Match Sales Order using transaction ID'),
|
||||||
@@ -59,7 +60,8 @@ class AccountStatementCompletionRule(Model):
|
|||||||
so_obj = self.pool.get('sale.order')
|
so_obj = self.pool.get('sale.order')
|
||||||
so_id = so_obj.search(cr,
|
so_id = so_obj.search(cr,
|
||||||
uid,
|
uid,
|
||||||
[('transaction_id', '=', st_line['transaction_id'])],
|
[('transaction_id', '=',
|
||||||
|
st_line['transaction_id'])],
|
||||||
context=context)
|
context=context)
|
||||||
if len(so_id) > 1:
|
if len(so_id) > 1:
|
||||||
raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more than '
|
raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more than '
|
||||||
@@ -70,11 +72,15 @@ class AccountStatementCompletionRule(Model):
|
|||||||
res['ref'] = so.name
|
res['ref'] = so.name
|
||||||
st_vals = st_obj.get_values_for_line(cr,
|
st_vals = st_obj.get_values_for_line(cr,
|
||||||
uid,
|
uid,
|
||||||
profile_id=st_line['profile_id'],
|
profile_id=st_line[
|
||||||
master_account_id=st_line['master_account_id'],
|
'profile_id'],
|
||||||
partner_id=res.get('partner_id', False),
|
master_account_id=st_line[
|
||||||
|
'master_account_id'],
|
||||||
|
partner_id=res.get(
|
||||||
|
'partner_id', False),
|
||||||
line_type=st_line['type'],
|
line_type=st_line['type'],
|
||||||
amount=st_line['amount'] if st_line['amount'] else 0.0,
|
amount=st_line['amount'] if st_line[
|
||||||
|
'amount'] else 0.0,
|
||||||
context=context)
|
context=context)
|
||||||
res.update(st_vals)
|
res.update(st_vals)
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
'depends': [
|
'depends': [
|
||||||
'account_statement_base_import',
|
'account_statement_base_import',
|
||||||
'account_statement_transactionid_completion'
|
'account_statement_transactionid_completion'
|
||||||
],
|
],
|
||||||
'description': """
|
'description': """
|
||||||
This module brings generic methods and fields on bank statement to deal with
|
This module brings generic methods and fields on bank statement to deal with
|
||||||
the importation of different bank and offices that uses transactionID.
|
the importation of different bank and offices that uses transactionID.
|
||||||
@@ -57,4 +57,4 @@
|
|||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from account_statement_base_import.parser.file_parser import FileParser
|
|||||||
|
|
||||||
|
|
||||||
class TransactionIDFileParser(FileParser):
|
class TransactionIDFileParser(FileParser):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
TransactionID parser that use a define format in csv or xls to import
|
TransactionID parser that use a define format in csv or xls to import
|
||||||
bank statement.
|
bank statement.
|
||||||
@@ -40,7 +41,8 @@ class TransactionIDFileParser(FileParser):
|
|||||||
super(TransactionIDFileParser, self).__init__(profile, extra_fields=extra_fields,
|
super(TransactionIDFileParser, self).__init__(profile, extra_fields=extra_fields,
|
||||||
ftype=ftype, header=header, **kwargs)
|
ftype=ftype, header=header, **kwargs)
|
||||||
# ref is replaced by transaction_id thus we delete it from check
|
# ref is replaced by transaction_id thus we delete it from check
|
||||||
self.keys_to_validate = [k for k in self.keys_to_validate if k != 'ref']
|
self.keys_to_validate = [
|
||||||
|
k for k in self.keys_to_validate if k != 'ref']
|
||||||
del self.conversion_dict['ref']
|
del self.conversion_dict['ref']
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class AccountStatementProfil(Model):
|
|||||||
Has to be inherited to add parser
|
Has to be inherited to add parser
|
||||||
"""
|
"""
|
||||||
res = super(AccountStatementProfil, self)._get_import_type_selection(
|
res = super(AccountStatementProfil, self)._get_import_type_selection(
|
||||||
cr, uid, context=context)
|
cr, uid, context=context)
|
||||||
res.append(('generic_csvxls_transaction',
|
res.append(('generic_csvxls_transaction',
|
||||||
'Generic .csv/.xls based on SO transaction ID'))
|
'Generic .csv/.xls based on SO transaction ID'))
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
'account',
|
'account',
|
||||||
'sale',
|
'sale',
|
||||||
'stock'
|
'stock'
|
||||||
],
|
],
|
||||||
'description': """
|
'description': """
|
||||||
Adds transaction id to invoice and sale models and views.
|
Adds transaction id to invoice and sale models and views.
|
||||||
On Sales order, you can specify the transaction ID used
|
On Sales order, you can specify the transaction ID used
|
||||||
@@ -47,11 +47,11 @@
|
|||||||
'update_xml': [
|
'update_xml': [
|
||||||
'invoice_view.xml',
|
'invoice_view.xml',
|
||||||
'sale_view.xml'
|
'sale_view.xml'
|
||||||
],
|
],
|
||||||
'demo_xml': [],
|
'demo_xml': [],
|
||||||
'test': [],
|
'test': [],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ class SaleOrder(Model):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def _prepare_invoice(self, cr, uid, order, lines, context=None):
|
def _prepare_invoice(self, cr, uid, order, lines, context=None):
|
||||||
#we put the transaction id in the generated invoices
|
# we put the transaction id in the generated invoices
|
||||||
invoice_vals = super(SaleOrder, self)._prepare_invoice(
|
invoice_vals = super(SaleOrder, self)._prepare_invoice(
|
||||||
cr, uid, order, lines, context=context)
|
cr, uid, order, lines, context=context)
|
||||||
invoice_vals.update({
|
invoice_vals.update({
|
||||||
'transaction_id': order.transaction_id})
|
'transaction_id': order.transaction_id})
|
||||||
return invoice_vals
|
return invoice_vals
|
||||||
|
|||||||
@@ -29,14 +29,14 @@ class StockPicking(Model):
|
|||||||
self, cr, uid, ids, journal_id=False, group=False,
|
self, cr, uid, ids, journal_id=False, group=False,
|
||||||
type='out_invoice', context=None):
|
type='out_invoice', context=None):
|
||||||
res = super(StockPicking, self).action_invoice_create(
|
res = super(StockPicking, self).action_invoice_create(
|
||||||
cr, uid, ids, journal_id, group, type, context)
|
cr, uid, ids, journal_id, group, type, context)
|
||||||
for pick_id in res:
|
for pick_id in res:
|
||||||
pick = self.browse(cr, uid, pick_id, context=context)
|
pick = self.browse(cr, uid, pick_id, context=context)
|
||||||
if pick.sale_id and pick.sale_id.transaction_id:
|
if pick.sale_id and pick.sale_id.transaction_id:
|
||||||
self.pool.get('account.invoice').write(
|
self.pool.get('account.invoice').write(
|
||||||
cr,
|
cr,
|
||||||
uid,
|
uid,
|
||||||
res[pick_id],
|
res[pick_id],
|
||||||
{'transaction_id': pick.sale_id.transaction_id},
|
{'transaction_id': pick.sale_id.transaction_id},
|
||||||
context=context)
|
context=context)
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ line will be take from imported line in this order:
|
|||||||
'depends': ['account_voucher', 'account_payment'],
|
'depends': ['account_voucher', 'account_payment'],
|
||||||
'data': [
|
'data': [
|
||||||
'statement_view.xml',
|
'statement_view.xml',
|
||||||
],
|
],
|
||||||
'test': [],
|
'test': [],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'active': False,
|
'active': False,
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ class AccountStatementFromInvoiceLines(orm.TransientModel):
|
|||||||
statement_line_obj = self.pool.get('account.bank.statement.line')
|
statement_line_obj = self.pool.get('account.bank.statement.line')
|
||||||
currency_obj = self.pool.get('res.currency')
|
currency_obj = self.pool.get('res.currency')
|
||||||
line_date = time.strftime('%Y-%m-%d')
|
line_date = time.strftime('%Y-%m-%d')
|
||||||
statement = statement_obj.browse(cr, uid, statement_id, context=context)
|
statement = statement_obj.browse(
|
||||||
|
cr, uid, statement_id, context=context)
|
||||||
# for each selected move lines
|
# for each selected move lines
|
||||||
for line in line_obj.browse(cr, uid, line_ids, context=context):
|
for line in line_obj.browse(cr, uid, line_ids, context=context):
|
||||||
ctx = context.copy()
|
ctx = context.copy()
|
||||||
@@ -60,10 +61,10 @@ class AccountStatementFromInvoiceLines(orm.TransientModel):
|
|||||||
|
|
||||||
if line.amount_currency:
|
if line.amount_currency:
|
||||||
amount = currency_obj.compute(cr, uid, line.currency_id.id,
|
amount = currency_obj.compute(cr, uid, line.currency_id.id,
|
||||||
statement.currency.id, line.amount_currency, context=ctx)
|
statement.currency.id, line.amount_currency, context=ctx)
|
||||||
elif (line.invoice and line.invoice.currency_id.id != statement.currency.id):
|
elif (line.invoice and line.invoice.currency_id.id != statement.currency.id):
|
||||||
amount = currency_obj.compute(cr, uid, line.invoice.currency_id.id,
|
amount = currency_obj.compute(cr, uid, line.invoice.currency_id.id,
|
||||||
statement.currency.id, amount, context=ctx)
|
statement.currency.id, amount, context=ctx)
|
||||||
|
|
||||||
context.update({'move_line_ids': [line.id],
|
context.update({'move_line_ids': [line.id],
|
||||||
'invoice_id': line.invoice.id})
|
'invoice_id': line.invoice.id})
|
||||||
@@ -109,13 +110,15 @@ class AccountPaymentPopulateStatement(orm.TransientModel):
|
|||||||
if not line_ids:
|
if not line_ids:
|
||||||
return {'type': 'ir.actions.act_window_close'}
|
return {'type': 'ir.actions.act_window_close'}
|
||||||
|
|
||||||
statement = statement_obj.browse(cr, uid, context['active_id'], context=context)
|
statement = statement_obj.browse(
|
||||||
|
cr, uid, context['active_id'], context=context)
|
||||||
|
|
||||||
for line in line_obj.browse(cr, uid, line_ids, context=context):
|
for line in line_obj.browse(cr, uid, line_ids, context=context):
|
||||||
ctx = context.copy()
|
ctx = context.copy()
|
||||||
ctx['date'] = line.ml_maturity_date # Last value_date earlier,but this field exists no more now
|
# Last value_date earlier,but this field exists no more now
|
||||||
|
ctx['date'] = line.ml_maturity_date
|
||||||
amount = currency_obj.compute(cr, uid, line.currency.id,
|
amount = currency_obj.compute(cr, uid, line.currency.id,
|
||||||
statement.currency.id, line.amount_currency, context=ctx)
|
statement.currency.id, line.amount_currency, context=ctx)
|
||||||
if not line.move_line_id.id:
|
if not line.move_line_id.id:
|
||||||
continue
|
continue
|
||||||
context.update({'move_line_ids': [line.move_line_id.id]})
|
context.update({'move_line_ids': [line.move_line_id.id]})
|
||||||
@@ -124,7 +127,8 @@ class AccountPaymentPopulateStatement(orm.TransientModel):
|
|||||||
st_line_id = statement_line_obj.create(cr, uid, vals,
|
st_line_id = statement_line_obj.create(cr, uid, vals,
|
||||||
context=context)
|
context=context)
|
||||||
|
|
||||||
line_obj.write(cr, uid, [line.id], {'bank_statement_line_id': st_line_id})
|
line_obj.write(
|
||||||
|
cr, uid, [line.id], {'bank_statement_line_id': st_line_id})
|
||||||
return {'type': 'ir.actions.act_window_close'}
|
return {'type': 'ir.actions.act_window_close'}
|
||||||
|
|
||||||
def _prepare_statement_line_vals(self, cr, uid, payment_line, amount,
|
def _prepare_statement_line_vals(self, cr, uid, payment_line, amount,
|
||||||
|
|||||||
Reference in New Issue
Block a user