summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2015-08-06 16:09:19 +0200
committerChristophe Simonis <chs@odoo.com>2015-08-06 16:09:19 +0200
commit95ac2cfd10f66d1ad0d5a369f62ee8af72b6f7c8 (patch)
tree9078494e7b3d3d57cb5e59b9ac455f424975bccd
parentf62cfd29803725bd755c353853d0313f4237f9e0 (diff)
parentbe58335f7f6bf727210e60accf67a47b98c17042 (diff)
[MERGE] forward port of branch saas-6 up to be58335
-rw-r--r--addons/account/views/account_view.xml2
-rw-r--r--addons/account_cancel/__init__.py2
-rw-r--r--addons/account_cancel/account_cancel_view.xml11
-rw-r--r--addons/account_cancel/models/__init__.py4
-rw-r--r--addons/account_cancel/models/account_bank_statement.py23
-rw-r--r--addons/analytic/models/analytic.py2
-rw-r--r--addons/auth_crypt/auth_crypt.py3
-rw-r--r--addons/auth_signup/res_users.py2
-rw-r--r--addons/calendar/calendar.py4
-rw-r--r--addons/calendar/i18n/calendar.pot2
-rw-r--r--addons/crm_partner_assign/crm_partner_assign.py3
-rw-r--r--addons/delivery/models/sale_order.py9
-rw-r--r--addons/delivery/stock.py5
-rw-r--r--addons/fetchmail/fetchmail.py3
-rw-r--r--addons/google_account/google_account.py6
-rw-r--r--addons/google_calendar/google_calendar.py4
-rw-r--r--addons/hr_timesheet_invoice/hr_timesheet_invoice.py20
-rw-r--r--addons/im_livechat/security/im_livechat_channel_security.xml2
-rw-r--r--addons/l10n_be/account_tax_template.xml30
-rw-r--r--addons/l10n_be_coda/l10n_be_coda_demo.xml1
-rw-r--r--addons/mrp_byproduct/mrp_byproduct.py8
-rw-r--r--addons/pad/pad.py2
-rw-r--r--addons/payment/models/payment_acquirer.py2
-rw-r--r--addons/payment_ogone/controllers/main.py2
-rw-r--r--addons/payment_ogone/models/ogone.py5
-rw-r--r--addons/point_of_sale/i18n/point_of_sale.pot7
-rw-r--r--addons/point_of_sale/static/src/xml/pos.xml1
-rw-r--r--addons/product/i18n/product.pot5
-rw-r--r--addons/product_margin/product_margin.py35
-rw-r--r--addons/product_margin/product_margin_view.xml2
-rw-r--r--addons/purchase/partner_view.xml2
-rw-r--r--addons/purchase/purchase.py46
-rw-r--r--addons/purchase/stock.py10
-rw-r--r--addons/purchase/wizard/purchase_line_invoice.py77
-rw-r--r--addons/sale/res_config.py2
-rw-r--r--addons/sale/sale.py10
-rw-r--r--addons/sale_stock/sale_stock.py2
-rw-r--r--addons/sales_team/sales_team.py2
-rw-r--r--addons/stock/stock.py10
-rw-r--r--addons/stock/stock_view.xml8
-rw-r--r--addons/web_calendar/static/src/js/web_calendar.js6
-rw-r--r--addons/website_sale/controllers/main.py5
-rw-r--r--addons/website_sale/static/src/js/website_sale_tracking.js2
-rw-r--r--addons/website_sale_delivery/__openerp__.py2
-rw-r--r--addons/website_sale_delivery/data/website_sale_delivery_demo.xml14
-rw-r--r--addons/website_sale_delivery/models/sale_order.py14
-rw-r--r--addons/website_slides/models/res_config.py2
-rw-r--r--doc/cla/individual/anthony25.md11
-rw-r--r--doc/howtos/backend.rst2
-rw-r--r--openerp/addons/base/ir/ir_translation.py5
-rw-r--r--openerp/addons/base/module/module.py2
-rw-r--r--openerp/addons/base/res/res_users.py2
-rw-r--r--openerp/addons/test_impex/tests/test_export.py22
-rw-r--r--openerp/fields.py41
-rw-r--r--openerp/models.py4
-rw-r--r--openerp/modules/loading.py2
-rw-r--r--openerp/tests/common.py17
57 files changed, 337 insertions, 192 deletions
diff --git a/addons/account/views/account_view.xml b/addons/account/views/account_view.xml
index b8899148606..fa15efda0db 100644
--- a/addons/account/views/account_view.xml
+++ b/addons/account/views/account_view.xml
@@ -1056,7 +1056,7 @@
<tree string="Journal Items" create="false">
<field name="date"/>
<field name="move_id" required="0"/>
- <field name="journal_id" options='{"no_open":True}' invisible="context.get('journal_id',False)"/>
+ <field name="journal_id" options='{"no_open":True}'/>
<field name="name"/>
<field name="ref"/>
<field name="statement_id" invisible="1"/>
diff --git a/addons/account_cancel/__init__.py b/addons/account_cancel/__init__.py
index 67dee8c60db..81fc81d29c9 100644
--- a/addons/account_cancel/__init__.py
+++ b/addons/account_cancel/__init__.py
@@ -1,2 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import models
diff --git a/addons/account_cancel/account_cancel_view.xml b/addons/account_cancel/account_cancel_view.xml
index d64d3101c64..9f18f6de651 100644
--- a/addons/account_cancel/account_cancel_view.xml
+++ b/addons/account_cancel/account_cancel_view.xml
@@ -34,6 +34,17 @@
</field>
</record>
+ <record id="bank_statement_draft_form_inherit" model="ir.ui.view">
+ <field name="name">bank.statement.draft.form.inherit</field>
+ <field name="model">account.bank.statement</field>
+ <field name="inherit_id" ref="account.view_bank_statement_form"/>
+ <field name="arch" type="xml">
+ <xpath expr="//button[@name='button_cancel']" position="after">
+ <button name="button_draft" states="confirm" string="Reset to New" type="object"/>
+ </xpath>
+ </field>
+ </record>
+
<record id="bank_statement_cancel_form_inherit" model="ir.ui.view">
<field name="name">bank.statement.cancel.form.inherit</field>
<field name="model">account.bank.statement</field>
diff --git a/addons/account_cancel/models/__init__.py b/addons/account_cancel/models/__init__.py
new file mode 100644
index 00000000000..433ad1bafd1
--- /dev/null
+++ b/addons/account_cancel/models/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import account_bank_statement
diff --git a/addons/account_cancel/models/account_bank_statement.py b/addons/account_cancel/models/account_bank_statement.py
new file mode 100644
index 00000000000..821014abf37
--- /dev/null
+++ b/addons/account_cancel/models/account_bank_statement.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from openerp import models, api, _
+from openerp.exceptions import Warning
+
+
+class BankStatement(models.Model):
+ _inherit = 'account.bank.statement'
+
+ @api.multi
+ def button_draft(self):
+ self.state = 'draft'
+
+class BankStatementLine(models.Model):
+ _inherit = 'account.bank.statement.line'
+
+ @api.multi
+ def cancel(self):
+ for line in self:
+ if line.statement_id.state == 'confirm':
+ raise Warning(_("Please set the bank statement to New before canceling."))
+ return super(BankStatementLine, self).cancel()
diff --git a/addons/analytic/models/analytic.py b/addons/analytic/models/analytic.py
index 0235b5d2e1a..2583d015f93 100644
--- a/addons/analytic/models/analytic.py
+++ b/addons/analytic/models/analytic.py
@@ -170,7 +170,7 @@ class account_analytic_account(osv.osv):
"The type 'Analytic account' stands for usual accounts that you only want to use in accounting.\n"\
"If you select Contract or Project, it offers you the possibility to manage the validity and the invoicing options for this account.\n"\
"The special type 'Template of Contract' allows you to define a template with default data that you can reuse easily."),
- 'template_id': fields.many2one('account.analytic.account', 'Template of Contract'),
+ 'template_id': fields.many2one('account.analytic.account', 'Template of Contract', ondelete='restrict'),
'description': fields.text('Description'),
'parent_id': fields.many2one('account.analytic.account', 'Parent Analytic Account', select=2),
'child_ids': fields.one2many('account.analytic.account', 'parent_id', 'Child Accounts', copy=True),
diff --git a/addons/auth_crypt/auth_crypt.py b/addons/auth_crypt/auth_crypt.py
index ca17cee7048..a813fddfae5 100644
--- a/addons/auth_crypt/auth_crypt.py
+++ b/addons/auth_crypt/auth_crypt.py
@@ -5,7 +5,8 @@ from passlib.context import CryptContext
import openerp
from openerp.osv import fields, osv
-openerp.addons.base.res.res_users.USER_PRIVATE_FIELDS.append('password_crypt')
+from openerp.addons.base.res import res_users
+res_users.USER_PRIVATE_FIELDS.append('password_crypt')
_logger = logging.getLogger(__name__)
diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py
index 043a78fed58..4168e35fecf 100644
--- a/addons/auth_signup/res_users.py
+++ b/addons/auth_signup/res_users.py
@@ -18,7 +18,7 @@ class SignupError(Exception):
def random_token():
# the token has an entropy of about 120 bits (6 bits/char * 20 chars)
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
- return ''.join(random.choice(chars) for i in xrange(20))
+ return ''.join(random.SystemRandom().choice(chars) for i in xrange(20))
def now(**kwargs):
dt = datetime.now() + timedelta(**kwargs)
diff --git a/addons/calendar/calendar.py b/addons/calendar/calendar.py
index 188f4123e3a..1dd7c06ac6f 100644
--- a/addons/calendar/calendar.py
+++ b/addons/calendar/calendar.py
@@ -575,7 +575,7 @@ class calendar_alarm(osv.Model):
'type': fields.selection([('notification', 'Notification'), ('email', 'Email')], 'Type', required=True),
'duration': fields.integer('Amount', required=True),
'interval': fields.selection(list(_interval_selection.iteritems()), 'Unit', required=True),
- 'duration_minutes': fields.function(_get_duration, type='integer', string='Duration', store=True, help="Duration in minutes"),
+ 'duration_minutes': fields.function(_get_duration, type='integer', string='Duration in minutes', store=True, help="Duration in minutes"),
}
_defaults = {
@@ -958,7 +958,7 @@ class calendar_event(osv.Model):
'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
'color_partner_id': fields.related('user_id', 'partner_id', 'id', type="integer", string="Color index of creator", store=False), # Color of creator
- 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the event alarm information without removing it."),
+ 'active': fields.boolean('Active', help="If the active field is set to false, it will allow you to hide the event alarm information without removing it."),
'categ_ids': fields.many2many('calendar.event.type', 'meeting_category_rel', 'event_id', 'type_id', 'Tags'),
'attendee_ids': fields.one2many('calendar.attendee', 'event_id', 'Attendees', ondelete='cascade'),
'partner_ids': fields.many2many('res.partner', 'calendar_event_res_partner_rel', string='Attendees', states={'done': [('readonly', True)]}),
diff --git a/addons/calendar/i18n/calendar.pot b/addons/calendar/i18n/calendar.pot
index 57c6471cbbc..86a30ca49a0 100644
--- a/addons/calendar/i18n/calendar.pot
+++ b/addons/calendar/i18n/calendar.pot
@@ -1441,7 +1441,7 @@ msgstr ""
#. module: calendar
#: field:calendar.alarm,duration_minutes:0
-msgid "duration_minutes"
+msgid "Duration in minutes"
msgstr ""
#. module: calendar
diff --git a/addons/crm_partner_assign/crm_partner_assign.py b/addons/crm_partner_assign/crm_partner_assign.py
index d8f342a1f54..f112b9f0cd1 100644
--- a/addons/crm_partner_assign/crm_partner_assign.py
+++ b/addons/crm_partner_assign/crm_partner_assign.py
@@ -187,7 +187,8 @@ class crm_lead(osv.osv):
# warning: point() type takes (longitude, latitude) as parameters in this order!
cr.execute("""SELECT id, distance
FROM (select id, (point(partner_longitude, partner_latitude) <-> point(%s,%s)) AS distance FROM res_partner
- WHERE partner_longitude is not null
+ WHERE active
+ AND partner_longitude is not null
AND partner_latitude is not null
AND partner_weight > 0) AS d
ORDER BY distance LIMIT 1""", (longitude, latitude))
diff --git a/addons/delivery/models/sale_order.py b/addons/delivery/models/sale_order.py
index 02031293d0e..2fbf68d86e7 100644
--- a/addons/delivery/models/sale_order.py
+++ b/addons/delivery/models/sale_order.py
@@ -31,7 +31,14 @@ class SaleOrder(models.Model):
@api.depends('carrier_id', 'partner_id', 'order_line')
def _compute_delivery_price(self):
for order in self:
- order.delivery_price = order.carrier_id.with_context(order_id=order.id).price
+ if order.state != 'draft':
+ # we do not want to recompute the shipping price of an already validated/done SO
+ continue
+ elif order.carrier_id.delivery_type != 'grid' and not order.order_line:
+ # prevent SOAP call to external shipping provider when SO has no lines yet
+ continue
+ else:
+ order.delivery_price = order.carrier_id.with_context(order_id=order.id).price
@api.multi
def delivery_set(self):
diff --git a/addons/delivery/stock.py b/addons/delivery/stock.py
index 600ac2023ac..26c8d4f7864 100644
--- a/addons/delivery/stock.py
+++ b/addons/delivery/stock.py
@@ -64,7 +64,7 @@ class stock_picking(osv.osv):
"""
carrier_obj = self.pool.get('delivery.carrier')
grid_obj = self.pool.get('delivery.grid')
- fpos_obj = self.pool['account.fiscal.position']
+ currency_obj = self.pool.get('res.currency')
if not picking.carrier_id or \
any(inv_line.product_id.id == picking.carrier_id.product_id.id
for inv_line in invoice.invoice_line_ids):
@@ -77,6 +77,9 @@ class stock_picking(osv.osv):
price = grid_obj.get_price_from_picking(cr, uid, grid_id,
invoice.amount_untaxed, picking.weight, picking.volume,
quantity, context=context)
+ if invoice.company_id.currency_id.id != invoice.currency_id.id:
+ price = currency_obj.compute(cr, uid, invoice.company_id.currency_id.id, invoice.currency_id.id,
+ price, context=dict(context or {}, date=invoice.date_invoice))
account_id = picking.carrier_id.product_id.property_account_income_id.id
if not account_id:
account_id = picking.carrier_id.product_id.categ_id\
diff --git a/addons/fetchmail/fetchmail.py b/addons/fetchmail/fetchmail.py
index a98330d8f6e..66fe3aaa9f8 100644
--- a/addons/fetchmail/fetchmail.py
+++ b/addons/fetchmail/fetchmail.py
@@ -24,6 +24,7 @@ from openerp.exceptions import UserError
_logger = logging.getLogger(__name__)
MAX_POP_MESSAGES = 50
+MAIL_TIMEOUT = 60
# Workaround for Python 2.7.8 bug https://bugs.python.org/issue23906
poplib._MAXLINE = 65536
@@ -137,6 +138,8 @@ openerp_mailgate: "|/path/to/openerp-mailgate.py --host=localhost -u %(uid)d -p
#connection.user("recent:"+server.user)
connection.user(server.user)
connection.pass_(server.password)
+ # Add timeout on socket
+ connection.sock.settimeout(MAIL_TIMEOUT)
return connection
def button_confirm_login(self, cr, uid, ids, context=None):
diff --git a/addons/google_account/google_account.py b/addons/google_account/google_account.py
index 2cc56d0cba4..ea1482d6925 100644
--- a/addons/google_account/google_account.py
+++ b/addons/google_account/google_account.py
@@ -163,13 +163,13 @@ class google_service(osv.osv_memory):
except:
pass
except urllib2.HTTPError, e:
- if e.code in (400, 401, 410):
- raise e
- elif e.code in (204, 404):
+ if e.code in (204, 404):
status = e.code
response = ""
else:
_logger.exception("Bad google request : %s !" % e.read())
+ if e.code in (400, 401, 410):
+ raise e
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong with your request to google"), context=context)
return (status, response, ask_time)
diff --git a/addons/google_calendar/google_calendar.py b/addons/google_calendar/google_calendar.py
index f77c40a6720..bbfcc961eaf 100644
--- a/addons/google_calendar/google_calendar.py
+++ b/addons/google_calendar/google_calendar.py
@@ -212,8 +212,10 @@ class google_calendar(osv.AbstractModel):
vstype = 'date'
attendee_list = []
for attendee in event.attendee_ids:
+ email = tools.email_split(attendee.email)
+ email = email[0] if email else 'NoEmail@mail.com'
attendee_list.append({
- 'email': attendee.email or 'NoEmail@mail.com',
+ 'email': email,
'displayName': attendee.partner_id.name,
'responseStatus': attendee.state or 'needsAction',
})
diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
index 058137f5b71..4be9e3a1de3 100644
--- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
+++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
@@ -177,16 +177,16 @@ class account_analytic_line(osv.osv):
if factor.customer_name:
factor_name += ' - ' + factor.customer_name
- general_account = product.property_account_income_id or product.categ_id.property_account_income_categ_id
- if not general_account:
- raise UserError(_("Configuration Error!") + '\n' + _("Please define income account for product '%s'.") % product.name)
- taxes = product.taxes_id or general_account.tax_ids
- tax = self.pool['account.fiscal.position'].map_tax(cr, uid, account.partner_id.property_account_position_id, taxes)
- curr_invoice_line.update({
- 'invoice_line_tax_ids': [(6, 0, tax)],
- 'name': factor_name,
- 'account_id': general_account.id,
- })
+ general_account = product.property_account_income_id or product.categ_id.property_account_income_categ_id
+ if not general_account:
+ raise UserError(_("Configuration Error!") + '\n' + _("Please define income account for product '%s'.") % product.name)
+ taxes = product.taxes_id or general_account.tax_ids
+ tax = self.pool['account.fiscal.position'].map_tax(cr, uid, account.partner_id.property_account_position_id, taxes)
+ curr_invoice_line.update({
+ 'invoice_line_tax_ids': [(6, 0, tax)],
+ 'name': factor_name,
+ 'account_id': general_account.id,
+ })
note = []
for line in analytic_line_ids:
diff --git a/addons/im_livechat/security/im_livechat_channel_security.xml b/addons/im_livechat/security/im_livechat_channel_security.xml
index 8b0e38e9bf8..71c8b08739a 100644
--- a/addons/im_livechat/security/im_livechat_channel_security.xml
+++ b/addons/im_livechat/security/im_livechat_channel_security.xml
@@ -36,7 +36,7 @@
<field name="name">Live Support Managers can see all session from live support</field>
<field name="model_id" ref="im_chat.model_im_chat_session"/>
<field name="groups" eval="[(6,0,[ref('im_livechat.im_livechat_group_manager')])]"/>
- <field name="domain_force">[('to_id.channel_id', '!=', None)]</field>
+ <field name="domain_force">[('channel_id', '!=', None)]</field>
<field name="perm_unlink" eval="1"/>
<field name="perm_write" eval="0"/>
<field name="perm_read" eval="1"/>
diff --git a/addons/l10n_be/account_tax_template.xml b/addons/l10n_be/account_tax_template.xml
index 319223a18af..cbf009587cd 100644
--- a/addons/l10n_be/account_tax_template.xml
+++ b/addons/l10n_be/account_tax_template.xml
@@ -91,7 +91,7 @@
<record id="attn_VAT-OUT-21-S" model="account.tax.template">
<field name="sequence">10</field>
<field name="description">VAT-OUT-21-S</field>
- <field name="name">VAT 21% - Services</field>
+ <field name="name">TVA 21% - Services</field>
<field name="refund_account_id" ref="a451054"/>
<field name="account_id" ref="a451054"/>
<field name="price_include" eval="0"/>
@@ -104,7 +104,7 @@
<record id="attn_VAT-OUT-21-L" model="account.tax.template">
<field name="sequence">11</field>
<field name="description">VAT-OUT-21-L</field>
- <field name="name">VAT 21%</field>
+ <field name="name">TVA 21%</field>
<field name="refund_account_id" ref="a451054"/>
<field name="account_id" ref="a451054"/>
<field name="price_include" eval="0"/>
@@ -117,7 +117,7 @@
<record id="attn_VAT-OUT-12-S" model="account.tax.template">
<field name="sequence">20</field>
<field name="description">VAT-OUT-12-S</field>
- <field name="name">VAT 12% - Services</field>
+ <field name="name">TVA 12% - Services</field>
<field name="refund_account_id" ref="a451054"/>
<field name="account_id" ref="a451054"/>
<field name="price_include" eval="0"/>
@@ -130,7 +130,7 @@
<record id="attn_VAT-OUT-12-L" model="account.tax.template">
<field name="sequence">21</field>
<field name="description">VAT-OUT-12-L</field>
- <field name="name">VAT 12%</field>
+ <field name="name">TVA 12%</field>
<field name="refund_account_id" ref="a451054"/>
<field name="account_id" ref="a451054"/>
<field name="price_include" eval="0"/>
@@ -143,7 +143,7 @@
<record id="attn_VAT-OUT-06-S" model="account.tax.template">
<field name="sequence">30</field>
<field name="description">VAT-OUT-06-S</field>
- <field name="name">VAT 6% - Services</field>
+ <field name="name">TVA 6% - Services</field>
<field name="refund_account_id" ref="a451054"/>
<field name="account_id" ref="a451054"/>
<field name="price_include" eval="0"/>
@@ -156,7 +156,7 @@
<record id="attn_VAT-OUT-06-L" model="account.tax.template">
<field name="sequence">31</field>
<field name="description">VAT-OUT-06-L</field>
- <field name="name">VAT 6%</field>
+ <field name="name">TVA 6%</field>
<field name="refund_account_id" ref="a451054"/>
<field name="account_id" ref="a451054"/>
<field name="price_include" eval="0"/>
@@ -169,7 +169,7 @@
<record id="attn_VAT-OUT-00-S" model="account.tax.template">
<field name="sequence">40</field>
<field name="description">VAT-OUT-00-S</field>
- <field name="name">VAT 0% - Services</field>
+ <field name="name">TVA 0% - Services</field>
<field name="price_include" eval="0"/>
<field name="amount">0</field>
<field name="amount_type">percent</field>
@@ -180,7 +180,7 @@
<record id="attn_VAT-OUT-00-L" model="account.tax.template">
<field name="sequence">41</field>
<field name="description">VAT-OUT-00-L</field>
- <field name="name">VAT 0%</field>
+ <field name="name">TVA 0%</field>
<field name="price_include" eval="0"/>
<field name="amount">0</field>
<field name="amount_type">percent</field>
@@ -191,7 +191,7 @@
<record id="attn_VAT-OUT-00-CC" model="account.tax.template">
<field name="sequence">50</field>
<field name="description">VAT-OUT-00-CC</field>
- <field name="name">VAT 0% Cocontractant</field>
+ <field name="name">TVA 0% Cocontractant</field>
<field name="price_include" eval="0"/>
<field name="amount">0</field>
<field name="amount_type">percent</field>
@@ -202,7 +202,7 @@
<record id="attn_VAT-OUT-00-EU-S" model="account.tax.template">
<field name="sequence">60</field>
<field name="description">VAT-OUT-00-EU-S</field>
- <field name="name">Services EU</field>
+ <field name="name">TVA services EU</field>
<field name="price_include" eval="0"/>
<field name="amount">0</field>
<field name="amount_type">percent</field>
@@ -213,7 +213,7 @@
<record id="attn_VAT-OUT-00-EU-L" model="account.tax.template">
<field name="sequence">61</field>
<field name="description">VAT-OUT-00-EU-L</field>
- <field name="name">Marchandises EU (Code L)</field>
+ <field name="name">TVA Marchandises EU (Code L)</field>
<field name="price_include" eval="0"/>
<field name="amount">0</field>
<field name="amount_type">percent</field>
@@ -224,7 +224,7 @@
<record id="attn_VAT-OUT-00-EU-T" model="account.tax.template">
<field name="sequence">62</field>
<field name="description">VAT-OUT-00-EU-T</field>
- <field name="name">Marchandises EU (Code T)</field>
+ <field name="name">TVA marchandises EU (Code T)</field>
<field name="price_include" eval="0"/>
<field name="amount">0</field>
<field name="amount_type">percent</field>
@@ -235,7 +235,7 @@
<record id="attn_VAT-OUT-00-ROW" model="account.tax.template">
<field name="sequence">70</field>
<field name="description">VAT-OUT-00-ROW</field>
- <field name="name">Export hors EU</field>
+ <field name="name">TVA export hors EU</field>
<field name="price_include" eval="0"/>
<field name="amount">0</field>
<field name="amount_type">percent</field>
@@ -818,7 +818,7 @@
<record id="attn_VAT-IN-V82-CAR-EXC-C1" model="account.tax.template">
<field name="sequence">721</field>
<field name="description">VAT-IN-V82-CAR-EXC-C1</field>
- <field name="name">Frais de voiture - VAT 50% Non Deductible</field>
+ <field name="name">Frais de voiture - TVA 50% Non Deductible</field>
<field name="refund_account_id" ref="a64012"/>
<field name="account_id" ref="a64012"/>
<field name="price_include" eval="0"/>
@@ -831,7 +831,7 @@
<record id="attn_VAT-IN-V82-CAR-EXC-C2" model="account.tax.template">
<field name="sequence">722</field>
<field name="description">VAT-IN-V82-CAR-EXC-C2</field>
- <field name="name">Frais de voiture - VAT 50% Deductible (Price Excl.)</field>
+ <field name="name">Frais de voiture - TVA 50% Deductible (Prix Excl.)</field>
<field name="refund_account_id" ref="a411059"/>
<field name="account_id" ref="a411059"/>
<field name="price_include" eval="0"/>
diff --git a/addons/l10n_be_coda/l10n_be_coda_demo.xml b/addons/l10n_be_coda/l10n_be_coda_demo.xml
index 8faadd6afc7..e5fb1c6e73c 100644
--- a/addons/l10n_be_coda/l10n_be_coda_demo.xml
+++ b/addons/l10n_be_coda/l10n_be_coda_demo.xml
@@ -14,6 +14,7 @@
<field name="partner_id" ref="base.res_partner_9"/>
<field name="reference_type">bba</field>
<field name="reference">+++240/2838/42818+++</field>
+ <field name="date_invoice">2011-01-20</field>
</record>
<record id="invoice_1_line_1" model="account.invoice.line">
<field name="name">Dell Inspiron Laptop without OS</field>
diff --git a/addons/mrp_byproduct/mrp_byproduct.py b/addons/mrp_byproduct/mrp_byproduct.py
index 174b0da5d2d..982723cc85c 100644
--- a/addons/mrp_byproduct/mrp_byproduct.py
+++ b/addons/mrp_byproduct/mrp_byproduct.py
@@ -76,23 +76,15 @@ class mrp_production(osv.osv):
for sub_product in production.bom_id.sub_products:
product_uom_factor = product_uom_obj._compute_qty(cr, uid, production.product_uom.id, production.product_qty, production.bom_id.product_uom.id)
qty1 = sub_product.product_qty
- qty2 = production.product_uos and production.product_uos_qty or False
- product_uos_factor = 0.0
- if qty2 and production.bom_id.product_uos.id:
- product_uos_factor = product_uom_obj._compute_qty(cr, uid, production.product_uos.id, production.product_uos_qty, production.bom_id.product_uos.id)
if sub_product.subproduct_type == 'variable':
if production.product_qty:
qty1 *= product_uom_factor / (production.bom_id.product_qty or 1.0)
- if production.product_uos_qty:
- qty2 *= product_uos_factor / (production.bom_id.product_uos_qty or 1.0)
data = {
'name': 'PROD:'+production.name,
'date': production.date_planned,
'product_id': sub_product.product_id.id,
'product_uom_qty': qty1,
'product_uom': sub_product.product_uom.id,
- 'product_uos_qty': qty2,
- 'product_uos': production.product_uos and production.product_uos.id or False,
'location_id': source,
'location_dest_id': production.location_dest_id.id,
'move_dest_id': production.move_prod_id.id,
diff --git a/addons/pad/pad.py b/addons/pad/pad.py
index 2cd22e0f6ca..0199368327a 100644
--- a/addons/pad/pad.py
+++ b/addons/pad/pad.py
@@ -36,7 +36,7 @@ class pad_common(osv.osv_memory):
pad["server"] = pad["server"].rstrip('/')
# generate a salt
s = string.ascii_uppercase + string.digits
- salt = ''.join([s[random.randint(0, len(s) - 1)] for i in range(10)])
+ salt = ''.join([s[random.SystemRandom().randint(0, len(s) - 1)] for i in range(10)])
#path
# etherpad hardcodes pad id length limit to 50
path = '-%s-%s' % (self._name, salt)
diff --git a/addons/payment/models/payment_acquirer.py b/addons/payment/models/payment_acquirer.py
index 1a248849430..5da97735e5a 100644
--- a/addons/payment/models/payment_acquirer.py
+++ b/addons/payment/models/payment_acquirer.py
@@ -389,7 +389,7 @@ class PaymentTransaction(osv.Model):
('done', 'Done'), ('error', 'Error'),
('cancel', 'Canceled')
], 'Status', required=True,
- track_visiblity='onchange', copy=False),
+ track_visibility='onchange', copy=False),
'state_message': fields.text('Message',
help='Field used to store error and/or validation messages for information'),
# payment
diff --git a/addons/payment_ogone/controllers/main.py b/addons/payment_ogone/controllers/main.py
index 6443e85f426..451c3683aaa 100644
--- a/addons/payment_ogone/controllers/main.py
+++ b/addons/payment_ogone/controllers/main.py
@@ -44,7 +44,7 @@ class OgoneController(http.Controller):
acquirer.s2s_process(post)
return werkzeug.utils.redirect(post.get('return_url', '/'))
- @http.route(['/payment/ogone/s2s/feedback'])
+ @http.route(['/payment/ogone/s2s/feedback'], auth='none')
def feedback(self, **kwargs):
cr, uid, context = request.cr, SUPERUSER_ID, request.context
payment = request.registry.get('payment.transaction')
diff --git a/addons/payment_ogone/models/ogone.py b/addons/payment_ogone/models/ogone.py
index aafe2e1f438..40bd0e2a974 100644
--- a/addons/payment_ogone/models/ogone.py
+++ b/addons/payment_ogone/models/ogone.py
@@ -373,11 +373,12 @@ class PaymentTxOgone(osv.Model):
def _ogone_s2s_validate(self, tx):
tree = self._ogone_s2s_get_tx_status(tx)
- return self.ogone_s2s_validate(tx, tree)
+ return self._ogone_s2s_validate_tree(tx, tree)
def _ogone_s2s_validate_tree(self, tx, tree, tries=2):
if tx.state not in ('draft', 'pending'):
- return True # already validated
+ _logger.info('Ogone: trying to validate an already validated tx (ref %s)', tx.reference)
+ return True
status = int(tree.get('STATUS', '0'))
if status in self._ogone_valid_tx_status:
diff --git a/addons/point_of_sale/i18n/point_of_sale.pot b/addons/point_of_sale/i18n/point_of_sale.pot
index 70bef66fd69..2a0dd7b1ba6 100644
--- a/addons/point_of_sale/i18n/point_of_sale.pot
+++ b/addons/point_of_sale/i18n/point_of_sale.pot
@@ -3867,6 +3867,13 @@ msgstr ""
#. module: point_of_sale
#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:914
+#, python-format
+msgid "Unknown Customer"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:845
#, python-format
msgid "Unknown Product"
diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml
index c36adc1c164..319966757bb 100644
--- a/addons/point_of_sale/static/src/xml/pos.xml
+++ b/addons/point_of_sale/static/src/xml/pos.xml
@@ -1232,7 +1232,6 @@
</span>
</t>
</t>
-
</span>
<span class="order-button square neworder-button">
<i class='fa fa-plus' />
diff --git a/addons/product/i18n/product.pot b/addons/product/i18n/product.pot
index 22559f142ce..1817e4ae649 100644
--- a/addons/product/i18n/product.pot
+++ b/addons/product/i18n/product.pot
@@ -3265,11 +3265,6 @@ msgid "lb(s)"
msgstr ""
#. module: product
-#: view:product.product:product.product_normal_form_view
-msgid "lst_price"
-msgstr ""
-
-#. module: product
#: model:product.uom,name:product.product_uom_mile
msgid "mile(s)"
msgstr ""
diff --git a/addons/product_margin/product_margin.py b/addons/product_margin/product_margin.py
index 3a12bb807b3..c3a67e2d662 100644
--- a/addons/product_margin/product_margin.py
+++ b/addons/product_margin/product_margin.py
@@ -9,6 +9,39 @@ from openerp.osv import fields, osv
class product_product(osv.osv):
_inherit = "product.product"
+ def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False, lazy=True):
+ """
+ Inherit read_group to calculate the sum of the non-stored fields, as it is not automatically done anymore through the XML.
+ """
+ res = super(product_product, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby, lazy=lazy)
+ if context is None:
+ context = {}
+ fields_list = ['turnover', 'sale_avg_price', 'sale_purchase_price', 'sale_num_invoiced', 'purchase_num_invoiced',
+ 'sales_gap', 'purchase_gap', 'total_cost', 'sale_expected', 'normal_cost', 'total_margin',
+ 'expected_margin', 'total_margin_rate', 'expected_margin_rate']
+ if any(x in fields for x in fields_list):
+ # Calculate first for every product in which line it needs to be applied
+ re_ind = 0
+ prod_re = {}
+ tot_products = []
+ for re in res:
+ if re.get('__domain'):
+ products = self.search(cr, uid, re['__domain'], context=context)
+ tot_products += products
+ for prod in products:
+ prod_re[prod] = re_ind
+ re_ind += 1
+
+ res_val = self._product_margin(cr, uid, tot_products, [x for x in fields if fields in fields_list], '', context=context)
+ for key in res_val.keys():
+ for l in res_val[key].keys():
+ re = res[prod_re[key]]
+ if re.get(l):
+ re[l] += res_val[key][l]
+ else:
+ re[l] = res_val[key][l]
+ return res
+
def _product_margin(self, cr, uid, ids, field_names, arg, context=None):
res = {}
if context is None:
@@ -47,7 +80,7 @@ class product_product(osv.osv):
from account_invoice_line l
left join account_invoice i on (l.invoice_id = i.id)
left join product_product product on (product.id=l.product_id)
- left join product_template pt on (pt.id = l.product_id)
+ left join product_template pt on (pt.id = product.product_tmpl_id)
left join product_uom pu on (pt.uom_id = pu.id)
left join product_uom pu2 on (l.uos_id = pu2.id)
where l.product_id = %s and i.state in %s and i.type IN %s and (i.date_invoice IS NULL or (i.date_invoice>=%s and i.date_invoice<=%s and i.company_id=%s))
diff --git a/addons/product_margin/product_margin_view.xml b/addons/product_margin/product_margin_view.xml
index d4919276e50..972765806f6 100644
--- a/addons/product_margin/product_margin_view.xml
+++ b/addons/product_margin/product_margin_view.xml
@@ -7,7 +7,7 @@
<field name="priority" eval="50"/>
<field name="arch" type="xml">
<graph string="Product Margins" type="bar">
- <field name="name"/>
+ <field name="product_tmpl_id"/>
<field name="turnover" operator="+"/>
<field name="total_cost" operator="+"/>
</graph>
diff --git a/addons/purchase/partner_view.xml b/addons/purchase/partner_view.xml
index 48c71ceec93..a724d5e029f 100644
--- a/addons/purchase/partner_view.xml
+++ b/addons/purchase/partner_view.xml
@@ -88,7 +88,7 @@
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="priority" eval="20"/>
- <field name="groups_id" eval="[(4, ref('account.group_account_user'))]"/>
+ <field name="groups_id" eval="[(4, ref('account.group_account_invoice'))]"/>
<field name="arch" type="xml">
<div name="button_box" position="inside">
<button class="oe_stat_button" name="%(purchase.act_res_partner_2_supplier_invoices)d" type="action"
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index f59767c87c6..3085f221c09 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -998,6 +998,30 @@ class purchase_order(osv.osv):
return orders_info
+ def _set_po_lines_invoiced(self, cr, uid, ids, context=None):
+ for po in self.browse(cr, uid, ids, context=context):
+ is_invoiced = []
+ if po.invoice_method == 'picking':
+ # We determine the invoiced state of the PO line based on the invoiced state
+ # of the associated moves. This should cover all possible cases:
+ # - all moves are done and invoiced
+ # - a PO line is split into multiple moves (e.g. if multiple pickings): some
+ # pickings are done, some are in progress, some are cancelled
+ for po_line in po.order_line:
+ if (po_line.move_ids and
+ all(move.state in ('done', 'cancel') for move in po_line.move_ids) and
+ not all(move.state == 'cancel' for move in po_line.move_ids) and
+ all(move.invoice_state == 'invoiced' for move in po_line.move_ids if move.state == 'done')):
+ is_invoiced.append(po_line.id)
+ else:
+ for po_line in po.order_line:
+ if (po_line.invoice_lines and
+ all(line.invoice_id.state not in ['draft', 'cancel'] for line in po_line.invoice_lines)):
+ is_invoiced.append(po_line.id)
+ if is_invoiced:
+ self.pool['purchase.order.line'].write(cr, uid, is_invoiced, {'invoiced': True})
+ workflow.trg_write(uid, 'purchase.order', po.id, cr)
+
class purchase_order_line(osv.osv):
def _amount_line(self, cr, uid, ids, prop, arg, context=None):
@@ -1118,6 +1142,9 @@ class purchase_order_line(osv.osv):
res = {'value': {'price_unit': price_unit or 0.0, 'name': name or '', 'product_uom' : uom_id or False}}
if not product_id:
+ if not uom_id:
+ uom_id = self.default_get(cr, uid, ['product_uom'], context=context).get('product_uom', False)
+ res['value']['product_uom'] = uom_id
return res
product_product = self.pool.get('product.product')
@@ -1740,22 +1767,9 @@ class account_invoice(osv.Model):
else:
user_id = uid
po_ids = purchase_order_obj.search(cr, user_id, [('invoice_ids', 'in', ids)], context=context)
- for order in purchase_order_obj.browse(cr, user_id, po_ids, context=context):
- purchase_order_obj.message_post(cr, user_id, order.id, body=_("Invoice received"), context=context)
- invoiced = []
- shipped = True
- # for invoice method manual or order, don't care about shipping state
- # for invoices based on incoming shippment, beware of partial deliveries
- if (order.invoice_method == 'picking' and
- not all(picking.invoice_state in ['invoiced'] for picking in order.picking_ids)):
- shipped = False
- for po_line in order.order_line:
- if (po_line.invoice_lines and
- all(line.invoice_id.state not in ['draft', 'cancel'] for line in po_line.invoice_lines)):
- invoiced.append(po_line.id)
- if invoiced and shipped:
- self.pool['purchase.order.line'].write(cr, user_id, invoiced, {'invoiced': True})
- workflow.trg_write(user_id, 'purchase.order', order.id, cr)
+ for po_id in po_ids:
+ purchase_order_obj.message_post(cr, user_id, po_id, body=_("Invoice received"), context=context)
+ purchase_order_obj._set_po_lines_invoiced(cr, user_id, [po_id], context=context)
return res
def confirm_paid(self, cr, uid, ids, context=None):
diff --git a/addons/purchase/stock.py b/addons/purchase/stock.py
index b0e40275637..eee573c8e53 100644
--- a/addons/purchase/stock.py
+++ b/addons/purchase/stock.py
@@ -27,15 +27,23 @@ class stock_move(osv.osv):
res = super(stock_move, self).write(cr, uid, ids, vals, context=context)
from openerp import workflow
if vals.get('state') in ['done', 'cancel']:
+ po_to_check = []
for move in self.browse(cr, uid, ids, context=context):
if move.purchase_line_id and move.purchase_line_id.order_id:
- order_id = move.purchase_line_id.order_id.id
+ order = move.purchase_line_id.order_id
+ order_id = order.id
# update linked purchase order as superuser as the warehouse
# user may not have rights to access purchase.order
if self.pool.get('purchase.order').test_moves_done(cr, uid, [order_id], context=context):
workflow.trg_validate(SUPERUSER_ID, 'purchase.order', order_id, 'picking_done', cr)
if self.pool.get('purchase.order').test_moves_except(cr, uid, [order_id], context=context):
workflow.trg_validate(SUPERUSER_ID, 'purchase.order', order_id, 'picking_cancel', cr)
+ if order_id not in po_to_check and vals['state'] == 'cancel' and order.invoice_method == 'picking':
+ po_to_check.append(order_id)
+ # Some moves which are cancelled might be part of a PO line which is partially
+ # invoiced, so we check if some PO line can be set on "invoiced = True".
+ if po_to_check:
+ self.pool.get('purchase.order')._set_po_lines_invoiced(cr, uid, po_to_check, context=context)
return res
def copy(self, cr, uid, id, default=None, context=None):
diff --git a/addons/purchase/wizard/purchase_line_invoice.py b/addons/purchase/wizard/purchase_line_invoice.py
index 39c5f1b9f3d..4e1d8c96c26 100644
--- a/addons/purchase/wizard/purchase_line_invoice.py
+++ b/addons/purchase/wizard/purchase_line_invoice.py
@@ -12,6 +12,41 @@ class purchase_line_invoice(osv.osv_memory):
_name = 'purchase.order.line_invoice'
_description = 'Purchase Order Line Make Invoice'
+ def _make_invoice_by_partner(self, cr, uid, partner, orders, lines_ids, context=None):
+ """
+ create a new invoice for one vendor
+ @param cr : Cursor
+ @param uid : Id of current user
+ @param partner : The object partner
+ @param orders : The set of orders to add in the invoice
+ @param lines : The list of line's id
+ """
+ purchase_obj = self.pool.get('purchase.order')
+ account_jrnl_obj = self.pool.get('account.journal')
+ invoice_obj = self.pool.get('account.invoice')
+ name = orders and orders[0].name or ''
+ journal_id = account_jrnl_obj\
+ .search(cr, uid, [('type', '=', 'purchase')], context=None)
+ journal_id = journal_id and journal_id[0] or False
+ a = partner.property_account_payable_id.id
+ inv = {
+ 'name': name,
+ 'origin': name,
+ 'type': 'in_invoice',
+ 'journal_id': journal_id,
+ 'reference': partner.ref,
+ 'account_id': a,
+ 'partner_id': partner.id,
+ 'invoice_line_ids': [(6, 0, lines_ids)],
+ 'currency_id': orders[0].currency_id.id,
+ 'comment': " \n".join([order.notes for order in orders if order.notes]),
+ 'payment_term_id': orders[0].payment_term_id.id,
+ 'fiscal_position_id': partner.property_account_position_id.id
+ }
+ inv_id = invoice_obj.create(cr, uid, inv, context=context)
+ purchase_obj.write(cr, uid, [order.id for order in orders], {'invoice_ids': [(4, inv_id)]}, context=context)
+ return inv_id
+
def makeInvoices(self, cr, uid, ids, context=None):
"""
@@ -30,49 +65,9 @@ class purchase_line_invoice(osv.osv_memory):
if record_ids:
res = False
invoices = {}
- invoice_obj = self.pool.get('account.invoice')
purchase_obj = self.pool.get('purchase.order')
purchase_line_obj = self.pool.get('purchase.order.line')
invoice_line_obj = self.pool.get('account.invoice.line')
- account_jrnl_obj = self.pool.get('account.journal')
-
- def multiple_order_invoice_notes(orders):
- notes = ""
- for order in orders:
- notes += "%s \n" % order.notes
- return notes
-
-
-
- def make_invoice_by_partner(partner, orders, lines_ids):
- """
- create a new invoice for one vendor
- @param partner : The object partner
- @param orders : The set of orders to add in the invoice
- @param lines : The list of line's id
- """
- name = orders and orders[0].name or ''
- journal_id = account_jrnl_obj.search(cr, uid, [('type', '=', 'purchase')], context=None)
- journal_id = journal_id and journal_id[0] or False
- a = partner.property_account_payable_id.id
- inv = {
- 'name': name,
- 'origin': name,
- 'type': 'in_invoice',
- 'journal_id':journal_id,
- 'reference' : partner.ref,
- 'account_id': a,
- 'partner_id': partner.id,
- 'invoice_line_ids': [(6, 0, lines_ids)],
- 'currency_id' : orders[0].currency_id.id,
- 'comment': multiple_order_invoice_notes(orders),
- 'payment_term_id': orders[0].payment_term_id.id,
- 'fiscal_position_id': partner.property_account_position_id.id
- }
- inv_id = invoice_obj.create(cr, uid, inv)
- for order in orders:
- order.write({'invoice_ids': [(4, inv_id)]})
- return inv_id
for line in purchase_line_obj.browse(cr, uid, record_ids, context=context):
if (not line.invoiced) and (line.state not in ('draft', 'cancel')):
@@ -90,7 +85,7 @@ class purchase_line_invoice(osv.osv_memory):
il = map(lambda x: x[1], result)
orders = list(set(map(lambda x : x[0].order_id, result)))
- res.append(make_invoice_by_partner(orders[0].partner_id, orders, il))
+ res.append(self._make_invoice_by_partner(cr, uid, orders[0].partner_id, orders, il, context=context))
return {
'domain': "[('id','in', ["+','.join(map(str,res))+"])]",
diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py
index 8caa269b7fe..20153d61712 100644
--- a/addons/sale/res_config.py
+++ b/addons/sale/res_config.py
@@ -71,6 +71,8 @@ Example: 10% for retailers, promotion of 5 EUR on this product, etc."""),
return {}
def onchange_task_work(self, cr, uid, ids, task_work, context=None):
+ if not task_work:
+ return {'value': {}}
return {'value': {
'module_project_timesheet': task_work,
'module_sale_service': task_work,
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index df53b4dd97c..17a99268f31 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -3,6 +3,7 @@
from datetime import datetime, timedelta
import time
+from openerp import SUPERUSER_ID
from openerp.addons.analytic.models import analytic
from openerp.osv import fields, osv
from openerp.tools.translate import _
@@ -1057,7 +1058,14 @@ class sale_order_line(osv.osv):
else:
fpos = self.pool['account.fiscal.position'].browse(cr, uid, fiscal_position_id)
if update_tax: # The quantity only have changed
- result['tax_id'] = self.pool['account.fiscal.position'].map_tax(cr, uid, fpos, product_obj.taxes_id)
+ # The superuser is used by website_sale in order to create a sale order. We need to make
+ # sure we only select the taxes related to the company of the partner. This should only
+ # apply if the partner is linked to a company.
+ if uid == SUPERUSER_ID and partner.company_id:
+ taxes = product_obj.taxes_id.filtered(lambda r: r.company_id == partner.company_id)
+ else:
+ taxes = product_obj.taxes_id
+ result['tax_id'] = self.pool['account.fiscal.position'].map_tax(cr, uid, fpos, taxes)
if not flag:
result['name'] = Product.name_get(cr, uid, [product_obj.id], context=ctx_product)[0][1]
diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py
index 4882bb3ac85..fbccaa4efa7 100644
--- a/addons/sale_stock/sale_stock.py
+++ b/addons/sale_stock/sale_stock.py
@@ -401,6 +401,8 @@ class stock_move(osv.osv):
fp = move.picking_id.sale_id.fiscal_position
res = self.pool.get("account.invoice.line").product_id_change(cr, uid, [], move.product_id.id, None, partner_id=move.picking_id.partner_id.id, fposition_id=(fp and fp.id), context=context)
extra_move_tax[0, move.product_id] = [(6, 0, res['value']['invoice_line_tax_ids'])]
+ else:
+ extra_move_tax[0, move.product_id] = [(6, 0, [x.id for x in move.product_id.product_tmpl_id.taxes_id])]
return (is_extra_move, extra_move_tax)
def _get_taxes(self, cr, uid, move, context=None):
diff --git a/addons/sales_team/sales_team.py b/addons/sales_team/sales_team.py
index 957afa9f3f5..4defeb4868d 100644
--- a/addons/sales_team/sales_team.py
+++ b/addons/sales_team/sales_team.py
@@ -43,7 +43,7 @@ class crm_team(osv.Model):
'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True, string="Full Name"),
'code': fields.char('Code', size=8),
'active': fields.boolean('Active', help="If the active field is set to "\
- "true, it will allow you to hide the sales team without removing it."),
+ "false, it will allow you to hide the sales team without removing it."),
'company_id': fields.many2one('res.company', 'Company'),
'user_id': fields.many2one('res.users', 'Team Leader'),
'member_ids': fields.many2many('res.users', 'sale_member_rel', 'team_id', 'member_id', 'Team Members'),
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index f9f025f5124..f3af62a583f 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -3421,11 +3421,11 @@ class stock_warehouse(osv.osv):
seq_obj = self.pool.get('ir.sequence')
picking_type_obj = self.pool.get('stock.picking.type')
#create new sequences
- in_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': warehouse.name + _(' Sequence in'), 'prefix': warehouse.code + '/IN/', 'padding': 5}, context=context)
- out_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': warehouse.name + _(' Sequence out'), 'prefix': warehouse.code + '/OUT/', 'padding': 5}, context=context)
- pack_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': warehouse.name + _(' Sequence packing'), 'prefix': warehouse.code + '/PACK/', 'padding': 5}, context=context)
- pick_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': warehouse.name + _(' Sequence picking'), 'prefix': warehouse.code + '/PICK/', 'padding': 5}, context=context)
- int_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': warehouse.name + _(' Sequence internal'), 'prefix': warehouse.code + '/INT/', 'padding': 5}, context=context)
+ in_seq_id = seq_obj.create(cr, SUPERUSER_ID, {'name': warehouse.name + _(' Sequence in'), 'prefix': warehouse.code + '/IN/', 'padding': 5}, context=context)
+ out_seq_id = seq_obj.create(cr, SUPERUSER_ID, {'name': warehouse.name + _(' Sequence out'), 'prefix': warehouse.code + '/OUT/', 'padding': 5}, context=context)
+ pack_seq_id = seq_obj.create(cr, SUPERUSER_ID, {'name': warehouse.name + _(' Sequence packing'), 'prefix': warehouse.code + '/PACK/', 'padding': 5}, context=context)
+ pick_seq_id = seq_obj.create(cr, SUPERUSER_ID, {'name': warehouse.name + _(' Sequence picking'), 'prefix': warehouse.code + '/PICK/', 'padding': 5}, context=context)
+ int_seq_id = seq_obj.create(cr, SUPERUSER_ID, {'name': warehouse.name + _(' Sequence internal'), 'prefix': warehouse.code + '/INT/', 'padding': 5}, context=context)
wh_stock_loc = warehouse.lot_stock_id
wh_input_stock_loc = warehouse.wh_input_stock_loc_id
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 18349e2cab5..80012b0b882 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -690,7 +690,7 @@
<button name="action_confirm" states="draft" string="Mark as Todo" type="object" class="oe_highlight" groups="base.group_user"/>
<button name="do_new_transfer" states="draft,partially_available,assigned" string="Validate" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
<button name="action_assign" states="confirmed,waiting" string="Reserve" type="object" class="oe_highlight" groups="base.group_user"/>
- <button name="rereserve_pick" states="waiting,partially_available" string="Recheck Reservation" type="object" class="oe_highlight" groups="base.group_user"/>
+ <button name="rereserve_pick" string="Recheck Availability" type="object" class="oe_highlight" groups="base.group_user" attrs="{'invisible': ['|', ('state', 'not in', ('waiting', 'partially_available')), ('pack_operation_exist','=',True)]}"/>
<button name="force_assign" states="confirmed,waiting,partially_available" string="Force Availability" type="object" groups="base.group_user"/>
<button name="do_print_picking" string="Print Picking List" groups="stock.group_stock_user" type="object" attrs="{'invisible': [('state', 'not in', ('assigned', 'partially_available'))]}"/>
<button name="%(act_stock_return_picking)d" string="Reverse Transfer" states="done" type="action" groups="base.group_user"/>
@@ -1246,6 +1246,9 @@
<group name="quants_grp" string="Reserved Quants" colspan="2" groups="base.group_no_one">
<field name="string_availability_info"/>
</group>
+ <group name="moved_quants_grp" string="Moved Quants" colspan="4" groups="base.group_no_one" attrs="{'invisible': [('state', '!=', 'done')]}">
+ <field name="quant_ids" readonly="1" nolabel="1"/>
+ </group>
</group>
</sheet>
</form>
@@ -1299,6 +1302,9 @@
<group name="quants_grp" string="Reserved">
<field name="string_availability_info"/>
</group>
+ <group name="moved_quants_grp" string="Moved Quants" colspan="4" groups="base.group_no_one" attrs="{'invisible': [('state', '!=', 'done')]}">
+ <field name="quant_ids" readonly="1" nolabel="1"/>
+ </group>
</group>
</form>
</field>
diff --git a/addons/web_calendar/static/src/js/web_calendar.js b/addons/web_calendar/static/src/js/web_calendar.js
index 12743efd33a..d5e28979d2d 100644
--- a/addons/web_calendar/static/src/js/web_calendar.js
+++ b/addons/web_calendar/static/src/js/web_calendar.js
@@ -723,9 +723,9 @@ var CalendarView = View.extend({
var color_field = self.fields[self.color_field];
_.each(events, function (e) {
var key,val = null;
- if (self.fields[self.color_field].type == "selection") {
+ if (color_field.type == "selection") {
key = e[self.color_field];
- val = _.find( self.fields[self.color_field].selection, function(name){ return name[0] === key;});
+ val = _.find(color_field.selection, function(name){ return name[0] === key;});
} else {
key = e[self.color_field][0];
val = e[self.color_field];
@@ -750,7 +750,7 @@ var CalendarView = View.extend({
self.sidebar.filter.set_filters();
events = $.map(events, function (e) {
- var key = self.fields[self.color_field].type == "selection" ? e[self.color_field] : e[self.color_field][0];
+ var key = color_field.type == "selection" ? e[self.color_field] : e[self.color_field][0];
if (_.contains(self.now_filter_ids, key) && self.all_filters[key].is_checked) {
return e;
}
diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index 49e164c99bb..ed655b5a051 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -365,6 +365,9 @@ class website_sale(http.Controller):
return {}
value = order._cart_update(product_id=product_id, line_id=line_id, add_qty=add_qty, set_qty=set_qty)
+ if not order.cart_quantity:
+ request.website.sale_reset()
+ return {}
if not display:
return None
value['cart_quantity'] = order.cart_quantity
@@ -882,6 +885,8 @@ class website_sale(http.Controller):
# clean context and session, then redirect to the confirmation page
request.website.sale_reset(context=context)
+ if tx and tx.state == 'draft':
+ return request.redirect('/shop')
return request.redirect('/shop/confirmation')
diff --git a/addons/website_sale/static/src/js/website_sale_tracking.js b/addons/website_sale/static/src/js/website_sale_tracking.js
index 0e06d49cd74..52d65a468fc 100644
--- a/addons/website_sale/static/src/js/website_sale_tracking.js
+++ b/addons/website_sale/static/src/js/website_sale_tracking.js
@@ -64,7 +64,7 @@ $(document).ready(function () {
}
function track_ga() {
- website_ga = this._gaw || function(){};
+ website_ga = this.ga || function(){};
website_ga.apply(this, arguments);
}
diff --git a/addons/website_sale_delivery/__openerp__.py b/addons/website_sale_delivery/__openerp__.py
index 099f6e6e264..6c160778ee0 100644
--- a/addons/website_sale_delivery/__openerp__.py
+++ b/addons/website_sale_delivery/__openerp__.py
@@ -16,7 +16,7 @@ Delivery Costs
'security/ir.model.access.csv',
],
'demo': [
- 'demo/website_sale_delivery_demo.xml',
+ 'data/website_sale_delivery_demo.xml'
],
'qweb': [],
'installable': True,
diff --git a/addons/website_sale_delivery/data/website_sale_delivery_demo.xml b/addons/website_sale_delivery/data/website_sale_delivery_demo.xml
new file mode 100644
index 00000000000..1be5cdcd156
--- /dev/null
+++ b/addons/website_sale_delivery/data/website_sale_delivery_demo.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data noupdate="1">
+
+ <record id="delivery.delivery_carrier" model="delivery.carrier">
+ <field name="website_published" eval="True" />
+ </record>
+
+ <record id="delivery.normal_delivery_carrier" model="delivery.carrier">
+ <field name="website_published" eval="True" />
+ </record>
+
+ </data>
+</odoo>
diff --git a/addons/website_sale_delivery/models/sale_order.py b/addons/website_sale_delivery/models/sale_order.py
index f63dd38d3f1..df240a6b07a 100644
--- a/addons/website_sale_delivery/models/sale_order.py
+++ b/addons/website_sale_delivery/models/sale_order.py
@@ -3,6 +3,8 @@
from openerp.osv import orm, fields
from openerp import SUPERUSER_ID
from openerp.addons import decimal_precision
+from openerp.exceptions import ValidationError
+from openerp.tools.translate import _
class delivery_carrier(orm.Model):
@@ -114,14 +116,22 @@ class SaleOrder(orm.Model):
# This can surely be done in a more efficient way, but at the moment, it mimics the way it's
# done in delivery_set method of sale.py, from delivery module
for delivery_id in carrier_obj.browse(cr, SUPERUSER_ID, delivery_ids, context=dict(context, order_id=order.id)):
- if not delivery_id.available:
+ try:
+ if not delivery_id.available:
+ delivery_ids.remove(delivery_id.id)
+ except ValidationError:
+ # RIM: hack to remove in master, because available field should not depend on a SOAP call to external shipping provider
+ # The validation error is used in backend to display errors in fedex config, but should fail silently in frontend
delivery_ids.remove(delivery_id.id)
return delivery_ids
def _get_errors(self, cr, uid, order, context=None):
errors = super(SaleOrder, self)._get_errors(cr, uid, order, context=context)
if not self._get_delivery_methods(cr, uid, order, context=context):
- errors.append(('No delivery method available', 'There is no available delivery method for your order'))
+ errors.append(
+ (_('Sorry, we are unable to ship your order'),
+ _('No shipping method is available for your current order and shipping address. '
+ 'Please contact us for more information.')))
return errors
def _get_website_data(self, cr, uid, order, context=None):
diff --git a/addons/website_slides/models/res_config.py b/addons/website_slides/models/res_config.py
index 664ee940d2c..4436c5aeb33 100644
--- a/addons/website_slides/models/res_config.py
+++ b/addons/website_slides/models/res_config.py
@@ -10,7 +10,7 @@ class website_config_settings(models.TransientModel):
website_slide_google_app_key = fields.Char(string='Google Doc Key')
@api.model
- def get_website_slide_google_app_key(self, fields):
+ def get_default_website_slide_google_app_key(self, fields):
website_slide_google_app_key = False
if 'website_slide_google_app_key' in fields:
website_slide_google_app_key = self.env['ir.config_parameter'].sudo().get_param('website_slides.google_app_key')
diff --git a/doc/cla/individual/anthony25.md b/doc/cla/individual/anthony25.md
new file mode 100644
index 00000000000..4c177cd135f
--- /dev/null
+++ b/doc/cla/individual/anthony25.md
@@ -0,0 +1,11 @@
+France, 07/30/2015
+
+I hereby agree to the terms of the Odoo Individual Contributor License
+Agreement v1.0.
+
+I declare that I am authorized and able to make this agreement and sign this
+declaration.
+
+Signed,
+
+Anthony Ruhier <anthony.ruhier@gmail.com> https://github.com/anthony25
diff --git a/doc/howtos/backend.rst b/doc/howtos/backend.rst
index 3077e087b99..45b02c60e80 100644
--- a/doc/howtos/backend.rst
+++ b/doc/howtos/backend.rst
@@ -623,7 +623,7 @@ instead of a single view its ``arch`` field is composed of any number of
<!-- improved idea categories list -->
<record id="idea_category_list2" model="ir.ui.view">
<field name="name">id.category.list2</field>
- <field name="model">idea.category/field>
+ <field name="model">idea.category</field>
<field name="inherit_id" ref="id_category_list"/>
<field name="arch" type="xml">
<!-- find field description inside tree, and add the field
diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py
index e5af3a85daa..151368de39e 100644
--- a/openerp/addons/base/ir/ir_translation.py
+++ b/openerp/addons/base/ir/ir_translation.py
@@ -292,7 +292,6 @@ class ir_translation(osv.osv):
def _set_ids(self, cr, uid, name, tt, lang, ids, value, src=None):
self.clear_caches()
- original_module = self.pool[name.split(',')[0]]._original_module
cr.execute('update ir_translation '
'set value=%s '
' , src=%s '
@@ -300,10 +299,9 @@ class ir_translation(osv.osv):
'where lang=%s '
'and type=%s '
'and name=%s '
- 'and module=%s '
'and res_id IN %s '
'returning res_id',
- (value,src,'translated',lang,tt,name,original_module,tuple(ids),))
+ (value,src,'translated',lang,tt,name,tuple(ids),))
existing_ids = [x[0] for x in cr.fetchall()]
@@ -313,7 +311,6 @@ class ir_translation(osv.osv):
'type':tt,
'name':name,
'res_id':id,
- 'module':original_module,
'value':value,
'src':src,
'state':'translated'
diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py
index f0e6214f622..5ad35924e8c 100644
--- a/openerp/addons/base/module/module.py
+++ b/openerp/addons/base/module/module.py
@@ -465,7 +465,7 @@ class module(osv.osv):
ir_model_data = self.pool.get('ir.model.data')
modules_to_remove = [m.name for m in self.browse(cr, uid, ids, context)]
ir_model_data._module_data_uninstall(cr, uid, modules_to_remove, context)
- self.write(cr, uid, ids, {'state': 'uninstalled'})
+ self.write(cr, uid, ids, {'state': 'uninstalled', 'latest_version': False})
return True
def downstream_dependencies(self, cr, uid, ids, known_dep_ids=None,
diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py
index 0fa3aba8aee..ce9c4cdd2a1 100644
--- a/openerp/addons/base/res/res_users.py
+++ b/openerp/addons/base/res/res_users.py
@@ -718,7 +718,7 @@ def parse_m2m(commands):
for command in commands:
if isinstance(command, (tuple, list)):
if command[0] in (1, 4):
- ids.append(command[2])
+ ids.append(command[1])
elif command[0] == 5:
ids = []
elif command[0] == 6:
diff --git a/openerp/addons/test_impex/tests/test_export.py b/openerp/addons/test_impex/tests/test_export.py
index 49a16387a3a..26f39db62e5 100644
--- a/openerp/addons/test_impex/tests/test_export.py
+++ b/openerp/addons/test_impex/tests/test_export.py
@@ -49,7 +49,7 @@ class test_integer_field(CreatorCase):
def test_0(self):
self.assertEqual(
self.export(0),
- [[False]])
+ [[u'0']])
def test_basic_value(self):
self.assertEqual(
@@ -72,7 +72,7 @@ class test_float_field(CreatorCase):
def test_0(self):
self.assertEqual(
self.export(0.0),
- [[False]])
+ [[u'0.0']])
def test_epsilon(self):
self.assertEqual(
@@ -100,14 +100,14 @@ class test_decimal_field(CreatorCase):
def test_0(self):
self.assertEqual(
self.export(0.0),
- [[False]])
+ [[u'0.0']])
def test_epsilon(self):
""" epsilon gets sliced to 0 due to precision
"""
self.assertEqual(
self.export(0.000000000027),
- [[False]])
+ [[u'0.0']])
def test_negative(self):
self.assertEqual(
@@ -129,7 +129,7 @@ class test_string_field(CreatorCase):
def test_empty(self):
self.assertEqual(
self.export(""),
- [[False]])
+ [['']])
def test_within_bounds(self):
self.assertEqual(
self.export("foobar"),
@@ -148,7 +148,7 @@ class test_unbound_string_field(CreatorCase):
def test_empty(self):
self.assertEqual(
self.export(""),
- [[False]])
+ [['']])
def test_small(self):
self.assertEqual(
self.export("foobar"),
@@ -170,7 +170,7 @@ class test_text(CreatorCase):
def test_empty(self):
self.assertEqual(
self.export(""),
- [[False]])
+ [['']])
def test_small(self):
self.assertEqual(
self.export("foobar"),
@@ -190,7 +190,7 @@ class test_date(CreatorCase):
def test_empty(self):
self.assertEqual(
self.export(False),
- [[False]])
+ [['']])
def test_basic(self):
self.assertEqual(
self.export('2011-11-07'),
@@ -202,7 +202,7 @@ class test_datetime(CreatorCase):
def test_empty(self):
self.assertEqual(
self.export(False),
- [[False]])
+ [['']])
def test_basic(self):
self.assertEqual(
self.export('2011-11-07 21:05:48'),
@@ -265,7 +265,7 @@ class test_selection_function(CreatorCase):
def test_empty(self):
self.assertEqual(
self.export(False),
- [[None]])
+ [['']])
def test_value(self):
# FIXME: selection functions export the *value* itself
@@ -278,7 +278,7 @@ class test_selection_function(CreatorCase):
# fucking hell
self.assertEqual(
self.export(0),
- [[None]])
+ [['']])
class test_m2o(CreatorCase):
model_name = 'export.many2one'
diff --git a/openerp/fields.py b/openerp/fields.py
index 449bbaf8d18..a0d3f59d4b7 100644
--- a/openerp/fields.py
+++ b/openerp/fields.py
@@ -761,9 +761,9 @@ class Field(object):
""" convert ``value`` from the cache to a valid value for export. The
parameter ``env`` is given for managing translations.
"""
- if env.context.get('export_raw_data'):
- return value
- return bool(value) and ustr(value)
+ if not value:
+ return ''
+ return value if env.context.get('export_raw_data') else ustr(value)
def convert_to_display_name(self, value, record=None):
""" convert ``value`` from the cache to a suitable display name. """
@@ -1015,6 +1015,11 @@ class Integer(Field):
# special case, when an integer field is used as inverse for a one2many
records._cache[self] = value.id or 0
+ def convert_to_export(self, value, env):
+ if value or value == 0:
+ return value if env.context.get('export_raw_data') else ustr(value)
+ return ''
+
class Float(Field):
""" The precision digits are given by the attribute
@@ -1062,6 +1067,11 @@ class Float(Field):
digits = self.digits
return float_round(value, precision_digits=digits[1]) if digits else value
+ def convert_to_export(self, value, env):
+ if value or value == 0.0:
+ return value if env.context.get('export_raw_data') else ustr(value)
+ return ''
+
class Monetary(Field):
""" The decimal precision and currency symbol are taken from the attribute
@@ -1152,11 +1162,6 @@ class _String(Field):
else:
return value
- def convert_to_export(self, value, env):
- if env.context.get('export_raw_data'):
- return value if value else None
- return bool(value) and ustr(value)
-
class Char(_String):
""" Basic string field, can be length-limited, usually displayed as a
@@ -1282,9 +1287,9 @@ class Date(Field):
return self.to_string(value)
def convert_to_export(self, value, env):
- if value and env.context.get('export_raw_data'):
- return self.from_string(value) or None
- return bool(value) and ustr(value)
+ if not value:
+ return ''
+ return self.from_string(value) if env.context.get('export_raw_data') else ustr(value)
class Datetime(Field):
@@ -1351,9 +1356,9 @@ class Datetime(Field):
return self.to_string(value)
def convert_to_export(self, value, env):
- if value and env.context.get('export_raw_data'):
- return self.from_string(value) or None
- return bool(value) and ustr(value)
+ if not value:
+ return ''
+ return self.from_string(value) if env.context.get('export_raw_data') else ustr(value)
def convert_to_display_name(self, value, record=None):
assert record, 'Record expected'
@@ -1461,7 +1466,7 @@ class Selection(Field):
def convert_to_export(self, value, env):
if not isinstance(self.selection, list):
# FIXME: this reproduces an existing buggy behavior!
- return value or None
+ return value if value else ''
for item in self._description_selection(env):
if item[0] == value:
return item[1]
@@ -1498,7 +1503,7 @@ class Reference(Selection):
return "%s,%s" % (value._name, value.id) if value else False
def convert_to_export(self, value, env):
- return value.name_get()[0][1] if value else None
+ return value.name_get()[0][1] if value else ''
def convert_to_display_name(self, value, record=None):
return ustr(value and value.display_name)
@@ -1638,7 +1643,7 @@ class Many2one(_Relational):
return value.id
def convert_to_export(self, value, env):
- return value.name_get()[0][1] if value else None
+ return value.name_get()[0][1] if value else ''
def convert_to_display_name(self, value, record=None):
return ustr(value.display_name)
@@ -1744,7 +1749,7 @@ class _RelationalMulti(_Relational):
return result
def convert_to_export(self, value, env):
- return ','.join(name for id, name in value.name_get()) if value else None
+ return ','.join(name for id, name in value.name_get()) if value else ''
def convert_to_display_name(self, value, record=None):
raise NotImplementedError()
diff --git a/openerp/models.py b/openerp/models.py
index a884d1ed3a2..c2433f21419 100644
--- a/openerp/models.py
+++ b/openerp/models.py
@@ -58,7 +58,7 @@ _logger = logging.getLogger(__name__)
_schema = logging.getLogger(__name__ + '.schema')
_unlink = logging.getLogger(__name__ + '.unlink')
-regex_order = re.compile('^( *([a-z0-9:_]+|"[a-z0-9:_]+")( *desc| *asc)?( *, *|))+$', re.I)
+regex_order = re.compile('^(\s*([a-z0-9:_]+|"[a-z0-9:_]+")(\s+(desc|asc))?\s*(,|$))+(?<!,)$', re.I)
regex_object_name = re.compile(r'^[a-z0-9_.]+$')
onchange_v7 = re.compile(r"^(\w+)\((.*)\)$")
@@ -3193,7 +3193,7 @@ class BaseModel(object):
result = self.read(list(fnames), load='_classic_write')
# check the cache, and update it if necessary
- if not self._cache.contains(field):
+ if field not in self._cache:
for values in result:
record = self.browse(values.pop('id'))
record._cache.update(record._convert_to_cache(values, validate=False))
diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py
index 0a21883e10d..7d4f59b77f9 100644
--- a/openerp/modules/loading.py
+++ b/openerp/modules/loading.py
@@ -122,7 +122,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
migrations.migrate_module(package, 'pre')
load_openerp_module(package.name)
- new_install = package.installed_version is None
+ new_install = package.state == 'to install'
if new_install:
py_module = sys.modules['openerp.addons.%s' % (module_name,)]
pre_init = package.info.get('pre_init_hook')
diff --git a/openerp/tests/common.py b/openerp/tests/common.py
index c591e8c7a68..17678cdbe1f 100644
--- a/openerp/tests/common.py
+++ b/openerp/tests/common.py
@@ -361,23 +361,6 @@ class HttpCase(TransactionCase):
openerp.tools.misc.dumpstacks()
t0 = t1
- def phantom_jsfile(self, jsfile, timeout=60, **kw):
- options = {
- 'timeout' : timeout,
- 'port': PORT,
- 'db': get_db_name(),
- 'session_id': self.session_id,
- }
- options.update(kw)
- phantomtest = os.path.join(os.path.dirname(__file__), 'phantomtest.js')
- # phantom.args[0] == phantomtest path
- # phantom.args[1] == options
- cmd = [
- 'phantomjs',
- jsfile, phantomtest, json.dumps(options)
- ]
- self.phantom_run(cmd, timeout)
-
def phantom_js(self, url_path, code, ready="window", login=None, timeout=60, **kw):
""" Test js code running in the browser
- optionnally log as 'login'