diff --git a/addons/website_sale_slides/__manifest__.py b/addons/website_sale_slides/__manifest__.py
index 4a0ab8ae952..3ef082aca44 100644
--- a/addons/website_sale_slides/__manifest__.py
+++ b/addons/website_sale_slides/__manifest__.py
@@ -10,6 +10,7 @@
'depends': ['website_slides', 'website_sale'],
'installable': True,
'data': [
+ 'data/product_data.xml',
'report/sale_report_views.xml',
'views/website_slides_menu_views.xml',
'views/slide_channel_views.xml',
@@ -25,6 +26,9 @@
'web.assets_frontend': [
'website_sale_slides/static/src/js/**/*',
],
+ 'web.assets_qweb': [
+ 'website_sale_slides/static/src/xml/website_slides_channel.xml',
+ ]
},
'license': 'LGPL-3',
}
diff --git a/addons/website_sale_slides/controllers/slides.py b/addons/website_sale_slides/controllers/slides.py
index 3debae40eef..67b76bd1f6a 100644
--- a/addons/website_sale_slides/controllers/slides.py
+++ b/addons/website_sale_slides/controllers/slides.py
@@ -2,11 +2,22 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.website_slides.controllers.main import WebsiteSlides
-from odoo.http import request
+from odoo.http import request, route
+from odoo.tools import format_amount
class WebsiteSaleSlides(WebsiteSlides):
+ @route('/slides/get_course_products', type='json', auth='user')
+ def get_course_products(self):
+ """Return a list of the course products values with formatted price."""
+ products = request.env['product.product'].search([('detailed_type', '=', 'course')])
+
+ return [{
+ 'id': product.id,
+ 'name': f'{product.name} ({format_amount(request.env, product.list_price, product.currency_id)})',
+ } for product in products]
+
def _prepare_additional_channel_values(self, values, **kwargs):
values = super(WebsiteSaleSlides, self)._prepare_additional_channel_values(values, **kwargs)
channel = values['channel']
@@ -15,3 +26,13 @@ class WebsiteSaleSlides(WebsiteSlides):
values['product_info'] = channel.product_id.product_tmpl_id._get_combination_info(product_id=channel.product_id.id, pricelist=pricelist)
values['product_info']['currency_id'] = request.website.currency_id
return values
+
+ def _slide_channel_prepare_values(self, **kwargs):
+ """Parse the values posted when we create a new course
+ from website to add the selected product.
+ """
+ channel = super(WebsiteSaleSlides, self)._slide_channel_prepare_values(**kwargs)
+ channel['enroll'] = kwargs.get('enroll')
+ if channel['enroll'] == 'payment' and 'product_id' in kwargs:
+ channel['product_id'] = int(kwargs['product_id'])
+ return channel
diff --git a/addons/website_sale_slides/data/product_data.xml b/addons/website_sale_slides/data/product_data.xml
new file mode 100644
index 00000000000..82d60e5339a
--- /dev/null
+++ b/addons/website_sale_slides/data/product_data.xml
@@ -0,0 +1,17 @@
+
+
+
+ Courses
+
+
+
+ Course Access
+ 99.99
+ 99.99
+ course
+ order
+
+
+
+
+
diff --git a/addons/website_sale_slides/data/product_demo.xml b/addons/website_sale_slides/data/product_demo.xml
index 90ed00688f6..95f549df859 100644
--- a/addons/website_sale_slides/data/product_demo.xml
+++ b/addons/website_sale_slides/data/product_demo.xml
@@ -6,7 +6,7 @@
Taking care of Trees Course
150.0
150.0
- service
+ course
order
@@ -18,7 +18,7 @@
DIY Furniture Course
100.0
100.0
- service
+ course
order
diff --git a/addons/website_sale_slides/models/__init__.py b/addons/website_sale_slides/models/__init__.py
index a7ae607df42..848605c053e 100644
--- a/addons/website_sale_slides/models/__init__.py
+++ b/addons/website_sale_slides/models/__init__.py
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
from . import product_product
-from . import slide_channel
+from . import product_template
from . import sale_order
+from . import slide_channel
+from . import website
diff --git a/addons/website_sale_slides/models/product_product.py b/addons/website_sale_slides/models/product_product.py
index 94fc0c6e82b..7d3cacf6d35 100644
--- a/addons/website_sale_slides/models/product_product.py
+++ b/addons/website_sale_slides/models/product_product.py
@@ -1,10 +1,18 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo import fields, models
+from odoo import _, fields, models
class Product(models.Model):
_inherit = "product.product"
channel_ids = fields.One2many('slide.channel', 'product_id', string='Courses')
+
+ def get_product_multiline_description_sale(self):
+ payment_channels = self.channel_ids.filtered(lambda course: course.enroll == 'payment')
+
+ if not payment_channels:
+ return super(Product, self).get_product_multiline_description_sale()
+
+ return _('Access to:\n%s', '\n'.join(payment_channels.mapped('name')))
diff --git a/addons/website_sale_slides/models/product_template.py b/addons/website_sale_slides/models/product_template.py
new file mode 100644
index 00000000000..caad6854d95
--- /dev/null
+++ b/addons/website_sale_slides/models/product_template.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models
+
+
+class ProductTemplate(models.Model):
+ _inherit = 'product.template'
+
+ detailed_type = fields.Selection(selection_add=[
+ ('course', 'Course'),
+ ], ondelete={'course': 'set service'})
+
+ def _detailed_type_mapping(self):
+ type_mapping = super(ProductTemplate, self)._detailed_type_mapping()
+ type_mapping['course'] = 'service'
+ return type_mapping
diff --git a/addons/website_sale_slides/models/sale_order.py b/addons/website_sale_slides/models/sale_order.py
index 03e345df922..08646c8df4c 100644
--- a/addons/website_sale_slides/models/sale_order.py
+++ b/addons/website_sale_slides/models/sale_order.py
@@ -17,7 +17,7 @@ class SaleOrder(models.Model):
)
products = so_lines.mapped('product_id')
related_channels = self.env['slide.channel'].search(
- [('product_id', 'in', products.ids)]
+ [('product_id', 'in', products.ids), ('enroll', '=', 'payment')],
)
channel_products = related_channels.mapped('product_id')
diff --git a/addons/website_sale_slides/models/slide_channel.py b/addons/website_sale_slides/models/slide_channel.py
index 37d158e0898..da503a966ef 100644
--- a/addons/website_sale_slides/models/slide_channel.py
+++ b/addons/website_sale_slides/models/slide_channel.py
@@ -7,10 +7,16 @@ from odoo import api, fields, models
class Channel(models.Model):
_inherit = 'slide.channel'
+ def _get_default_product_id(self):
+ product_courses = self.env['product.product'].search(
+ [('detailed_type', '=', 'course')], limit=2)
+ return product_courses.id if len(product_courses) == 1 else False
+
enroll = fields.Selection(selection_add=[
('payment', 'On payment')
], ondelete={'payment': lambda recs: recs.write({'enroll': 'invite'})})
- product_id = fields.Many2one('product.product', 'Product', index=True)
+ product_id = fields.Many2one('product.product', 'Product', domain=[('detailed_type', '=', 'course')],
+ default=_get_default_product_id)
product_sale_revenues = fields.Monetary(
string='Total revenues', compute='_compute_product_sale_revenues',
groups="sales_team.group_sale_salesman")
diff --git a/addons/website_sale_slides/models/website.py b/addons/website_sale_slides/models/website.py
new file mode 100644
index 00000000000..e110e51a26e
--- /dev/null
+++ b/addons/website_sale_slides/models/website.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models
+from odoo.osv import expression
+
+
+class Website(models.Model):
+ _inherit = 'website'
+
+ def sale_product_domain(self):
+ return expression.AND([
+ super(Website, self).sale_product_domain(),
+ [('detailed_type', '!=', 'course')],
+ ])
diff --git a/addons/website_sale_slides/static/img/default_course_product.svg b/addons/website_sale_slides/static/img/default_course_product.svg
new file mode 100644
index 00000000000..67682f913b3
--- /dev/null
+++ b/addons/website_sale_slides/static/img/default_course_product.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/addons/website_sale_slides/static/src/js/website_sale_slides_editor.js b/addons/website_sale_slides/static/src/js/website_sale_slides_editor.js
new file mode 100644
index 00000000000..349ca3793c4
--- /dev/null
+++ b/addons/website_sale_slides/static/src/js/website_sale_slides_editor.js
@@ -0,0 +1,26 @@
+/** @odoo-module **/
+
+import {ChannelCreateDialog} from '@website_slides/js/website_slides.editor';
+
+ChannelCreateDialog.include({
+ xmlDependencies: ChannelCreateDialog.prototype.xmlDependencies.concat(
+ ['/website_sale_slides/static/src/xml/website_slides_channel.xml']
+ ),
+
+ events: _.extend({}, ChannelCreateDialog.prototype.events, {
+ 'change input[name="enroll"]': '_onEnrollChanged',
+ }),
+
+ willStart: async function () {
+ await this._super();
+
+ this.products = await this._rpc({route: '/slides/get_course_products'});
+ },
+
+ /**
+ * @private
+ */
+ _onEnrollChanged: function (ev) {
+ this.$('.o_wslides_course_products').toggleClass('d-none', ev.target.value !== 'payment');
+ },
+});
diff --git a/addons/website_sale_slides/static/src/xml/website_slides_channel.xml b/addons/website_sale_slides/static/src/xml/website_slides_channel.xml
new file mode 100644
index 00000000000..1b03ebccf96
--- /dev/null
+++ b/addons/website_sale_slides/static/src/xml/website_slides_channel.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/website_sale_slides/views/slide_channel_views.xml b/addons/website_sale_slides/views/slide_channel_views.xml
index d334b8931f2..3cb54e7316f 100644
--- a/addons/website_sale_slides/views/slide_channel_views.xml
+++ b/addons/website_sale_slides/views/slide_channel_views.xml
@@ -8,7 +8,7 @@
+ context="{'default_detailed_type': 'course', 'default_invoice_policy': 'order', 'default_purchase_ok': False, 'default_sale_ok': True, 'default_website_published': True}"/>