[IMP] account,sale:checked multi-company in accounting and sale module

bzr revid: mtr@mtr-20100608064531-6q96hu7uet2e5qc9
This commit is contained in:
mtr 2010-06-08 12:15:31 +05:30
parent fcc0296fff
commit af6e99a052
5 changed files with 158 additions and 118 deletions

View File

@ -513,6 +513,10 @@ class account_account(osv.osv):
self._check_moves(cr, uid, ids, "write", context)
if 'type' in vals.keys():
self._check_allow_type_change(cr, uid, ids, vals['type'], context=context)
if 'company_id' in vals:
obj=self.pool.get('account.move.line').search(cr, uid, [('account_id', '=', ids)])
if obj:
raise osv.except_osv(_('Warning !'), _('You cannot update Company as its related record exist in Entry Lines'))
return super(account_account, self).write(cr, uid, ids, vals, context=context)
def unlink(self, cr, uid, ids, context={}):
@ -711,7 +715,7 @@ class account_period(osv.osv):
'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True, states={'done':[('readonly',True)]}, select=True),
'state': fields.selection([('draft','Draft'), ('done','Done')], 'State', readonly=True,
help='When monthly periods are created. The state is \'Draft\'. At the end of monthly period it is in \'Done\' state.'),
'company_id': fields.many2one('res.company', 'Company', required=True)
'company_id': fields.related('fiscalyear_id','company_id',type='many2one',relation='res.company',string='Company',store=True)
}
_defaults = {
'state': lambda *a: 'draft',
@ -783,7 +787,15 @@ class account_period(osv.osv):
if not ids:
ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit)
return self.name_get(cr, user, ids, context=context)
def write(self, cr, uid, ids, vals, context=None):
obj=[]
if 'company_id' in vals:
obj=self.pool.get('account.move.line').search(cr, uid, [('period_id', '=', ids)])
if obj:
raise osv.except_osv(_('Warning !'), _('You cannot update Company as its related record exist in Entry Lines'))
return super(account_period, self).write(cr, uid, ids, vals, context=context)
account_period()
class account_journal_period(osv.osv):
@ -809,7 +821,7 @@ class account_journal_period(osv.osv):
'state': fields.selection([('draft','Draft'), ('printed','Printed'), ('done','Done')], 'State', required=True, readonly=True,
help='When journal period is created. The state is \'Draft\'. If a report is printed it comes to \'Printed\' state. When all transactions are done, it comes in \'Done\' state.'),
'fiscalyear_id': fields.related('period_id', 'fiscalyear_id', string='Fiscal Year', type='many2one', relation='account.fiscalyear'),
'company_id' : fields.many2one('res.company', 'Company')
'company_id': fields.related('journal_id','company_id',type='many2one',relation='res.company',string='Company')
}
def _check(self, cr, uid, ids, context={}):

View File

@ -497,10 +497,18 @@ class account_move_line(osv.osv):
if l.account_id.type == 'closed':
return False
return True
def _check_company_id(self, cr, uid, ids):
lines = self.browse(cr, uid, ids)
for l in lines:
if l.company_id == l.account_id.company_id and l.company_id == l.period_id.company_id:
return True
return False
_constraints = [
(_check_no_view, 'You can not create move line on view account.', ['account_id']),
(_check_no_closed, 'You can not create move line on closed account.', ['account_id']),
(_check_company_id,'Company must be same for its related account and period.',['company_id'] ),
]
#TODO: ONCHANGE_ACCOUNT_ID: set account_tax_id
@ -574,28 +582,37 @@ class account_move_line(osv.osv):
unmerge = []
total = 0.0
merges_rec = []
for line in self.browse(cr, uid, ids, context):
if line.reconcile_id:
raise osv.except_osv(_('Warning'), _('Already Reconciled!'))
if line.reconcile_partial_id:
for line2 in line.reconcile_partial_id.line_partial_ids:
if not line2.reconcile_id:
if line2.id not in merges:
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:
res = self.reconcile(cr, uid, merges+unmerge, context=context)
return res
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
flag=False
for line in self.browse(cr, uid, ids, context.get('active_ids')):
for line1 in self.browse(cr, uid, ids, context.get('active_ids')):
if line1.company_id == line.company_id:
flag=True
else:
raise osv.except_osv(_('Warning !'), _('To reconcile the records Company must be the same'))
if flag:
for line in self.browse(cr, uid, ids, context):
if line.reconcile_id:
raise osv.except_osv(_('Warning'), _('Already Reconciled!'))
if line.reconcile_partial_id:
for line2 in line.reconcile_partial_id.line_partial_ids:
if not line2.reconcile_id:
if line2.id not in merges:
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:
res = self.reconcile(cr, uid, merges+unmerge, context=context)
return res
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={}):
lines = self.browse(cr, uid, ids, context=context)
@ -604,104 +621,112 @@ class account_move_line(osv.osv):
currency = 0.0
account_id = False
partner_id = False
for line in unrec_lines:
if line.state <> 'valid':
raise osv.except_osv(_('Error'),
_('Entry "%s" is not valid !') % line.name)
credit += line['credit']
debit += line['debit']
currency += line['amount_currency'] or 0.0
account_id = line['account_id']['id']
partner_id = (line['partner_id'] and line['partner_id']['id']) or False
writeoff = debit - credit
# Ifdate_p in context => take this date
if context.has_key('date_p') and context['date_p']:
date=context['date_p']
else:
date = time.strftime('%Y-%m-%d')
cr.execute('SELECT account_id, reconcile_id \
FROM account_move_line \
WHERE id =ANY(%s) \
GROUP BY account_id,reconcile_id',(ids,))
r = cr.fetchall()
#TODO: move this check to a constraint in the account_move_reconcile object
if (len(r) != 1) and not context.get('fy_closing', False):
raise osv.except_osv(_('Error'), _('Entries are not of the same account or already reconciled ! '))
if not unrec_lines:
raise osv.except_osv(_('Error'), _('Entry is already reconciled'))
account = self.pool.get('account.account').browse(cr, uid, account_id, context=context)
if not context.get('fy_closing', False) and not account.reconcile:
raise osv.except_osv(_('Error'), _('The account is not defined to be reconciled !'))
if r[0][1] != None:
raise osv.except_osv(_('Error'), _('Some entries are already reconciled !'))
if (not self.pool.get('res.currency').is_zero(cr, uid, account.company_id.currency_id, writeoff)) or \
(account.currency_id and (not self.pool.get('res.currency').is_zero(cr, uid, account.currency_id, currency))):
if not writeoff_acc_id:
raise osv.except_osv(_('Warning'), _('You have to provide an account for the write off entry !'))
if writeoff > 0:
debit = writeoff
credit = 0.0
self_credit = writeoff
self_debit = 0.0
flag=False
for line in self.browse(cr, uid, ids, context.get('active_ids')):
for line1 in self.browse(cr, uid, ids, context.get('active_ids')):
if line1.company_id == line.company_id:
flag=True
else:
raise osv.except_osv(_('Warning !'), _('To reconcile the records Company must be the same'))
if flag:
for line in unrec_lines:
if line.state <> 'valid':
raise osv.except_osv(_('Error'),
_('Entry "%s" is not valid !') % line.name)
credit += line['credit']
debit += line['debit']
currency += line['amount_currency'] or 0.0
account_id = line['account_id']['id']
partner_id = (line['partner_id'] and line['partner_id']['id']) or False
writeoff = debit - credit
# Ifdate_p in context => take this date
if context.has_key('date_p') and context['date_p']:
date=context['date_p']
else:
debit = 0.0
credit = -writeoff
self_credit = 0.0
self_debit = -writeoff
date = time.strftime('%Y-%m-%d')
# If comment exist in context, take it
if 'comment' in context and context['comment']:
libelle=context['comment']
else:
libelle='Write-Off'
cr.execute('SELECT account_id, reconcile_id \
FROM account_move_line \
WHERE id =ANY(%s) \
GROUP BY account_id,reconcile_id',(ids,))
r = cr.fetchall()
#TODO: move this check to a constraint in the account_move_reconcile object
if (len(r) != 1) and not context.get('fy_closing', False):
raise osv.except_osv(_('Error'), _('Entries are not of the same account or already reconciled ! '))
if not unrec_lines:
raise osv.except_osv(_('Error'), _('Entry is already reconciled'))
account = self.pool.get('account.account').browse(cr, uid, account_id, context=context)
if not context.get('fy_closing', False) and not account.reconcile:
raise osv.except_osv(_('Error'), _('The account is not defined to be reconciled !'))
if r[0][1] != None:
raise osv.except_osv(_('Error'), _('Some entries are already reconciled !'))
writeoff_lines = [
(0, 0, {
'name':libelle,
'debit':self_debit,
'credit':self_credit,
'account_id':account_id,
if (not self.pool.get('res.currency').is_zero(cr, uid, account.company_id.currency_id, writeoff)) or \
(account.currency_id and (not self.pool.get('res.currency').is_zero(cr, uid, account.currency_id, currency))):
if not writeoff_acc_id:
raise osv.except_osv(_('Warning'), _('You have to provide an account for the write off entry !'))
if writeoff > 0:
debit = writeoff
credit = 0.0
self_credit = writeoff
self_debit = 0.0
else:
debit = 0.0
credit = -writeoff
self_credit = 0.0
self_debit = -writeoff
# If comment exist in context, take it
if 'comment' in context and context['comment']:
libelle=context['comment']
else:
libelle='Write-Off'
writeoff_lines = [
(0, 0, {
'name':libelle,
'debit':self_debit,
'credit':self_credit,
'account_id':account_id,
'date':date,
'partner_id':partner_id,
'currency_id': account.currency_id.id or False,
'amount_currency': account.currency_id.id and -currency or 0.0
}),
(0, 0, {
'name':libelle,
'debit':debit,
'credit':credit,
'account_id':writeoff_acc_id,
'analytic_account_id': context.get('analytic_id', False),
'date':date,
'partner_id':partner_id
})
]
writeoff_move_id = self.pool.get('account.move').create(cr, uid, {
'period_id': writeoff_period_id,
'journal_id': writeoff_journal_id,
'date':date,
'partner_id':partner_id,
'currency_id': account.currency_id.id or False,
'amount_currency': account.currency_id.id and -currency or 0.0
}),
(0, 0, {
'name':libelle,
'debit':debit,
'credit':credit,
'account_id':writeoff_acc_id,
'analytic_account_id': context.get('analytic_id', False),
'date':date,
'partner_id':partner_id
'state': 'draft',
'line_id': writeoff_lines
})
]
writeoff_move_id = self.pool.get('account.move').create(cr, uid, {
'period_id': writeoff_period_id,
'journal_id': writeoff_journal_id,
'date':date,
'state': 'draft',
'line_id': writeoff_lines
writeoff_line_ids = self.search(cr, uid, [('move_id', '=', writeoff_move_id), ('account_id', '=', account_id)])
ids += writeoff_line_ids
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_partial_ids': map(lambda x: (3,x,False), ids)
})
writeoff_line_ids = self.search(cr, uid, [('move_id', '=', writeoff_move_id), ('account_id', '=', account_id)])
ids += writeoff_line_ids
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_partial_ids': map(lambda x: (3,x,False), ids)
})
wf_service = netsvc.LocalService("workflow")
# 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)
for id in ids:
wf_service.trg_trigger(uid, 'account.move.line', id, cr)
return r_id
wf_service = netsvc.LocalService("workflow")
# 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)
for id in ids:
wf_service.trg_trigger(uid, 'account.move.line', id, cr)
return r_id
def view_header_get(self, cr, user, view_id, view_type, context):
if context.get('account_id', False):

View File

@ -39,6 +39,7 @@ class sale_shop(osv.osv):
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'),
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist'),
'project_id': fields.many2one('account.analytic.account', 'Analytic Account'),
'company_id': fields.many2one('res.company', 'Company'),
}
sale_shop()
@ -277,7 +278,7 @@ class sale_order(osv.osv):
'invoice_quantity': fields.selection([('order', 'Ordered Quantities'), ('procurement', 'Shipped Quantities')], 'Invoice on', help="The sale order will automatically create the invoice proposition (draft invoice). Ordered and delivered quantities may not be the same. You have to choose if you invoice based on ordered or shipped quantities. If the product is a service, shipped quantities means hours spent on the associated tasks.", required=True),
'payment_term': fields.many2one('account.payment.term', 'Payment Term'),
'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position'),
'company_id': fields.many2one('res.company','Company',select=1),
'company_id': fields.related('shop_id','company_id',type='many2one',relation='res.company',string='Company',store=True)
}
_defaults = {
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'sale.order', context=c),

View File

@ -16,6 +16,7 @@
<field model="res.company" name="name" search="[]" use="name"/>
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
<field model="account.payment.term" name="payment_default_id" search="[]"/>
<field model="res.company" name="company_id" search="[]"/>
</record>
<function eval="('default',False,'shop_id', [('sale.order', False)], shop, True, False, False, False, True)" id="sale_default_set" model="ir.values" name="set"/>

View File

@ -14,6 +14,7 @@
<form string="Sale Shop">
<field name="name" select="1"/>
<field name="warehouse_id" required="1" select="1" widget="selection"/>
<field name="company_id"/>
<separator colspan="4" string="Accounting"/>
<field name="payment_default_id"/>
<field domain="[('type','=','sale')]" name="pricelist_id" select="1"/>