diff --git a/addons/account/account.py b/addons/account/account.py
index a95e6107a68..3772a660de9 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -416,15 +416,27 @@ class account_account(osv.osv):
default['child_parent_ids'] = False
return super(account_account, self).copy(cr, uid, id, default, context=context)
+ def _check_moves(self, cr, uid, ids, method, context):
+ line_obj = self.pool.get('account.move.line')
+ account_ids = self.search(cr, uid, [('id', 'child_of', ids)])
+ if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
+ if method == 'write':
+ raise osv.except_osv(_('Error !'), _('You cannot deactivate an account that contains account moves.'))
+ elif method == 'unlink':
+ raise osv.except_osv(_('Error !'), _('You cannot remove an account which has account entries!. '))
+ return True
+
def write(self, cr, uid, ids, vals, context=None):
if not context:
context = {}
if 'active' in vals and not vals['active']:
- line_obj = self.pool.get('account.move.line')
- account_ids = self.search(cr, uid, [('id', 'child_of', ids)])
- if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
- raise osv.except_osv(_('Error !'), _('You can not deactivate an account that contains Ledger Postings.'))
+ self._check_moves(cr, uid, ids, "write", context)
return super(account_account, self).write(cr, uid, ids, vals, context=context)
+
+ def unlink(self, cr, uid, ids, context={}):
+ self._check_moves(cr, uid, ids, "unlink", context)
+ return super(account_account, self).unlink(cr, uid, ids, context)
+
account_account()
class account_journal_view(osv.osv):
@@ -767,6 +779,23 @@ class account_move(osv.osv):
for id in ids:
result.setdefault(id, 0.0)
return result
+
+ def _search_amount(self, cr, uid, obj, name, args, context):
+ ids = []
+ cr.execute('select move_id,sum(debit) from account_move_line group by move_id')
+ result = dict(cr.fetchall())
+
+ for item in args:
+ if item[1] == '>=':
+ res = [('id', 'in', [k for k,v in result.iteritems() if v >= item[2]])]
+ else:
+ res = [('id', 'in', [k for k,v in result.iteritems() if v <= item[2]])]
+ ids += res
+
+ if not ids:
+ return [('id', '>', '0')]
+
+ return ids
_columns = {
'name': fields.char('Number', size=64, required=True),
@@ -778,7 +807,7 @@ class account_move(osv.osv):
'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
'to_check': fields.boolean('To Be Verified'),
'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner"),
- 'amount': fields.function(_amount_compute, method=True, string='Amount', digits=(16,int(config['price_accuracy']))),
+ 'amount': fields.function(_amount_compute, method=True, string='Amount', digits=(16,int(config['price_accuracy'])), type='float', fnct_search=_search_amount),
'date': fields.date('Date', required=True),
'type': fields.selection([
('pay_voucher','Cash Payment'),
@@ -956,7 +985,7 @@ class account_move(osv.osv):
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, {
- 'name': _t(cr, None, 'selection', context.get('lang'), source=(mode.capitalize()+' Centralisation')) or (mode.capitalize()+' Centralisation'),
+ 'name': _(mode.capitalize()+' Centralisation'),
'centralisation': mode,
'account_id': account_id,
'move_id': move.id,
@@ -1084,8 +1113,8 @@ class account_move_reconcile(osv.osv):
'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={}):
+ total = 0.0
for rec in self.browse(cr, uid, ids, context):
- total = 0.0
for line in rec.line_partial_ids:
total += (line.debit or 0.0) - (line.credit or 0.0)
if not total:
@@ -1546,7 +1575,8 @@ class account_model(osv.osv):
def generate(self, cr, uid, ids, datas={}, context={}):
move_ids = []
for model in self.browse(cr, uid, ids, context):
- period_id = self.pool.get('account.period').find(cr,uid, context=context)
+ context.update({'date':datas['date']})
+ period_id = self.pool.get('account.period').find(cr, uid, dt=context.get('date',False))
if not period_id:
raise osv.except_osv(_('No period found !'), _('Unable to find a valid period !'))
period_id = period_id[0]
@@ -1554,6 +1584,7 @@ class account_model(osv.osv):
'ref': model.ref,
'period_id': period_id,
'journal_id': model.journal_id.id,
+ 'date': context.get('date',time.strftime('%Y-%m-%d'))
})
move_ids.append(move_id)
for line in model.lines_id:
@@ -1571,7 +1602,7 @@ class account_model(osv.osv):
'move_id': move_id,
'ref': line.ref,
'partner_id': line.partner_id.id,
- 'date': time.strftime('%Y-%m-%d'),
+ 'date': context.get('date',time.strftime('%Y-%m-%d')),
'date_maturity': time.strftime('%Y-%m-%d')
})
c = context.copy()
diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py
index c78d1c289fb..88c8e53fa6a 100644
--- a/addons/account/account_bank_statement.py
+++ b/addons/account/account_bank_statement.py
@@ -143,8 +143,7 @@ class account_bank_statement(osv.osv):
'period_id': _get_period,
}
- def button_confirm(self, cr, uid, ids, context=None):
- context = context or {}
+ def button_confirm(self, cr, uid, ids, context={}):
done = []
res_currency_obj = self.pool.get('res.currency')
res_users_obj = self.pool.get('res.users')
@@ -166,7 +165,7 @@ class account_bank_statement(osv.osv):
_('The expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end))
if (not st.journal_id.default_credit_account_id) \
or (not st.journal_id.default_debit_account_id):
- raise osv.except_osv(_('Configration Error !'),
+ raise osv.except_osv(_('Configuration Error !'),
_('Please verify that an account is defined in the journal.'))
for line in st.move_line_ids:
@@ -178,10 +177,10 @@ class account_bank_statement(osv.osv):
# in bank stat.rec we get line_new_ids on bank.stat.rec.line
for move in st.line_ids:
context.update({'date':move.date})
-
move_id = account_move_obj.create(cr, uid, {
'journal_id': st.journal_id.id,
'period_id': st.period_id.id,
+ 'date': move.date,
}, context=context)
account_bank_statement_line_obj.write(cr, uid, [move.id], {
'move_ids': [(4,move_id, False)]
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index 4afb7e7837c..9b126658157 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -294,7 +294,7 @@ class account_move_line(osv.osv):
return [('id', '=', '0')]
return [('id', 'in', [x[0] for x in res])]
- def _invoice_search(self, cursor, user, obj, name, args):
+ def _invoice_search(self, cursor, user, obj, name, args, context):
if not len(args):
return []
invoice_obj = self.pool.get('account.invoice')
diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml
index caeb642101a..82f49d83cae 100644
--- a/addons/account/account_view.xml
+++ b/addons/account/account_view.xml
@@ -1582,6 +1582,8 @@
+
+
diff --git a/addons/account/invoice.py b/addons/account/invoice.py
index c2024c86eb3..7bfc4b702a7 100644
--- a/addons/account/invoice.py
+++ b/addons/account/invoice.py
@@ -153,7 +153,9 @@ class account_invoice(osv.osv):
if not move_lines:
res[id] = []
continue
+ res[id] = []
data_lines = self.pool.get('account.move.line').browse(cr,uid,move_lines)
+ partial_ids = []# Keeps the track of ids where partial payments are done with payment terms
for line in data_lines:
ids_line = []
if line.reconcile_id:
@@ -161,7 +163,8 @@ class account_invoice(osv.osv):
elif line.reconcile_partial_id:
ids_line = line.reconcile_partial_id.line_partial_ids
l = map(lambda x: x.id, ids_line)
- res[id]=[x for x in l if x <> line.id]
+ partial_ids.append(line.id)
+ res[id] =[x for x in l if x <> line.id and x not in partial_ids]
return res
def _get_invoice_line(self, cr, uid, ids, context=None):
@@ -183,11 +186,14 @@ class account_invoice(osv.osv):
src = []
lines = []
for m in self.pool.get('account.move.line').browse(cr, uid, moves, context):
+ temp_lines = []#Added temp list to avoid duplicate records
if m.reconcile_id:
- lines += map(lambda x: x.id, m.reconcile_id.line_id)
+ temp_lines = map(lambda x: x.id, m.reconcile_id.line_id)
elif m.reconcile_partial_id:
- lines += map(lambda x: x.id, m.reconcile_partial_id.line_partial_ids)
+ temp_lines = map(lambda x: x.id, m.reconcile_partial_id.line_partial_ids)
+ lines += [x for x in temp_lines if x not in lines]
src.append(m.id)
+
lines = filter(lambda x: x not in src, lines)
result[invoice.id] = lines
return result
@@ -991,14 +997,17 @@ class account_invoice(osv.osv):
else:
amount_currency = False
currency_id = False
-
+ if invoice.type in ('in_invoice', 'in_refund'):
+ ref = invoice.reference
+ else:
+ ref = self._convert_ref(cr, uid, invoice.number)
# Pay attention to the sign for both debit/credit AND amount_currency
l1 = {
'debit': direction * pay_amount>0 and direction * pay_amount,
'credit': direction * pay_amount<0 and - direction * pay_amount,
'account_id': src_account_id,
'partner_id': invoice.partner_id.id,
- 'ref':invoice.number,
+ 'ref':ref,
'date': date,
'currency_id':currency_id,
'amount_currency':amount_currency and direction * amount_currency or 0.0,
@@ -1009,7 +1018,7 @@ class account_invoice(osv.osv):
'credit': direction * pay_amount>0 and direction * pay_amount,
'account_id': pay_account_id,
'partner_id': invoice.partner_id.id,
- 'ref':invoice.number,
+ 'ref':ref,
'date': date,
'currency_id':currency_id,
'amount_currency':amount_currency and - direction * amount_currency or 0.0,
@@ -1022,7 +1031,7 @@ class account_invoice(osv.osv):
l2['name'] = name
lines = [(0, 0, l1), (0, 0, l2)]
- move = {'ref': invoice.number, 'line_id': lines, 'journal_id': pay_journal_id, 'period_id': period_id, 'date': date}
+ move = {'ref': ref, 'line_id': lines, 'journal_id': pay_journal_id, 'period_id': period_id, 'date': date}
move_id = self.pool.get('account.move').create(cr, uid, move, context=context)
line_ids = []
diff --git a/addons/account/partner.py b/addons/account/partner.py
index 54c902f4f86..a3985ee68e9 100644
--- a/addons/account/partner.py
+++ b/addons/account/partner.py
@@ -117,7 +117,7 @@ class res_partner(osv.osv):
res[pid][maps[type]] = (type=='receivable') and val or -val
return res
- def _credit_search(self, cr, uid, obj, name, args):
+ def _credit_search(self, cr, uid, obj, name, args, context):
if not len(args):
return []
where = ' and '.join(map(lambda x: '(sum(debit-credit)'+x[1]+str(x[2])+')',args))
@@ -128,7 +128,7 @@ class res_partner(osv.osv):
return [('id','=','0')]
return [('id','in',map(lambda x:x[0], res))]
- def _debit_search(self, cr, uid, obj, name, args):
+ def _debit_search(self, cr, uid, obj, name, args, context):
if not len(args):
return []
query = self.pool.get('account.move.line')._query_get(cr, uid, context={})
diff --git a/addons/account/wizard/wizard_fiscalyear_close.py b/addons/account/wizard/wizard_fiscalyear_close.py
index a3400d0ddf1..7e48f7c496c 100644
--- a/addons/account/wizard/wizard_fiscalyear_close.py
+++ b/addons/account/wizard/wizard_fiscalyear_close.py
@@ -79,10 +79,12 @@ def _data_save(self, cr, uid, data, context):
if move_ids:
raise wizard.except_wizard(_('UserError'),
_('The opening journal must not have any entry in the new fiscal year !'))
-
-
+ query = "SELECT id FROM account_fiscalyear WHERE date_stop < '" + str(new_fyear.date_start) + "'"
+ cr.execute(query)
+ result = cr.dictfetchall()
+ fy_ids = ','.join([str(x['id']) for x in result])
query_line = pool.get('account.move.line')._query_get(cr, uid,
- obj='account_move_line', context={'fiscalyear': fy_id})
+ obj='account_move_line', context={'fiscalyear': fy_ids})
cr.execute('select id from account_account WHERE active')
ids = map(lambda x: x[0], cr.fetchall())
for account in pool.get('account.account').browse(cr, uid, ids,
diff --git a/addons/account/wizard/wizard_statement_from_invoice.py b/addons/account/wizard/wizard_statement_from_invoice.py
index be4a01c94c4..5bb9a0d9772 100644
--- a/addons/account/wizard/wizard_statement_from_invoice.py
+++ b/addons/account/wizard/wizard_statement_from_invoice.py
@@ -58,15 +58,35 @@ def _search_invoices(obj, cr, uid, data, context):
journal_obj = pool.get('account.journal')
statement = statement_obj.browse(cr, uid, data['id'], context=context)
+ args_move_line = []
+ repeated_move_line_ids = []
+ # Creating a group that is unique for importing move lines(move lines, once imported into statement lines, should not appear again)
+ for st_line in statement.line_ids:
+ args_move_line = []
+ args_move_line.append(('name','=', st_line.name))
+ args_move_line.append(('ref','=',st_line.ref))
+ if st_line.partner_id:
+ args_move_line.append(('partner_id','=',st_line.partner_id.id))
+ args_move_line.append(('account_id','=',st_line.account_id.id))
+
+ move_line_id = line_obj.search(cr, uid, args_move_line,context=context)
+ if move_line_id:
+ repeated_move_line_ids.append(move_line_id)
+
journal_ids = data['form']['journal_id'][0][2]
if journal_ids == []:
journal_ids = journal_obj.search(cr, uid, [('type', 'in', ('sale','cash','purchase'))], context=context)
-
- line_ids = line_obj.search(cr, uid, [
+
+ args = [
('reconcile_id', '=', False),
('journal_id', 'in', journal_ids),
- ('account_id.reconcile', '=', True)],
+ ('account_id.reconcile', '=', True)]
+
+ if repeated_move_line_ids:
+ args.append(('id','not in',repeated_move_line_ids))
+
+ line_ids = line_obj.search(cr, uid, args,
#order='date DESC, id DESC', #doesn't work
context=context)
diff --git a/addons/account/wizard/wizard_subscription_generate.py b/addons/account/wizard/wizard_subscription_generate.py
index 49344b1d870..51cbad9ec3a 100644
--- a/addons/account/wizard/wizard_subscription_generate.py
+++ b/addons/account/wizard/wizard_subscription_generate.py
@@ -29,7 +29,7 @@ import pooler
_subscription_form = '''
''' % ('Subscription Compute',)
@@ -38,7 +38,7 @@ _subscription_fields = {
}
class wiz_subscription(wizard.interface):
- def _action_generate(self, cr, uid, data, context):
+ def _action_generate(self, cr, uid, data, context={}):
cr.execute('select id from account_subscription_line where date<%s and move_id is null', (data['form']['date'],))
ids = map(lambda x: x[0], cr.fetchall())
pooler.get_pool(cr.dbname).get('account.subscription.line').move_create(cr, uid, ids)
diff --git a/addons/account_analytic_default/__terp__.py b/addons/account_analytic_default/__terp__.py
index 79459a22935..9c3982990b3 100644
--- a/addons/account_analytic_default/__terp__.py
+++ b/addons/account_analytic_default/__terp__.py
@@ -34,7 +34,7 @@ Allows to automatically select analytic accounts based on criterions:
""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
- 'depends': ['account'],
+ 'depends': ['account', 'sale'],
'init_xml': [],
'update_xml': ['security/ir.model.access.csv', 'account_analytic_default_view.xml'],
'demo_xml': [],
diff --git a/addons/account_analytic_default/account_analytic_default.py b/addons/account_analytic_default/account_analytic_default.py
index 0e5a5219b71..f22e37e5e71 100644
--- a/addons/account_analytic_default/account_analytic_default.py
+++ b/addons/account_analytic_default/account_analytic_default.py
@@ -70,12 +70,51 @@ account_analytic_default()
class account_invoice_line(osv.osv):
_inherit = 'account.invoice.line'
_description = 'account invoice line'
- def product_id_change(self, cr, uid, ids, product, uom, qty=0, name='', type='out_invoice', partner_id=False, fposition=False, price_unit=False, address_invoice_id=False, context=None):
+
+ def product_id_change(self, cr, uid, ids, product, uom, qty=0, name='', type='out_invoice', partner_id=False, fposition=False, price_unit=False, address_invoice_id=False, context={}):
res_prod = super(account_invoice_line,self).product_id_change(cr, uid, ids, product, uom, qty, name, type, partner_id, fposition, price_unit, address_invoice_id, context)
rec = self.pool.get('account.analytic.default').account_get(cr, uid, product, partner_id, uid, time.strftime('%Y-%m-%d'), context)
if rec:
res_prod['value'].update({'account_analytic_id':rec.analytic_id.id})
+ else:
+ res_prod['value'].update({'account_analytic_id':False})
return res_prod
account_invoice_line()
+
+class stock_picking(osv.osv):
+ _inherit = "stock.picking"
+
+ def _get_account_analytic_invoice(self, cursor, user, picking, move_line):
+ partner_id = picking.address_id and picking.address_id.partner_id or False
+ rec = self.pool.get('account.analytic.default').account_get(cursor, user, move_line.product_id.id, partner_id and partner_id.id, user, time.strftime('%Y-%m-%d'), context={})
+
+ if rec:
+ return rec.analytic_id.id
+
+ return super(stock_picking, self)._get_account_analytic_invoice(cursor,
+ user, picking, move_line)
+
+stock_picking()
+
+class sale_order_line(osv.osv):
+ _inherit = 'sale.order.line'
+
+ # Method overridden to set the analytic account by default on criterion match
+ def invoice_line_create(self, cr, uid, ids, context={}):
+ create_ids = super(sale_order_line,self).invoice_line_create(cr, uid, ids, context)
+ sale_line_obj = self.browse(cr, uid, ids[0], context)
+ pool_inv_line = self.pool.get('account.invoice.line')
+
+ for line in pool_inv_line.browse(cr, uid, create_ids, context):
+ rec = self.pool.get('account.analytic.default').account_get(cr, uid, line.product_id.id, sale_line_obj.order_id.partner_id.id, uid, time.strftime('%Y-%m-%d'), context)
+
+ if rec:
+ pool_inv_line.write(cr, uid, [line.id], {'account_analytic_id':rec.analytic_id.id}, context=context)
+ return create_ids
+
+sale_order_line()
+
+
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_analytic_plans/account_analytic_plans.py b/addons/account_analytic_plans/account_analytic_plans.py
index d870976c5e4..51b37fdebb2 100644
--- a/addons/account_analytic_plans/account_analytic_plans.py
+++ b/addons/account_analytic_plans/account_analytic_plans.py
@@ -374,4 +374,25 @@ class analytic_default(osv.osv):
}
analytic_default()
+class sale_order_line(osv.osv):
+ _inherit = 'sale.order.line'
+
+ # Method overridden to set the analytic account by default on criterion match
+ def invoice_line_create(self, cr, uid, ids, context={}):
+ create_ids = super(sale_order_line,self).invoice_line_create(cr, uid, ids, context)
+ if ids:
+ sale_line_obj = self.browse(cr, uid, ids[0], context)
+ pool_inv_line = self.pool.get('account.invoice.line')
+
+ for line in pool_inv_line.browse(cr, uid, create_ids, context):
+ rec = self.pool.get('account.analytic.default').account_get(cr, uid, line.product_id.id, sale_line_obj.order_id.partner_id.id, uid, time.strftime('%Y-%m-%d'), context)
+
+ if rec:
+ pool_inv_line.write(cr, uid, [line.id], {'analytics_id':rec.analytics_id.id}, context=context)
+ cr.commit()
+ return create_ids
+
+sale_order_line()
+
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_followup/wizard/wizard_followup_print.py b/addons/account_followup/wizard/wizard_followup_print.py
index 9d7e62d9a37..2f82ec6ba60 100644
--- a/addons/account_followup/wizard/wizard_followup_print.py
+++ b/addons/account_followup/wizard/wizard_followup_print.py
@@ -125,12 +125,13 @@ class followup_all_print(wizard.interface):
def _update_partners(self, cr, uid, data, context):
to_update = data['form']['to_update']
for id in to_update.keys():
- cr.execute(
- "UPDATE account_move_line "\
- "SET followup_line_id=%s, followup_date=%s "\
- "WHERE id=%s",
- (to_update[id],
- data['form']['date'], int(id),))
+ if to_update[id]['partner_id'] in data['form']['partner_ids'][0][2]:
+ cr.execute(
+ "UPDATE account_move_line "\
+ "SET followup_line_id=%s, followup_date=%s "\
+ "WHERE id=%s",
+ (to_update[id]['level'],
+ data['form']['date'], int(id),))
return {}
def _sendmail(self ,cr, uid, data, context):
@@ -263,12 +264,12 @@ class followup_all_print(wizard.interface):
if date_maturity <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
if partner_id not in partner_list:
partner_list.append(partner_id)
- to_update[str(id)] = fups[followup_line_id][1]
+ to_update[str(id)]= {'level': fups[followup_line_id][1], 'partner_id': partner_id}
elif date and date <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
if partner_id not in partner_list:
partner_list.append(partner_id)
- to_update[str(id)] = fups[followup_line_id][1]
-
+ to_update[str(id)]= {'level': fups[followup_line_id][1], 'partner_id': partner_id}
+
message = pool.get('res.users').browse(cr, uid, uid, context=context).company_id.follow_up_msg
return {'partner_ids': partner_list, 'to_update': to_update, 'email_body':message}
diff --git a/addons/account_payment/account_move_line.py b/addons/account_payment/account_move_line.py
index d501975f565..0c7f61928c3 100644
--- a/addons/account_payment/account_move_line.py
+++ b/addons/account_payment/account_move_line.py
@@ -46,7 +46,7 @@ class account_move_line(osv.osv):
r=dict(cr.fetchall())
return r
- def _to_pay_search(self, cr, uid, obj, name, args):
+ def _to_pay_search(self, cr, uid, obj, name, args, context):
if not len(args):
return []
line_obj = self.pool.get('account.move.line')
diff --git a/addons/account_tax_include/invoice_tax_incl.py b/addons/account_tax_include/invoice_tax_incl.py
index 62c2dca1a48..f47c587babc 100644
--- a/addons/account_tax_include/invoice_tax_incl.py
+++ b/addons/account_tax_include/invoice_tax_incl.py
@@ -23,6 +23,7 @@ import time
import netsvc
from osv import fields, osv
import ir
+from tools import config
class account_invoice(osv.osv):
_inherit = "account.invoice"
@@ -45,7 +46,9 @@ class account_invoice_line(osv.osv):
"""
res = {}
tax_obj = self.pool.get('account.tax')
+ cur_obj = self.pool.get('res.currency')
for line in self.browse(cr, uid, ids):
+ cur = line.invoice_id and line.invoice_id.currency_id or False
res_init = super(account_invoice_line, self)._amount_line(cr, uid, [line.id], name, args, context)
res[line.id] = {
'price_subtotal': 0.0,
@@ -63,13 +66,13 @@ class account_invoice_line(osv.osv):
product_taxes = filter(lambda x: x.price_include, line.product_id.supplier_taxes_id)
if ((set(product_taxes) == set(line.invoice_line_tax_id)) or not product_taxes) and (line.invoice_id.price_type == 'tax_included'):
- res[line.id]['price_subtotal_incl'] = res_init[line.id]
+ res[line.id]['price_subtotal_incl'] = cur and cur_obj.round(cr, uid, cur, res_init[line.id]) or res_init[line.id]
else:
- res[line.id]['price_subtotal'] = res_init[line.id]
+ res[line.id]['price_subtotal'] = cur and cur_obj.round(cr, uid, cur, res_init[line.id]) or res_init[line.id]
for tax in tax_obj.compute_inv(cr, uid, product_taxes, res_init[line.id]/line.quantity, line.quantity):
- res[line.id]['price_subtotal'] = res[line.id]['price_subtotal'] - round(tax['amount'], 2)
+ res[line.id]['price_subtotal'] = res[line.id]['price_subtotal'] - round(tax['amount'], int(config['price_accuracy']))
else:
- res[line.id]['price_subtotal'] = res_init[line.id]
+ res[line.id]['price_subtotal'] = cur and cur_obj.round(cr, uid, cur, res_init[line.id]) or res_init[line.id]
if res[line.id]['price_subtotal']:
res[line.id]['price_subtotal_incl'] = res[line.id]['price_subtotal']
@@ -82,8 +85,8 @@ class account_invoice_line(osv.osv):
res[line.id]['price_subtotal'] = res[line.id]['price_subtotal'] - tax['amount']
res[line.id]['data'].append( tax)
- res[line.id]['price_subtotal']= round(res[line.id]['price_subtotal'], 2)
- res[line.id]['price_subtotal_incl']= round(res[line.id]['price_subtotal_incl'], 2)
+ res[line.id]['price_subtotal']= round(res[line.id]['price_subtotal'], int(config['price_accuracy']))
+ res[line.id]['price_subtotal_incl']= round(res[line.id]['price_subtotal_incl'], int(config['price_accuracy']))
return res
def _price_unit_default(self, cr, uid, context=None):
diff --git a/addons/account_voucher/account.py b/addons/account_voucher/account.py
index 8d6d59acf84..ec886bef6c6 100644
--- a/addons/account_voucher/account.py
+++ b/addons/account_voucher/account.py
@@ -28,7 +28,7 @@ import mx.DateTime
from mx.DateTime import RelativeDateTime
from tools import config
-class Account(osv.osv):
+class account_account(osv.osv):
_inherit = "account.account"
def _get_level(self, cr, uid, ids, field_name, arg, context={}):
@@ -108,7 +108,7 @@ class Account(osv.osv):
vals['type1'] = 'none'
journal_ids=self.pool.get('account.journal').search(cr,uid,[('name','=','Opening Journal')])
vals['journal_id'] = journal_ids and journal_ids[0] or False
- account_id = super(Account, self).create(cr, uid, vals, context)
+ account_id = super(account_account, self).create(cr, uid, vals, context)
if vals.get('type1', False) != False:
journal_id = vals.get('journal_id',False)
if journal_id and vals.has_key('open_bal'):
@@ -157,7 +157,7 @@ class Account(osv.osv):
vals['type1'] = 'cr'
else:
vals['type1'] = 'none'
- super(Account, self).write(cr, uid,ids, vals, context)
+ super(account_account, self).write(cr, uid,ids, vals, context)
if vals.has_key('open_bal'):
self_obj= self.browse(cr,uid,ids)
move_pool=self.pool.get('account.move')
@@ -213,16 +213,16 @@ class Account(osv.osv):
return {
'value' : {'type1' : type1}
}
-Account()
+account_account()
-class AccountMove(osv.osv):
+class account_move(osv.osv):
_inherit = "account.move"
_columns = {
'name':fields.char('Name', size=256, required=True, readonly=True, states={'draft':[('readonly',False)]}),
'narration':fields.text('Narration', readonly=True, select=True, states={'draft':[('readonly',False)]}),
}
-AccountMove()
+account_move()
class res_currency(osv.osv):
_inherit = "res.currency"
diff --git a/addons/account_voucher/report/report_voucher.rml b/addons/account_voucher/report/report_voucher.rml
index 9be52c064d7..93b767e5416 100755
--- a/addons/account_voucher/report/report_voucher.rml
+++ b/addons/account_voucher/report/report_voucher.rml
@@ -30,7 +30,7 @@
-
+
@@ -63,26 +63,29 @@
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -91,27 +94,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- [[ repeatIn(objects,'voucher') ]]
+ [[ repeatIn(objects,'voucher') ]]
[[ company.name ]]
- [[ company.partner_id.address and company.partner_id.address[0].street ]], [[ company.partner_id.address and company.partner_id.address[0].street2 ]]
+ [[ company.partner_id.address and company.partner_id.address[0].street ]]
[[ company.partner_id.address and company.partner_id.address[0].zip ]] [[ company.partner_id.address and company.partner_id.address[0].city ]] - [[ company.partner_id.address and company.partner_id.address[0].country_id and company.partner_id.address[0].country_id.name ]]
[[ company.partner_id.address and company.partner_id.address[0].phone ]]
[[ company.partner_id.address and company.partner_id.address[0].email ]]
- Cash Receipt Voucher [[ (voucher.type == 'rec_voucher' or removeParentNode('para')) and '' ]]
+
+
+
+ Cash Receipt Voucher [[ (voucher.type == 'rec_voucher' or removeParentNode('para')) and '' ]]
Cash Payment Voucher [[ (voucher.type == 'pay_voucher' or removeParentNode('para')) and '' ]]
- Bank Receipt Voucher [[ (voucher.type == 'bank_rec_voucher' or removeParentNode('para')) and '' ]]
+ Bank Receipt Voucher [[ (voucher.type == 'bank_rec_voucher' or removeParentNode('para')) and '' ]]
Bank Payment Voucher [[ (voucher.type == 'bank_pay_voucher' or removeParentNode('para')) and '' ]]
-
+
+
+
|
No.
|
- [[ voucher.number ]]
+ [[ voucher.number ]]
|
@@ -122,7 +174,7 @@
Dated :
|
- [[ time.strftime('%d %B,%Y', time.strptime(voucher.date , '%Y-%m-%d')) or '' ]]
+ [[ time.strftime('%d %B,%Y', time.strptime(voucher.date , '%Y-%m-%d')) or '' ]]
|
@@ -130,10 +182,10 @@
State :
|
- PRO-FORMA [[ ((voucher.state == 'proforma') or removeParentNode('para')) and '' ]]
- Draft[[ ((voucher.state == 'draft') or removeParentNode('para')) and '' ]]
- Canceled [[ ((voucher.state == 'cancel') or removeParentNode('para')) and '' ]]
- Posted [[ ((voucher.state == 'posted') or removeParentNode('para')) and '' ]]
+ PRO-FORMA [[ ((voucher.state == 'proforma') or removeParentNode('para')) and '' ]]
+ Draft[[ ((voucher.state == 'draft') or removeParentNode('para')) and '' ]]
+ Canceled [[ ((voucher.state == 'cancel') or removeParentNode('para')) and '' ]]
+ Posted [[ ((voucher.state == 'posted') or removeParentNode('para')) and '' ]]
|
@@ -144,51 +196,58 @@
Ref. :
|
- [[ voucher.reference ]]
+ [[ voucher.reference ]]
|
-
+
-
+
|
- Particulars
+ Particulars
|
- Debit
+ Debit
|
- Credit
+ Credit
|
-
+
- [[ repeatIn(voucher.move_ids,'move_ids') ]]
-
-
- |
- [[ (move_ids.partner_id and move_ids.partner_id.name) or 'Account']] :
- [[ move_ids.account_id.name ]]
- [[ move_ids.name ]] - [[ get_ref(voucher.id,move_ids) ]]
-
- |
-
- [[ move_ids.debit ]]
- |
-
- [[ move_ids.credit ]]
- |
-
-
-
+
+
+
+
+ [[ repeatIn(voucher.move_ids,'move_ids') ]]
+
+
+ |
+ [[ (move_ids.partner_id and move_ids.partner_id.name) or '']] :
+ [[ move_ids.account_id.name ]]
+ [[ get_ref(voucher.id,move_ids) ]]
+ |
+
+ [[ move_ids.debit ]]
+ |
+
+ [[ move_ids.credit ]]
+ |
+
+
+
+
+
+
+
|
@@ -197,7 +256,7 @@
|
-
+
|
@@ -214,7 +273,7 @@
|
- Through :
+ Through :
|
@@ -229,7 +288,7 @@
|
|
- [[ voucher.narration or '']]
+ [[ voucher.narration or '']]
|
@@ -244,7 +303,7 @@
|
|
- On Account of :
+ On Account of :
|
@@ -259,7 +318,7 @@
|
|
- [[ voucher.name ]]
+ [[ voucher.name ]]
|
@@ -274,7 +333,22 @@
|
|
- Amount (in words) :
+ Amount (in words) :
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+ |
+ [[ convert(voucher.amount,voucher.currency_id.name) ]]
|
@@ -289,34 +363,19 @@
|
|
- [[ convert(voucher.amount,voucher.currency_id.name) ]]
- |
-
-
+
|
-
-
-
- |
-
-
- |
-
-
-
+ [[ debit(voucher.move_ids)]]
|
- [[ debit(voucher.move_ids)]]
- |
-
- [[ credit(voucher.move_ids) ]]
+ [[ credit(voucher.move_ids) ]]
|
-
+
@@ -353,20 +412,20 @@
|
- Receiver's Signature
+ Receiver's Signature
|
-
+
|
-
+
|
- Authorised Signatory
+ Authorised Signatory
|
diff --git a/addons/account_voucher/report/report_voucher_amount.rml b/addons/account_voucher/report/report_voucher_amount.rml
index bcc47fa6434..d8175fe3b58 100755
--- a/addons/account_voucher/report/report_voucher_amount.rml
+++ b/addons/account_voucher/report/report_voucher_amount.rml
@@ -16,7 +16,7 @@
- D
+
@@ -27,7 +27,7 @@
-
+
@@ -57,25 +57,25 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -84,10 +84,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- [[ repeatIn(objects,'voucher') ]]
+ [[ repeatIn(objects,'voucher') ]]
[[ company.name ]]
[[ company.partner_id.address and company.partner_id.address[0].street ]]
[[ company.partner_id.address and company.partner_id.address[0].zip ]] [[ company.partner_id.address and company.partner_id.address[0].city ]] - [[ company.partner_id.address and company.partner_id.address[0].country_id and company.partner_id.address[0].country_id.name ]]
@@ -96,11 +140,11 @@
- Cash Receipt Voucher [[ (voucher.type == 'rec_voucher' or removeParentNode('para')) and '' ]]
+ Cash Receipt Voucher [[ (voucher.type == 'rec_voucher' or removeParentNode('para')) and '' ]]
Cash Payment Voucher [[ (voucher.type == 'pay_voucher' or removeParentNode('para')) and '' ]]
- Bank Receipt Voucher [[ (voucher.type == 'bank_rec_voucher' or removeParentNode('para')) and '' ]]
+ Bank Receipt Voucher [[ (voucher.type == 'bank_rec_voucher' or removeParentNode('para')) and '' ]]
Bank Payment Voucher [[ (voucher.type == 'bank_pay_voucher' or removeParentNode('para')) and '' ]]
-
+
@@ -109,7 +153,7 @@
No.
- [[ voucher.number ]]
+ [[ voucher.number ]]
|
@@ -120,7 +164,7 @@
Dated :
|
- [[ time.strftime('%d %B,%Y', time.strptime(voucher.date , '%Y-%m-%d')) or '' ]]
+ [[ time.strftime('%d %B,%Y', time.strptime(voucher.date , '%Y-%m-%d')) or '' ]]
|
@@ -128,10 +172,10 @@
State :
|
- PRO-FORMA [[ ((voucher.state == 'proforma') or removeParentNode('para')) and '' ]]
- Draft[[ ((voucher.state == 'draft') or removeParentNode('para')) and '' ]]
- Canceled [[ ((voucher.state == 'cancel') or removeParentNode('para')) and '' ]]
- Posted [[ ((voucher.state == 'posted') or removeParentNode('para')) and '' ]]
+ PRO-FORMA [[ ((voucher.state == 'proforma') or removeParentNode('para')) and '' ]]
+ Draft[[ ((voucher.state == 'draft') or removeParentNode('para')) and '' ]]
+ Canceled [[ ((voucher.state == 'cancel') or removeParentNode('para')) and '' ]]
+ Posted [[ ((voucher.state == 'posted') or removeParentNode('para')) and '' ]]
|
@@ -142,7 +186,7 @@
Ref. :
|
- [[ voucher.reference ]]
+ [[ voucher.reference ]]
|
@@ -150,7 +194,7 @@
Account :
|
- [[ voucher.account_id.name ]]
+ [[ voucher.account_id.name ]]
|
@@ -163,17 +207,19 @@
|
-
+
|
-
-
+
+
+
+
|
Particulars
@@ -183,26 +229,31 @@
|
-
-
-
- [[ repeatIn(voucher.payment_ids,'payment_ids') ]]
-
-
- |
- [[ payment_ids.partner_id.name ]] :
- [[ payment_ids.account_id.name ]]
- [[ payment_ids.ref ]] [[ payment_ids.amount ]] [[ payment_ids.type ]]
- |
-
- [[ payment_ids.amount ]]
- |
-
-
-
+
+
+
+
+ [[ repeatIn(voucher.payment_ids,'payment_ids') ]]
+
+
+ |
+ [[ payment_ids.partner_id.name ]] :
+ [[ payment_ids.account_id.name ]]
+ [[ payment_ids.ref ]] [[ payment_ids.amount ]] [[ payment_ids.type ]]
+ |
+
+ [[ payment_ids.amount ]]
+ |
+
+
+
+
+
+
+
|
@@ -233,10 +284,10 @@
|
- [[ voucher.narration or '' ]]
+ [[ voucher.narration or '' ]]
|
-
+
|
@@ -253,10 +304,10 @@
|
- [[ voucher.name ]]
+ [[ voucher.name ]]
|
-
+
|
@@ -273,7 +324,7 @@
|
- [[ convert(voucher.amount,voucher.currency_id.name) ]]
+ [[ convert(voucher.amount,voucher.currency_id.name) ]]
|
@@ -329,20 +380,20 @@
|
|
- Receiver's Signature
+ Receiver's Signature
|
-
+
|
-
+
|
- Authorised Signatory
+ Authorised Signatory
|
diff --git a/addons/base_contact/base_contact.py b/addons/base_contact/base_contact.py
index ec529a96865..457a96a1c6b 100644
--- a/addons/base_contact/base_contact.py
+++ b/addons/base_contact/base_contact.py
@@ -39,6 +39,13 @@ class res_partner_contact(osv.osv):
res = [(r['shortcut'], r['name']) for r in res if r['domain']=='contact']
return res
+ def _main_job(self, cr, uid, ids, fields, arg, context=None):
+ res = dict.fromkeys(ids, False)
+ for contact in self.browse(cr, uid, ids, context):
+ if contact.job_ids:
+ res[contact.id] = contact.job_ids[0].name_get()[0]
+ return res
+
_columns = {
'name': fields.char('Last Name', size=30,required=True),
'first_name': fields.char('First Name', size=30),
@@ -52,7 +59,7 @@ class res_partner_contact(osv.osv):
'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the partner contact without removing it."),
'partner_id':fields.related('job_ids','address_id','partner_id',type='many2one', relation='res.partner', string='Main Employer'),
'function_id':fields.related('job_ids','function_id',type='many2one', relation='res.partner.function', string='Main Function'),
- 'job_id':fields.related('job_ids',type='many2one', relation='res.partner.job', string='Main Job'),
+ 'job_id': fields.function(_main_job, method=True, type='many2one', relation='res.partner.job', string='Main Job'),
'email': fields.char('E-Mail', size=240),
'comment' : fields.text('Notes', translate=True),
'photo' : fields.binary('Image'),
@@ -81,6 +88,12 @@ res_partner_contact()
class res_partner_address(osv.osv):
+ def search(self, cr, user, args, offset=0, limit=None, order=None,
+ context=None, count=False):
+ if context and context.has_key('address_partner_id' ) and context['address_partner_id']:
+ args.append(('partner_id', '=', context['address_partner_id']))
+ return super(res_partner_address, self).search(cr, user, args, offset, limit, order, context, count)
+
#overriding of the name_get defined in base in order to remove the old contact name
def name_get(self, cr, user, ids, context={}):
if not len(ids):
@@ -155,7 +168,7 @@ class res_partner_job(osv.osv):
_defaults = {
'sequence_contact' : lambda *a: 0,
- 'state' : lambda *a: 'current',
+ 'state' : lambda *a: 'current',
}
res_partner_job()
diff --git a/addons/base_contact/base_contact_view.xml b/addons/base_contact/base_contact_view.xml
index db7ea54314e..6123e7ed938 100644
--- a/addons/base_contact/base_contact_view.xml
+++ b/addons/base_contact/base_contact_view.xml
@@ -48,16 +48,13 @@
-
+
diff --git a/addons/base_report_creator/wizard/base_report_creator_open.py b/addons/base_report_creator/wizard/base_report_creator_open.py
index a342114d119..be7420c5744 100644
--- a/addons/base_report_creator/wizard/base_report_creator_open.py
+++ b/addons/base_report_creator/wizard/base_report_creator_open.py
@@ -25,13 +25,15 @@ import netsvc
import time
import pooler
from osv import osv
-
+from tools.translate import _
class report_creator_open(wizard.interface):
def _open_report(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
+ if context.get('report_id',False):
+ raise wizard.except_wizard(_('UserError'),_('No Wizards available for this object!'))
rep = pool.get('base_report_creator.report').browse(cr, uid, data['id'], context)
view_mode = rep.view_type1
if rep.view_type2:
diff --git a/addons/base_report_creator/wizard/wiz_set_filter_fields.py b/addons/base_report_creator/wizard/wiz_set_filter_fields.py
index 82083cb3858..cf4accf56e9 100644
--- a/addons/base_report_creator/wizard/wiz_set_filter_fields.py
+++ b/addons/base_report_creator/wizard/wiz_set_filter_fields.py
@@ -22,6 +22,7 @@
import wizard
import netsvc
import pooler
+import tools
relation_type=['one2many','many2one','many2many']
char_type = ['char','text','selection']
@@ -121,7 +122,7 @@ def _set_filter_value(self, cr, uid, data, context):
model_pool = pooler.get_pool(cr.dbname).get(model_name)
table_name = model_pool._table
model_name = model_pool._description
-
+
if field_type:
if field_type == 'boolean':
if value_data == 1:
@@ -138,12 +139,12 @@ def _set_filter_value(self, cr, uid, data, context):
fields_list = set_field_operator(self,table_name+"."+field_data['name'],field_data['ttype'],form_data['operator'],value_data)
if fields_list:
create_dict = {
- 'name':model_name + "/" +field_data['field_description'] +" "+ mapping_fields[form_data['operator']] + " " + str(fields_list[2]) + " ",
- 'expression':' '.join(map(str,fields_list)),
+ 'name':model_name + "/" +field_data['field_description'] +" "+ mapping_fields[form_data['operator']] + " " + tools.ustr(fields_list[2]) + " ",
+ 'expression':' '.join(map(tools.ustr,fields_list)),
'report_id':data['id'],
'condition' : form_data['condition']
}
- pooler.get_pool(cr.dbname).get('base_report_creator.report.filter').create(cr,uid,create_dict)
+ pooler.get_pool(cr.dbname).get('base_report_creator.report.filter').create(cr,uid,create_dict,context)
#end if field_type == 'many2many' and value_data and len(value_data):
# pooler.get_pool(cr.dbname).get('custom.report.filter').create(cr,uid,form_data)
#end if field_type:
diff --git a/addons/crm/crm_segmentation.py b/addons/crm/crm_segmentation.py
index c65bedfd3a0..2f0e2a1c650 100644
--- a/addons/crm/crm_segmentation.py
+++ b/addons/crm/crm_segmentation.py
@@ -41,7 +41,7 @@ class crm_segmentation(osv.osv):
'segmentation_line': fields.one2many('crm.segmentation.line', 'segmentation_id', 'Criteria', required=True),
'som_interval': fields.integer('Days per Periode', help="A period is the average number of days between two cycle of sale or purchase for this segmentation. It's mainly used to detect if a partner has not purchased or buy for a too long time, so we suppose that his state of mind has decreased because he probably bought goods to another supplier. Use this functionality for recurring businesses."),
'som_interval_max': fields.integer('Max Interval', help="The computation is made on all events that occured during this interval, the past X periods."),
- 'som_interval_decrease': fields.float('Decrease (0>1)', help="If the partner has not purchased (or buied) during a period, decrease the state of mind by this factor. It\'s a multiplication"),
+ 'som_interval_decrease': fields.float('Decrease (0>1)', help="If the partner has not purchased (or bought) during a period, decrease the state of mind by this factor. It\'s a multiplication"),
'som_interval_default': fields.float('Default (0=None)', help="Default state of mind for period preceeding the 'Max Interval' computation. This is the starting state of mind by default if the partner has no event."),
'sales_purchase_active': fields.boolean('Use The Sales Purchase Rules', help='Check if you want to use this tab as part of the segmentation rule. If not checked, the criteria beneath will be ignored')
}
diff --git a/addons/crm_profiling/__terp__.py b/addons/crm_profiling/__terp__.py
index 1ce0af585b9..b155e806e0f 100644
--- a/addons/crm_profiling/__terp__.py
+++ b/addons/crm_profiling/__terp__.py
@@ -25,12 +25,11 @@
'version': '1.3',
'category': 'Generic Modules/CRM & SRM',
'description': """
- This module allow users to perform segmentation within partners.
- It use the profiles criteria from the earlier segmentation module and improve it thanks to the new concept of questionnaire. You can now regroup questions into a questionnaire and directly use it on a partner.
+ This module allows users to perform segmentation within partners.
+ It uses the profiles criteria from the earlier segmentation module and improve it. Thanks to the new concept of questionnaire. You can now regroup questions into a questionnaire and directly use it on a partner.
It also has been merged with the earlier CRM & SRM segmentation tool because they were overlapping.
-
The menu items related are in "CRM & SRM\Configuration\Segmentations"
diff --git a/addons/crm_profiling/crm_profiling_view.xml b/addons/crm_profiling/crm_profiling_view.xml
index 8ff3c67e6dc..e2ac5c4d1fc 100644
--- a/addons/crm_profiling/crm_profiling_view.xml
+++ b/addons/crm_profiling/crm_profiling_view.xml
@@ -172,7 +172,7 @@
-
+
diff --git a/addons/document/__terp__.py b/addons/document/__terp__.py
index bb9f41bfa6b..a9d7026776b 100644
--- a/addons/document/__terp__.py
+++ b/addons/document/__terp__.py
@@ -27,6 +27,12 @@
'description': """This is a complete document management system:
* User Authentication
* Document Indexation
+
+ ATTENTION:
+ - When you install this module in a running company that have already PDF files stored into the database,
+ you will lose them all.
+ - After installing this module PDF's are not longer stored into the database,
+ but in the servers rootpad like /server/bin/filestore.
""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
diff --git a/addons/hr/hr_department.py b/addons/hr/hr_department.py
index db771abd408..83c1f7101fd 100644
--- a/addons/hr/hr_department.py
+++ b/addons/hr/hr_department.py
@@ -97,7 +97,7 @@ class res_users(osv.osv):
result[user_id] = parent_ids
return result
- def _parent_search(self, cr, uid, obj, name, args):
+ def _parent_search(self, cr, uid, obj, name, args, context):
parent = []
for arg in args:
if arg[0] == 'parent_id':
@@ -132,7 +132,7 @@ class res_users(osv.osv):
result[manager_id] = child_ids
return result
- def _child_search(self, cr, uid, obj, name, args):
+ def _child_search(self, cr, uid, obj, name, args, context):
parent = []
for arg in args:
if arg[0] == 'child_ids':
diff --git a/addons/hr_holidays/hr.py b/addons/hr_holidays/hr.py
index 048b80b0744..3d07e506ea1 100755
--- a/addons/hr_holidays/hr.py
+++ b/addons/hr_holidays/hr.py
@@ -164,24 +164,6 @@ class hr_holidays(osv.osv):
}
_order = 'date_from desc'
- def create(self, cr, uid, vals, context={}):
- if context:
- if context.has_key('type'):
- vals['type'] = context['type']
- if context.has_key('allocation_type'):
- vals['allocation_type'] = context['allocation_type']
- return super(osv.osv,self).create(cr, uid, vals, context)
-
- #~ def _check_date(self, cr, uid, ids):
- #~ if ids:
- #~ cr.execute('select number_of_days from hr_holidays where id in ('+','.join(map(str, ids))+')')
- #~ res = cr.fetchall()
- #~ if res and res[0][0] <= 0:
- #~ return False
- #~ return True
-
- #_constraints = [(_check_date, 'Start date should not be greater than end date! ', ['number_of_days'])]
-
def onchange_date_from(self, cr, uid, ids, date_to, date_from):
result = {}
if date_to and date_from:
@@ -197,6 +179,51 @@ class hr_holidays(osv.osv):
}
return result
+ def _update_user_holidays(self, cr, uid, ids):
+ for record in self.browse(cr, uid, ids):
+ if record.state=='validate':
+ holiday_id=self.pool.get('hr.holidays.per.user').search(cr, uid, [('employee_id','=', record.employee_id.id),('holiday_status','=',record.holiday_status.id)])
+ if holiday_id:
+ obj_holidays_per_user=self.pool.get('hr.holidays.per.user').browse(cr, uid,holiday_id[0])
+ self.pool.get('hr.holidays.per.user').write(cr,uid,obj_holidays_per_user.id,{'leaves_taken':obj_holidays_per_user.leaves_taken - record.number_of_days})
+ if record.case_id:
+ if record.case_id.state <> 'draft':
+ raise osv.except_osv(_('Warning !'),
+ _('You can not cancel this holiday request. first You have to make its case in draft state.'))
+ else:
+ self.pool.get('crm.case').unlink(cr,uid,[record.case_id.id])
+
+ def _check_date(self, cr, uid, ids):
+ if ids:
+ cr.execute('select number_of_days from hr_holidays where id in ('+','.join(map(str, ids))+')')
+ res = cr.fetchall()
+ if res and res[0][0] < 0:
+ return False
+ return True
+
+ _constraints = [(_check_date, 'Start date should not be larger than end date! ', ['number_of_days'])]
+
+ def create(self, cr, uid, vals, *args, **kwargs):
+ id_holiday = super(hr_holidays, self).create(cr, uid, vals, *args, **kwargs)
+ self._create_holiday(cr, uid, [id_holiday])
+ return id_holiday
+
+ def unlink(self, cr, uid, ids, context={}):
+ self._update_user_holidays(cr, uid, ids)
+ return super(hr_holidays, self).unlink(cr, uid, ids, context)
+
+ def _create_holiday(self, cr, uid, ids):
+ holidays_user_obj = self.pool.get('hr.holidays.per.user')
+ holidays_data = self.browse(cr, uid, ids[0])
+ list_holiday = []
+ ids_user_hdays = holidays_user_obj.search(cr, uid, [('employee_id', '=', holidays_data.employee_id.id),('holiday_status', '=', holidays_data.holiday_status.id)])
+ for hdays in holidays_user_obj.browse(cr, uid, ids_user_hdays):
+ for req in hdays.holiday_ids:
+ list_holiday.append(req.id)
+ list_holiday.append(ids[0])
+ holidays_user_obj.write(cr, uid, ids_user_hdays, {'holiday_ids': [(6, 0, list_holiday)]})
+ return True
+
def onchange_date_to(self, cr, uid, ids, date_from, date_to):
result = {}
if date_from and date_to:
@@ -290,16 +317,7 @@ class hr_holidays(osv.osv):
return True
def holidays_cancel(self, cr, uid, ids, *args):
- for record in self.browse(cr, uid, ids):
- if record.state=='validate':
- if record.case_id:
- self.pool.get('crm.case').unlink(cr,uid,[record.case_id.id])
- if record.linked_request_ids:
- list_ids = []
- for id in record.linked_request_ids:
- list_ids.append(id.id)
- self.holidays_cancel(cr,uid,list_ids)
- self.unlink(cr,uid,list_ids)
+ self._update_user_holidays(cr, uid, ids)
self.write(cr, uid, ids, {
'state':'cancel'
})
diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
index 4595665d5c9..41e65e2d8fc 100644
--- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
+++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
@@ -72,7 +72,7 @@ account_analytic_account()
class account_analytic_line(osv.osv):
_inherit = 'account.analytic.line'
_columns = {
- 'invoice_id': fields.many2one('account.invoice', 'Invoice'),
+ 'invoice_id': fields.many2one('account.invoice', 'Invoice', ondelete="set null"),
'to_invoice': fields.many2one('hr_timesheet_invoice.factor', 'Type of Invoicing'),
}
diff --git a/addons/hr_timesheet_invoice/report/cost_ledger.py b/addons/hr_timesheet_invoice/report/cost_ledger.py
index f2ede84438f..9bde3837790 100644
--- a/addons/hr_timesheet_invoice/report/cost_ledger.py
+++ b/addons/hr_timesheet_invoice/report/cost_ledger.py
@@ -87,7 +87,7 @@ class account_analytic_cost_ledger(report_sxw.rml_parse):
revenue = 0.0
if lines[id].amount < 0 and lines[id].product_id and lines[id].product_uom_id and lines[id].account_id.pricelist_id:
ctx = {'uom': lines[id].product_uom_id.id}
- price = price_obj.price_get(self.cr, self.uid, [lines[id].pricelist_id.id], lines[id].product_id.id, lines[id].unit_amount, ctx)[lines[id].pricelist_id.id]
+ price = price_obj.price_get(self.cr, self.uid, [lines[id].account_id.pricelist_id.id], lines[id].product_id.id, lines[id].unit_amount, ctx)[lines[id].account_id.pricelist_id.id]
revenue = round(price * lines[id].unit_amount, 2)
r['revenue'] = revenue
self.sum_revenue[account_id] += revenue
diff --git a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
index 66bc45c8f7b..a7a0a4b6a51 100644
--- a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
+++ b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
@@ -35,6 +35,13 @@ class invoice_create(wizard.interface):
def _get_accounts(self, cr, uid, data, context):
if not len(data['ids']):
return {}
+ #Checking whether the analytic line is invoiced or not
+ pool = pooler.get_pool(cr.dbname)
+ analytic_line_obj = pool.get('account.analytic.line').browse(cr, uid, data['ids'], context)
+ for obj_acc in analytic_line_obj:
+ if obj_acc.invoice_id and obj_acc.invoice_id.state !='cancel':
+ raise wizard.except_wizard(_('Warning'),_('The analytic entry "%s" is already invoiced!')%(obj_acc.name,))
+
cr.execute("SELECT distinct(account_id) from account_analytic_line where id IN (%s)"% (','.join(map(str,data['ids'])),))
account_ids = cr.fetchall()
return {'accounts': [x[0] for x in account_ids]}
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
index 836df03b0f9..c63e19bd582 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
@@ -319,9 +319,12 @@ class hr_timesheet_sheet(osv.osv):
context, load='_classic_write')]
def unlink(self, cr, uid, ids, context=None):
- sheets = self.read(cr, uid, ids, ['state'])
- if any(s['state'] in ('confirm', 'done') for s in sheets):
- raise osv.except_osv(_('Invalid action !'), _('Cannot delete Sheet(s) which are already confirmed !'))
+ sheets = self.read(cr, uid, ids, ['state','total_attendance'])
+ for sheet in sheets:
+ if sheet['state'] in ('confirm', 'done'):
+ raise osv.except_osv(_('Invalid action !'), _('Cannot delete Sheet(s) which are already confirmed !'))
+ elif sheet['total_attendance'] <> 0.00:
+ raise osv.except_osv(_('Invalid action !'), _('Cannot delete Sheet(s) which have attendance entries encoded !'))
return super(hr_timesheet_sheet, self).unlink(cr, uid, ids, context=context)
hr_timesheet_sheet()
@@ -362,7 +365,7 @@ class hr_timesheet_line(osv.osv):
res[line_id] = False
return res
- def _sheet_search(self, cursor, user, obj, name, args):
+ def _sheet_search(self, cursor, user, obj, name, args, context):
if not len(args):
return []
sheet_obj = self.pool.get('hr_timesheet_sheet.sheet')
diff --git a/addons/l10n_be/account_pcmn_belgium.xml b/addons/l10n_be/account_pcmn_belgium.xml
index e657d259e60..9281d3c45ac 100644
--- a/addons/l10n_be/account_pcmn_belgium.xml
+++ b/addons/l10n_be/account_pcmn_belgium.xml
@@ -7021,8 +7021,8 @@
VI 0
percent
-
-
+
+
sale
diff --git a/addons/l10n_chart_uk_minimal/account_tax.xml b/addons/l10n_chart_uk_minimal/account_tax.xml
index a030925f8fa..42f214e5685 100755
--- a/addons/l10n_chart_uk_minimal/account_tax.xml
+++ b/addons/l10n_chart_uk_minimal/account_tax.xml
@@ -21,6 +21,7 @@
Input VAT
+
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index df41baf7bc2..1f3be7c0943 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -544,7 +544,7 @@ class mrp_production(osv.osv):
#TODO Review materials in function in_prod and prod_end.
def action_production_end(self, cr, uid, ids):
- move_ids = []
+# move_ids = []
for production in self.browse(cr, uid, ids):
for res in production.move_lines:
for move in production.move_created_ids:
@@ -552,7 +552,7 @@ class mrp_production(osv.osv):
cr.execute('INSERT INTO stock_move_history_ids \
(parent_id, child_id) VALUES (%s,%s)',
(res.id, move.id))
- move_ids.append(res.id)
+# move_ids.append(res.id)
vals= {'state':'confirmed'}
new_moves = [x.id for x in production.move_created_ids]
self.pool.get('stock.move').write(cr, uid, new_moves, vals)
@@ -562,7 +562,7 @@ class mrp_production(osv.osv):
self.pool.get('stock.move').check_assign(cr, uid, new_moves)
self.pool.get('stock.move').action_done(cr, uid, new_moves)
self._costs_generate(cr, uid, production)
- self.pool.get('stock.move').action_done(cr, uid, move_ids)
+# self.pool.get('stock.move').action_done(cr, uid, move_ids)
self.write(cr, uid, ids, {'state': 'done'})
return True
@@ -1009,7 +1009,7 @@ class mrp_procurement(osv.osv):
self.write(cr, uid, ids, {'state':'confirmed','message':''})
return True
- def action_move_assigned(self, cr, uid, ids):
+ def action_move_assigned(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state':'running','message':_('from stock: products assigned.')})
return True
@@ -1085,11 +1085,13 @@ class mrp_procurement(osv.osv):
newdate = newdate - DateTime.RelativeDateTime(days=company.po_lead)
newdate = newdate - procurement.product_id.seller_ids[0].delay
- context.update({'lang':partner.lang})
+ #Passing partner_id to context for purchase order line integrity of Line name
+ context.update({'lang':partner.lang, 'partner_id':partner_id})
+
product=self.pool.get('product.product').browse(cr,uid,procurement.product_id.id,context=context)
line = {
- 'name': product.name,
+ 'name': product.partner_ref,
'product_qty': qty,
'product_id': procurement.product_id.id,
'product_uom': uom_id,
diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml
index 40145749a22..34ea506fb23 100644
--- a/addons/mrp/mrp_view.xml
+++ b/addons/mrp/mrp_view.xml
@@ -717,9 +717,8 @@
-
+
-
diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py
index 1848470ad15..8a6efa625bb 100644
--- a/addons/mrp_operations/mrp_operations.py
+++ b/addons/mrp_operations/mrp_operations.py
@@ -141,7 +141,16 @@ class mrp_production_workcenter_line(osv.osv):
return True
def action_done(self, cr, uid, ids):
- self.write(cr, uid, ids, {'state':'done', 'date_finnished': time.strftime('%Y-%m-%d %H:%M:%S')})
+ delay = 0.0
+ date_now = time.strftime('%Y-%m-%d %H:%M:%S')
+ obj_line = self.browse(cr, uid, ids[0])
+
+ date_start = datetime.datetime.strptime(obj_line.date_start,'%Y-%m-%d %H:%M:%S')
+ date_finished = datetime.datetime.strptime(date_now,'%Y-%m-%d %H:%M:%S')
+ delay += (date_finished-date_start).days * 24
+ delay += (date_finished-date_start).seconds / float(60*60)
+
+ self.write(cr, uid, ids, {'state':'done', 'date_finnished': date_now,'delay':delay})
self.modify_production_order_state(cr,uid,ids,'done')
return True
@@ -337,7 +346,7 @@ class mrp_operations_operation(osv.osv):
a = datetime.datetime.strptime(time_lst[i-1],'%Y-%m-%d %H:%M:%S')
b = datetime.datetime.strptime(time_lst[i],'%Y-%m-%d %H:%M:%S')
diff += (b-a).days * 24
- diff += (b-a).seconds / (60*60)
+ diff += (b-a).seconds / float(60*60)
return diff
def check_operation(self,cr,uid,vals):
@@ -412,6 +421,7 @@ class mrp_operations_operation(osv.osv):
if code.start_stop=='start':
tmp=self.pool.get('mrp.production.workcenter.line').action_start_working(cr,uid,wc_op_id)
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', wc_op_id[0], 'button_start_working', cr)
+
if code.start_stop=='done':
tmp=self.pool.get('mrp.production.workcenter.line').action_done(cr,uid,wc_op_id)
@@ -433,9 +443,17 @@ class mrp_operations_operation(osv.osv):
if not self.check_operation(cr, uid, vals):
return
delay=self.calc_delay(cr, uid, vals)
- self.pool.get('mrp.production.workcenter.line').write(cr,uid,wc_op_id,{'delay':delay})
+ line_vals = {}
+ line_vals['delay'] = delay
+ if vals.get('date_start',False):
+ if code.start_stop == 'done':
+ line_vals['date_finnished'] = vals['date_start']
+ elif code.start_stop == 'start':
+ line_vals['date_start'] = vals['date_start']
- return super(mrp_operations_operation, self).create(cr, uid, vals, context=context)
+ self.pool.get('mrp.production.workcenter.line').write(cr, uid, wc_op_id, line_vals, context=context)
+
+ return super(mrp_operations_operation, self).create(cr, uid, vals, context=context)
_columns={
'production_id':fields.many2one('mrp.production','Production',required=True),
diff --git a/addons/point_of_sale/pos.py b/addons/point_of_sale/pos.py
index e9c89570729..7115495a647 100644
--- a/addons/point_of_sale/pos.py
+++ b/addons/point_of_sale/pos.py
@@ -510,19 +510,20 @@ class pos_order(osv.osv):
if line.qty < 0:
location_id, stock_dest_id = stock_dest_id, location_id
- self.pool.get('stock.move').create(cr, uid, {
- 'name': 'Stock move (POS %d)' % (order.id, ),
- 'product_uom': line.product_id.uom_id.id,
- 'product_uos': line.product_id.uom_id.id,
- 'picking_id': picking_id,
- 'product_id': line.product_id.id,
- 'product_uos_qty': abs(line.qty),
- 'product_qty': abs(line.qty),
- 'tracking_id': False,
- 'state': 'waiting',
- 'location_id': location_id,
- 'location_dest_id': stock_dest_id,
- })
+ self.pool.get('stock.move').create(cr, uid, {
+ 'name': 'Stock move (POS %d)' % (order.id, ),
+ 'product_uom': line.product_id.uom_id.id,
+ 'product_uos': line.product_id.uom_id.id,
+ 'picking_id': picking_id,
+ 'product_id': line.product_id.id,
+ 'product_uos_qty': abs(line.qty),
+ 'product_qty': abs(line.qty),
+ 'tracking_id': False,
+ 'pos_line_id': line.id,
+ 'state': 'waiting',
+ 'location_id': location_id,
+ 'location_dest_id': stock_dest_id,
+ })
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
diff --git a/addons/project/project.py b/addons/project/project.py
index 765456ed964..4370d9e7183 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -362,7 +362,7 @@ class task(osv.osv):
'delegated_user_id': fields.related('child_ids','user_id',type='many2one', relation='res.users', string='Delegated To'),
'partner_id': fields.many2one('res.partner', 'Partner'),
'work_ids': fields.one2many('project.task.work', 'task_id', 'Work done'),
-# 'manager_id': fields.related('project_id','manager', type='many2one', relation='res.users', string='Project Manager'),
+ 'manager_id': fields.related('project_id','category_id','user_id', type='many2one', relation='res.users', string='Project Manager'),
'company_id': fields.many2one('res.company', 'Company'),
}
_defaults = {
diff --git a/addons/project/wizard/task_delegate.py b/addons/project/wizard/task_delegate.py
index 49f8ea4bcc7..35fe2019ea6 100644
--- a/addons/project/wizard/task_delegate.py
+++ b/addons/project/wizard/task_delegate.py
@@ -63,7 +63,7 @@ class wizard_delegate(wizard.interface):
'child_ids': [],
'work_ids': []
})
- task_obj.write(cr, uid, data['id'], {
+ task_obj.write(cr, uid, [data['id']], {
'remaining_hours': data['form']['planned_hours_me'],
'name': newname
})
diff --git a/addons/project_gtd/project_gtd.py b/addons/project_gtd/project_gtd.py
index 076b3ae4b9e..943ecc2c7d0 100644
--- a/addons/project_gtd/project_gtd.py
+++ b/addons/project_gtd/project_gtd.py
@@ -19,9 +19,6 @@
#
##############################################################################
-from xml import dom
-from lxml import etree
-
from mx import DateTime
from mx.DateTime import now
import time
@@ -31,6 +28,15 @@ from osv import fields, osv
import ir
from tools.translate import _
+import sys
+from tools.translate import _
+
+try:
+ from lxml import etree
+except ImportError:
+ sys.stderr.write("ERROR: Import lxml module\n")
+ sys.stderr.write("ERROR: Try to install the python-lxml package\n")
+
class project_gtd_context(osv.osv):
_name = "project.gtd.context"
_description = "Contexts"
diff --git a/addons/project_timesheet/project_timesheet.py b/addons/project_timesheet/project_timesheet.py
index d4ff62184bd..063d9937fd4 100644
--- a/addons/project_timesheet/project_timesheet.py
+++ b/addons/project_timesheet/project_timesheet.py
@@ -110,11 +110,13 @@ class project_work(osv.osv):
return super(project_work,self).write(cr, uid, ids, vals, context)
def unlink(self, cr, uid, ids, *args, **kwargs):
- timesheet_id = self.pool.get('project.task.work').browse(cr, uid, ids)[0].hr_analytic_timesheet_id
-# delete entry from timesheet too while deleting entry to task.
- list_avail_ids = self.pool.get('hr.analytic.timesheet').search(cr, uid, [])
- if timesheet_id in list_avail_ids:
- obj = self.pool.get('hr.analytic.timesheet').unlink(cr, uid, [timesheet_id], *args, **kwargs)
+ pool_analytic_timesheet = self.pool.get('hr.analytic.timesheet')
+ for work_id in ids:
+ timesheet_id = self.read(cr, uid, work_id, ['hr_analytic_timesheet_id'])['hr_analytic_timesheet_id']
+# delete entry from timesheet too while deleting entry to task.
+ list_avail_ids = pool_analytic_timesheet.search(cr, uid, [])
+ if timesheet_id in list_avail_ids:
+ obj = pool_analytic_timesheet.unlink(cr, uid, [timesheet_id], *args, **kwargs)
return super(project_work,self).unlink(cr, uid, ids, *args, **kwargs)
@@ -124,6 +126,40 @@ class project_work(osv.osv):
project_work()
+class task(osv.osv):
+ _inherit = "project.task"
+ _description = "Tasks"
+
+ def unlink(self, cr, uid, ids, *args, **kwargs):
+ for task_obj in self.browse(cr, uid, ids, *args, **kwargs):
+ if task_obj.work_ids:
+ work_ids = [x.id for x in task_obj.work_ids]
+ self.pool.get('project.task.work').unlink(cr, uid, work_ids, *args, **kwargs)
+
+ return super(task,self).unlink(cr, uid, ids, *args, **kwargs)
+
+ def write(self, cr, uid, ids,vals,context={}):
+ if (vals.has_key('project_id') and vals['project_id']) or (vals.has_key('name') and vals['name']):
+ vals_line = {}
+ hr_anlytic_timesheet = self.pool.get('hr.analytic.timesheet')
+ task_obj_l = self.browse(cr, uid, ids, context)
+ if (vals.has_key('project_id') and vals['project_id']):
+ project_obj = self.pool.get('project.project').browse(cr, uid, vals['project_id'])
+ acc_id = project_obj.category_id.id
+
+ for task_obj in task_obj_l:
+ if len(task_obj.work_ids):
+ for task_work in task_obj.work_ids:
+ line_id = task_work.hr_analytic_timesheet_id
+ if (vals.has_key('project_id') and vals['project_id']):
+ vals_line['account_id'] = acc_id
+ if (vals.has_key('name') and vals['name']):
+ vals_line['name'] = '%s: %s' % (tools.ustr(vals['name']), tools.ustr(task_work.name) or '/')
+ hr_anlytic_timesheet.write(cr, uid, [line_id], vals_line, {})
+ return super(task,self).write(cr, uid, ids, vals, context)
+
+task()
+
class project_project(osv.osv):
_inherit = "project.project"
def name_get(self, cr, user, ids, context=None):
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 6943dc2e03c..c7700a757c1 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -151,20 +151,17 @@ class purchase_order(osv.osv):
'partner_ref': fields.char('Supplier Reference', size=64),
'date_order':fields.date('Date Ordered', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, help="Date on which this document has been created."),
'date_approve':fields.date('Date Approved', readonly=1),
- 'partner_id':fields.many2one('res.partner', 'Supplier', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, change_default=True),
- 'partner_address_id':fields.many2one('res.partner.address', 'Supplier Address', required=True, states={'posted':[('readonly',True)]}),
-
+ 'partner_id':fields.many2one('res.partner', 'Supplier', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]}, change_default=True),
+ 'partner_address_id':fields.many2one('res.partner.address', 'Address', required=True, states={'posted':[('readonly',True)]}),
'dest_address_id':fields.many2one('res.partner.address', 'Destination Address', states={'posted':[('readonly',True)]},
help="Put an address if you want to deliver directly from the supplier to the customer." \
"In this case, it will remove the warehouse link and set the customer location."
),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', states={'posted':[('readonly',True)]}),
'location_id': fields.many2one('stock.location', 'Destination', required=True),
-
- 'pricelist_id':fields.many2one('product.pricelist', 'Pricelist', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, help="The pricelist sets the currency used for this purchase order. It also computes the supplier price for the selected products/quantities."),
-
+ 'pricelist_id':fields.many2one('product.pricelist', 'Pricelist', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]}, help="The pricelist sets the currency used for this purchase order. It also computes the supplier price for the selected products/quantities."),
'state': fields.selection([('draft', 'Request for Quotation'), ('wait', 'Waiting'), ('confirmed', 'Waiting Supplier Ack'), ('approved', 'Approved'),('except_picking', 'Shipping Exception'), ('except_invoice', 'Invoice Exception'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, help="The state of the purchase order or the quotation request. A quotation is a purchase order in a 'Draft' state. Then the order has to be confirmed by the user, the state switch to 'Confirmed'. Then the supplier must confirm the order to change the state to 'Approved'. When the purchase order is paid and received, the state becomes 'Done'. If a cancel action occurs in the invoice or in the reception of goods, the state becomes in exception.", select=True),
- 'order_line': fields.one2many('purchase.order.line', 'order_id', 'Order Lines', states={'approved':[('readonly',True)]}),
+ 'order_line': fields.one2many('purchase.order.line', 'order_id', 'Order Lines', states={'approved':[('readonly',True)],'done':[('readonly',True)]}),
'validator' : fields.many2one('res.users', 'Validated by', readonly=True),
'notes': fields.text('Notes', translate=True),
'invoice_id': fields.many2one('account.invoice', 'Invoice', readonly=True),
@@ -396,7 +393,7 @@ class purchase_order(osv.osv):
continue
if order_line.product_id.product_tmpl_id.type in ('product', 'consu'):
dest = order.location_id.id
- self.pool.get('stock.move').create(cr, uid, {
+ move = self.pool.get('stock.move').create(cr, uid, {
'name': 'PO:'+order_line.name,
'product_id': order_line.product_id.id,
'product_qty': order_line.product_qty,
@@ -408,12 +405,14 @@ class purchase_order(osv.osv):
'location_dest_id': dest,
'picking_id': picking_id,
'move_dest_id': order_line.move_dest_id.id,
- 'state': 'assigned',
+ 'state': 'draft',
'purchase_line_id': order_line.id,
'company_id': order.company_id.id,
})
if order_line.move_dest_id:
self.pool.get('stock.move').write(cr, uid, [order_line.move_dest_id.id], {'location_id':order.location_id.id})
+ self.pool.get('stock.move').action_confirm(cr, uid, [move])
+ self.pool.get('stock.move').force_assign(cr,uid, [move])
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
return picking_id
@@ -493,15 +492,6 @@ class purchase_order_line(osv.osv):
uom = prod_uom_po
if not date_order:
date_order = time.strftime('%Y-%m-%d')
- if price_unit:
- price = price_unit
- else:
- price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist],
- product, qty or 1.0, partner_id, {
- 'uom': uom,
- 'date': date_order,
- })[pricelist]
-
qty = qty or 1.0
seller_delay = 0
for s in prod.seller_ids:
@@ -510,7 +500,14 @@ class purchase_order_line(osv.osv):
temp_qty = s.qty # supplier _qty assigned to temp
if qty < temp_qty: # If the supplier quantity is greater than entered from user, set minimal.
qty = temp_qty
-
+ if price_unit:
+ price = price_unit
+ else:
+ price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist],
+ product, qty or 1.0, partner_id, {
+ 'uom': uom,
+ 'date': date_order,
+ })[pricelist]
dt = (DateTime.now() + DateTime.RelativeDateTime(days=seller_delay or 0.0)).strftime('%Y-%m-%d %H:%M:%S')
prod_name = self.pool.get('product.product').name_get(cr, uid, [prod.id])[0][1]
diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml
index 01f2ff22e84..9480f3327c3 100644
--- a/addons/purchase/purchase_view.xml
+++ b/addons/purchase/purchase_view.xml
@@ -245,6 +245,7 @@
tree
+
diff --git a/addons/purchase/security/ir.model.access.csv b/addons/purchase/security/ir.model.access.csv
index 68be681fdf5..5fb968e6ce1 100644
--- a/addons/purchase/security/ir.model.access.csv
+++ b/addons/purchase/security/ir.model.access.csv
@@ -7,3 +7,4 @@
"access_stock_move_purchase_user","stock.move purchase_user","stock.model_stock_move","purchase.group_purchase_user",1,1,1,1
"access_purchase_order_stock_worker","purchase.order stock_worker","model_purchase_order","stock.group_stock_user",1,0,0,0
"access_purchase_order_line_stock_worker","purchase.order.line stock_worker","model_purchase_order_line","stock.group_stock_user",1,0,0,0
+"access_account_tax_purchase_user","account.tax purchase_user","account.model_account_tax","purchase.group_purchase_user",1,0,0,0
\ No newline at end of file
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 8643b0775b9..5f6e0db3448 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -148,7 +148,7 @@ class sale_order(osv.osv):
res[sale.id] = False
return res
- def _invoiced_search(self, cursor, user, obj, name, args):
+ def _invoiced_search(self, cursor, user, obj, name, args, context):
if not len(args):
return []
clause = ''
@@ -453,7 +453,23 @@ class sale_order(osv.osv):
self.pool.get('sale.order.line').write(cr, uid, [line.id], {'invoiced': invoiced})
self.write(cr, uid, ids, {'state': 'invoice_except', 'invoice_ids': False})
return True
-
+
+ def action_invoice_end(self, cr, uid, ids, context={}):
+ for order in self.browse(cr, uid, ids):
+ val = {'invoiced': True}
+ if order.state == 'invoice_except':
+ val['state'] = 'progress'
+
+ for line in order.order_line:
+ towrite = []
+ if line.state == 'exception':
+ towrite.append(line.id)
+ if towrite:
+ self.pool.get('sale.order.line').write(cr, uid, towrite, {'state': 'confirmed'}, context=context)
+ self.write(cr, uid, [order.id], val)
+
+ return True
+
def action_cancel(self, cr, uid, ids, context={}):
ok = True
sale_order_line_obj = self.pool.get('sale.order.line')
@@ -517,25 +533,9 @@ class sale_order(osv.osv):
notcanceled = False
write_done_ids = []
write_cancel_ids = []
- stock_move_obj = self.pool.get('stock.move')
for order in self.browse(cr, uid, ids, context={}):
-
- #check for pending deliveries
- pending_deliveries = False
- # check => if order_lines do not exist,don't proceed for any mode.
- if not order.order_line:
- return False
for line in order.order_line:
- move_ids = stock_move_obj.search(cr, uid, [('sale_line_id','=', line.id)])
- for move in stock_move_obj.browse( cr, uid, move_ids ):
- #if one of the related order lines is in state draft, auto or confirmed
- #this order line is not yet delivered
- if move.state in ('draft', 'waiting', 'confirmed'):
- pending_deliveries = True
- # Reason => if there are no move lines,the following condition will always set to be true,and will set SO to 'DONE'.
- # Added move_ids check to SOLVE.
- if move_ids and ((not line.procurement_id) or (line.procurement_id.state=='done')) and not pending_deliveries:
-# finished = True
+ if (not line.procurement_id) or (line.procurement_id.state=='done'):
if line.state != 'done':
write_done_ids.append(line.id)
else:
diff --git a/addons/sale/sale_workflow.xml b/addons/sale/sale_workflow.xml
index 15b6f359175..6a7e7b6a8ee 100644
--- a/addons/sale/sale_workflow.xml
+++ b/addons/sale/sale_workflow.xml
@@ -75,7 +75,8 @@
invoice_end
- dummy
+ function
+ action_invoice_end()
diff --git a/addons/sale_crm/wizard/makesale.py b/addons/sale_crm/wizard/makesale.py
index fc2a27d479a..c5ad6a92a72 100644
--- a/addons/sale_crm/wizard/makesale.py
+++ b/addons/sale_crm/wizard/makesale.py
@@ -120,7 +120,7 @@ class make_sale(wizard.interface):
value['tax_id'] = [(6,0,value['tax_id'])]
sale_line_obj.create(cr, uid, value)
- case_obj.write(cr, uid, case.id, {'ref': 'sale.order,%s' % new_id})
+ case_obj.write(cr, uid, [case.id], {'ref': 'sale.order,%s' % new_id})
new_ids.append(new_id)
if data['form']['close']:
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 04a044077ac..1ea6aa998b2 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -533,8 +533,8 @@ class stock_picking(osv.osv):
def force_assign(self, cr, uid, ids, *args):
wf_service = netsvc.LocalService("workflow")
for pick in self.browse(cr, uid, ids):
-# move_ids = [x.id for x in pick.move_lines if x.state == 'confirmed']
- move_ids = [x.id for x in pick.move_lines]
+ move_ids = [x.id for x in pick.move_lines if x.state in ['confirmed','waiting']]
+# move_ids = [x.id for x in pick.move_lines]
self.pool.get('stock.move').force_assign(cr, uid, move_ids)
wf_service.trg_write(uid, 'stock.picking', pick.id, cr)
return True
@@ -770,7 +770,7 @@ class stock_picking(osv.osv):
tax_ids = self._get_taxes_invoice(cursor, user, move_line, type)
account_analytic_id = self._get_account_analytic_invoice(cursor,
user, picking, move_line)
-
+
#set UoS if it's a sale and the picking doesn't have one
uos_id = move_line.product_uos and move_line.product_uos.id or False
if not uos_id and type in ('out_invoice', 'out_refund'):
@@ -819,6 +819,18 @@ class stock_picking(osv.osv):
return False
return True
+ def unlink(self, cr, uid, ids, context=None):
+ for pick in self.browse(cr, uid, ids, context=context):
+ if pick.state in ['done','cancel']:
+ raise osv.except_osv(_('Error'), _('You cannot remove the picking which is in %s state !')%(pick.state,))
+ elif pick.state in ['confirmed','assigned']:
+ ids2 = [move.id for move in pick.move_lines]
+ context.update({'call_unlink':True})
+ self.pool.get('stock.move').action_cancel(cr, uid, ids2, context)
+ else:
+ continue
+ return super(stock_picking, self).unlink(cr, uid, ids, context=context)
+
stock_picking()
@@ -864,7 +876,7 @@ class stock_production_lot(osv.osv):
res.update(dict(cr.fetchall()))
return res
- def _stock_search(self, cr, uid, obj, name, args):
+ def _stock_search(self, cr, uid, obj, name, args, context):
locations = self.pool.get('stock.location').search(cr, uid, [('usage', '=', 'internal')])
cr.execute('''select
prodlot_id,
@@ -1016,8 +1028,8 @@ class stock_move(osv.osv):
( \
(move.product_id.track_production and move.location_id.usage=='production') or \
(move.product_id.track_production and move.location_dest_id.usage=='production') or \
- (move.product_id.track_incoming and move.location_id.usage=='supplier') or \
- (move.product_id.track_outgoing and move.location_dest_id.usage=='customer') \
+ (move.product_id.track_incoming and move.location_id.usage in ('supplier','internal')) or \
+ (move.product_id.track_outgoing and move.location_dest_id.usage in ('customer','internal')) \
)):
return False
return True
@@ -1149,25 +1161,25 @@ class stock_move(osv.osv):
'message': 'You are moving %.2f products but only %.2f available in this lot.' % (product_qty, prodlot.stock_available or 0.0)
}
return {'warning': warning}
-
+
def onchange_quantity(self, cr, uid, ids, product_id, product_qty, product_uom, product_uos):
result = {
'product_uos_qty': 0.00
}
-
+
if (not product_id) or (product_qty <=0.0):
return {'value': result}
-
+
product_obj = self.pool.get('product.product')
uos_coeff = product_obj.read(cr, uid, product_id, ['uos_coeff'])
-
+
if product_uos and product_uom and (product_uom != product_uos):
result['product_uos_qty'] = product_qty * uos_coeff['uos_coeff']
else:
result['product_uos_qty'] = product_qty
-
+
return {'value': result}
-
+
def onchange_product_id(self, cr, uid, ids, prod_id=False, loc_id=False, loc_dest_id=False):
if not prod_id:
return {}
@@ -1180,7 +1192,7 @@ class stock_move(osv.osv):
'product_qty': 1.00,
'product_uos_qty' : self.pool.get('stock.move').onchange_quantity(cr, uid, ids, prod_id, 1.00, product.uom_id.id, uos_id)['value']['product_uos_qty']
}
-
+
if loc_id:
result['location_id'] = loc_id
if loc_dest_id:
@@ -1323,14 +1335,14 @@ class stock_move(osv.osv):
pickings[move.picking_id.id] = True
if move.move_dest_id and move.move_dest_id.state == 'waiting':
self.write(cr, uid, [move.move_dest_id.id], {'state': 'assigned'})
- if move.move_dest_id.picking_id:
+ if context.get('call_unlink',False) and move.move_dest_id.picking_id:
wf_service = netsvc.LocalService("workflow")
wf_service.trg_write(uid, 'stock.picking', move.move_dest_id.picking_id.id, cr)
self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False})
-
- for pick in self.pool.get('stock.picking').browse(cr, uid, pickings.keys()):
- if all(move.state == 'cancel' for move in pick.move_lines):
- self.pool.get('stock.picking').write(cr, uid, [pick.id], {'state': 'cancel'})
+ if not context.get('call_unlink',False):
+ for pick in self.pool.get('stock.picking').browse(cr, uid, pickings.keys()):
+ if all(move.state == 'cancel' for move in pick.move_lines):
+ self.pool.get('stock.picking').write(cr, uid, [pick.id], {'state': 'cancel'})
wf_service = netsvc.LocalService("workflow")
for id in ids:
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 0d0de9525b4..9d0c9016e05 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -259,7 +259,7 @@
-
+
@@ -281,7 +281,7 @@
-
+
diff --git a/addons/stock/wizard/wizard_partial_picking.py b/addons/stock/wizard/wizard_partial_picking.py
index be5226956fc..d9a40cc8690 100644
--- a/addons/stock/wizard/wizard_partial_picking.py
+++ b/addons/stock/wizard/wizard_partial_picking.py
@@ -58,6 +58,8 @@ def _get_moves(self, cr, uid, data, context):
_moves_arch_lst = ['', '