76
73
return self.pool.get('account.analytic.journal').get_journal_type(cr, uid, context)
75
def _get_entry_sequence(self, cr, uid, ids, field_names, args, context=None):
77
Give right entry sequence. Either move_id.move_id.name,
78
or commitment_line_id.commit_id.name, or
79
if the line was imported, the stored name
84
for l in self.browse(cr, uid, ids, context):
87
res[l.id] = l.move_id.move_id.name
88
elif l.commitment_line_id:
89
res[l.id] = l.commitment_line_id.commit_id.name
90
elif l.imported_commitment:
91
res[l.id] = l.imported_entry_sequence
94
# on create the value is inserted by a sql query, so we can retreive it after the insertion
95
# the field has store=True so we don't create a loop
96
# on write the value is not updated by the query, the method always returns the value set at creation
97
res[l.id] = l.entry_sequence
100
def _get_period_id(self, cr, uid, ids, field_name, args, context=None):
102
Fetch period_id from:
109
# Prepare some values
111
period_obj = self.pool.get('account.period')
112
for al in self.browse(cr, uid, ids, context):
114
# UTP-943: Since this ticket, we search period regarding analytic line posting date.
115
period_ids = period_obj.get_period_from_date(cr, uid, date=al.date)
117
res[al.id] = period_ids[0]
120
def _search_period_id(self, cr, uid, obj, name, args, context=None):
122
Search period regarding date.
123
First fetch period date_start and date_stop.
124
Then check that analytic line have a posting date bewteen these two date.
125
Finally do this check as "OR" for each given period.
128
['&', ('date', '>=', '2013-01-01'), ('date', '<=', '2013-01-31')]
129
- January + February:
130
['|', '&', ('date', '>=', '2013-01-01'), ('date', '<=', '2013-01-31'), '&', ('date', '>=', '2013-02-01'), ('date', '<=', '2013-02-28')]
131
- January + February + March
132
['|', '|', '&', ('date', '>=', '2013-01-01'), ('date', '<=', '2013-01-31'), '&', ('date', '>=', '2013-02-01'), ('date', '<=', '2013-02-28'), '&', ('date', '>=', '2013-03-01'), ('date', '<=', '2013-03-31')]
140
period_obj = self.pool.get('account.period')
142
if len(arg) == 3 and arg[1] in ['=', 'in']:
144
if isinstance(periods, (int, long)):
147
for _ in range(len(periods) - 1):
150
period = period_obj.browse(cr, uid, [p_id])[0]
152
new_args.append(('date', '>=', period.date_start))
153
new_args.append(('date', '<=', period.date_stop))
156
def _get_from_commitment_line(self, cr, uid, ids, field_name, args, context=None):
158
Check if line comes from a 'engagement' journal type. If yes, True. Otherwise False.
163
for al in self.browse(cr, uid, ids, context=context):
165
if al.journal_id.type == 'engagement':
169
def _get_is_unposted(self, cr, uid, ids, field_name, args, context=None):
171
Check journal entry state. If unposted: True, otherwise False.
172
A line that comes from a commitment cannot be posted. So it's always to False.
177
for al in self.browse(cr, uid, ids, context=context):
179
if al.move_state != 'posted' and al.journal_id.type != 'engagement':
79
'distribution_id': fields.many2one('analytic.distribution', string='Analytic Distribution'),
80
'cost_center_id': fields.many2one('account.analytic.account', string='Cost Center', domain="[('category', '=', 'OC'), ('type', '<>', 'view')]"),
81
184
'commitment_line_id': fields.many2one('account.commitment.line', string='Commitment Voucher Line', ondelete='cascade'),
82
'from_write_off': fields.boolean(string='From write-off account line?', readonly=True, help="Indicates that this line come from a write-off account line."),
83
'destination_id': fields.many2one('account.analytic.account', string="Destination", domain="[('category', '=', 'DEST'), ('type', '<>', 'view')]"),
84
185
'is_fp_compat_with': fields.function(_get_fake_is_fp_compat_with, fnct_search=_search_is_fp_compat_with, method=True, type="char", size=254, string="Is compatible with some FP?"),
85
'distrib_line_id': fields.reference('Distribution Line ID', selection=[('funding.pool.distribution.line', 'FP'),('free.1.distribution.line', 'free1'), ('free.2.distribution.line', 'free2')], size=512),
86
186
'move_state': fields.related('move_id', 'move_id', 'state', type='selection', size=64, relation="account.move.line", selection=[('draft', 'Unposted'), ('posted', 'Posted')], string='Journal Entry state', readonly=True, help="Indicates that this line come from an Unposted Journal Entry."),
87
187
'journal_type': fields.related('journal_id', 'type', type='selection', selection=_journal_type_get, string="Journal Type", readonly=True, \
88
188
help="Indicates the Journal Type of the Analytic journal item"),
189
'entry_sequence': fields.function(_get_entry_sequence, method=True, type='text', string="Entry Sequence", readonly=True, store=True),
190
'period_id': fields.function(_get_period_id, fnct_search=_search_period_id, method=True, string="Period", readonly=True, type="many2one", relation="account.period", store=False),
191
'from_commitment_line': fields.function(_get_from_commitment_line, method=True, type='boolean', string="Commitment?"),
192
'is_unposted': fields.function(_get_is_unposted, method=True, type='boolean', string="Unposted?"),
193
'imported_commitment': fields.boolean(string="From imported commitment?"),
194
'imported_entry_sequence': fields.text("Imported Entry Sequence"),
92
'from_write_off': lambda *a: False,
198
'imported_commitment': lambda *a: False,
95
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
97
Change account_id field name to "Funding Pool if we come from a funding pool
102
is_funding_pool_view = False
103
if context.get('display_fp', False) and context.get('display_fp') is True:
104
is_funding_pool_view = True
105
view = super(analytic_line, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
106
if view_type in ('tree', 'search') and is_funding_pool_view:
107
tree = etree.fromstring(view['arch'])
109
fields = tree.xpath('/' + view_type + '//field[@name="account_id"]')
111
field.set('string', _("Funding Pool"))
112
field.set('domain', "[('category', '=', 'FUNDING'), ('type', '<>', 'view')]")
113
view['arch'] = etree.tostring(tree)
116
def _check_date(self, cr, uid, vals, context=None):
118
Check if given account_id is active for given date. Except for mass reallocation ('from' = 'mass_reallocation' in context)
122
if not 'account_id' in vals:
123
raise osv.except_osv(_('Error'), _('No account_id found in given values!'))
124
if 'date' in vals and vals['date'] is not False:
125
account_obj = self.pool.get('account.analytic.account')
127
account = account_obj.browse(cr, uid, vals['account_id'], context=context)
128
# FIXME: refactoring of next code
129
if date < account.date_start or (account.date != False and date >= account.date):
130
if 'from' not in context or context.get('from') != 'mass_reallocation':
131
raise osv.except_osv(_('Error'), _("The analytic account selected '%s' is not active.") % (account.name or '',))
132
if 'cost_center_id' in vals:
133
cc = account_obj.browse(cr, uid, vals['cost_center_id'], context=context)
134
if date < cc.date_start or (cc.date != False and date >= cc.date):
135
if 'from' not in context or context.get('from') != 'mass_reallocation':
136
raise osv.except_osv(_('Error'), _("The analytic account selected '%s' is not active.") % (cc.name or '',))
137
if 'destination_id' in vals:
138
dest = account_obj.browse(cr, uid, vals['destination_id'], context=context)
139
if date < dest.date_start or (dest.date != False and date >= dest.date):
140
if 'from' not in context or context.get('from') != 'mass_reallocation':
141
raise osv.except_osv(_('Error'), _("The analytic account selected '%s' is not active.") % (dest.name or '',))
144
201
def create(self, cr, uid, vals, context=None):
146
203
Check date for given date and given account_id
210
253
if account.category == 'DEST':
211
254
fieldname = 'destination_id'
212
255
# if period is not closed, so override line.
213
if period and period.state != 'done':
215
self.write(cr, uid, [aline.id], {fieldname: account_id, 'date': date,
256
if period and period.state not in ['done', 'mission-closed']:
257
# Update account # Date: UTP-943 speak about original date for non closed periods
258
self.write(cr, uid, [aline.id], {fieldname: account_id, 'date': aline.date,
216
259
'source_date': aline.source_date or aline.date}, context=context)
217
260
# else reverse line before recreating them with right values
219
262
# First reverse line
220
self.pool.get('account.analytic.line').reverse(cr, uid, [aline.id])
263
rev_ids = self.pool.get('account.analytic.line').reverse(cr, uid, [aline.id], posting_date=date)
264
# UTP-943: Shoud have a correction journal on these lines
265
self.pool.get('account.analytic.line').write(cr, uid, rev_ids, {'journal_id': correction_journal_id, 'is_reversal': True, 'reversal_origin': aline.id, 'last_corrected_id': False})
266
# UTP-943: Check that period is open
267
correction_period_ids = self.pool.get('account.period').get_period_from_date(cr, uid, date, context=context)
268
if not correction_period_ids:
269
raise osv.except_osv(_('Error'), _('No period found for this date: %s') % (date,))
270
for p in self.pool.get('account.period').browse(cr, uid, correction_period_ids, context=context):
271
if p.state != 'draft':
272
raise osv.except_osv(_('Error'), _('Period (%s) is not open.') % (p.name,))
221
273
# then create new lines
222
self.pool.get('account.analytic.line').copy(cr, uid, aline.id, {fieldname: account_id, 'date': date,
223
'source_date': aline.source_date or aline.date}, context=context)
274
cor_ids = self.pool.get('account.analytic.line').copy(cr, uid, aline.id, {fieldname: account_id, 'date': date,
275
'source_date': aline.source_date or aline.date, 'journal_id': correction_journal_id}, context=context)
276
self.pool.get('account.analytic.line').write(cr, uid, cor_ids, {'last_corrected_id': aline.id})
224
277
# finally flag analytic line as reallocated
225
278
self.pool.get('account.analytic.line').write(cr, uid, [aline.id], {'is_reallocated': True})
228
281
self.write(cr, uid, [aline.id], {'account_id': account_id}, context=context)
282
# Set line as corrected upstream if we are in COORDO/HQ instance
283
self.pool.get('account.move.line').corrected_upstream_marker(cr, uid, [aline.move_id.id], context=context)
231
286
def check_analytic_account(self, cr, uid, ids, account_id, context=None):