Merge pull request #2352 from odoo-dev/8.0-imp-bank-statement-reconciliation-widget-ama
fixes and improvements in the new bank statement reconciliation widget.
This commit is contained in:
commit
3f4ff3e725
|
@ -417,6 +417,11 @@ class account_bank_statement(osv.osv):
|
|||
|
||||
class account_bank_statement_line(osv.osv):
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
if vals.get('amount_currency', 0) and not vals.get('amount', 0):
|
||||
raise osv.except_osv(_('Error!'), _('If "Amount Currency" is specified, then "Amount" must be as well.'))
|
||||
return super(account_bank_statement_line, self).create(cr, uid, vals, context=context)
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
for item in self.browse(cr, uid, ids, context=context):
|
||||
if item.journal_entry_id:
|
||||
|
@ -496,6 +501,7 @@ class account_bank_statement_line(osv.osv):
|
|||
'account_code': st_line.journal_id.default_debit_account_id.code,
|
||||
'account_name': st_line.journal_id.default_debit_account_id.name,
|
||||
'partner_name': st_line.partner_id.name,
|
||||
'communication_partner_name': st_line.partner_name,
|
||||
'amount_currency_str': amount_currency_str, # Amount in the statement currency
|
||||
'has_no_partner': not st_line.partner_id.id,
|
||||
}
|
||||
|
@ -538,15 +544,20 @@ class account_bank_statement_line(osv.osv):
|
|||
sign = 1
|
||||
if statement_currency == company_currency:
|
||||
amount_field = 'credit'
|
||||
sign = -1
|
||||
if st_line.amount > 0:
|
||||
amount_field = 'debit'
|
||||
else:
|
||||
sign = -1
|
||||
else:
|
||||
amount_field = 'amount_currency'
|
||||
if st_line.amount < 0:
|
||||
sign = -1
|
||||
if st_line.amount_currency:
|
||||
amount = st_line.amount_currency
|
||||
else:
|
||||
amount = st_line.amount
|
||||
|
||||
match_id = self.get_move_lines_for_reconciliation(cr, uid, st_line, excluded_ids=excluded_ids, offset=0, limit=1, additional_domain=[(amount_field, '=', (sign * st_line.amount))])
|
||||
match_id = self.get_move_lines_for_reconciliation(cr, uid, st_line, excluded_ids=excluded_ids, offset=0, limit=1, additional_domain=[(amount_field, '=', (sign * amount))])
|
||||
if match_id:
|
||||
return [match_id[0]]
|
||||
|
||||
|
@ -576,36 +587,47 @@ class account_bank_statement_line(osv.osv):
|
|||
mv_line_pool = self.pool.get('account.move.line')
|
||||
|
||||
# Make domain
|
||||
domain = additional_domain + [('reconcile_id', '=', False),('state', '=', 'valid')]
|
||||
domain = additional_domain + [('reconcile_id', '=', False), ('state', '=', 'valid'), ('account_id.reconcile', '=', True)]
|
||||
if st_line.partner_id.id:
|
||||
domain += [('partner_id', '=', st_line.partner_id.id),
|
||||
'|', ('account_id.type', '=', 'receivable'),
|
||||
('account_id.type', '=', 'payable')]
|
||||
else:
|
||||
domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')]
|
||||
if str:
|
||||
domain += [('partner_id.name', 'ilike', str)]
|
||||
domain += [('partner_id', '=', st_line.partner_id.id)]
|
||||
if excluded_ids:
|
||||
domain.append(('id', 'not in', excluded_ids))
|
||||
if str:
|
||||
domain += ['|', ('move_id.name', 'ilike', str), ('move_id.ref', 'ilike', str)]
|
||||
if not st_line.partner_id.id:
|
||||
domain.insert(-1, '|', )
|
||||
domain.append(('partner_id.name', 'ilike', str))
|
||||
if str != '/':
|
||||
domain.insert(-1, '|', )
|
||||
domain.append(('name', 'ilike', str))
|
||||
|
||||
# Get move lines
|
||||
line_ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context)
|
||||
lines = mv_line_pool.browse(cr, uid, line_ids, context=context)
|
||||
|
||||
# Either return number of lines
|
||||
if count:
|
||||
nb_lines = 0
|
||||
reconcile_partial_ids = [] # for a partial reconciliation, take only one line
|
||||
# Get move lines ; in case of a partial reconciliation, only consider one line
|
||||
filtered_lines = []
|
||||
reconcile_partial_ids = []
|
||||
actual_offset = offset
|
||||
while True:
|
||||
line_ids = mv_line_pool.search(cr, uid, domain, offset=actual_offset, limit=limit, order="date_maturity asc, id asc", context=context)
|
||||
lines = mv_line_pool.browse(cr, uid, line_ids, context=context)
|
||||
make_one_more_loop = False
|
||||
for line in lines:
|
||||
if line.reconcile_partial_id and line.reconcile_partial_id.id in reconcile_partial_ids:
|
||||
#if we filtered a line because it is partially reconciled with an already selected line, we must do one more loop
|
||||
#in order to get the right number of items in the pager
|
||||
make_one_more_loop = True
|
||||
continue
|
||||
nb_lines += 1
|
||||
filtered_lines.append(line)
|
||||
if line.reconcile_partial_id:
|
||||
reconcile_partial_ids.append(line.reconcile_partial_id.id)
|
||||
return nb_lines
|
||||
|
||||
|
||||
if not limit or not make_one_more_loop or len(filtered_lines) >= limit:
|
||||
break
|
||||
actual_offset = actual_offset + limit
|
||||
lines = limit and filtered_lines[:limit] or filtered_lines
|
||||
|
||||
# Either return number of lines
|
||||
if count:
|
||||
return len(lines)
|
||||
|
||||
# Or return list of dicts representing the formatted move lines
|
||||
else:
|
||||
target_currency = st_line.currency_id or st_line.journal_id.currency or st_line.journal_id.company_id.currency_id
|
||||
|
@ -639,6 +661,10 @@ class account_bank_statement_line(osv.osv):
|
|||
'account_id': account_id
|
||||
}
|
||||
|
||||
def process_reconciliations(self, cr, uid, data, context=None):
|
||||
for datum in data:
|
||||
self.process_reconciliation(cr, uid, datum[0], datum[1], context=context)
|
||||
|
||||
def process_reconciliation(self, cr, uid, id, mv_line_dicts, context=None):
|
||||
""" Creates a move line for each item of mv_line_dicts and for the statement line. Reconcile a new move line with its counterpart_move_line_id if specified. Finally, mark the statement line as reconciled by putting the newly created move id in the column journal_entry_id.
|
||||
|
||||
|
@ -699,6 +725,7 @@ class account_bank_statement_line(osv.osv):
|
|||
mv_line_dict['statement_id'] = st_line.statement_id.id
|
||||
if mv_line_dict.get('counterpart_move_line_id'):
|
||||
mv_line = aml_obj.browse(cr, uid, mv_line_dict['counterpart_move_line_id'], context=context)
|
||||
mv_line_dict['partner_id'] = mv_line.partner_id.id or st_line.partner_id.id
|
||||
mv_line_dict['account_id'] = mv_line.account_id.id
|
||||
if st_line_currency.id != company_currency.id:
|
||||
ctx = context.copy()
|
||||
|
|
|
@ -766,18 +766,17 @@ class account_move_line(osv.osv):
|
|||
currency_obj = self.pool.get('res.currency')
|
||||
company_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id
|
||||
rml_parser = report_sxw.rml_parse(cr, uid, 'reconciliation_widget_aml', context=context)
|
||||
reconcile_partial_ids = [] # for a partial reconciliation, take only one line
|
||||
ret = []
|
||||
|
||||
for line in lines:
|
||||
if line.reconcile_partial_id and line.reconcile_partial_id.id in reconcile_partial_ids:
|
||||
continue
|
||||
partial_reconciliation_siblings_ids = []
|
||||
if line.reconcile_partial_id:
|
||||
reconcile_partial_ids.append(line.reconcile_partial_id.id)
|
||||
partial_reconciliation_siblings_ids = self.search(cr, uid, [('reconcile_partial_id', '=', line.reconcile_partial_id.id)], context=context)
|
||||
partial_reconciliation_siblings_ids.remove(line.id)
|
||||
|
||||
ret_line = {
|
||||
'id': line.id,
|
||||
'name': line.move_id.name,
|
||||
'name': line.name != '/' and line.move_id.name + ': ' + line.name or line.move_id.name,
|
||||
'ref': line.move_id.ref,
|
||||
'account_code': line.account_id.code,
|
||||
'account_name': line.account_id.name,
|
||||
|
@ -788,35 +787,59 @@ class account_move_line(osv.osv):
|
|||
'journal_name': line.journal_id.name,
|
||||
'partner_id': line.partner_id.id,
|
||||
'partner_name': line.partner_id.name,
|
||||
'is_partially_reconciled': bool(line.reconcile_partial_id),
|
||||
'partial_reconciliation_siblings_ids': partial_reconciliation_siblings_ids,
|
||||
}
|
||||
|
||||
# Amount residual can be negative
|
||||
debit = line.debit
|
||||
credit = line.credit
|
||||
total_amount = abs(debit - credit)
|
||||
total_amount_currency = line.amount_currency
|
||||
amount_residual = line.amount_residual
|
||||
amount_residual_currency = line.amount_residual_currency
|
||||
if line.amount_residual < 0:
|
||||
debit, credit = credit, debit
|
||||
amount_residual = -amount_residual
|
||||
amount_residual_currency = -amount_residual_currency
|
||||
|
||||
# Get right debit / credit:
|
||||
line_currency = line.currency_id or company_currency
|
||||
amount_currency_str = ""
|
||||
total_amount_currency_str = ""
|
||||
if line.currency_id and line.amount_currency:
|
||||
amount_currency_str = rml_parser.formatLang(line.amount_currency, currency_obj=line.currency_id)
|
||||
amount_currency_str = rml_parser.formatLang(amount_residual_currency, currency_obj=line.currency_id)
|
||||
total_amount_currency_str = rml_parser.formatLang(total_amount_currency, currency_obj=line.currency_id)
|
||||
if target_currency and line_currency == target_currency and target_currency != company_currency:
|
||||
debit = line.debit > 0 and line.amount_residual_currency or 0.0
|
||||
credit = line.credit > 0 and line.amount_residual_currency or 0.0
|
||||
amount_currency_str = rml_parser.formatLang(line.amount_residual, currency_obj=company_currency)
|
||||
debit = debit > 0 and amount_residual_currency or 0.0
|
||||
credit = credit > 0 and amount_residual_currency or 0.0
|
||||
amount_currency_str = rml_parser.formatLang(amount_residual, currency_obj=company_currency)
|
||||
total_amount_currency_str = rml_parser.formatLang(total_amount, currency_obj=company_currency)
|
||||
amount_str = rml_parser.formatLang(debit or credit, currency_obj=target_currency)
|
||||
total_amount_str = rml_parser.formatLang(total_amount_currency, currency_obj=target_currency)
|
||||
else:
|
||||
debit = line.debit > 0 and line.amount_residual or 0.0
|
||||
credit = line.credit > 0 and line.amount_residual or 0.0
|
||||
debit = debit > 0 and amount_residual or 0.0
|
||||
credit = credit > 0 and amount_residual or 0.0
|
||||
amount_str = rml_parser.formatLang(debit or credit, currency_obj=company_currency)
|
||||
total_amount_str = rml_parser.formatLang(total_amount, currency_obj=company_currency)
|
||||
if target_currency and target_currency != company_currency:
|
||||
amount_currency_str = rml_parser.formatLang(debit or credit, currency_obj=line_currency)
|
||||
total_amount_currency_str = rml_parser.formatLang(total_amount, currency_obj=line_currency)
|
||||
ctx = context.copy()
|
||||
if target_date:
|
||||
ctx.update({'date': target_date})
|
||||
debit = currency_obj.compute(cr, uid, target_currency.id, company_currency.id, debit, context=ctx)
|
||||
credit = currency_obj.compute(cr, uid, target_currency.id, company_currency.id, credit, context=ctx)
|
||||
debit = currency_obj.compute(cr, uid, company_currency.id, target_currency.id, debit, context=ctx)
|
||||
credit = currency_obj.compute(cr, uid, company_currency.id, target_currency.id, credit, context=ctx)
|
||||
amount_str = rml_parser.formatLang(debit or credit, currency_obj=target_currency)
|
||||
total_amount = currency_obj.compute(cr, uid, company_currency.id, target_currency.id, total_amount, context=ctx)
|
||||
total_amount_str = rml_parser.formatLang(total_amount, currency_obj=target_currency)
|
||||
|
||||
ret_line['credit'] = credit
|
||||
ret_line['debit'] = debit
|
||||
ret_line['amount_str'] = amount_str
|
||||
ret_line['amount_currency_str'] = amount_currency_str
|
||||
ret_line['total_amount_str'] = total_amount_str # For partial reconciliations
|
||||
ret_line['total_amount_currency_str'] = total_amount_currency_str
|
||||
ret.append(ret_line)
|
||||
return ret
|
||||
|
||||
|
|
|
@ -18,17 +18,31 @@
|
|||
border-top: 0;
|
||||
border-bottom: 0;
|
||||
height: 100%; }
|
||||
.openerp .oe_bank_statement_reconciliation h1 input, .openerp .oe_bank_statement_reconciliation h2 input {
|
||||
height: auto !important; }
|
||||
.openerp .oe_bank_statement_reconciliation h1 {
|
||||
width: 48%;
|
||||
padding: 0 0 0 15px;
|
||||
margin: 0 0 25px 0;
|
||||
float: left;
|
||||
font-size: 2em; }
|
||||
font-size: 2em;
|
||||
height: 1.5em; }
|
||||
.openerp .oe_bank_statement_reconciliation .statement_name span {
|
||||
line-height: 1.5em;
|
||||
cursor: pointer; }
|
||||
.openerp .oe_bank_statement_reconciliation .change_statement_name_container {
|
||||
display: none;
|
||||
width: 95%; }
|
||||
.openerp .oe_bank_statement_reconciliation .change_statement_name_container td:first-child, .openerp .oe_bank_statement_reconciliation .change_statement_name_container td:first-child > input {
|
||||
width: 99%; }
|
||||
.openerp .oe_bank_statement_reconciliation .change_statement_name_container td:last-child {
|
||||
width: 1%;
|
||||
padding-left: 3px; }
|
||||
.openerp .oe_bank_statement_reconciliation h2 {
|
||||
font-size: 1.8em; }
|
||||
.openerp .oe_bank_statement_reconciliation .progress {
|
||||
width: 49%;
|
||||
margin: 4px 15px 0 0;
|
||||
margin: 10px 15px 0 0;
|
||||
float: right;
|
||||
position: relative;
|
||||
display: inline-block; }
|
||||
|
@ -121,6 +135,12 @@
|
|||
-ms-transform: rotate(90deg);
|
||||
-o-transform: rotate(90deg);
|
||||
transform: rotate(90deg); }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .partner_name .change_partner {
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
margin: 0 10px 0 5px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .partner_name:hover .change_partner {
|
||||
display: inline; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .change_partner_container {
|
||||
width: 200px;
|
||||
display: none;
|
||||
|
@ -181,43 +201,44 @@
|
|||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr .undo_partial_reconcile_button, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr .undo_partial_reconcile_button {
|
||||
color: #555;
|
||||
padding-right: 5px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td {
|
||||
border-top: 1px solid #bbbbbb;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 5px;
|
||||
background-color: #f0f0f0;
|
||||
-webkit-transition-property: background-color;
|
||||
-moz-transition-property: background-color;
|
||||
-ms-transition-property: background-color;
|
||||
transition-property: background-color;
|
||||
-webkit-transition-duration: 300ms;
|
||||
-moz-transition-duration: 300ms;
|
||||
-ms-transition-duration: 300ms;
|
||||
-o-transition-duration: 300ms;
|
||||
transition-duration: 300ms; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td.cell_action, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td.cell_info_popover {
|
||||
border-top: none;
|
||||
background: white !important;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 3px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption {
|
||||
text-align: left;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
height: 26px;
|
||||
margin: 0 15px 4px 15px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption button {
|
||||
float: right; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption button:disabled {
|
||||
opacity: 0.5; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption > span, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption > input {
|
||||
position: relative;
|
||||
top: 7px;
|
||||
/* meh */
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view {
|
||||
border-collapse: separate; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td {
|
||||
border-top: 1px solid #bbb;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 5px;
|
||||
background-color: #f0f0f0;
|
||||
-webkit-transition-property: background-color;
|
||||
-moz-transition-property: background-color;
|
||||
-ms-transition-property: background-color;
|
||||
transition-property: background-color;
|
||||
-webkit-transition-duration: 300ms;
|
||||
-moz-transition-duration: 300ms;
|
||||
-ms-transition-duration: 300ms;
|
||||
-o-transition-duration: 300ms;
|
||||
transition-duration: 300ms; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td.cell_action, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view .initial_line > td.cell_info_popover {
|
||||
border-top: none;
|
||||
background: white !important;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 3px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption {
|
||||
text-align: left;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
cursor: pointer; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td.cell_credit {
|
||||
border-left: 1px solid black; }
|
||||
height: 26px;
|
||||
margin: 0 15px 4px 15px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption button {
|
||||
float: right; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption button:disabled {
|
||||
opacity: 0.5; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption > span, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption > input {
|
||||
position: relative;
|
||||
top: 7px;
|
||||
/* meh */
|
||||
font-weight: bold; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td.cell_credit {
|
||||
border-left: 1px solid #000; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match .match_controls {
|
||||
padding: 0 0 5px 18px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match .match_controls .filter {
|
||||
|
@ -250,9 +271,11 @@
|
|||
width: 49%;
|
||||
height: 26px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .create .oe_form > table:nth-child(2n+1) {
|
||||
float: left; }
|
||||
float: left;
|
||||
clear: left; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .create .oe_form > table:nth-child(2n) {
|
||||
float: right; }
|
||||
float: right;
|
||||
clear: right; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .create .oe_form > table th {
|
||||
font-weight: bold;
|
||||
line-height: 26px;
|
||||
|
|
|
@ -31,12 +31,35 @@ $aestetic_animation_speed: 300ms;
|
|||
}
|
||||
}
|
||||
|
||||
h1 input, h2 input {
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
width: 48%;
|
||||
padding: 0 0 0 $actionColWidth;
|
||||
margin: 0 0 25px 0;
|
||||
float: left;
|
||||
font-size: 2em;
|
||||
height: 1.5em;
|
||||
}
|
||||
|
||||
.statement_name span {
|
||||
line-height: 1.5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.change_statement_name_container {
|
||||
display: none;
|
||||
width: 95%;
|
||||
|
||||
td:first-child, td:first-child > input {
|
||||
width: 99%;
|
||||
}
|
||||
td:last-child {
|
||||
width: 1%;
|
||||
padding-left: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
|
@ -45,7 +68,7 @@ $aestetic_animation_speed: 300ms;
|
|||
|
||||
.progress {
|
||||
width: 49%;
|
||||
margin: 4px $actionColWidth 0 0;
|
||||
margin: 10px $actionColWidth 0 0;
|
||||
float: right;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
@ -173,6 +196,17 @@ $aestetic_animation_speed: 300ms;
|
|||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.partner_name {
|
||||
.change_partner {
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
margin: 0 10px 0 5px;
|
||||
}
|
||||
&:hover .change_partner {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.change_partner_container {
|
||||
width: 200px;
|
||||
display: none;
|
||||
|
@ -308,6 +342,7 @@ $aestetic_animation_speed: 300ms;
|
|||
|
||||
/* Partie infos */
|
||||
.accounting_view {
|
||||
border-collapse: separate;
|
||||
|
||||
.initial_line > td {
|
||||
border-top: $lightBorder;
|
||||
|
@ -351,7 +386,6 @@ $aestetic_animation_speed: 300ms;
|
|||
> span, > input {
|
||||
position: relative; top: 7px; /* meh */
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,8 +450,8 @@ $aestetic_animation_speed: 300ms;
|
|||
width: 49%;
|
||||
height: 26px;
|
||||
|
||||
&:nth-child(2n+1) { float: left; }
|
||||
&:nth-child(2n) { float: right; }
|
||||
&:nth-child(2n+1) { float: left; clear: left; }
|
||||
&:nth-child(2n) { float: right; clear: right; }
|
||||
|
||||
th {
|
||||
font-weight: bold;
|
||||
|
|
|
@ -9,12 +9,20 @@ openerp.account = function (instance) {
|
|||
instance.web.client_actions.add('bank_statement_reconciliation_view', 'instance.web.account.bankStatementReconciliation');
|
||||
instance.web.account.bankStatementReconciliation = instance.web.Widget.extend({
|
||||
className: 'oe_bank_statement_reconciliation',
|
||||
|
||||
events: {
|
||||
"click .statement_name span": "statementNameClickHandler",
|
||||
"keyup .change_statement_name_field": "changeStatementNameFieldHandler",
|
||||
"click .change_statement_name_button": "changeStatementButtonClickHandler",
|
||||
},
|
||||
|
||||
init: function(parent, context) {
|
||||
this._super(parent);
|
||||
this.max_reconciliations_displayed = 10;
|
||||
if (context.context.statement_id) this.statement_ids = [context.context.statement_id];
|
||||
if (context.context.statement_ids) this.statement_ids = context.context.statement_ids;
|
||||
this.single_statement = this.statement_ids !== undefined && this.statement_ids.length === 1;
|
||||
this.multiple_statements = this.statement_ids !== undefined && this.statement_ids.length > 1;
|
||||
this.title = context.context.title || _t("Reconciliation");
|
||||
this.st_lines = [];
|
||||
this.last_displayed_reconciliation_index = undefined; // Flow control
|
||||
|
@ -127,8 +135,8 @@ openerp.account = function (instance) {
|
|||
if (self.statement_ids && self.statement_ids.length > 0) {
|
||||
lines_filter.push(['statement_id', 'in', self.statement_ids]);
|
||||
|
||||
// If only one statement, retreive its name
|
||||
if (self.statement_ids.length === 1) {
|
||||
// If only one statement, display its name as title and allow to modify it
|
||||
if (self.single_statement) {
|
||||
deferred_promises.push(self.model_bank_statement
|
||||
.query(["name"])
|
||||
.filter([['id', '=', self.statement_ids[0]]])
|
||||
|
@ -211,7 +219,11 @@ openerp.account = function (instance) {
|
|||
});
|
||||
|
||||
// Render and display
|
||||
self.$el.prepend(QWeb.render("bank_statement_reconciliation", {title: self.title, total_lines: self.already_reconciled_lines+self.st_lines.length}));
|
||||
self.$el.prepend(QWeb.render("bank_statement_reconciliation", {
|
||||
title: self.title,
|
||||
single_statement: self.single_statement,
|
||||
total_lines: self.already_reconciled_lines+self.st_lines.length
|
||||
}));
|
||||
self.updateProgressbar();
|
||||
var reconciliations_to_show = self.st_lines.slice(0, self.max_reconciliations_displayed);
|
||||
self.last_displayed_reconciliation_index = reconciliations_to_show.length;
|
||||
|
@ -222,33 +234,135 @@ openerp.account = function (instance) {
|
|||
.call("get_data_for_reconciliations", [reconciliations_to_show])
|
||||
.then(function (data) {
|
||||
var child_promises = [];
|
||||
_.each(reconciliations_to_show, function(st_line_id){
|
||||
var datum = data.shift();
|
||||
child_promises.push(self.displayReconciliation(st_line_id, 'inactive', false, true, datum.st_line, datum.reconciliation_proposition));
|
||||
});
|
||||
while ((datum = data.shift()) !== undefined)
|
||||
child_promises.push(self.displayReconciliation(datum.st_line.id, 'inactive', false, true, datum.st_line, datum.reconciliation_proposition));
|
||||
$.when.apply($, child_promises).then(function(){
|
||||
self.getChildren()[0].set("mode", "match");
|
||||
self.$(".reconciliation_lines_container").animate({opacity: 1}, self.aestetic_animation_speed);
|
||||
self.getChildren()[0].set("mode", "match");
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
statementNameClickHandler: function() {
|
||||
if (! this.single_statement) return;
|
||||
this.$(".statement_name span").hide();
|
||||
this.$(".change_statement_name_field").attr("value", this.title);
|
||||
this.$(".change_statement_name_container").show();
|
||||
this.$(".change_statement_name_field").focus();
|
||||
},
|
||||
|
||||
changeStatementNameFieldHandler: function(e) {
|
||||
var name = this.$(".change_statement_name_field").val();
|
||||
if (name === "") this.$(".change_statement_name_button").attr("disabled", "disabled");
|
||||
else this.$(".change_statement_name_button").removeAttr("disabled");
|
||||
|
||||
if (name !== "" && e.which === 13) // Enter
|
||||
this.$(".change_statement_name_button").trigger("click");
|
||||
if (e.which === 27) { // Escape
|
||||
this.$(".statement_name span").show();
|
||||
this.$(".change_statement_name_container").hide();
|
||||
}
|
||||
},
|
||||
|
||||
changeStatementButtonClickHandler: function() {
|
||||
var self = this;
|
||||
if (! self.single_statement) return;
|
||||
var name = self.$(".change_statement_name_field").val();
|
||||
if (name === "") return;
|
||||
return self.model_bank_statement
|
||||
.call("write", [[self.statement_ids[0]], {'name': name}])
|
||||
.then(function () {
|
||||
self.title = name;
|
||||
self.$(".statement_name span").text(name).show();
|
||||
self.$(".change_statement_name_container").hide();
|
||||
});
|
||||
},
|
||||
|
||||
keyboardShortcutsHandler: function(e) {
|
||||
var self = this;
|
||||
if ((e.which === 13 || e.which === 10) && (e.ctrlKey || e.metaKey)) {
|
||||
$.each(self.getChildren(), function(i, o){
|
||||
if (o.is_valid && o.persistAndDestroy()) {
|
||||
self.lines_reconciled_with_ctrl_enter++;
|
||||
}
|
||||
});
|
||||
self.persistReconciliations(_.filter(self.getChildren(), function(o) { return o.is_valid; }));
|
||||
}
|
||||
},
|
||||
|
||||
persistReconciliations: function(reconciliations) {
|
||||
if (reconciliations.length === 0) return;
|
||||
var self = this;
|
||||
// Prepare data
|
||||
var data = [];
|
||||
for (var i=0; i<reconciliations.length; i++) {
|
||||
var child = reconciliations[i];
|
||||
data.push([child.st_line_id, child.makeMoveLineDicts()]);
|
||||
}
|
||||
var deferred_animation = self.$(".reconciliation_lines_container").fadeOut(self.aestetic_animation_speed);
|
||||
deferred_rpc = self.model_bank_statement_line.call("process_reconciliations", [data]);
|
||||
return $.when(deferred_animation, deferred_rpc)
|
||||
.done(function() {
|
||||
// Remove children
|
||||
for (var i=0; i<reconciliations.length; i++) {
|
||||
var child = reconciliations[i];
|
||||
self.unexcludeMoveLines(child, child.partner_id, child.get("mv_lines_selected"));
|
||||
$.each(child.$(".bootstrap_popover"), function(){ $(this).popover('destroy') });
|
||||
child.destroy();
|
||||
}
|
||||
// Update interface
|
||||
self.lines_reconciled_with_ctrl_enter += reconciliations.length;
|
||||
self.reconciled_lines += reconciliations.length;
|
||||
self.updateProgressbar();
|
||||
self.doReloadMenuReconciliation();
|
||||
|
||||
// Display new line if there are left
|
||||
if (self.last_displayed_reconciliation_index < self.st_lines.length) {
|
||||
var begin = self.last_displayed_reconciliation_index;
|
||||
var end = Math.min((begin+self.max_reconciliations_displayed), self.st_lines.length);
|
||||
var reconciliations_to_show = self.st_lines.slice(begin, end);
|
||||
|
||||
return self.model_bank_statement_line
|
||||
.call("get_data_for_reconciliations", [reconciliations_to_show])
|
||||
.then(function (data) {
|
||||
var child_promises = [];
|
||||
var datum;
|
||||
while ((datum = data.shift()) !== undefined) {
|
||||
var context = {
|
||||
st_line_id: datum.st_line.id,
|
||||
mode: 'inactive',
|
||||
animate_entrance: false,
|
||||
initial_data_provided: true,
|
||||
st_line: datum.st_line,
|
||||
reconciliation_proposition: datum.reconciliation_proposition,
|
||||
};
|
||||
var widget = new instance.web.account.bankStatementReconciliationLine(self, context);
|
||||
child_promises.push(widget.appendTo(self.$(".reconciliation_lines_container")));
|
||||
}
|
||||
self.last_displayed_reconciliation_index += reconciliations_to_show.length;
|
||||
return $.when.apply($, child_promises).then(function() {
|
||||
// Put the first line in match mode
|
||||
if (self.reconciled_lines !== self.st_lines.length) {
|
||||
var first_child = self.getChildren()[0];
|
||||
if (first_child.get("mode") === "inactive") {
|
||||
first_child.set("mode", "match");
|
||||
}
|
||||
}
|
||||
self.$(".reconciliation_lines_container").fadeIn(self.aestetic_animation_speed);
|
||||
});
|
||||
});
|
||||
}
|
||||
// Congratulate the user if the work is done
|
||||
if (self.reconciled_lines === self.st_lines.length) {
|
||||
self.displayDoneMessage();
|
||||
}
|
||||
}).fail(function() {
|
||||
self.$(".reconciliation_lines_container").fadeIn(self.aestetic_animation_speed);
|
||||
});
|
||||
},
|
||||
|
||||
// Adds move line ids to the list of move lines not to fetch for a given partner
|
||||
// This is required because the same move line cannot be selected for multiple reconciliation
|
||||
excludeMoveLines: function(source_child, partner_id, line_ids) {
|
||||
// and because for a partial reconciliation only one line can be fetched)
|
||||
excludeMoveLines: function(source_child, partner_id, lines) {
|
||||
var self = this;
|
||||
var line_ids = _.collect(lines, function(o) { return o.id });
|
||||
|
||||
var excluded_ids = this.excluded_move_lines_ids[partner_id];
|
||||
var excluded_move_lines_changed = false;
|
||||
|
@ -285,9 +399,10 @@ openerp.account = function (instance) {
|
|||
});
|
||||
},
|
||||
|
||||
unexcludeMoveLines: function(source_child, partner_id, line_ids) {
|
||||
unexcludeMoveLines: function(source_child, partner_id, lines) {
|
||||
var self = this;
|
||||
|
||||
var line_ids = _.collect(lines, function(o) { return o.id });
|
||||
|
||||
var initial_excluded_lines_num = this.excluded_move_lines_ids[partner_id].length;
|
||||
this.excluded_move_lines_ids[partner_id] = _.difference(this.excluded_move_lines_ids[partner_id], line_ids);
|
||||
if (this.excluded_move_lines_ids[partner_id].length === initial_excluded_lines_num)
|
||||
|
@ -341,11 +456,36 @@ openerp.account = function (instance) {
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
goBackToStatementsTreeView: function() {
|
||||
var self = this;
|
||||
new instance.web.Model("ir.model.data")
|
||||
.call("get_object_reference", ['account', 'action_bank_statement_tree'])
|
||||
.then(function (result) {
|
||||
var action_id = result[1];
|
||||
// Warning : altough I don't see why this widget wouldn't be directly instanciated by the
|
||||
// action manager, if it wasn't, this code wouldn't work. You'd have to do something like :
|
||||
// var action_manager = self;
|
||||
// while (! action_manager instanceof ActionManager)
|
||||
// action_manager = action_manager.getParent();
|
||||
var action_manager = self.getParent();
|
||||
var breadcrumbs = action_manager.breadcrumbs;
|
||||
var found = false;
|
||||
for (var i=breadcrumbs.length-1; i>=0; i--) {
|
||||
if (breadcrumbs[i].action && breadcrumbs[i].action.id === action_id) {
|
||||
var title = breadcrumbs[i].get_title();
|
||||
action_manager.select_breadcrumb(i, _.isArray(title) ? i : undefined);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
instance.web.Home(self);
|
||||
});
|
||||
},
|
||||
|
||||
displayDoneMessage: function() {
|
||||
var self = this;
|
||||
|
||||
var is_single_statement = self.statement_ids !== undefined && self.statement_ids.length === 1;
|
||||
var sec_taken = Math.round((Date.now()-self.time_widget_loaded)/1000);
|
||||
var sec_per_item = Math.round(sec_taken/self.reconciled_lines);
|
||||
var achievements = [];
|
||||
|
@ -381,7 +521,8 @@ openerp.account = function (instance) {
|
|||
transactions_done: self.reconciled_lines,
|
||||
done_with_ctrl_enter: self.lines_reconciled_with_ctrl_enter,
|
||||
achievements: achievements,
|
||||
has_statement_id: is_single_statement,
|
||||
single_statement: self.single_statement,
|
||||
multiple_statements: self.multiple_statements,
|
||||
}));
|
||||
|
||||
// Animate it
|
||||
|
@ -392,32 +533,28 @@ openerp.account = function (instance) {
|
|||
|
||||
// Make it interactive
|
||||
self.$(".achievement").popover({'placement': 'top', 'container': self.el, 'trigger': 'hover'});
|
||||
|
||||
self.$(".button_back_to_statement").click(function() {
|
||||
self.do_action({
|
||||
type: 'ir.actions.client',
|
||||
tag: 'history_back',
|
||||
});
|
||||
});
|
||||
|
||||
if (is_single_statement && self.$(".button_close_statement").length !== 0) {
|
||||
if (self.$(".button_back_to_statement").length !== 0) {
|
||||
self.$(".button_back_to_statement").click(function() {
|
||||
self.goBackToStatementsTreeView();
|
||||
});
|
||||
}
|
||||
|
||||
if (self.$(".button_close_statement").length !== 0) {
|
||||
self.$(".button_close_statement").hide();
|
||||
self.model_bank_statement
|
||||
.query(["balance_end_real", "balance_end"])
|
||||
.filter([['id', '=', self.statement_ids[0]]])
|
||||
.first()
|
||||
.filter([['id', 'in', self.statement_ids]])
|
||||
.all()
|
||||
.then(function(data){
|
||||
if (data.balance_end_real === data.balance_end) {
|
||||
if (_.all(data, function(o) { return o.balance_end_real === o.balance_end })) {
|
||||
self.$(".button_close_statement").show();
|
||||
self.$(".button_close_statement").click(function() {
|
||||
self.$(".button_close_statement").attr("disabled", "disabled");
|
||||
self.model_bank_statement
|
||||
.call("button_confirm_bank", [[self.statement_ids[0]]])
|
||||
.call("button_confirm_bank", [self.statement_ids])
|
||||
.then(function () {
|
||||
self.do_action({
|
||||
type: 'ir.actions.client',
|
||||
tag: 'history_back',
|
||||
});
|
||||
self.goBackToStatementsTreeView();
|
||||
}, function() {
|
||||
self.$(".button_close_statement").removeAttr("disabled");
|
||||
});
|
||||
|
@ -455,7 +592,7 @@ openerp.account = function (instance) {
|
|||
className: 'oe_bank_statement_reconciliation_line',
|
||||
|
||||
events: {
|
||||
"click .partner_name": "partnerNameClickHandler",
|
||||
"click .change_partner": "changePartnerClickHandler",
|
||||
"click .button_ok": "persistAndDestroy",
|
||||
"click .mv_line": "moveLineClickHandler",
|
||||
"click .initial_line": "initialLineClickHandler",
|
||||
|
@ -485,10 +622,9 @@ openerp.account = function (instance) {
|
|||
this.decorateStatementLine(this.st_line);
|
||||
|
||||
// Exclude selected move lines
|
||||
var selected_line_ids = _(context.reconciliation_proposition).map(function(o){ return o.id });
|
||||
if (this.getParent().excluded_move_lines_ids[this.partner_id] === undefined)
|
||||
this.getParent().excluded_move_lines_ids[this.partner_id] = [];
|
||||
this.getParent().excludeMoveLines(this, this.partner_id, selected_line_ids);
|
||||
this.getParent().excludeMoveLines(this, this.partner_id, context.reconciliation_proposition);
|
||||
} else {
|
||||
this.set("mv_lines_selected", []);
|
||||
this.st_line = undefined;
|
||||
|
@ -634,12 +770,13 @@ openerp.account = function (instance) {
|
|||
restart: function(mode) {
|
||||
var self = this;
|
||||
mode = (mode === undefined ? 'inactive' : mode);
|
||||
self.context.animate_entrance = false;
|
||||
self.$el.css("height", self.$el.outerHeight());
|
||||
// Destroy everything
|
||||
_.each(self.getChildren(), function(o){ o.destroy() });
|
||||
self.is_consistent = false;
|
||||
return $.when(self.$el.animate({opacity: 0}, self.animation_speed)).then(function() {
|
||||
self.getParent().unexcludeMoveLines(self, self.partner_id, _.map(self.get("mv_lines_selected"), function(o){ return o.id }));
|
||||
self.getParent().unexcludeMoveLines(self, self.partner_id, self.get("mv_lines_selected"));
|
||||
$.each(self.$(".bootstrap_popover"), function(){ $(this).popover('destroy') });
|
||||
self.$el.empty();
|
||||
self.$el.removeClass("no_partner");
|
||||
|
@ -786,7 +923,7 @@ openerp.account = function (instance) {
|
|||
self.change_partner_field.on("change:value", self.change_partner_field, function() {
|
||||
self.changePartner(this.get_value());
|
||||
});
|
||||
self.change_partner_field.$el.find("input").attr("placeholder", _t("Select Partner"));
|
||||
self.change_partner_field.$el.find("input").attr("placeholder", self.st_line.communication_partner_name || _t("Select Partner"));
|
||||
|
||||
field_manager.do_show();
|
||||
},
|
||||
|
@ -875,18 +1012,7 @@ openerp.account = function (instance) {
|
|||
return;
|
||||
}
|
||||
|
||||
// If statement line has no partner, give it the partner of the selected move line
|
||||
if (!this.st_line.partner_id && line.partner_id) {
|
||||
self.changePartner(line.partner_id, function() {
|
||||
self.selectMoveLine(mv_line);
|
||||
});
|
||||
} else {
|
||||
self.set("mv_lines_selected", self.get("mv_lines_selected").concat(line));
|
||||
// $(mv_line).attr('data-selected','true');
|
||||
// self.set("mv_lines_selected", self.get("mv_lines_selected").concat(line));
|
||||
// this.set("mv_lines", _.reject(this.get("mv_lines"), function(o){return o.id == line_id}));
|
||||
// this.getParent().excludeMoveLines([line_id]);
|
||||
}
|
||||
self.set("mv_lines_selected", self.get("mv_lines_selected").concat(line));
|
||||
},
|
||||
|
||||
deselectMoveLine: function(mv_line) {
|
||||
|
@ -906,11 +1032,6 @@ openerp.account = function (instance) {
|
|||
self.$el.removeClass("no_match");
|
||||
self.set("mode", "match");
|
||||
self.set("mv_lines_selected", mv_lines_selected);
|
||||
|
||||
|
||||
// $(mv_line).attr('data-selected','false');
|
||||
// this.set("mv_lines", this.get("mv_lines").concat(line));
|
||||
// this.getParent().unexcludeMoveLines([line_id]);
|
||||
},
|
||||
|
||||
/** Matches pagination */
|
||||
|
@ -1019,20 +1140,18 @@ openerp.account = function (instance) {
|
|||
lineOpenBalanceClickHandler: function() {
|
||||
var self = this;
|
||||
if (self.get("mode") === "create") {
|
||||
self.addLineBeingEdited();
|
||||
self.set("mode", "match");
|
||||
} else {
|
||||
self.set("mode", "create");
|
||||
}
|
||||
},
|
||||
|
||||
partnerNameClickHandler: function() {
|
||||
changePartnerClickHandler: function() {
|
||||
var self = this;
|
||||
// Delete statement line's partner
|
||||
return self.changePartner('', function() {
|
||||
self.$(".partner_name").hide();
|
||||
self.$(".change_partner_container").show();
|
||||
});
|
||||
self.$(".change_partner_container").find("input").attr("placeholder", self.st_line.partner_name);
|
||||
self.$(".change_partner_container").show();
|
||||
self.$(".partner_name").hide();
|
||||
self.change_partner_field.$drop_down.trigger("click");
|
||||
},
|
||||
|
||||
|
||||
|
@ -1158,27 +1277,13 @@ openerp.account = function (instance) {
|
|||
}
|
||||
},
|
||||
|
||||
modeChanged: function() {
|
||||
modeChanged: function(o, val) {
|
||||
var self = this;
|
||||
|
||||
self.$(".action_pane.active").removeClass("active");
|
||||
|
||||
// Special case hack : if no_partner, either inactive or create
|
||||
if (self.st_line.has_no_partner) {
|
||||
if (self.get("mode") === "inactive") {
|
||||
self.$(".match").slideUp(self.animation_speed);
|
||||
self.$(".create").slideUp(self.animation_speed);
|
||||
self.$(".toggle_match").removeClass("visible_toggle");
|
||||
self.el.dataset.mode = "inactive";
|
||||
} else {
|
||||
self.initializeCreateForm();
|
||||
self.$(".match").slideUp(self.animation_speed);
|
||||
self.$(".create").slideDown(self.animation_speed);
|
||||
self.$(".toggle_match").addClass("visible_toggle");
|
||||
self.el.dataset.mode = "create";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (val.oldValue === "create")
|
||||
self.addLineBeingEdited();
|
||||
|
||||
if (self.get("mode") === "inactive") {
|
||||
self.$(".match").slideUp(self.animation_speed);
|
||||
|
@ -1186,14 +1291,21 @@ openerp.account = function (instance) {
|
|||
self.el.dataset.mode = "inactive";
|
||||
|
||||
} else if (self.get("mode") === "match") {
|
||||
// TODO : remove this old_animation_speed / new_animation_speed hack
|
||||
// when .on handler's returned deferred's no longer lost
|
||||
var old_animation_speed = self.animation_speed;
|
||||
return $.when(self.updateMatches()).then(function() {
|
||||
var new_animation_speed = self.animation_speed;
|
||||
self.animation_speed = old_animation_speed;
|
||||
if (self.$el.hasClass("no_match")) {
|
||||
self.set("mode", "inactive");
|
||||
self.animation_speed = 0;
|
||||
self.set("mode", "create");
|
||||
return;
|
||||
}
|
||||
self.$(".match").slideDown(self.animation_speed);
|
||||
self.$(".create").slideUp(self.animation_speed);
|
||||
self.el.dataset.mode = "match";
|
||||
self.animation_speed = new_animation_speed;
|
||||
});
|
||||
|
||||
} else if (self.get("mode") === "create") {
|
||||
|
@ -1224,7 +1336,14 @@ openerp.account = function (instance) {
|
|||
} else {
|
||||
self.$el.removeClass("no_match");
|
||||
}
|
||||
|
||||
|
||||
_.each(self.get("mv_lines"), function(line) {
|
||||
if (line.partial_reconciliation_siblings_ids.length > 0) {
|
||||
var correct_format = _.collect(line.partial_reconciliation_siblings_ids, function(o) { return {'id': o} });
|
||||
self.getParent().excludeMoveLines(self, self.partner_id, correct_format);
|
||||
}
|
||||
});
|
||||
|
||||
self.updateMatchView();
|
||||
self.updatePagerControls();
|
||||
},
|
||||
|
@ -1232,11 +1351,11 @@ openerp.account = function (instance) {
|
|||
mvLinesSelectedChanged: function(elt, val) {
|
||||
var self = this;
|
||||
|
||||
var added_lines_ids = _.map(_.difference(val.newValue, val.oldValue), function(o){ return o.id });
|
||||
var removed_lines_ids = _.map(_.difference(val.oldValue, val.newValue), function(o){ return o.id });
|
||||
var added_lines = _.difference(val.newValue, val.oldValue);
|
||||
var removed_lines = _.difference(val.oldValue, val.newValue);
|
||||
|
||||
self.getParent().excludeMoveLines(self, self.partner_id, added_lines_ids);
|
||||
self.getParent().unexcludeMoveLines(self, self.partner_id, removed_lines_ids);
|
||||
self.getParent().excludeMoveLines(self, self.partner_id, added_lines);
|
||||
self.getParent().unexcludeMoveLines(self, self.partner_id, removed_lines);
|
||||
|
||||
$.when(self.updateMatches()).then(function(){
|
||||
self.updateAccountingViewMatchedLines();
|
||||
|
@ -1374,10 +1493,9 @@ openerp.account = function (instance) {
|
|||
var self = this;
|
||||
var mv_lines_selected = self.get("mv_lines_selected");
|
||||
var lines_selected_num = mv_lines_selected.length;
|
||||
var lines_created_num = self.getCreatedLines().length;
|
||||
|
||||
// Undo partial reconciliation if necessary
|
||||
if (lines_selected_num !== 1 || lines_created_num !== 0) {
|
||||
if (lines_selected_num !== 1) {
|
||||
_.each(mv_lines_selected, function(line) {
|
||||
if (line.partial_reconcile === true) self.unpartialReconcileLine(line);
|
||||
if (line.propose_partial_reconcile === true) line.propose_partial_reconcile = false;
|
||||
|
@ -1394,20 +1512,26 @@ openerp.account = function (instance) {
|
|||
_.each(self.getCreatedLines(), function(o) {
|
||||
balance += o.amount;
|
||||
});
|
||||
// Should work as long as currency's rounding factor is > 0.001 (ie: don't use gold kilos as a currency)
|
||||
// Dealing with floating-point
|
||||
balance = Math.round(balance*1000)/1000;
|
||||
self.set("balance", balance);
|
||||
|
||||
// Propose partial reconciliation if necessary
|
||||
if (lines_selected_num === 1 && lines_created_num === 0 && self.st_line.amount * balance > 0) {
|
||||
if (lines_selected_num === 1 &&
|
||||
self.st_line.amount * balance > 0 &&
|
||||
self.st_line.amount * (mv_lines_selected[0].debit - mv_lines_selected[0].credit) < 0 &&
|
||||
! mv_lines_selected[0].partial_reconcile) {
|
||||
|
||||
mv_lines_selected[0].propose_partial_reconcile = true;
|
||||
self.updateAccountingViewMatchedLines();
|
||||
} else if (lines_selected_num === 1) {
|
||||
mv_lines_selected[0].propose_partial_reconcile = false;
|
||||
self.updateAccountingViewMatchedLines();
|
||||
}
|
||||
},
|
||||
|
||||
// Loads move lines according to the widget's state
|
||||
updateMatches: function() {
|
||||
if (this.st_line.has_no_partner) return;
|
||||
var self = this;
|
||||
var deselected_lines_num = self.mv_lines_deselected.length;
|
||||
var move_lines_num = 0;
|
||||
|
@ -1415,8 +1539,13 @@ openerp.account = function (instance) {
|
|||
if (offset < 0) offset = 0;
|
||||
var limit = (self.get("pager_index")+1) * self.max_move_lines_displayed - deselected_lines_num;
|
||||
if (limit > self.max_move_lines_displayed) limit = self.max_move_lines_displayed;
|
||||
var excluded_ids = _.collect(self.get("mv_lines_selected").concat(self.mv_lines_deselected), function(o){ return o.id });
|
||||
excluded_ids = excluded_ids.concat(self.getParent().excluded_move_lines_ids[self.partner_id]);
|
||||
var excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id];
|
||||
var excluded_ids = _.collect(self.get("mv_lines_selected").concat(self.mv_lines_deselected), function(o) { return o.id; });
|
||||
var globally_excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id];
|
||||
if (globally_excluded_ids !== undefined)
|
||||
for (var i=0; i<globally_excluded_ids.length; i++)
|
||||
if (excluded_ids.indexOf(globally_excluded_ids[i]) === -1)
|
||||
excluded_ids.push(globally_excluded_ids[i]);
|
||||
|
||||
var deferred_move_lines;
|
||||
var move_lines = [];
|
||||
|
@ -1454,6 +1583,7 @@ openerp.account = function (instance) {
|
|||
.call("write", [[self.st_line_id], {'partner_id': partner_id}])
|
||||
.then(function () {
|
||||
self.do_load_reconciliation_proposition = false; // of the server might set the statement line's partner
|
||||
self.animation_speed = 0;
|
||||
return $.when(self.restart(self.get("mode"))).then(function(){
|
||||
self.do_load_reconciliation_proposition = true;
|
||||
self.is_consistent = true;
|
||||
|
@ -1501,6 +1631,15 @@ openerp.account = function (instance) {
|
|||
|
||||
return dict;
|
||||
},
|
||||
|
||||
makeMoveLineDicts: function() {
|
||||
var self = this;
|
||||
var mv_line_dicts = [];
|
||||
_.each(self.get("mv_lines_selected"), function(o) { mv_line_dicts.push(self.prepareSelectedMoveLineForPersisting(o)) });
|
||||
_.each(self.getCreatedLines(), function(o) { mv_line_dicts.push(self.prepareCreatedMoveLineForPersisting(o)) });
|
||||
if (Math.abs(self.get("balance")).toFixed(3) !== "0.000") mv_line_dicts.push(self.prepareOpenBalanceForPersisting());
|
||||
return mv_line_dicts;
|
||||
},
|
||||
|
||||
// Persist data, notify parent view and terminate widget
|
||||
persistAndDestroy: function(speed) {
|
||||
|
@ -1508,8 +1647,6 @@ openerp.account = function (instance) {
|
|||
speed = (isNaN(speed) ? self.animation_speed : speed);
|
||||
if (! self.is_consistent) return;
|
||||
|
||||
self.getParent().unexcludeMoveLines(self, self.partner_id, _.map(self.get("mv_lines_selected"), function(o){ return o.id }));
|
||||
|
||||
// Sliding animation
|
||||
var height = self.$el.outerHeight();
|
||||
var container = $("<div />");
|
||||
|
@ -1520,8 +1657,10 @@ openerp.account = function (instance) {
|
|||
var deferred_animation = self.$el.parent().slideUp(speed*height/150);
|
||||
|
||||
// RPC
|
||||
return $.when(self.makeRPCForPersisting())
|
||||
return self.model_bank_statement_line
|
||||
.call("process_reconciliation", [self.st_line_id, self.makeMoveLineDicts()])
|
||||
.then(function () {
|
||||
self.getParent().unexcludeMoveLines(self, self.partner_id, self.get("mv_lines_selected"));
|
||||
$.each(self.$(".bootstrap_popover"), function(){ $(this).popover('destroy') });
|
||||
return $.when(deferred_animation).then(function(){
|
||||
self.$el.parent().remove();
|
||||
|
@ -1536,16 +1675,6 @@ openerp.account = function (instance) {
|
|||
});
|
||||
});
|
||||
},
|
||||
|
||||
makeRPCForPersisting: function() {
|
||||
var self = this;
|
||||
var mv_line_dicts = [];
|
||||
_.each(self.get("mv_lines_selected"), function(o) { mv_line_dicts.push(self.prepareSelectedMoveLineForPersisting(o)) });
|
||||
_.each(self.getCreatedLines(), function(o) { mv_line_dicts.push(self.prepareCreatedMoveLineForPersisting(o)) });
|
||||
if (Math.abs(self.get("balance")).toFixed(3) !== "0.000") mv_line_dicts.push(self.prepareOpenBalanceForPersisting());
|
||||
return self.model_bank_statement_line
|
||||
.call("process_reconciliation", [self.st_line_id, mv_line_dicts]);
|
||||
},
|
||||
});
|
||||
|
||||
instance.web.views.add('tree_account_reconciliation', 'instance.web.account.ReconciliationListView');
|
||||
|
|
|
@ -13,7 +13,18 @@
|
|||
|
||||
<t t-name="bank_statement_reconciliation">
|
||||
<div class="oe_form_sheetbg"><div class="oe_form_sheet oe_form_sheet_width">
|
||||
<h1><t t-esc="title"/></h1>
|
||||
<t t-if="single_statement">
|
||||
<h1 class="statement_name">
|
||||
<span><t t-esc="title"/></span>
|
||||
<table class="change_statement_name_container oe_form"><tr>
|
||||
<td><input class="change_statement_name_field" type="text"/></td>
|
||||
<td><button class="change_statement_name_button oe_highlight">OK</button></td>
|
||||
</tr></table>
|
||||
</h1>
|
||||
</t>
|
||||
<t t-if="!single_statement">
|
||||
<h1><t t-esc="title"/></h1>
|
||||
</t>
|
||||
<div class="progress progress-striped">
|
||||
<div class="progress-text"><span class="valuenow">0</span> / <span class="valuemax"><t t-esc="total_lines"/></span></div>
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" t-att-aria-valuemax="total_lines" style="width: 0%;">
|
||||
|
@ -38,9 +49,9 @@
|
|||
</t>
|
||||
</p>
|
||||
<p class="action_buttons">
|
||||
<t t-if="has_statement_id">
|
||||
<button class="button_back_to_statement">Back to statement</button>
|
||||
<button class="button_close_statement">Close the statement</button>
|
||||
<t t-if="single_statement or multiple_statements">
|
||||
<button class="button_back_to_statement">Back to statements list</button>
|
||||
<button class="button_close_statement">Close the statement<t t-if="multiple_statements">s</t></button>
|
||||
</t>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -53,7 +64,10 @@
|
|||
<table class="accounting_view">
|
||||
<caption>
|
||||
<button class="button_ok"></button>
|
||||
<span t-if="! line.has_no_partner" class="partner_name"><t t-esc="line.partner_name"/></span>
|
||||
<span t-if="! line.has_no_partner" class="partner_name">
|
||||
<t t-esc="line.partner_name"/>
|
||||
<span class="change_partner glyphicon glyphicon-pencil"></span>
|
||||
</span>
|
||||
<div class="change_partner_container oe_form"></div>
|
||||
</caption>
|
||||
<tbody class="tbody_initial_line">
|
||||
|
@ -61,7 +75,9 @@
|
|||
<td class="cell_action"><span class="toggle_match glyphicon glyphicon-cog"></span></td>
|
||||
<td class="cell_account_code"><t t-esc="line.account_code"/></td>
|
||||
<td class="cell_due_date"><t t-esc="line.date"/></td>
|
||||
<td class="cell_label"><t t-if="line.name" t-esc="line.name"/>
|
||||
<td class="cell_label">
|
||||
<t t-if="line.name" t-esc="line.name"/>
|
||||
<t t-if="line.ref"> : <t t-esc="line.ref" /></t>
|
||||
<t t-if="line.amount_currency_str"> (<t t-esc="line.amount_currency_str"/>)</t></td>
|
||||
<td class="cell_debit"><t t-if="line.amount > 0">
|
||||
<t t-esc="line.amount_str"/></t></td>
|
||||
|
@ -134,22 +150,26 @@
|
|||
</tr>
|
||||
</t>
|
||||
|
||||
<t t-name="icon_do_partial_reconciliation"><i class="do_partial_reconcile_button fa fa-exclamation-triangle" data-content="This move's amount is higher than the transaction's amount. Click to do a partial reconciliation"></i></t>
|
||||
<t t-name="icon_do_partial_reconciliation"><i class="do_partial_reconcile_button fa fa-exclamation-triangle" data-content="Click to register a partial payment and keep the invoice open. Otherwise it does a full reconciliation."></i></t>
|
||||
|
||||
<t t-name="icon_undo_partial_reconciliation"><i class="undo_partial_reconcile_button fa fa-exclamation-triangle" data-content="Undo the partial reconciliation."></i></t>
|
||||
|
||||
<t t-name="bank_statement_reconciliation_move_line_details">
|
||||
<table class='details'>
|
||||
<tr><td>id</td><td><t t-esc="line.id" /></td></tr>
|
||||
<tr t-if="line.account_code"><td>Account</td><td><t t-esc="line.account_code"/> <t t-esc="line.account_name"/></td></tr>
|
||||
<tr><td>Journal</td><td><t t-esc="line.journal_name"/></td></tr>
|
||||
<tr><td>Period</td><td><t t-esc="line.period_name"/></td></tr>
|
||||
<tr><td>Date</td><td><t t-esc="line.date"/></td></tr>
|
||||
<tr><td>Due Date</td><td><t t-esc="line.q_due_date"/></td></tr>
|
||||
<tr><td>Amount</td>
|
||||
<td><t t-if="line.debit !== 0" t-esc="line.debit_str"/><t t-if="line.credit !== 0" t-esc="line.credit_str"/>
|
||||
<t t-if="line.amount_currency_str"> (<t t-esc="line.amount_currency_str"/>)</t>
|
||||
<t t-if="line.is_partially_reconciled">
|
||||
<tr><td>Total</td><td>
|
||||
<t t-esc="line.total_amount_str"/><t t-if="line.total_amount_currency_str"> (<t t-esc="line.total_amount_currency_str"/>)</t>
|
||||
</td></tr>
|
||||
</t>
|
||||
<tr><td><t t-if="line.is_partially_reconciled">Residual</t><t t-if="! line.is_partially_reconciled">Amount</t></td><td>
|
||||
<t t-if="line.debit !== 0" t-esc="line.debit_str"/><t t-if="line.credit !== 0" t-esc="line.credit_str"/>
|
||||
<t t-if="line.amount_currency_str"> (<t t-esc="line.amount_currency_str"/>)</t>
|
||||
</td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
|
|
Loading…
Reference in New Issue