-
-
Notifications
You must be signed in to change notification settings - Fork 184
🎉 saas apps #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 12.0
Are you sure you want to change the base?
🎉 saas apps #100
Changes from 11 commits
845b109
b98976d
e3b5afa
29848c6
235ebc2
40f02c3
e8dd2e8
58234c9
9e61bae
eb2907d
81e4d1e
79c35c7
3154109
f1a14e0
1440f2d
b0fa938
c47992f
e776229
d1136db
29911a7
337085a
d2aa52b
787c8e1
8147ade
9b5d380
cfa5293
5c64909
80673c3
0e1086b
b038cd6
009f9a1
ea56bde
8419591
07f7d44
fde507d
b5ba13d
77dfd5a
32dbf36
992e60d
1085d17
0a8c338
1a757b0
c571c0c
e0b6343
540cb72
c2210a4
838e4a6
e5fb5d5
b1f4710
e7ecfcc
e589d21
dd76550
bd57266
da1e5db
47c2974
da04c05
0dbe77d
37a8121
a5b9676
2324ede
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| .. image:: https://img.shields.io/badge/license-LGPL--3-blue.png | ||
| :target: https://www.gnu.org/licenses/lgpl | ||
| :alt: License: LGPL-3 | ||
|
|
||
| =========== | ||
| Saas Apps | ||
| =========== | ||
|
|
||
| Base module for manage modules in saas. | ||
|
|
||
| Module allows to choose modules that users gona use in their db. | ||
|
|
||
| Credits | ||
| ======= | ||
|
|
||
| Contributors | ||
| ------------ | ||
| * `Vildan Safin <https://www.it-projects.info/team/Enigma228322>`__ | ||
|
|
||
| Sponsors | ||
| -------- | ||
| * `IT-Projects LLC <https://it-projects.info>`__ | ||
|
|
||
| Maintainers | ||
| ----------- | ||
| * `IT-Projects LLC <https://it-projects.info>`__ | ||
|
|
||
| To get a guaranteed support | ||
| you are kindly requested to purchase the module | ||
| at `odoo apps store <https://apps.odoo.com/apps/modules/12.0/saas_apps/>`__. | ||
|
|
||
| Thank you for understanding! | ||
|
|
||
| `IT-Projects Team <https://www.it-projects.info/team>`__ | ||
|
|
||
| Further information | ||
| =================== | ||
|
|
||
| Demo: http://runbot.it-projects.info/demo/odoo-saas-tools/12.0 | ||
|
|
||
| HTML Description: https://apps.odoo.com/apps/modules/12.0/saas_apps/ | ||
|
|
||
| Usage instructions: `<doc/index.rst>`_ | ||
|
|
||
| Changelog: `<doc/changelog.rst>`_ | ||
|
|
||
| Notifications on updates: `via Atom <https://github.com/it-projects-llc/odoo-saas-tools/commits/12.0/saas_apps.atom>`_, `by Email <https://blogtrottr.com/?subscribe=https://github.com/it-projects-llc/odoo-saas-tools/commits/12.0/saas_apps.atom>`_ | ||
|
|
||
| Tested on Odoo 12.0 feb7c99f47cae55fff77035fe53975ea4a14d624 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). | ||
| from . import controllers, models |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # Copyright 2020 Vildan Safin <https://github.com/Enigma228322> | ||
| # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). | ||
|
|
||
| { | ||
| "name": """SaaS Apps""", | ||
| "summary": """Choose your apps""", | ||
| "category": "Marketing", | ||
| # "live_test_url": "http://apps.it-projects.info/shop/product/DEMO-URL?version=12.0", | ||
| "images": ['/images/attention.jpg'], | ||
| "version": "12.0.1.0.0", | ||
| "application": False, | ||
|
|
||
| "author": "IT-Projects LLC, Vildan Safin", | ||
| "support": "apps@it-projects.info", | ||
| "website": "https://apps.odoo.com/apps/modules/12.0/saas_apps/", | ||
| "license": "LGPL-3", | ||
| # "price": 9.00, | ||
| # "currency": "EUR", | ||
|
|
||
| "depends": ['website'], | ||
| "external_dependencies": {"python": [], "bin": []}, | ||
| "data": [ | ||
| 'security/ir.model.access.csv', | ||
| 'views/calculator.xml', | ||
| 'views/manage.xml', | ||
| 'views/assets.xml' | ||
| ], | ||
| "demo": [ | ||
| ], | ||
| "qweb": [ | ||
| 'views/refresh.xml' | ||
| ], | ||
|
|
||
| "post_load": None, | ||
| "pre_init_hook": None, | ||
| "post_init_hook": None, | ||
| "uninstall_hook": None, | ||
|
|
||
| "auto_install": False, | ||
| "installable": True, | ||
|
|
||
| # "demo_title": "SaaS Apps", | ||
| # "demo_addons": [ | ||
| # ], | ||
| # "demo_addons_hidden": [ | ||
| # ], | ||
| # "demo_url": "DEMO-URL", | ||
| # "demo_summary": "short", | ||
| # "demo_images": [ | ||
| # "images/MAIN_IMAGE", | ||
| # ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). | ||
| from . import main |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Copyright 2020 Vildan Safin <https://github.com/Enigma228322> | ||
| # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). | ||
|
|
||
| from odoo.http import route, request, Controller | ||
| from odoo import http | ||
|
Enigma228322 marked this conversation as resolved.
Outdated
|
||
| from openerp.http import request | ||
| import json | ||
|
|
||
| class SaaSAppsController(Controller): | ||
| @route('/price', auth='public', website=True) | ||
| def user_page(self, **kw): | ||
| apps = http.request.env['saas.line'] | ||
| return http.request.render('saas_apps.index', { | ||
| 'apps': apps.search([('allow_to_sell', '=', True)]) | ||
| }) | ||
|
|
||
| @http.route(['/refresh'], type='json', auth='public', website=True) | ||
| def catch_app_click(self, **kw): | ||
| apps = http.request.env['saas.line'] | ||
| apps.refresh() | ||
| return {} | ||
|
|
||
| @http.route(['/what_dependencies'], type='json', auth='public', website=True) | ||
| def what_dependencies(self, **kw): | ||
|
Enigma228322 marked this conversation as resolved.
Outdated
|
||
| app_name, which_price = kw['args'] | ||
| app = http.request.env['saas.line'].search([('name', '=', app_name)]) | ||
| month = False | ||
| if which_price == 'month': | ||
| month = True | ||
| return { | ||
| 'dependencies': app.dependencies_info(month, 0) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| `1.0.0` | ||
| ------- | ||
|
|
||
| - **Init version** | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😍 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| =========== | ||
| Saas Apps | ||
| =========== | ||
|
|
||
| Installation | ||
| ============ | ||
| {Instruction about things to do before actual installation} | ||
|
|
||
| * {OPTIONAL }`Activate longpolling <https://odoo-development.readthedocs.io/en/latest/admin/longpolling.html>`__ | ||
| * {Additional notes if any} | ||
| * `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way | ||
|
|
||
| Configuration | ||
| ============= | ||
|
|
||
| {Instruction how to configure the module before start to use it} | ||
|
Enigma228322 marked this conversation as resolved.
Outdated
|
||
|
|
||
| * `Log in as SUPERUSER <https://odoo-development.readthedocs.io/en/latest/odoo/usage/login-as-superuser.html>`__ | ||
| * `Activate Developer Mode <https://odoo-development.readthedocs.io/en/latest/odoo/usage/debug-mode.html>`__ | ||
| * Open menu ``[[ {Menu} ]] >> {Submenu} >> {Subsubmenu}`` | ||
| * Click ``[{Button Name}]`` | ||
|
|
||
| Usage | ||
| ===== | ||
|
|
||
| {Instruction for daily usage. It should describe how to check that module works. What shall user do and what would user get.} | ||
|
|
||
| * Open menu ``[[ {Menu} ]]>> {Submenu} >> {Subsubmenu}`` | ||
| * Click ``[{Button Name}]`` | ||
| * RESULT: {what user gets, how the modules changes default behaviour} | ||
|
Enigma228322 marked this conversation as resolved.
Outdated
|
||
|
|
||
| Uninstallation | ||
| ============== | ||
|
|
||
| {Optional section for uninstallation notes. Delete it if you don't have notes for uninstallation.} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). | ||
| from . import saas_apps |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| # Copyright 2020 Vildan Safin <https://github.com/Enigma228322> | ||
| # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). | ||
|
|
||
| from odoo import api, fields, models | ||
| import logging | ||
|
|
||
| _logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| class SAASModule(models.Model): | ||
| _name = 'saas.module' | ||
|
Enigma228322 marked this conversation as resolved.
Outdated
|
||
| _description = 'Model line' | ||
|
|
||
| name = fields.Char(default="default", string="Module Name") | ||
| month_price = fields.Float(default=0.0, string="Month price") | ||
| year_price = fields.Float(default=0.0, string="Year price") | ||
| icon_path = fields.Char(compute='_compute_path', string="icon path") | ||
| saas_modules = fields.Many2one('saas.line', string="Module dependencies") | ||
|
|
||
| def _compute_path(self): | ||
| self.icon_path = "/saas_apps/static/src/img/%s.png" % self.name | ||
|
|
||
| @api.model | ||
| def create(self, vals): | ||
| rec = super(SAASModule, self).create(vals) | ||
| if len(self.saas_modules) > 0: | ||
| self.name = self.saas_modules.name | ||
| return rec | ||
|
Enigma228322 marked this conversation as resolved.
Outdated
|
||
|
|
||
| @api.constrains('month_price', 'year_price') | ||
| def _validate_price(self): | ||
| if self.month_price < 0 or self.year_price < 0: | ||
| raise "Price can't be negative." | ||
|
Enigma228322 marked this conversation as resolved.
Outdated
|
||
|
|
||
| def add_new_module(self, name): | ||
| self.create({ | ||
| 'name': name | ||
| }) | ||
| return True | ||
|
Enigma228322 marked this conversation as resolved.
Outdated
|
||
|
|
||
| def refresh(self): | ||
| irmodules = self.env["ir.module.module"].search([]) | ||
| if len(irmodules) > len(self.search([])): | ||
| for irmodule in irmodules: | ||
| if len(self.search([('name', '=', irmodule.name)])) == 0: | ||
| self.create({'name': irmodule.name}) | ||
|
|
||
| def cost(self, month): | ||
| if month: | ||
| return self.month_price | ||
| else: | ||
| return self.year_price | ||
|
|
||
|
|
||
| class SAASDependence(models.Model): | ||
| _name = 'saas.line' | ||
| _description = 'Module dependencies' | ||
|
|
||
| # First dependence is root module | ||
| name = fields.Char(default="default", string="Module Name") | ||
| allow_to_sell = fields.Boolean(string="Sellable") | ||
| dependencies = fields.One2many('saas.module', 'saas_modules', ondelete='cascade', delegate=True) | ||
| year_price = fields.Float(default=0.0, compute='_compute_year_price', string="Price per year") | ||
| month_price = fields.Float(default=0.0, compute='_compute_month_price', string="Price per month") | ||
|
|
||
| def refresh(self): | ||
| apps = self.env["saas.module"] | ||
| apps.refresh() | ||
| apps = apps.search([]) | ||
| if len(apps) > len(self.search([])): | ||
| for app in apps: | ||
| if len(self.search([('name', '=', app.name)])) == 0: | ||
| new = self.create({'name': app.name}) | ||
| new.dependencies += app | ||
|
|
||
| def _compute_year_price(self): | ||
| for module in self.dependencies: | ||
| self.year_price += module.year_price | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Обнуляем сначала, потом суммируем. Если незаметно от глаз будет 2 раза вызываться _compute_year_price, то ничего хорошего не будет. |
||
|
|
||
| def _compute_month_price(self): | ||
| for module in self.dependencies: | ||
| self.month_price += module.month_price | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Аналогично |
||
|
|
||
| def dependencies_info(self, for_month, deep): | ||
| apps = [] | ||
| # Root module | ||
| if not deep: | ||
| apps.append({ | ||
| 'parent': 'root', | ||
| 'name': self.name, | ||
| 'price': self.dependencies[0].cost(for_month) | ||
| }) | ||
| # Looking to the period | ||
| for app in self.dependencies - self.dependencies[0]: | ||
| set = self.search([('name', '=', app.name)]) | ||
| leafs = set.dependencies_info(for_month, deep + 1) | ||
| for leaf in leafs: | ||
| if not(leaf in apps): | ||
| apps.append(leaf) | ||
| item = { | ||
| 'parent': self.name, | ||
| 'name': app.name, | ||
| 'price': app.cost(for_month) | ||
| } | ||
| if not(item in apps): | ||
| apps.append(item) | ||
| return apps | ||
|
|
||
| @api.multi | ||
| def write(self, vals): | ||
| last_value = self.allow_to_sell | ||
| res = super(SAASDependence, self).write(vals) | ||
| # If value of allow_to_sell changed, other sets allow_to_sell vars should be changed too | ||
|
Enigma228322 marked this conversation as resolved.
|
||
| # If it's not, then if root modules(self) allow_to_sell value is True, then other sets allow_to_sell values should be True | ||
| if "allow_to_sell" in vals: | ||
| if vals['allow_to_sell'] != last_value and not last_value: | ||
| for app in self.dependencies: | ||
| self.search([('name', '=', app.name)]).allow_to_sell = vals['allow_to_sell'] | ||
| else: | ||
| if last_value: | ||
| for app in self.dependencies: | ||
| self.search([('name', '=', app.name)]).allow_to_sell = True | ||
| return res | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink | ||
| access_saas_line,access_saas_line,model_saas_line,base.group_user,1,1,1,1 | ||
| access_saas_module,access_saas_module,model_saas_module,base.group_user,1,1,1,1 | ||
|
Comment on lines
+1
to
+3
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если различные манипуляции с saas.module и saas.line будут исключительно в коде, то может быть для пользователей оставим возможность только читать? |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| .col-lg-12{ | ||
| flex: 0 0 100%; | ||
| max-width: 100%; | ||
| } | ||
|
|
||
| .img{ | ||
| float: left; | ||
| width: 30%; | ||
| padding: 10px; | ||
| } | ||
|
|
||
| @media (min-width: 1000px) { | ||
| #price-window | ||
| { | ||
| position: fixed; | ||
| right: 30%; | ||
| top: 20%; | ||
| width: 15%; | ||
| z-index: 1; | ||
| } | ||
| } | ||
|
|
||
| @media (min-width: 800px) { | ||
| #price-window | ||
| { | ||
| position: fixed; | ||
| right: 15%; | ||
| top: 20%; | ||
| width: 25%; | ||
| z-index: 1; | ||
| } | ||
| } | ||
|
|
||
| @media (max-width: 799px) { | ||
| #price-window | ||
| { | ||
| position: fixed; | ||
| right: 0; | ||
| bottom: -10%; | ||
| width: 100%; | ||
| z-index: 1; | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.