[MOV] sale_*: move sale customer portal to sale
Customer portal is now a feature coming directly with sale module. As it uses a simple website renderer customization and advanced website features are not available and depends on having website module installed.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
from . import controllers
|
||||
from . import report
|
||||
from . import wizard
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
'description': """
|
||||
This module contains all the common features of Sales Management and eCommerce.
|
||||
""",
|
||||
'depends': ['sales_team', 'account', 'procurement'],
|
||||
'depends': ['sales_team', 'account', 'procurement', 'portal'],
|
||||
'data': [
|
||||
'data/ir_sequence_data.xml',
|
||||
'data/sale_data.xml',
|
||||
@@ -26,6 +26,7 @@ This module contains all the common features of Sales Management and eCommerce.
|
||||
'views/sales_team_views.xml',
|
||||
'views/res_partner_views.xml',
|
||||
'views/sale_templates.xml',
|
||||
'views/sale_portal_templates.xml',
|
||||
'views/sale_layout_category_view.xml',
|
||||
'views/sale_config_settings_views.xml',
|
||||
],
|
||||
|
||||
+1
-1
@@ -2,4 +2,4 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import mail
|
||||
from . import main
|
||||
from . import portal
|
||||
@@ -6,14 +6,13 @@ from odoo.exceptions import AccessError
|
||||
from odoo.http import request
|
||||
from odoo.tools import consteq
|
||||
|
||||
from odoo.addons.portal.controllers.portal import get_records_pager
|
||||
from odoo.addons.website_portal.controllers.main import website_account
|
||||
from odoo.addons.portal.controllers.portal import CustomerPortal, get_records_pager
|
||||
|
||||
|
||||
class website_account(website_account):
|
||||
class CustomerPortal(CustomerPortal):
|
||||
|
||||
def _prepare_portal_layout_values(self):
|
||||
values = super(website_account, self)._prepare_portal_layout_values()
|
||||
values = super(CustomerPortal, self)._prepare_portal_layout_values()
|
||||
partner = request.env.user.partner_id
|
||||
|
||||
SaleOrder = request.env['sale.order']
|
||||
@@ -64,7 +63,7 @@ class website_account(website_account):
|
||||
# count for pager
|
||||
quotation_count = SaleOrder.search_count(domain)
|
||||
# make pager
|
||||
pager = request.website.pager(
|
||||
pager = request.pager(
|
||||
url="/my/quotes",
|
||||
url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby},
|
||||
total=quotation_count,
|
||||
@@ -85,7 +84,7 @@ class website_account(website_account):
|
||||
'searchbar_sortings': searchbar_sortings,
|
||||
'sortby': sortby,
|
||||
})
|
||||
return request.render("website_portal_sale.portal_my_quotations", values)
|
||||
return request.render("sale.portal_my_quotations", values)
|
||||
|
||||
@http.route(['/my/orders', '/my/orders/page/<int:page>'], type='http', auth="user", website=True)
|
||||
def portal_my_orders(self, page=1, date_begin=None, date_end=None, sortby=None, **kw):
|
||||
@@ -114,7 +113,7 @@ class website_account(website_account):
|
||||
# count for pager
|
||||
order_count = SaleOrder.search_count(domain)
|
||||
# pager
|
||||
pager = request.website.pager(
|
||||
pager = request.pager(
|
||||
url="/my/orders",
|
||||
url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby},
|
||||
total=order_count,
|
||||
@@ -135,7 +134,7 @@ class website_account(website_account):
|
||||
'searchbar_sortings': searchbar_sortings,
|
||||
'sortby': sortby,
|
||||
})
|
||||
return request.render("website_portal_sale.portal_my_orders", values)
|
||||
return request.render("sale.portal_my_orders", values)
|
||||
|
||||
@http.route(['/my/orders/<int:order>'], type='http', auth="public", website=True)
|
||||
def orders_followup(self, order=None, access_token=None, **kw):
|
||||
@@ -147,7 +146,7 @@ class website_account(website_account):
|
||||
order.check_access_rule('read')
|
||||
except AccessError:
|
||||
if not access_token or not consteq(order_sudo.access_token, access_token):
|
||||
return request.render("website.403")
|
||||
return request.redirect('/my')
|
||||
values.update({'no_breadcrumbs': True})
|
||||
|
||||
order_invoice_lines = {il.product_id.id: il.invoice_id for il in order_sudo.invoice_ids.mapped('invoice_line_ids')}
|
||||
@@ -158,5 +157,4 @@ class website_account(website_account):
|
||||
'order_invoice_lines': order_invoice_lines,
|
||||
})
|
||||
values.update(get_records_pager(history, order_sudo))
|
||||
return request.render("website_portal_sale.orders_followup", values)
|
||||
|
||||
return request.render("sale.orders_followup", values)
|
||||
@@ -613,5 +613,78 @@ Thanks!</field>
|
||||
<record id="base.user_demo" model="res.users">
|
||||
<field eval="[(4, ref('sales_team.group_sale_salesman'))]" name="groups_id"/>
|
||||
</record>
|
||||
|
||||
<!-- records coming from website_portal_sale, now dead module -->
|
||||
<record id="portal_sale_order_1" model="sale.order">
|
||||
<field name="partner_id" ref="base.partner_demo_portal"/>
|
||||
<field name="partner_invoice_id" ref="base.partner_demo_portal"/>
|
||||
<field name="partner_shipping_id" ref="base.partner_demo_portal"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="pricelist_id" ref="product.list0"/>
|
||||
<field name="state">sent</field>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="date_order" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="message_partner_ids" eval="[(4, ref('base.partner_demo_portal'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="portal_sale_order_line_1" model="sale.order.line">
|
||||
<field name="order_id" ref="portal_sale_order_1"/>
|
||||
<field name="name">Laptop E5023</field>
|
||||
<field name="product_id" ref="product.product_product_25"/>
|
||||
<field name="product_uom_qty">3</field>
|
||||
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||
<field name="price_unit">2950.00</field>
|
||||
</record>
|
||||
|
||||
<record id="portal_sale_order_line_2" model="sale.order.line">
|
||||
<field name="order_id" ref="portal_sale_order_1"/>
|
||||
<field name="name">Pen drive, 16GB</field>
|
||||
<field name="product_id" ref="product.product_delivery_02"/>
|
||||
<field name="product_uom_qty">5</field>
|
||||
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||
<field name="price_unit">145.00</field>
|
||||
</record>
|
||||
|
||||
<record id="portal_sale_order_line_3" model="sale.order.line">
|
||||
<field name="order_id" ref="portal_sale_order_1"/>
|
||||
<field name="name">Headset USB</field>
|
||||
<field name="product_id" ref="product.product_delivery_01"/>
|
||||
<field name="product_uom_qty">2</field>
|
||||
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||
<field name="price_unit">65.00</field>
|
||||
</record>
|
||||
|
||||
<record id="portal_sale_order_2" model="sale.order">
|
||||
<field name="partner_id" ref="base.partner_demo_portal"/>
|
||||
<field name="partner_invoice_id" ref="base.partner_demo_portal"/>
|
||||
<field name="partner_shipping_id" ref="base.partner_demo_portal"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="pricelist_id" ref="product.list0"/>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="date_order" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="message_partner_ids" eval="[(4, ref('base.partner_demo_portal'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="portal_sale_order_line_4" model="sale.order.line">
|
||||
<field name="order_id" ref="portal_sale_order_2"/>
|
||||
<field name="name">Service on demand</field>
|
||||
<field name="product_id" ref="product.product_product_1"/>
|
||||
<field name="product_uom_qty">24</field>
|
||||
<field name="product_uom" ref="product.product_uom_hour"/>
|
||||
<field name="price_unit">75.00</field>
|
||||
</record>
|
||||
|
||||
<record id="portal_sale_order_line_5" model="sale.order.line">
|
||||
<field name="order_id" ref="portal_sale_order_2"/>
|
||||
<field name="name">On Site Assistance</field>
|
||||
<field name="product_id" ref="product.product_product_2"/>
|
||||
<field name="product_uom_qty">30</field>
|
||||
<field name="product_uom" ref="product.product_uom_hour"/>
|
||||
<field name="price_unit">38.25</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Confirm some Sales Orders-->
|
||||
<function model="sale.order" name="action_confirm" eval="[[ref('portal_sale_order_2')]]"/>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -5,9 +5,10 @@ import uuid
|
||||
|
||||
from itertools import groupby
|
||||
from datetime import datetime, timedelta
|
||||
from werkzeug.urls import url_encode
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.exceptions import UserError, AccessError
|
||||
from odoo.tools import float_is_zero, float_compare, DEFAULT_SERVER_DATETIME_FORMAT, pycompat
|
||||
from odoo.tools.misc import formatLang
|
||||
|
||||
@@ -118,6 +119,9 @@ class SaleOrder(models.Model):
|
||||
access_token = fields.Char(
|
||||
'Security Token', copy=False,
|
||||
default=_get_default_access_token)
|
||||
website_url = fields.Char(
|
||||
'Website URL', compute='_website_url',
|
||||
help='The full URL to access the document using the customer portal.')
|
||||
|
||||
state = fields.Selection([
|
||||
('draft', 'Quotation'),
|
||||
@@ -166,6 +170,10 @@ class SaleOrder(models.Model):
|
||||
|
||||
product_id = fields.Many2one('product.product', related='order_line.product_id', string='Product')
|
||||
|
||||
def _website_url(self):
|
||||
for so in self:
|
||||
so.website_url = '/my/orders/%s' % (so.id)
|
||||
|
||||
@api.model
|
||||
def _get_customer_lead(self, product_tmpl_id):
|
||||
return False
|
||||
@@ -560,6 +568,54 @@ class SaleOrder(models.Model):
|
||||
res = [(l[0].name, l[1]) for l in res]
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self, access_uid=None):
|
||||
""" Instead of the classic form view, redirect to the online order for
|
||||
portal users or if force_website=True in the context. """
|
||||
# TDE note: read access on sales order to portal users granted to followed sales orders
|
||||
self.ensure_one()
|
||||
if self.state == 'cancel' or (self.state == 'draft' and not self.env.context.get('mark_so_as_sent')):
|
||||
return super(SaleOrder, self).get_access_action(access_uid)
|
||||
|
||||
user = self.env['res.users'].sudo().browse(access_uid) if access_uid else self.env.user
|
||||
if user.share or self.env.context.get('force_website'):
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/orders/%s?access_token=%s' % (self.id, self.access_token),
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
return super(SaleOrder, self).get_access_action(access_uid)
|
||||
|
||||
def get_mail_url(self):
|
||||
self.ensure_one()
|
||||
params = {
|
||||
'model': self._name,
|
||||
'res_id': self.id,
|
||||
'access_token': self.access_token,
|
||||
}
|
||||
params.update(self.partner_id.signup_get_auth_param()[self.partner_id.id])
|
||||
return '/mail/view?' + url_encode(params)
|
||||
|
||||
@api.multi
|
||||
def _notification_recipients(self, message, groups):
|
||||
groups = super(SaleOrder, self)._notification_recipients(message, groups)
|
||||
|
||||
self.ensure_one()
|
||||
if self.state not in ('draft', 'cancel'):
|
||||
for group_name, group_method, group_data in groups:
|
||||
group_data['has_button_access'] = True
|
||||
|
||||
return groups
|
||||
|
||||
@api.multi
|
||||
def get_signup_url(self):
|
||||
self.ensure_one()
|
||||
return self.partner_id.with_context(signup_valid=True)._get_signup_url_for_action(
|
||||
action='/mail/view',
|
||||
model=self._name,
|
||||
res_id=self.id)[self.partner_id.id]
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
_name = 'sale.order.line'
|
||||
@@ -804,6 +860,8 @@ class SaleOrderLine(models.Model):
|
||||
product_id = fields.Many2one('product.product', string='Product', domain=[('sale_ok', '=', True)], change_default=True, ondelete='restrict', required=True)
|
||||
product_uom_qty = fields.Float(string='Quantity', digits=dp.get_precision('Product Unit of Measure'), required=True, default=1.0)
|
||||
product_uom = fields.Many2one('product.uom', string='Unit of Measure', required=True)
|
||||
# Non-stored related field to allow portal user to see the image of the product he has ordered
|
||||
product_image = fields.Binary('Product Image', related="product_id.image", store=False)
|
||||
|
||||
qty_delivered_updateable = fields.Boolean(compute='_compute_qty_delivered_updateable', string='Can Edit Delivered', readonly=True, default=True)
|
||||
qty_delivered = fields.Float(string='Delivered', copy=False, digits=dp.get_precision('Product Unit of Measure'), default=0.0)
|
||||
|
||||
@@ -2,6 +2,8 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_sale_order,sale.order,model_sale_order,sales_team.group_sale_salesman,1,1,1,0
|
||||
access_sale_order_line,sale.order.line,model_sale_order_line,sales_team.group_sale_salesman,1,1,1,1
|
||||
access_sale_order_line_accountant,sale.order.line accountant,model_sale_order_line,account.group_account_user,1,1,0,0
|
||||
access_sale_order_portal,sale.order.portal,sale.model_sale_order,base.group_portal,1,0,0,0
|
||||
access_sale_order_line_portal,sale.order.line.portal,sale.model_sale_order_line,base.group_portal,1,0,0,0
|
||||
access_account_invoice_tax_salesman,account_invoice_tax salesman,account.model_account_invoice_tax,sales_team.group_sale_salesman,1,1,1,0
|
||||
access_account_invoice_salesman,account_invoice salesman,account.model_account_invoice,sales_team.group_sale_salesman,1,1,1,0
|
||||
access_account_invoice_manager,account_invoice manager,account.model_account_invoice,sales_team.group_sale_manager,1,1,1,1
|
||||
|
||||
|
@@ -90,6 +90,25 @@
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<!-- Portal Access Rules -->
|
||||
<record id="sale_order_rule_portal" model="ir.rule">
|
||||
<field name="name">Portal Personal Quotations/Sales Orders</field>
|
||||
<field name="model_id" ref="sale.model_sale_order"/>
|
||||
<field name="domain_force">[('message_partner_ids','child_of',[user.commercial_partner_id.id])]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_portal'))]"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="sale_order_line_rule_portal" model="ir.rule">
|
||||
<field name="name">Portal Sales Orders Line</field>
|
||||
<field name="model_id" ref="sale.model_sale_order_line"/>
|
||||
<field name="domain_force">[('order_id.message_partner_ids','child_of',[user.commercial_partner_id.id])]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_portal'))]"/>
|
||||
</record>
|
||||
|
||||
<!-- Multi - Salesmen sales order assignation rules -->
|
||||
|
||||
<record id="sale_order_personal_rule" model="ir.rule">
|
||||
|
||||
+4
-5
@@ -1,8 +1,8 @@
|
||||
<odoo>
|
||||
|
||||
<template id="assets_frontend" inherit_id="website.assets_frontend" name="Website Portal Sale">
|
||||
<template id="assets_frontend" inherit_id="web.assets_frontend" name="Website Portal Sale">
|
||||
<xpath expr="." position="inside">
|
||||
<link rel='stylesheet' href='/website_portal_sale/static/src/less/website_portal_sale.less'/>
|
||||
<link rel='stylesheet' href='/sale/static/src/less/sale_portal.less'/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
</t>
|
||||
</table></div>
|
||||
<div t-if="pager" class="o_portal_pager text-center">
|
||||
<t t-call="website.pager"/>
|
||||
<t t-call="portal.pager"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
@@ -129,7 +129,7 @@
|
||||
</t>
|
||||
</table></div>
|
||||
<div t-if="pager" class="o_portal_pager text-center">
|
||||
<t t-call="website.pager"/>
|
||||
<t t-call="portal.pager"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
@@ -284,7 +284,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="oe_structure mb32"/>
|
||||
</t>
|
||||
@@ -1,5 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import controllers
|
||||
from . import models
|
||||
|
||||
@@ -16,12 +16,8 @@ Add your sales document in the frontend portal. Your customers will be able to c
|
||||
'website_payment',
|
||||
],
|
||||
'data': [
|
||||
'views/website_portal_sale_templates.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'security/sale_order_security.xml',
|
||||
],
|
||||
'demo': [
|
||||
'data/sale_demo.xml'
|
||||
],
|
||||
'installable': True,
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="sale_order_1" model="sale.order">
|
||||
<field name="partner_id" ref="base.partner_demo_portal"/>
|
||||
<field name="partner_invoice_id" ref="base.partner_demo_portal"/>
|
||||
<field name="partner_shipping_id" ref="base.partner_demo_portal"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="pricelist_id" ref="product.list0"/>
|
||||
<field name="state">sent</field>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="date_order" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="message_partner_ids" eval="[(4, ref('base.partner_demo_portal'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="sale_order_line_1" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_1"/>
|
||||
<field name="name">Laptop E5023</field>
|
||||
<field name="product_id" ref="product.product_product_25"/>
|
||||
<field name="product_uom_qty">3</field>
|
||||
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||
<field name="price_unit">2950.00</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_order_line_2" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_1"/>
|
||||
<field name="name">Pen drive, 16GB</field>
|
||||
<field name="product_id" ref="product.product_delivery_02"/>
|
||||
<field name="product_uom_qty">5</field>
|
||||
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||
<field name="price_unit">145.00</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_order_line_3" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_1"/>
|
||||
<field name="name">Headset USB</field>
|
||||
<field name="product_id" ref="product.product_delivery_01"/>
|
||||
<field name="product_uom_qty">2</field>
|
||||
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||
<field name="price_unit">65.00</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_order_2" model="sale.order">
|
||||
<field name="partner_id" ref="base.partner_demo_portal"/>
|
||||
<field name="partner_invoice_id" ref="base.partner_demo_portal"/>
|
||||
<field name="partner_shipping_id" ref="base.partner_demo_portal"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="pricelist_id" ref="product.list0"/>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="date_order" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="message_partner_ids" eval="[(4, ref('base.partner_demo_portal'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="sale_order_line_4" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_2"/>
|
||||
<field name="name">Service on demand</field>
|
||||
<field name="product_id" ref="product.product_product_1"/>
|
||||
<field name="product_uom_qty">24</field>
|
||||
<field name="product_uom" ref="product.product_uom_hour"/>
|
||||
<field name="price_unit">75.00</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_order_line_5" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_2"/>
|
||||
<field name="name">On Site Assistance</field>
|
||||
<field name="product_id" ref="product.product_product_2"/>
|
||||
<field name="product_uom_qty">30</field>
|
||||
<field name="product_uom" ref="product.product_uom_hour"/>
|
||||
<field name="price_unit">38.25</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Confirm some Sales Orders-->
|
||||
<function model="sale.order" name="action_confirm" eval="[[ref('sale_order_2')]]"/>
|
||||
|
||||
</odoo>
|
||||
@@ -1,4 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import sale_order
|
||||
@@ -1,74 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
from werkzeug.urls import url_encode
|
||||
import uuid
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
|
||||
_inherit = 'sale.order'
|
||||
|
||||
website_url = fields.Char('Website URL', compute='_website_url', help='The full URL to access the document through the website.')
|
||||
|
||||
def _website_url(self):
|
||||
for so in self:
|
||||
so.website_url = '/my/orders/%s' % (so.id)
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self, access_uid=None):
|
||||
""" Instead of the classic form view, redirect to the online order for
|
||||
portal users or if force_website=True in the context. """
|
||||
# TDE note: read access on sales order to portal users granted to followed sales orders
|
||||
self.ensure_one()
|
||||
if self.state == 'cancel' or (self.state == 'draft' and not self.env.context.get('mark_so_as_sent')):
|
||||
return super(SaleOrder, self).get_access_action(access_uid)
|
||||
|
||||
user = self.env['res.users'].sudo().browse(access_uid) if access_uid else self.env.user
|
||||
if user.share or self.env.context.get('force_website'):
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/orders/%s?access_token=%s' % (self.id, self.access_token),
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
return super(SaleOrder, self).get_access_action(access_uid)
|
||||
|
||||
def get_mail_url(self):
|
||||
self.ensure_one()
|
||||
params = {
|
||||
'model': self._name,
|
||||
'res_id': self.id,
|
||||
'access_token': self.access_token,
|
||||
}
|
||||
params.update(self.partner_id.signup_get_auth_param()[self.partner_id.id])
|
||||
return '/mail/view?' + url_encode(params)
|
||||
|
||||
@api.multi
|
||||
def _notification_recipients(self, message, groups):
|
||||
groups = super(SaleOrder, self)._notification_recipients(message, groups)
|
||||
|
||||
self.ensure_one()
|
||||
if self.state not in ('draft', 'cancel'):
|
||||
for group_name, group_method, group_data in groups:
|
||||
group_data['has_button_access'] = True
|
||||
|
||||
return groups
|
||||
|
||||
@api.multi
|
||||
def get_signup_url(self):
|
||||
self.ensure_one()
|
||||
return self.partner_id.with_context(signup_valid=True)._get_signup_url_for_action(
|
||||
action='/mail/view',
|
||||
model=self._name,
|
||||
res_id=self.id)[self.partner_id.id]
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
|
||||
_inherit = 'sale.order.line'
|
||||
|
||||
# Non-stored related field to allow portal user to see the image of the product he has ordered
|
||||
product_image = fields.Binary('Product Image', related="product_id.image", store=False)
|
||||
@@ -1,3 +0,0 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_sale_order,sale.order,sale.model_sale_order,base.group_portal,1,0,0,0
|
||||
access_sale_order_line,sale.order.line,sale.model_sale_order_line,base.group_portal,1,0,0,0
|
||||
|
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<!-- Sale Portal Access Rules -->
|
||||
<record id="portal_sale_order_user_rule" model="ir.rule">
|
||||
<field name="name">Portal Personal Quotations/Sales Orders</field>
|
||||
<field name="model_id" ref="sale.model_sale_order"/>
|
||||
<field name="domain_force">[('message_partner_ids','child_of',[user.commercial_partner_id.id])]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_portal'))]"/>
|
||||
<field eval="1" name="perm_unlink"/>
|
||||
<field eval="1" name="perm_write"/>
|
||||
<field eval="1" name="perm_read"/>
|
||||
<field eval="0" name="perm_create"/>
|
||||
</record>
|
||||
|
||||
<record id="portal_sale_order_line_rule" model="ir.rule">
|
||||
<field name="name">Portal Sales Orders Line</field>
|
||||
<field name="model_id" ref="sale.model_sale_order_line"/>
|
||||
<field name="domain_force">[('order_id.message_partner_ids','child_of',[user.commercial_partner_id.id])]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_portal'))]"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -706,7 +706,7 @@
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="quotations" inherit_id="website_portal_sale.portal_my_quotations">
|
||||
<template id="quotations" inherit_id="sale.portal_my_quotations">
|
||||
<xpath expr="//t[@t-foreach='quotations']" position="replace">
|
||||
<t t-foreach="quotations" t-as="quotation">
|
||||
<tr>
|
||||
|
||||
@@ -1708,7 +1708,7 @@
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="orders_followup_products_links" name="Orders Followup Products Links" inherit_id="website_portal_sale.orders_followup">
|
||||
<template id="orders_followup_products_links" name="Orders Followup Products Links" inherit_id="sale.orders_followup">
|
||||
<xpath expr="//div[@id='product_name']/*" position="replace">
|
||||
<a t-if="ol.product_id.website_published" t-att-href="ol.product_id.website_url">
|
||||
<span t-esc="ol.name" />
|
||||
|
||||
@@ -7,9 +7,10 @@ from werkzeug.utils import redirect
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.addons.website_portal_sale.controllers.main import website_account
|
||||
from odoo.addons.sale.controllers.portal import CustomerPortal
|
||||
from odoo.addons.website_sale.controllers.main import WebsiteSale
|
||||
|
||||
|
||||
class WebsiteSaleDigitalConfirmation(WebsiteSale):
|
||||
@http.route([
|
||||
'/shop/confirmation',
|
||||
@@ -22,7 +23,7 @@ class WebsiteSaleDigitalConfirmation(WebsiteSale):
|
||||
return response
|
||||
|
||||
|
||||
class WebsiteSaleDigital(website_account):
|
||||
class WebsiteSaleDigital(CustomerPortal):
|
||||
orders_page = '/my/orders'
|
||||
|
||||
@http.route([
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="orders_followup_downloads" name="Orders Downloads Followup" inherit_id="website_portal_sale.orders_followup">
|
||||
<template id="orders_followup_downloads" name="Orders Downloads Followup" inherit_id="sale.orders_followup">
|
||||
<xpath expr="//div[@id='product_name']" position="inside">
|
||||
<t t-set="attachments" t-value="digital_attachments.get(ol.product_id.id)"/>
|
||||
<t t-if="attachments">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="orders_followup_shipping" name="Orders Shipping Followup" inherit_id="website_portal_sale.orders_followup">
|
||||
<template id="orders_followup_shipping" name="Orders Shipping Followup" inherit_id="sale.orders_followup">
|
||||
<xpath expr="//div[@id='shipping_address']" position="inside">
|
||||
<t t-if="order.picking_ids">
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user