Improvement in the accounting:

Reconciliation and multiple lines in bank statement
	Journal controls on account type and account for:
		Entries in journals
		Bank statement
	-> to avoid using the wrong account depending on the journal

bzr revid: fp@tinyerp.com-e6e78405e32db42f11d574b4d5c55a832d43f846
This commit is contained in:
Fabien Pinckaers 2007-04-19 19:58:31 +00:00
parent 4b69295eea
commit 3cef1f4386
4 changed files with 182 additions and 26 deletions

View File

@ -126,6 +126,21 @@ class account_account(osv.osv):
_name = "account.account"
_description = "Account"
def search(self, cr, uid, args, offset=0, limit=None, order=None):
pos = 0
while pos<len(args):
if args[pos][0]=='journal_id':
jour = self.pool.get('account.journal').browse(cr, uid, args[pos][2])
if (not (jour.account_control_ids or jour.type_control_ids)) or not args[pos][2]:
del args[pos]
continue
ids3 = map(lambda x: x.code, jour.type_control_ids)
ids1 = super(account_account,self).search(cr, uid, [('type','in',ids3)])
ids1 += map(lambda x: x.id, jour.account_control_ids)
args[pos] = ('id','in',ids1)
pos+=1
return super(account_account,self).search(cr, uid, args, offset, limit, order)
def _credit(self, cr, uid, ids, field_name, arg, context={}):
acc_set = ",".join(map(str, ids))
cr.execute("SELECT a.id, COALESCE(SUM(l.credit*a.sign),0) FROM account_account a LEFT JOIN account_move_line l ON (a.id=l.account_id) WHERE a.type!='view' AND a.id IN (%s) AND l.active AND l.state<>'draft' GROUP BY a.id" % acc_set)
@ -312,7 +327,10 @@ class account_journal(osv.osv):
'name': fields.char('Journal Name', size=64, required=True),
'code': fields.char('Code', size=16),
'type': fields.selection([('sale','Sale'), ('purchase','Purchase'), ('cash','Cash'), ('general','General'), ('situation','Situation')], 'Type', size=32, required=True),
'type_control_ids': fields.many2many('account.account.type', 'account_journal_type_rel', 'journal_id','type_id', 'Type Controls', domain=[('code','<>','view')]),
'account_control_ids': fields.many2many('account.account', 'account_account_type_rel', 'journal_id','account_id', 'Account', domain=[('type','<>','view')]),
'active': fields.boolean('Active'),
'view_id': fields.many2one('account.journal.view', 'View', required=True, help="Gives the view used when writing or browsing entries in this journal. The view tell Tiny ERP which fields should be visible, required or readonly and in which order. You can create your own view for a faster encoding in each journal."),
'default_credit_account_id': fields.many2one('account.account', 'Default Credit Account'),
@ -561,6 +579,12 @@ class account_move(osv.osv):
l[2]['period_id'] = default_period
context['period_id'] = default_period
if not 'name' in vals:
journal = self.pool.get('account.journal').browse(cr, uid, context.get('journal_id', vals.get('journal_id', False)))
if journal.sequence_id:
vals['name'] = self.pool.get('ir.sequence').get_id(cr, uid, journal.sequence_id.id)
else:
raise osv.except_osv('Error', 'No sequence defined in the journal !')
if 'line_id' in vals:
c = context.copy()
c['novalidate'] = True

View File

@ -104,32 +104,63 @@ class account_bank_statement(osv.osv):
if (not st.journal_id.default_credit_account_id) or (not st.journal_id.default_debit_account_id):
raise osv.except_osv('Configration Error !', 'Please verify that an account is defined in the journal.')
for move in st.line_ids:
move_id = self.pool.get('account.move').create(cr, uid, {
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
}, context=context)
if not move.amount:
continue
self.pool.get('account.move.line').create(cr, uid, {
torec = []
amount = move.amount
if move.reconcile_id and move.reconcile_id.line_new_ids:
for newline in move.reconcile_id.line_new_ids:
amount += newline.amount
torec.append(self.pool.get('account.move.line').create(cr, uid, {
'name': move.name,
'date': move.date,
'move_id': move_id,
'partner_id': ((move.partner_id) and move.partner_id.id) or False,
'account_id': (move.account_id) and move.account_id.id,
'credit': ((move.amount>0) and move.amount) or 0.0,
'debit': ((move.amount<0) and -move.amount) or 0.0,
'credit': ((amount>0) and amount) or 0.0,
'debit': ((amount<0) and -amount) or 0.0,
'statement_id': st.id,
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
'ref': move.invoice_id and move.invoice_id.number or ''
}, context=context)
if not st.journal_id.centralisation:
c = context.copy()
c['journal_id'] = st.journal_id.id
c['period_id'] = st.period_id.id
fields = ['move_id','name','date','partner_id','account_id','credit','debit']
default = self.pool.get('account.move.line').default_get(cr, uid, fields, context=c)
default.update({
'statement_id': st.id,
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
})
self.pool.get('account.move.line').create(cr, uid, default, context=context)
}, context=context))
if move.reconcile_id and move.reconcile_id.line_new_ids:
for newline in move.reconcile_id.line_new_ids:
self.pool.get('account.move.line').create(cr, uid, {
'name': newline.name or move.name,
'date': move.date,
'move_id': move_id,
'partner_id': ((move.partner_id) and move.partner_id.id) or False,
'account_id': (newline.account_id) and newline.account_id.id,
'debit': newline.amount>0 and newline.amount or 0.0,
'credit': newline.amount<0 and -newline.amount or 0.0,
'statement_id': st.id,
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
}, context=context)
c = context.copy()
c['journal_id'] = st.journal_id.id
c['period_id'] = st.period_id.id
fields = ['move_id','name','date','partner_id','account_id','credit','debit']
default = self.pool.get('account.move.line').default_get(cr, uid, fields, context=c)
default.update({
'statement_id': st.id,
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
'move_id': move_id,
})
self.pool.get('account.move.line').create(cr, uid, default, context=context)
if move.reconcile_id and move.reconcile_id.line_ids:
torec += map(lambda x: x.id, move.reconcile_id.line_ids)
try:
self.pool.get('account.move.line').reconcile(cr, uid, torec, 'statement', context)
except:
raise osv.except_osv('Error !', 'Unable to reconcile entry "%s": %.2f'%(move.name, move.amount))
done.append(st.id)
self.write(cr, uid, done, {'state':'confirm'}, context=context)
return True
@ -153,6 +184,69 @@ class account_bank_statement(osv.osv):
return {}
account_bank_statement()
class account_bank_statement_reconcile(osv.osv):
_name = "account.bank.statement.reconcile"
_description = "Statement reconcile"
def _total_entry(self, cr, uid, ids, prop, unknow_none, context={}):
result = {}
for o in self.browse(cr, uid, ids, context):
result[o.id] = 0.0
for line in o.line_ids:
result[o.id] += line.debit - line.credit
return result
def _total_new(self, cr, uid, ids, prop, unknow_none, context={}):
result = {}
for o in self.browse(cr, uid, ids, context):
result[o.id] = 0.0
for line in o.line_new_ids:
result[o.id] += line.amount
return result
def _total_balance(self, cr, uid, ids, prop, unknow_none, context={}):
result = {}
for o in self.browse(cr, uid, ids, context):
result[o.id] = o.total_new-o.total_entry+o.total_amount
return result
def _total_amount(self, cr, uid, ids, prop, unknow_none, context={}):
return dict(map(lambda x: (x,context.get('amount', 0.0)), ids))
def name_get(self, cr, uid, ids, context):
res= []
for o in self.browse(cr, uid, ids, context):
res.append((o.id, '[%.2f/%.2f]' % (o.total_entry, o.total_new)))
return res
_columns = {
'name': fields.char('Date', size=64, required=True),
'partner_id': fields.many2one('res.partner', 'Partner', readonly=True),
'line_new_ids': fields.one2many('account.bank.statement.reconcile.line', 'line_id', 'Write-Off'),
'total_entry': fields.function(_total_entry, method=True, string='Total entries'),
'total_new': fields.function(_total_new, method=True, string='Total write-off'),
'total_amount': fields.function(_total_amount, method=True, string='Payment amount'),
'total_balance': fields.function(_total_balance, method=True, string='Balance'),
}
_defaults = {
'name': lambda *a:time.strftime('%Y-%m-%d'),
'partner_id': lambda s,cr,u,c={}: c.get('partner', False),
'total_amount': lambda s,cr,u,c={}: c.get('amount', 0.0)
}
account_bank_statement_reconcile()
class account_bank_statement_reconcile_line(osv.osv):
_name = "account.bank.statement.reconcile.line"
_description = "Statement reconcile line"
_columns = {
'name': fields.char('Description', size=64),
'account_id': fields.many2one('account.account', 'Account', required=True),
'line_id': fields.many2one('account.bank.statement.reconcile', 'Reconcile'),
'amount': fields.float('Amount', required=True),
}
account_bank_statement_reconcile_line()
class account_bank_statement_line(osv.osv):
def onchange_partner_id(self, cr, uid, id, partner_id, type, context={}):
if not partner_id:
@ -177,9 +271,8 @@ class account_bank_statement_line(osv.osv):
'partner_id': fields.many2one('res.partner', 'Partner'),
'account_id': fields.many2one('account.account','Account', required=True),
'statement_id': fields.many2one('account.bank.statement', 'Statement', select=True),
'invoice_id': fields.many2one('account.invoice', 'Invoice', states={'confirm':[('readonly',True)]}),
'reconcile_id': fields.many2one('account.bank.statement.reconcile', 'Reconcile', states={'confirm':[('readonly',True)]}),
}
_defaults = {
'name': lambda self,cr,uid,context={}: self.pool.get('ir.sequence').get(cr, uid, 'account.bank.statement.line'),
@ -189,5 +282,3 @@ class account_bank_statement_line(osv.osv):
account_bank_statement_line()

View File

@ -358,6 +358,8 @@ class account_move_line(osv.osv):
for field in journal.view_id.columns_id:
fields.append(field.field)
attrs = []
if field.field=='account_id' and journal.id:
attrs.append('domain="[(\'journal_id\', \'=\', '+str(journal.id)+'),(\'type\',\'&lt;&gt;\',\'view\')]"')
if field.readonly:
attrs.append('readonly="1"')
if field.required:
@ -474,3 +476,13 @@ class account_move_line(osv.osv):
self.pool.get('account.move').validate(cr, uid, [vals['move_id']], context)
return result
account_move_line()
class account_bank_statement_reconcile(osv.osv):
_inherit = "account.bank.statement.reconcile"
_columns = {
'line_ids': fields.many2many('account.move.line', 'account_bank_statement_line_rel', 'statement_id', 'line_id', 'Entries'),
}
account_bank_statement_reconcile()

View File

@ -403,14 +403,14 @@
<field name="balance_end_real"/>
<separator string="Entry Lines" colspan="4"/>
<field name="line_ids" colspan="4" nolabel="1">
<tree string="Statement Lines" editable="bottom">
<tree string="Statement lines" editable="bottom">
<field name="date"/>
<field name="name"/>
<field name="type"/>
<field name="partner_id" on_change="onchange_partner_id(partner_id,type)"/>
<field name="invoice_id" select="1" domain="[('partner_id','=',partner_id),('state','=','open')]"/>
<field name="account_id"/>
<field name="account_id" domain="[('journal_id','=',parent.journal_id)]"/>
<field name="amount"/>
<field name="reconcile_id" context="{'partner_id':partner_id,'amount':amount,'account_id':account_id}"/>
</tree>
</field>
<group col="7" colspan="4">
@ -435,6 +435,34 @@
</record>
<menuitem name="Financial Management/Entries/Statements" id="menu_bank_statement_tree" action="action_bank_statement_tree"/>
<record model="ir.ui.view" id="view_bank_statement_reconcile">
<field name="name">account.bank.statement.reconcile.form</field>
<field name="model">account.bank.statement.reconcile</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Reconcile">
<field name="name" select="1"/>
<field name="total_amount"/>
<separator colspan="4" string="Entries"/>
<field name="line_ids" view_mode="tree" colspan="4" nolabel="1" domain="[('partner_id','=',context.get('partner_id', False)),('state','=','valid'),('account_id','=',context.get('account_id', False))]">
</field>
<field name="line_new_ids" colspan="4" nolabel="1">
<tree string="Write-Off" editable="bottom">
<field name="account_id"/>
<field name="amount"/>
<field name="name"/>
</tree>
</field>
<group colspan="4" col="5">
<field name="total_entry"/>
<field name="total_new"/>
<field name="total_balance"/>
<button name="dummy" string="Compute" colspan="2"/>
</group>
</form>
</field>
</record>
#---------------------------------------------------------
# Account Types
#---------------------------------------------------------
@ -695,11 +723,10 @@
<tree string="Account Entry Line">
<field name="date"/>
<field name="move_id"/>
<field name="statement_id" string="St."/>
<field name="ref"/>
<field name="name"/>
<field name="partner_id"/>
<field name="account_id"/>
<field name="date_maturity"/>
<field name="debit"/>
<field name="credit"/>
<field name="state"/>
@ -719,6 +746,8 @@
<separator string="General Information" colspan="4"/>
<field name="name" select="1"/>
<field name="date" select="1"/>
<field name="ref" select="1"/>
<newline/>
<field name="account_id" select="1"/>
<field name="partner_id" select="1"/>