51
51
_name = 'banking.import.transaction'
52
52
_description = 'Bank import transaction'
53
53
_rec_name = 'transaction'
54
55
signal_duplicate_keys = [
55
56
'execution_date', 'local_account', 'remote_account',
56
57
'remote_owner', 'reference', 'message', 'transferred_amount'
126
127
return [x for x in invoice.move_id.line_id if x.account_id.reconcile]
128
129
def _match_debit_order(
129
self, cr, uid, trans, account_info, log, context=None):
130
self, cr, uid, trans, log, context=None):
131
132
def is_zero(total):
132
133
return self.pool.get('res.currency').is_zero(
133
cr, uid, account_info.currency_id, total)
134
cr, uid, trans.statement_id.currency_id, total)
135
136
payment_order_obj = self.pool.get('payment.order')
136
137
order_ids = payment_order_obj.search(
146
147
if len(candidates) > 0:
147
148
# retrieve the common account_id, if any
148
149
account_id = False
149
for order in candidates:
150
for line in order.line_ids[0].debit_move_line_id.move_id.line_id:
151
if line.account_id.type == 'other':
152
if account_id and account_id != line.account_id.id:
156
account_id = line.account_id.id
158
# TODO at statement line confirm
159
# this action generates a reconcile object
160
# with all the payment order's move lines
161
# on the transfer account
162
# reconcile_id = payment_order_obj.debit_reconcile_transfer(
163
# cr, uid, candidates[0].id, trans.transferred_amount, log, context)
165
# the move_line is only used for the account
166
# and the reconcile_ids, so we return the first.
168
move_line_ids = False,
169
match_type = 'payment_order',
170
payment_order_ids = [x.id for x in candidates],
171
account_id = account_id,
173
partner_bank_id = False,
150
for line in candidate[0].line_ids[0].debit_move_line_id.move_id.line_id:
151
if line.account_id.type == 'other':
152
account_id = line.account_id.id
155
move_line_ids = False,
156
match_type = 'payment_order',
157
payment_order_ids = [x.id for x in candidates],
158
account_id = account_id,
160
partner_bank_id = False,
179
166
def _match_invoice(self, cr, uid, trans, move_lines,
180
partner_ids, bank_account_ids, log, linked_invoices,
167
partner_ids, bank_account_ids,
168
log, linked_invoices,
183
171
Find the invoice belonging to this reference - if there is one
278
266
def is_zero(move_line, total):
279
267
return self.pool.get('res.currency').is_zero(
280
cr, uid, move_line.company_id.currency_id, total)
268
cr, uid, trans.statement_id.currency, total)
282
270
digits = dp.get_precision('Account')(cr)[1]
394
382
# Last partial payment will not flag invoice paid without
395
383
# manual assistence
396
# TODO Stefan: disable this now for the interactive method
397
# Solve this with proper handling of partial reconciliation
384
# TODO Stefan: disable this here for the interactive method
385
# Handled this with proper handling of partial reconciliation
398
386
# and the workflow service
399
387
# invoice_obj = self.pool.get('account.invoice')
400
388
# invoice_obj.write(cr, uid, [invoice.id], {
564
552
transaction.statement_line_id.statement_id.name,
565
553
transaction.statement_line_id.name
567
currency = (transaction.statement_line_id.statement_id.journal_id.currency or
568
transaction.statement_line_id.statement_id.company_id.currency_id)
555
currency = transaction.statement_line_id.statement_id.currency
569
556
line_ids = [transaction.move_line_id.id]
570
557
if transaction.writeoff_move_line_id:
571
558
line_ids.append(transaction.writeoff_move_line_id.id)
665
652
statement_line_obj = self.pool.get('account.bank.statement.line')
666
653
transaction = self.browse(cr, uid, transaction_id, context=context)
667
654
move_line_id = transaction.move_line_id.id
668
currency = (transaction.statement_line_id.statement_id.journal_id.currency or
669
transaction.statement_line_id.statement_id.company_id.currency_id)
655
currency = transaction.statement_line_id.statement_id.currency
670
656
line_ids = [transaction.move_line_id.id]
671
657
if transaction.writeoff_move_line_id:
672
658
line_ids.append(transaction.writeoff_move_line_id.id)
869
855
cr, uid, [move_id], context=context)
871
857
def _match_storno(
872
self, cr, uid, trans, account_info, log, context=None):
858
self, cr, uid, trans, log, context=None):
873
859
payment_line_obj = self.pool.get('payment.line')
874
860
move_line_obj = self.pool.get('account.move.line')
875
861
line_ids = payment_line_obj.search(
882
868
if len(line_ids) == 1:
883
869
account_id = payment_line_obj.get_storno_account_id(
884
870
cr, uid, line_ids[0], trans.transferred_amount,
885
account_info.currency_id, context=None)
871
trans.statement_id.currency, context=None)
888
874
account_id = account_id,
1055
1041
# No filtering can be done, as empty dates carry value for C2B
1056
1042
# communication. Most likely there are much less sent payments
1057
1043
# than reconciled and open/draft payments.
1058
# TODO: Don't payment_orders have a company nowadays?
1044
# Strangely, payment_orders still do not have company_id
1059
1045
cr.execute("SELECT l.id FROM payment_order o, payment_line l "
1060
1046
"WHERE l.order_id = o.id AND "
1061
1047
"o.state = 'sent' AND "
1073
1059
max_trans = len(transactions)
1074
1060
while i < max_trans:
1075
move_info = False # TODO: this at statement_line confirmation time?
1077
1063
# Force FIFO behavior
1078
1064
transaction = injected.pop(0)
1080
1066
transaction = transactions[i]
1082
if transaction.statement_line_id:
1084
# and undo any reconciliation
1068
if (transaction.statement_line_id and
1069
transaction.statement_line_id.state == 'confirmed'):
1070
raise osv.except_osv(
1071
_("Cannot perform match"),
1072
_("Cannot perform match on a confirmed transction"))
1087
1074
if transaction.local_account in error_accounts:
1088
1075
results['trans_skipped_cnt'] += 1
1089
1076
if not injected:
1228
1215
transaction=self.browse(cr, uid, transaction.id, context=context)
1229
1216
# Match full direct debit orders
1230
1217
if transaction.type == bt.DIRECT_DEBIT:
1231
move_info = self._match_debit_order( # TODO reconcile preservation
1232
cr, uid, transaction, account_info, results['log'], context)
1218
move_info = self._match_debit_order(
1219
cr, uid, transaction, results['log'], context)
1233
1220
if transaction.type == bt.STORNO:
1234
move_info = self._match_storno( # TODO reconcile preservation
1235
cr, uid, transaction, account_info, results['log'], context)
1221
move_info = self._match_storno(
1222
cr, uid, transaction, results['log'], context)
1236
1223
# Allow inclusion of generated bank invoices
1237
1224
if transaction.type == bt.BANK_COSTS:
1238
1225
lines = self._match_costs(
1259
1246
country_code = iban.countrycode
1260
1247
elif transaction.remote_owner_country_code:
1261
1248
country_code = transaction.remote_owner_country_code
1262
# TODO: pass the parser's local country code to the transaction
1263
# elif hasattr(parser, 'country_code') and parser.country_code:
1264
# country_code = parser.country_code
1265
# For now, substituted by the company's country
1249
# fallback on the import parsers country code
1250
elif transaction.bank_country_code:
1251
country_code = transaction.bank_country_code
1266
1252
elif company.partner_id and company.partner_id.country:
1267
1253
country_code = company.partner_id.country.code
1423
1409
wf_service.trg_validate(
1424
1410
uid, 'payment.order', id, 'done', cr)
1427
'statement_id': 'statement',
1431
1412
def _get_residual(self, cr, uid, ids, name, args, context=None):
1433
1414
Calculate the residual against the candidate reconciliation.
1508
1489
write_vals.update(vals or {})
1509
1490
return self.write(cr, uid, ids, write_vals, context=context)
1493
# used in bank_import.py, converting non-osv transactions
1494
'statement_id': 'statement',
1512
1499
# start mem_bank_transaction atributes
1513
1500
# see parsers/models.py
1542
1529
'provision_costs_description': fields.char('provision_costs_description', size=24),
1543
1530
'error_message': fields.char('error_message', size=1024),
1544
1531
'storno_retry': fields.boolean('storno_retry'),
1546
1532
# end of mem_bank_transaction_fields
1533
'bank_country_code': fields.char(
1534
'Bank country code', size=2,
1535
help=("Fallback default country for new partner records, "
1536
"as defined by the import parser"),
1547
1538
'company_id': fields.many2one(
1548
1539
'res.company', 'Company', required=True),
1549
1540
'duplicate': fields.boolean('duplicate'),
1748
1739
def _end_balance(self, cursor, user, ids, name, attr, context=None):
1750
This method taken from account/account_bank_statement.py
1751
to take the statement line subflow into account
1741
This method taken from account/account_bank_statement.py and
1742
altered to take the statement line subflow into account
1754
1745
res_currency_obj = self.pool.get('res.currency')