[MERGE] forward port of branch saas-5 up to 73d39a0
This commit is contained in:
commit
f654a7719b
|
@ -700,7 +700,9 @@ class account_analytic_account(osv.osv):
|
||||||
|
|
||||||
def _prepare_invoice_lines(self, cr, uid, contract, fiscal_position_id, context=None):
|
def _prepare_invoice_lines(self, cr, uid, contract, fiscal_position_id, context=None):
|
||||||
fpos_obj = self.pool.get('account.fiscal.position')
|
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 = []
|
invoice_lines = []
|
||||||
for line in contract.recurring_invoice_line_ids:
|
for line in contract.recurring_invoice_line_ids:
|
||||||
|
|
||||||
|
|
|
@ -222,9 +222,9 @@ class email_template(osv.osv):
|
||||||
help="Optional translation language (ISO code) to select when sending out an email. "
|
help="Optional translation language (ISO code) to select when sending out an email. "
|
||||||
"If not set, the english version will be used. "
|
"If not set, the english version will be used. "
|
||||||
"This should usually be a placeholder expression "
|
"This should usually be a placeholder expression "
|
||||||
"that provides the appropriate language code, e.g. "
|
"that provides the appropriate language, e.g. "
|
||||||
"${object.partner_id.lang.code}.",
|
"${object.partner_id.lang}.",
|
||||||
placeholder="${object.partner_id.lang.code}"),
|
placeholder="${object.partner_id.lang}"),
|
||||||
'user_signature': fields.boolean('Add Signature',
|
'user_signature': fields.boolean('Add Signature',
|
||||||
help="If checked, the user's signature will be appended to the text version "
|
help="If checked, the user's signature will be appended to the text version "
|
||||||
"of the message"),
|
"of the message"),
|
||||||
|
|
|
@ -55,7 +55,7 @@ class event_event(models.Model):
|
||||||
readonly=False, states={'done': [('readonly', True)]})
|
readonly=False, states={'done': [('readonly', True)]})
|
||||||
type = fields.Many2one('event.type', string='Type of Event',
|
type = fields.Many2one('event.type', string='Type of Event',
|
||||||
readonly=False, states={'done': [('readonly', True)]})
|
readonly=False, states={'done': [('readonly', True)]})
|
||||||
seats_max = fields.Integer(string='Maximum Avalaible Seats', oldname='register_max',
|
seats_max = fields.Integer(string='Maximum Available Seats', oldname='register_max',
|
||||||
readonly=True, states={'draft': [('readonly', False)]},
|
readonly=True, states={'draft': [('readonly', False)]},
|
||||||
help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )")
|
help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )")
|
||||||
seats_min = fields.Integer(string='Minimum Reserved Seats', oldname='register_min',
|
seats_min = fields.Integer(string='Minimum Reserved Seats', oldname='register_min',
|
||||||
|
|
|
@ -186,7 +186,7 @@ class event_ticket(osv.osv):
|
||||||
'deadline': fields.date("Sales End"),
|
'deadline': fields.date("Sales End"),
|
||||||
'is_expired': fields.function(_is_expired, type='boolean', string='Is Expired'),
|
'is_expired': fields.function(_is_expired, type='boolean', string='Is Expired'),
|
||||||
'price': fields.float('Price'),
|
'price': fields.float('Price'),
|
||||||
'seats_max': fields.integer('Maximum Avalaible Seats', oldname='register_max', help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )"),
|
'seats_max': fields.integer('Maximum Available Seats', oldname='register_max', help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )"),
|
||||||
'seats_reserved': fields.function(_get_seats, string='Reserved Seats', type='integer', multi='seats_reserved'),
|
'seats_reserved': fields.function(_get_seats, string='Reserved Seats', type='integer', multi='seats_reserved'),
|
||||||
'seats_available': fields.function(_get_seats, string='Available Seats', type='integer', multi='seats_reserved'),
|
'seats_available': fields.function(_get_seats, string='Available Seats', type='integer', multi='seats_reserved'),
|
||||||
'seats_unconfirmed': fields.function(_get_seats, string='Unconfirmed Seat Reservations', type='integer', multi='seats_reserved'),
|
'seats_unconfirmed': fields.function(_get_seats, string='Unconfirmed Seat Reservations', type='integer', multi='seats_reserved'),
|
||||||
|
|
|
@ -220,8 +220,7 @@ class report_custom(report_rml):
|
||||||
|
|
||||||
elif data['model']=='ir.ui.menu':
|
elif data['model']=='ir.ui.menu':
|
||||||
for dept in obj_dept.browse(cr, uid, data['form']['depts'], context=context):
|
for dept in obj_dept.browse(cr, uid, data['form']['depts'], context=context):
|
||||||
cr.execute("SELECT id FROM hr_employee WHERE department_id = %s", (dept.id,))
|
emp_ids = obj_emp.search(cr, uid, [('department_id', '=', dept.id)], context=context)
|
||||||
emp_ids = [x[0] for x in cr.fetchall()]
|
|
||||||
if emp_ids==[]:
|
if emp_ids==[]:
|
||||||
continue
|
continue
|
||||||
dept_done=0
|
dept_done=0
|
||||||
|
|
|
@ -74,6 +74,11 @@ class MailMail(osv.Model):
|
||||||
""" Override to add the tracking URL to the body. """
|
""" Override to add the tracking URL to the body. """
|
||||||
body = super(MailMail, self).send_get_mail_body(cr, uid, mail, partner=partner, context=context)
|
body = super(MailMail, self).send_get_mail_body(cr, uid, mail, partner=partner, context=context)
|
||||||
|
|
||||||
|
# prepend <base> tag for images using absolute urls
|
||||||
|
domain = self.pool.get("ir.config_parameter").get_param(cr, uid, "web.base.url", context=context)
|
||||||
|
base = "<base href='%s'>" % domain
|
||||||
|
body = tools.append_content_to_html(base, body, plaintext=False, container_tag='div')
|
||||||
|
|
||||||
# generate tracking URL
|
# generate tracking URL
|
||||||
if mail.statistics_ids:
|
if mail.statistics_ids:
|
||||||
tracking_url = self._get_tracking_url(cr, uid, mail, partner, context=context)
|
tracking_url = self._get_tracking_url(cr, uid, mail, partner, context=context)
|
||||||
|
|
|
@ -10,6 +10,6 @@
|
||||||
report_type="qweb-pdf"
|
report_type="qweb-pdf"
|
||||||
name="product.report_pricelist"
|
name="product.report_pricelist"
|
||||||
file="product.report_pricelist"
|
file="product.report_pricelist"
|
||||||
/>
|
menu="False"/>
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
<group>
|
<group>
|
||||||
<field name="type"/>
|
<field name="type"/>
|
||||||
<field name="uom_id" on_change="onchange_uom(uom_id,uom_po_id)" groups="product.group_uom"/>
|
<field name="uom_id" on_change="onchange_uom(uom_id,uom_po_id)" groups="product.group_uom"/>
|
||||||
<field name="lst_price"/>
|
<field name="list_price"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="active"/>
|
<field name="active"/>
|
||||||
|
@ -269,6 +269,9 @@
|
||||||
<form position="attributes">
|
<form position="attributes">
|
||||||
<attribute name="string">Product Variant</attribute>
|
<attribute name="string">Product Variant</attribute>
|
||||||
</form>
|
</form>
|
||||||
|
<field name="list_price" position="attributes">
|
||||||
|
<attribute name="name">lst_price</attribute>
|
||||||
|
</field>
|
||||||
<field name="name" position="replace">
|
<field name="name" position="replace">
|
||||||
<field name="name" attrs="{'invisible': [('id', '!=', False)]}"/>
|
<field name="name" attrs="{'invisible': [('id', '!=', False)]}"/>
|
||||||
<field name="product_tmpl_id" class="oe_inline" readonly="1" attrs="{'invisible': [('id', '=', False)], 'required': [('id', '!=', False)]}"/>
|
<field name="product_tmpl_id" class="oe_inline" readonly="1" attrs="{'invisible': [('id', '=', False)], 'required': [('id', '!=', False)]}"/>
|
||||||
|
|
|
@ -3,7 +3,7 @@ access_stock_incoterms_all,stock.incoterms all,model_stock_incoterms,,1,0,0,0
|
||||||
access_stock_incoterms_manager,stock.incoterms manager,model_stock_incoterms,stock.group_stock_manager,1,1,1,1
|
access_stock_incoterms_manager,stock.incoterms manager,model_stock_incoterms,stock.group_stock_manager,1,1,1,1
|
||||||
access_stock_warehouse_manager,stock.warehouse.manager,model_stock_warehouse,stock.group_stock_manager,1,1,1,1
|
access_stock_warehouse_manager,stock.warehouse.manager,model_stock_warehouse,stock.group_stock_manager,1,1,1,1
|
||||||
access_stock_warehouse_user,stock.warehouse.user,model_stock_warehouse,base.group_user,1,0,0,0
|
access_stock_warehouse_user,stock.warehouse.user,model_stock_warehouse,base.group_user,1,0,0,0
|
||||||
access_stock_location__partner_manager,stock.location.partner.manager,model_stock_location,base.group_partner_manager,1,1,1,1
|
access_stock_location__partner_manager,stock.location.partner.manager,model_stock_location,base.group_partner_manager,1,0,0,0
|
||||||
access_stock_location_manager,stock.location.manager,model_stock_location,stock.group_stock_manager,1,1,1,1
|
access_stock_location_manager,stock.location.manager,model_stock_location,stock.group_stock_manager,1,1,1,1
|
||||||
access_stock_location_user,stock.location.user,model_stock_location,base.group_user,1,0,0,0
|
access_stock_location_user,stock.location.user,model_stock_location,base.group_user,1,0,0,0
|
||||||
access_stock_picking_user,stock.picking user,model_stock_picking,stock.group_stock_user,1,1,1,1
|
access_stock_picking_user,stock.picking user,model_stock_picking,stock.group_stock_user,1,1,1,1
|
||||||
|
|
|
|
@ -40,8 +40,7 @@ class Website(openerp.addons.web.controllers.main.Home):
|
||||||
if not (first_menu.url.startswith(('/page/', '/?', '/#')) or (first_menu.url=='/')):
|
if not (first_menu.url.startswith(('/page/', '/?', '/#')) or (first_menu.url=='/')):
|
||||||
return request.redirect(first_menu.url)
|
return request.redirect(first_menu.url)
|
||||||
if first_menu.url.startswith('/page/'):
|
if first_menu.url.startswith('/page/'):
|
||||||
page = first_menu.url[6:]
|
return request.registry['ir.http'].reroute(first_menu.url)
|
||||||
|
|
||||||
return self.page(page)
|
return self.page(page)
|
||||||
|
|
||||||
@http.route(website=True, auth="public")
|
@http.route(website=True, auth="public")
|
||||||
|
|
|
@ -94,6 +94,17 @@
|
||||||
<t t-call-assets="website.assets_frontend"/>
|
<t t-call-assets="website.assets_frontend"/>
|
||||||
|
|
||||||
<t t-raw="head or ''" name='layout_head'/>
|
<t t-raw="head or ''" name='layout_head'/>
|
||||||
|
<t t-if="website and website.google_analytics_key">
|
||||||
|
<script>
|
||||||
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
|
})(window,document,'script','//www.google-analytics.com/analytics.js','_gaw');
|
||||||
|
|
||||||
|
_gaw('create',_.str.trim('<t t-esc="website.google_analytics_key"/>'));
|
||||||
|
_gaw('send','pageview');
|
||||||
|
</script>
|
||||||
|
</t>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="wrapwrap">
|
<div id="wrapwrap">
|
||||||
|
@ -150,17 +161,6 @@
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<t t-if="website and website.google_analytics_key">
|
|
||||||
<script>
|
|
||||||
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
|
|
||||||
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
|
|
||||||
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
|
|
||||||
e.src='//www.google-analytics.com/analytics.js';
|
|
||||||
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
|
|
||||||
ga('create',_.str.trim('<t t-esc="website.google_analytics_key"/>'));
|
|
||||||
ga('send','pageview');
|
|
||||||
</script>
|
|
||||||
</t>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -39,7 +39,7 @@ class contactus(http.Controller):
|
||||||
|
|
||||||
post_file = [] # List of file to add to ir_attachment once we have the ID
|
post_file = [] # List of file to add to ir_attachment once we have the ID
|
||||||
post_description = [] # Info to add after the message
|
post_description = [] # Info to add after the message
|
||||||
values = {'user_id': False}
|
values = {}
|
||||||
|
|
||||||
lead_model = request.registry['crm.lead']
|
lead_model = request.registry['crm.lead']
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ class contactus(http.Controller):
|
||||||
post_description.append("%s: %s" % ("REFERER", environ.get("HTTP_REFERER")))
|
post_description.append("%s: %s" % ("REFERER", environ.get("HTTP_REFERER")))
|
||||||
values['description'] += dict_to_str(_("Environ Fields: "), post_description)
|
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:
|
if lead_id:
|
||||||
for field_value in post_file:
|
for field_value in post_file:
|
||||||
attachment_value = {
|
attachment_value = {
|
||||||
|
|
|
@ -109,7 +109,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
|
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)
|
partners = partner_obj.browse(request.cr, SUPERUSER_ID, partner_ids, request.context)
|
||||||
# remove me in trunk
|
# remove me in trunk
|
||||||
partners = sorted(partners, key=lambda x: (-1 * (x.grade_id and x.grade_id.id or 0), len(x.implemented_partner_ids)), reverse=True)
|
partners = sorted(partners, 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]
|
partners = partners[pager['offset']:pager['offset'] + self._references_per_page]
|
||||||
|
|
||||||
google_map_partner_ids = ','.join(map(str, [p.id for p in partners]))
|
google_map_partner_ids = ','.join(map(str, [p.id for p in partners]))
|
||||||
|
|
|
@ -112,7 +112,7 @@ class Post(osv.Model):
|
||||||
_name = 'forum.post'
|
_name = 'forum.post'
|
||||||
_description = 'Forum Post'
|
_description = 'Forum Post'
|
||||||
_inherit = ['mail.thread', 'website.seo.metadata']
|
_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):
|
def _get_user_vote(self, cr, uid, ids, field_name, arg, context):
|
||||||
res = dict.fromkeys(ids, 0)
|
res = dict.fromkeys(ids, 0)
|
||||||
|
|
|
@ -17,7 +17,7 @@ class WebsiteResPartner(osv.Model):
|
||||||
'Website Partner Full Description'
|
'Website Partner Full Description'
|
||||||
),
|
),
|
||||||
'website_short_description': fields.text(
|
'website_short_description': fields.text(
|
||||||
'Website artner Short Description'
|
'Website Partner Short Description'
|
||||||
),
|
),
|
||||||
# hack to allow using plain browse record in qweb views
|
# hack to allow using plain browse record in qweb views
|
||||||
'self': fields.function(_get_ids, type='many2one', relation=_name),
|
'self': fields.function(_get_ids, type='many2one', relation=_name),
|
||||||
|
|
|
@ -820,5 +820,30 @@ class website_sale(http.Controller):
|
||||||
product = product_obj.browse(request.cr, request.uid, id, context=request.context)
|
product = product_obj.browse(request.cr, request.uid, id, context=request.context)
|
||||||
return product.write({'website_size_x': x, 'website_size_y': y})
|
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:
|
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
|
@ -344,6 +344,7 @@
|
||||||
|
|
||||||
<template id="product" name="Product">
|
<template id="product" name="Product">
|
||||||
<t t-call="website.layout">
|
<t t-call="website.layout">
|
||||||
|
<script type="text/javascript" src="/website_sale/static/src/js/website_sale_tracking.js"></script>
|
||||||
<t t-set="additional_title" t-value="product.name"/>
|
<t t-set="additional_title" t-value="product.name"/>
|
||||||
<div itemscope="itemscope" itemtype="http://schema.org/Product" id="wrap" class="js_sale">
|
<div itemscope="itemscope" itemtype="http://schema.org/Product" id="wrap" class="js_sale">
|
||||||
|
|
||||||
|
@ -649,6 +650,7 @@
|
||||||
|
|
||||||
<template id="cart" name="Shopping Cart">
|
<template id="cart" name="Shopping Cart">
|
||||||
<t t-call="website.layout">
|
<t t-call="website.layout">
|
||||||
|
<script type="text/javascript" src="/website_sale/static/src/js/website_sale_tracking.js"></script>
|
||||||
<div id="wrap">
|
<div id="wrap">
|
||||||
<div class="container oe_website_sale">
|
<div class="container oe_website_sale">
|
||||||
|
|
||||||
|
@ -836,6 +838,7 @@
|
||||||
|
|
||||||
<template id="checkout">
|
<template id="checkout">
|
||||||
<t t-call="website.layout">
|
<t t-call="website.layout">
|
||||||
|
<script type="text/javascript" src="/website_sale/static/src/js/website_sale_tracking.js"></script>
|
||||||
<t t-set="additional_title">Shop - Checkout</t>
|
<t t-set="additional_title">Shop - Checkout</t>
|
||||||
<div id="wrap">
|
<div id="wrap">
|
||||||
<div class="container oe_website_sale">
|
<div class="container oe_website_sale">
|
||||||
|
@ -998,6 +1001,7 @@
|
||||||
|
|
||||||
<template id="payment">
|
<template id="payment">
|
||||||
<t t-call="website.layout">
|
<t t-call="website.layout">
|
||||||
|
<script type="text/javascript" src="/website_sale/static/src/js/website_sale_tracking.js"></script>
|
||||||
<t t-set="additional_title">Shop - Select Payment Mode</t>
|
<t t-set="additional_title">Shop - Select Payment Mode</t>
|
||||||
<div id="wrap">
|
<div id="wrap">
|
||||||
<div class="container oe_website_sale">
|
<div class="container oe_website_sale">
|
||||||
|
@ -1116,6 +1120,7 @@
|
||||||
|
|
||||||
<template id="confirmation">
|
<template id="confirmation">
|
||||||
<t t-call="website.layout">
|
<t t-call="website.layout">
|
||||||
|
<script type="text/javascript" src="/website_sale/static/src/js/website_sale_tracking.js"></script>
|
||||||
<t t-set="additional_title">Shop - Confirmed</t>
|
<t t-set="additional_title">Shop - Confirmed</t>
|
||||||
<div id="wrap">
|
<div id="wrap">
|
||||||
<div class="container oe_website_sale">
|
<div class="container oe_website_sale">
|
||||||
|
|
|
@ -145,7 +145,7 @@ class ir_model(osv.osv):
|
||||||
if result and result[0] == 'v':
|
if result and result[0] == 'v':
|
||||||
cr.execute('DROP view %s' % (model_pool._table,))
|
cr.execute('DROP view %s' % (model_pool._table,))
|
||||||
elif result and result[0] == 'r':
|
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
|
return True
|
||||||
|
|
||||||
def unlink(self, cr, user, ids, context=None):
|
def unlink(self, cr, user, ids, context=None):
|
||||||
|
@ -309,6 +309,14 @@ class ir_model_fields(osv.osv):
|
||||||
if column_name and (result and result[0] == 'r'):
|
if column_name and (result and result[0] == 'r'):
|
||||||
cr.execute('ALTER table "%s" DROP column "%s" cascade' % (model._table, field.name))
|
cr.execute('ALTER table "%s" DROP column "%s" cascade' % (model._table, field.name))
|
||||||
model._columns.pop(field.name, None)
|
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
|
return True
|
||||||
|
|
||||||
def unlink(self, cr, user, ids, context=None):
|
def unlink(self, cr, user, ids, context=None):
|
||||||
|
|
|
@ -2775,7 +2775,10 @@ class BaseModel(object):
|
||||||
|
|
||||||
def _m2m_raise_or_create_relation(self, cr, f):
|
def _m2m_raise_or_create_relation(self, cr, f):
|
||||||
m2m_tbl, col1, col2 = f._sql_names(self)
|
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,))
|
cr.execute("SELECT relname FROM pg_class WHERE relkind IN ('r','v') AND relname=%s", (m2m_tbl,))
|
||||||
if not cr.dictfetchall():
|
if not cr.dictfetchall():
|
||||||
if f._obj not in self.pool:
|
if f._obj not in self.pool:
|
||||||
|
|
Loading…
Reference in New Issue