summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Delavallée <tde@openerp.com>2012-11-28 16:52:46 +0100
committerThibault Delavallée <tde@openerp.com>2012-11-28 16:52:46 +0100
commitb4e8416486b32b6e5e6d15c36e5652db9abece49 (patch)
tree5e719d215c6b29bead24ed5bd9ea2e0fa592c24b
parent3bc0186a4ce999c504b440dbef35751f67e2c802 (diff)
parent74657199b0a8ee832ecf1b66a53b584729b58f62 (diff)
[MERGE] Sync with trunk.
bzr revid: tde@openerp.com-20121128155246-33vcdcysd47uk4k5
-rw-r--r--addons/account/account.py61
-rw-r--r--addons/account/account_bank_statement.py2
-rw-r--r--addons/account/account_invoice.py12
-rw-r--r--addons/account/account_move_line.py26
-rw-r--r--addons/account/wizard/account_fiscalyear_close.py4
-rw-r--r--addons/account_analytic_analysis/account_analytic_analysis.py20
-rw-r--r--addons/account_payment/account_invoice.py19
-rw-r--r--addons/account_voucher/account_voucher.py9
-rw-r--r--addons/account_voucher/test/case5_suppl_usd_usd.yml8
-rw-r--r--addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py52
-rw-r--r--addons/auth_oauth/static/src/js/auth_oauth.js3
-rw-r--r--addons/auth_reset_password/res_users.py3
-rw-r--r--addons/auth_reset_password/res_users_view.xml8
-rw-r--r--addons/auth_signup/res_users.py8
-rw-r--r--addons/base_calendar/crm_meeting_view.xml4
-rw-r--r--addons/crm/crm_lead_view.xml4
-rw-r--r--addons/crm/crm_phonecall_view.xml4
-rw-r--r--addons/event/event_view.xml8
-rw-r--r--addons/fleet/fleet_view.xml7
-rw-r--r--addons/hr_holidays/hr_holidays_view.xml4
-rw-r--r--addons/hr_recruitment/__openerp__.py1
-rw-r--r--addons/hr_recruitment/hr_recruitment_view.xml8
-rw-r--r--addons/hr_recruitment/static/src/js/hr_recruitment.js35
-rw-r--r--addons/hr_timesheet_invoice/hr_timesheet_invoice.py140
-rw-r--r--addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py158
-rw-r--r--addons/membership/membership.py6
-rw-r--r--addons/point_of_sale/static/src/js/db.js6
-rw-r--r--addons/portal_project_issue/portal_project_issue_view.xml7
-rw-r--r--addons/project/project_view.xml14
-rw-r--r--addons/project/static/src/js/project.js29
-rw-r--r--addons/project_issue/__openerp__.py1
-rw-r--r--addons/project_issue/project_issue_view.xml8
-rw-r--r--addons/project_issue/static/src/js/project_issue.js13
-rw-r--r--addons/purchase/purchase_view.xml4
-rw-r--r--addons/purchase/report/request_quotation.rml5
-rw-r--r--addons/sale/sale_view.xml4
36 files changed, 350 insertions, 355 deletions
diff --git a/addons/account/account.py b/addons/account/account.py
index cfba30856a9..15881100441 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -641,8 +641,7 @@ class account_account(osv.osv):
return True
def _check_allow_type_change(self, cr, uid, ids, new_type, context=None):
- group1 = ['payable', 'receivable', 'other']
- group2 = ['consolidation','view']
+ restricted_groups = ['consolidation','view']
line_obj = self.pool.get('account.move.line')
for account in self.browse(cr, uid, ids, context=context):
old_type = account.type
@@ -650,14 +649,25 @@ class account_account(osv.osv):
if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
#Check for 'Closed' type
if old_type == 'closed' and new_type !='closed':
- raise osv.except_osv(_('Warning!'), _("You cannot change the type of account from 'Closed' to any other type which contains journal items!"))
- #Check for change From group1 to group2 and vice versa
- if (old_type in group1 and new_type in group2) or (old_type in group2 and new_type in group1):
- raise osv.except_osv(_('Warning!'), _("You cannot change the type of account from '%s' to '%s' type as it contains journal items!") % (old_type,new_type,))
+ raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from 'Closed' to any other type as it contains journal items!"))
+ # Forbid to change an account type for restricted_groups as it contains journal items (or if one of its children does)
+ if (new_type in restricted_groups):
+ raise osv.except_osv(_('Warning !'), _("You cannot change the type of account to '%s' type as it contains journal items!") % (new_type,))
+
return True
- def write(self, cr, uid, ids, vals, context=None):
+ # For legal reason (forbiden to modify journal entries which belongs to a closed fy or period), Forbid to modify
+ # the code of an account if journal entries have been already posted on this account. This cannot be simply
+ # 'configurable' since it can lead to a lack of confidence in OpenERP and this is what we want to change.
+ def _check_allow_code_change(self, cr, uid, ids, context=None):
+ line_obj = self.pool.get('account.move.line')
+ for account in self.browse(cr, uid, ids, context=context):
+ account_ids = self.search(cr, uid, [('id', 'child_of', [account.id])], context=context)
+ if line_obj.search(cr, uid, [('account_id', 'in', account_ids)], context=context):
+ raise osv.except_osv(_('Warning !'), _("You cannot change the code of account which contains journal items!"))
+ return True
+ def write(self, cr, uid, ids, vals, context=None):
if context is None:
context = {}
if not ids:
@@ -677,6 +687,8 @@ class account_account(osv.osv):
self._check_moves(cr, uid, ids, "write", context=context)
if 'type' in vals.keys():
self._check_allow_type_change(cr, uid, ids, vals['type'], context=context)
+ if 'code' in vals.keys():
+ self._check_allow_code_change(cr, uid, ids, context=context)
return super(account_account, self).write(cr, uid, ids, vals, context=context)
def unlink(self, cr, uid, ids, context=None):
@@ -1470,6 +1482,11 @@ class account_move(osv.osv):
raise osv.except_osv(_('User Error!'),
_('You cannot delete a posted journal entry "%s".') % \
move['name'])
+ for line in move.line_id:
+ if line.invoice:
+ raise osv.except_osv(_('User Error!'),
+ _("Move cannot be deleted if linked to an invoice. (Invoice: %s - Move ID:%s)") % \
+ (line.invoice.number,move.name))
line_ids = map(lambda x: x.id, move.line_id)
context['journal_id'] = move.journal_id.id
context['period_id'] = move.period_id.id
@@ -1678,11 +1695,41 @@ class account_move_reconcile(osv.osv):
'line_id': fields.one2many('account.move.line', 'reconcile_id', 'Entry Lines'),
'line_partial_ids': fields.one2many('account.move.line', 'reconcile_partial_id', 'Partial Entry lines'),
'create_date': fields.date('Creation date', readonly=True),
+ 'opening_reconciliation': fields.boolean('Opening Entries Reconciliation', help="Is this reconciliation produced by the opening of a new fiscal year ?."),
}
_defaults = {
'name': lambda self,cr,uid,ctx=None: self.pool.get('ir.sequence').get(cr, uid, 'account.reconcile', context=ctx) or '/',
}
+
+ # You cannot unlink a reconciliation if it is a opening_reconciliation one,
+ # you should use the generate opening entries wizard for that
+ def unlink(self, cr, uid, ids, context=None):
+ for move_rec in self.browse(cr, uid, ids, context=context):
+ if move_rec.opening_reconciliation:
+ raise osv.except_osv(_('Error!'), _('You cannot unreconcile journal items if they has been generated by the \
+ opening/closing fiscal year process.'))
+ return super(account_move_reconcile, self).unlink(cr, uid, ids, context=context)
+
+ # Look in the line_id and line_partial_ids to ensure the partner is the same or empty
+ # on all lines. We allow that only for opening/closing period
+ def _check_same_partner(self, cr, uid, ids, context=None):
+ for reconcile in self.browse(cr, uid, ids, context=context):
+ move_lines = []
+ if not reconcile.opening_reconciliation:
+ if reconcile.line_id:
+ first_partner = reconcile.line_id[0].partner_id.id
+ move_lines = reconcile.line_id
+ elif reconcile.line_partial_ids:
+ first_partner = reconcile.line_partial_ids[0].partner_id.id
+ move_lines = reconcile.line_partial_ids
+ if any([line.partner_id.id != first_partner for line in move_lines]):
+ return False
+ return True
+ _constraints = [
+ (_check_same_partner, 'You can only reconcile journal items with the same partner.', ['line_id']),
+ ]
+
def reconcile_partial_check(self, cr, uid, ids, type='auto', context=None):
total = 0.0
for rec in self.browse(cr, uid, ids, context=context):
diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py
index 4422537007f..e7e3f740067 100644
--- a/addons/account/account_bank_statement.py
+++ b/addons/account/account_bank_statement.py
@@ -311,7 +311,7 @@ class account_bank_statement(osv.osv):
'statement_id': st_line.statement_id.id,
'journal_id': st_line.statement_id.journal_id.id,
'period_id': st_line.statement_id.period_id.id,
- 'currency_id': cur_id,
+ 'currency_id': amount_currency and cur_id,
'amount_currency': amount_currency,
'analytic_account_id': analytic_id,
}
diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py
index 80a406bb0b7..6804d5116f1 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -1073,8 +1073,9 @@ class account_invoice(osv.osv):
self.message_post(cr, uid, [inv_id], body=message, context=context)
return True
- def action_cancel(self, cr, uid, ids, *args):
- context = {} # TODO: Use context from arguments
+ def action_cancel(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
account_move_obj = self.pool.get('account.move')
invoices = self.read(cr, uid, ids, ['move_id', 'payment_ids'])
move_ids = [] # ones that we will need to remove
@@ -1244,12 +1245,15 @@ class account_invoice(osv.osv):
ref = invoice.reference
else:
ref = self._convert_ref(cr, uid, invoice.number)
+ partner = invoice.partner_id
+ if partner.parent_id and not partner.is_company:
+ partner = partner.parent_id
# 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,
+ 'partner_id': partner.id,
'ref':ref,
'date': date,
'currency_id':currency_id,
@@ -1260,7 +1264,7 @@ class account_invoice(osv.osv):
'debit': direction * pay_amount<0 and - direction * pay_amount,
'credit': direction * pay_amount>0 and direction * pay_amount,
'account_id': pay_account_id,
- 'partner_id': invoice.partner_id.id,
+ 'partner_id': partner.id,
'ref':ref,
'date': date,
'currency_id':currency_id,
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index 00fad390282..3b2fe21d95b 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -620,12 +620,34 @@ class account_move_line(osv.osv):
return False
return True
+ def _check_currency_and_amount(self, cr, uid, ids, context=None):
+ for l in self.browse(cr, uid, ids, context=context):
+ if (l.amount_currency and not l.currency_id):
+ return False
+ return True
+
+ def _check_currency_amount(self, cr, uid, ids, context=None):
+ for l in self.browse(cr, uid, ids, context=context):
+ if l.amount_currency:
+ if (l.amount_currency > 0.0 and l.credit > 0.0) or (l.amount_currency < 0.0 and l.debit > 0.0):
+ return False
+ return True
+
+ def _check_currency_company(self, cr, uid, ids, context=None):
+ for l in self.browse(cr, uid, ids, context=context):
+ if l.currency_id.id == l.company_id.currency_id.id:
+ return False
+ return True
+
_constraints = [
(_check_no_view, 'You cannot create journal items on an account of type view.', ['account_id']),
(_check_no_closed, 'You cannot create journal items on closed account.', ['account_id']),
(_check_company_id, 'Account and Period must belong to the same company.', ['company_id']),
(_check_date, 'The date of your Journal Entry is not in the defined period! You should change the date or remove this constraint from the journal.', ['date']),
(_check_currency, 'The selected account of your Journal Entry forces to provide a secondary currency. You should remove the secondary currency on the account or select a multi-currency view on the journal.', ['currency_id']),
+ (_check_currency_and_amount, "You cannot create journal items with a secondary currency without recording both 'currency' and 'amount currency' field.", ['currency_id','amount_currency']),
+ (_check_currency_amount, 'The amount expressed in the secondary currency must be positif when journal item are debit and negatif when journal item are credit.', ['amount_currency']),
+ (_check_currency_company, "You cannot provide a secondary currency if it is the same than the company one." , ['currency_id']),
]
#TODO: ONCHANGE_ACCOUNT_ID: set account_tax_id
@@ -1111,7 +1133,7 @@ class account_move_line(osv.osv):
'has been confirmed.') % res[2])
return res
- def _remove_move_reconcile(self, cr, uid, move_ids=None, context=None):
+ def _remove_move_reconcile(self, cr, uid, move_ids=None, opening_reconciliation=False, context=None):
# Function remove move rencocile ids related with moves
obj_move_line = self.pool.get('account.move.line')
obj_move_rec = self.pool.get('account.move.reconcile')
@@ -1126,6 +1148,8 @@ class account_move_line(osv.osv):
unlink_ids += rec_ids
unlink_ids += part_rec_ids
if unlink_ids:
+ if opening_reconciliation:
+ obj_move_rec.write(cr, uid, unlink_ids, {'opening_reconciliation': False})
obj_move_rec.unlink(cr, uid, unlink_ids)
return True
diff --git a/addons/account/wizard/account_fiscalyear_close.py b/addons/account/wizard/account_fiscalyear_close.py
index dbf815d5218..e11b4dcd34b 100644
--- a/addons/account/wizard/account_fiscalyear_close.py
+++ b/addons/account/wizard/account_fiscalyear_close.py
@@ -60,7 +60,7 @@ class account_fiscalyear_close(osv.osv_memory):
cr.execute('select distinct(company_id) from account_move_line where id in %s',(tuple(ids),))
if len(cr.fetchall()) > 1:
raise osv.except_osv(_('Warning!'), _('The entries to reconcile should belong to the same company.'))
- r_id = self.pool.get('account.move.reconcile').create(cr, uid, {'type': 'auto'})
+ r_id = self.pool.get('account.move.reconcile').create(cr, uid, {'type': 'auto', 'opening_reconciliation': True})
cr.execute('update account_move_line set reconcile_id = %s where id in %s',(r_id, tuple(ids),))
return r_id
@@ -107,7 +107,7 @@ class account_fiscalyear_close(osv.osv_memory):
('journal_id', '=', new_journal.id), ('period_id', '=', period.id)])
if move_ids:
move_line_ids = obj_acc_move_line.search(cr, uid, [('move_id', 'in', move_ids)])
- obj_acc_move_line._remove_move_reconcile(cr, uid, move_line_ids, context=context)
+ obj_acc_move_line._remove_move_reconcile(cr, uid, move_line_ids, opening_reconciliation=True, context=context)
obj_acc_move_line.unlink(cr, uid, move_line_ids, context=context)
obj_acc_move.unlink(cr, uid, move_ids, context=context)
diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py
index 06e2fd2bb18..466db63e61e 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis.py
+++ b/addons/account_analytic_analysis/account_analytic_analysis.py
@@ -75,15 +75,21 @@ class account_analytic_account(osv.osv):
res[id][f] = 0.0
res2 = {}
for account in accounts:
- cr.execute("SELECT product_id, user_id, to_invoice, sum(unit_amount), product_uom_id, name " \
- "FROM account_analytic_line as line " \
- "WHERE account_id = %s " \
- "AND invoice_id is NULL AND to_invoice IS NOT NULL " \
- "GROUP BY product_id, user_id, to_invoice, product_uom_id, name", (account.id,))
+ cr.execute("""
+ SELECT product_id, sum(amount), user_id, to_invoice, sum(unit_amount), product_uom_id, line.name
+ FROM account_analytic_line line
+ LEFT JOIN account_analytic_journal journal ON (journal.id = line.journal_id)
+ WHERE account_id = %s
+ AND journal.type != 'purchase'
+ AND invoice_id IS NULL
+ AND to_invoice IS NOT NULL
+ GROUP BY product_id, user_id, to_invoice, product_uom_id, line.name""", (account.id,))
res[account.id][f] = 0.0
- for product_id, user_id, factor_id, qty, uom, line_name in cr.fetchall():
- price = self.pool.get('account.analytic.line')._get_invoice_price(cr, uid, account, product_id, user_id, qty, context)
+ for product_id, price, user_id, factor_id, qty, uom, line_name in cr.fetchall():
+ price = -price
+ if product_id:
+ price = self.pool.get('account.analytic.line')._get_invoice_price(cr, uid, account, product_id, user_id, qty, context)
factor = self.pool.get('hr_timesheet_invoice.factor').browse(cr, uid, factor_id, context=context)
res[account.id][f] += price * qty * (100-factor.factor or 0.0) / 100.0
diff --git a/addons/account_payment/account_invoice.py b/addons/account_payment/account_invoice.py
index 7138540fa3b..ec4feca9b81 100644
--- a/addons/account_payment/account_invoice.py
+++ b/addons/account_payment/account_invoice.py
@@ -20,12 +20,29 @@
##############################################################################
from datetime import datetime
-
+from tools.translate import _
from osv import fields, osv
class Invoice(osv.osv):
_inherit = 'account.invoice'
+ # Forbid to cancel an invoice if the related move lines have already been
+ # used in a payment order. The risk is that importing the payment line
+ # in the bank statement will result in a crash cause no more move will
+ # be found in the payment line
+ def action_cancel(self, cr, uid, ids, context=None):
+ payment_line_obj = self.pool.get('payment.line')
+ for inv in self.browse(cr, uid, ids, context=context):
+ pl_line_ids = []
+ if inv.move_id and inv.move_id.line_id:
+ inv_mv_lines = [x.id for x in inv.move_id.line_id]
+ pl_line_ids = payment_line_obj.search(cr, uid, [('move_line_id','in',inv_mv_lines)], context=context)
+ if pl_line_ids:
+ pay_line = payment_line_obj.browse(cr, uid, pl_line_ids, context=context)
+ payment_order_name = ','.join(map(lambda x: x.order_id.reference, pay_line))
+ raise osv.except_osv(_('Error!'), _("You cannot cancel an invoice which has already been imported in a payment order. Remove it from the following payment order : %s."%(payment_order_name)))
+ return super(Invoice, self).action_cancel(cr, uid, ids, context=context)
+
def _amount_to_pay(self, cursor, user, ids, name, args, context=None):
'''Return the amount still to pay regarding all the payment orders'''
if not ids:
diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py
index 32be8c34929..ffc7cf1769d 100644
--- a/addons/account_voucher/account_voucher.py
+++ b/addons/account_voucher/account_voucher.py
@@ -1549,6 +1549,15 @@ class account_bank_statement(osv.osv):
return move_line_obj.write(cr, uid, [x.id for x in v.move_ids], {'statement_id': st_line.statement_id.id}, context=context)
return super(account_bank_statement, self).create_move_from_st_line(cr, uid, st_line.id, company_currency_id, next_number, context=context)
+ def write(self, cr, uid, ids, vals, context=None):
+ # Restrict to modify the journal if we already have some voucher of reconciliation created/generated.
+ # Because the voucher keeps in memory the journal it was created with.
+ for bk_st in self.browse(cr, uid, ids, context=context):
+ if vals.get('journal_id') and bk_st.line_ids:
+ if any([x.voucher_id and True or False for x in bk_st.line_ids]):
+ raise osv.except_osv(_('Unable to change journal !'), _('You can not change the journal as you already reconciled some statement lines!'))
+ return super(account_bank_statement, self).write(cr, uid, ids, vals, context=context)
+
account_bank_statement()
class account_bank_statement_line(osv.osv):
diff --git a/addons/account_voucher/test/case5_suppl_usd_usd.yml b/addons/account_voucher/test/case5_suppl_usd_usd.yml
index 3cae9667d84..4caeb19c847 100644
--- a/addons/account_voucher/test/case5_suppl_usd_usd.yml
+++ b/addons/account_voucher/test/case5_suppl_usd_usd.yml
@@ -4,10 +4,10 @@
-
I create a cash account with currency USD
-
- !record {model: account.account, id: account_cash_usd_id}:
+ !record {model: account.account, id: account_cash_usd_id2}:
currency_id: base.USD
name: "cash account in usd"
- code: "Xcash usd"
+ code: "Xcash usd2"
type: 'liquidity'
user_type: "account.data_account_type_cash"
@@ -56,8 +56,8 @@
type: bank
analytic_journal_id: account.sit
sequence_id: account.sequence_bank_journal
- default_debit_account_id: account_cash_usd_id
- default_credit_account_id: account_cash_usd_id
+ default_debit_account_id: account_cash_usd_id2
+ default_credit_account_id: account_cash_usd_id2
currency: base.USD
company_id: base.main_company
view_id: account.account_journal_bank_view
diff --git a/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py b/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py
index 35177ee3a66..ee92b469744 100644
--- a/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py
+++ b/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py
@@ -65,39 +65,25 @@ class account_analytic_account(osv.osv):
def _expense_to_invoice_calc(self, cr, uid, ids, name, arg, context=None):
res = {}
- res_final = {}
- child_ids = tuple(ids) #We don't want consolidation for each of these fields because those complex computation is resource-greedy.
- for i in child_ids:
- res[i] = 0.0
- if not child_ids:
- return res
-
- if child_ids:
- cr.execute("""SELECT account_analytic_account.id, \
- COALESCE(SUM (product_template.list_price * \
- account_analytic_line.unit_amount * \
- ((100-hr_timesheet_invoice_factor.factor)/100)), 0.0) \
- AS ca_to_invoice \
- FROM product_template \
- JOIN product_product \
- ON product_template.id = product_product.product_tmpl_id \
- JOIN account_analytic_line \
- ON account_analytic_line.product_id = product_product.id \
- JOIN account_analytic_journal \
- ON account_analytic_line.journal_id = account_analytic_journal.id \
- JOIN account_analytic_account \
- ON account_analytic_account.id = account_analytic_line.account_id \
- JOIN hr_timesheet_invoice_factor \
- ON hr_timesheet_invoice_factor.id = account_analytic_account.to_invoice \
- WHERE account_analytic_account.id IN %s \
- AND account_analytic_line.invoice_id IS NULL \
- AND account_analytic_line.to_invoice IS NOT NULL \
- AND account_analytic_journal.type = 'purchase' \
- GROUP BY account_analytic_account.id;""",(child_ids,))
- for account_id, sum in cr.fetchall():
- res[account_id] = sum
- res_final = res
- return res_final
+ #We don't want consolidation for each of these fields because those complex computation is resource-greedy.
+ for account in self.pool.get('account.analytic.account').browse(cr, uid, ids, context=context):
+ cr.execute("""
+ SELECT product_id, sum(amount), user_id, to_invoice, sum(unit_amount), product_uom_id, line.name
+ FROM account_analytic_line line
+ LEFT JOIN account_analytic_journal journal ON (journal.id = line.journal_id)
+ WHERE account_id = %s
+ AND journal.type = 'purchase'
+ AND invoice_id IS NULL
+ AND to_invoice IS NOT NULL
+ GROUP BY product_id, user_id, to_invoice, product_uom_id, line.name""", (account.id,))
+
+ res[account.id] = 0.0
+ for product_id, price, user_id, factor_id, qty, uom, line_name in cr.fetchall():
+ #the amount to reinvoice is the real cost. We don't use the pricelist
+ price = -price
+ factor = self.pool.get('hr_timesheet_invoice.factor').browse(cr, uid, factor_id, context=context)
+ res[account.id] += price * qty * (100 - factor.factor or 0.0) / 100.0
+ return res
def _expense_invoiced_calc(self, cr, uid, ids, name, arg, context=None):
lines_obj = self.pool.get('account.analytic.line')
diff --git a/addons/auth_oauth/static/src/js/auth_oauth.js b/addons/auth_oauth/static/src/js/auth_oauth.js
index fdf7baf607c..c24dab3d55a 100644
--- a/addons/auth_oauth/static/src/js/auth_oauth.js
+++ b/addons/auth_oauth/static/src/js/auth_oauth.js
@@ -36,6 +36,9 @@ openerp.auth_oauth = function(instance) {
ev.preventDefault();
var index = $(ev.target).data('index');
var provider = this.oauth_providers[index];
+ return this.do_oauth_sign_in(provider);
+ },
+ do_oauth_sign_in: function(provider) {
var return_url = _.str.sprintf('%s//%s/auth_oauth/signin', location.protocol, location.host);
if (instance.session.debug) {
return_url += '?debug';
diff --git a/addons/auth_reset_password/res_users.py b/addons/auth_reset_password/res_users.py
index b1039031812..cfac20c76f9 100644
--- a/addons/auth_reset_password/res_users.py
+++ b/addons/auth_reset_password/res_users.py
@@ -21,6 +21,7 @@
from openerp.osv import osv, fields
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
+from openerp.tools.translate import _
from datetime import datetime, timedelta
@@ -54,6 +55,8 @@ class res_users(osv.osv):
template = self.pool.get('ir.model.data').get_object(cr, uid, 'auth_reset_password', 'reset_password_email')
assert template._name == 'email.template'
for user in self.browse(cr, uid, ids, context):
+ if not user.email:
+ raise osv.except_osv(_("Cannot send email: user has no email address."), user.name)
self.pool.get('email.template').send_mail(cr, uid, template.id, user.id, context=context)
return True
diff --git a/addons/auth_reset_password/res_users_view.xml b/addons/auth_reset_password/res_users_view.xml
index 9952162ae65..628e95b6ff9 100644
--- a/addons/auth_reset_password/res_users_view.xml
+++ b/addons/auth_reset_password/res_users_view.xml
@@ -7,11 +7,17 @@
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form"/>
<field name="arch" type="xml">
+ <!-- Reset Password button -->
<xpath expr="//sheet/*[1]" position="before">
<div class="oe_right oe_button_box">
- <button string="Reset Password" type="object" name="action_reset_password"/>
+ <button string="Reset Password" type="object" name="action_reset_password"
+ help="Send a special url by email to make the user (re)set their password."/>
</div>
</xpath>
+ <!-- password is never required; one can use Reset Password -->
+ <field name="new_password" position="attributes">
+ <attribute name="attrs">{}</attribute>
+ </field>
</field>
</record>
diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py
index 69ec45b80e5..7dbb19853a2 100644
--- a/addons/auth_signup/res_users.py
+++ b/addons/auth_signup/res_users.py
@@ -150,8 +150,12 @@ class res_users(osv.Model):
_inherit = 'res.users'
def _get_state(self, cr, uid, ids, name, arg, context=None):
- return dict((user.id, 'new' if not user.login_date else 'reset' if user.signup_token else 'active')
- for user in self.browse(cr, uid, ids, context))
+ res = {}
+ for user in self.browse(cr, uid, ids, context):
+ res[user.id] = ('reset' if user.signup_valid else
+ 'active' if user.login_date else
+ 'new')
+ return res
_columns = {
'state': fields.function(_get_state, string='Status', type='selection',
diff --git a/addons/base_calendar/crm_meeting_view.xml b/addons/base_calendar/crm_meeting_view.xml
index 8590bcb8b49..84c03d68dbd 100644
--- a/addons/base_calendar/crm_meeting_view.xml
+++ b/addons/base_calendar/crm_meeting_view.xml
@@ -5,7 +5,7 @@
<!-- Read/Unread actions -->
<record id="actions_server_crm_meeting_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">CRM Meeting: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_meeting"/>
@@ -23,7 +23,7 @@
</record>
<record id="actions_server_crm_meeting_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">CRM Meeting: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_meeting"/>
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index 88b2edcd665..c552b1835f2 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -4,7 +4,7 @@
<!-- Read/Unread actions -->
<record id="actions_server_crm_lead_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">CRM Lead: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_lead"/>
@@ -22,7 +22,7 @@
</record>
<record id="actions_server_crm_lead_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">CRM Lead: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_lead"/>
diff --git a/addons/crm/crm_phonecall_view.xml b/addons/crm/crm_phonecall_view.xml
index 9cb09e71be2..a6e8dbe397a 100644
--- a/addons/crm/crm_phonecall_view.xml
+++ b/addons/crm/crm_phonecall_view.xml
@@ -4,7 +4,7 @@
<!-- Read/Unread actions -->
<record id="actions_server_crm_phonecall_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">CRM Phonecall: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_phonecall"/>
@@ -22,7 +22,7 @@
</record>
<record id="actions_server_crm_phonecall_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">CRM Phonecall: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_phonecall"/>
diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml
index 14895f2a1a7..9a548679dd3 100644
--- a/addons/event/event_view.xml
+++ b/addons/event/event_view.xml
@@ -59,7 +59,7 @@
<!-- Event Read/Unread actions -->
<record id="actions_server_event_event_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">Event: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_event_event"/>
@@ -77,7 +77,7 @@
</record>
<record id="actions_server_event_event_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">Event: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_event_event"/>
@@ -377,7 +377,7 @@
<!-- Registration Read/Unread actions -->
<record id="actions_server_event_registration_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">Event registration : Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_event_registration"/>
@@ -395,7 +395,7 @@
</record>
<record id="actions_server_event_registration_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">Event registration : Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_event_registration"/>
diff --git a/addons/fleet/fleet_view.xml b/addons/fleet/fleet_view.xml
index 8c7ceaf8d2d..416ca191a6e 100644
--- a/addons/fleet/fleet_view.xml
+++ b/addons/fleet/fleet_view.xml
@@ -318,12 +318,7 @@
</ul>
- <div class="oe_kanban_partner_categories">
- <span class="oe_kanban_list_many2many">
- <div modifiers="{}" name="tag_ids" class="oe_form_field oe_tags" model="fleet.vehicle.tag" t-att-data="record.tag_ids.raw_value" />
- </span>
- </div>
-
+ <field name="tag_ids"/>
</div>
</div>
</t>
diff --git a/addons/hr_holidays/hr_holidays_view.xml b/addons/hr_holidays/hr_holidays_view.xml
index 1914d30ec05..aba6dd36538 100644
--- a/addons/hr_holidays/hr_holidays_view.xml
+++ b/addons/hr_holidays/hr_holidays_view.xml
@@ -3,7 +3,7 @@
<!-- Hr holidays Read/Unread actions -->
<record id="actions_server_holidays_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">Holidays: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_hr_holidays"/>
@@ -21,7 +21,7 @@
</record>
<record id="actions_server_holidays_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">Holidays: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_hr_holidays"/>
diff --git a/addons/hr_recruitment/__openerp__.py b/addons/hr_recruitment/__openerp__.py
index 63c1cf47ccb..f2ba3d55057 100644
--- a/addons/hr_recruitment/__openerp__.py
+++ b/addons/hr_recruitment/__openerp__.py
@@ -60,7 +60,6 @@ You can define the different phases of interviews and easily rate the applicant
'hr_recruitment_data.xml'
],
'demo': ['hr_recruitment_demo.yml'],
- 'js': ['static/src/js/hr_recruitment.js'],
'test': ['test/recruitment_process.yml'],
'installable': True,
'auto_install': False,
diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml
index c3281b43b94..8282c5a300c 100644
--- a/addons/hr_recruitment/hr_recruitment_view.xml
+++ b/addons/hr_recruitment/hr_recruitment_view.xml
@@ -37,7 +37,7 @@
<!-- Jobs -->
<!-- Applicant Read/Unread actions -->
<record id="actions_server_applicant_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">HR Applicant: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_hr_applicant"/>
@@ -55,7 +55,7 @@
</record>
<record id="actions_server_applicant_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">HR Applicant: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_hr_applicant"/>
@@ -314,9 +314,7 @@
</div>
<div class="oe_kanban_footer_left" style="margin-top:5px;">
- <div class="oe_left oe_tags">
- <field name="categ_ids"/>
- </div>
+ <field name="categ_ids"/>
</div>
</div>
<div class="oe_clear"></div>
diff --git a/addons/hr_recruitment/static/src/js/hr_recruitment.js b/addons/hr_recruitment/static/src/js/hr_recruitment.js
deleted file mode 100644
index d11326ac9de..00000000000
--- a/addons/hr_recruitment/static/src/js/hr_recruitment.js
+++ /dev/null
@@ -1,35 +0,0 @@
-openerp.hr_recruitment = function(openerp) {
- openerp.web_kanban.KanbanView.include({
- applicant_display_categ_names: function() {
- /*
- * Set proper names to applicant categories.
- * In kanban views, many2many fields only return a list of ids.
- * Therefore, we have to fetch the matching data by ourselves.
- */
- var self = this;
- var categ_ids = [];
-
- // Collect categories ids
- self.$el.find('span[data-categ_id]').each(function() {
- categ_ids.push($(this).data('categ_id'));
- });
-
- // Find their matching names
- var dataset = new openerp.web.DataSetSearch(self, 'hr.applicant_category', self.session.context, [['id', 'in', _.uniq(categ_ids)]]);
- dataset.read_slice(['id', 'name']).done(function(result) {
- _.each(result, function(v, k) {
- // Set the proper value in the DOM and display the element
- self.$el.find('span[data-categ_id=' + v.id + ']').text(v.name);
- });
- });
- },
- on_groups_started: function() {
- var self = this;
- self._super.apply(self, arguments);
-
- if (self.dataset.model === 'hr.applicant') {
- self.applicant_display_categ_names();
- }
- }
- });
-};
diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
index a24208d6ce0..161ac761aec 100644
--- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
+++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
@@ -19,8 +19,9 @@
#
##############################################################################
-from osv import fields, osv
+import time
+from osv import fields, osv
from tools.translate import _
class hr_timesheet_invoice_factor(osv.osv):
@@ -172,6 +173,143 @@ class account_analytic_line(osv.osv):
return super(account_analytic_line, self).copy(cursor, user, obj_id,
default, context=context)
+ def _get_invoice_price(self, cr, uid, account, product_id, user_id, qty, context = {}):
+ pro_price_obj = self.pool.get('product.pricelist')
+ if account.pricelist_id:
+ pl = account.pricelist_id.id
+ price = pro_price_obj.price_get(cr,uid,[pl], product_id, qty or 1.0, account.partner_id.id, context=context)[pl]
+ else:
+ price = 0.0
+ return price
+
+ def invoice_cost_create(self, cr, uid, ids, data=None, context=None):
+ analytic_account_obj = self.pool.get('account.analytic.account')
+ account_payment_term_obj = self.pool.get('account.payment.term')
+ invoice_obj = self.pool.get('account.invoice')
+ product_obj = self.pool.get('product.product')
+ invoice_factor_obj = self.pool.get('hr_timesheet_invoice.factor')
+ fiscal_pos_obj = self.pool.get('account.fiscal.position')
+ product_uom_obj = self.pool.get('product.uom')
+ invoice_line_obj = self.pool.get('account.invoice.line')
+ invoices = []
+ if context is None:
+ context = {}
+ if data is None:
+ data = {}
+
+ journal_types = {}
+ for line in self.pool.get('account.analytic.line').browse(cr, uid, ids, context=context):
+ if line.journal_id.type not in journal_types:
+ journal_types[line.journal_id.type] = set()
+ journal_types[line.journal_id.type].add(line.account_id.id)
+ for journal_type, account_ids in journal_types.items():
+ for account in analytic_account_obj.browse(cr, uid, list(account_ids), context=context):
+ partner = account.partner_id
+ if (not partner) or not (account.pricelist_id):
+ raise osv.except_osv(_('Analytic Account incomplete !'),
+ _('Contract incomplete. Please fill in the Customer and Pricelist fields.'))
+
+ date_due = False
+ if partner.property_payment_term:
+ pterm_list= account_payment_term_obj.compute(cr, uid,
+ partner.property_payment_term.id, value=1,
+ date_ref=time.strftime('%Y-%m-%d'))
+ if pterm_list:
+ pterm_list = [line[0] for line in pterm_list]
+ pterm_list.sort()
+ date_due = pterm_list[-1]
+
+ curr_invoice = {
+ 'name': time.strftime('%d/%m/%Y') + ' - '+account.name,
+ 'partner_id': account.partner_id.id,
+ 'company_id': account.company_id.id,
+ 'payment_term': partner.property_payment_term.id or False,
+ 'account_id': partner.property_account_receivable.id,
+ 'currency_id': account.pricelist_id.currency_id.id,
+ 'date_due': date_due,
+ 'fiscal_position': account.partner_id.property_account_position.id
+ }
+
+ context2 = context.copy()
+ context2['lang'] = partner.lang
+ # set company_id in context, so the correct default journal will be selected
+ context2['force_company'] = curr_invoice['company_id']
+ # set force_company in context so the correct product properties are selected (eg. income account)
+ context2['company_id'] = curr_invoice['company_id']
+
+ last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=context2)
+ invoices.append(last_invoice)
+
+ cr.execute("""SELECT product_id, user_id, to_invoice, sum(unit_amount), product_uom_id
+ FROM account_analytic_line as line LEFT JOIN account_analytic_journal journal ON (line.journal_id = journal.id)
+ WHERE account_id = %s
+ AND line.id IN %s AND journal.type = %s AND to_invoice IS NOT NULL
+ GROUP BY product_id, user_id, to_invoice, product_uom_id""", (account.id, tuple(ids), journal_type))
+
+ for product_id, user_id, factor_id, qty, uom in cr.fetchall():
+ if data.get('product'):
+ product_id = data['product'][0]
+ product = product_obj.browse(cr, uid, product_id, context=context2)
+ if not product:
+ raise osv.except_osv(_('Error!'), _('There is no product defined. Please select one or force the product through the wizard.'))
+ factor = invoice_factor_obj.browse(cr, uid, factor_id, context=context2)
+ factor_name = product_obj.name_get(cr, uid, [product_id], context=context2)[0][1]
+ if factor.customer_name:
+ factor_name += ' - ' + factor.customer_name
+
+ ctx = context.copy()
+ ctx.update({'uom':uom})
+
+ price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, ctx)
+
+ general_account = product.product_tmpl_id.property_account_income or product.categ_id.property_account_income_categ
+ if not general_account:
+ raise osv.except_osv(_("Configuration Error!"), _("Please define income account for product '%s'.") % product.name)
+ taxes = product.taxes_id or general_account.tax_ids
+ tax = fiscal_pos_obj.map_tax(cr, uid, account.partner_id.property_account_position, taxes)
+ curr_line = {
+ 'price_unit': price,
+ 'quantity': qty,
+ 'discount':factor.factor,
+ 'invoice_line_tax_id': [(6,0,tax )],
+ 'invoice_id': last_invoice,
+ 'name': factor_name,
+ 'product_id': product_id,
+ 'invoice_line_tax_id': [(6,0,tax)],
+ 'uos_id': uom,
+ 'account_id': general_account.id,
+ 'account_analytic_id': account.id,
+ }
+
+ #
+ # Compute for lines
+ #
+ cr.execute("SELECT * FROM account_analytic_line WHERE account_id = %s and id IN %s AND product_id=%s and to_invoice=%s ORDER BY account_analytic_line.date", (account.id, tuple(ids), product_id, factor_id))
+
+ line_ids = cr.dictfetchall()
+ note = []
+ for line in line_ids:
+ # set invoice_line_note
+ details = []
+ if data.get('date', False):
+ details.append(line['date'])
+ if data.get('time', False):
+ if line['product_uom_id']:
+ details.append("%s %s" % (line['unit_amount'], product_uom_obj.browse(cr, uid, [line['product_uom_id']],context2)[0].name))
+ else:
+ details.append("%s" % (line['unit_amount'], ))
+ if data.get('name', False):
+ details.append(line['name'])
+ note.append(u' - '.join(map(lambda x: unicode(x) or '',details)))
+
+ if note:
+ curr_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '',note)))
+ invoice_line_obj.create(cr, uid, curr_line, context=context)
+ cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id IN %s", (last_invoice, account.id, tuple(ids)))
+
+ invoice_obj.button_reset_taxes(cr, uid, [last_invoice], context)
+ return invoices
+
account_analytic_line()
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 ac799f41364..0a8fd36f469 100644
--- a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
+++ b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
@@ -19,163 +19,10 @@
#
##############################################################################
-import time
from osv import osv, fields
from tools.translate import _
-## Create an invoice based on selected timesheet lines
-#
-
-class account_analytic_line(osv.osv):
- _inherit = "account.analytic.line"
- def _get_invoice_price(self, cr, uid, account, product_id, user_id, qty, context = {}):
- pro_price_obj = self.pool.get('product.pricelist')
- if account.pricelist_id:
- pl = account.pricelist_id.id
- price = pro_price_obj.price_get(cr,uid,[pl], product_id, qty or 1.0, account.partner_id.id, context=context)[pl]
- else:
- price = 0.0
- return price
-
-
- #
- # data = {
- # 'date': boolean
- # 'time': boolean
- # 'name': boolean
- # 'price': boolean
- # 'product': many2one id
- # }
- def invoice_cost_create(self, cr, uid, ids, data=None, context=None):
- analytic_account_obj = self.pool.get('account.analytic.account')
- account_payment_term_obj = self.pool.get('account.payment.term')
- invoice_obj = self.pool.get('account.invoice')
- product_obj = self.pool.get('product.product')
- invoice_factor_obj = self.pool.get('hr_timesheet_invoice.factor')
- fiscal_pos_obj = self.pool.get('account.fiscal.position')
- product_uom_obj = self.pool.get('product.uom')
- invoice_line_obj = self.pool.get('account.invoice.line')
- invoices = []
- if context is None:
- context = {}
- if data is None:
- data = {}
-
- account_ids = [line.account_id.id for line in self.pool.get('account.analytic.line').browse(cr, uid, ids, context=context)]
- for account in analytic_account_obj.browse(cr, uid, account_ids, context=context):
- partner = account.partner_id
- if (not partner) or not (account.pricelist_id):
- raise osv.except_osv(_('Analytic Account incomplete !'),
- _('Contract incomplete. Please fill in the Customer and Pricelist fields.'))
-
-
-
- date_due = False
- if partner.property_payment_term:
- pterm_list= account_payment_term_obj.compute(cr, uid,
- partner.property_payment_term.id, value=1,
- date_ref=time.strftime('%Y-%m-%d'))
- if pterm_list:
- pterm_list = [line[0] for line in pterm_list]
- pterm_list.sort()
- date_due = pterm_list[-1]
-
- curr_invoice = {
- 'name': time.strftime('%d/%m/%Y')+' - '+account.name,
- 'partner_id': account.partner_id.id,
- 'company_id': account.company_id.id,
- 'payment_term': partner.property_payment_term.id or False,
- 'account_id': partner.property_account_receivable.id,
- 'currency_id': account.pricelist_id.currency_id.id,
- 'date_due': date_due,
- 'fiscal_position': account.partner_id.property_account_position.id
- }
-
- context2 = context.copy()
- context2['lang'] = partner.lang
- # set company_id in context, so the correct default journal will be selected
- context2['force_company'] = curr_invoice['company_id']
- # set force_company in context so the correct product properties are selected (eg. income account)
- context2['company_id'] = curr_invoice['company_id']
-
- last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=context2)
- invoices.append(last_invoice)
-
- cr.execute("SELECT product_id, user_id, to_invoice, sum(unit_amount), product_uom_id " \
- "FROM account_analytic_line as line " \
- "WHERE account_id = %s " \
- "AND id IN %s AND to_invoice IS NOT NULL " \
- "GROUP BY product_id, user_id, to_invoice, product_uom_id", (account.id, tuple(ids),))
-
- for product_id, user_id, factor_id, qty, uom in cr.fetchall():
- if data.get('product'):
- product_id = data['product'][0]
- product = product_obj.browse(cr, uid, product_id, context=context2)
- if not product:
- raise osv.except_osv(_('Error!'), _('There is no product defined. Please select one or force the product through the wizard.'))
- factor = invoice_factor_obj.browse(cr, uid, factor_id, context=context2)
- factor_name = product_obj.name_get(cr, uid, [product_id], context=context2)[0][1]
- if factor.customer_name:
- factor_name += ' - ' + factor.customer_name
-
- ctx = context.copy()
- ctx.update({'uom':uom})
-
- price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, ctx)
-
- general_account = product.product_tmpl_id.property_account_income or product.categ_id.property_account_income_categ
- if not general_account:
- raise osv.except_osv(_("Configuration Error!"), _("Please define income account for product '%s'.") % product.name)
- taxes = product.taxes_id or general_account.tax_ids
- tax = fiscal_pos_obj.map_tax(cr, uid, account.partner_id.property_account_position, taxes)
- curr_line = {
- 'price_unit': price,
- 'quantity': qty,
- 'discount':factor.factor,
- 'invoice_line_tax_id': [(6,0,tax )],
- 'invoice_id': last_invoice,
- 'name': factor_name,
- 'product_id': product_id,
- 'invoice_line_tax_id': [(6,0,tax)],
- 'uos_id': uom,
- 'account_id': general_account.id,
- 'account_analytic_id': account.id,
- }
-
- #
- # Compute for lines
- #
- cr.execute("SELECT * FROM account_analytic_line WHERE account_id = %s and id IN %s AND product_id=%s and to_invoice=%s ORDER BY account_analytic_line.date", (account.id, tuple(ids), product_id, factor_id))
-
- line_ids = cr.dictfetchall()
- note = []
- for line in line_ids:
- # set invoice_line_note
- details = []
- if data.get('date', False):
- details.append(line['date'])
- if data.get('time', False):
- if line['product_uom_id']:
- details.append("%s %s" % (line['unit_amount'], product_uom_obj.browse(cr, uid, [line['product_uom_id']],context2)[0].name))
- else:
- details.append("%s" % (line['unit_amount'], ))
- if data.get('name', False):
- details.append(line['name'])
- note.append(u' - '.join(map(lambda x: unicode(x) or '',details)))
-
- if note:
- curr_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '',note)))
- invoice_line_obj.create(cr, uid, curr_line, context=context)
- cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id IN %s", (last_invoice, account.id, tuple(ids)))
-
- invoice_obj.button_reset_taxes(cr, uid, [last_invoice], context)
- return invoices
-
-#
-# TODO: check unit of measure !!!
-#
-
class hr_timesheet_invoice_create(osv.osv_memory):
_name = 'hr.timesheet.invoice.create'
@@ -189,8 +36,8 @@ class hr_timesheet_invoice_create(osv.osv_memory):
}
_defaults = {
- 'date': lambda *args: 1,
- 'name': lambda *args: 1
+ 'date': 1,
+ 'name': 1,
}
def view_init(self, cr, uid, fields, context=None):
@@ -210,6 +57,7 @@ class hr_timesheet_invoice_create(osv.osv_memory):
def do_create(self, cr, uid, ids, context=None):
data = self.read(cr, uid, ids, [], context=context)[0]
+ # Create an invoice based on selected timesheet lines
invs = self.pool.get('account.analytic.line').invoice_cost_create(cr, uid, context['active_ids'], data, context=context)
mod_obj = self.pool.get('ir.model.data')
act_obj = self.pool.get('ir.actions.act_window')
diff --git a/addons/membership/membership.py b/addons/membership/membership.py
index 12e1c89a04a..4ffd067d73e 100644
--- a/addons/membership/membership.py
+++ b/addons/membership/membership.py
@@ -483,16 +483,16 @@ class Invoice(osv.osv):
'''Invoice'''
_inherit = 'account.invoice'
- def action_cancel(self, cr, uid, ids, *args):
+ def action_cancel(self, cr, uid, ids, context=None):
'''Create a 'date_cancel' on the membership_line object'''
member_line_obj = self.pool.get('membership.membership_line')
today = time.strftime('%Y-%m-%d')
- for invoice in self.browse(cr, uid, ids):
+ for invoice in self.browse(cr, uid, ids, context=context):
mlines = member_line_obj.search(cr, uid,
[('account_invoice_line', 'in',
[l.id for l in invoice.invoice_line])])
member_line_obj.write(cr, uid, mlines, {'date_cancel': today})
- return super(Invoice, self).action_cancel(cr, uid, ids)
+ return super(Invoice, self).action_cancel(cr, uid, ids, context=context)
Invoice()
diff --git a/addons/point_of_sale/static/src/js/db.js b/addons/point_of_sale/static/src/js/db.js
index f8ae9cdb56d..0df57759156 100644
--- a/addons/point_of_sale/static/src/js/db.js
+++ b/addons/point_of_sale/static/src/js/db.js
@@ -213,8 +213,10 @@ function openerp_pos_db(instance, module){
var stored_products = this.load('products',{});
var product_ids = stored_categories[category_id];
var list = [];
- for(var i = 0, len = Math.min(product_ids.length,this.limit); i < len; i++){
- list.push(stored_products[product_ids[i]]);
+ if (product_ids) {
+ for (var i = 0, len = Math.min(product_ids.length, this.limit); i < len; i++) {
+ list.push(stored_products[product_ids[i]]);
+ }
}
return list;
},
diff --git a/addons/portal_project_issue/portal_project_issue_view.xml b/addons/portal_project_issue/portal_project_issue_view.xml
index 6502d92b4dc..c943bb3b825 100644
--- a/addons/portal_project_issue/portal_project_issue_view.xml
+++ b/addons/portal_project_issue/portal_project_issue_view.xml
@@ -24,12 +24,7 @@
<field name="version_id"/>
</div>
<div class="oe_kanban_footer_left">
- <div class="oe_left oe_tags">
- <t t-foreach="record.categ_ids.raw_value" t-as="categ_id">
- <span class="oe_tag" t-att-data-categ_id="categ_id"></span>
- </t>
- <field name="categ_ids"/>
- </div>
+ <field name="categ_ids"/>
<div class="oe_right">
Creation: <field name="create_date"/>
<span class="oe_kanban_highlight">
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index 8bb45ca6738..f54fb20ea20 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -21,7 +21,7 @@
<!-- Project Read/Unread actions -->
<record id="actions_server_project_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">Project: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_project"/>
@@ -39,7 +39,7 @@
</record>
<record id="actions_server_project_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">Project: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_project"/>
@@ -344,7 +344,7 @@
<!-- Task Read/Unread actions -->
<record id="actions_server_project_task_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">Task: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_task"/>
@@ -362,7 +362,7 @@
</record>
<record id="actions_server_project_task_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">Task: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_task"/>
@@ -546,11 +546,7 @@
</span>
</div>
<div class="oe_kanban_footer_left" style="margin-top:5px;">
- <div class="oe_left oe_tags">
- <t t-foreach="record.categ_ids.raw_value" t-as="categ_id">
- <span class="oe_tag" t-att-data-categ_id="categ_id"></span>
- </t>
- </div>
+ <field name="categ_ids"/>
</div>
</div>
<div class="oe_clear"></div>
diff --git a/addons/project/static/src/js/project.js b/addons/project/static/src/js/project.js
index 38578a6226e..ce8be146e54 100644
--- a/addons/project/static/src/js/project.js
+++ b/addons/project/static/src/js/project.js
@@ -25,37 +25,12 @@ openerp.project = function(openerp) {
});
});
},
- project_display_categ_names: function() {
- /*
- * Set proper names to project categories.
- * In kanban views, many2many fields only return a list of ids.
- * Therefore, we have to fetch the matching data by ourselves.
- */
- var self = this;
- var categ_ids = [];
-
- // Collect categories ids
- self.$el.find('span[data-categ_id]').each(function() {
- categ_ids.push($(this).data('categ_id'));
- });
-
- // Find their matching names
- var dataset = new openerp.web.DataSetSearch(self, 'project.category', self.session.context, [['id', 'in', _.uniq(categ_ids)]]);
- dataset.read_slice(['id', 'name']).done(function(result) {
- _.each(result, function(v, k) {
- // Set the proper value in the DOM and display the element
- self.$el.find('span[data-categ_id=' + v.id + ']').text(v.name);
- });
- });
- },
on_groups_started: function() {
var self = this;
self._super.apply(self, arguments);
if (self.dataset.model === 'project.project') {
self.project_display_members_names();
- } else if (self.dataset.model === 'project.task') {
- self.project_display_categ_names();
}
},
on_record_moved: function(record, old_group, old_index, new_group, new_index){
@@ -74,9 +49,5 @@ openerp.project = function(openerp) {
this._super.apply(this, arguments);
}
},
- bind_events: function() {
- this._super();
- this.view.project_display_categ_names();
- },
});
};
diff --git a/addons/project_issue/__openerp__.py b/addons/project_issue/__openerp__.py
index b2e9197cefd..2c5f311c044 100644
--- a/addons/project_issue/__openerp__.py
+++ b/addons/project_issue/__openerp__.py
@@ -61,7 +61,6 @@ It allows the manager to quickly check the issues, assign them and decide on the
'installable': True,
'auto_install': False,
'application': True,
- 'js': ['static/src/js/project_issue.js'],
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml
index e3105127c5d..7d026da96a9 100644
--- a/addons/project_issue/project_issue_view.xml
+++ b/addons/project_issue/project_issue_view.xml
@@ -6,7 +6,7 @@
<!-- Project issue Read/Unread actions -->
<record id="actions_server_project_issue_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">Issue: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_issue"/>
@@ -24,7 +24,7 @@
</record>
<record id="actions_server_project_issue_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">Issue: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_issue"/>
@@ -264,9 +264,7 @@
<field name="version_id"/>
</div>
<div class="oe_kanban_footer_left">
- <div class="oe_left oe_tags">
- <field name="categ_ids"/>
- </div>
+ <field name="categ_ids"/>
<div class="oe_right">
<span class="oe_kanban_highlight">
<t t-set="priority" t-value="record.priority.raw_value || 5"/>
diff --git a/addons/project_issue/static/src/js/project_issue.js b/addons/project_issue/static/src/js/project_issue.js
deleted file mode 100644
index 24e5ff7cc49..00000000000
--- a/addons/project_issue/static/src/js/project_issue.js
+++ /dev/null
@@ -1,13 +0,0 @@
-openerp.portal_project_issue = function(openerp) {
- openerp.web_kanban.KanbanView.include({
- on_groups_started: function() {
- var self = this;
- self._super.apply(this, arguments);
-
- if (self.dataset.model === 'project.issue') {
- // Load project's categories names from m2m field
- self.project_display_categ_names();
- }
- }
- });
-};
diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml
index 9397a95c970..f0be9e56dec 100644
--- a/addons/purchase/purchase_view.xml
+++ b/addons/purchase/purchase_view.xml
@@ -134,7 +134,7 @@
<!-- Purchase order Read/Unread actions -->
<record id="actions_server_purchase_order_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">Purchase: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_purchase_order"/>
@@ -152,7 +152,7 @@
</record>
<record id="actions_server_purchase_order_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">Purchase: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_purchase_order"/>
diff --git a/addons/purchase/report/request_quotation.rml b/addons/purchase/report/request_quotation.rml
index 495c8790e7b..c1500c48710 100644
--- a/addons/purchase/report/request_quotation.rml
+++ b/addons/purchase/report/request_quotation.rml
@@ -149,11 +149,6 @@
<para style="terp_default_Right_9">[[ (order_line.product_uom and order_line.product_uom.name) or '' ]]</para>
</td>
</tr>
- <tr>
- <td>
- <para style="terp_default_8_italic">[[ format(order_line.notes or removeParentNode('tr')) ]]</para>
- </td>
- </tr>
</blockTable>
</section>
<para style="terp_default_9">
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index f248f4735e0..cbf31f93941 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -68,7 +68,7 @@
<!-- Sale order Read/Unread actions -->
<record id="actions_server_sale_order_unread" model="ir.actions.server">
- <field name="name">Mark unread</field>
+ <field name="name">Sale: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_sale_order"/>
@@ -86,7 +86,7 @@
</record>
<record id="actions_server_sale_order_read" model="ir.actions.server">
- <field name="name">Mark read</field>
+ <field name="name">Sale: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_sale_order"/>