[IMP] account,sale:checked multi-company in accounting and sale module
bzr revid: mtr@mtr-20100608064531-6q96hu7uet2e5qc9
This commit is contained in:
parent
fcc0296fff
commit
af6e99a052
|
@ -513,6 +513,10 @@ class account_account(osv.osv):
|
||||||
self._check_moves(cr, uid, ids, "write", context)
|
self._check_moves(cr, uid, ids, "write", context)
|
||||||
if 'type' in vals.keys():
|
if 'type' in vals.keys():
|
||||||
self._check_allow_type_change(cr, uid, ids, vals['type'], context=context)
|
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)
|
return super(account_account, self).write(cr, uid, ids, vals, context=context)
|
||||||
|
|
||||||
def unlink(self, cr, uid, ids, 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),
|
'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,
|
'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.'),
|
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 = {
|
_defaults = {
|
||||||
'state': lambda *a: 'draft',
|
'state': lambda *a: 'draft',
|
||||||
|
@ -783,7 +787,15 @@ class account_period(osv.osv):
|
||||||
if not ids:
|
if not ids:
|
||||||
ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit)
|
ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit)
|
||||||
return self.name_get(cr, user, ids, context=context)
|
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()
|
account_period()
|
||||||
|
|
||||||
class account_journal_period(osv.osv):
|
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,
|
'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.'),
|
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'),
|
'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={}):
|
def _check(self, cr, uid, ids, context={}):
|
||||||
|
|
|
@ -497,10 +497,18 @@ class account_move_line(osv.osv):
|
||||||
if l.account_id.type == 'closed':
|
if l.account_id.type == 'closed':
|
||||||
return False
|
return False
|
||||||
return True
|
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 = [
|
_constraints = [
|
||||||
(_check_no_view, 'You can not create move line on view account.', ['account_id']),
|
(_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_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
|
#TODO: ONCHANGE_ACCOUNT_ID: set account_tax_id
|
||||||
|
@ -574,28 +582,37 @@ class account_move_line(osv.osv):
|
||||||
unmerge = []
|
unmerge = []
|
||||||
total = 0.0
|
total = 0.0
|
||||||
merges_rec = []
|
merges_rec = []
|
||||||
for line in self.browse(cr, uid, ids, context):
|
flag=False
|
||||||
if line.reconcile_id:
|
for line in self.browse(cr, uid, ids, context.get('active_ids')):
|
||||||
raise osv.except_osv(_('Warning'), _('Already Reconciled!'))
|
for line1 in self.browse(cr, uid, ids, context.get('active_ids')):
|
||||||
if line.reconcile_partial_id:
|
if line1.company_id == line.company_id:
|
||||||
for line2 in line.reconcile_partial_id.line_partial_ids:
|
flag=True
|
||||||
if not line2.reconcile_id:
|
else:
|
||||||
if line2.id not in merges:
|
raise osv.except_osv(_('Warning !'), _('To reconcile the records Company must be the same'))
|
||||||
merges.append(line2.id)
|
if flag:
|
||||||
total += (line2.debit or 0.0) - (line2.credit or 0.0)
|
for line in self.browse(cr, uid, ids, context):
|
||||||
merges_rec.append(line.reconcile_partial_id.id)
|
if line.reconcile_id:
|
||||||
else:
|
raise osv.except_osv(_('Warning'), _('Already Reconciled!'))
|
||||||
unmerge.append(line.id)
|
if line.reconcile_partial_id:
|
||||||
total += (line.debit or 0.0) - (line.credit or 0.0)
|
for line2 in line.reconcile_partial_id.line_partial_ids:
|
||||||
if not total:
|
if not line2.reconcile_id:
|
||||||
res = self.reconcile(cr, uid, merges+unmerge, context=context)
|
if line2.id not in merges:
|
||||||
return res
|
merges.append(line2.id)
|
||||||
r_id = self.pool.get('account.move.reconcile').create(cr, uid, {
|
total += (line2.debit or 0.0) - (line2.credit or 0.0)
|
||||||
'type': type,
|
merges_rec.append(line.reconcile_partial_id.id)
|
||||||
'line_partial_ids': map(lambda x: (4,x,False), merges+unmerge)
|
else:
|
||||||
})
|
unmerge.append(line.id)
|
||||||
self.pool.get('account.move.reconcile').reconcile_partial_check(cr, uid, [r_id] + merges_rec, context=context)
|
total += (line.debit or 0.0) - (line.credit or 0.0)
|
||||||
return True
|
|
||||||
|
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={}):
|
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)
|
lines = self.browse(cr, uid, ids, context=context)
|
||||||
|
@ -604,104 +621,112 @@ class account_move_line(osv.osv):
|
||||||
currency = 0.0
|
currency = 0.0
|
||||||
account_id = False
|
account_id = False
|
||||||
partner_id = False
|
partner_id = False
|
||||||
for line in unrec_lines:
|
flag=False
|
||||||
if line.state <> 'valid':
|
for line in self.browse(cr, uid, ids, context.get('active_ids')):
|
||||||
raise osv.except_osv(_('Error'),
|
for line1 in self.browse(cr, uid, ids, context.get('active_ids')):
|
||||||
_('Entry "%s" is not valid !') % line.name)
|
if line1.company_id == line.company_id:
|
||||||
credit += line['credit']
|
flag=True
|
||||||
debit += line['debit']
|
else:
|
||||||
currency += line['amount_currency'] or 0.0
|
raise osv.except_osv(_('Warning !'), _('To reconcile the records Company must be the same'))
|
||||||
account_id = line['account_id']['id']
|
if flag:
|
||||||
partner_id = (line['partner_id'] and line['partner_id']['id']) or False
|
for line in unrec_lines:
|
||||||
writeoff = debit - credit
|
if line.state <> 'valid':
|
||||||
# Ifdate_p in context => take this date
|
raise osv.except_osv(_('Error'),
|
||||||
if context.has_key('date_p') and context['date_p']:
|
_('Entry "%s" is not valid !') % line.name)
|
||||||
date=context['date_p']
|
credit += line['credit']
|
||||||
else:
|
debit += line['debit']
|
||||||
date = time.strftime('%Y-%m-%d')
|
currency += line['amount_currency'] or 0.0
|
||||||
|
account_id = line['account_id']['id']
|
||||||
cr.execute('SELECT account_id, reconcile_id \
|
partner_id = (line['partner_id'] and line['partner_id']['id']) or False
|
||||||
FROM account_move_line \
|
writeoff = debit - credit
|
||||||
WHERE id =ANY(%s) \
|
# Ifdate_p in context => take this date
|
||||||
GROUP BY account_id,reconcile_id',(ids,))
|
if context.has_key('date_p') and context['date_p']:
|
||||||
r = cr.fetchall()
|
date=context['date_p']
|
||||||
#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
|
|
||||||
else:
|
else:
|
||||||
debit = 0.0
|
date = time.strftime('%Y-%m-%d')
|
||||||
credit = -writeoff
|
|
||||||
self_credit = 0.0
|
|
||||||
self_debit = -writeoff
|
|
||||||
|
|
||||||
# If comment exist in context, take it
|
cr.execute('SELECT account_id, reconcile_id \
|
||||||
if 'comment' in context and context['comment']:
|
FROM account_move_line \
|
||||||
libelle=context['comment']
|
WHERE id =ANY(%s) \
|
||||||
else:
|
GROUP BY account_id,reconcile_id',(ids,))
|
||||||
libelle='Write-Off'
|
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 = [
|
if (not self.pool.get('res.currency').is_zero(cr, uid, account.company_id.currency_id, writeoff)) or \
|
||||||
(0, 0, {
|
(account.currency_id and (not self.pool.get('res.currency').is_zero(cr, uid, account.currency_id, currency))):
|
||||||
'name':libelle,
|
if not writeoff_acc_id:
|
||||||
'debit':self_debit,
|
raise osv.except_osv(_('Warning'), _('You have to provide an account for the write off entry !'))
|
||||||
'credit':self_credit,
|
if writeoff > 0:
|
||||||
'account_id':account_id,
|
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,
|
'date':date,
|
||||||
'partner_id':partner_id,
|
'state': 'draft',
|
||||||
'currency_id': account.currency_id.id or False,
|
'line_id': writeoff_lines
|
||||||
'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, {
|
writeoff_line_ids = self.search(cr, uid, [('move_id', '=', writeoff_move_id), ('account_id', '=', account_id)])
|
||||||
'period_id': writeoff_period_id,
|
ids += writeoff_line_ids
|
||||||
'journal_id': writeoff_journal_id,
|
|
||||||
'date':date,
|
r_id = self.pool.get('account.move.reconcile').create(cr, uid, {
|
||||||
'state': 'draft',
|
#'name': date,
|
||||||
'line_id': writeoff_lines
|
'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")
|
||||||
writeoff_line_ids = self.search(cr, uid, [('move_id', '=', writeoff_move_id), ('account_id', '=', account_id)])
|
# the id of the move.reconcile is written in the move.line (self) by the create method above
|
||||||
ids += writeoff_line_ids
|
# because of the way the line_id are defined: (4, x, False)
|
||||||
|
for id in ids:
|
||||||
r_id = self.pool.get('account.move.reconcile').create(cr, uid, {
|
wf_service.trg_trigger(uid, 'account.move.line', id, cr)
|
||||||
#'name': date,
|
return r_id
|
||||||
'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
|
|
||||||
|
|
||||||
def view_header_get(self, cr, user, view_id, view_type, context):
|
def view_header_get(self, cr, user, view_id, view_type, context):
|
||||||
if context.get('account_id', False):
|
if context.get('account_id', False):
|
||||||
|
|
|
@ -39,6 +39,7 @@ class sale_shop(osv.osv):
|
||||||
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'),
|
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'),
|
||||||
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist'),
|
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist'),
|
||||||
'project_id': fields.many2one('account.analytic.account', 'Analytic Account'),
|
'project_id': fields.many2one('account.analytic.account', 'Analytic Account'),
|
||||||
|
'company_id': fields.many2one('res.company', 'Company'),
|
||||||
}
|
}
|
||||||
sale_shop()
|
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),
|
'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'),
|
'payment_term': fields.many2one('account.payment.term', 'Payment Term'),
|
||||||
'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position'),
|
'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 = {
|
_defaults = {
|
||||||
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'sale.order', context=c),
|
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'sale.order', context=c),
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<field model="res.company" name="name" search="[]" use="name"/>
|
<field model="res.company" name="name" search="[]" use="name"/>
|
||||||
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
|
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
|
||||||
<field model="account.payment.term" name="payment_default_id" search="[]"/>
|
<field model="account.payment.term" name="payment_default_id" search="[]"/>
|
||||||
|
<field model="res.company" name="company_id" search="[]"/>
|
||||||
</record>
|
</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"/>
|
<function eval="('default',False,'shop_id', [('sale.order', False)], shop, True, False, False, False, True)" id="sale_default_set" model="ir.values" name="set"/>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
<form string="Sale Shop">
|
<form string="Sale Shop">
|
||||||
<field name="name" select="1"/>
|
<field name="name" select="1"/>
|
||||||
<field name="warehouse_id" required="1" select="1" widget="selection"/>
|
<field name="warehouse_id" required="1" select="1" widget="selection"/>
|
||||||
|
<field name="company_id"/>
|
||||||
<separator colspan="4" string="Accounting"/>
|
<separator colspan="4" string="Accounting"/>
|
||||||
<field name="payment_default_id"/>
|
<field name="payment_default_id"/>
|
||||||
<field domain="[('type','=','sale')]" name="pricelist_id" select="1"/>
|
<field domain="[('type','=','sale')]" name="pricelist_id" select="1"/>
|
||||||
|
|
Loading…
Reference in New Issue