Browse Source

[ADD] Initial Commit 'subscription_package'

pull/201/head
AjmalCybro 3 years ago
parent
commit
af5c1c6f23
  1. 36
      subscription_package/README.md
  2. 25
      subscription_package/__init__.py
  3. 57
      subscription_package/__manifest__.py
  4. 14
      subscription_package/data/cron.xml
  5. 56
      subscription_package/data/mail_template.xml
  6. 25
      subscription_package/data/subscription_stage_data.xml
  7. 24
      subscription_package/data/uom_demo.xml
  8. 29
      subscription_package/models/__init__.py
  9. 34
      subscription_package/models/res_partner.py
  10. 33
      subscription_package/models/subscription_close.py
  11. 386
      subscription_package/models/subscription_package.py
  12. 130
      subscription_package/models/subscription_plan.py
  13. 51
      subscription_package/models/subscription_products.py
  14. 68
      subscription_package/models/subscription_renew.py
  15. 42
      subscription_package/models/subscription_stage.py
  16. 23
      subscription_package/report/__init__.py
  17. 62
      subscription_package/report/subscription_report.py
  18. 37
      subscription_package/report/subscription_report_view.xml
  19. 8
      subscription_package/security/ir.model.access.csv
  20. 25
      subscription_package/security/security.xml
  21. BIN
      subscription_package/static/description/assets/icons/check.png
  22. BIN
      subscription_package/static/description/assets/icons/chevron.png
  23. BIN
      subscription_package/static/description/assets/icons/cogs.png
  24. BIN
      subscription_package/static/description/assets/icons/consultation.png
  25. BIN
      subscription_package/static/description/assets/icons/ecom-black.png
  26. BIN
      subscription_package/static/description/assets/icons/education-black.png
  27. BIN
      subscription_package/static/description/assets/icons/hotel-black.png
  28. BIN
      subscription_package/static/description/assets/icons/license.png
  29. BIN
      subscription_package/static/description/assets/icons/lifebuoy.png
  30. BIN
      subscription_package/static/description/assets/icons/logo.png
  31. BIN
      subscription_package/static/description/assets/icons/manufacturing-black.png
  32. BIN
      subscription_package/static/description/assets/icons/pos-black.png
  33. BIN
      subscription_package/static/description/assets/icons/puzzle.png
  34. BIN
      subscription_package/static/description/assets/icons/restaurant-black.png
  35. BIN
      subscription_package/static/description/assets/icons/service-black.png
  36. BIN
      subscription_package/static/description/assets/icons/trading-black.png
  37. BIN
      subscription_package/static/description/assets/icons/training.png
  38. BIN
      subscription_package/static/description/assets/icons/update.png
  39. BIN
      subscription_package/static/description/assets/icons/user.png
  40. BIN
      subscription_package/static/description/assets/icons/wrench.png
  41. BIN
      subscription_package/static/description/assets/modules/automatic_image.png
  42. BIN
      subscription_package/static/description/assets/modules/budget_image.png
  43. BIN
      subscription_package/static/description/assets/modules/crm_dashboard_image.png
  44. BIN
      subscription_package/static/description/assets/modules/crm_image.png
  45. BIN
      subscription_package/static/description/assets/modules/crm_kit_image.png
  46. BIN
      subscription_package/static/description/assets/modules/employee_image.png
  47. BIN
      subscription_package/static/description/assets/modules/ip_image.png
  48. BIN
      subscription_package/static/description/assets/modules/payable_image.png
  49. BIN
      subscription_package/static/description/assets/modules/product_custom_image.png
  50. BIN
      subscription_package/static/description/assets/modules/salesperson_image.png
  51. BIN
      subscription_package/static/description/assets/modules/task_deadline_image.png
  52. BIN
      subscription_package/static/description/assets/screenshots/activity_type.png
  53. BIN
      subscription_package/static/description/assets/screenshots/close_reason.png
  54. BIN
      subscription_package/static/description/assets/screenshots/create_sub.png
  55. BIN
      subscription_package/static/description/assets/screenshots/create_sub_plan.png
  56. BIN
      subscription_package/static/description/assets/screenshots/create_sub_stage.png
  57. BIN
      subscription_package/static/description/assets/screenshots/hero.gif
  58. BIN
      subscription_package/static/description/assets/screenshots/sub_customer.png
  59. BIN
      subscription_package/static/description/assets/screenshots/sub_package.png
  60. BIN
      subscription_package/static/description/assets/screenshots/sub_product.png
  61. BIN
      subscription_package/static/description/assets/screenshots/sub_renew.png
  62. BIN
      subscription_package/static/description/assets/screenshots/sub_report.png
  63. BIN
      subscription_package/static/description/assets/screenshots/sub_sale.png
  64. BIN
      subscription_package/static/description/assets/screenshots/sub_stage.png
  65. BIN
      subscription_package/static/description/assets/screenshots/subscription_plan.png
  66. BIN
      subscription_package/static/description/banner.png
  67. BIN
      subscription_package/static/description/icon.png
  68. 719
      subscription_package/static/description/index.html
  69. 18
      subscription_package/views/mail_activity_views.xml
  70. 27
      subscription_package/views/res_partner.xml
  71. 27
      subscription_package/views/subscription_close.xml
  72. 272
      subscription_package/views/subscription_package.xml
  73. 108
      subscription_package/views/subscription_plan.xml
  74. 86
      subscription_package/views/subscription_products.xml
  75. 21
      subscription_package/views/subscription_renew.xml
  76. 51
      subscription_package/views/subscription_stage.xml
  77. 23
      subscription_package/wizard/__init__.py
  78. 45
      subscription_package/wizard/subscription_close_wizard.py
  79. 23
      subscription_package/wizard/subscription_close_wizard.xml

36
subscription_package/README.md

@ -0,0 +1,36 @@
Subscription Package for Community
==================================
* Subscription Package for Odoo 15 community edition
Installation
============
- www.odoo.com/documentation/15.0/setup/install.html
- Install our custom addon
Company
-------
* 'Cybrosys Techno Solutions <https://cybrosys.com/>`__
Contacts
--------
* Mail Contact : odoo@cybrosys.com
* Website : https://cybrosys.com
Credits
--------
* Developer: Amal Prasad @ Cybrosys,
Alakananda @ Cybrosys
Bug Tracker
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
Maintainer
==========
This module is maintained by Cybrosys Technologies.
For support and more information, please visit https://www.cybrosys.com
Further information
===================
HTML Description: `<static/description/index.html>`__

25
subscription_package/__init__.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import models
from . import report
from . import wizard

57
subscription_package/__manifest__.py

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
###################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
{
'name': 'Subscription Management For Community',
'Version': '15.0.1.0.0',
'summary': 'Subscription Package Management Module For Odoo15 Community',
'description': 'Subscription Package Management Module For Odoo15 Community',
'category': 'Sales',
'author': 'Cybrosys Techno solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': "https://www.cybrosys.com",
'depends': ['base', 'sale_management'],
'data': [
'security/security.xml',
'security/ir.model.access.csv',
'data/uom_demo.xml',
'data/subscription_stage_data.xml',
'data/mail_template.xml',
'data/cron.xml',
'wizard/subscription_close_wizard.xml',
'views/subscription_package.xml',
'views/subscription_products.xml',
'views/subscription_plan.xml',
'views/subscription_stage.xml',
'views/subscription_close.xml',
'views/subscription_renew.xml',
'views/mail_activity_views.xml',
'views/res_partner.xml',
'report/subscription_report_view.xml',
],
'images': ['static/description/banner.png'],
'license': 'AGPL-3',
'installable': True,
'application': True,
'auto_install': False,
}

14
subscription_package/data/cron.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Cron Jobs -->
<record id="close_limit_cron" model="ir.cron">
<field name="name">Check Close Limit</field>
<field name="model_id" ref="model_subscription_package"/>
<field name="state">code</field>
<field name="code">model.close_limit_cron()</field>
<field name='interval_number'>1</field>
<field name='interval_type'>days</field>
<field name="numbercall">-1</field>
</record>
</odoo>

56
subscription_package/data/mail_template.xml

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Email Templates -->
<record id="mail_template_subscription_renew" model="mail.template">
<field name="name">Subscription: Email Renew Alert</field>
<field name="model_id" ref="subscription_package.model_subscription_package"/>
<field name="subject">{{ object.company_id.name }}: Please check the subscription {{ object.name }}</field>
<field name="email_from">{{ object.company_id.email }}</field>
<field name="email_to">{{ object.partner_id.email }}</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 style="width:600px;margin:5px auto;">
<tbody>
<tr>
<td>
<a href="/">
<img src="/web/binary/company_logo"
style="vertical-align:baseline;max-width:100px;"/>
</a>
</td>
<td style="text-align:right;vertical-align:middle;">
Subscription Renew Alert
</td>
</tr>
</tbody>
</table>
<table style="width:600px;margin:0px auto;background:white;border:1px solid #e1e1e1;">
<tbody>
<tr>
<td style="padding:15px 20px 10px 20px;">
<p>Dear<t t-out="object.partner_id.name or ''"/>,
</p>
<p>Your subscription Plan
<strong t-out="object.name or ''"/>
is going to Expired on
<strong t-out="object.close_date or ''"/>.
</p>
<p>If you have some concerns about it, please contact your contact person
<t
t-out="object.company_id.name or ''"/>
or reply to this email.
</p>
<p>Kind regards.</p>
</td>
</tr>
<tr>
</tr>
</tbody>
</table>
</div>
</field>
</record>
</odoo>

25
subscription_package/data/subscription_stage_data.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record model="subscription.package.stage" id="draft_stage">
<field name="name">Draft</field>
<field name="sequence">5</field>
<field name="category">draft</field>
</record>
<record model="subscription.package.stage" id="progress_stage">
<field name="name">In Progress</field>
<field name="sequence">10</field>
<field name="category">progress</field>
</record>
<record model="subscription.package.stage" id="closed_stage">
<field name="name">Closed</field>
<field name="sequence">15</field>
<field name="fold" eval="True"/>
<field name="category">closed</field>
</record>
</data>
</odoo>

24
subscription_package/data/uom_demo.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="uom_categ_time" model="uom.category">
<field name="name">Time</field>
</record>
<record id="product_uom_months" model="uom.uom">
<field name="category_id" ref="uom_categ_time"/>
<field name="name">Months</field>
<field name="factor_inv" eval="1"/>
<field name="uom_type">reference</field>
</record>
<record id="product_uom_years" model="uom.uom">
<field name="category_id" ref="uom_categ_time"/>
<field name="name">Years</field>
<field name="factor_inv" eval="12"/>
<field name="uom_type">bigger</field>
</record>
</data>
</odoo>

29
subscription_package/models/__init__.py

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import subscription_plan
from . import subscription_stage
from . import subscription_package
from . import subscription_products
from . import subscription_close
from . import subscription_renew
from . import res_partner

34
subscription_package/models/res_partner.py

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class Partner(models.Model):
_inherit = 'res.partner'
active_subscription = fields.Boolean(string="Active Subscription",
default=False)
subscription_product_line_ids = fields.One2many('subscription.package.product.line',
'res_partner_id',
ondelete='restrict',
string='Products Line')

33
subscription_package/models/subscription_close.py

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields
class SubscriptionPackageStopReason(models.Model):
_name = "subscription.package.stop"
_description = "Subscription Package Stop Reason"
_order = 'sequence'
sequence = fields.Integer(help="Determine the display order", index=True,
string='Sequence')
name = fields.Char(string='Reason', required=True)

386
subscription_package/models/subscription_package.py

@ -0,0 +1,386 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import _, api, models, fields, SUPERUSER_ID
import datetime
from odoo.exceptions import UserError
from dateutil.relativedelta import relativedelta
class SubscriptionPackageProductLine(models.Model):
_name = 'subscription.package.product.line'
_description = 'Subscription Product Lines'
subscription_id = fields.Many2one('subscription.package', store=True,
string='Subscription')
company_id = fields.Many2one('res.company', string='Company', store=True,
related='subscription_id.company_id')
create_date = fields.Datetime(string='Create date', store=True,
default=fields.Datetime.now)
user_id = fields.Many2one('res.users', string='Salesperson', store=True,
related='subscription_id.user_id')
product_id = fields.Many2one('product.product', string='Product',
store=True, ondelete='restrict',
domain=[('is_subscription', '=', True)])
product_qty = fields.Float(string='Quantity', store=True, default=1.0)
product_uom_id = fields.Many2one('uom.uom', string='UoM', store=True,
related='product_id.uom_id',
ondelete='restrict')
uom_catg_id = fields.Many2one('uom.category', string='UoM', store=True,
related='product_id.uom_id.category_id')
unit_price = fields.Float(string='Unit Price', store=True, readonly=False,
related='product_id.list_price')
currency_id = fields.Many2one('res.currency', string='Currency',
store=True,
related='subscription_id.currency_id')
total_amount = fields.Monetary(string='Subtotal', store=True,
compute='_compute_total_amount')
sequence = fields.Integer('Sequence', help="Determine the display order",
index=True)
res_partner_id = fields.Many2one('res.partner', string='Currency',
store=True,
related='subscription_id.partner_id')
@api.depends('product_qty', 'unit_price')
def _compute_total_amount(self):
""" Calculate subtotal amount of product line """
for rec in self:
if rec.product_id:
rec.total_amount = rec.unit_price * rec.product_qty
class SubscriptionPackage(models.Model):
_name = 'subscription.package'
_description = 'Subscription Package'
_rec_name = 'name'
_inherit = ['mail.thread', 'mail.activity.mixin']
@api.model
def _read_group_stage_ids(self, categories, domain, order):
""" Read all the stages and display it in the kanban view,
even if it is empty."""
category_ids = categories._search([], order=order,
access_rights_uid=SUPERUSER_ID)
return categories.browse(category_ids)
def _default_stage_id(self):
"""Setting default stage"""
rec = self.env['subscription.package.stage'].search([], limit=1,
order='sequence ASC')
return rec.id if rec else None
name = fields.Char(string='Name', default="New", compute='_compute_name',
store=True, required=True)
partner_id = fields.Many2one('res.partner', string='Customer', store=True)
partner_invoice_id = fields.Many2one('res.partner',
string='Invoice Address',
related='partner_id', readonly=False)
partner_shipping_id = fields.Many2one('res.partner',
string='Shipping/Service Address',
related='partner_id',
readonly=False)
plan_id = fields.Many2one('subscription.package.plan',
string='Subscription Plan')
start_date = fields.Date(string='Start Date', store=True,
ondelete='restrict')
next_invoice_date = fields.Date(string='Next Invoice Date', readonly=False,
store=True,
compute="_compute_next_invoice_date")
company_id = fields.Many2one('res.company', string='Company',
default=lambda self: self.env.company,
required=True)
user_id = fields.Many2one('res.users', string='Sales Person',
default=lambda self: self.env.user)
sale_order = fields.Many2one('sale.order', string="Sale Order")
to_renew = fields.Boolean(string='To Renew', default=False)
tag_ids = fields.Many2many('account.analytic.tag', string='Tags')
stage_id = fields.Many2one('subscription.package.stage', string='Stage',
default=lambda self: self._default_stage_id(),
index=True,
group_expand='_read_group_stage_ids')
invoice_count = fields.Integer(string='Invoices',
compute='_compute_invoice_count')
so_count = fields.Integer(string='Sales', compute='_compute_sale_count')
description = fields.Text(string='Description')
analytic_account_id = fields.Many2one('account.analytic.account',
string='Analytic Account')
product_line_ids = fields.One2many('subscription.package.product.line',
'subscription_id', ondelete='restrict',
string='Products Line')
currency_id = fields.Many2one('res.currency', string='Currency',
readonly=True,
default=lambda
self: self.env.company.currency_id)
current_stage = fields.Char(string='Current Stage', default='Draft',
store=True, compute='_compute_current_stage')
reference_code = fields.Char(string='Reference', store=True)
is_closed = fields.Boolean(string="Closed", default=False)
close_reason = fields.Many2one('subscription.package.stop',
string='Close Reason')
closed_by = fields.Many2one('res.users', string='Closed By')
close_date = fields.Date(string='Closed on')
stage_category = fields.Selection(related='stage_id.category', store=True)
invoice_mode = fields.Selection(related="plan_id.invoice_mode")
total_recurring_price = fields.Float(string='Recurring Price',
compute='_compute_total_recurring_price',
store=True)
@api.depends('invoice_count')
def _compute_invoice_count(self):
""" Calculate Invoice count based on subscription package """
invoice_count = self.env['account.move'].search_count(
[('subscription_id', '=', self.id)])
if invoice_count > 0:
self.invoice_count = invoice_count
else:
self.invoice_count = 0
@api.depends('so_count')
def _compute_sale_count(self):
""" Calculate sale order count based on subscription package """
self.so_count = self.env['sale.order'].search_count(
[('subscription_id', '=', self.id)])
@api.depends('stage_id')
def _compute_current_stage(self):
""" It displays current stage for subscription package """
for rec in self:
rec.current_stage = rec.env['subscription.package.stage'].search(
[('id', '=', rec.stage_id.id)]).category
@api.depends('start_date')
def _compute_next_invoice_date(self):
pending_subscriptions = self.env['subscription.package'].search(
[('stage_category', '=', 'progress')])
for sub in pending_subscriptions:
if sub.start_date:
sub.next_invoice_date = sub.start_date + relativedelta(
days=sub.plan_id.renewal_time)
def button_invoice_count(self):
""" It displays invoice based on subscription package """
return {
'name': 'Invoices',
'domain': [('subscription_id', '=', self.id)],
'view_type': 'form',
'res_model': 'account.move',
'view_mode': 'tree,form',
'type': 'ir.actions.act_window',
'context': {
"create": False
}
}
def button_sale_count(self):
""" It displays sale order based on subscription package """
return {
'name': 'Products',
'domain': [('subscription_id', '=', self.id)],
'view_type': 'form',
'res_model': 'sale.order',
'view_mode': 'tree,form',
'type': 'ir.actions.act_window',
'context': {
"create": False
}
}
def button_close(self):
""" Button for subscription close wizard """
return {
'name': "Subscription Close Reason",
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'subscription.close.wizard',
'target': 'new'
}
def button_payment(self):
""" Button to create invoice for subscription package"""
this_products_line = []
for rec in self.product_line_ids:
rec_list = [0, 0, {'product_id': rec.product_id.id,
'quantity': rec.product_qty}]
this_products_line.append(rec_list)
invoices = self.env['account.move'].search([('subscription_id', '=', self.id), ('state', '=', 'draft')])
orders = self.env['sale.order'].search([('subscription_id', '=', self.id), ('invoice_status', '=', 'no')])
if invoices:
for invoice in invoices:
invoice.action_post()
if orders and invoices:
for order in orders:
order.action_confirm()
for invoice in invoices:
invoice.action_post()
out_invoice = self.env['account.move'].create(
{
'move_type': 'out_invoice',
'date': fields.Date.today(),
'invoice_date': fields.Date.today(),
'partner_id': self.partner_invoice_id.id,
'currency_id': self.partner_invoice_id.currency_id.id,
'invoice_line_ids': this_products_line
})
self.env['account.move'].payment_id = out_invoice.id
if self.stage_category == 'progress':
values = {'start_date': datetime.datetime.today()}
self.write(values)
return {
'name': 'Subscription Payment',
'type': 'ir.actions.act_window',
'res_model': 'account.move',
'view_mode': 'form',
'res_id': out_invoice.id
}
def button_start_date(self):
"""Button to start subscription package"""
if not self.start_date:
self.start_date = datetime.date.today()
for rec in self:
if len(rec.env['subscription.package.stage'].search([('category', '=', 'draft')])) > 1:
raise UserError(
_('More than one stage is having category "Draft". '
'Please change category of stage to "In Progress", '
'only one stage is allowed to have category "Draft"'))
else:
rec.write(
{'stage_id': (rec.env['subscription.package.stage'].search([
('category', '=', 'draft')]).id) + 1})
def button_sale_order(self):
"""Button to create sale order"""
this_products_line = []
for rec in self.product_line_ids:
rec_list = [0, 0, {'product_id': rec.product_id.id,
'product_uom_qty': rec.product_qty}]
this_products_line.append(rec_list)
# for order in self.sale_order:
orders = self.env['sale.order'].search([('subscription_id', '=', self.id), ('invoice_status', '=', 'no')])
if orders:
for order in orders:
order.action_confirm()
so_id = self.env['sale.order'].create({
'partner_id': self.partner_id.id,
'partner_invoice_id': self.partner_id.id,
'partner_shipping_id': self.partner_id.id,
'is_subscription': True,
'subscription_id': self.id,
'order_line': this_products_line
})
self.sale_order = so_id
return {
'name': _('Sales Orders'),
'type': 'ir.actions.act_window',
'res_model': 'sale.order',
'domain': [('id', '=', so_id.id)],
'view_mode': 'tree,form'
}
@api.model
def create(self, vals):
"""It displays subscription product in partner and generate sequence"""
partner = self.env['res.partner'].search(
[('id', '=', vals.get('partner_id'))])
partner.active_subscription = True
if vals.get('reference_code', 'New') is False:
vals['reference_code'] = self.env['ir.sequence'].next_by_code(
'sequence.reference.code') or 'New'
create_id = super(SubscriptionPackage, self).create(vals)
return create_id
@api.depends('reference_code')
def _compute_name(self):
"""It displays record name as combination of short code, reference
code and partner name """
plan_id = self.env['subscription.package.plan'].search(
[('id', '=', self.plan_id.id)])
if plan_id.short_code and self.reference_code:
self.name = plan_id.short_code + '/' + self.reference_code + '-' + self.partner_id.name
def set_close(self):
""" Button to close subscription package """
stage = self.env['subscription.package.stage'].search(
[('category', '=', 'closed')], limit=1).id
for sub in self:
values = {'stage_id': stage, 'to_renew': False}
sub.write(values)
return True
def close_limit_cron(self):
""" It Checks renew date, close date. It will send mail when renew date """
pending_subscriptions = self.env['subscription.package'].search(
[('stage_category', '=', 'progress')])
today_date = fields.Date.today()
pending_subscription = False
close_subscription = False
for pending_subscription in pending_subscriptions:
pending_subscription.close_date = pending_subscription.start_date + relativedelta(
days=pending_subscription.plan_id.days_to_end)
difference = (
pending_subscription.close_date - pending_subscription.start_date).days / 10
renew_date = pending_subscription.close_date - relativedelta(
days=difference)
if today_date == renew_date:
self.env.ref(
'subscription_package.mail_template_subscription_renew').send_mail(
pending_subscription.id, force_send=True)
pending_subscription.write({'to_renew': True})
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}]
this_products_line.append(rec_list)
self.env['account.move'].create(
{
'move_type': 'out_invoice',
'date': fields.Date.today(),
'invoice_date': fields.Date.today(),
'state': 'draft',
'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': datetime.datetime.today()})
close_subscriptions = self.env['subscription.package'].search(
[('stage_category', '=', 'progress'), ('to_renew', '=', True)])
for close_subscription in close_subscriptions:
close_subscription.close_date = close_subscription.start_date + relativedelta(
days=close_subscription.plan_id.days_to_end)
if today_date == close_subscription.close_date:
close_subscription.set_close()
return dict(pending=pending_subscription, closed=close_subscription)
@api.depends('product_line_ids.total_amount')
def _compute_total_recurring_price(self):
""" Calculate recurring price """
for record in self:
total_recurring = 0
for line in record.product_line_ids:
total_recurring += line.total_amount
record['total_recurring_price'] = total_recurring
def action_renew(self):
return self.button_sale_order()

130
subscription_package/models/subscription_plan.py

@ -0,0 +1,130 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, models, fields
class SubscriptionPlan(models.Model):
_name = 'subscription.package.plan'
_description = 'Subscription Package Plan'
name = fields.Char(string='Plan Name', required=True)
renewal_value = fields.Char(string='Renewal')
renewal_period = fields.Selection([('days', 'Day(s)'),
('weeks', 'Week(s)'),
('months', 'Month(s)'),
('years', 'Year(s)')],
default='months')
renewal_time = fields.Integer(string='Renewal Time Interval',
readonly=True,
compute='_compute_renewal_time',
store=True)
limit_choice = fields.Selection([('ones', 'Ones'),
('manual', 'Until Closed Manually'),
('custom', 'Custom')],
default='ones')
limit_count = fields.Integer(string='Custom Renewal Limit')
days_to_end = fields.Integer(string='Days End', readonly=True,
compute='_compute_days_to_end', store=True,
help="Subscription ending date")
invoice_mode = fields.Selection([('manual', 'Manually'),
('draft_invoice', 'Draft')],
default='draft_invoice')
journal_id = fields.Many2one('account.journal', string='Journal',
store=True, domain="[('type', '=', 'sale')]")
company_id = fields.Many2one('res.company', string='Company', store=True,
default=lambda self: self.env.company)
short_code = fields.Char(string='Short Code')
terms_and_conditions = fields.Text(string='Terms and Conditions')
product_count = fields.Integer(string='Products',
compute='_compute_product_count')
subscription_count = fields.Integer(string='Subscriptions',
compute='_compute_subscription_count')
@api.depends('product_count')
def _compute_product_count(self):
""" Calculate product count based on subscription plan """
self.product_count = self.env['product.product'].search_count(
[('subscription_plan_id', '=', self.id)])
@api.depends('subscription_count')
def _compute_subscription_count(self):
""" Calculate subscription count based on subscription plan """
self.subscription_count = self.env[
'subscription.package'].search_count([('plan_id', '=', self.id)])
@api.depends('renewal_value', 'renewal_period')
def _compute_renewal_time(self):
""" This method calculate renewal time based on renewal value """
for rec in self:
if rec.renewal_period == 'days':
rec.renewal_time = int(rec.renewal_value)
elif rec.renewal_period == 'weeks':
rec.renewal_time = int(rec.renewal_value) * 7
elif rec.renewal_period == 'months':
rec.renewal_time = int(rec.renewal_value) * 28
elif rec.renewal_period == 'years':
rec.renewal_time = int(rec.renewal_value) * 364
if rec.name:
rec.short_code = str(rec.name[0:3]).upper()
@api.depends('renewal_time', 'limit_count')
def _compute_days_to_end(self):
""" This method calculate days to end for subscription plan based on
limit count """
for rec in self:
if rec.limit_choice == 'ones':
rec.days_to_end = rec.renewal_time
if rec.limit_choice == 'manual':
rec.days_to_end = False
if rec.limit_choice == 'custom':
rec.days_to_end = rec.renewal_time * rec.limit_count
def button_product_count(self):
""" It displays products based on subscription plan """
return {
'name': 'Products',
'domain': [('subscription_plan_id', '=', self.id)],
'view_type': 'form',
'res_model': 'product.product',
'view_mode': 'tree,form',
'type': 'ir.actions.act_window',
}
def button_sub_count(self):
""" It displays subscriptions based on subscription plan """
return {
'name': 'Subscriptions',
'domain': [('plan_id', '=', self.id)],
'view_type': 'form',
'res_model': 'subscription.package',
'view_mode': 'tree,form',
'type': 'ir.actions.act_window',
}
def name_get(self):
""" It displays record name as combination of short code and
plan name """
res = []
for rec in self:
res.append((rec.id, '%s - %s' % (rec.short_code, rec.name)))
return res

51
subscription_package/models/subscription_products.py

@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, models, fields
class SubscriptionInvoice(models.Model):
_inherit = "account.move"
is_subscription = fields.Boolean(string='Is Subscription', default=False)
subscription_id = fields.Many2one('subscription.package',
string='Subscription')
@api.model_create_multi
def create(self, vals_list):
""" It displays subscription in account move """
for rec in vals_list:
so_id = self.env['sale.order'].search(
[('name', '=', rec.get('invoice_origin'))])
if so_id.is_subscription is True:
new_vals_list = [{'is_subscription': True,
'subscription_id': so_id.subscription_id}]
vals_list[0].update(new_vals_list[0])
return super(SubscriptionInvoice, self).create(vals_list)
class SubscriptionProduct(models.Model):
_inherit = "product.template"
is_subscription = fields.Boolean(string='Is Subscription', default=False)
subscription_plan_id = fields.Many2one('subscription.package.plan',
string='Subscription Plan')

68
subscription_package/models/subscription_renew.py

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, models, fields
import datetime
class SubscriptionSaleOrder(models.Model):
_inherit = "sale.order"
is_subscription = fields.Boolean(string='Is Subscription', default=False)
subscription_id = fields.Many2one('subscription.package',
string='Subscription')
sub_reference = fields.Char(string="Sub Reference Code", store=True,
compute="_compute_reference_code")
@api.model
def create(self, vals):
""" It displays subscription in sale order """
if vals.get('is_subscription') is True:
new_vals = [{
'is_subscription': True,
'subscription_id': vals.get('subscription_id'),
}]
vals.update(new_vals[0])
return super(SubscriptionSaleOrder, self).create(vals)
else:
return super(SubscriptionSaleOrder, self).create(vals)
@api.depends('subscription_id')
def _compute_reference_code(self):
""" It displays subscription reference code """
self.sub_reference = self.env['subscription.package'].search(
[('id', '=', int(self.subscription_id.id))]).reference_code
def action_confirm(self):
""" It Changed the stage, to renew, start date for subscription
package based on sale order confirm """
res = super(SubscriptionSaleOrder, self).action_confirm()
sale_order = self.subscription_id.sale_order
so_state = self.search([('id', '=', sale_order.id)]).state
if so_state in ['sale', 'done']:
stage = self.env['subscription.package.stage'].search(
[('category', '=', 'progress')], limit=1).id
values = {'stage_id': stage, 'to_renew': False,
'start_date': datetime.datetime.today()}
self.subscription_id.write(values)
return res

42
subscription_package/models/subscription_stage.py

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields
class SubscriptionPackageStage(models.Model):
_name = "subscription.package.stage"
_description = "Subscription Package Stages"
_rec_name = 'name'
name = fields.Char(string='Stage Name', required=True)
sequence = fields.Integer('Sequence', help="Determine the display order",
index=True)
condition = fields.Text(string='Conditions')
fold = fields.Boolean(string='Folded in Kanban',
help="This stage is folded in the kanban view "
"when there are no records in that stage "
"to display.")
category = fields.Selection([('draft', 'Draft'),
('progress', 'In Progress'),
('closed', 'Closed')],
readonly=False, default='draft')

23
subscription_package/report/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import subscription_report

62
subscription_package/report/subscription_report.py

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields
from odoo import tools
class SubscriptionReport(models.Model):
_name = "subscription.report"
_description = "Subscription Analysis"
_auto = False
total_recurring_price = fields.Float('Recurring Price', readonly=True)
quantity = fields.Float('Quantity', readonly=True)
user_id = fields.Many2one('res.users', 'Salesperson', readonly=True)
plan_id = fields.Many2one('subscription.package.plan', 'Subscription Template', readonly=True)
def _query(self):
select_ = """
SELECT min(sl.id) as id,
sl.product_qty as quantity,
sub.total_recurring_price as total_recurring_price,
sub.user_id as user_id,
sub.plan_id as plan_id,
sub.name as name
"""
from_ = """
subscription_package_product_line sl
join subscription_package sub on (sl.subscription_id = sub.id)
"""
groupby_ = """
GROUP BY sl.product_qty,
sub.total_recurring_price,
sub.user_id,
sub.plan_id,
sub.name
"""
return '%s FROM ( %s ) %s' % (select_, from_, groupby_)
def init(self):
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute("""CREATE or REPLACE VIEW %s as (%s)""" % (
self._table, self._query()))

37
subscription_package/report/subscription_report_view.xml

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="subscription_report_pivot" model="ir.ui.view">
<field name="name">Subscription Report Pivot</field>
<field name="model">subscription.report</field>
<field name="arch" type="xml">
<pivot string="Subscription Analysis" sample="1">
<field name="plan_id" type="row"/>
<field name="user_id" type="col"/>
</pivot>
</field>
</record>
<record id="subscription_report_graph" model="ir.ui.view">
<field name="name">Subscription Report Graph</field>
<field name="model">subscription.report</field>
<field name="arch" type="xml">
<graph string="Subscription Analysis" sample="1">
<field name="plan_id"/>
</graph>
</field>
</record>
<record id="subscription_action_action_view_pivot" model="ir.actions.act_window">
<field name="name">Subscriptions Report</field>
<field name="res_model">subscription.report</field>
<field name="view_mode">pivot,graph</field>
</record>
<menuitem id="subscription_menu_report"
name="Report"
parent="subscription_package.subscription_menu_root"
action="subscription_package.subscription_action_action_view_pivot"
sequence="11"/>
</odoo>

8
subscription_package/security/ir.model.access.csv

@ -0,0 +1,8 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_subscription_package_plan,subscription.package_plan,model_subscription_package_plan,base.group_user,1,1,1,1
access_subscription_package_stage,subscription.package.stage,model_subscription_package_stage,base.group_user,1,1,1,1
access_subscription_package,subscription.package,model_subscription_package,base.group_user,1,1,1,1
access_subscription_report,subscription.report,model_subscription_report,base.group_user,1,1,1,1
access_subscription_package_product_line,subscription.package.product.line,model_subscription_package_product_line,base.group_user,1,1,1,1
access_subscription_package_stop,subscription.package.stop,model_subscription_package_stop,base.group_user,1,1,1,1
access_subscription_close_wizard,access.subscription.close.wizard,model_subscription_close_wizard,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_subscription_package_plan subscription.package_plan model_subscription_package_plan base.group_user 1 1 1 1
3 access_subscription_package_stage subscription.package.stage model_subscription_package_stage base.group_user 1 1 1 1
4 access_subscription_package subscription.package model_subscription_package base.group_user 1 1 1 1
5 access_subscription_report subscription.report model_subscription_report base.group_user 1 1 1 1
6 access_subscription_package_product_line subscription.package.product.line model_subscription_package_product_line base.group_user 1 1 1 1
7 access_subscription_package_stop subscription.package.stop model_subscription_package_stop base.group_user 1 1 1 1
8 access_subscription_close_wizard access.subscription.close.wizard model_subscription_close_wizard base.group_user 1 1 1 1

25
subscription_package/security/security.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record model="ir.module.category" id="module_subscription_category">
<field name="name">Subscription</field>
<field name="description">Helps you handle your subscription security.</field>
<field name="sequence">9</field>
</record>
<record id="group_subscription_user" model="res.groups">
<field name="name">User</field>
<field name="category_id" ref="module_subscription_category"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="group_subscription_manager" model="res.groups">
<field name="name">Subscription Administrator</field>
<field name="category_id" ref="module_subscription_category"/>
<field name="implied_ids" eval="[(4, ref('group_subscription_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
</data>
</odoo>

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
subscription_package/static/description/assets/screenshots/activity_type.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
subscription_package/static/description/assets/screenshots/close_reason.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
subscription_package/static/description/assets/screenshots/create_sub.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

BIN
subscription_package/static/description/assets/screenshots/create_sub_plan.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
subscription_package/static/description/assets/screenshots/create_sub_stage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

BIN
subscription_package/static/description/assets/screenshots/sub_customer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

BIN
subscription_package/static/description/assets/screenshots/sub_package.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
subscription_package/static/description/assets/screenshots/sub_product.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
subscription_package/static/description/assets/screenshots/sub_renew.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
subscription_package/static/description/assets/screenshots/sub_report.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
subscription_package/static/description/assets/screenshots/sub_sale.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
subscription_package/static/description/assets/screenshots/sub_stage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
subscription_package/static/description/assets/screenshots/subscription_plan.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
subscription_package/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
subscription_package/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

719
subscription_package/static/description/index.html

@ -0,0 +1,719 @@
<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
style="background-color: #875A7B !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>Enterprise
</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;">
Subscription Package</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;">
Print Subscription Package
</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 is used to generate subscription package </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 &amp; Enterprise Support</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Available in Odoo 15.0 Community and Enterprise.</p>
</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;">
Subscription Package Plan </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;">
Subscription Renewable </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;">
Automatic Subscription Closed </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;">
Renew Email Alerts </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 Subscription Plans </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;">
Recurring Invoices Daily/Weekly/Monthly/Yearly </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-2">
<h4 class="mt-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Subscription Plans</h4>
<img src="assets/screenshots/subscription_plan.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;">
Create Subscription Plan</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
<ul>
<li>First of all, You will create a Subscription Plan.</li>
<li>In Subscription Plan we have a Radio Button named 'Number of Occurrence',<br />
- if we choose 'Ones', then this plan will expire according to 'Invoice on' time interval.<br />
- if we choose 'Until Closed Manually', then this plan will expire only after clicking the button 'Close
Subscription'.<br />
- if we choose 'Custom', then this plan will expire according to 'Invoice on' time interval and 'Renewal
Limit'.
</li>
<li>In Subscription Plan we have a Radio Button named 'Create Invoice',</li>
- If we choose 'Manually', then invoice creation is manually.<br />
- If we choose 'Draft', then invoice creation is automatically.<br />
</ul>
</p>
<img src="assets/screenshots/create_sub_plan.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;">
Create Subscription Product</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
<ul>
<li>First of all, You will create a Product.</li>
<li>Here we have a CheckBox named 'Is Subscription', if we Enable the Checkbox, then the product is
subscription
product.</li>
<li>Now we choose a Subscription Plan for the period.</li>
</ul>
</p>
<img src="assets/screenshots/sub_product.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;">
Create Subscription Customer</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
<ul>
<li>First of all, You will create a Customer.</li>
<li>Here we have a page 'Subscription' that show subscription product for customer.</li>
</ul>
</p>
<img src="assets/screenshots/sub_customer.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;">
Activity Types </h4>
<img src="assets/screenshots/activity_type.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;">
Subscription Close Reasons </h4>
<img src="assets/screenshots/close_reason.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;">
Subscription Stages </h4>
<img src="assets/screenshots/sub_stage.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;">
Create Subscription Stage </h4>
<img src="assets/screenshots/create_sub_stage.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;">
Subscription Report </h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
It shows report for subscription plans.
</p>
<img src="assets/screenshots/sub_report.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;">
Subscriptions to Renew </h4>
<img src="assets/screenshots/sub_renew.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;">
Create Subscription Package with Sale Order </h4>
<img src="assets/screenshots/create_sub.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;">
<ul>
<li>To create a Subscription with source 'Create Sale Order', Create a Quotation of Sale Order with at least
one
subscription type product in the order line.</li>
<li>When we click on the 'Confirm' button on the 'Sale Quotation' then, automatically a subscription is
created
in 'In-progress' state. </li>
</ul>
</p>
<img src="assets/screenshots/sub_sale.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>

18
subscription_package/views/mail_activity_views.xml

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<odoo>
<!-- Activity types config -->
<record id="action_config_subscription_package_mail_activity" model="ir.actions.act_window">
<field name="name">Activity Types</field>
<field name="res_model">mail.activity.type</field>
<field name="view_mode">tree,form</field>
<field name="domain">['|', ('res_model', '=', False), ('res_model', '=', 'subscription.package')]</field>
<field name="context">{'default_res_model': 'subscription.package'}</field>
</record>
<menuitem id="subscription_config_menu_mail_activity"
name="Activity Types"
parent="subscription_package.subscription_menu_config"
action="subscription_package.action_config_subscription_package_mail_activity"
sequence="28"/>
</odoo>

27
subscription_package/views/res_partner.xml

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="inherit_subscription_partner_form" model="ir.ui.view">
<field name="name">inherit.subscription.partner.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<page name="sales_purchases" position="after">
<page string="Subscription">
<group string="Subscriptions"
name="subscription_product_id">
<field name="subscription_product_line_ids" nolabel="1">
<tree editable="bottom">
<field name="product_id"/>
<field name="uom_catg_id"/>
<field name="product_uom_id"/>
<field name="unit_price"/>
</tree>
</field>
</group>
</page>
</page>
</field>
</record>
</odoo>

27
subscription_package/views/subscription_close.xml

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="action_config_subscription_stop" model="ir.actions.act_window">
<field name="name">Subscription Stop Reason</field>
<field name="res_model">subscription.package.stop</field>
<field name="view_mode">tree</field>
</record>
<record id="subscription_close_reason_tree" model="ir.ui.view">
<field name="name">Subscription Stop Reason Tree</field>
<field name="model">subscription.package.stop</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name" colspan="3"/>
</tree>
</field>
</record>
<menuitem id="subscription_menu_close_reason"
name="Reason to Close"
parent="subscription_package.subscription_menu_config"
action="subscription_package.action_config_subscription_stop"
sequence="27"/>
</odoo>

272
subscription_package/views/subscription_package.xml

@ -0,0 +1,272 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="sequence_reference_code" model="ir.sequence">
<field name="name">Reference Code</field>
<field name="code">sequence.reference.code</field>
<field name="prefix">SUB</field>
<field name="padding">4</field>
</record>
</data>
<record id="subscription_action_subscriptions" model="ir.actions.act_window">
<field name="name">Subscriptions</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">subscription.package</field>
<field name="view_mode">kanban,tree,form,pivot</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new subscription package !
</p>
</field>
</record>
<record id="subscription_action_subscriptions_customers" model="ir.actions.act_window">
<field name="name">Subscriptions Customers</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner</field>
<field name="view_mode">kanban,tree,form</field>
<field name="domain">[('active_subscription', '=', True)]</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new subscription package !
</p>
</field>
</record>
<record id="subscription_action_subscriptions_to_renew" model="ir.actions.act_window">
<field name="name">Subscriptions to Renew</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">subscription.package</field>
<field name="domain">[('to_renew', '=', True)]</field>
<field name="view_mode">kanban,tree,form,pivot</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new subscription package !
</p>
</field>
</record>
<record id="subscription_package_tree" model="ir.ui.view">
<field name="name">subscription.package.tree</field>
<field name="model">subscription.package</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="stage_id"/>
<field name="partner_id"/>
<field name="reference_code"/>
<field name="start_date"/>
</tree>
</field>
</record>
<record id="subscription_package_form" model="ir.ui.view">
<field name="name">subscription.package.form</field>
<field name="model">subscription.package</field>
<field name="groups_id" eval="[(4, ref('subscription_package.group_subscription_user'))]"/>
<field name="arch" type="xml">
<form>
<header>
<field name="current_stage" invisible="1"/>
<field name="is_closed" invisible="1"/>
<button name="button_start_date" string="START"
type="object" class="btn-primary oe_read_only" attrs="{'invisible': [('stage_category','!=', 'draft')]}"/>
<button name="button_sale_order" string="Create Sale Order"
type="object" class="btn-primary oe_read_only" attrs="{'invisible': [('so_count','>',0)]}"/>
<button name="button_payment" string="Invoice"
type="object" class="btn-primary oe_read_only"
attrs="{'invisible': [('so_count', '=', 0)]}"
invisible="1"/>
<button name="button_close" string="Close Subscription"
type="object" class="btn-primary oe_read_only"
attrs="{'invisible': [('stage_category', 'in', ['draft', 'closed'])]}"/>
<button name="action_renew" string="Renew" type="object" class="btn-primary oe_read_only" attrs="{'invisible': [('so_count', '=', 0)]}"/>
<field name="stage_id" widget="statusbar" options="{'clickable' :0}"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="button_sale_count" type="object" class="oe_stat_button"
icon="fa-credit-card" attrs="{'invisible': [('sale_order', '=', False)]}">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value">
<field name="so_count"/>
</span>
<span class="o_stat_text">
Sale Order
</span>
</div>
</button>
<button name="button_invoice_count" type="object" class="oe_stat_button"
icon="fa-book" attrs="{'invisible': [('invoice_count','&lt;=',0)]}">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value">
<field name="invoice_count"/>
</span>
<span class="o_stat_text">
Invoices
</span>
</div>
</button>
</div>
<div class="text-truncate w-100">
<h1>
<field name="name"
placeholder="e.g. Monthly Subscriptions"
attrs="{'readonly': 1}"/>
</h1>
<div class="badge-pill badge-danger float-right"
attrs="{'invisible': [('to_renew', '=', False)]}">
For Renewal
</div>
</div>
<group>
<group>
<field name="partner_id" attrs="{'required': True}"/>
<field name="partner_invoice_id"/>
<field name="partner_shipping_id"/>
<field name="start_date"/>
<field name="next_invoice_date"/>
</group>
<group>
<field name="plan_id" attrs="{'required': True}"/>
<field name="to_renew"/>
<field name="reference_code"/>
<field name="analytic_account_id"/>
<field name="tag_ids" widget="many2many_tags"
options="{'limit': 2, 'create': false, 'create_edit': false}"/>
<field name="user_id"/>
<field name="company_id"/>
<field name="stage_category" invisible="1"/>
<field name="invoice_mode" invisible="1"/>
</group>
</group>
<notebook>
<page string="Subscriptions" name="subscription_products_line">
<field name="product_line_ids">
<tree string="Product lines" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="product_id" required="1"/>
<field name="uom_catg_id" invisible="1"/>
<field name="product_qty" required="1"/>
<field name="product_uom_id" required="1"/>
<field name="currency_id" invisible="1"/>
<field name="unit_price" required="1"/>
<field name="total_amount" readonly="1"/>
</tree>
</field>
<group name="note_group" col="6" class="mt-2 mt-md-0">
<group class="oe_subtotal_footer oe_right" colspan="2" name="recurring_total">
<field name="total_recurring_price"/>
</group>
</group>
</page>
<page string="Terms and Conditions" name="terms_and_conditions">
<field name="description" placeholder="Terms and Conditions."/>
</page>
<page string="Other Info" name="other_info">
<group>
<group>
<field name="user_id"/>
<field name="sale_order"/>
</group>
<group>
</group>
</group>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
<field name="activity_ids" widget="mail_activity"/>
</div>
</form>
</field>
</record>
<record id="subscription_package_kanban" model="ir.ui.view">
<field name="name">subscription.package.kanban</field>
<field name="model">subscription.package</field>
<field name="arch" type="xml">
<kanban default_group_by="stage_id" quick_create="false" class="o_kanban_mobile" sample="1">
<field name="stage_id"/>
<field name="user_id"/>
<field name="to_renew"/>
<field name="partner_id"/>
<field name="reference_code"/>
<progressbar field='stage_id'
colors='{"progress_stage": "success", "draft_stage": "warning", "closed_stage": "muted"}'/>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_card oe_kanban_global_click">
<div class="oe_kanban_content">
<div class="o_kanban_record_title">
<field name="partner_id"/>
</div>
<div class="o_kanban_record_body">
<field name="reference_code"/>
<br/>
<div class="badge badge-pill badge-info badge-danger mt4 mr16"
attrs="{'invisible': [('to_renew', '=', False)]}">
To Renew
</div>
</div>
<div class="o_kanban_record_bottom">
<div class="oe_kanban_bottom_left">
<field name="activity_ids" widget="kanban_activity"/>
</div>
<div class="oe_kanban_bottom_right">
<field name="user_id" widget="many2one_avatar_user"/>
</div>
</div>
</div>
<div class="oe_clear"/>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="subscription_package_pivot" model="ir.ui.view">
<field name="name">subscription.package.pivot</field>
<field name="model">subscription.package</field>
<field name="arch" type="xml">
<pivot string="Pivot View">
<field name="name" type="row"/>
</pivot>
</field>
</record>
<menuitem id="subscription_menu_root"
name="Subscription"
action="subscription_package.subscription_action_subscriptions"
sequence="1" groups="group_subscription_user"/>
<menuitem id="subscription_menu_subscriptions"
name="Subscriptions"
parent="subscription_package.subscription_menu_root"
sequence="3"/>
<menuitem id="subscriptions_menu_subscriptions"
name="Subscriptions"
parent="subscription_package.subscription_menu_subscriptions"
action="subscription_package.subscription_action_subscriptions"
sequence="5"/>
<menuitem id="subscriptions_menu_subscriptions_to_renew"
name="Subscriptions to Renew"
parent="subscription_package.subscription_menu_subscriptions"
action="subscription_package.subscription_action_subscriptions_to_renew"
sequence="6"/>
<menuitem id="subscriptions_menu_subscriptions_customers"
name="Customers"
parent="subscription_package.subscription_menu_subscriptions"
action="subscription_package.subscription_action_subscriptions_customers"
sequence="7"/>
</odoo>

108
subscription_package/views/subscription_plan.xml

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="action_conf_subscription_plan" model="ir.actions.act_window">
<field name="name">Subscription Plan</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">subscription.package.plan</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new subscription plan !
</p>
</field>
</record>
<record id="subscription_plan_tree" model="ir.ui.view">
<field name="name">subscription.package.plan.tree</field>
<field name="model">subscription.package.plan</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="renewal_period"/>
<field name="company_id"/>
<field name="short_code"/>
</tree>
</field>
</record>
<record id="subscription_plan_form" model="ir.ui.view">
<field name="name">subscription.package.plan.form</field>
<field name="model">subscription.package.plan</field>
<field name="arch" type="xml">
<form>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="button_product_count" type="object"
class="oe_stat_button" icon="fa-shopping-cart">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value">
<field name="product_count"/>
</span>
<span class="o_stat_text">
Products
</span>
</div>
</button>
<button name="button_sub_count" class="oe_stat_button"
icon="fa-book" type="object">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value">
<field name="subscription_count"/>
</span>
<span class="o_stat_text">
Subscriptions
</span>
</div>
</button>
</div>
<div class="oe_title">
<h1><field name="name" placeholder="e.g. Yearly Subscription"/>
</h1>
</div>
<group id="conditions">
<group id="invoicing_left">
<label string="Invoice on" for="renewal_value"/>
<div class="o_row">
Every
<field name="renewal_value" attrs="{'required': True}"/>
<field name="renewal_period" attrs="{'required': True}"/>
</div>
<field name="limit_choice" string="Number of Occurrence"
widget="radio"/>
<label string="Renewal Limit" for="limit_count" attrs="{'invisible': [('limit_choice', '!=', 'custom')]}"/>
<div class="o_row" attrs="{'invisible': [('limit_choice', '!=', 'custom')]}">
<field name="limit_count" attrs="{'required': [('limit_choice', '=', 'custom')]}" readonly="0"/>
term(s)
</div>
</group>
<group id="invoicing_right">
<field name="renewal_time" invisible="1"/>
<field name="days_to_end" invisible="1"/>
<field name="invoice_mode" string="Create Invoice"
widget="radio" attrs="{'required': True}"/>
<field name="short_code"/>
<field name="journal_id"/>
<field name="company_id"/>
</group>
</group>
<separator string="Terms and conditions"/>
<field name="terms_and_conditions"
placeholder="Terms and conditions."/>
</sheet>
</form>
</field>
</record>
<menuitem id="subscription_menu_config"
name="Configuration"
parent="subscription_package.subscription_menu_root"
sequence="21" groups="group_subscription_manager"/>
<menuitem id="subscription_config_menu_subscription_template"
name="Subscription Plan"
parent="subscription_package.subscription_menu_config"
action="subscription_package.action_conf_subscription_plan"
sequence="23" groups="group_subscription_manager"/>
</odoo>

86
subscription_package/views/subscription_products.xml

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="product_template_search_view_inherit" model="ir.ui.view">
<field name="name">Inherit Product Search</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_search_view"/>
<field name="priority">25</field>
<field name="arch" type="xml">
<xpath expr="//filter[@name='filter_to_sell']" position="before">
<filter string="Is Subscription Product"
name="filter_is_subscription"
domain="[('is_subscription','=',True)]"/>
<separator/>
</xpath>
</field>
</record>
<record id="product_inherit_subscription" model="ir.ui.view">
<field name="name">Inherit Product Product: Is Subscription Product</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="//page[@name='sales']" position="after">
<page name="subscription" string="Subscription">
<group>
<group name="subscription" string="Subscription">
<field name="is_subscription"/>
<field name="subscription_plan_id"
attrs="{'required': [('is_subscription', '=', True)],
'invisible': [('is_subscription', '!=', True)],}"/>
</group>
</group>
</page>
</xpath>
</field>
</record>
<record id="product_template_inherit_subscription" model="ir.ui.view">
<field name="name">Inherit Product Template: Product Subscription</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_only_form_view"/>
<field name="priority">25</field>
<field name="arch" type="xml">
<xpath expr="//page[@name='sales']" position="after">
<page name="subscription" string="Subscription">
<group>
<group name="subscription" string="Subscription">
<field name="is_subscription"/>
<field name="subscription_plan_id"
attrs="{'required': [('is_subscription', '=', True)],
'invisible': [('is_subscription', '!=', True)],}"/>
</group>
</group>
</page>
</xpath>
</field>
</record>
<record id="action_subscription_products" model="ir.actions.act_window">
<field name="name">Products</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.template</field>
<field name="view_mode">kanban,tree,form,activity</field>
<field name="view_id" ref="product.product_template_kanban_view"/>
<field name="search_view_id" ref="product.product_template_search_view"/>
<field name="context">{
'search_default_filter_is_subscription': True,
'search_default_filter_to_sell':1,
'default_type':'service',
'default_is_subscription':True}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new product
</p>
</field>
</record>
<menuitem id="subscription_menu_subscription_products"
name="Products"
parent="subscription_package.subscription_menu_subscriptions"
action="subscription_package.action_subscription_products"
sequence="9"/>
</odoo>

21
subscription_package/views/subscription_renew.xml

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_order_form_subscription" model="ir.ui.view">
<field name="name">sale.order.form.subscription.info</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<data>
<xpath expr="//group[@name='sales_person']" position='after'>
<group string="Subscription" name="subscription_info">
<field name="is_subscription"/>
<field name="subscription_id"/>
<field name="sub_reference"/>
</group>
</xpath>
</data>
</field>
</record>
</odoo>

51
subscription_package/views/subscription_stage.xml

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="action_config_subscription_stages" model="ir.actions.act_window">
<field name="name">Stages</field>
<field name="res_model">subscription.package.stage</field>
<field name="view_mode">tree,form</field>
</record>
<record id="subscription_stages_tree" model="ir.ui.view">
<field name="name">Subscription Stage Tree</field>
<field name="model">subscription.package.stage</field>
<field name="arch" type="xml">
<tree>
<field name="sequence" widget="handle"/>
<field name="name"/>
</tree>
</field>
</record>
<record id="subscription_stages_form" model="ir.ui.view">
<field name="name">Subscription Stage Form</field>
<field name="model">subscription.package.stage</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group>
<field name="name" attrs="{'required': True}"/>
<field name="sequence"/>
</group>
<group>
<field name="fold"/>
<field name="category" widget="radio"/>
</group>
</group>
<separator string="Conditions"/>
<field name="condition"
placeholder="Specify the conditions that need to be satisfied to move to this stage."/>
</sheet>
</form>
</field>
</record>
<menuitem id="subscription_config_menu_subscription_stages"
name="Stages"
parent="subscription_package.subscription_menu_config"
action="subscription_package.action_config_subscription_stages"
sequence="25"/>
</odoo>

23
subscription_package/wizard/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import subscription_close_wizard

45
subscription_package/wizard/subscription_close_wizard.py

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models, fields, api
class SubscriptionCloseWizard(models.TransientModel):
_name = 'subscription.close.wizard'
_description = 'Subscription Close Wizard'
close_reason = fields.Many2one('subscription.package.stop', string='Close Reason')
closed_by = fields.Many2one('res.users', string='Closed By', default=lambda self: self.env.user)
close_date = fields.Date(string='Closed On', default=lambda self: fields.Date.today())
def button_submit(self):
self.ensure_one()
this_sub_id = self.env.context.get('active_id')
sub = self.env['subscription.package'].search([('id', '=', this_sub_id)])
sub.is_closed = True
sub.close_reason = self.close_reason
sub.closed_by = self.closed_by
sub.close_date = self.close_date
stage = (self.env['subscription.package.stage'].search([
('category', '=', 'closed')]).id)
values = {'stage_id': stage, 'to_renew': False}
sub.write(values)

23
subscription_package/wizard/subscription_close_wizard.xml

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="subscription_close_wizard_view" model="ir.ui.view">
<field name="name">subscription.close.wizard.view</field>
<field name="model">subscription.close.wizard</field>
<field name="arch" type="xml">
<form string="Subscription Close Wizard">
<group class="oe_title">
<field name="close_reason"/>
<field name="closed_by"/>
<field name="close_date"/>
</group>
<footer>
<button name="button_submit" string="Submit" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary"
special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>
Loading…
Cancel
Save