Browse Source

Aug 31: [ADD] Initial commit 'website_subscription_package'

pull/254/merge
Cybrosys Technologies 8 months ago
parent
commit
a23ce831c9
  1. 48
      website_subscription_package/README.rst
  2. 23
      website_subscription_package/__init__.py
  3. 53
      website_subscription_package/__manifest__.py
  4. 23
      website_subscription_package/controllers/__init__.py
  5. 98
      website_subscription_package/controllers/portal.py
  6. 133
      website_subscription_package/controllers/website_subscription_package.py
  7. 56
      website_subscription_package/data/mail_template_data.xml
  8. 6
      website_subscription_package/doc/RELEASE_NOTES.md
  9. 26
      website_subscription_package/models/__init__.py
  10. 46
      website_subscription_package/models/product_product.py
  11. 49
      website_subscription_package/models/product_template.py
  12. 39
      website_subscription_package/models/sale_order.py
  13. 36
      website_subscription_package/models/sale_order_line.py
  14. 120
      website_subscription_package/models/subscription_package.py
  15. 2
      website_subscription_package/security/ir.model.access.csv
  16. BIN
      website_subscription_package/static/description/assets/icons/check.png
  17. BIN
      website_subscription_package/static/description/assets/icons/chevron.png
  18. BIN
      website_subscription_package/static/description/assets/icons/cogs.png
  19. BIN
      website_subscription_package/static/description/assets/icons/consultation.png
  20. BIN
      website_subscription_package/static/description/assets/icons/ecom-black.png
  21. BIN
      website_subscription_package/static/description/assets/icons/education-black.png
  22. BIN
      website_subscription_package/static/description/assets/icons/hotel-black.png
  23. BIN
      website_subscription_package/static/description/assets/icons/license.png
  24. BIN
      website_subscription_package/static/description/assets/icons/lifebuoy.png
  25. BIN
      website_subscription_package/static/description/assets/icons/logo.png
  26. BIN
      website_subscription_package/static/description/assets/icons/manufacturing-black.png
  27. BIN
      website_subscription_package/static/description/assets/icons/pos-black.png
  28. BIN
      website_subscription_package/static/description/assets/icons/puzzle.png
  29. BIN
      website_subscription_package/static/description/assets/icons/restaurant-black.png
  30. BIN
      website_subscription_package/static/description/assets/icons/service-black.png
  31. BIN
      website_subscription_package/static/description/assets/icons/trading-black.png
  32. BIN
      website_subscription_package/static/description/assets/icons/training.png
  33. BIN
      website_subscription_package/static/description/assets/icons/update.png
  34. BIN
      website_subscription_package/static/description/assets/icons/user.png
  35. BIN
      website_subscription_package/static/description/assets/icons/wrench.png
  36. BIN
      website_subscription_package/static/description/assets/modules/automatic_image.png
  37. BIN
      website_subscription_package/static/description/assets/modules/budget_image.png
  38. BIN
      website_subscription_package/static/description/assets/modules/crm_dashboard_image.png
  39. BIN
      website_subscription_package/static/description/assets/modules/crm_image.png
  40. BIN
      website_subscription_package/static/description/assets/modules/crm_kit_image.png
  41. BIN
      website_subscription_package/static/description/assets/modules/employee_image.png
  42. BIN
      website_subscription_package/static/description/assets/modules/ip_image.png
  43. BIN
      website_subscription_package/static/description/assets/modules/payable_image.png
  44. BIN
      website_subscription_package/static/description/assets/modules/product_custom_image.png
  45. BIN
      website_subscription_package/static/description/assets/modules/salesperson_image.png
  46. BIN
      website_subscription_package/static/description/assets/modules/task_deadline_image.png
  47. BIN
      website_subscription_package/static/description/assets/screenshots/hero.gif
  48. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_001.png
  49. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_0016.0.png
  50. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_002.png
  51. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_003.png
  52. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_004.png
  53. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_005.png
  54. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_006.png
  55. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_007.png
  56. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_008.png
  57. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_009.png
  58. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_010.png
  59. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_011.png
  60. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_012.png
  61. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_013.png
  62. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_014.png
  63. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_015.png
  64. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_016.png
  65. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_017.png
  66. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_018.png
  67. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_019.png
  68. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_020.png
  69. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_021.png
  70. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_022.png
  71. BIN
      website_subscription_package/static/description/assets/screenshots/scrn_023.png
  72. BIN
      website_subscription_package/static/description/banner.png
  73. BIN
      website_subscription_package/static/description/icon.png
  74. 698
      website_subscription_package/static/description/index.html
  75. 30
      website_subscription_package/static/src/js/website_sale.js
  76. 196
      website_subscription_package/views/portal_templates.xml
  77. 46
      website_subscription_package/views/product_product_views.xml
  78. 30
      website_subscription_package/views/product_template_views.xml
  79. 19
      website_subscription_package/views/sale_order_views.xml
  80. 17
      website_subscription_package/views/subscription_package_views.xml
  81. 77
      website_subscription_package/views/website_product_subscription_template.xml

48
website_subscription_package/README.rst

@ -0,0 +1,48 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
Website Subscription Package Management
=======================================
This Module Create Subscription for A Product From Website.
Configuration
=============
* No Additional configuration is needed.
License
-------
Affero General Public License v3.0 (AGPL v3)
(https://www.gnu.org/licenses/agpl-3.0-standalone.html)
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
Credits
-------
* Developer: (V16) Anagha S,
(V15) Sabeel B
Contact: odoo@cybrosys.com
Contacts
--------
* Mail Contact : odoo@cybrosys.com
* Website : https://cybrosys.com
Bug Tracker
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
Maintainer
==========
.. image:: https://cybrosys.com/images/logo.png
:target: https://cybrosys.com
This module is maintained by Cybrosys Technologies.
For support and more information, please visit `Our Website <https://cybrosys.com/>`__
Further information
===================
HTML Description: `<static/description/index.html>`__

23
website_subscription_package/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
from . import controllers
from . import models

53
website_subscription_package/__manifest__.py

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
{
'name': 'Website Subscription Package Management',
'version': '15.0.1.0.0',
'category': 'Sales, Website',
'summary': 'Subscription Package Management Through website',
'description': """This Module Create Subscription for A Product From
Website""",
'author': 'Cybrosys Techno solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': "https://www.cybrosys.com",
'depends': ['subscription_package', 'website_sale'],
'data': [
'data/mail_template_data.xml',
'views/product_product_views.xml',
'views/product_template_views.xml',
'views/subscription_package_views.xml',
'views/sale_order_views.xml',
'views/portal_templates.xml',
'views/website_product_subscription_template.xml',
],
'assets': {
'web.assets_frontend': [
'website_subscription_package/static/src/js/website_sale.js',
],
},
'images': ['static/description/banner.png'],
'license': 'AGPL-3',
'installable': True,
'auto_install': False,
'application': False,
}

23
website_subscription_package/controllers/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
from . import portal
from . import website_subscription_package

98
website_subscription_package/controllers/portal.py

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import _, http
from odoo.exceptions import AccessError
from odoo.http import request
from odoo.addons.portal.controllers import portal
from odoo.addons.portal.controllers.portal import pager as portal_pager
class SubscriptionCustomerPortal(portal.CustomerPortal):
"""A class representing a subscription-based customer portal.
This class extends the functionality of the base CustomerPortal class to
provide features specific to subscription management and interactions."""
def _prepare_home_portal_values(self, counters):
"""Values for /my & /my/home routes template rendering.
Includes the record count for subscription order."""
values = super()._prepare_home_portal_values(counters)
if 'subscription_count' in counters:
subscription_count = request.env[
'subscription.package'].sudo().search_count(
[('partner_id', '=', request.env.user.partner_id.id),
('is_closed', '=', False)])
values['subscription_count'] = subscription_count
return values
@http.route('/my/subscription_order',
type='http', auth='user', website=True)
def portal_my_subscription_orders(self, page=1, sortby=None, filterby=None,
search=None, search_in='all',
groupby='none'):
"""Values for /my/subscription_order routes template rendering."""
values = self._prepare_portal_layout_values()
subscription = request.env['subscription.package'].sudo()
domain = [('partner_id', '=', request.env.user.partner_id.id),
('is_closed', '=', False)]
if not sortby:
sortby = 'start_date'
subscription_count = subscription.search_count(domain)
pager = portal_pager(
url="/my/subscription_order",
url_args={'sortby': sortby, 'search_in': search_in,
'search': search, 'groupby': groupby},
total=subscription_count, page=page, step=self._items_per_page)
subscription_order = subscription.search(
domain, limit=self._items_per_page, offset=pager['offset'])
grouped_subscriptions = False
values.update({
'subscriptions': subscription_order,
'grouped_subscriptions': grouped_subscriptions,
'page_name': 'Subscription',
'pager': pager,
'default_url': '/my/subscription_order',
'search_in': search_in,
'search': search,
'sortby': sortby,
'groupby': groupby,
'filterby': filterby})
return request.render(
"website_subscription_package.portal_my_subscriptions", values)
@http.route(
['/my/subscription_order/<int:subscription>',
'/my/subscription_order/id=<int:subscription>/state=<string:state>'],
type='http', auth="user", website=True)
def subscription_page(self, subscription=None, state=None):
"""Render subscription page."""
subscription = request.env['subscription.package'].sudo().browse(
subscription)
if state == 'Draft':
subscription.button_start_date()
try:
subscription.check_access_rights('read')
subscription.check_access_rule('read')
except AccessError:
return request.website.render("website.403")
return request.render(
"website_subscription_package.subscription_page", {
'subscription': subscription.sudo()})

133
website_subscription_package/controllers/website_subscription_package.py

@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, http
from odoo.http import request
from odoo.addons.website.controllers.main import QueryURL
from odoo.addons.website_sale.controllers.main import WebsiteSale
from odoo.tools.json import scriptsafe as json_scriptsafe
class WebsiteSaleSubscription(WebsiteSale):
"""Inherited class of website sale."""
@http.route(['/shop/<model("product.template"):product>'],
type='http', auth="public", website=True)
def product(self, product, category='', search=''):
"""Add Subscription plan and recurrence period for subscription
Product in website."""
product_context = dict(request.env.context, active_id=product.id)
product_category = request.env['product.public.category']
if category:
category = product_category.browse(int(category)).exists()
attrib_list = request.httprequest.args.getlist('attrib')
attrib_values = [map(int, value.split("-")) for value in attrib_list if
value]
attrib_set = {value[1] for value in attrib_values}
keep = QueryURL('/shop', category=category and category.id,
search=search, attrib=attrib_list)
categories = product_category.search([('parent_id', '=', False)])
price_list = request.website.get_current_pricelist()
from_currency = request.env.user.company_id.currency_id
to_currency = price_list.currency_id
compute_currency = lambda price: from_currency.compute(price,
to_currency)
subscription_plan = []
recurrence_period = []
if not product_context.get('pricelist'):
product_context['pricelist'] = price_list.id
product = product.with_context(product_context)
if product.is_subscription:
subscription_product = request.env[
'product.template'].sudo().browse(product.id)
subscription_plan = subscription_product.subscription_plan_id
recurrence_period = (subscription_product.
subscription_recurrence_period_ids)
values = {
'search': search,
'category': category,
'pricelist': price_list,
'attrib_values': attrib_values,
'compute_currency': compute_currency,
'attrib_set': attrib_set,
'keep': keep,
'categories': categories,
'main_object': product,
'product': product,
'subscription_plan': subscription_plan,
'recurrence_period': recurrence_period
}
return request.render("website_sale.product", values)
@http.route(['/shop/cart/update_json'], type='json', auth="public",
methods=['POST'], website=True, csrf=False)
def cart_update_json(self, product_id, line_id=None, add_qty=None,
set_qty=None, display=True, **kw):
"""
This route is called :
- When changing quantity from the cart.
- When adding a product from the wishlist.
- When adding a product to cart on the same page
(without redirection).
"""
order = request.website.sale_get_order(force_create=1)
if order.state != 'draft':
request.website.sale_reset()
if kw.get('force_create'):
order = request.website.sale_get_order(force_create=1)
else:
return {}
pcav = kw.get('product_custom_attribute_values')
nvav = kw.get('no_variant_attribute_values')
value = order._cart_update(
product_id=product_id,
line_id=line_id,
add_qty=add_qty,
set_qty=set_qty,
product_custom_attribute_values=json_scriptsafe.loads(
pcav) if pcav else None,
no_variant_attribute_values=json_scriptsafe.loads(
nvav) if nvav else None,
period=kw.get('period')
)
if not order.cart_quantity:
request.website.sale_reset()
return value
order = request.website.sale_get_order()
value['cart_quantity'] = order.cart_quantity
if not display:
return value
value['website_sale.cart_lines'] = request.env[
'ir.ui.view']._render_template("website_sale.cart_lines", {
'website_sale_order': order,
'date': fields.Date.today(),
'suggested_products': order._cart_accessories()
})
value['website_sale.short_cart_summary'] = request.env[
'ir.ui.view']._render_template("website_sale.short_cart_summary", {
'website_sale_order': order,
})
return value

56
website_subscription_package/data/mail_template_data.xml

@ -0,0 +1,56 @@
<?xml version="1.0"?>
<odoo>
<!-- Email Template: Email for renew subscription -->
<record id="mail_template_subscription_order" model="mail.template">
<field name="name">Subscription: Send Subscription Order From Website</field>
<field name="model_id" ref="website_subscription_package.model_subscription_package"/>
<field name="subject">{{ object.company_id.name }}: Subscription Order {{ object.name }}</field>
<field name="email_from">{{ object.company_id.email }}</field>
<field name="email_to">{{ object.partner_id.email }}</field>
<!-- <field name="description">Sent Subscription Order to customers.</field>-->
<field name="auto_delete" eval="True"/>
<field name="lang">{{ object.partner_id.lang }}</field>
<field name="body_html" type="html">
<div style="background:#F0F0F0;color:#515166;padding:10px 0px;font-family:Arial,Helvetica,sans-serif;font-size:14px;">
<table border="0" cellpadding="0" cellspacing="0"
style="padding-top: 16px; background-color: #F1F1F1; font-family:Verdana, Arial,sans-serif; color: #454748; width: 100%; border-collapse:separate;">
<tr>
<td align="center">
<table border="0" cellpadding="0" cellspacing="0"
width="590"
style="padding: 16px; background-color: white; color: #454748; border-collapse:separate;">
<tbody>
<!-- CONTENT -->
<tr>
<td align="center"
style="min-width: 590px;">
<table border="0" cellpadding="0"
cellspacing="0" width="590"
style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="top" style="font-size: 13px;">
<div>
Dear <t t-out="object.partner_id.name or ''">Marc Demo</t>,
<br/>
<br/>
Your subscription<span style="font-weight:bold; font-size: 15px;" t-out="object.name or ''">
SUB001
</span>
has been created for product
<span t-out="object.product_line_ids.product_id.name or ''">Product
</span>
<br/>Do not Hesitate to contact us.
</div>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</div>
</field>
</record>
</odoo>

6
website_subscription_package/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module <website_subscription_package>
#### 09.08.2024
#### Version 15.0.1.0.0
#### ADD
- Initial commit for Website Subscription Package Management

26
website_subscription_package/models/__init__.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
from . import product_product
from . import product_template
from . import sale_order
from . import sale_order_line
from . import subscription_package

46
website_subscription_package/models/product_product.py

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models, _
class ProductProduct(models.Model):
"""Adding a new field for discounts for variants of subscription products
second subscription."""
_inherit = "product.product"
subscription_discount = fields.Float(
string="Discount(%)", help="Discount for second subscription.")
def action_open_attribute_values_discount(self):
"""Set Discounts for variants of subscription products second
subscription."""
return {
'type': 'ir.actions.act_window',
'name': _("Product Variant Discount For 2nd subscription"),
'res_model': 'product.product',
'view_mode': 'tree',
'views': [(self.env.ref('website_subscription_package.'
'product_product_website_subscription_tree_view').id, 'list')],
'context': {
'search_default_product_tmpl_id': self.product_tmpl_id.id,
'default_product_tmpl_id': self.product_tmpl_id.id},
'target': 'current'}

49
website_subscription_package/models/product_template.py

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models, _
class ProductTemplate(models.Model):
"""Inherited product template model add new field to select recurrence
period for subscription product."""
_inherit = "product.template"
subscription_recurrence_period_ids = fields.Many2many(
comodel_name='recurrence.period', string='Recurrence period',
help="Select recurrence period (subscription interval) for the "
"product.")
def action_open_attribute_values_discount(self):
"""Set Discounts for variants of subscription products second
subscription."""
return {
'type': 'ir.actions.act_window',
'name': _("Product Variant Discount For 2nd subscription"),
'res_model': 'product.product',
'view_mode': 'tree',
'views': [(self.env.ref('website_subscription_package.'
'product_product_website_subscription_tree_view').id,
'list')],
'context': {'search_default_product_tmpl_id': self.id,
'default_product_tmpl_id': self.id},
'target': 'new'}

39
website_subscription_package/models/sale_order.py

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import models
class SaleOrder(models.Model):
"""Extends the Sale Order model to handle subscription orders."""
_inherit = 'sale.order'
def _cart_update(self, product_id=None, line_id=None, add_qty=0,
set_qty=0, **kwargs):
"""Supering the _cart_update function to write the interval_id"""
res = super()._cart_update(product_id=product_id, line_id=line_id,
add_qty=add_qty, set_qty=set_qty, **kwargs)
order_line = self.env['sale.order.line'].sudo().browse(res['line_id'])
if kwargs.get('period'):
order_line.write({
'subscription_interval_id': int(kwargs.get('period')),
})
return res

36
website_subscription_package/models/sale_order_line.py

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
class SaleOrderLine(models.Model):
"""Add a new field to the sale order line for the subscription interval
for subscription product."""
_inherit = 'sale.order.line'
subscription_interval_id = fields.Many2one("recurrence.period",
string="Subscription Interval",
help="Recurrence period for "
"subscription product.")
is_product_subscription = fields.Boolean(
related='product_template_id.is_subscription',
string="Is Subscription", help="Is subscription product.")

120
website_subscription_package/models/subscription_package.py

@ -0,0 +1,120 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Sabeel B (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
class SubscriptionPackage(models.Model):
"""This class inherits from the 'subscription.package' model and extends
its functionality. It provides methods for sending subscription order
details to customers and managing subscription limits."""
_inherit = "subscription.package"
recurrence_period_id = fields.Many2one("recurrence.period",
string="Recurrence Period",
help="The period of the recurrence")
def send_subscription_order_to_customer(self):
"""Generates a mail and send to customer about the subscription order
details."""
template_id = self.env.ref(
'website_subscription_package.mail_template_subscription_order')
for rec in self:
email_vals = {'message_type': 'notification',
'is_notification': True,
"model": 'subscription.package',
"res_id": rec.id}
template_id.send_mail(
rec.id, force_send=True,
notif_layout='mail.mail_notification_light',
email_values=email_vals)
def close_limit_cron(self):
"""It Checks renew date, close date. It will send mail when renew
date and also generates invoices based on the plan.
It wil close the subscription automatically if renewal limit is
exceeded."""
pending_subscriptions = self.env['subscription.package'].search(
[('stage_category', '=', 'progress')])
today_date = fields.Date.today()
pending_subscription = False
for pending_subscription in pending_subscriptions:
get_dates = self.find_renew_date(
pending_subscription.next_invoice_date,
pending_subscription.date_started,
pending_subscription.plan_id.days_to_end)
renew_date = get_dates['renew_date']
end_date = get_dates['end_date']
pending_subscription.close_date = get_dates['close_date']
if today_date == pending_subscription.next_invoice_date:
if pending_subscription.plan_id.invoice_mode == 'draft_invoice':
this_products_line = []
for rec in pending_subscription.product_line_ids:
rec_list = [0, 0, {'product_id': rec.product_id.id,
'quantity': rec.product_qty,
'price_unit': rec.unit_price,
'discount': rec.product_id.subscription_discount,
'tax_ids': rec.tax_id
}]
this_products_line.append(rec_list)
self.env['account.move'].create(
{'move_type': 'out_invoice',
'invoice_date_due': today_date,
'invoice_payment_term_id': False,
'invoice_date': today_date,
'state': 'draft',
'subscription_id': pending_subscription.id,
'partner_id': pending_subscription.partner_invoice_id.id,
'currency_id': pending_subscription.partner_invoice_id.currency_id.id,
'invoice_line_ids': this_products_line
})
pending_subscription.write({
'to_renew': False,
'start_date': pending_subscription.next_invoice_date})
new_date = self.find_renew_date(
pending_subscription.next_invoice_date,
pending_subscription.date_started,
pending_subscription.plan_id.days_to_end)
pending_subscription.write(
{'close_date': new_date['close_date']})
self.send_renew_alert_mail(today_date,
new_date['renew_date'],
pending_subscription.id)
if (today_date == end_date) and (
pending_subscription.plan_id.limit_choice != 'manual'):
display_msg = ("<h5><i>The renewal limit has been exceeded "
"today for this subscription based on the "
"current subscription plan.</i></h5>")
pending_subscription.message_post(body=display_msg)
pending_subscription.is_closed = True
reason = (self.env['subscription.package.stop'].search([
('name', '=', 'Renewal Limit Exceeded')]).id)
pending_subscription.close_reason = reason
pending_subscription.closed_by = self.user_id
pending_subscription.close_date = fields.Date.today()
stage = (self.env['subscription.package.stage'].search([
('category', '=', 'closed')]).id)
values = {'stage_id': stage, 'to_renew': False,
'next_invoice_date': False}
pending_subscription.write(values)
self.send_renew_alert_mail(today_date, renew_date,
pending_subscription.id)
return dict(pending=pending_subscription)

2
website_subscription_package/security/ir.model.access.csv

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_recurrence_period_user,access.recurrence.period.user,model_recurrence_period,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_recurrence_period_user access.recurrence.period.user model_recurrence_period base.group_user 1 1 1 1

BIN
website_subscription_package/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
website_subscription_package/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
website_subscription_package/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
website_subscription_package/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
website_subscription_package/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
website_subscription_package/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
website_subscription_package/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
website_subscription_package/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
website_subscription_package/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
website_subscription_package/static/description/assets/icons/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
website_subscription_package/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
website_subscription_package/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
website_subscription_package/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
website_subscription_package/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
website_subscription_package/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
website_subscription_package/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
website_subscription_package/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
website_subscription_package/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
website_subscription_package/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
website_subscription_package/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
website_subscription_package/static/description/assets/modules/automatic_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
website_subscription_package/static/description/assets/modules/budget_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
website_subscription_package/static/description/assets/modules/crm_dashboard_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
website_subscription_package/static/description/assets/modules/crm_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
website_subscription_package/static/description/assets/modules/crm_kit_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
website_subscription_package/static/description/assets/modules/employee_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
website_subscription_package/static/description/assets/modules/ip_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
website_subscription_package/static/description/assets/modules/payable_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
website_subscription_package/static/description/assets/modules/product_custom_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
website_subscription_package/static/description/assets/modules/salesperson_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
website_subscription_package/static/description/assets/modules/task_deadline_image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
website_subscription_package/static/description/assets/screenshots/hero.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_001.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_0016.0.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_002.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_003.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_004.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_005.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_006.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_007.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_008.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_009.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_010.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_011.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_012.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_013.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_014.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_015.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_016.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_017.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_018.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_019.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_020.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_021.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_022.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

BIN
website_subscription_package/static/description/assets/screenshots/scrn_023.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
website_subscription_package/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
website_subscription_package/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

698
website_subscription_package/static/description/index.html

@ -0,0 +1,698 @@
<div class="container" style="padding: 1rem !important; margin-bottom: 1rem !important;">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12 d-flex justify-content-between" style="border-bottom: 1px solid #d5d5d5;">
<div class="my-3">
<img src="./assets/icons/logo.png" style="width: auto !important; height: 40px !important;">
</div>
<div class="my-3 d-flex align-items-center">
<div
style="background-color: #7C7BAD !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;">
<i class="fa fa-check mr-1"></i>Community
</div>
</div>
</div>
</div>
</div>
<div class="container" style="padding: 0rem 1.5rem 4rem !important">
<div class="row" style="height: 900px !important;">
<div class="col-sm-12 col-md-12 col-lg-12"
style="padding: 4rem 1rem !important; background-color: #714B67 !important; height: 600px !important; border-radius: 20px !important;">
<h1
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #FFFFFF !important; font-size: 3.5rem !important; text-align: center !important;">
Website Subscription Package Management</h1>
<p
style="font-family: 'Montserrat', sans-serif !important; font-weight: 300 !important; color: #FFFFFF !important; font-size: 1.4rem !important; text-align: center !important;">
This Module Create Subscription for A Product From
Website.
</p>
<img src="./assets/screenshots/hero.gif" class="img-responsive" width="100%" height="auto" />
</div>
</div>
<div class="row">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin-bottom: 2rem !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-compass mr-2"></i>Explore this module
</h2>
</div>
<div class="col-md-6">
<a href="#overview" style="text-decoration: none !important;">
<div class="row"
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;">
<div class="col-8">
<h3
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;">
Overview</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;">
Learn more about this module</p>
</div>
<div class="col-4 text-right d-flex justify-content-end align-items-center">
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i>
</div>
</div>
</a>
</div>
<div class="col-md-6">
<a href="#features" style="text-decoration: none !important;">
<div class="row"
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;">
<div class="col-8">
<h3
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;">
Features</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;">
View features of this module</p>
</div>
<div class="col-4 text-right d-flex justify-content-end align-items-center">
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i>
</div>
</div>
</a>
</div>
<div class="col-md-6">
<a href="#screenshots" style="text-decoration: none !important;">
<div class="row"
style="background-color: #f5f2f5 !important; border-radius: 10px !important; margin: 1rem !important; padding: 1.5em !important; height: 100px !important;">
<div class="col-8">
<h3
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.2rem !important;">
Screenshots</h3>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #714B67 !important; font-size: 0.9rem !important;">
See key screenshots of this module</p>
</div>
<div class="col-4 text-right d-flex justify-content-end align-items-center">
<i class="fa fa-chevron-right" style="color: #714B67 !important;"></i>
</div>
</div>
</a>
</div>
</div>
<div class="row" id="overview">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-pie-chart mr-2"></i>Overview
</h2>
</div>
<div class="col-mg-12 pl-3">
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important; line-height: 30px !important;">
This Module Create Subscription for A Product
From
Website.</p>
</div>
</div>
<div class="row" id="features">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-star mr-2"></i>Features
</h2>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="assets/icons/check.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Community compatible.</h4>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="assets/icons/check.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Auto Create Product Subscription and Sale Order From Website.</h4>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="assets/icons/check.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Send Mail After Auto Create Sale Order & Subscription To the customer.</h4>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="assets/icons/check.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Create Variant wise 2nd Subscription Discount.</h4>
</div>
</div>
<div class="col-md-6 pl-3 py-3 d-flex">
<div>
<img src="assets/icons/check.png">
</div>
<div>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
User Can Manage Subscription from Portal.</h4>
</div>
</div>
</div>
<div class="row" id="screenshots">
<div class="col-md-12" style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important">
<h2
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
<i class="fa fa-image mr-2"></i>Screenshots
</h2>
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Create Recurrence Period And Subscription Plan.</h4>
<img src="assets/screenshots/scrn_001.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<img src="assets/screenshots/scrn_002.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Go to Sales-> Configuration-> Settings. Enable 'Discounts'.
</p>
<img src="assets/screenshots/scrn_003.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Subscription Product.</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Create New Subscription Product.
</p>
<img src="assets/screenshots/scrn_004.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Create Variants for the
Product.
</p>
<img src="assets/screenshots/scrn_005.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Enable 'Is Subscription' from 'Subscription' tab and
provide discount for variants.Select subscription plan and
Recurrence Period.
</p>
<img src="assets/screenshots/scrn_006.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Create variant wise Discount for Subscription Product.
</p>
<img src="assets/screenshots/scrn_007.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Select the Product from Website.</h4>
<img src="assets/screenshots/scrn_008.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Select Recurrence Period and add to cart.
</p>
<img src="assets/screenshots/scrn_009.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Can see subscription details in Cart.
</p>
<img src="assets/screenshots/scrn_010.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Confirm the order.
</p>
<img src="assets/screenshots/scrn_011.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<img src="assets/screenshots/scrn_012.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Sale order and subscription order will be created. </h4>
<img src="assets/screenshots/scrn_013.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<img src="assets/screenshots/scrn_014.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Send mail after auto create sale order & subscription to the
customer.
</p>
<img src="assets/screenshots/scrn_015.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Subscription Interval added in sale order line.
</p>
<img src="assets/screenshots/scrn_0016.0.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Start the Subscription Order on clicking 'START' button.
</p>
<img src="assets/screenshots/scrn_016.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<img src="assets/screenshots/scrn_017.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Stage changed to IN PROGRESS.
</p>
<img src="assets/screenshots/scrn_018.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Customer can see their subscription order from Portal.
</p>
<img src="assets/screenshots/scrn_019.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<img src="assets/screenshots/scrn_020.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Click 'Start' to start the subscription Order from portal.
</p>
<img src="assets/screenshots/scrn_021.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
<img src="assets/screenshots/scrn_022.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div class="col-lg-12 my-3">
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
A recurring invoice will be generated for the subscription order according to the recurring period. Starting from the second invoice onward, variant-specific discount will be applied.
</p>
<img src="assets/screenshots/scrn_023.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
</div>
<!-- SUGGESTED PRODUCTS -->
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center"
style="text-align: center; padding: 2.5rem 1rem !important;">
<h2 style="color: #212529 !important;">Suggested Products</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" />
<div id="demo1" class="row carousel slide" data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner">
<div class="carousel-item active" style="min-height:0px">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/crm_dashboard/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/crm_dashboard_image.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/commission_plan/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/crm_image.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/crm_kit/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/crm_kit_image.png">
</div>
</a>
</div>
</div>
<div class="carousel-item" style="min-height:0px">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/access_restriction_by_ip/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/ip_image.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/dynamic_product_fields/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/product_custom_image.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/task_deadline_reminder/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-top-left-radius:10px; border-top-right-radius:10px"
src="./assets/modules/task_deadline_image.png">
</div>
</a>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#demo1" data-slide="prev" style="left:-25px;width: 35px;color: #000;">
<span class="carousel-control-prev-icon"><i class="fa fa-chevron-left" style="font-size:24px"></i></span>
</a>
<a class="carousel-control-next" href="#demo1" data-slide="next" style="right:-25px;width: 35px;color: #000;">
<span class="carousel-control-next-icon"><i class="fa fa-chevron-right" style="font-size:24px"></i></span>
</a>
</div>
</div>
</div>
<!-- END OF SUGGESTED PRODUCTS -->
<!-- OUR SERVICES -->
<section class="container" style="margin-top: 6rem !important;">
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Our Services</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" />
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/cogs.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Customization</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/wrench.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/lifebuoy.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Support</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/user.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Hire
Odoo
Developer</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/puzzle.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Integration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/update.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Migration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/consultation.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Consultancy</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/training.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/license.png" class="img-responsive" height="48px" width="48px">
</div>
<h6 class="text-center" style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Licensing Consultancy</h6>
</div>
</div>
</section>
<!-- END OF END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<section class="container" style="margin-top: 6rem !important;">
<div class="row">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Our Industries</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" />
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/trading-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Trading
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easily procure
and
sell your products</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/pos-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
POS
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easy
configuration
and convivial experience</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/education-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Education
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
A platform for
educational management</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/manufacturing-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Manufacturing
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Plan, track and
schedule your operations</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/ecom-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
E-commerce &amp; Website
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Mobile
friendly,
awe-inspiring product pages</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/service-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Service Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Keep track of
services and invoice</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/restaurant-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Restaurant
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Run your bar or
restaurant methodically</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;">
<img src="./assets/icons/hotel-black.png" class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Hotel Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
An
all-inclusive
hotel management application</p>
</div>
</div>
</div>
</section>
<!-- END OF END OF OUR INDUSTRIES -->
<!-- FOOTER -->
<!-- Footer Section -->
<section class="container" style="margin: 5rem auto 2rem;">
<div class="row" style="max-width:1540px;">
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center">
<h2 style="color: #212529 !important;">Need Help?</h2>
<hr
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;" />
</div>
</div>
<!-- Contact Cards -->
<div class="row d-flex justify-content-center align-items-center"
style="max-width:1540px; margin: 0 auto 2rem auto;">
<div class="col-lg-12" style="padding: 0rem 3rem 2rem; border-radius: 10px; margin-right: 3rem; ">
<div class="row mt-4">
<div class="col-lg-6">
<a href="mailto:odoo@cybrosys.com" target="_blank" class="btn btn-block mb-2 deep_hover"
style="text-decoration: none; background-color: #4d4d4d; color: #FFF; border-radius: 4px;"><i
class="fa fa-envelope mr-2"></i>odoo@cybrosys.com</a>
</div>
<div class="col-lg-6">
<a href="https://api.whatsapp.com/send?phone=918606827707" target="_blank"
class="btn btn-block mb-2 deep_hover"
style="text-decoration: none; background-color: #25D366; color: #FFF; border-radius: 4px;"><i
class="fa fa-whatsapp mr-2"></i>+91 86068 27707</a>
</div>
</div>
</div>
</div>
<!-- End of Contact Cards -->
</section>
<!-- Footer -->
<section class="oe_container" style="padding: 2rem 3rem 1rem;">
<div class="row" style="max-width:1540px; margin: 0 auto; margin-right: 3rem; ">
<!-- Logo -->
<div class="col-lg-12 d-flex justify-content-center align-items-center" style="margin-top: 3rem;">
<img src="https://www.cybrosys.com/images/logo.png" width="200px" height="auto" />
</div>
<!-- End of Logo -->
<div class="col-lg-12">
<hr
style="margin-top: 3rem;background: linear-gradient(90deg, rgba(2,0,36,0) 0%, rgba(229,229,229,1) 33%, rgba(229,229,229,1) 58%, rgba(0,212,255,0) 100%); height: 2px; border-style: none;">
<!-- End of Footer Section -->
</div>
</div>
</section>
<!-- END OF FOOTER -->
</div>

30
website_subscription_package/static/src/js/website_sale.js

@ -0,0 +1,30 @@
/** @odoo-module **/
import { WebsiteSale } from 'website_sale.website_sale';
WebsiteSale.include({
/**
* Assign the recurrence period to the rootProduct for subscription products.
*
* @override
*/
_submitForm: function () {
const params = this.rootProduct;
const $product = $('#product_detail');
const recurrence = $('#recurrence_period')[0];
let recurrence_id = 0;
const productTrackingInfo = $product.data('product-tracking-info');
if (productTrackingInfo) {
productTrackingInfo.quantity = params.quantity;
$product.trigger('add_to_cart_event', [productTrackingInfo]);
}
for (let item of recurrence) {
if (item.selected === true) {
recurrence_id = item.value;
}
}
params.add_qty = params.quantity;
params.product_custom_attribute_values = JSON.stringify(params.product_custom_attribute_values);
params.no_variant_attribute_values = JSON.stringify(params.no_variant_attribute_values);
params['period'] = recurrence_id;
return this.addToCart(params);
},
});

196
website_subscription_package/views/portal_templates.xml

@ -0,0 +1,196 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Subscription portal -->
<template id="portal_my_home_menu_subscription"
name="Portal layout : subscription menu entries"
inherit_id="portal.portal_breadcrumbs" priority="20">
<xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside">
<li t-if="page_name == 'Subscription'"
t-attf-class="breadcrumb-item #{'active ' if not subscriptions else ''}">
<a t-if="subscriptions"
t-attf-href="/my/subscription_order?{{ keep_query() }}">
Subscription
</a>
<t t-else="">Subscription</t>
</li>
<li t-if="subscription" class="breadcrumb-item active">
<a t-att-href="default_url">
<span t-field="subscription.name"/>
<t t-out="subscription.name"/>
</a>
</li>
</xpath>
</template>
<!-- Subscription Order in home -->
<template id="portal_my_home_subscription_order" name="Show Subscription"
inherit_id="portal.portal_my_home" customize_show="True"
priority="30">
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
<t t-call="portal.portal_docs_entry">
<t t-set="title">Subscription</t>
<t t-set="url" t-value="'/my/subscription_order'"/>
<t t-set="placeholder_count" t-value="'subscription_count'"/>
</t>
</xpath>
</template>
<!-- Users subscription orders on Portal -->
<template id="portal_my_subscriptions" name="My Subscriptions">
<t t-call="portal.portal_layout">
<t t-set="breadcrumbs_searchbar" t-value="True"/>
<t t-call="portal.portal_searchbar">
<t t-set="title">Sbscriptions</t>
</t>
<t t-if="subscriptions" t-call="portal.portal_table">
<thead>
<tr class="active">
<th>Subscription #</th>
<th class="text-end">Start Date</th>
<th class="text-end">Next Invoice Date</th>
<th class="text-center"/>
<th class="text-end">Total</th>
</tr>
</thead>
<t t-foreach="subscriptions" t-as="subscription">
<tr>
<td>
<a t-att-href="'/my/subscription_order/'+str(subscription.id)">
<t t-out="subscription.name"/>
</a>
</td>
<td class="text-end">
<span t-field="subscription.start_date"/>
</td>
<td class="text-end">
<span t-field="subscription.next_invoice_date"/>
</td>
<td class="text-center">
<span t-field="subscription.stage_id"/>
</td>
<td class="text-end">
<span t-field="subscription.total_recurring_price"/>
</td>
</tr>
</t>
</t>
<p t-else="">There are currently no Subscription for your account.
</p>
</t>
</template>
<!-- Subscription page for subscription order -->
<template id="subscription_page" name="Subscription Detail Page">
<t t-call="portal.portal_layout">
<t t-set="wrapwrap_classes" t-value="'o_portal_bg_dark'"/>
<div class="row mt16 o_portal_sidebar">
<!-- Subscription detail page -->
<div class="col-12 col-lg">
<div class="card">
<div class="card-header bg-white pb-2 pt-3"
style="background: white;">
<div>
<div class="row">
<div class="col-md-9">
<h1>
<span t-esc="subscription.name"/>
</h1>
</div>
<t t-if="subscription.stage_id.name == 'Draft'">
<a t-att-href="'/my/subscription_order/id=%s/state=%s' % (subscription.id,subscription.stage_id.name)">
<button type="button"
t-att-id="subscription.id"
class="btn btn-primary">
<i class="fa fa-caret-left">
</i>
Start
</button>
</a>
</t>
<div class="subscription_state" style="margin-left: 130px;">
<span class="badge rounded-pill bg-info text-white float-end fs-6"
t-field="subscription.stage_id.name">
</span>
</div>
</div>
</div>
<div>
<div class="row">
<div class="col-md-6">
<div>
<strong>Reference:</strong>
<span t-field="subscription.name"/>
</div>
</div>
<div class="col-md-6">
<div>
<strong>Start date:</strong>
<span t-field="subscription.start_date"/>
</div>
<div>
<strong>Close date:</strong>
<span t-field="subscription.close_date"/>
</div>
<div>
<strong>Billing:</strong>
Every:
<span t-field="subscription.plan_id.renewal_value"/>
<span t-field="subscription.plan_id.renewal_period"/>
</div>
<div>
<strong>Next invoice:</strong>
<span t-field="subscription.next_invoice_date"/>
</div>
<div>
<strong>Recurrence Period:</strong>
<span t-field="subscription.recurrence_period_id.name"/>
</div>
</div>
</div>
<hr/>
<t t-call="website_subscription_package.subscription_lines"/>
</div>
</div>
</div>
</div>
</div>
</t>
</template>
<!-- Subscription lines -->
<template id="subscription_lines" name="Subscription Items">
<section id="subscription_items">
<t t-if="subscription.product_line_ids">
<div class="card-body">
<h5>Contract details</h5>
<table class="table table-sm table-responsive-lg">
<thead>
<tr>
<th>Subscription Product</th>
<th class="text-right">Quantity</th>
<th class="text-right">Unit Price</th>
<th class="text-right">Subtotal</th>
</tr>
</thead>
<tbody>
<t t-foreach="subscription.product_line_ids"
t-as="lines">
<tr>
<td class="line-product">
<span t-field="lines.product_id.display_name"/>
</td>
<td class="text-right">
<span t-field="lines.product_qty"/>
<span t-field="lines.uom_catg_id"/>
</td>
<td class="text-right">
<span t-field="lines.unit_price"/>
</td>
<td class="text-right">
<span t-field="lines.total_amount"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
</t>
</section>
</template>
</odoo>

46
website_subscription_package/views/product_product_views.xml

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- To add attribute discount for product on second subscription-->
<record id="product_product_website_subscription_tree_view" model="ir.ui.view">
<field name="name">product.product.website.subscription.tree</field>
<field name="model">product.product</field>
<field name="arch" type="xml">
<tree string="Attributes" create="false" delete="false" editable="bottom">
<field name="name" readonly="1"/>
<field name="product_template_variant_value_ids"
widget="many2many_tags"
groups="product.group_product_variant"
readonly="1"/>
<field name="subscription_discount"/>
</tree>
</field>
</record>
<!-- New field to select subscription periods for product-->
<record id="product_normal_form_view" model="ir.ui.view">
<field name="name">
product.product.view.form.inherit.website.subscription.management
</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="priority">25</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='subscription_plan_id']"
position="after">
<field name="subscription_recurrence_period_ids"
widget="many2many_tags"
attrs="{'required': [('is_subscription', '=', True)],
'invisible': [('is_subscription', '!=', True)],}"/>
</xpath>
<xpath expr="//page[@name='subscription']" position="inside">
<button string="Update Discount on Variants"
class="btn btn-link"
attrs="{'required': [('is_subscription', '=', True)],
'invisible': [('is_subscription', '!=', True)]}"
type="object"
name="action_open_attribute_values_discount"/>
</xpath>
</field>
</record>
</odoo>

30
website_subscription_package/views/product_template_views.xml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- New field to select subscription periods for product -->
<record id="product_template_inherit_subscription" model="ir.ui.view">
<field name="name">
product.template.view.form.inherit.website.subscription.management
</field>
<field name="model">product.template</field>
<field name="inherit_id"
ref="subscription_package.product_template_inherit_subscription"/>
<field name="priority">25</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='subscription_plan_id']"
position="after">
<field name="subscription_recurrence_period_ids"
widget="many2many_tags"
attrs="{'required': [('is_subscription', '=', True)],
'invisible': [('is_subscription', '!=', True)],}"/>
</xpath>
<xpath expr="//page[@name='subscription']" position="inside">
<button string="Update Discount on Variants"
class="btn btn-link"
attrs="{'required': [('is_subscription', '=', True)],
'invisible': [('is_subscription', '!=', True)]}"
type="object"
name="action_open_attribute_values_discount"/>
</xpath>
</field>
</record>
</odoo>

19
website_subscription_package/views/sale_order_views.xml

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- New field subscription interval for subscription product in sale order line -->
<record id="view_order_form" model="ir.ui.view">
<field name="name">
sale.order.form.view.inherit.website.subscription.management
</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="/form/sheet/notebook/page/field[@name='order_line']/tree/field[@name='name']"
position="after">
<field name="is_product_subscription" invisible="1"/>
<field name="subscription_interval_id"
attrs="{'invisible':[('is_product_subscription','=',False)]}"/>
</xpath>
</field>
</record>
</odoo>

17
website_subscription_package/views/subscription_package_views.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--Inherited form view of the model subscription.package-->
<record id="subscription_package_form" model="ir.ui.view">
<field name="name">
subscription.package.view.form.inherit.website.subscription.package
</field>
<field name="model">subscription.package</field>
<field name="inherit_id"
ref="subscription_package.subscription_package_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='reference_code']" position="after">
<field name="recurrence_period_id"/>
</xpath>
</field>
</record>
</odoo>

77
website_subscription_package/views/website_product_subscription_template.xml

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Subscription product details in product page -->
<template id="product_subscription" inherit_id="website_sale.product"
name="product Subscription">
<xpath expr="//p[hasclass('css_not_available_msg')]" position="before">
<br/>
<!-- <hr/>-->
<div t-if="product.is_subscription"
class="subs position-relative mb-2">
<div>
<hr/>
<div id="check_id" name="select_card">
<span>The plan for this product is&amp;nbsp;
<strong t-esc="subscription_plan.name"/>
<br/>
Chose how often it's delivered.We'll send you a
reminder before each delivery
</span>
<select name="recurrence_period"
id="recurrence_period"
style="width:160px; height:42px"
class="form-control"
required="True">
<t t-foreach='recurrence_period'
t-as="period">
<option t-esc='period.name'
t-att-value="period.id"/>
</t>
</select>
<t t-if="product.product_variant_ids.product_template_variant_value_ids">
<t t-foreach='product.product_variant_ids'
t-as="info">
<t t-if="info.subscription_discount != 0">
<t t-foreach='info.product_template_variant_value_ids'
t-as="var">
For&amp;nbsp;
<t t-esc="var.name"/>
</t>
<t t-esc="info.subscription_discount"/>%
discount for second subscription.
<br/>
</t>
</t>
</t>
</div>
<br/>
</div>
</div>
</xpath>
</template>
<!-- Subscription interval on cart -->
<template id="cart_lines_subscription_prod"
inherit_id="website_sale.cart_lines">
<xpath expr="//td[@class='td-product_name']" position="inside">
<t t-if="line.is_product_subscription">
<div class="subs_cart">
<strong>Subscription Interval:</strong>
<strong t-field="line.subscription_interval_id"/>
</div>
</t>
</xpath>
</template>
<!-- Subscription interval on cart summary -->
<template id="cart_summary_subscription_prod"
inherit_id="website_sale.cart_summary">
<xpath expr="//td[@class='td-product_name']" position="inside">
<t t-if="line.is_product_subscription">
<div class="subs_cart">
<strong>Subscription Interval:</strong>
<strong t-field="line.subscription_interval_id"/>
</div>
</t>
</xpath>
</template>
</odoo>
Loading…
Cancel
Save