69
95
('cancel', 'Cancelled')], 'Status', required=True),
70
96
# Field to store the third party's name for list view
71
97
'third_party_name': fields.char('Third Party', size=64),
98
'entry_sequence': fields.function(_get_entry_sequence, method=True,
99
store=False, string="Number", type="char", readonly="True"),
75
103
'third_party_type': 'res.partner',
76
'journal_id': lambda self,cr,uid,c: self.pool.get('account.journal').search(cr, uid, [('code', '=', 'AC')])[0],
104
'journal_id': lambda self,cr,uid,c: self.pool.get('account.journal').search(cr, uid, [('type', '=', 'accrual'),
105
('is_current_instance', '=', True)])[0],
77
106
'functional_currency_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.currency_id.id,
110
def _create_write_set_vals(self, cr, uid, vals, context=None):
111
if 'third_party_type' in vals:
112
if vals['third_party_type'] == 'hr.employee' and 'employee_id' in vals:
113
employee = self.pool.get('hr.employee').browse(cr, uid, vals['employee_id'], context=context)
114
vals['third_party_name'] = employee.name
115
elif vals['third_party_type'] == 'res.partner' and 'partner_id' in vals:
116
partner = self.pool.get('res.partner').browse(cr, uid, vals['partner_id'], context=context)
117
vals['third_party_name'] = partner.name
118
elif not vals['third_party_type']:
119
vals['partner_id'] = False
120
if 'period_id' in vals:
121
period = self.pool.get('account.period').browse(cr, uid, vals['period_id'], context=context)
122
vals['date'] = period.date_stop
123
if 'currency_id' in vals and 'date' in vals:
124
cr.execute("SELECT currency_id, name, rate FROM res_currency_rate WHERE currency_id = %s AND name <= %s ORDER BY name desc LIMIT 1" ,(vals['currency_id'], vals['date']))
126
currency_name = self.pool.get('res.currency').browse(cr, uid, vals['currency_id'], context=context).name
127
formatted_date = datetime.datetime.strptime(vals['date'], '%Y-%m-%d').strftime('%d/%b/%Y')
128
raise osv.except_osv(_('Warning !'), _("The currency '%s' does not have any rate set for date '%s'!") % (currency_name, formatted_date))
81
130
def create(self, cr, uid, vals, context=None):
82
131
if context is None:
84
if 'third_party_type' in vals:
85
if vals['third_party_type'] == 'hr.employee' and 'employee_id' in vals:
86
employee = self.pool.get('hr.employee').browse(cr, uid, vals['employee_id'], context=context)
87
vals['third_party_name'] = employee.name
88
elif vals['third_party_type'] == 'res.partner' and 'partner_id' in vals:
89
partner = self.pool.get('res.partner').browse(cr, uid, vals['partner_id'], context=context)
90
vals['third_party_name'] = partner.name
91
if 'period_id' in vals:
92
period = self.pool.get('account.period').browse(cr, uid, vals['period_id'], context=context)
93
vals['date'] = period.date_stop
134
if 'document_date' in vals and vals.get('period_id', False):
135
# US-192 check doc date regarding post date
136
# => read (as date readonly in form) to get posting date:
138
posting_date = self.pool.get('account.period').read(cr, uid,
139
vals['period_id'], ['date_stop', ],
140
context=context)['date_stop']
141
self.pool.get('finance.tools').check_document_date(cr, uid,
142
vals['document_date'], posting_date, context=context)
144
self._create_write_set_vals(cr, uid, vals, context=context)
94
145
return super(msf_accrual_line, self).create(cr, uid, vals, context=context)
96
147
def write(self, cr, uid, ids, vals, context=None):
97
148
if context is None:
99
if 'third_party_type' in vals:
100
if vals['third_party_type'] == 'hr.employee' and 'employee_id' in vals:
101
employee = self.pool.get('hr.employee').browse(cr, uid, vals['employee_id'], context=context)
102
vals['third_party_name'] = employee.name
103
elif vals['third_party_type'] == 'res.partner' and 'partner_id' in vals:
104
partner = self.pool.get('res.partner').browse(cr, uid, vals['partner_id'], context=context)
105
vals['third_party_name'] = partner.name
106
if 'period_id' in vals:
107
period = self.pool.get('account.period').browse(cr, uid, vals['period_id'], context=context)
108
vals['date'] = period.date_stop
150
if isinstance(ids, (int, long, )):
153
if 'document_date' in vals:
154
# US-192 check doc date reagarding post date
155
# => read date field (as readonly in form)
156
for r in self.read(cr, uid, ids, ['date', ], context=context):
157
self.pool.get('finance.tools').check_document_date(cr, uid,
158
vals['document_date'], r['date'], context=context)
160
self._create_write_set_vals(cr, uid, vals, context=context)
109
161
return super(msf_accrual_line, self).write(cr, uid, ids, vals, context=context)
111
163
def button_cancel(self, cr, uid, ids, context=None):
119
171
for accrual_line in self.browse(cr, uid, ids, context=context):
120
172
# check for periods, distribution, etc.
121
173
if accrual_line.state != 'posted':
122
raise osv.except_osv(_('Warning !'), _("The line '%s' is already posted!" % accrual_line.description))
124
move_date = accrual_line.period_id.date_stop
125
reversal_move_date = (datetime.datetime.strptime(move_date, '%Y-%m-%d') + relativedelta(days=1)).strftime('%Y-%m-%d')
126
# check if periods are open
127
reversal_period_ids = period_obj.find(cr, uid, reversal_move_date, context=context)
128
reversal_period_id = reversal_period_ids[0]
131
'ref': accrual_line.reference,
132
'period_id': accrual_line.period_id.id,
133
'journal_id': accrual_line.journal_id.id,
136
reversal_move_vals = {
137
'ref': accrual_line.reference,
138
'period_id': reversal_period_id,
139
'journal_id': accrual_line.journal_id.id,
140
'date': reversal_move_date
142
move_id = move_obj.create(cr, uid, move_vals, context=context)
143
reversal_move_id = move_obj.create(cr, uid, reversal_move_vals, context=context)
145
cancel_description = "CANCEL - " + accrual_line.description
146
reverse_cancel_description = "CANCEL - REV - " + accrual_line.description
149
accrual_move_line_vals = {
153
'journal_id': accrual_line.journal_id.id,
154
'period_id': accrual_line.period_id.id,
155
'reference': accrual_line.reference,
156
'name': cancel_description,
157
'account_id': accrual_line.accrual_account_id.id,
158
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
159
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
160
'debit_currency': accrual_line.accrual_amount,
161
'currency_id': accrual_line.currency_id.id,
163
expense_move_line_vals = {
167
'journal_id': accrual_line.journal_id.id,
168
'period_id': accrual_line.period_id.id,
169
'reference': accrual_line.reference,
170
'name': cancel_description,
171
'account_id': accrual_line.expense_account_id.id,
172
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
173
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
174
'credit_currency': accrual_line.accrual_amount,
175
'currency_id': accrual_line.currency_id.id,
176
'analytic_distribution_id': accrual_line.analytic_distribution_id.id,
179
# and their reversal (source_date to keep the old change rate)
180
reversal_accrual_move_line_vals = {
182
'move_id': reversal_move_id,
183
'date': reversal_move_date,
184
'source_date': move_date,
185
'journal_id': accrual_line.journal_id.id,
186
'period_id': reversal_period_id,
187
'reference': accrual_line.reference,
188
'name': reverse_cancel_description,
189
'account_id': accrual_line.accrual_account_id.id,
190
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
191
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
192
'credit_currency': accrual_line.accrual_amount,
193
'currency_id': accrual_line.currency_id.id,
195
reversal_expense_move_line_vals = {
197
'move_id': reversal_move_id,
198
'date': reversal_move_date,
199
'source_date': move_date,
200
'journal_id': accrual_line.journal_id.id,
201
'period_id': reversal_period_id,
202
'reference': accrual_line.reference,
203
'name': reverse_cancel_description,
204
'account_id': accrual_line.expense_account_id.id,
205
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
206
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
207
'debit_currency': accrual_line.accrual_amount,
208
'currency_id': accrual_line.currency_id.id,
209
'analytic_distribution_id': accrual_line.analytic_distribution_id.id,
212
accrual_move_line_id = move_line_obj.create(cr, uid, accrual_move_line_vals, context=context)
213
expense_move_line_id = move_line_obj.create(cr, uid, expense_move_line_vals, context=context)
214
reversal_accrual_move_line_id = move_line_obj.create(cr, uid, reversal_accrual_move_line_vals, context=context)
215
reversal_expense_move_line_id = move_line_obj.create(cr, uid, reversal_expense_move_line_vals, context=context)
218
move_obj.post(cr, uid, [move_id, reversal_move_id], context=context)
219
# Reconcile the accrual move line with its reversal
220
move_line_obj.reconcile_partial(cr, uid, [accrual_move_line_id, reversal_accrual_move_line_id], context=context)
221
# validate the accrual line
222
self.write(cr, uid, [accrual_line.id], {'state': 'cancel'}, context=context)
174
raise osv.except_osv(_('Warning !'), _("The line '%s' is already posted!") % accrual_line.description)
177
if accrual_line.period_id.state not in ('draft', 'field-closed'):
178
raise osv.except_osv(_('Warning !'), _("The period '%s' is not open!" % accrual_line.period_id.name))
180
move_date = accrual_line.period_id.date_stop
181
reversal_move_date = (datetime.datetime.strptime(move_date, '%Y-%m-%d') + relativedelta(days=1)).strftime('%Y-%m-%d')
182
# check if periods are open
183
reversal_period_ids = period_obj.find(cr, uid, reversal_move_date, context=context)
184
reversal_period_id = reversal_period_ids[0]
187
'ref': accrual_line.reference,
188
'period_id': accrual_line.period_id.id,
189
'journal_id': accrual_line.journal_id.id,
192
reversal_move_vals = {
193
'ref': accrual_line.reference,
194
'period_id': reversal_period_id,
195
'journal_id': accrual_line.journal_id.id,
196
'date': reversal_move_date
198
move_id = move_obj.create(cr, uid, move_vals, context=context)
199
reversal_move_id = move_obj.create(cr, uid, reversal_move_vals, context=context)
201
cancel_description = "CANCEL - " + accrual_line.description
202
reverse_cancel_description = "CANCEL - REV - " + accrual_line.description
205
booking_field = accrual_line.accrual_amount > 0 and 'debit_currency' or 'credit_currency' # reverse of initial entry
206
accrual_move_line_vals = {
210
'document_date': accrual_line.document_date,
211
'journal_id': accrual_line.journal_id.id,
212
'period_id': accrual_line.period_id.id,
213
'reference': accrual_line.reference,
214
'name': cancel_description,
215
'account_id': accrual_line.accrual_account_id.id,
216
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
217
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
218
booking_field: abs(accrual_line.accrual_amount),
219
'currency_id': accrual_line.currency_id.id,
221
booking_field = accrual_line.accrual_amount > 0 and 'credit_currency' or 'debit_currency'
222
expense_move_line_vals = {
226
'document_date': accrual_line.document_date,
227
'journal_id': accrual_line.journal_id.id,
228
'period_id': accrual_line.period_id.id,
229
'reference': accrual_line.reference,
230
'name': cancel_description,
231
'account_id': accrual_line.expense_account_id.id,
232
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
233
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
234
booking_field: abs(accrual_line.accrual_amount),
235
'currency_id': accrual_line.currency_id.id,
236
'analytic_distribution_id': accrual_line.analytic_distribution_id.id,
239
# and their reversal (source_date to keep the old change rate)
240
booking_field = accrual_line.accrual_amount > 0 and 'credit_currency' or 'debit_currency'
241
reversal_accrual_move_line_vals = {
243
'move_id': reversal_move_id,
244
'date': reversal_move_date,
245
'document_date': reversal_move_date,
246
'source_date': move_date,
247
'journal_id': accrual_line.journal_id.id,
248
'period_id': reversal_period_id,
249
'reference': accrual_line.reference,
250
'name': reverse_cancel_description,
251
'account_id': accrual_line.accrual_account_id.id,
252
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
253
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
254
booking_field: abs(accrual_line.accrual_amount),
255
'currency_id': accrual_line.currency_id.id,
257
booking_field = accrual_line.accrual_amount > 0 and 'debit_currency' or 'credit_currency'
258
reversal_expense_move_line_vals = {
260
'move_id': reversal_move_id,
261
'date': reversal_move_date,
262
'document_date': reversal_move_date,
263
'source_date': move_date,
264
'journal_id': accrual_line.journal_id.id,
265
'period_id': reversal_period_id,
266
'reference': accrual_line.reference,
267
'name': reverse_cancel_description,
268
'account_id': accrual_line.expense_account_id.id,
269
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
270
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
271
booking_field: abs(accrual_line.accrual_amount),
272
'currency_id': accrual_line.currency_id.id,
273
'analytic_distribution_id': accrual_line.analytic_distribution_id.id,
276
accrual_move_line_id = move_line_obj.create(cr, uid, accrual_move_line_vals, context=context)
277
expense_move_line_id = move_line_obj.create(cr, uid, expense_move_line_vals, context=context)
278
reversal_accrual_move_line_id = move_line_obj.create(cr, uid, reversal_accrual_move_line_vals, context=context)
279
reversal_expense_move_line_id = move_line_obj.create(cr, uid, reversal_expense_move_line_vals, context=context)
282
move_obj.post(cr, uid, [move_id, reversal_move_id], context=context)
283
# Reconcile the accrual move line with its reversal
284
move_line_obj.reconcile_partial(cr, uid, [accrual_move_line_id, reversal_accrual_move_line_id], context=context)
285
# validate the accrual line
286
self.write(cr, uid, [accrual_line.id], {'state': 'cancel'}, context=context)
225
289
def button_duplicate(self, cr, uid, ids, context=None):