diff --git a/addons/website_portal/__init__.py b/addons/website_portal/__init__.py new file mode 100644 index 00000000000..355939a4922 --- /dev/null +++ b/addons/website_portal/__init__.py @@ -0,0 +1 @@ +import controllers \ No newline at end of file diff --git a/addons/website_portal/__openerp__.py b/addons/website_portal/__openerp__.py new file mode 100644 index 00000000000..61abb18fe4c --- /dev/null +++ b/addons/website_portal/__openerp__.py @@ -0,0 +1,24 @@ +{ + 'name': 'Website Portal', + 'category': 'Website', + 'summary': 'Account Management Frontend for your Customers', + 'version': '1.0', + 'description': """ +Allows your customers to manage their account from a beautiful web interface. + """, + 'author': 'Odoo SA', + 'website': 'https://www.odoo.com/', + 'depends': [ + 'sale', + 'website', + ], + 'data': [ + 'views/templates.xml', + ], + 'qweb': [ + ], + 'demo': [ + 'data/demo.xml' + ], + 'installable': True, +} diff --git a/addons/website_portal/controllers/__init__.py b/addons/website_portal/controllers/__init__.py new file mode 100644 index 00000000000..039d9715fab --- /dev/null +++ b/addons/website_portal/controllers/__init__.py @@ -0,0 +1 @@ +import main \ No newline at end of file diff --git a/addons/website_portal/controllers/main.py b/addons/website_portal/controllers/main.py new file mode 100644 index 00000000000..3f3c09c95e3 --- /dev/null +++ b/addons/website_portal/controllers/main.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +import datetime + +from openerp import http +from openerp.http import request +from openerp import tools +from openerp.tools.translate import _ + + +class website_account(http.Controller): + @http.route(['/my', '/my/home'], type='http', auth="public", website=True) + def account(self): + partner = request.env.user.partner_id + values = { + 'date': datetime.date.today().strftime('%Y-%m-%d') + } + + res_sale_order = request.env['sale.order'] + res_invoices = request.env['account.invoice'] + quotations = res_sale_order.search([ + ('partner_id.id', '=', partner.id), + ('state', 'in', ['sent', 'cancel']) + ]) + orders = res_sale_order.search([ + ('partner_id.id', '=', partner.id), + ('state', 'in', ['progress', 'manual', 'shipping_except', 'invoice_except', 'done']) + ]) + invoices = res_invoices.search([ + ('partner_id.id', '=', partner.id), + ('state', 'in', ['open', 'paid', 'cancelled']) + ]) + + values.update({ + 'quotations': quotations, + 'orders': orders, + 'invoices': invoices + }) + + # get customer sales rep + if partner.user_id: + sales_rep = partner.user_id + else: + sales_rep = False + values.update({ + 'sales_rep': sales_rep, + 'company': request.website.company_id, + 'user': request.env.user + }) + + return request.website.render("website_portal.account", values) + + @http.route(['/my/orders/'], type='http', auth="user", website=True) + def orders_followup(self, order=None): + partner = request.env['res.users'].browse(request.uid).partner_id + domain = [ + ('partner_id.id', '=', partner.id), + ('state', 'not in', ['draft', 'cancel']), + ('id', '=', order) + ] + order = request.env['sale.order'].search(domain) + invoiced_lines = request.env['account.invoice.line'].search([('invoice_id', 'in', order.invoice_ids.ids)]) + order_invoice_lines = {il.product_id.id: il.invoice_id for il in invoiced_lines} + + return request.website.render("website_portal.orders_followup", { + 'order': order.sudo(), + 'order_invoice_lines': order_invoice_lines, + }) + + @http.route(['/my/account'], type='http', auth='user', website=True) + def details(self, **post): + partner = request.env['res.users'].browse(request.uid).partner_id + values = { + 'error': {}, + 'error_message': [] + } + + if post: + error, error_message = self.details_form_validate(post) + values.update({'error': error, 'error_message': error_message}) + values.update(post) + if not error: + post.update({'zip': post.pop('zipcode', '')}) + partner.sudo().write(post) + return request.redirect('/my/home') + + countries = request.env['res.country'].sudo().search([]) + states = request.env['res.country.state'].sudo().search([]) + + values.update({ + 'partner': partner, + 'countries': countries, + 'states': states, + 'has_check_vat': hasattr(request.env['res.partner'], 'check_vat'), + }) + + return request.website.render("website_portal.details", values) + + def details_form_validate(self, data): + error = dict() + error_message = [] + + mandatory_billing_fields = ["name", "phone", "email", "street2", "city", "country_id"] + + # Validation + for field_name in mandatory_billing_fields: + if not data.get(field_name): + error[field_name] = 'missing' + + # email validation + if data.get('email') and not tools.single_email_re.match(data.get('email')): + error["email"] = 'error' + error_message.append(_('Invalid Email! Please enter a valid email address.')) + + # vat validation + if data.get("vat") and hasattr(request.env["res.partner"], "check_vat"): + if request.website.company_id.vat_check_vies: + # force full VIES online check + check_func = request.env["res.partner"].vies_vat_check + else: + # quick and partial off-line checksum validation + check_func = request.env["res.partner"].simple_vat_check + vat_country, vat_number = request.env["res.partner"]._split_vat(data.get("vat")) + if not check_func(vat_country, vat_number): # simple_vat_check + error["vat"] = 'error' + # error message for empty required fields + if [err for err in error.values() if err == 'missing']: + error_message.append(_('Some required fields are empty.')) + + return error, error_message diff --git a/addons/website_portal/data/demo.xml b/addons/website_portal/data/demo.xml new file mode 100644 index 00000000000..05c2672f14a --- /dev/null +++ b/addons/website_portal/data/demo.xml @@ -0,0 +1,123 @@ + + + + + + + + + + sent + + + + + + + + Laptop E5023 + + 3 + 3 + + 2950.00 + + + + + Pen drive, 16GB + + 5 + 5 + + 145.00 + + + + + Headset USB + + 2 + 2 + + 65.00 + + + + + + + + + manual + + + + + + + + Service on demand + + 24 + 24 + + 75.00 + + + + + On Site Assistance + + 30 + 30 + + 38.25 + + + + + + + + + + + + + + + open + out_invoice + + Test invoice 1 + + + Basic formation with Dvorak + + 500 + 1 + + + + + + + + + + paid + out_invoice + + Test invoice 1 + + + Service on demand + + 75 + 6 + + + + + diff --git a/addons/website_portal/static/src/css/website_portal.less b/addons/website_portal/static/src/css/website_portal.less new file mode 100644 index 00000000000..239244676a4 --- /dev/null +++ b/addons/website_portal/static/src/css/website_portal.less @@ -0,0 +1,30 @@ +/* ---- My Orders page ---- */ + +.orders_vertical_align { + display: flex; + align-items: center; +} + + +.orders_label_text_align { + vertical-align: 15%; +} + +.status_table { + th,td { + text-align: right; + } + th:nth-last-child(2) { + width: 150px; + } + th:nth-last-child(1), { + width: 120px; + } + th:nth-child(1), + td:nth-child(1) { + width: auto; + min-width: 150px; + text-align: left; + } + table-layout: fixed; +} \ No newline at end of file diff --git a/addons/website_portal/static/src/js/website_portal.js b/addons/website_portal/static/src/js/website_portal.js new file mode 100644 index 00000000000..709c72e97a7 --- /dev/null +++ b/addons/website_portal/static/src/js/website_portal.js @@ -0,0 +1,24 @@ +(function () { + 'use strict'; + + var website = openerp.website; + var qweb = openerp.qweb; + website.ready().done(function() { + + $('.oe_website_portal').on('change', "select[name='country_id']", function () { + var $select = $("select[name='state_id']"); + $select.find("option:not(:first)").hide(); + var nb = $select.find("option[data-country_id="+($(this).val() || 0)+"]").show().size(); + $select.parent().toggle(nb>1); + }); + $('.oe_website_portal').find("select[name='country_id']").change(); + + $('.wp_show_more').on('click', function(ev) { + ev.preventDefault(); + $(this).parents('table').find(".to_hide").toggleClass('hidden'); + $(this).find('span').toggleClass('hidden'); + }); + + }); + +})(); \ No newline at end of file diff --git a/addons/website_portal/views/templates.xml b/addons/website_portal/views/templates.xml new file mode 100644 index 00000000000..35ed0a5618a --- /dev/null +++ b/addons/website_portal/views/templates.xml @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/website_sale/__openerp__.py b/addons/website_sale/__openerp__.py index 88e1dd29516..dc1298136b4 100644 --- a/addons/website_sale/__openerp__.py +++ b/addons/website_sale/__openerp__.py @@ -10,7 +10,7 @@ OpenERP E-Commerce """, 'author': 'OpenERP SA', - 'depends': ['website', 'sale', 'payment'], + 'depends': ['website', 'sale', 'payment', 'website_portal'], 'data': [ 'data/data.xml', 'views/views.xml', diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 482ec694dbc..e5232cedff2 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -346,33 +346,6 @@ class website_sale(http.Controller): }) return value - @http.route([ - '/shop/orders', - '/shop/orders/page/', - ], type='http', auth="user", website=True) - def orders_followup(self, page=1, by = 5, **post): - partner = request.env['res.users'].browse(request.uid).partner_id - orders = request.env['sale.order'].sudo().search([('partner_id', '=', partner.id), ('state', 'not in', ['draft', 'cancel'])]) - - nbr_pages = max((len(orders) / by) + (1 if len(orders) % by > 0 else 0), 1) - page = min(page, nbr_pages) - pager = request.website.pager( - url='/shop/orders', total=nbr_pages, page=page, step=1, - scope=by, url_args=post - ) - orders = orders[by*(page-1):by*(page-1)+by] - - order_invoice_lines = {} - for o in orders: - invoiced_lines = request.env['account.invoice.line'].sudo().search([('invoice_id', 'in', o.invoice_ids.ids)]) - order_invoice_lines[o.id] = {il.product_id.id: il.invoice_id for il in invoiced_lines} - - return request.website.render("website_sale.orders_followup", { - 'orders': orders, - 'order_invoice_lines': order_invoice_lines, - 'pager': pager, - }) - #------------------------------------------------------ # Checkout #------------------------------------------------------ diff --git a/addons/website_sale/static/src/css/website_sale.css b/addons/website_sale/static/src/css/website_sale.css index 4aca45b7f18..6a5b20e76d1 100644 --- a/addons/website_sale/static/src/css/website_sale.css +++ b/addons/website_sale/static/src/css/website_sale.css @@ -1,83 +1,101 @@ +@charset "utf-8"; /* ---- Default Styles ---- */ .oe_product { - border: 1px solid rgba(100, 100, 100, 0.2); } + border: 1px solid rgba(100, 100, 100, 0.2); +} .products_pager { - text-align: center; } - .products_pager > div { - margin: 0 auto; - display: inline-block; } - .products_pager > div > * { - vertical-align: middle; - float: none; - padding: 0; } - .products_pager > div > ul { - padding-left: 10px; } - .products_pager > ul { - margin-left: auto; - margin-right: auto; } + text-align: center; +} +.products_pager > div { + margin: 0 auto; + display: inline-block; +} +.products_pager > div > * { + vertical-align: middle; + float: none; + padding: 0; +} +.products_pager > div > ul { + padding-left: 10px; +} +.products_pager > ul { + margin-left: auto; + margin-right: auto; +} .oe_website_sale ul ul { - margin-left: 1.5em; } + margin-left: 1.5em; +} /* ---- Default Styles ---- */ .oe_product { - position: relative; } - .oe_product .oe_product_image { - position: absolute; - left: 15px; - right: 15px; - top: 15px; - bottom: 55px; - text-align: center; } - .oe_product .oe_product_image img { - max-width: 100%; - max-height: 100%; - margin: auto; - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - z-index: 4; } - .oe_product section { - position: absolute; - left: 0; - right: 0; - bottom: 0; - overflow: hidden; - padding: 0 15px 24px 10px; - min-height: 56px; - border-top: 1px solid rgba(255, 255, 255, 0.2); - background: rgba(255, 255, 255, 0.75); - z-index: 5; } - .oe_product .product_price { - padding: 5px 0; - position: absolute; - bottom: 0; } - .oe_product .oe_product_cart { - position: relative; - width: 100%; - height: 100%; } - .oe_product .oe_subdescription { - font-size: 0.8em; - overflow: hidden; - margin-bottom: 10px; } + position: relative; +} +.oe_product .oe_product_image { + position: absolute; + left: 15px; + right: 15px; + top: 15px; + bottom: 55px; + text-align: center; +} +.oe_product .oe_product_image img { + max-width: 100%; + max-height: 100%; + margin: auto; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + z-index: 4; +} +.oe_product section { + position: absolute; + left: 0; + right: 0; + bottom: 0; + overflow: hidden; + padding: 0 15px 24px 10px; + min-height: 56px; + border-top: 1px solid rgba(255, 255, 255, 0.2); + background: rgba(255, 255, 255, 0.75); + z-index: 5; +} +.oe_product .product_price { + padding: 5px 0; + position: absolute; + bottom: 0; +} +.oe_product .oe_product_cart { + position: relative; + width: 100%; + height: 100%; +} +.oe_product .oe_subdescription { + font-size: 0.8em; + overflow: hidden; + margin-bottom: 10px; +} .oe_mycart .input-group-addon { padding-left: 6px; - padding-right: 6px; } + padding-right: 6px; +} /* Products Options */ .oe_product.oe_image_full .oe_product_image { left: 0; right: 0; top: 0; - bottom: 0; } + bottom: 0; +} /* Ribbon for promotionso on products */ .oe_product.oe_ribbon_promo .ribbon-wrapper { - display: block; } + display: block; +} .oe_product .ribbon-wrapper { display: none; width: 85px; @@ -86,7 +104,8 @@ overflow: hidden; position: absolute; top: 0; - right: 0; } + right: 0; +} .oe_product .ribbon { font: bold 15px Sans-Serif; color: white; @@ -100,97 +119,137 @@ left: -5px; top: 15px; width: 120px; - cursor: default; } + cursor: default; +} /* ---- Product Sizes ---- */ .col-md-12 .oe-height-1 { - height: 75px; } + height: 75px; +} .col-md-12 .oe-height-2 { - height: 150px; } + height: 150px; +} .col-md-12 .oe-height-4 { - height: 300px; } + height: 300px; +} .col-md-12 .oe-height-6 { - height: 450px; } + height: 450px; +} .col-md-12 .oe-height-8 { - height: 600px; } + height: 600px; +} .col-md-9 .oe-height-1 { - height: 70px; } + height: 70px; +} .col-md-9 .oe-height-2 { - height: 140px; } + height: 140px; +} .col-md-9 .oe-height-4 { - height: 280px; } + height: 280px; +} .col-md-9 .oe-height-6 { - height: 420px; } + height: 420px; +} .col-md-9 .oe-height-8 { - height: 560px; } + height: 560px; +} @media (max-width: 768px) { #products_grid table, #products_grid tbody, #products_grid tr, #products_grid td { float: left; width: 100%; - display: inline-block; } + display: inline-block; + } #products_grid .oe_product { float: left; width: 100%; height: 300px; - display: inline-block; } + display: inline-block; + } .products_pager .pagination { - margin: 5px auto !important; } } + margin: 5px auto !important; + } +} @media (max-width: 400px) { #products_grid .oe_product { - height: 270px; } - #products_grid .oe_product section { - background: rgba(100, 100, 100, 0.2); } - #products_grid .oe_product .oe_product_image { - top: 0; - bottom: 65px; } + height: 270px; + } + #products_grid .oe_product section { + background: rgba(100, 100, 100, 0.2); + } + #products_grid .oe_product .oe_product_image { + top: 0; + bottom: 65px; + } #products_grid .oe_product.oe_image_full .oe_product_image { - bottom: 50px; } } + bottom: 50px; + } +} @media (min-width: 992px) { .col-md-12 .oe-height-1 { - height: 95px; } + height: 95px; + } .col-md-12 .oe-height-2 { - height: 190px; } + height: 190px; + } .col-md-12 .oe-height-4 { - height: 380px; } + height: 380px; + } .col-md-12 .oe-height-6 { - height: 570px; } + height: 570px; + } .col-md-12 .oe-height-8 { - height: 760px; } + height: 760px; + } .col-md-9 .oe-height-1 { - height: 72px; } + height: 72px; + } .col-md-9 .oe-height-2 { - height: 144px; } + height: 144px; + } .col-md-9 .oe-height-4 { - height: 288px; } + height: 288px; + } .col-md-9 .oe-height-6 { - height: 432px; } + height: 432px; + } .col-md-9 .oe-height-8 { - height: 576px; } } + height: 576px; + } +} @media (min-width: 1200px) { .col-md-12 .oe-height-1 { - height: 125px; } + height: 125px; + } .col-md-12 .oe-height-2 { - height: 250px; } + height: 250px; + } .col-md-12 .oe-height-4 { - height: 500px; } + height: 500px; + } .col-md-12 .oe-height-6 { - height: 750px; } + height: 750px; + } .col-md-12 .oe-height-8 { - height: 1000px; } + height: 1000px; + } .col-md-9 .oe-height-1 { - height: 95px; } + height: 95px; + } .col-md-9 .oe-height-2 { - height: 190px; } + height: 190px; + } .col-md-9 .oe-height-4 { - height: 380px; } + height: 380px; + } .col-md-9 .oe-height-6 { - height: 570px; } + height: 570px; + } .col-md-9 .oe-height-8 { height: 760px; } } /* ---- Cart ---- */ @@ -274,98 +333,115 @@ width: 100%; min-height: 100px; position: relative; - padding-bottom: 5px; } - .oe_product.oe_list .oe_product_image { - top: 0; - bottom: 0; - left: 0; - right: 0; - width: 170px; } - .oe_product.oe_list section { - position: relative; - border: 0; - top: 0; - bottom: auto; - left: 180px; - background: transparent; } } + padding-bottom: 5px; + } + .oe_product.oe_list .oe_product_image { + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 170px; + } + .oe_product.oe_list section { + position: relative; + border: 0; + top: 0; + bottom: auto; + left: 180px; + background: transparent; + } +} .oe_website_sale .row .row .col-md-12 { - float: none; } + float: none; +} /* product detail */ .css_attribute_color { display: inline-block; border: 1px solid #999999; - text-align: center; } - .css_attribute_color input { - margin: 8px; - height: 13px; - opacity: 0; } - .css_attribute_color.active { - border: 3px ridge #66ee66; } - .css_attribute_color.active input { - margin: 6px; } + text-align: center; +} +.css_attribute_color input { + margin: 8px; + height: 13px; + opacity: 0; +} +.css_attribute_color.active { + border: 3px ridge #66ee66; +} +.css_attribute_color.active input { + margin: 6px; +} .css_not_available_msg { - display: none; } + display: none; +} .css_not_available.js_product > *:nth-child(4) > * { - display: none; } + display: none; +} .css_not_available.js_product .product_price, .css_not_available.js_product .css_quantity { - display: none; } + display: none; +} .css_not_available.js_product .css_not_available_msg { - display: block; } + display: block; +} option.css_not_available { - color: #ccc; } + color: #cccccc; +} label.css_not_available { - opacity: 0.6; } + opacity: 0.6; +} label.css_attribute_color.css_not_available { opacity: 1; background-image: url("/website_sale/static/src/img/redcross.png"); - background-size: cover; } + background-size: cover; +} .product_detail_img { margin-left: auto; margin-right: auto; display: block; - max-height: 500px; } + max-height: 500px; +} .oe_default_price { - display: none; } + display: none; +} .discount .oe_default_price { - display: block; } + display: block; +} .oe_website_sale input.js_quantity { min-width: 48px; - text-align: center; } + text-align: center; +} /* ---- Publish managment and options ---- */ .oe_overlay_options .dropdown ul[name="size"] table { - margin-left: 20px; } + margin-left: 20px; +} .oe_overlay_options .dropdown ul[name="size"] td { margin: 0; padding: 0; width: 20px; height: 20px; border: 1px #dddddd solid; - cursor: pointer; } - .oe_overlay_options .dropdown ul[name="size"] td.selected { - background-color: #B1D4F1; } + cursor: pointer; +} +.oe_overlay_options .dropdown ul[name="size"] td.selected { + background-color: #b1d4f1; +} .oe_overlay_options .dropdown ul[name="size"] table.oe_hover td.selected { - background-color: transparent; } + background-color: transparent; +} .oe_overlay_options .dropdown ul[name="size"] table.oe_hover td.select { - background-color: #B1D4F1; } - -/* ---- My Orders page ---- */ -.orders_vertical_align { - display: flex; - align-items: center; } - -.orders_label_text_align { - vertical-align: 15%; } + background-color: #b1d4f1; +} /* Wizard */ ul.wizard { @@ -377,7 +453,8 @@ ul.wizard { border-radius: 4px; -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.065); -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.065); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.065); } + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.065); +} ul.wizard li { border: 1px solid #d4d4d4; @@ -387,7 +464,8 @@ ul.wizard li { padding: 0 10px 0 20px; margin: 0; line-height: 38px; - background: #fbfbfb; } + background: #fbfbfb; +} ul.wizard li .chevron { position: absolute; @@ -397,7 +475,8 @@ ul.wizard li .chevron { display: block; border: 20px solid transparent; border-right: 0; - border-left: 10px solid #d4d4d4; } + border-left: 10px solid #d4d4d4; +} ul.wizard li .chevron:before { position: absolute; @@ -407,19 +486,24 @@ ul.wizard li .chevron:before { border: 20px solid transparent; border-right: 0; border-left: 10px solid #fbfbfb; - content: ""; } + content: ""; +} ul.wizard li.text-success { - background: #f3f4f5; } + background: #f3f4f5; +} ul.wizard li.text-success .chevron:before { - border-left: 10px solid #f5f5f5; } + border-left: 10px solid whitesmoke; +} ul.wizard li.text-primary { - background: #f1f6fc; } + background: #f1f6fc; +} ul.wizard li.text-primary .chevron:before { - border-left: 10px solid #f1f6fc; } + border-left: 10px solid #f1f6fc; +} ul.wizard li:first-child { padding-left: 15px; diff --git a/addons/website_sale/static/src/css/website_sale.sass b/addons/website_sale/static/src/css/website_sale.sass index d46881c869f..66d98183fb9 100644 --- a/addons/website_sale/static/src/css/website_sale.sass +++ b/addons/website_sale/static/src/css/website_sale.sass @@ -367,17 +367,6 @@ label.css_attribute_color.css_not_available table.oe_hover td.select background-color: #B1D4F1 -/* ---- My Orders page ---- */ - -.orders_vertical_align - display: flex - align-items: center - - -.orders_label_text_align - vertical-align: 15% - - /* Wizard */ diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index b798aa3873c..efc62d1393a 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -1245,217 +1245,5 @@
  • New Product
  • - - - - - - - - - - - diff --git a/addons/website_sale_digital/controllers/main.py b/addons/website_sale_digital/controllers/main.py index 276d1752c4e..1f725890b4b 100644 --- a/addons/website_sale_digital/controllers/main.py +++ b/addons/website_sale_digital/controllers/main.py @@ -4,68 +4,69 @@ import base64 from openerp.addons.web import http from openerp.addons.web.http import request from openerp.addons.website.controllers.main import Website +from openerp.addons.website_portal.controllers.main import website_account from openerp.addons.website_sale.controllers.main import website_sale from cStringIO import StringIO from werkzeug.utils import redirect -class website_sale_digital(website_sale): - - orders_page = '/shop/orders' +class website_sale_digital_confirmation(website_sale): @http.route([ '/shop/confirmation', ], type='http', auth="public", website=True) def payment_confirmation(self, **post): - response = super(website_sale_digital, self).payment_confirmation(**post) + response = super(website_sale_digital_confirmation, self).payment_confirmation(**post) order_lines = response.qcontext['order'].order_line digital_content = map(lambda x: x.product_id.digital_content, order_lines) response.qcontext.update(digital=any(digital_content)) return response + +class website_sale_digital(website_account): + + orders_page = '/my/orders' + @http.route([ - '/shop/orders', - '/shop/orders/page/', + '/my/orders/', ], type='http', auth='user', website=True) - def orders_followup(self, page=1, **post): - response = super(website_sale_digital, self).orders_followup(**post) + def orders_followup(self, order=None, **post): + response = super(website_sale_digital, self).orders_followup(order=order, **post) order_products_attachments = {} - for o in response.qcontext['orders']: - invoiced_lines = request.env['account.invoice.line'].sudo().search([('invoice_id', 'in', o.invoice_ids.ids), ('invoice_id.state', '=', 'paid')]) + order = response.qcontext['order'] + invoiced_lines = request.env['account.invoice.line'].sudo().search([('invoice_id', 'in', order.invoice_ids.ids), ('invoice_id.state', '=', 'paid')]) - purchased_products_attachments = {} - for il in invoiced_lines: - p_obj = il.product_id - # Ignore products that do not have digital content - if not p_obj.product_tmpl_id.digital_content: - continue + purchased_products_attachments = {} + for il in invoiced_lines: + p_obj = il.product_id + # Ignore products that do not have digital content + if not p_obj.product_tmpl_id.digital_content: + continue - # Search for product attachments - A = request.env['ir.attachment'] - p_id = p_obj.id - template = p_obj.product_tmpl_id - att = A.search_read( - domain=['|', '&', ('res_model', '=', p_obj._name), ('res_id', '=', p_id), '&', ('res_model', '=', template._name), ('res_id', '=', template.id)], - fields=['name', 'write_date'], - order='write_date desc', - ) + # Search for product attachments + A = request.env['ir.attachment'] + p_id = p_obj.id + template = p_obj.product_tmpl_id + att = A.search_read( + domain=['|', '&', ('res_model', '=', p_obj._name), ('res_id', '=', p_id), '&', ('res_model', '=', template._name), ('res_id', '=', template.id)], + fields=['name', 'write_date'], + order='write_date desc', + ) - # Ignore products with no attachments - if not att: - continue + # Ignore products with no attachments + if not att: + continue - purchased_products_attachments[p_id] = att - - order_products_attachments[o.id] = purchased_products_attachments + purchased_products_attachments[p_id] = att response.qcontext.update({ - 'digital_attachments': order_products_attachments, + 'digital_attachments': purchased_products_attachments, }) return response @http.route([ - '/shop/download', + '/my/download', ], type='http', auth='public') def download_attachment(self, attachment_id): # Check if this is a valid attachment id diff --git a/addons/website_sale_digital/views/website_sale_digital.xml b/addons/website_sale_digital/views/website_sale_digital.xml index b62c315fdb6..ec4e2d14067 100644 --- a/addons/website_sale_digital/views/website_sale_digital.xml +++ b/addons/website_sale_digital/views/website_sale_digital.xml @@ -1,8 +1,8 @@ -