'name': fields.char('Name', size=64, required=True),
'type': fields.char('Type', size=16, required=True),
'line_id': fields.one2many('account.move.line', 'reconcile_id', 'Entry lines'),
+ 'line_partial_ids': fields.one2many('account.move.line', 'reconcile_partial_id', 'Partial Entry lines'),
'create_date': fields.date('Creation date', readonly=True),
}
_defaults = {
'name': lambda self,cr,uid,ctx={}: self.pool.get('ir.sequence').get(cr, uid, 'account.reconcile') or '/',
}
+ def reconcile_partial_check(self, cr, uid, ids, type='auto', context={}):
+ for rec in self.pool.get('account.move.reconcile').browse(cr, uid, ids):
+ total = 0.0
+ for line in rec.line_partial_ids:
+ total += (line.debit or 0.0) - (line.credit or 0.0)
+ if not total:
+ self.write(cr,uid, map(lambda x: x.id, rec.line_partial_ids), {'reconcile_id': rec.id })
+ for line in rec.line_partial_ids:
+ total += (line.debit or 0.0) - (line.credit or 0.0)
+ return True
+ def name_get(self, cr, uid, ids, context=None):
+ result = {}
+ for r in self.browse(cr, uid, ids, context):
+ total = reduce(lambda y,t: (t.debit or 0.0) - (t.credit or 0.0) + y, r.line_partial_ids, 0.0)
+ if total:
+ result[r.id] = '%s (%.2f)' % (r.name, total)
+ else:
+ result[r.id] = r.name
+ return result
account_move_reconcile()
#----------------------------------------------------------
if move.reconcile_id and move.reconcile_id.line_ids:
torec += map(lambda x: x.id, move.reconcile_id.line_ids)
try:
- account_move_line_obj.reconcile(cr, uid, torec, 'statement', context)
+ if abs(move.reconcile_amount-move.amount<0.0001):
+ account_move_line_obj.reconcile(cr, uid, torec, 'statement', context)
+ else:
+ account_move_line_obj.reconcile_partial(cr, uid, torec, 'statement', context)
except:
raise osv.except_osv('Error !', 'Unable to reconcile entry "%s": %.2f'%(move.name, move.amount))
'ref': fields.char('Ref.', size=32),
'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),
'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optionnal other currency if it is a multi-currency entry."),
'currency_id': fields.many2one('res.currency', 'Currency', help="The optionnal other currency if it is a multi-currency entry."),
# writeoff; entry generated for the difference between the lines
#
+ def reconcile_partial(self, cr, uid, ids, type='auto', context={}):
+ merges = []
+ unmerge = []
+ total = 0.0
+ merges_rec = []
+ for line in self.browse(cr, uid, ids, context):
+ if line.reconcile_id:
+ raise 'Already Reconciled'
+ if line.reconcile_partial_id:
+ for line2 in line.reconcile_partial_id.line_partial_ids:
+ if not line2.reconcile_id:
+ merges.append(line2.id)
+ total += (line2.debit or 0.0) - (line2.credit or 0.0)
+ merges_rec.append(line.reconcile_partial_id.id)
+ else:
+ unmerge.append(line.id)
+ total += (line.debit or 0.0) - (line.credit or 0.0)
+ if not total:
+ return self.reconcile(cr, uid, merges+unmerge, context=context)
+ r_id = self.pool.get('account.move.reconcile').create(cr, uid, {
+ 'type': type,
+ 'line_partial_ids': map(lambda x: (4,x,False), merges+unmerge)
+ })
+ self.pool.get('account.move.reconcile').reconcile_partial_check(cr, uid, [r_id] + merges_rec, context=context)
+ return True
+
def reconcile(self, cr, uid, ids, type='auto', writeoff_acc_id=False, writeoff_period_id=False, writeoff_journal_id=False, context={}):
id_set = ','.join(map(str, ids))
lines = self.browse(cr, uid, ids, context=context)
r_id = self.pool.get('account.move.reconcile').create(cr, uid, {
#'name': date,
'type': type,
- 'line_id': map(lambda x: (4,x,False), ids)
+ 'line_id': map(lambda x: (4,x,False), ids),
+ 'line_partial_ids': map(lambda x: (3,x,False), ids)
})
# the id of the move.reconcile is written in the move.line (self) by the create method above
# because of the way the line_id are defined: (4, x, False)
<field name="journal_id" select="2"/>
<field name="period_id"/>
<field name="reconcile_id"/>
+ <field name="reconcile_partial_id"/>
<field name="active" select="2"/>
<field name="state" select="2"/>
</page>
<field name="blocked" select="3"/>
<separator string="State" colspan="4"/>
- <field name="state" select="2"/>
+ <newline/>
<field name="reconcile_id"/>
+ <field name="reconcile_partial_id"/>
+ <field name="state" select="2"/>
</page>
<page string="Analytic Lines">
<field name="analytic_lines" colspan="4" nolabel="1"/>
<separator string="State" colspan="4"/>
<field name="reconcile_id"/>
+ <field name="reconcile_partial_id"/>
<field name="statement_id"/>
<field name="state"/>
</form>
move_id = self.pool.get('account.move').create(cr, uid, move)
line_ids = []
+ total = 0.0
line = self.pool.get('account.move.line')
cr.execute('select id from account_move_line where move_id in ('+str(move_id)+','+str(invoice.move_id.id)+')')
lines = line.browse(cr, uid, map(lambda x: x[0], cr.fetchall()) )
for l in lines:
if l.account_id.id==src_account_id:
line_ids.append(l.id)
-
- self.pool.get('account.move.line').reconcile(cr, uid, line_ids, 'manual', writeoff_acc_id, writeoff_period_id, writeoff_journal_id, context)
+ total += (l.debit or 0.0) - (l.credit or 0.0)
+ print total, writeoff_period_id, writeoff_acc_id
+ if (not total) or writeoff_acc_id:
+ print 'Total'
+ self.pool.get('account.move.line').reconcile(cr, uid, line_ids, 'manual', writeoff_acc_id, writeoff_period_id, writeoff_journal_id, context)
+ else:
+ print 'Partial'
+ self.pool.get('account.move.line').reconcile_partial(cr, uid, line_ids, 'manual', context)
return True
account_invoice()
states = {
'init': {
'actions': [_get_period],
- 'result': {'type':'form', 'arch':pay_form, 'fields':pay_fields, 'state':[('end','Cancel'),('writeoff_check','Pay Invoice')]}
+ 'result': {'type':'form', 'arch':pay_form, 'fields':pay_fields, 'state':[('end','Cancel'),('reconcile','Partial Payment'),('writeoff_check','Full Payment')]}
},
'writeoff_check': {
'actions': [],
account_id = line.account_id.id
return {'trans_nbr': count, 'account_id': account_id, 'credit': credit, 'debit': debit, 'writeoff': debit - credit}
+def _trans_rec_reconcile_partial(self, cr, uid, data, context=None):
+ pool = pooler.get_pool(cr.dbname)
+ account_move_line_obj = pool.get('account.move.line')
+ account_move_line_obj.reconcile_partial(cr, uid, data['ids'], 'manual', context=context)
+ return {}
+
def _trans_rec_reconcile(self, cr, uid, data, context=None):
pool = pooler.get_pool(cr.dbname)
account_move_line_obj = pool.get('account.move.line')
period_id, journal_id, context=context)
return {}
-def _wo_check(self, cr, uid, data, context):
- if data['form']['writeoff'] == 0:
- return 'reconcile'
- return 'addendum'
+def _partial_check(self, cr, uid, data, context):
+ if _trans_rec_get(self,cr,uid, data, context)['writeoff'] == 0:
+ return 'init_full'
+ return 'init_partial'
_transaction_add_form = '''<?xml version="1.0"?>
<form string="Information addendum">
class wiz_reconcile(wizard.interface):
states = {
'init': {
+ 'actions': [],
+ 'result': {'type': 'choice', 'next_state': _partial_check}
+ },
+ 'init_full': {
'actions': [_trans_rec_get],
- 'result': {'type': 'form', 'arch':_transaction_form, 'fields':_transaction_fields, 'state':[('end','Cancel'),('writeoff_check','Reconcile')]}
+ 'result': {'type': 'form', 'arch':_transaction_form, 'fields':_transaction_fields, 'state':[('end','Cancel'),('reconcile','Reconcile')]}
},
- 'writeoff_check': {
- 'actions': [],
- 'result' : {'type' : 'choice', 'next_state': _wo_check }
+ 'init_partial': {
+ 'actions': [_trans_rec_get],
+ 'result': {'type': 'form', 'arch':_transaction_form, 'fields':_transaction_fields, 'state':[('end','Cancel'),('addendum','Reconcile With Write-Off'),('partial','Partial Reconcile')]}
},
'addendum': {
'actions': [_trans_rec_addendum],
'reconcile': {
'actions': [_trans_rec_reconcile],
'result': {'type': 'state', 'state':'end'}
+ },
+ 'partial': {
+ 'actions': [_trans_rec_reconcile_partial],
+ 'result': {'type': 'state', 'state':'end'}
}
}
wiz_reconcile('account.move.line.reconcile')