1
# -*- coding: utf-8 -*-
2
##############################################################################
4
# Copyright 2012 Camptocamp SA (Guewen Baconnier)
5
# Copyright (C) 2010 Sébastien Beau
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU Affero General Public License as
9
# published by the Free Software Foundation, either version 3 of the
10
# License, or (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Affero General Public License for more details.
17
# You should have received a copy of the GNU Affero General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
##############################################################################
23
from openerp.osv.orm import Model, AbstractModel
24
from openerp.osv import fields
25
from openerp.tools.translate import _
26
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
29
class easy_reconcile_options(AbstractModel):
30
"""Options of a reconciliation profile, columns
31
shared by the configuration of methods and by the
32
reconciliation wizards. This allows decoupling
33
of the methods with the wizards and allows to
34
launch the wizards alone
37
_name = 'easy.reconcile.options'
39
def _get_rec_base_date(self, cr, uid, context=None):
40
return [('end_period_last_credit', 'End of period of most recent credit'),
41
('newest', 'Most recent move line'),
43
('end_period', 'End of period of most recent move line'),
44
('newest_credit', 'Date of most recent credit'),
45
('newest_debit', 'Date of most recent debit')]
48
'write_off': fields.float('Write off allowed'),
49
'account_lost_id': fields.many2one('account.account', 'Account Lost'),
50
'account_profit_id': fields.many2one('account.account', 'Account Profit'),
51
'journal_id': fields.many2one('account.journal', 'Journal'),
52
'date_base_on': fields.selection(_get_rec_base_date,
54
string='Date of reconcilation'),
55
'filter': fields.char('Filter', size=128),
60
'date_base_on': 'end_period_last_credit',
64
class account_easy_reconcile_method(Model):
66
_name = 'account.easy.reconcile.method'
67
_description = 'reconcile method for account_easy_reconcile'
69
_inherit = 'easy.reconcile.options'
70
_auto = True # restore property set to False by AbstractModel
74
def _get_all_rec_method(self, cr, uid, context=None):
76
('easy.reconcile.simple.name', 'Simple. Amount and Name'),
77
('easy.reconcile.simple.partner', 'Simple. Amount and Partner'),
78
('easy.reconcile.simple.reference', 'Simple. Amount and Reference'),
81
def _get_rec_method(self, cr, uid, context=None):
82
return self._get_all_rec_method(cr, uid, context=None)
85
'name': fields.selection(_get_rec_method, 'Type', size=128, required=True),
86
'sequence': fields.integer('Sequence', required=True,
87
help="The sequence field is used to order the reconcile method"),
88
'task_id': fields.many2one('account.easy.reconcile', 'Task',
89
required=True, ondelete='cascade'),
97
""" Migration stuff, name is not anymore methods names
100
UPDATE account_easy_reconcile_method
101
SET name = 'easy.reconcile.simple.partner'
102
WHERE name = 'action_rec_auto_partner'
105
UPDATE account_easy_reconcile_method
106
SET name = 'easy.reconcile.simple.name'
107
WHERE name = 'action_rec_auto_name'
111
class account_easy_reconcile(Model):
113
_name = 'account.easy.reconcile'
114
_description = 'account easy reconcile'
116
def _get_total_unrec(self, cr, uid, ids, name, arg, context=None):
117
obj_move_line = self.pool.get('account.move.line')
119
for task in self.browse(cr, uid, ids, context=context):
120
res[task.id] = len(obj_move_line.search(
122
[('account_id', '=', task.account.id),
123
('reconcile_id', '=', False),
124
('reconcile_partial_id', '=', False)],
128
def _get_partial_rec(self, cr, uid, ids, name, arg, context=None):
129
obj_move_line = self.pool.get('account.move.line')
131
for task in self.browse(cr, uid, ids, context=context):
132
res[task.id] = len(obj_move_line.search(
134
[('account_id', '=', task.account.id),
135
('reconcile_id', '=', False),
136
('reconcile_partial_id', '!=', False)],
141
'name': fields.char('Name', size=64, required=True),
142
'account': fields.many2one('account.account', 'Account', required=True),
143
'reconcile_method': fields.one2many('account.easy.reconcile.method', 'task_id', 'Method'),
144
'scheduler': fields.many2one('ir.cron', 'scheduler', readonly=True),
145
'rec_log': fields.text('log', readonly=True),
146
'unreconciled_count': fields.function(_get_total_unrec,
147
type='integer', string='Fully Unreconciled Entries'),
148
'reconciled_partial_count': fields.function(_get_partial_rec,
149
type='integer', string='Partially Reconciled Entries'),
152
def copy_data(self, cr, uid, id, default=None, context=None):
155
default = dict(default, rec_log=False, scheduler=False)
156
return super(account_easy_reconcile, self).copy_data(
157
cr, uid, id, default=default, context=context)
159
def _prepare_run_transient(self, cr, uid, rec_method, context=None):
160
return {'account_id': rec_method.task_id.account.id,
161
'write_off': rec_method.write_off,
162
'account_lost_id': rec_method.account_lost_id and \
163
rec_method.account_lost_id.id,
164
'account_profit_id': rec_method.account_profit_id and \
165
rec_method.account_profit_id.id,
166
'journal_id': rec_method.journal_id and rec_method.journal_id.id,
167
'date_base_on': rec_method.date_base_on,
168
'filter': rec_method.filter}
170
def run_reconcile(self, cr, uid, ids, context=None):
174
rec = self.browse(cr, uid, rec_id, context=context)
176
total_partial_rec = 0
179
for method in rec.reconcile_method:
182
rec_model = self.pool.get(method.name)
183
auto_rec_id = rec_model.create(
185
self._prepare_run_transient(cr, uid, method, context=context),
188
rec_ids, partial_ids = rec_model.automatic_reconcile(
189
cr, uid, auto_rec_id, context=context)
191
details.append(_('method %d : full: %d lines, partial: %d lines') % \
192
(count, len(rec_ids), len(partial_ids)))
194
total_rec += len(rec_ids)
195
total_partial_rec += len(partial_ids)
197
log = self.read(cr, uid, rec_id, ['rec_log'], context=context)['rec_log']
198
log_lines = log and log.splitlines() or []
199
log_lines[0:0] = [_("%s : %d lines have been fully reconciled" \
200
" and %d lines have been partially reconciled (%s)") % \
201
(time.strftime(DEFAULT_SERVER_DATETIME_FORMAT), total_rec,
202
total_partial_rec, ' | '.join(details))]
203
log = "\n".join(log_lines)
204
self.write(cr, uid, rec_id, {'rec_log': log}, context=context)