From 6c623b59b50ebfab781016c2b6449a439b6bbd32 Mon Sep 17 00:00:00 2001 From: JoshuaJan Date: Sun, 6 Jul 2014 17:41:07 +0800 Subject: [PATCH 01/23] skip the inactivate employee in leaves summary --- addons/hr_holidays/report/holidays_summary_report.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/hr_holidays/report/holidays_summary_report.py b/addons/hr_holidays/report/holidays_summary_report.py index 36087a57325..3f3a93d21a6 100644 --- a/addons/hr_holidays/report/holidays_summary_report.py +++ b/addons/hr_holidays/report/holidays_summary_report.py @@ -223,9 +223,7 @@ class report_custom(report_rml): elif data['model']=='ir.ui.menu': for id in data['form']['depts']: dept = obj_dept.browse(cr, uid, id, context=context) - cr.execute("""SELECT id FROM hr_employee \ - WHERE department_id = %s""", (id,)) - emp_ids = [x[0] for x in cr.fetchall()] + emp_ids = obj_emp.search(cr, uid, [('department_id', '=', id)]) if emp_ids==[]: continue dept_done=0 From ea470b67bf669684c69dfc27be7749fe7c62d3bf Mon Sep 17 00:00:00 2001 From: Hitesh Trivedi Date: Mon, 7 Jul 2014 12:00:19 +0530 Subject: [PATCH 02/23] [FIX]Display answers in order by posted date in descending (latest to old) --- addons/website_forum/models/forum.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index 1a7f68eb32a..ce4e2a7dac1 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -69,7 +69,7 @@ class Post(osv.Model): _name = 'forum.post' _description = 'Forum Post' _inherit = ['mail.thread', 'website.seo.metadata'] - _order = "is_correct DESC, vote_count DESC" + _order = "is_correct DESC, vote_count DESC, write_date DESC" def _get_user_vote(self, cr, uid, ids, field_name, arg, context): res = dict.fromkeys(ids, 0) From 9da1214de3a36f6909fe4dad0074f6fbd87efaea Mon Sep 17 00:00:00 2001 From: JoshuaJan Date: Mon, 7 Jul 2014 17:30:25 +0800 Subject: [PATCH 03/23] Update holidays_summary_report.py Add context to search method --- addons/hr_holidays/report/holidays_summary_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/hr_holidays/report/holidays_summary_report.py b/addons/hr_holidays/report/holidays_summary_report.py index 3f3a93d21a6..cf29e3abd01 100644 --- a/addons/hr_holidays/report/holidays_summary_report.py +++ b/addons/hr_holidays/report/holidays_summary_report.py @@ -223,7 +223,7 @@ class report_custom(report_rml): elif data['model']=='ir.ui.menu': for id in data['form']['depts']: dept = obj_dept.browse(cr, uid, id, context=context) - emp_ids = obj_emp.search(cr, uid, [('department_id', '=', id)]) + emp_ids = obj_emp.search(cr, uid, [('department_id', '=', id)], context) if emp_ids==[]: continue dept_done=0 From 6c776d54068ccfb2282925f7b513ba1f5191fd99 Mon Sep 17 00:00:00 2001 From: JoshuaJan Date: Mon, 7 Jul 2014 18:17:20 +0800 Subject: [PATCH 04/23] Update holidays_summary_report.py --- addons/hr_holidays/report/holidays_summary_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/hr_holidays/report/holidays_summary_report.py b/addons/hr_holidays/report/holidays_summary_report.py index cf29e3abd01..2aee179b13d 100644 --- a/addons/hr_holidays/report/holidays_summary_report.py +++ b/addons/hr_holidays/report/holidays_summary_report.py @@ -223,7 +223,7 @@ class report_custom(report_rml): elif data['model']=='ir.ui.menu': for id in data['form']['depts']: dept = obj_dept.browse(cr, uid, id, context=context) - emp_ids = obj_emp.search(cr, uid, [('department_id', '=', id)], context) + emp_ids = obj_emp.search(cr, uid, [('department_id', '=', id)], context=context) if emp_ids==[]: continue dept_done=0 From 90f7eaa0941b016b544cf1873c0ab55380264c27 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 7 Jul 2014 17:12:27 +0200 Subject: [PATCH 05/23] [FIX] portal: avoid errors during autovacuum When the cron for autovacuum runs, the osv_memory objects are deleted. The portal.wizard.user object has a required field (wizard_id) linked to another osv_memory object (portal.user) which causes a traceback when the cron tries to delete portal.user object before the portal.wizard.user. opw 609918 --- addons/portal/wizard/portal_wizard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/portal/wizard/portal_wizard.py b/addons/portal/wizard/portal_wizard.py index fb46533b559..0f9ad7a7073 100644 --- a/addons/portal/wizard/portal_wizard.py +++ b/addons/portal/wizard/portal_wizard.py @@ -116,7 +116,7 @@ class wizard_user(osv.osv_memory): _description = 'Portal User Config' _columns = { - 'wizard_id': fields.many2one('portal.wizard', string='Wizard', required=True), + 'wizard_id': fields.many2one('portal.wizard', string='Wizard', required=True, ondelete="cascade"), 'partner_id': fields.many2one('res.partner', string='Contact', required=True, readonly=True), 'email': fields.char(size=240, string='Email'), 'in_portal': fields.boolean('In Portal'), From c0aa86b9ab46068553b0bc6117da715743d7851f Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 8 May 2014 09:50:25 +0200 Subject: [PATCH 06/23] [FIX] configuration file dbfilter's option has no effect lp bug: https://launchpad.net/bugs/940439 fixed bzr revid: fme@openerp.com-20140508075025-yszqmzie1z4n7l4j --- openerp/tools/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tools/config.py b/openerp/tools/config.py index 71d1d015d91..3e7fc331e2c 100644 --- a/openerp/tools/config.py +++ b/openerp/tools/config.py @@ -154,7 +154,7 @@ class configmanager(object): # WEB # TODO move to web addons after MetaOption merge group = optparse.OptionGroup(parser, "Web interface Configuration") - group.add_option("--db-filter", dest="dbfilter", default='.*', + group.add_option("--db-filter", dest="dbfilter", my_default='.*', help="Filter listed database", metavar="REGEXP") parser.add_option_group(group) From 5207f12be0e5287913481702b96bfe7ad2379bf6 Mon Sep 17 00:00:00 2001 From: Atul Patel Date: Tue, 8 Jul 2014 16:11:28 +0530 Subject: [PATCH 07/23] [FIX]product: disable menu name come from report declaration.because it's called from wizard --- addons/product/product_report.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/product/product_report.xml b/addons/product/product_report.xml index 5d2c3b99f62..9c7ca7e390c 100644 --- a/addons/product/product_report.xml +++ b/addons/product/product_report.xml @@ -10,6 +10,6 @@ report_type="qweb-pdf" name="product.report_pricelist" file="product.report_pricelist" - /> + menu="False"/> From 6af3193d17021108f7501cfda824e7a1aecc8a85 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 8 Jul 2014 13:55:48 +0200 Subject: [PATCH 08/23] [FIX] ir.model.fields: better unlink When droping a column, remove also the relation table in case of custom m2m field. The relation table needs to be dropped otherwise an unremovable constraint to the targetted table is kept (and anyway is not needed anymore). --- openerp/addons/base/ir/ir_model.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index e7775b8ecbc..966f5e29077 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -312,6 +312,14 @@ class ir_model_fields(osv.osv): if column_name and (result and result[0] == 'r'): cr.execute('ALTER table "%s" DROP column "%s" cascade' % (model._table, field.name)) model._columns.pop(field.name, None) + + # remove m2m relation table for custom fields + # we consider the m2m relation is only one way as it's not possible + # to specify the relation table in the interface for custom fields + # TODO master: maybe use ir.model.relations for custom fields + if field.state == 'manual' and field.ttype == 'many2many': + rel_name = self.pool[field.model]._all_columns[field.name].column._rel + cr.execute('DROP table "%s"' % (rel_name)) return True def unlink(self, cr, user, ids, context=None): From 8b3d19921a825191fd71d9f41dc5b0d131116dea Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Tue, 8 Jul 2014 15:54:00 +0200 Subject: [PATCH 09/23] [FIX] Crm partner assign: Sort the partners by grade / published implemented. else the display are not explicit on website, because old order takes all the implemented partner but on website we display the number of reference published --- addons/website_crm_partner_assign/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_crm_partner_assign/controllers/main.py b/addons/website_crm_partner_assign/controllers/main.py index a880a83ad54..975914ad8ac 100644 --- a/addons/website_crm_partner_assign/controllers/main.py +++ b/addons/website_crm_partner_assign/controllers/main.py @@ -124,7 +124,7 @@ class WebsiteCrmPartnerAssign(http.Controller): context=request.context) # todo in trunk: order="grade_id DESC, implemented_count DESC", offset=pager['offset'], limit=self._references_per_page partners = partner_obj.browse(request.cr, SUPERUSER_ID, partner_ids, request.context) # remove me in trunk - partners.sort(key=lambda x: (-1 * (x.grade_id and x.grade_id.id or 0), len(x.implemented_partner_ids)), reverse=True) + partners.sort(key=lambda x: (x.grade_id.sequence if x.grade_id else 0, len([i for i in x.implemented_partner_ids if i.website_published])), reverse=True) partners = partners[pager['offset']:pager['offset'] + self._references_per_page] google_map_partner_ids = ','.join(map(str, [p.id for p in partners])) From 84e9a67cdf78db94cb7a09543c1b7ac4ad19d8b4 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 8 Jul 2014 15:56:24 +0200 Subject: [PATCH 10/23] [FIX] orm: better removal of custom m2m fields orm: do not try to create ir.model.relation for custom m2m as self._module is either empty (for custom models), either the one of the last inheriting module (which is wrong). The field should be removed manually and should not be impacted by the uninstallation of modules. The removal of the relation table can be done when removing manually the custom field (see rev 6af3193). ir.model: when removing a model, drop the table with the CASCADE instruction. This will remove left constraints from remaining m2m tables. This means that dropping a table (either manually removing a custom model or uninstalling a module) will not drop the relation table for a custom m2m field. This is not ideal but better than the previous behaviour (which was to fail the DROP TABLE instruction and keep the table with a few columns and unconsistent data). --- openerp/addons/base/ir/ir_model.py | 2 +- openerp/osv/orm.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index 966f5e29077..8796f892960 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -151,7 +151,7 @@ class ir_model(osv.osv): if result and result[0] == 'v': cr.execute('DROP view %s' % (model_pool._table,)) elif result and result[0] == 'r': - cr.execute('DROP TABLE %s' % (model_pool._table,)) + cr.execute('DROP TABLE %s CASCADE' % (model_pool._table,)) return True def unlink(self, cr, user, ids, context=None): diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index fc381695fef..1f2823b7919 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -3385,7 +3385,10 @@ class BaseModel(object): def _m2m_raise_or_create_relation(self, cr, f): m2m_tbl, col1, col2 = f._sql_names(self) - self._save_relation_table(cr, m2m_tbl) + # do not create relations for custom fields as they do not belong to a module + # they will be automatically removed when dropping the corresponding ir.model.field + if not f.string.startswith('x_'): + self._save_relation_table(cr, m2m_tbl) cr.execute("SELECT relname FROM pg_class WHERE relkind IN ('r','v') AND relname=%s", (m2m_tbl,)) if not cr.dictfetchall(): if not self.pool.get(f._obj): From 1ddb3439be06460243cf87bab0b691cd81276c9d Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 8 Jul 2014 17:44:40 +0200 Subject: [PATCH 11/23] [FIX] account_analytic_account: handle partners without fiscal position gracefully --- addons/account_analytic_analysis/account_analytic_analysis.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py index af8f77b9566..973206bfef6 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis.py +++ b/addons/account_analytic_analysis/account_analytic_analysis.py @@ -697,7 +697,9 @@ class account_analytic_account(osv.osv): def _prepare_invoice_lines(self, cr, uid, contract, fiscal_position_id, context=None): fpos_obj = self.pool.get('account.fiscal.position') - fiscal_position = fpos_obj.browse(cr, uid, fiscal_position_id, context=context) + fiscal_position = None + if fiscal_position_id: + fiscal_position = fpos_obj.browse(cr, uid, fiscal_position_id, context=context) invoice_lines = [] for line in contract.recurring_invoice_line_ids: From e0ed658044f7b9c646b9e12dc96eb17b90e80c96 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 9 Jul 2014 10:39:00 +0200 Subject: [PATCH 12/23] [FIX] website: if the first menu refered to a website page and the route for this path is overwrited, the route is not used, the template has not the values of the route. (e.g. contact-us menu in first position if website_crm is installed) --- addons/website/controllers/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index a1006af395a..9c6749a389a 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -40,8 +40,7 @@ class Website(openerp.addons.web.controllers.main.Home): if not (first_menu.url.startswith(('/page/', '/?', '/#')) or (first_menu.url=='/')): return request.redirect(first_menu.url) if first_menu.url.startswith('/page/'): - page = first_menu.url[6:] - + return request.registry['ir.http'].reroute(first_menu.url) return self.page(page) @http.route(website=True, auth="public") From 6183fb105efd310d5922b168b0d6a4a59d2ff3f4 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 9 Jul 2014 10:45:35 +0200 Subject: [PATCH 13/23] [FIX] website_crm: the path '/crm/contactus' have an error if you does'nt use the website contact form or if you reload the page, insead of redirect to contact form. --- addons/website_crm/controllers/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website_crm/controllers/main.py b/addons/website_crm/controllers/main.py index 37d661e8a04..935e1005c6b 100644 --- a/addons/website_crm/controllers/main.py +++ b/addons/website_crm/controllers/main.py @@ -40,7 +40,7 @@ class contactus(http.Controller): post_file = [] # List of file to add to ir_attachment once we have the ID post_description = [] # Info to add after the message - values = {'user_id': False} + values = {} lead_model = request.registry['crm.lead'] @@ -81,7 +81,7 @@ class contactus(http.Controller): post_description.append("%s: %s" % ("REFERER", environ.get("HTTP_REFERER"))) values['description'] += dict_to_str(_("Environ Fields: "), post_description) - lead_id = lead_model.create(request.cr, SUPERUSER_ID, values, request.context) + lead_id = lead_model.create(request.cr, SUPERUSER_ID, dict(values, user_id=False), request.context) if lead_id: for field_value in post_file: attachment_value = { From bd163d7bd4499f60d6e5b5aca6abedfeb354a4d5 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 9 Jul 2014 13:20:48 +0200 Subject: [PATCH 14/23] [FIX] product: allow user to set price at template creation The lst_price field on product.template is a related to list_price. As we do not allow to set a value for related fields at creation (see orm.py , L4180), we display the list_price instead (float field). On the product.product form, we display the lst_price (function field, readonly) as we don't want to allow changing the template price from the product. opw 609497 --- addons/product/product_view.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml index ddecdea996b..b7d746c023f 100644 --- a/addons/product/product_view.xml +++ b/addons/product/product_view.xml @@ -69,7 +69,7 @@ - + @@ -268,6 +268,9 @@
Product Variant
+ + lst_price + From fa44bdb4860bec31bb2d090c2e54c62cb551fcb7 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 9 Jul 2014 16:42:22 +0200 Subject: [PATCH 15/23] [FIX] mass_mailing: load images in emails The emails containing emails generated with the image widget have absolute path (src='/website/static/...'), adding tag allows the mail client to load it correctly. --- addons/mass_mailing/models/mail_mail.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/addons/mass_mailing/models/mail_mail.py b/addons/mass_mailing/models/mail_mail.py index 0e44399a256..41be9c21cbf 100644 --- a/addons/mass_mailing/models/mail_mail.py +++ b/addons/mass_mailing/models/mail_mail.py @@ -74,6 +74,11 @@ class MailMail(osv.Model): """ Override to add the tracking URL to the body. """ body = super(MailMail, self).send_get_mail_body(cr, uid, mail, partner=partner, context=context) + # prepend tag for images using absolute urls + domain = self.pool.get("ir.config_parameter").get_param(cr, uid, "web.base.url", context=context) + base = "" % domain + body = tools.append_content_to_html(base, body, plaintext=False, container_tag='div') + # generate tracking URL if mail.statistics_ids: tracking_url = self._get_tracking_url(cr, uid, mail, partner, context=context) From 8eb97cc0829290d7a1f3c2b1b007e257a5615b4c Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Wed, 9 Jul 2014 17:45:40 +0200 Subject: [PATCH 16/23] [IMP] website_sale: Add google analytics on checkout process --- addons/website/views/website_templates.xml | 22 +++--- addons/website_sale/controllers/main.py | 25 +++++++ .../static/src/js/website_sale_tracking.js | 67 +++++++++++++++++++ addons/website_sale/views/templates.xml | 5 ++ 4 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 addons/website_sale/static/src/js/website_sale_tracking.js diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index d0c4231eac6..2e3bc4ee3e2 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -93,6 +93,17 @@ + + +
@@ -207,17 +218,6 @@
- - - diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index a6bcd15f9e5..525530fca79 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -759,5 +759,30 @@ class website_sale(http.Controller): product = product_obj.browse(request.cr, request.uid, id, context=request.context) return product.write({'website_size_x': x, 'website_size_y': y}) + @http.route(['/shop/tracking_last_order'], type='json', auth="public") + def tracking_cart(self, **post): + """ return JS code for google analytics""" + cr, uid, context = request.cr, request.uid, request.context + ret = {} + sale_order_id = request.session.get('sale_last_order_id') + if sale_order_id: + order = request.registry['sale.order'].browse(cr, SUPERUSER_ID, sale_order_id, context=context) + ret['transaction'] = { + 'id': sale_order_id, + 'affiliation': order.company_id.name, + 'revenue': order.amount_total, + 'currency': order.currency_id.name + } + ret['lines'] = [] + for line in order.order_line: + if not line.is_delivery: + ret['lines'].append({ + 'id': line.order_id and line.order_id.id, + 'name': line.product_id.categ_id and line.product_id.categ_id.name or '-', + 'sku': line.product_id.id, + 'quantity': line.product_uom_qty, + 'price': line.price_unit, + }) + return ret # vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/website_sale/static/src/js/website_sale_tracking.js b/addons/website_sale/static/src/js/website_sale_tracking.js new file mode 100644 index 00000000000..8ff5a5ac789 --- /dev/null +++ b/addons/website_sale/static/src/js/website_sale_tracking.js @@ -0,0 +1,67 @@ +$(document).ready(function () { + + // Watching a product + if ($("#product_detail.oe_website_sale").length) { + prod_id = $("input[name='product_id']").attr('value'); + vpv("/stats/ecom/product_view/" + prod_id); + } + + // Add a product into the cart + $(".oe_website_sale form[action='/shop/cart/update'] a.a-submit").on('click', function(o) { + prod_id = $("input[name='product_id']").attr('value'); + vpv("/stats/ecom/product_add_to_cart/" + prod_id); + }); + + // Start checkout + $(".oe_website_sale a[href='/shop/checkout']").on('click', function(o) { + vpv("/stats/ecom/customer_checkout"); + }); + + $(".oe_website_sale div.oe_cart a[href^='/web?redirect'][href$='/shop/checkout']").on('click', function(o) { + vpv("/stats/ecom/customer_signin"); + }); + + $(".oe_website_sale form[action='/shop/confirm_order'] a.a-submit").on('click', function(o) { + if ($("#top_menu > li > a[href='/web/login']").length){ + vpv("/stats/ecom/customer_signup"); + } + vpv("/stats/ecom/order_checkout"); + }); + + $(".oe_website_sale form[target='_self'] button[type=submit]").on('click', function(o) { + var method = $("#payment_method input[name=acquirer]:checked").nextAll("span:first").text(); + vpv("/stats/ecom/order_payment/" + method); + }); + + if ($(".oe_website_sale div.oe_cart div.oe_website_sale_tx_status").length) { + track_ga('require', 'ecommerce'); + + order_id = $(".oe_website_sale div.oe_cart div.oe_website_sale_tx_status").data("order-id"); + vpv("/stats/ecom/order_confirmed/" + order_id); + + openerp.jsonRpc("/shop/tracking_last_order/").then(function(o) { + track_ga('ecommerce:clear'); + + if (o.transaction && o.lines) { + track_ga('ecommerce:addTransaction', o.transaction); + _.forEach(o.lines, function(line) { + track_ga('ecommerce:addItem', line); + }); + } + track_ga('ecommerce:send'); + }); + } + + function vpv(page){ //virtual page view + track_ga('send', 'pageview', { + 'page': page, + 'title': document.title, + }); + } + + function track_ga() { + website_ga = this._gaw || function(){}; + website_ga.apply(this, arguments); + } + +}); diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index 28f4d3e2418..d36951ec8e6 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -335,6 +335,7 @@