[MERGE] new v8 api by rco

A squashed merge is required as the conversion of the apiculture branch from
bzr to git was not correctly done. The git history contains irrelevant blobs
and commits. This branch brings a lot of changes and fixes, too many to list
exhaustively.

- New orm api, objects are now used instead of ids
- Environements to encapsulates cr uid context while maintaining backward compatibility
- Field compute attribute is a new object oriented way to define function fields
- Shared browse record cache
- New onchange protocol
- Optional copy flag on fields
- Documentation update
- Dead code cleanup
- Lots of fixes
This commit is contained in:
Raphael Collet 2014-07-06 16:44:26 +02:00 committed by Antony Lesuisse
parent d78192c489
commit cbe2dbb672
426 changed files with 14918 additions and 12581 deletions

View File

@ -26,7 +26,7 @@ from operator import itemgetter
import time
import openerp
from openerp import SUPERUSER_ID
from openerp import SUPERUSER_ID, api
from openerp import tools
from openerp.osv import fields, osv, expression
from openerp.tools.translate import _
@ -62,7 +62,7 @@ class account_payment_term(osv.osv):
'name': fields.char('Payment Term', translate=True, required=True),
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the payment term without removing it."),
'note': fields.text('Description', translate=True),
'line_ids': fields.one2many('account.payment.term.line', 'payment_id', 'Terms'),
'line_ids': fields.one2many('account.payment.term.line', 'payment_id', 'Terms', copy=True),
}
_defaults = {
'active': 1,
@ -213,9 +213,6 @@ def _code_get(self, cr, uid, context=None):
# Accounts
#----------------------------------------------------------
class account_tax(osv.osv):
_name = 'account.tax'
class account_account(osv.osv):
_order = "parent_left"
_parent_order = "code"
@ -640,16 +637,16 @@ class account_account(osv.osv):
def _check_moves(self, cr, uid, ids, method, context=None):
line_obj = self.pool.get('account.move.line')
account_ids = self.search(cr, uid, [('id', 'child_of', ids)])
account_ids = self.search(cr, uid, [('id', 'child_of', ids)], context=context)
if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
if line_obj.search(cr, uid, [('account_id', 'in', account_ids)], context=context):
if method == 'write':
raise osv.except_osv(_('Error!'), _('You cannot deactivate an account that contains journal items.'))
elif method == 'unlink':
raise osv.except_osv(_('Error!'), _('You cannot remove an account that contains journal items.'))
#Checking whether the account is set as a property to any Partner or not
value = 'account.account,' + str(ids[0])
partner_prop_acc = self.pool.get('ir.property').search(cr, uid, [('value_reference','=',value)], context=context)
values = ['account.account,%s' % (account_id,) for account_id in ids]
partner_prop_acc = self.pool.get('ir.property').search(cr, uid, [('value_reference','in', values)], context=context)
if partner_prop_acc:
raise osv.except_osv(_('Warning!'), _('You cannot remove/deactivate an account which is set on a customer or supplier.'))
return True
@ -691,10 +688,10 @@ class account_account(osv.osv):
# Dont allow changing the company_id when account_move_line already exist
if 'company_id' in vals:
move_lines = self.pool.get('account.move.line').search(cr, uid, [('account_id', 'in', ids)])
move_lines = self.pool.get('account.move.line').search(cr, uid, [('account_id', 'in', ids)], context=context)
if move_lines:
# Allow the write if the value is the same
for i in [i['company_id'][0] for i in self.read(cr,uid,ids,['company_id'])]:
for i in [i['company_id'][0] for i in self.read(cr,uid,ids,['company_id'], context=context)]:
if vals['company_id']!=i:
raise osv.except_osv(_('Warning!'), _('You cannot change the owner company of an account that already contains journal items.'))
if 'active' in vals and not vals['active']:
@ -730,7 +727,7 @@ class account_journal(osv.osv):
'centralisation': fields.boolean('Centralized Counterpart', help="Check this box to determine that each entry of this journal won't create a new counterpart but will share the same counterpart. This is used in fiscal year closing."),
'update_posted': fields.boolean('Allow Cancelling Entries', help="Check this box if you want to allow the cancellation the entries related to this journal or of the invoice related to this journal"),
'group_invoice_lines': fields.boolean('Group Invoice Lines', help="If this box is checked, the system will try to group the accounting lines when generating them from invoices."),
'sequence_id': fields.many2one('ir.sequence', 'Entry Sequence', help="This field contains the information related to the numbering of the journal entries of this journal.", required=True),
'sequence_id': fields.many2one('ir.sequence', 'Entry Sequence', help="This field contains the information related to the numbering of the journal entries of this journal.", required=True, copy=False),
'user_id': fields.many2one('res.users', 'User', help="The user responsible for this journal"),
'groups_id': fields.many2many('res.groups', 'account_journal_group_rel', 'journal_id', 'group_id', 'Groups'),
'currency': fields.many2one('res.currency', 'Currency', help='The currency used to enter statement'),
@ -769,15 +766,12 @@ class account_journal(osv.osv):
(_check_currency, 'Configuration error!\nThe currency chosen should be shared by the default accounts too.', ['currency','default_debit_account_id','default_credit_account_id']),
]
def copy(self, cr, uid, id, default=None, context=None, done_list=None, local=False):
default = {} if default is None else default.copy()
if done_list is None:
done_list = []
def copy(self, cr, uid, id, default=None, context=None):
default = dict(context or {})
journal = self.browse(cr, uid, id, context=context)
default.update(
code=_("%s (copy)") % (journal['code'] or ''),
name=_("%s (copy)") % (journal['name'] or ''),
sequence_id=False)
name=_("%s (copy)") % (journal['name'] or ''))
return super(account_journal, self).copy(cr, uid, id, default, context=context)
def write(self, cr, uid, ids, vals, context=None):
@ -865,7 +859,10 @@ class account_fiscalyear(osv.osv):
'date_start': fields.date('Start Date', required=True),
'date_stop': fields.date('End Date', required=True),
'period_ids': fields.one2many('account.period', 'fiscalyear_id', 'Periods'),
'state': fields.selection([('draft','Open'), ('done','Closed')], 'Status', readonly=True),
'state': fields.selection([('draft','Open'), ('done','Closed')], 'Status', readonly=True, copy=False),
'end_journal_period_id': fields.many2one(
'account.journal.period', 'End of Year Entries Journal',
readonly=True, copy=False),
}
_defaults = {
'state': 'draft',
@ -960,7 +957,7 @@ class account_period(osv.osv):
'date_start': fields.date('Start of Period', required=True, states={'done':[('readonly',True)]}),
'date_stop': fields.date('End of Period', required=True, states={'done':[('readonly',True)]}),
'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True, states={'done':[('readonly',True)]}, select=True),
'state': fields.selection([('draft','Open'), ('done','Closed')], 'Status', readonly=True,
'state': fields.selection([('draft','Open'), ('done','Closed')], 'Status', readonly=True, copy=False,
help='When monthly periods are created. The status is \'Draft\'. At the end of monthly period it is in \'Done\' status.'),
'company_id': fields.related('fiscalyear_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True)
}
@ -1000,12 +997,14 @@ class account_period(osv.osv):
(_check_year_limit, 'Error!\nThe period is invalid. Either some periods are overlapping or the period\'s dates are not matching the scope of the fiscal year.', ['date_stop'])
]
@api.returns('self')
def next(self, cr, uid, period, step, context=None):
ids = self.search(cr, uid, [('date_start','>',period.date_start)])
if len(ids)>=step:
return ids[step-1]
return False
@api.returns('self')
def find(self, cr, uid, dt=None, context=None):
if context is None: context = {}
if not dt:
@ -1028,13 +1027,14 @@ class account_period(osv.osv):
raise openerp.exceptions.RedirectWarning(msg, action_id, _('Go to the configuration panel'))
return result
def action_draft(self, cr, uid, ids, *args):
def action_draft(self, cr, uid, ids, context=None):
mode = 'draft'
for period in self.browse(cr, uid, ids):
if period.fiscalyear_id.state == 'done':
raise osv.except_osv(_('Warning!'), _('You can not re-open a period which belongs to closed fiscal year'))
cr.execute('update account_journal_period set state=%s where period_id in %s', (mode, tuple(ids),))
cr.execute('update account_period set state=%s where id in %s', (mode, tuple(ids),))
self.invalidate_cache(cr, uid, context=context)
return True
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
@ -1132,22 +1132,6 @@ class account_journal_period(osv.osv):
}
_order = "period_id"
class account_fiscalyear(osv.osv):
_inherit = "account.fiscalyear"
_description = "Fiscal Year"
_columns = {
'end_journal_period_id':fields.many2one('account.journal.period','End of Year Entries Journal', readonly=True),
}
def copy(self, cr, uid, id, default=None, context=None):
default = {} if default is None else default.copy()
default.update({
'period_ids': [],
'end_journal_period_id': False
})
return super(account_fiscalyear, self).copy(cr, uid, id, default=default, context=context)
#----------------------------------------------------------
# Entries
#----------------------------------------------------------
@ -1235,13 +1219,21 @@ class account_move(osv.osv):
return [line.move_id.id for line in line_obj.browse(cr, uid, ids, context=context)]
_columns = {
'name': fields.char('Number', required=True),
'ref': fields.char('Reference'),
'name': fields.char('Number', required=True, copy=False),
'ref': fields.char('Reference', copy=False),
'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
'journal_id': fields.many2one('account.journal', 'Journal', required=True, states={'posted':[('readonly',True)]}),
'state': fields.selection([('draft','Unposted'), ('posted','Posted')], 'Status', required=True, readonly=True,
help='All manually created new journal entries are usually in the status \'Unposted\', but you can set the option to skip that status on the related journal. In that case, they will behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' status.'),
'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
'state': fields.selection(
[('draft','Unposted'), ('posted','Posted')], 'Status',
required=True, readonly=True, copy=False,
help='All manually created new journal entries are usually in the status \'Unposted\', '
'but you can set the option to skip that status on the related journal. '
'In that case, they will behave as journal entries automatically created by the '
'system on document validation (invoices, bank statements...) and will be created '
'in \'Posted\' status.'),
'line_id': fields.one2many('account.move.line', 'move_id', 'Entries',
states={'posted':[('readonly',True)]},
copy=True),
'to_check': fields.boolean('To Review', help='Check this box if you are unsure of that journal entry and if you want to note it as \'to be reviewed\' by an accounting expert.'),
'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store={
_name: (lambda self, cr,uid,ids,c: ids, ['line_id'], 10),
@ -1309,6 +1301,7 @@ class account_move(osv.osv):
'SET state=%s '\
'WHERE id IN %s',
('posted', tuple(valid_moves),))
self.invalidate_cache(cr, uid, context=context)
return True
def button_validate(self, cursor, user, ids, context=None):
@ -1335,6 +1328,7 @@ class account_move(osv.osv):
cr.execute('UPDATE account_move '\
'SET state=%s '\
'WHERE id IN %s', ('draft', tuple(ids),))
self.invalidate_cache(cr, uid, context=context)
return True
def write(self, cr, uid, ids, vals, context=None):
@ -1350,23 +1344,9 @@ class account_move(osv.osv):
# TODO: Check if period is closed !
#
def create(self, cr, uid, vals, context=None):
if context is None:
context = {}
if 'line_id' in vals and context.get('copy'):
for l in vals['line_id']:
if not l[0]:
l[2].update({
'reconcile_id':False,
'reconcile_partial_id':False,
'analytic_lines':False,
'invoice':False,
'ref':False,
'balance':False,
'account_tax_id':False,
'statement_id': False,
})
if 'journal_id' in vals and vals.get('journal_id', False):
context = dict(context or {})
if vals.get('line_id'):
if vals.get('journal_id'):
for l in vals['line_id']:
if not l[0]:
l[2]['journal_id'] = vals['journal_id']
@ -1383,7 +1363,6 @@ class account_move(osv.osv):
l[2]['period_id'] = default_period
context['period_id'] = default_period
if vals.get('line_id', False):
c = context.copy()
c['novalidate'] = True
c['period_id'] = vals['period_id'] if 'period_id' in vals else self._get_period(cr, uid, context)
@ -1398,22 +1377,8 @@ class account_move(osv.osv):
result = super(account_move, self).create(cr, uid, vals, context)
return result
def copy(self, cr, uid, id, default=None, context=None):
default = {} if default is None else default.copy()
context = {} if context is None else context.copy()
default.update({
'state':'draft',
'ref': False,
'name':'/',
})
context.update({
'copy':True
})
return super(account_move, self).copy(cr, uid, id, default, context)
def unlink(self, cr, uid, ids, context=None, check=True):
if context is None:
context = {}
context = dict(context or {})
if isinstance(ids, (int, long)):
ids = [ids]
toremove = []
@ -1447,8 +1412,8 @@ class account_move(osv.osv):
def _centralise(self, cr, uid, move, mode, context=None):
assert mode in ('debit', 'credit'), 'Invalid Mode' #to prevent sql injection
currency_obj = self.pool.get('res.currency')
if context is None:
context = {}
account_move_line_obj = self.pool.get('account.move.line')
context = dict(context or {})
if mode=='credit':
account_id = move.journal_id.default_debit_account_id.id
@ -1473,7 +1438,7 @@ class account_move(osv.osv):
line_id = res[0]
else:
context.update({'journal_id': move.journal_id.id, 'period_id': move.period_id.id})
line_id = self.pool.get('account.move.line').create(cr, uid, {
line_id = account_move_line_obj.create(cr, uid, {
'name': _(mode.capitalize()+' Centralisation'),
'centralisation': mode,
'partner_id': False,
@ -1498,6 +1463,7 @@ class account_move(osv.osv):
cr.execute('SELECT SUM(%s) FROM account_move_line WHERE move_id=%%s AND id!=%%s' % (mode,), (move.id, line_id2))
result = cr.fetchone()[0] or 0.0
cr.execute('update account_move_line set '+mode2+'=%s where id=%s', (result, line_id))
account_move_line_obj.invalidate_cache(cr, uid, [mode2], [line_id], context=context)
#adjust also the amount in currency if needed
cr.execute("select currency_id, sum(amount_currency) as amount_currency from account_move_line where move_id = %s and currency_id is not null group by currency_id", (move.id,))
@ -1510,9 +1476,10 @@ class account_move(osv.osv):
res = cr.fetchone()
if res:
cr.execute('update account_move_line set amount_currency=%s , account_id=%s where id=%s', (amount_currency, account_id, res[0]))
account_move_line_obj.invalidate_cache(cr, uid, ['amount_currency', 'account_id'], [res[0]], context=context)
else:
context.update({'journal_id': move.journal_id.id, 'period_id': move.period_id.id})
line_id = self.pool.get('account.move.line').create(cr, uid, {
line_id = account_move_line_obj.create(cr, uid, {
'name': _('Currency Adjustment'),
'centralisation': 'currency',
'partner_id': False,
@ -1818,7 +1785,7 @@ class account_tax_code(osv.osv):
return []
if isinstance(ids, (int, long)):
ids = [ids]
reads = self.read(cr, uid, ids, ['name','code'], context, load='_classic_write')
reads = self.read(cr, uid, ids, ['name','code'], context=context, load='_classic_write')
return [(x['id'], (x['code'] and (x['code'] + ' - ') or '') + x['name']) \
for x in reads]
@ -1827,19 +1794,13 @@ class account_tax_code(osv.osv):
if user.company_id:
return user.company_id.id
return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
_defaults = {
'company_id': _default_company,
'sign': 1.0,
'notprintable': False,
}
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
default = default.copy()
default.update({'line_ids': []})
return super(account_tax_code, self).copy(cr, uid, id, default, context)
_check_recursion = check_cycle
_constraints = [
(_check_recursion, 'Error!\nYou cannot create recursive accounts.', ['parent_id'])
@ -1868,10 +1829,9 @@ class account_tax(osv.osv):
def copy_data(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
name = self.read(cr, uid, id, ['name'], context=context)['name']
default = default.copy()
default.update({'name': name + _(' (Copy)')})
return super(account_tax, self).copy_data(cr, uid, id, default=default, context=context)
this = self.browse(cr, uid, id, context=context)
tmp_default = dict(default, name=_("%s (Copy)") % this.name)
return super(account_tax, self).copy_data(cr, uid, id, default=tmp_default, context=context)
_name = 'account.tax'
_description = 'Tax'
@ -2087,6 +2047,7 @@ class account_tax(osv.osv):
tax = self.browse(cr, uid, tax_id, context=context)
return self.compute_all(cr, uid, [tax], amount, 1) # TOCHECK may use force_exclude parameter
@api.v7
def compute_all(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None, force_excluded=False):
"""
:param force_excluded: boolean used to say that we don't want to consider the value of field price_include of
@ -2137,6 +2098,12 @@ class account_tax(osv.osv):
'taxes': tin + tex
}
@api.v8
def compute_all(self, price_unit, quantity, product=None, partner=None, force_excluded=False):
return self._model.compute_all(
self._cr, self._uid, self, price_unit, quantity,
product=product, partner=partner, force_excluded=force_excluded)
def compute(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None):
_logger.warning("Deprecated, use compute_all(...)['taxes'] instead of compute(...) to manage prices with tax included.")
return self._compute(cr, uid, taxes, price_unit, quantity, product, partner)
@ -2270,7 +2237,7 @@ class account_model(osv.osv):
'name': fields.char('Model Name', required=True, help="This is a model for recurring accounting entries"),
'journal_id': fields.many2one('account.journal', 'Journal', required=True),
'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
'lines_id': fields.one2many('account.model.line', 'model_id', 'Model Entries'),
'lines_id': fields.one2many('account.model.line', 'model_id', 'Model Entries', copy=True),
'legend': fields.text('Legend', readonly=True, size=100),
}
@ -2292,6 +2259,7 @@ class account_model(osv.osv):
context = {}
if data.get('date', False):
context = dict(context)
context.update({'date': data['date']})
move_date = context.get('date', time.strftime('%Y-%m-%d'))
@ -2409,8 +2377,8 @@ class account_subscription(osv.osv):
'period_total': fields.integer('Number of Periods', required=True),
'period_nbr': fields.integer('Period', required=True),
'period_type': fields.selection([('day','days'),('month','month'),('year','year')], 'Period Type', required=True),
'state': fields.selection([('draft','Draft'),('running','Running'),('done','Done')], 'Status', required=True, readonly=True),
'lines_id': fields.one2many('account.subscription.line', 'subscription_id', 'Subscription Lines')
'state': fields.selection([('draft','Draft'),('running','Running'),('done','Done')], 'Status', required=True, readonly=True, copy=False),
'lines_id': fields.one2many('account.subscription.line', 'subscription_id', 'Subscription Lines', copy=True)
}
_defaults = {
'date_start': fields.date.context_today,
@ -2742,7 +2710,7 @@ class account_tax_code_template(osv.osv):
return []
if isinstance(ids, (int, long)):
ids = [ids]
reads = self.read(cr, uid, ids, ['name','code'], context, load='_classic_write')
reads = self.read(cr, uid, ids, ['name','code'], context=context, load='_classic_write')
return [(x['id'], (x['code'] and x['code'] + ' - ' or '') + x['name']) \
for x in reads]

View File

@ -69,8 +69,7 @@ class account_bank_statement(osv.osv):
return False
def _compute_default_statement_name(self, cr, uid, journal_id, context=None):
if context is None:
context = {}
context = dict(context or {})
obj_seq = self.pool.get('ir.sequence')
period = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, context=context), context=context)
context['fiscalyear_id'] = period.fiscalyear_id.id
@ -114,8 +113,16 @@ class account_bank_statement(osv.osv):
_description = "Bank Statement"
_inherit = ['mail.thread']
_columns = {
'name': fields.char('Reference', states={'draft': [('readonly', False)]}, readonly=True, help='if you give the Name other then /, its created Accounting Entries Move will be with same name as statement name. This allows the statement entries to have the same references than the statement itself'), # readonly for account_cash_statement
'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}, select=True),
'name': fields.char(
'Reference', states={'draft': [('readonly', False)]},
readonly=True, # readonly for account_cash_statement
copy=False,
help='if you give the Name other then /, its created Accounting Entries Move '
'will be with same name as statement name. '
'This allows the statement entries to have the same references than the '
'statement itself'),
'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]},
select=True, copy=False),
'journal_id': fields.many2one('account.journal', 'Journal', required=True,
readonly=True, states={'draft':[('readonly',False)]}),
'period_id': fields.many2one('account.period', 'Period', required=True,
@ -132,14 +139,15 @@ class account_bank_statement(osv.osv):
string="Computed Balance", help='Balance as calculated based on Opening Balance and transaction lines'),
'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
'line_ids': fields.one2many('account.bank.statement.line',
'statement_id', 'Statement lines',
states={'confirm':[('readonly', True)]}),
'statement_id', 'Statement lines',
states={'confirm':[('readonly', True)]}, copy=True),
'move_line_ids': fields.one2many('account.move.line', 'statement_id',
'Entry lines', states={'confirm':[('readonly',True)]}),
'Entry lines', states={'confirm':[('readonly',True)]}),
'state': fields.selection([('draft', 'New'),
('open','Open'), # used by cash statements
('confirm', 'Closed')],
'Status', required=True, readonly="1",
copy=False,
help='When new statement is created the status will be \'Draft\'.\n'
'And after getting confirmation from the bank it will be in \'Confirmed\' status.'),
'currency': fields.function(_currency, string='Currency',
@ -182,7 +190,7 @@ class account_bank_statement(osv.osv):
pids = period_pool.find(cr, uid, dt=date, context=ctx)
if pids:
res.update({'period_id': pids[0]})
context.update({'period_id': pids[0]})
context = dict(context, period_id=pids[0])
return {
'value':res,
@ -363,24 +371,13 @@ class account_bank_statement(osv.osv):
return {'value': res}
def unlink(self, cr, uid, ids, context=None):
stat = self.read(cr, uid, ids, ['state'], context=context)
unlink_ids = []
for t in stat:
if t['state'] in ('draft'):
unlink_ids.append(t['id'])
else:
raise osv.except_osv(_('Invalid Action!'), _('In order to delete a bank statement, you must first cancel it to delete related journal items.'))
osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
return True
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
if context is None:
context = {}
default = default.copy()
default['move_line_ids'] = []
return super(account_bank_statement, self).copy(cr, uid, id, default, context=context)
for item in self.browse(cr, uid, ids, context=context):
if item.state != 'draft':
raise osv.except_osv(
_('Invalid Action!'),
_('In order to delete a bank statement, you must first cancel it to delete related journal items.')
)
return super(account_bank_statement, self).unlink(cr, uid, ids, context=context)
def button_journal_entries(self, cr, uid, ids, context=None):
ctx = (context or {}).copy()
@ -806,8 +803,8 @@ class account_bank_statement_line(osv.osv):
_description = "Bank Statement Line"
_inherit = ['ir.needaction_mixin']
_columns = {
'name': fields.char('Description', required=True),
'date': fields.date('Date', required=True),
'name': fields.char('Description', required=True, copy=False),
'date': fields.date('Date', required=True, copy=False),
'amount': fields.float('Amount', digits_compute=dp.get_precision('Account')),
'partner_id': fields.many2one('res.partner', 'Partner'),
'bank_account_id': fields.many2one('res.partner.bank','Bank Account'),

View File

@ -179,7 +179,7 @@ class account_cash_statement(osv.osv):
},
help="Total of cash transaction lines."),
'closing_date': fields.datetime("Closed On"),
'details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='CashBox Lines'),
'details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='CashBox Lines', copy=True),
'opening_details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='Opening Cashbox Lines'),
'closing_details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='Closing Cashbox Lines'),
'user_id': fields.many2one('res.users', 'Responsible', required=False),
@ -337,7 +337,7 @@ class account_journal(osv.osv):
return result
_columns = {
'cashbox_line_ids' : fields.one2many('account.journal.cashbox.line', 'journal_id', 'CashBox'),
'cashbox_line_ids' : fields.one2many('account.journal.cashbox.line', 'journal_id', 'CashBox', copy=True),
}
_defaults = {

File diff suppressed because it is too large Load Diff

View File

@ -183,7 +183,7 @@
<field domain="[('company_id', '=', company_id), ('type', '=', 'payable')]"
name="account_id" groups="account.group_account_user"/>
<field name="journal_id" groups="account.group_account_user"
on_change="onchange_journal_id(journal_id, context)" options="{'no_create': True}"/>
on_change="onchange_journal_id(journal_id)" options="{'no_create': True}"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="check_total" groups="account.group_supplier_inv_check_total"/>
</group>
@ -258,7 +258,7 @@
<group>
<field name="move_id" groups="account.group_account_user"/>
<field name="period_id" domain="[('state', '=', 'draft'), ('company_id', '=', company_id)]" groups="account.group_account_user"/>
<field name="company_id" on_change="onchange_company_id(company_id,partner_id,type,invoice_line,currency_id,context)" widget="selection" groups="base.group_multi_company"/>
<field name="company_id" on_change="onchange_company_id(company_id,partner_id,type,invoice_line,currency_id)" widget="selection" groups="base.group_multi_company"/>
</group>
</group>
</page>
@ -329,7 +329,7 @@
<group>
<field name="date_invoice"/>
<field name="journal_id" groups="account.group_account_user"
on_change="onchange_journal_id(journal_id, context)" options="{'no_create': True}"/>
on_change="onchange_journal_id(journal_id)" options="{'no_create': True}"/>
<field domain="[('company_id', '=', company_id),('type','=', 'receivable')]"
name="account_id" groups="account.group_account_user"/>
@ -393,7 +393,7 @@
<page string="Other Info">
<group col="4">
<group>
<field name="company_id" on_change="onchange_company_id(company_id,partner_id,type,invoice_line,currency_id,context)" widget="selection" groups="base.group_multi_company"/>
<field name="company_id" on_change="onchange_company_id(company_id,partner_id,type,invoice_line,currency_id)" widget="selection" groups="base.group_multi_company"/>
<field name="user_id" groups="base.group_user" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'account.group_account_invoice']}"/>
<field domain="[('partner_id.ref_companies', 'in', [company_id])]" name="partner_bank_id"/>
<field name="period_id" domain="[('state', '=', 'draft'), ('company_id', '=', company_id)]"

View File

@ -19,15 +19,12 @@
#
##############################################################################
import sys
import time
from datetime import datetime
from operator import itemgetter
from lxml import etree
from openerp import workflow
from openerp.osv import fields, osv, orm
from openerp.osv import fields, osv
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp
from openerp import tools
@ -42,8 +39,7 @@ class account_move_line(osv.osv):
fiscalperiod_obj = self.pool.get('account.period')
account_obj = self.pool.get('account.account')
fiscalyear_ids = []
if context is None:
context = {}
context = dict(context or {})
initial_bal = context.get('initial_bal', False)
company_clause = " "
if context.get('company_id', False):
@ -217,17 +213,14 @@ class account_move_line(osv.osv):
period_id = context.get('period_id')
if type(period_id) == str:
ids = period_obj.search(cr, uid, [('name', 'ilike', period_id)])
context.update({
'period_id': ids and ids[0] or False
})
context = dict(context, period_id=ids and ids[0] or False)
return context
def _default_get(self, cr, uid, fields, context=None):
#default_get should only do the following:
# -propose the next amount in debit/credit in order to balance the move
# -propose the next account from the journal (default debit/credit account) accordingly
if context is None:
context = {}
context = dict(context or {})
account_obj = self.pool.get('account.account')
period_obj = self.pool.get('account.period')
journal_obj = self.pool.get('account.journal')
@ -456,10 +449,10 @@ class account_move_line(osv.osv):
'move_id': fields.many2one('account.move', 'Journal Entry', ondelete="cascade", help="The move of this entry line.", select=2, required=True),
'narration': fields.related('move_id','narration', type='text', relation='account.move', string='Internal Note'),
'ref': fields.related('move_id', 'ref', string='Reference', type='char', store=True),
'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1),
'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2),
'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2),
'reconcile': fields.function(_get_reconcile, type='char', string='Reconcile Ref', store={
'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1, copy=False),
'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2, copy=False),
'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2, copy=False),
'reconcile_ref': fields.function(_get_reconcile, type='char', string='Reconcile Ref', oldname='reconcile', store={
'account.move.line': (lambda self, cr, uid, ids, c={}: ids, ['reconcile_id','reconcile_partial_id'], 50),'account.move.reconcile': (_get_move_from_reconcile, None, 50)}),
'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency if it is a multi-currency entry.", digits_compute=dp.get_precision('Account')),
'amount_residual_currency': fields.function(_amount_residual, string='Residual Amount in Currency', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in its currency (maybe different of the company currency)."),
@ -484,13 +477,13 @@ class account_move_line(osv.osv):
'analytic_lines': fields.one2many('account.analytic.line', 'move_id', 'Analytic lines'),
'centralisation': fields.selection([('normal','Normal'),('credit','Credit Centralisation'),('debit','Debit Centralisation'),('currency','Currency Adjustment')], 'Centralisation', size=8),
'balance': fields.function(_balance, fnct_search=_balance_search, string='Balance'),
'state': fields.selection([('draft','Unbalanced'), ('valid','Balanced')], 'Status', readonly=True),
'state': fields.selection([('draft','Unbalanced'), ('valid','Balanced')], 'Status', readonly=True, copy=False),
'tax_code_id': fields.many2one('account.tax.code', 'Tax Account', help="The Account can either be a base tax code or a tax code account."),
'tax_amount': fields.float('Tax/Base Amount', digits_compute=dp.get_precision('Account'), select=True, help="If the Tax account is a tax code account, this field will contain the taxed amount.If the tax account is base tax code, "\
"this field will contain the basic amount(without tax)."),
'invoice': fields.function(_invoice, string='Invoice',
type='many2one', relation='account.invoice', fnct_search=_invoice_search),
'account_tax_id':fields.many2one('account.tax', 'Tax'),
'account_tax_id':fields.many2one('account.tax', 'Tax', copy=False),
'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account'),
'company_id': fields.related('account_id', 'company_id', type='many2one', relation='res.company',
string='Company', store=True, readonly=True)
@ -666,6 +659,7 @@ class account_move_line(osv.osv):
if (amount>0) and journal:
x = journal_obj.browse(cr, uid, journal).default_credit_account_id
if x: acc = x
context = dict(context)
context.update({
'date': date,
'res.currency.compute.account': acc,
@ -1006,12 +1000,8 @@ class account_move_line(osv.osv):
period_pool = self.pool.get('account.period')
pids = period_pool.find(cr, user, date, context=context)
if pids:
res.update({
'period_id':pids[0]
})
context.update({
'period_id':pids[0]
})
res.update({'period_id':pids[0]})
context = dict(context, period_id=pids[0])
return {
'value':res,
'context':context,
@ -1158,15 +1148,14 @@ class account_move_line(osv.osv):
move_obj = self.pool.get('account.move')
cur_obj = self.pool.get('res.currency')
journal_obj = self.pool.get('account.journal')
if context is None:
context = {}
context = dict(context or {})
if vals.get('move_id', False):
move = self.pool.get('account.move').browse(cr, uid, vals['move_id'], context=context)
if move.company_id:
vals['company_id'] = move.company_id.id
if move.date and not vals.get('date'):
vals['date'] = move.date
if ('account_id' in vals) and not account_obj.read(cr, uid, vals['account_id'], ['active'])['active']:
if ('account_id' in vals) and not account_obj.read(cr, uid, [vals['account_id']], ['active'])[0]['active']:
raise osv.except_osv(_('Bad Account!'), _('You cannot use an inactive account.'))
if 'journal_id' in vals and vals['journal_id']:
context['journal_id'] = vals['journal_id']

View File

@ -1209,7 +1209,7 @@
<field name="debit" sum="Total Debit"/>
<field name="credit" sum="Total Credit"/>
<field name="date_maturity" invisible="context.get('journal_type', False) not in ['sale','sale_refund','purchase','purchase_refund']"/>
<field name="reconcile"/>
<field name="reconcile_ref"/>
<field name="invoice" invisible="1"/>
<field name="amount_currency" readonly="True" invisible="not context.get('currency',False)"/>
<field name="currency_id" readonly="True" invisible="not context.get('currency',False)" />

View File

@ -208,7 +208,7 @@ class account_invoice(osv.osv, EDIMixin):
edi_document.pop('partner_ref', None)
# journal_id: should be selected based on type: simply put the 'type' in the context when calling create(), will be selected correctly
context.update(type=invoice_type)
context = dict(context, type=invoice_type)
# for invoice lines, the account_id value should be taken from the product's default, i.e. from the default category, as it will not be provided.
for edi_invoice_line in edi_document['invoice_line']:

View File

@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import api
from openerp.osv import fields, osv
class ir_sequence_fiscalyear(osv.osv):
@ -43,9 +43,10 @@ class ir_sequence(osv.osv):
_inherit = 'ir.sequence'
_columns = {
'fiscal_ids': fields.one2many('account.sequence.fiscalyear',
'sequence_main_id', 'Sequences')
'sequence_main_id', 'Sequences', copy=True)
}
@api.cr_uid_ids_context
def _next(self, cr, uid, seq_ids, context=None):
if context is None:
context = {}

View File

@ -23,6 +23,7 @@ from operator import itemgetter
import time
from openerp.osv import fields, osv
from openerp import api
class account_fiscal_position(osv.osv):
_name = 'account.fiscal.position'
@ -33,8 +34,8 @@ class account_fiscal_position(osv.osv):
'name': fields.char('Fiscal Position', required=True),
'active': fields.boolean('Active', help="By unchecking the active field, you may hide a fiscal position without deleting it."),
'company_id': fields.many2one('res.company', 'Company'),
'account_ids': fields.one2many('account.fiscal.position.account', 'position_id', 'Account Mapping'),
'tax_ids': fields.one2many('account.fiscal.position.tax', 'position_id', 'Tax Mapping'),
'account_ids': fields.one2many('account.fiscal.position.account', 'position_id', 'Account Mapping', copy=True),
'tax_ids': fields.one2many('account.fiscal.position.tax', 'position_id', 'Tax Mapping', copy=True),
'note': fields.text('Notes'),
'auto_apply': fields.boolean('Automatic', help="Apply automatically this fiscal position."),
'vat_required': fields.boolean('VAT required', help="Apply only if partner has a VAT number."),
@ -46,6 +47,7 @@ class account_fiscal_position(osv.osv):
'active': True,
}
@api.v7
def map_tax(self, cr, uid, fposition_id, taxes, context=None):
if not taxes:
return []
@ -63,6 +65,20 @@ class account_fiscal_position(osv.osv):
result.add(t.id)
return list(result)
@api.v8
def map_tax(self, taxes):
result = taxes.browse()
for tax in taxes:
found = False
for t in self.tax_ids:
if t.tax_src_id == tax:
result |= t.tax_dest_id
found = True
if not found:
result |= tax
return result
@api.v7
def map_account(self, cr, uid, fposition_id, account_id, context=None):
if not fposition_id:
return account_id
@ -72,6 +88,13 @@ class account_fiscal_position(osv.osv):
break
return account_id
@api.v8
def map_account(self, account):
for pos in self.account_ids:
if pos.account_src_id == account:
return pos.account_dest_id
return account
def get_fiscal_position(self, cr, uid, company_id, partner_id, delivery_id=None, context=None):
if not partner_id:
return False
@ -279,7 +302,14 @@ class res_partner(osv.osv):
help="This payment term will be used instead of the default one for purchase orders and supplier invoices"),
'ref_companies': fields.one2many('res.company', 'partner_id',
'Companies that refers to partner'),
'last_reconciliation_date': fields.datetime('Latest Full Reconciliation Date', help='Date on which the partner accounting entries were fully reconciled last time. It differs from the last date where a reconciliation has been made for this partner, as here we depict the fact that nothing more was to be reconciled at this date. This can be achieved in 2 different ways: either the last unreconciled debit/credit entry of this partner was reconciled, either the user pressed the button "Nothing more to reconcile" during the manual reconciliation process.')
'last_reconciliation_date': fields.datetime(
'Latest Full Reconciliation Date', copy=False,
help='Date on which the partner accounting entries were fully reconciled last time. '
'It differs from the last date where a reconciliation has been made for this partner, '
'as here we depict the fact that nothing more was to be reconciled at this date. '
'This can be achieved in 2 different ways: either the last unreconciled debit/credit '
'entry of this partner was reconciled, either the user pressed the button '
'"Nothing more to reconcile" during the manual reconciliation process.')
}
def _commercial_fields(self, cr, uid, context=None):

View File

@ -156,6 +156,7 @@ class journal_print(report_sxw.rml_parse, common_report_header):
journal_id = [journal_id]
obj_mline = self.pool.get('account.move.line')
self.cr.execute('update account_journal_period set state=%s where journal_id IN %s and period_id=%s and state=%s', ('printed', self.journal_ids, period_id, 'draft'))
self.pool.get('account.journal.period').invalidate_cache(self.cr, self.uid, ['state'], context=self.context)
move_state = ['draft','posted']
if self.target_move == 'posted':

View File

@ -20,7 +20,7 @@
##############################################################################
import time
from datetime import datetime
import datetime
from dateutil.relativedelta import relativedelta
from openerp import tools
@ -91,7 +91,7 @@ class report_aged_receivable(osv.osv):
"""
if context is None:context = {}
if not self.called:
self.init(cr, user)
self._init(cr, user)
self.called = True # To make sure that init doesn't get called multiple times
res = super(report_aged_receivable, self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
@ -116,29 +116,37 @@ class report_aged_receivable(osv.osv):
'balance': fields.function(_calc_bal, string='Balance', readonly=True),
}
def init(self, cr, uid=1):
def init(self, cr):
return self._init(cr, 1)
def _init(self, cr, uid):
""" This view will be used in dashboard
The reason writing this code here is, we need to check date range from today to first date of fiscal year.
"""
pool_obj_fy = self.pool['account.fiscalyear']
today = time.strftime('%Y-%m-%d')
current_date = datetime.date.today()
fy_id = pool_obj_fy.find(cr, uid, exception=False)
LIST_RANGES = []
names = []
def add(names, start_on, stop_on):
names.append(start_on.strftime("%Y-%m-%d") + ' to ' + stop_on.strftime('%Y-%m-%d'))
return names
if fy_id:
fy_start_date = pool_obj_fy.read(cr, uid, fy_id, ['date_start'])['date_start']
fy_start_date = datetime.strptime(fy_start_date, '%Y-%m-%d')
last_month_date = datetime.strptime(today, '%Y-%m-%d') - relativedelta(months=1)
fiscal_year = pool_obj_fy.browse(cr, uid, fy_id)
fy_start_date = datetime.datetime.strptime(fiscal_year.date_start, '%Y-%m-%d').date()
last_month_date = current_date - relativedelta(months=1)
while (last_month_date > fy_start_date):
LIST_RANGES.append(today + " to " + last_month_date.strftime('%Y-%m-%d'))
today = (last_month_date- relativedelta(days=1)).strftime('%Y-%m-%d')
last_month_date = datetime.strptime(today, '%Y-%m-%d') - relativedelta(months=1)
add(names, current_date, last_month_date)
current_date = last_month_date - relativedelta(days=1)
last_month_date = current_date - relativedelta(months=1)
LIST_RANGES.append(today +" to " + fy_start_date.strftime('%Y-%m-%d'))
add(names, current_date, fy_start_date)
cr.execute('delete from temp_range')
for range in LIST_RANGES:
self.pool['temp.range'].create(cr, uid, {'name':range})
for name in names:
self.pool['temp.range'].create(cr, uid, {'name':name})
cr.execute("""
create or replace view report_aged_receivable as (

View File

@ -239,7 +239,7 @@ class account_automatic_reconcile(osv.osv_memory):
(account_id.id,))
additional_unrec = cr.fetchone()[0]
unreconciled = unreconciled + additional_unrec
context.update({'reconciled': reconciled, 'unreconciled': unreconciled})
context = dict(context, reconciled=reconciled, unreconciled=unreconciled)
model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','account_automatic_reconcile_view1')])
resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id']
return {

View File

@ -85,7 +85,7 @@ class account_chart(osv.osv_memory):
fy_obj = self.pool.get('account.fiscalyear')
if context is None:
context = {}
data = self.read(cr, uid, ids, [], context=context)[0]
data = self.read(cr, uid, ids, context=context)[0]
result = mod_obj.get_object_reference(cr, uid, 'account', 'action_account_tree')
id = result and result[1] or False
result = act_obj.read(cr, uid, [id], context=context)[0]

View File

@ -62,6 +62,7 @@ class account_fiscalyear_close(osv.osv_memory):
raise osv.except_osv(_('Warning!'), _('The entries to reconcile should belong to the same company.'))
r_id = self.pool.get('account.move.reconcile').create(cr, uid, {'type': 'auto', 'opening_reconciliation': True})
cr.execute('update account_move_line set reconcile_id = %s where id in %s',(r_id, tuple(ids),))
obj_acc_move_line.invalidate_cache(cr, uid, ['reconcile_id'], ids, context=context)
return r_id
obj_acc_period = self.pool.get('account.period')
@ -175,6 +176,7 @@ class account_fiscalyear_close(osv.osv_memory):
AND b.reconcile_id IN (SELECT DISTINCT(reconcile_id)
FROM account_move_line a
WHERE a.period_id IN ('''+fy2_period_set+''')))''', (new_journal.id, period.id, period.date_start, move_id, tuple(account_ids),))
self.invalidate_cache(cr, uid, context=context)
#2. report of the accounts with defferal method == 'detail'
cr.execute('''
@ -203,7 +205,7 @@ class account_fiscalyear_close(osv.osv_memory):
WHERE account_id IN %s
AND ''' + query_line + ''')
''', (new_journal.id, period.id, period.date_start, move_id, tuple(account_ids),))
self.invalidate_cache(cr, uid, context=context)
#3. report of the accounts with defferal method == 'balance'
cr.execute('''
@ -243,6 +245,7 @@ class account_fiscalyear_close(osv.osv_memory):
'draft')
if query_2nd_part:
cr.execute(query_1st_part + query_2nd_part, tuple(query_2nd_part_args))
self.invalidate_cache(cr, uid, context=context)
#validate and centralize the opening move
obj_acc_move.validate(cr, uid, [move_id], context=context)
@ -267,6 +270,7 @@ class account_fiscalyear_close(osv.osv_memory):
cr.execute('UPDATE account_fiscalyear ' \
'SET end_journal_period_id = %s ' \
'WHERE id = %s', (ids[0], old_fyear.id))
obj_acc_fiscalyear.invalidate_cache(cr, uid, ['end_journal_period_id'], [old_fyear.id], context=context)
return {'type': 'ir.actions.act_window_close'}

View File

@ -41,6 +41,10 @@ class account_fiscalyear_close_state(osv.osv_memory):
@param ids: List of Account fiscalyear close states IDs
"""
journal_period_obj = self.pool.get('account.journal.period')
period_obj = self.pool.get('account.period')
fiscalyear_obj = self.pool.get('account.fiscalyear')
for data in self.read(cr, uid, ids, context=context):
fy_id = data['fy_id'][0]
@ -53,6 +57,7 @@ class account_fiscalyear_close_state(osv.osv_memory):
'WHERE fiscalyear_id = %s', ('done', fy_id))
cr.execute('UPDATE account_fiscalyear ' \
'SET state = %s WHERE id = %s', ('done', fy_id))
self.invalidate_cache(cr, uid, context=context)
return {'type': 'ir.actions.act_window_close'}

View File

@ -68,10 +68,10 @@ class account_invoice_refund(osv.osv_memory):
}
def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):