diff --git a/addons/website_portal_purchase/__init__.py b/addons/website_portal_purchase/__init__.py new file mode 100644 index 00000000000..ac0011716f6 --- /dev/null +++ b/addons/website_portal_purchase/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import controllers +import models diff --git a/addons/website_portal_purchase/__manifest__.py b/addons/website_portal_purchase/__manifest__.py new file mode 100644 index 00000000000..473ee58521f --- /dev/null +++ b/addons/website_portal_purchase/__manifest__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Website Portal for Purchases', + 'category': 'Website', + 'summary': 'Add your purchase orders in the frontend portal', + 'version': '1.0', + 'description': """ +Display purchase orders on your website. Customers will be able to access their purchase orders in their own portal, see their state and communicate with salesmen. + """, + 'depends': [ + 'purchase', + 'website_portal', + ], + 'data': [ + 'views/website_portal_purchase_templates.xml', + 'security/ir.model.access.csv', + 'security/website_portal_purchase_security.xml', + ], + 'installable': True, +} diff --git a/addons/website_portal_purchase/controllers/__init__.py b/addons/website_portal_purchase/controllers/__init__.py new file mode 100644 index 00000000000..64e12cc7845 --- /dev/null +++ b/addons/website_portal_purchase/controllers/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import website_portal diff --git a/addons/website_portal_purchase/controllers/website_portal.py b/addons/website_portal_purchase/controllers/website_portal.py new file mode 100644 index 00000000000..4d8762e4346 --- /dev/null +++ b/addons/website_portal_purchase/controllers/website_portal.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from collections import OrderedDict + +from odoo import http +from odoo.exceptions import AccessError +from odoo.http import request +from odoo.tools.translate import _ + +from odoo.addons.website_portal.controllers.main import website_account, get_records_pager + + +class WebsitePortal(website_account): + + def _prepare_portal_layout_values(self): + values = super(WebsitePortal, self)._prepare_portal_layout_values() + partner = request.env.user.partner_id + values['purchase_count'] = request.env['purchase.order'].search_count([ + '|', + ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]), + ('partner_id', 'child_of', [partner.commercial_partner_id.id]), + ('state', 'in', ['purchase', 'done', 'cancel']) + ]) + return values + + @http.route(['/my/purchase', '/my/purchase/page/'], type='http', auth="user", website=True) + def portal_my_purchase_orders(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw): + values = self._prepare_portal_layout_values() + partner = request.env.user.partner_id + PurchaseOrder = request.env['purchase.order'] + + domain = [ + '|', + ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]), + ('partner_id', 'child_of', [partner.commercial_partner_id.id]), + ] + + archive_groups = self._get_archive_groups('purchase.order', domain) + if date_begin and date_end: + domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)] + + searchbar_sortings = { + 'date': {'label': _('Newest'), 'order': 'create_date desc, id desc'}, + 'name': {'label': _('Name'), 'order': 'name asc, id asc'}, + 'amount_total': {'label': _('Total'), 'order': 'amount_total desc, id desc'}, + } + # default sort by value + if not sortby: + sortby = 'date' + order = searchbar_sortings[sortby]['order'] + + searchbar_filters = { + 'all': {'label': _('All'), 'domain': [('state', 'in', ['purchase', 'done', 'cancel'])]}, + 'purchase': {'label': _('Purchase Order'), 'domain': [('state', '=', 'purchase')]}, + 'cancel': {'label': _('Cancelled'), 'domain': [('state', '=', 'cancel')]}, + 'done': {'label': _('Locked'), 'domain': [('state', '=', 'done')]}, + } + # default filter by value + if not filterby: + filterby = 'all' + domain += searchbar_filters[filterby]['domain'] + + # count for pager + purchase_count = PurchaseOrder.search_count(domain) + # make pager + pager = request.website.pager( + url="/my/purchase", + url_args={'date_begin': date_begin, 'date_end': date_end}, + total=purchase_count, + page=page, + step=self._items_per_page + ) + # search the purchase orders to display, according to the pager data + orders = PurchaseOrder.search( + domain, + order=order, + limit=self._items_per_page, + offset=pager['offset'] + ) + request.session['my_purchases_history'] = orders.ids[:100] + + values.update({ + 'date': date_begin, + 'orders': orders, + 'page_name': 'purchase', + 'pager': pager, + 'archive_groups': archive_groups, + 'searchbar_sortings': searchbar_sortings, + 'sortby': sortby, + 'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())), + 'filterby': filterby, + 'default_url': '/my/purchase', + }) + return request.render("website_portal_purchase.portal_my_purchase_orders", values) + + @http.route(['/my/purchase/'], type='http', auth="user", website=True) + def portal_my_purchase_order(self, order_id=None, **kw): + order = request.env['purchase.order'].browse(order_id) + try: + order.check_access_rights('read') + order.check_access_rule('read') + except AccessError: + return request.render("website.403") + history = request.session.get('my_purchases_history', []) + values = { + 'order': order.sudo(), + } + values.update(get_records_pager(history, order)) + return request.render("website_portal_purchase.portal_my_purchase_order", values) diff --git a/addons/website_portal_purchase/models/__init__.py b/addons/website_portal_purchase/models/__init__.py new file mode 100644 index 00000000000..5fcefe23eeb --- /dev/null +++ b/addons/website_portal_purchase/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import purchase diff --git a/addons/website_portal_purchase/models/purchase.py b/addons/website_portal_purchase/models/purchase.py new file mode 100644 index 00000000000..10e55775c21 --- /dev/null +++ b/addons/website_portal_purchase/models/purchase.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class PurchaseOrder(models.Model): + + _inherit = 'purchase.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 order in self: + order.website_url = '/my/purchase/%s' % (order.id) + + +class PurchaseOrderLine(models.Model): + + _inherit = 'purchase.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") diff --git a/addons/website_portal_purchase/security/ir.model.access.csv b/addons/website_portal_purchase/security/ir.model.access.csv new file mode 100644 index 00000000000..1405075a7a6 --- /dev/null +++ b/addons/website_portal_purchase/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_purchase_order_portal,purchase.order.portal,purchase.model_purchase_order,base.group_portal,1,0,0,0 +access_purchase_order_line_portal,purchase.order.line.portal,purchase.model_purchase_order_line,base.group_portal,1,0,0,0 diff --git a/addons/website_portal_purchase/security/website_portal_purchase_security.xml b/addons/website_portal_purchase/security/website_portal_purchase_security.xml new file mode 100644 index 00000000000..d689d887377 --- /dev/null +++ b/addons/website_portal_purchase/security/website_portal_purchase_security.xml @@ -0,0 +1,24 @@ + + + + + + Portal Purchase Orders + + [('message_partner_ids','child_of',[user.commercial_partner_id.id])] + + + + + + + + + Portal Purhcase Orders Line + + [('order_id.message_partner_ids','child_of',[user.commercial_partner_id.id])] + + + + + diff --git a/addons/website_portal_purchase/static/src/less/website_portal_purchase.less b/addons/website_portal_purchase/static/src/less/website_portal_purchase.less new file mode 100644 index 00000000000..a8a074ea11b --- /dev/null +++ b/addons/website_portal_purchase/static/src/less/website_portal_purchase.less @@ -0,0 +1,6 @@ +/* ---- My Purchase Orders page ---- */ + +.purchases_vertical_align { + display: flex; + align-items: center; +} diff --git a/addons/website_portal_purchase/views/website_portal_purchase_templates.xml b/addons/website_portal_purchase/views/website_portal_purchase_templates.xml new file mode 100644 index 00000000000..861e1b84892 --- /dev/null +++ b/addons/website_portal_purchase/views/website_portal_purchase_templates.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + diff --git a/addons/website_portal_sale/views/website_portal_sale_templates.xml b/addons/website_portal_sale/views/website_portal_sale_templates.xml index a01de67c800..c08351be785 100644 --- a/addons/website_portal_sale/views/website_portal_sale_templates.xml +++ b/addons/website_portal_sale/views/website_portal_sale_templates.xml @@ -12,8 +12,13 @@ Quotes
  • - Orders + Sales Orders
  • + + + + + +