From 845b10965b652e8b8fd1e586e0d8725d98e4e1d8 Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Sat, 22 Feb 2020 17:05:59 +0500 Subject: [PATCH 01/60] :tada: first commit Signed-off-by: Vildan Safin --- .mrbob.ini | 18 +++++++++ saas_apps/README.rst | 51 ++++++++++++++++++++++++++ saas_apps/__init__.py | 2 + saas_apps/__manifest__.py | 48 ++++++++++++++++++++++++ saas_apps/controllers/__init__.py | 2 + saas_apps/controllers/main.py | 10 +++++ saas_apps/doc/changelog.rst | 4 ++ saas_apps/doc/index.rst | 35 ++++++++++++++++++ saas_apps/models/__init__.py | 2 + saas_apps/models/saas_apps.py | 11 ++++++ saas_apps/static/description/icon.png | Bin 0 -> 4957 bytes 11 files changed, 183 insertions(+) create mode 100644 .mrbob.ini create mode 100644 saas_apps/README.rst create mode 100644 saas_apps/__init__.py create mode 100644 saas_apps/__manifest__.py create mode 100644 saas_apps/controllers/__init__.py create mode 100644 saas_apps/controllers/main.py create mode 100644 saas_apps/doc/changelog.rst create mode 100644 saas_apps/doc/index.rst create mode 100644 saas_apps/models/__init__.py create mode 100644 saas_apps/models/saas_apps.py create mode 100644 saas_apps/static/description/icon.png diff --git a/.mrbob.ini b/.mrbob.ini new file mode 100644 index 000000000..c2469e116 --- /dev/null +++ b/.mrbob.ini @@ -0,0 +1,18 @@ +[variables] +copyright.name = saas apps +copyright.github = saas-addons +addon.version = 12 +addon.technical_category = saas +addon.category = Marketing +addon.dependency = +addon.upstream = odoo-saas-tools +addon.name = SaaS Apps +addon.technical_name = saas_apps +addon.summary = short +addon.description = Loong +odoo.version = 12 +addon.name_camelwords = Saas Apps +copyright.year = 2020 +addon.branch = 12.0 +addon.odoo_sha = feb7c99f47cae55fff77035fe53975ea4a14d624 + diff --git a/saas_apps/README.rst b/saas_apps/README.rst new file mode 100644 index 000000000..660002acc --- /dev/null +++ b/saas_apps/README.rst @@ -0,0 +1,51 @@ +.. image:: https://img.shields.io/badge/license-LGPL--3-blue.png + :target: https://www.gnu.org/licenses/lgpl + :alt: License: LGPL-3 + +=========== + Saas Apps +=========== + +short + +Loong + +Credits +======= + +Contributors +------------ +* `saas apps `__: + + * :one::zero: init version of the module + +Sponsors +-------- +* `IT-Projects LLC `__ + +Maintainers +----------- +* `IT-Projects LLC `__ + + To get a guaranteed support + you are kindly requested to purchase the module + at `odoo apps store `__. + + Thank you for understanding! + + `IT-Projects 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: ``_ + +Changelog: ``_ + +Notifications on updates: `via Atom `_, `by Email `_ + +Tested on Odoo 12.0 feb7c99f47cae55fff77035fe53975ea4a14d624 diff --git a/saas_apps/__init__.py b/saas_apps/__init__.py new file mode 100644 index 000000000..e465a1fcd --- /dev/null +++ b/saas_apps/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import controllers, models diff --git a/saas_apps/__manifest__.py b/saas_apps/__manifest__.py new file mode 100644 index 000000000..242bd9be6 --- /dev/null +++ b/saas_apps/__manifest__.py @@ -0,0 +1,48 @@ +# Copyright 2020 Vildan Safin +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +{ + "name": """SaaS Apps""", + "summary": """short""", + "category": "Marketing", + # "live_test_url": "http://apps.it-projects.info/shop/product/DEMO-URL?version=12.0", + "images": [], + "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": [ + ], + "external_dependencies": {"python": [], "bin": []}, + "data": [ + ], + "demo": [ + ], + "qweb": [ + ], + + "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", + # ] +} diff --git a/saas_apps/controllers/__init__.py b/saas_apps/controllers/__init__.py new file mode 100644 index 000000000..ce9b7f1e6 --- /dev/null +++ b/saas_apps/controllers/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import main diff --git a/saas_apps/controllers/main.py b/saas_apps/controllers/main.py new file mode 100644 index 000000000..0ddc65176 --- /dev/null +++ b/saas_apps/controllers/main.py @@ -0,0 +1,10 @@ +# Copyright 2020 Vildan Safin +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo.http import route, request, Controller + + +class SaaSAppsController(Controller): + @route('/price', type='http', auth='public') + def index(self, *kw): + return "shit" diff --git a/saas_apps/doc/changelog.rst b/saas_apps/doc/changelog.rst new file mode 100644 index 000000000..5583eb326 --- /dev/null +++ b/saas_apps/doc/changelog.rst @@ -0,0 +1,4 @@ +`1.0.0` +------- + +- **Init version** diff --git a/saas_apps/doc/index.rst b/saas_apps/doc/index.rst new file mode 100644 index 000000000..d8ac8d5a2 --- /dev/null +++ b/saas_apps/doc/index.rst @@ -0,0 +1,35 @@ +=========== + Saas Apps +=========== + +Installation +============ +{Instruction about things to do before actual installation} + +* {OPTIONAL }`Activate longpolling `__ +* {Additional notes if any} +* `Install `__ this module in a usual way + +Configuration +============= + +{Instruction how to configure the module before start to use it} + +* `Log in as SUPERUSER `__ +* `Activate Developer Mode `__ +* 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} + +Uninstallation +============== + +{Optional section for uninstallation notes. Delete it if you don't have notes for uninstallation.} diff --git a/saas_apps/models/__init__.py b/saas_apps/models/__init__.py new file mode 100644 index 000000000..b9a95232a --- /dev/null +++ b/saas_apps/models/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import saas_apps diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py new file mode 100644 index 000000000..ea644efb2 --- /dev/null +++ b/saas_apps/models/saas_apps.py @@ -0,0 +1,11 @@ +# Copyright 2020 Vildan Safin +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class SAASApps(models.Model): + _name = 'saas.apps' + _description = 'Module for selecting applications' + + users = fields.Integer(default=0) diff --git a/saas_apps/static/description/icon.png b/saas_apps/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6c7d8a3ca480a67b9168333e5fec57fa9cf5b371 GIT binary patch literal 4957 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 Date: Mon, 24 Feb 2020 19:00:21 +0500 Subject: [PATCH 02/60] :bomb: developing process Signed-off-by: Vildan Safin --- .mrbob.ini | 18 ------ saas_apps/README.rst | 8 +-- saas_apps/__manifest__.py | 11 ++-- saas_apps/controllers/main.py | 39 +++++++++++-- saas_apps/images/attention.jpg | Bin 0 -> 69376 bytes saas_apps/models/saas_apps.py | 70 +++++++++++++++++++++++- saas_apps/security/ir.model.access.csv | 4 ++ saas_apps/static/src/css/calculator.css | 9 +++ saas_apps/static/src/img/default.png | Bin 0 -> 25193 bytes saas_apps/static/src/js/apps.js | 22 ++++++++ saas_apps/views/assets.xml | 11 ++++ saas_apps/views/calculator.xml | 70 ++++++++++++++++++++++++ saas_apps/views/manage.xml | 26 +++++++++ saas_apps/views/module_info.xml | 11 ++++ 14 files changed, 266 insertions(+), 33 deletions(-) delete mode 100644 .mrbob.ini create mode 100644 saas_apps/images/attention.jpg create mode 100644 saas_apps/security/ir.model.access.csv create mode 100644 saas_apps/static/src/css/calculator.css create mode 100644 saas_apps/static/src/img/default.png create mode 100644 saas_apps/static/src/js/apps.js create mode 100644 saas_apps/views/assets.xml create mode 100644 saas_apps/views/calculator.xml create mode 100644 saas_apps/views/manage.xml create mode 100644 saas_apps/views/module_info.xml diff --git a/.mrbob.ini b/.mrbob.ini deleted file mode 100644 index c2469e116..000000000 --- a/.mrbob.ini +++ /dev/null @@ -1,18 +0,0 @@ -[variables] -copyright.name = saas apps -copyright.github = saas-addons -addon.version = 12 -addon.technical_category = saas -addon.category = Marketing -addon.dependency = -addon.upstream = odoo-saas-tools -addon.name = SaaS Apps -addon.technical_name = saas_apps -addon.summary = short -addon.description = Loong -odoo.version = 12 -addon.name_camelwords = Saas Apps -copyright.year = 2020 -addon.branch = 12.0 -addon.odoo_sha = feb7c99f47cae55fff77035fe53975ea4a14d624 - diff --git a/saas_apps/README.rst b/saas_apps/README.rst index 660002acc..95c401776 100644 --- a/saas_apps/README.rst +++ b/saas_apps/README.rst @@ -6,18 +6,16 @@ Saas Apps =========== -short +Base module for manage modules in saas. -Loong +Module allows to choose modules that users gona use in their db. Credits ======= Contributors ------------ -* `saas apps `__: - - * :one::zero: init version of the module +* `Vildan Safin `__ Sponsors -------- diff --git a/saas_apps/__manifest__.py b/saas_apps/__manifest__.py index 242bd9be6..96534d7b3 100644 --- a/saas_apps/__manifest__.py +++ b/saas_apps/__manifest__.py @@ -3,10 +3,10 @@ { "name": """SaaS Apps""", - "summary": """short""", + "summary": """Choose your apps""", "category": "Marketing", # "live_test_url": "http://apps.it-projects.info/shop/product/DEMO-URL?version=12.0", - "images": [], + "images": ['/images/attention.jpg'], "version": "12.0.1.0.0", "application": False, @@ -17,10 +17,13 @@ # "price": 9.00, # "currency": "EUR", - "depends": [ - ], + "depends": ['website'], "external_dependencies": {"python": [], "bin": []}, "data": [ + 'security/ir.model.access.csv', + 'views/calculator.xml', + 'views/manage.xml', + 'views/assets.xml' ], "demo": [ ], diff --git a/saas_apps/controllers/main.py b/saas_apps/controllers/main.py index 0ddc65176..8fdab4fb4 100644 --- a/saas_apps/controllers/main.py +++ b/saas_apps/controllers/main.py @@ -2,9 +2,40 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo.http import route, request, Controller - +from odoo import http +from openerp.http import request +import json class SaaSAppsController(Controller): - @route('/price', type='http', auth='public') - def index(self, *kw): - return "shit" + @route('/price', auth='public', website=True) + def user_page(self, **kw): + import wdb + wdb.set_trace() + apps = http.request.env['saas.lines'] + return http.request.render('saas_apps.index', { + 'apps': apps.search([]) + }) + + @route('/manage', auth='public', website=True) + def manager_page(self, **kw): + apps = http.request.env['ir.module.module'] + return http.request.render('saas_apps.manage', { + 'apps': apps.search([]) + }) + + # @route('/manage/', auth='public', website=True) + # def module_information(self, name): + # return http.request.render('saas_apps.info', {}) + + @http.route(['/test'], type='json', auth='public', website=True) + def catch_app_click(self, **kw): + import wdb + wdb.set_trace() + # Mark choosen module as saleable + http.request.env['ir.module.module'].search([('name', '=', kw['args'][0])]).allow_to_sell = True + apps = http.request.env['saas.lines'] + apps.add_new_module(kw['args'][0]) + # request.redirect('/manage/%s' % name) + return { + 'apps': kw['args'][0] + } diff --git a/saas_apps/images/attention.jpg b/saas_apps/images/attention.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6a5528b8a392c8000207c8fead3082e081a01563 GIT binary patch literal 69376 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 Ly2AGoKil$eDWt(7 literal 0 HcmV?d00001 diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py index ea644efb2..d126b97e6 100644 --- a/saas_apps/models/saas_apps.py +++ b/saas_apps/models/saas_apps.py @@ -2,10 +2,76 @@ # 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 SAASApps(models.Model): - _name = 'saas.apps' +class SAASBasket(models.Model): + _name = 'saas.basket' _description = 'Module for selecting applications' users = fields.Integer(default=0) + module_sets_in_basket = fields.One2many('saas.set', 'basket', ondelete="cascade", delegate=True) + final_basket_price = fields.Float(default=0.0, compute='_compute_price', string="Price of the set") + + def _compute_price(self): + for module_set in self.module_set_in_basket: + self.final_basket_price = self.final_basket_price + module_set.price + + +class SAASLine(models.Model): + _name = 'saas.lines' + _description = 'Model line' + + module_name = fields.Char(default="default") + price = fields.Float(default=0.0) + icon_path = fields.Char(compute='_compute_path', string="icon path") + dependencies = fields.Many2one('saas.set', string="Module dependences") + + def _compute_path(self): + self.icon_path = "/saas_apps/static/src/img/%s.png" % self.module_name + + @api.constrains('price') + def _validate_price(self): + if self.price < 0: + self.price = 0 + raise "Price can't be negative." + + def add_new_module(self, name): + import wdb + wdb.set_trace() + # for module in self: + # if(module.module_name == name) + # return False + self.create({ + 'name': name + }) + return True + + +class SAASDependence(models.Model): + _name = 'saas.set' + _description = 'Module with dependencies' + + basket = fields.Many2one('saas.basket', string='Modules in basket') + modules = fields.One2many('saas.lines', 'dependencies', ondelete='cascade', delegate=True) + final_set_price = fields.Float(default=0.0, compute='_compute_price', string="Price of the set") + + def add_dependence(self, new_module_name, new_module_price): + try: + self.modules.create({ + 'module_name': new_module_name, + 'price': int(new_module_name_price) + }) + except: + _logger.error("Can't add new item in dependencies of this module") + + def _compute_price(self): + for module in self.modules: + self.final_set_price = self.final_set_price + module.price + + +# class IrModuleModule(models.Model): +# _inherit = "ir.module.module" + +# allow_to_sell = fields.Boolean(default=False) diff --git a/saas_apps/security/ir.model.access.csv b/saas_apps/security/ir.model.access.csv new file mode 100644 index 000000000..1278b44e3 --- /dev/null +++ b/saas_apps/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_saas_basket,access_saas_basket,model_saas_basket,base.group_user,1,1,1,1 +access_saas_lines,access_saas_lines,model_saas_lines,base.group_user,1,1,1,1 +access_saas_set,access_saas_set,model_saas_set,base.group_user,1,1,1,1 diff --git a/saas_apps/static/src/css/calculator.css b/saas_apps/static/src/css/calculator.css new file mode 100644 index 000000000..0efc03b36 --- /dev/null +++ b/saas_apps/static/src/css/calculator.css @@ -0,0 +1,9 @@ +.main-control-pad{ + margin-left: 15%; + width: auto; +} + +.col-lg-12{ + flex: 0 0 100%; + max-width: 100%; +} \ No newline at end of file diff --git a/saas_apps/static/src/img/default.png b/saas_apps/static/src/img/default.png new file mode 100644 index 0000000000000000000000000000000000000000..abf1e5d8ddbb0a6fc1b379ea2a1039c86d114ea7 GIT binary patch literal 25193 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 literal 0 HcmV?d00001 diff --git a/saas_apps/static/src/js/apps.js b/saas_apps/static/src/js/apps.js new file mode 100644 index 000000000..b0eb5b06f --- /dev/null +++ b/saas_apps/static/src/js/apps.js @@ -0,0 +1,22 @@ +odoo.define('saas_apps.model', function (require){ + 'use_strict'; + + var session = require('web.session'); + + + // function poopup_widjet(args){ + + // } + + window.onclick=function(e){ + console.log(e.target.innerText); + + if(window.location.pathname === "/manage") + session.rpc('/test', { + args: [e.target.innerText] + }).then(function (result) { + console.log(result); + // poopup_widjet(result); + }); + } +}); diff --git a/saas_apps/views/assets.xml b/saas_apps/views/assets.xml new file mode 100644 index 000000000..c9cc72fa3 --- /dev/null +++ b/saas_apps/views/assets.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/saas_apps/views/calculator.xml b/saas_apps/views/calculator.xml new file mode 100644 index 000000000..5eb50c245 --- /dev/null +++ b/saas_apps/views/calculator.xml @@ -0,0 +1,70 @@ + + + + + diff --git a/saas_apps/views/manage.xml b/saas_apps/views/manage.xml new file mode 100644 index 000000000..31c4208a0 --- /dev/null +++ b/saas_apps/views/manage.xml @@ -0,0 +1,26 @@ + + + + + diff --git a/saas_apps/views/module_info.xml b/saas_apps/views/module_info.xml new file mode 100644 index 000000000..037465cbb --- /dev/null +++ b/saas_apps/views/module_info.xml @@ -0,0 +1,11 @@ + + + + + From e3b5afa600569ff65574f055c8f16b4d8a030db2 Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Fri, 28 Feb 2020 16:44:00 +0500 Subject: [PATCH 03/60] :bomb: Added Manage Apps view in website configuration Signed-off-by: Vildan Safin --- saas_apps/models/saas_apps.py | 26 +++++++++++--------- saas_apps/views/manage.xml | 45 +++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py index d126b97e6..a999a0c58 100644 --- a/saas_apps/models/saas_apps.py +++ b/saas_apps/models/saas_apps.py @@ -23,8 +23,9 @@ class SAASLine(models.Model): _name = 'saas.lines' _description = 'Model line' - module_name = fields.Char(default="default") - price = fields.Float(default=0.0) + module_name = fields.Char(default="default", string="Module Name") + price = fields.Float(default=0.0, string="Price") + allow_to_sell = fields.Boolean(string="Sellable") icon_path = fields.Char(compute='_compute_path', string="icon path") dependencies = fields.Many2one('saas.set', string="Module dependences") @@ -38,15 +39,24 @@ def _validate_price(self): raise "Price can't be negative." def add_new_module(self, name): - import wdb - wdb.set_trace() # for module in self: # if(module.module_name == name) # return False self.create({ - 'name': name + 'module_name': name }) return True + + def create(self, cr, user, vals, context=None): + import wdb + wdb.set_trace() + new_id = super(product_test, self).create(cr, user, vals, context) + irmodules = self.env["ir.module.module"].search([]) + if len(irmodules) > len(self.search([])): + for irmodule in irmodules: + if len(self.search([('module_name', '=', irmodule.name)])) == 0: + self.create({'module_name': irmodule.name}) + return new_id class SAASDependence(models.Model): @@ -69,9 +79,3 @@ def add_dependence(self, new_module_name, new_module_price): def _compute_price(self): for module in self.modules: self.final_set_price = self.final_set_price + module.price - - -# class IrModuleModule(models.Model): -# _inherit = "ir.module.module" - -# allow_to_sell = fields.Boolean(default=False) diff --git a/saas_apps/views/manage.xml b/saas_apps/views/manage.xml index 31c4208a0..c039b14ea 100644 --- a/saas_apps/views/manage.xml +++ b/saas_apps/views/manage.xml @@ -23,4 +23,49 @@ + + + saas.lines.search + saas.lines + + + + + + + + + + saas.lines.list + saas.lines + + + + + + + + + + Website Apps + saas.lines + form + tree,form + + current + + + + + + + + + + From 29848c6614c5708602de846c685573d2282a38b3 Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Sat, 29 Feb 2020 22:17:26 +0500 Subject: [PATCH 04/60] :bomb: Added 'Refresh' button Signed-off-by: Vildan Safin --- saas_apps/__manifest__.py | 1 + saas_apps/controllers/main.py | 16 ++++----------- saas_apps/models/saas_apps.py | 6 +----- saas_apps/static/src/js/refresh_button.js | 24 +++++++++++++++++++++++ saas_apps/views/assets.xml | 5 +++++ saas_apps/views/manage.xml | 8 +------- saas_apps/views/refresh.xml | 12 ++++++++++++ 7 files changed, 48 insertions(+), 24 deletions(-) create mode 100644 saas_apps/static/src/js/refresh_button.js create mode 100644 saas_apps/views/refresh.xml diff --git a/saas_apps/__manifest__.py b/saas_apps/__manifest__.py index 96534d7b3..f5f9af7c8 100644 --- a/saas_apps/__manifest__.py +++ b/saas_apps/__manifest__.py @@ -28,6 +28,7 @@ "demo": [ ], "qweb": [ + 'views/refresh.xml' ], "post_load": None, diff --git a/saas_apps/controllers/main.py b/saas_apps/controllers/main.py index 8fdab4fb4..39b2870b4 100644 --- a/saas_apps/controllers/main.py +++ b/saas_apps/controllers/main.py @@ -9,11 +9,9 @@ class SaaSAppsController(Controller): @route('/price', auth='public', website=True) def user_page(self, **kw): - import wdb - wdb.set_trace() apps = http.request.env['saas.lines'] return http.request.render('saas_apps.index', { - 'apps': apps.search([]) + 'apps': apps.search([('allow_to_sell', '=', True)]) }) @route('/manage', auth='public', website=True) @@ -27,15 +25,9 @@ def manager_page(self, **kw): # def module_information(self, name): # return http.request.render('saas_apps.info', {}) - @http.route(['/test'], type='json', auth='public', website=True) + @http.route(['/refresh'], type='json', auth='public', website=True) def catch_app_click(self, **kw): - import wdb - wdb.set_trace() - # Mark choosen module as saleable - http.request.env['ir.module.module'].search([('name', '=', kw['args'][0])]).allow_to_sell = True apps = http.request.env['saas.lines'] - apps.add_new_module(kw['args'][0]) + apps.refresh() # request.redirect('/manage/%s' % name) - return { - 'apps': kw['args'][0] - } + return {} diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py index a999a0c58..1530d9071 100644 --- a/saas_apps/models/saas_apps.py +++ b/saas_apps/models/saas_apps.py @@ -47,16 +47,12 @@ def add_new_module(self, name): }) return True - def create(self, cr, user, vals, context=None): - import wdb - wdb.set_trace() - new_id = super(product_test, self).create(cr, user, vals, context) + def refresh(self): irmodules = self.env["ir.module.module"].search([]) if len(irmodules) > len(self.search([])): for irmodule in irmodules: if len(self.search([('module_name', '=', irmodule.name)])) == 0: self.create({'module_name': irmodule.name}) - return new_id class SAASDependence(models.Model): diff --git a/saas_apps/static/src/js/refresh_button.js b/saas_apps/static/src/js/refresh_button.js new file mode 100644 index 000000000..f01648534 --- /dev/null +++ b/saas_apps/static/src/js/refresh_button.js @@ -0,0 +1,24 @@ +odoo.define('whatever.filter_button', function (require) { + "use strict"; + + var core = require('web.core'); + var session = require('web.session'); + var ListController = require('web.ListController'); + + ListController.include({ + renderButtons: function($node) { + this._super.apply(this, arguments); + if (this.$buttons) { + let filter_button = this.$buttons.find('.oe_filter_button'); + filter_button && filter_button.click(this.proxy('filter_button')) ; + } + }, + filter_button: function () { + // Loading all modules in saas.lines from ir.module.module + session.rpc('/refresh', { + }).then(function (result) { + window.location.reload() + }); + } + }); +}); \ No newline at end of file diff --git a/saas_apps/views/assets.xml b/saas_apps/views/assets.xml index c9cc72fa3..07bdbfa35 100644 --- a/saas_apps/views/assets.xml +++ b/saas_apps/views/assets.xml @@ -8,4 +8,9 @@ + diff --git a/saas_apps/views/manage.xml b/saas_apps/views/manage.xml index c039b14ea..ee591749a 100644 --- a/saas_apps/views/manage.xml +++ b/saas_apps/views/manage.xml @@ -57,15 +57,9 @@ - - - - - - diff --git a/saas_apps/views/refresh.xml b/saas_apps/views/refresh.xml new file mode 100644 index 000000000..37cd124df --- /dev/null +++ b/saas_apps/views/refresh.xml @@ -0,0 +1,12 @@ + + + \ No newline at end of file From 235ebc23ae74576dd4b870c459e00d5accd2f26b Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Mon, 2 Mar 2020 19:02:51 +0500 Subject: [PATCH 05/60] :bomb: started js low flexing Signed-off-by: Vildan Safin --- saas_apps/controllers/main.py | 9 +++++ saas_apps/models/saas_apps.py | 58 ++++++++++++++++----------------- saas_apps/static/src/js/apps.js | 12 ++----- saas_apps/views/calculator.xml | 2 +- saas_apps/views/manage.xml | 2 +- saas_apps/views/refresh.xml | 2 +- 6 files changed, 42 insertions(+), 43 deletions(-) diff --git a/saas_apps/controllers/main.py b/saas_apps/controllers/main.py index 39b2870b4..f6467ce33 100644 --- a/saas_apps/controllers/main.py +++ b/saas_apps/controllers/main.py @@ -31,3 +31,12 @@ def catch_app_click(self, **kw): apps.refresh() # request.redirect('/manage/%s' % name) return {} + + @http.route(['/what_dependencies'], type='json', auth='public', website=True) + def put_in_basket(self, **kw): + app_name = kw['args'][0] + app = http.request.env['saas.lines'].search([('module_name', '=', app_name)]) + return { + 'dependencies': app.dependencies_info(), + 'price': app.final_set_price + } diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py index 1530d9071..f239f12af 100644 --- a/saas_apps/models/saas_apps.py +++ b/saas_apps/models/saas_apps.py @@ -6,17 +6,19 @@ _logger = logging.getLogger(__name__) -class SAASBasket(models.Model): - _name = 'saas.basket' - _description = 'Module for selecting applications' +# class SAASBasket(models.Model): +# _name = 'saas.basket' +# _description = 'Module for selecting applications' - users = fields.Integer(default=0) - module_sets_in_basket = fields.One2many('saas.set', 'basket', ondelete="cascade", delegate=True) - final_basket_price = fields.Float(default=0.0, compute='_compute_price', string="Price of the set") +# users = fields.Integer(default=0) +# name = fields.Char(default="Basket", string="Basket Name") +# modules_in_basket = fields.One2many('saas.lines', 'basket', ondelete="cascade", delegate=True) +# final_basket_price = fields.Float(default=0.0, compute='_compute_price', string="Price of the set") - def _compute_price(self): - for module_set in self.module_set_in_basket: - self.final_basket_price = self.final_basket_price + module_set.price +# def _compute_price(self): +# if len(self.modules_in_basket) > 0: +# for module in self.modules_in_basket: +# self.final_basket_price += module.final_set_price class SAASLine(models.Model): @@ -27,10 +29,17 @@ class SAASLine(models.Model): price = fields.Float(default=0.0, string="Price") allow_to_sell = fields.Boolean(string="Sellable") icon_path = fields.Char(compute='_compute_path', string="icon path") - dependencies = fields.Many2one('saas.set', string="Module dependences") + dependencies = fields.One2many('saas.set', 'saas_modules', ondelete='cascade', delegate=True) + final_set_price = fields.Float(default=0.0, compute='_compute_price', string="Price of the set") + # basket = fields.Many2one('saas.basket', string='Modules in basket') def _compute_path(self): self.icon_path = "/saas_apps/static/src/img/%s.png" % self.module_name + + def _compute_price(self): + self.final_set_price = self.price + for module in self.dependencies: + self.final_set_price += module.saas_modules.price @api.constrains('price') def _validate_price(self): @@ -39,9 +48,6 @@ def _validate_price(self): raise "Price can't be negative." def add_new_module(self, name): - # for module in self: - # if(module.module_name == name) - # return False self.create({ 'module_name': name }) @@ -53,25 +59,17 @@ def refresh(self): for irmodule in irmodules: if len(self.search([('module_name', '=', irmodule.name)])) == 0: self.create({'module_name': irmodule.name}) + + def dependencies_info(self): + apps = [] + for app in self.dependencies: + apps.append(app.saas_modules.module_name) + return apps class SAASDependence(models.Model): _name = 'saas.set' - _description = 'Module with dependencies' + _description = 'Module dependencies' - basket = fields.Many2one('saas.basket', string='Modules in basket') - modules = fields.One2many('saas.lines', 'dependencies', ondelete='cascade', delegate=True) - final_set_price = fields.Float(default=0.0, compute='_compute_price', string="Price of the set") - - def add_dependence(self, new_module_name, new_module_price): - try: - self.modules.create({ - 'module_name': new_module_name, - 'price': int(new_module_name_price) - }) - except: - _logger.error("Can't add new item in dependencies of this module") - - def _compute_price(self): - for module in self.modules: - self.final_set_price = self.final_set_price + module.price + saas_modules = fields.Many2one('saas.lines', string="Module dependencies") + # module = fields.One2many() diff --git a/saas_apps/static/src/js/apps.js b/saas_apps/static/src/js/apps.js index b0eb5b06f..c50f6591d 100644 --- a/saas_apps/static/src/js/apps.js +++ b/saas_apps/static/src/js/apps.js @@ -3,20 +3,12 @@ odoo.define('saas_apps.model', function (require){ var session = require('web.session'); - - // function poopup_widjet(args){ - - // } - window.onclick=function(e){ - console.log(e.target.innerText); - - if(window.location.pathname === "/manage") - session.rpc('/test', { + if(window.location.pathname === "/price" && e.target.id == "application") + session.rpc('/what_dependencies', { args: [e.target.innerText] }).then(function (result) { console.log(result); - // poopup_widjet(result); }); } }); diff --git a/saas_apps/views/calculator.xml b/saas_apps/views/calculator.xml index 5eb50c245..53d85c5eb 100644 --- a/saas_apps/views/calculator.xml +++ b/saas_apps/views/calculator.xml @@ -35,7 +35,7 @@

-

+

diff --git a/saas_apps/views/manage.xml b/saas_apps/views/manage.xml index ee591749a..3ea090da7 100644 --- a/saas_apps/views/manage.xml +++ b/saas_apps/views/manage.xml @@ -39,7 +39,7 @@ saas.lines.list saas.lines - + diff --git a/saas_apps/views/refresh.xml b/saas_apps/views/refresh.xml index 37cd124df..9e216b2f8 100644 --- a/saas_apps/views/refresh.xml +++ b/saas_apps/views/refresh.xml @@ -3,7 +3,7 @@ - From 1440f2de07d2d1ff9e5534ab7bd9a0a8da51780d Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Tue, 17 Mar 2020 19:21:09 +0500 Subject: [PATCH 15/60] :bomb: shifted block with modules in center Signed-off-by: Vildan Safin --- saas_apps/static/src/css/calculator.css | 27 +++++++++++++++++++++++-- saas_apps/views/calculator.xml | 2 ++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/saas_apps/static/src/css/calculator.css b/saas_apps/static/src/css/calculator.css index 7c81b1bdf..b8bb91984 100644 --- a/saas_apps/static/src/css/calculator.css +++ b/saas_apps/static/src/css/calculator.css @@ -7,18 +7,29 @@ transition: 0.5s; } -@media (min-width: 1000px) { +.app{ + max-height: 70px; +} + +@media (min-width: 1400px) { #price-window { position: fixed; right: 30%; top: 20%; width: 15%; + min-width: 20%; z-index: 1; } + + .row{ + margin-right: auto; + margin-left: 10%; + max-width: 40%; + } } -@media (min-width: 800px) { +@media (min-width: 999px) { #price-window { position: fixed; @@ -27,6 +38,12 @@ width: 20%; z-index: 1; } + + .row{ + margin-right: auto; + margin-left: 10%; + max-width: 40%; + } } @media (max-width: 799px) { @@ -41,6 +58,12 @@ .container{ margin-left: auto !important; } + + .row{ + margin-right: auto; + margin-left: 0px; + max-width: 80%; + } } .col-lg-9{ diff --git a/saas_apps/views/calculator.xml b/saas_apps/views/calculator.xml index b653a8f95..c4991442d 100644 --- a/saas_apps/views/calculator.xml +++ b/saas_apps/views/calculator.xml @@ -6,6 +6,7 @@ Apps
+
@@ -66,6 +67,7 @@
+
From b0fa938158e3b3b20f492ffb2f521dbe7a9499ad Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Tue, 17 Mar 2020 20:22:14 +0500 Subject: [PATCH 16/60] :bomb: Made frontend like pushka Signed-off-by: Vildan Safin --- .../description/icons8-check-all-100.png | Bin 2506 -> 0 bytes saas_apps/static/src/css/calculator.css | 2 +- saas_apps/static/src/js/apps.js | 31 +++++++++++------- saas_apps/views/calculator.xml | 21 +++++------- 4 files changed, 29 insertions(+), 25 deletions(-) delete mode 100644 saas_apps/static/description/icons8-check-all-100.png diff --git a/saas_apps/static/description/icons8-check-all-100.png b/saas_apps/static/description/icons8-check-all-100.png deleted file mode 100644 index 13468f6aae029c6e7e8adcfe065f42c5b2545847..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2506 zcmV;*2{rbKP)gyOSI?v0uYbeG>(~A3nFk020)apv5C{YUfj}S-2m}IwKp@Z-!&+spV!#+Tb~sNzpNMaOuLh~P2Z!Ck_Vc4{M4}@^~%RfZGfPV@PA7X6E}7^$$y-Nw~x0LdASX5A8+Eu#!!8(hMMx) z00aEmQeX42UiqjRA?*|Re|rT7^3uln%E)MTw6L$>07v(f&`@o`>6A4|_Ergv4CTf3 z*|*ilVRx`HX9IR?BeEnI`jIeYBwzmXYYeiK4Co@nptAosfZ?NtDh>Mz4$$i!e`cFz((hLh-9m<)BtbZva34t5;PG)fU1B z-KR3FK6JP`?5$T0YK8m)r&I1$rzuZEb0GqC2q7MZ5aMA7As$Bes&nW>)S$TiNQ`NJ z*`=lX9x0^0s)1b_KId#n8G~X5lDK#hA$@|cyYH$6o32}CdE?0UO1)?In{QEb@}%o! zFCYepkz_-5RCJuCrTZQyq_(o2JX1b@n4eDa=BfOB^EQgs?k4r^XRf<{-G#cF#+>x$ zca-gxCI`043tTwz9Vd&5a9C}RdC7+20nxFVlpsjSanYns`>tBBN!76>gMoy_i}1TA2xKM<92`4QO}uU|q@mhE-qHe| zUzkDatZ7QSIlqwiR;?%Poup1Dbhx!S$69BH#{Te19c6??7;g|kJNo^0B%r=@-))6hYOHKAnOU5jPR1O4WdH<4gu6CXmF~Nx5SNTa zS!t?e-0oFYXL$PuxHeUl?z^23OO2J>b{U!JNlN>jjtn(dSzUo!Zwwo%EflTY&Dj%W z3>q4|nnl^^3K*+cE~-~pu*WlmYY`Daq#?wB*K#Uq}ncbrq2n_GBh#$*Z#3R(MM?p-r7T5#hxj~O9?HiQrlLkRIOgb)uy z2=Op97h*6-w6?Tr9kxqoZEnS2(0u(JRj3tm8Q@Ce6{R7hPcT(yYgC4H4^?NX2?@V? zpX0DQfVPi_>V;Y%6##XW4NAlPXeJ^0Si%+up~0v9X<$hVeg{C*n9;iBr+P+(l#JhwMx!xpswUVDcj!Np-hb31&7_i)_1pa zytovLs%gnF(6ObQgW&;~BLu zN3{$sPFb3j-`khPdwk&F*og*NN|xJ}ZW@4&3%PWLkH0^G_ub3ABSsK4W;A`{MIBSn4qIiFYqLU496g2X1*kZ3 zM8_1gqvCMe`;aARubMcz36UkI8KAUiSI6PrEortl^24tG03b=SSxqe6gtV{3w#Q+$ z@y(ib$WEtTsi;DBIw@ZB0S=oDWWG3e>ev@*;_14;ZcymG`wd95trZmkma_9iJn#Ts zKA!jgMmnR}-pK#nUrqVJLjbi-Z)uvfuDV`LOx>R*4Tz2%XF%Ekg!%;qF)Z;3B1b+* zP-G-N{{DKW_X}E@8nIreRCeU37bnntVGG92orJVCW zet$}fa2_GVMRzFO1DBB~lacmGl5AExX9xrWfj}S-2m}IwKp+qZ1OkCTAn0=b4-WfY U`Hd{lssI2007*qoM6N<$g1dmnz5oCK diff --git a/saas_apps/static/src/css/calculator.css b/saas_apps/static/src/css/calculator.css index b8bb91984..1d4d3e5f7 100644 --- a/saas_apps/static/src/css/calculator.css +++ b/saas_apps/static/src/css/calculator.css @@ -4,7 +4,7 @@ } .transition { - transition: 0.5s; + transition: 0.3s; } .app{ diff --git a/saas_apps/static/src/js/apps.js b/saas_apps/static/src/js/apps.js index e54c36fcd..97aee3db0 100644 --- a/saas_apps/static/src/js/apps.js +++ b/saas_apps/static/src/js/apps.js @@ -10,10 +10,10 @@ odoo.define('saas_apps.model', function (require){ var price = 0; var per_month = false; /* Also need to add this https://odoo-development.readthedocs.io/en/latest/dev/pos/send-pos-orders-to-server.html#saving-removed-products-of-pos-order-module*/ - var choosen = new Map() - var parent_tree = new Map() - var child_tree = new Map() - var prices = new Map() + var choosen = new Map(); + var parent_tree = new Map(); + var child_tree = new Map(); + var prices = new Map(); function Calc_Price(){ // Calculate general price @@ -122,8 +122,7 @@ odoo.define('saas_apps.model', function (require){ elem = $(".app_tech_name:contains('"+module_name+"')").filter(function(_, el) { return $(el).html() == module_name }) - elem[0].previousElementSibling.style.color = "green"; - elem[0].previousElementSibling.lastElementChild.style.opacity = 1; + elem[0].previousElementSibling.style = "border: 2px solid green" } } @@ -133,10 +132,21 @@ odoo.define('saas_apps.model', function (require){ elem = $(".app_tech_name:contains('"+module_name+"')").filter(function(_, el) { return $(el).html() == module_name }) - elem[0].previousElementSibling.style.color = "black"; - elem[0].previousElementSibling.lastElementChild.style.opacity = 0; + elem[0].previousElementSibling.style = "border: 2px solid #FFFFFF" } } + + function calc_price_window_vals(choosen_qty){ + price = Calc_Price(); + var period = per_month ? "month" : "year"; + $('#price')[0].innerHTML = '

$'+String(price)+ + ' / '+ period +'

'; + $('#users-qty')[0].innerText = String($('#users')[0].value); + users_price_period = per_month ? 12.5 : 10.0; + $('#price-users')[0].innerText = String(users_price_period); + $('#apps-qty')[0].innerText = String(choosen_qty); + + } window.onclick=function(e){ if(window.location.pathname === "/price"){ @@ -161,10 +171,7 @@ odoo.define('saas_apps.model', function (require){ // Check choosen period per_month = e.target.innerText === "Monthly" ? true : false; } - price = Calc_Price(); - var period = per_month ? "month" : "year"; - $('#price')[0].innerHTML = '

$'+String(price)+ - ' / '+ period +'

'; + calc_price_window_vals(choosen.size); } } diff --git a/saas_apps/views/calculator.xml b/saas_apps/views/calculator.xml index c4991442d..88771f71e 100644 --- a/saas_apps/views/calculator.xml +++ b/saas_apps/views/calculator.xml @@ -8,7 +8,7 @@
-
+

Choose the number of Users

@@ -28,13 +28,11 @@
-

+

-

@@ -54,15 +52,14 @@
-
-

$15 - / year

-
    -
  • 20 users included
  • -
  • 10 GB of storage
  • -
  • Priority email support
  • -
  • Help center access
  • +
    +
      +
    • 1 Users
    • +
    • 10 EUR
    • +
    • 0 Apps in busket
    +

    $10 + / year

    From c47992f8ce377e59fde7d1fdae5bd86291ffc9c2 Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Wed, 18 Mar 2020 19:04:35 +0500 Subject: [PATCH 17/60] :bomb: Changed allow_to_sell vars changing in overrided write function in saas.lines and added new controller that should redirect user to the new DB with choosen apps Signed-off-by: Vildan Safin --- saas_apps/controllers/main.py | 20 +++++++++++++++++ saas_apps/doc/index.rst | 9 +++----- saas_apps/models/saas_apps.py | 12 +++------- saas_apps/static/src/js/apps.js | 27 +++++++++++++++++------ saas_apps/static/src/js/refresh_button.js | 4 +++- saas_apps/views/calculator.xml | 2 +- saas_apps/views/refresh.xml | 3 ++- 7 files changed, 52 insertions(+), 25 deletions(-) diff --git a/saas_apps/controllers/main.py b/saas_apps/controllers/main.py index b60a4a7a5..4e6c00e5a 100644 --- a/saas_apps/controllers/main.py +++ b/saas_apps/controllers/main.py @@ -5,6 +5,7 @@ from odoo import http from openerp.http import request import json +from odoo.addons.saas_public.controllers.saas_public import SaaSPublicController class SaaSAppsController(Controller): @route('/price', auth='public', website=True) @@ -27,3 +28,22 @@ def what_dependencies(self, **kw): return { 'dependencies': app.dependencies_info('root') } + +class SaaSAppsPublicController(SaaSPublicController): + @http.route(['/create_saas_template'], type='json', auth='public', website=True) + def what_dependencies(self, **kw): + templates = http.request.env['saas.template'] + installing_modules_names = kw['args'][0] + import wdb + wdb.set_trace() + installing_modules = [] + for name in installing_modules_names: + installing_modules += http.request.env['saas.lines'].search([('name', '=', name)]) + new_template = templates.create({ + 'name': 'Template ' + str(len(templates.search([]))), + 'template_demo': True, + 'public_access': True, + 'template_module_ids': installing_modules, + }) + new_template.operator_ids += templates.action_create_build() + self.create_fast_build(new_template.id) diff --git a/saas_apps/doc/index.rst b/saas_apps/doc/index.rst index b63f051e7..fd949c930 100644 --- a/saas_apps/doc/index.rst +++ b/saas_apps/doc/index.rst @@ -4,17 +4,14 @@ Installation ============ -{Instruction about things to do before actual installation} -* {OPTIONAL }`Activate longpolling `__ -* {Additional notes if any} +* `Activate longpolling `__ +* * `Install `__ this module in a usual way Configuration ============= -{Instruction how to configure the module before start to use it} - * `Log in as SUPERUSER `__ * `Activate Developer Mode `__ * Open menu ``[[ Website ]] >> Configuration >> Manage Apps`` @@ -36,4 +33,4 @@ Usage Uninstallation ============== -{Optional section for uninstallation notes. Delete it if you don't have notes for uninstallation.} +* Open menu ``[[ Apps ]] >> [[SaaS Apps]] >> Uninstall`` diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py index bc1d5df76..2bc8db4f5 100644 --- a/saas_apps/models/saas_apps.py +++ b/saas_apps/models/saas_apps.py @@ -109,16 +109,10 @@ def dependencies_info(self, root): @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 - # 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 + this_app = self.dependencies.search([('name', '=', self.name)]) + for app in self.dependencies - this_app: + self.search([('name', '=', app.name)]).allow_to_sell = vals['allow_to_sell'] return res diff --git a/saas_apps/static/src/js/apps.js b/saas_apps/static/src/js/apps.js index 97aee3db0..2b35ebf42 100644 --- a/saas_apps/static/src/js/apps.js +++ b/saas_apps/static/src/js/apps.js @@ -1,6 +1,5 @@ /* Copyright 2020 Vildan Safin License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).*/ - odoo.define('saas_apps.model', function (require){ 'use_strict'; @@ -24,6 +23,17 @@ odoo.define('saas_apps.model', function (require){ } return price + parseInt($('#users')[0].value, 10)*users_price_period; } + + // Need to check this in backend + function redirect_to_build(){ + modules_to_install = []; + for (var key of choosen.keys()) { + modules_to_install.push(key); + } + session.rpc('/create_saas_template', { + args: [modules_to_install] + }).then(function (result) {}); + } // Finding all the links up to the parent_tree, // and push them to delete_list @@ -118,21 +128,21 @@ odoo.define('saas_apps.model', function (require){ function add_to_basket(module_name){ if(choosen.get(module_name) === undefined){ var price = per_month ? prices.get(module_name)[0] : prices.get(module_name)[1]; - choosen.set(module_name, price), - elem = $(".app_tech_name:contains('"+module_name+"')").filter(function(_, el) { - return $(el).html() == module_name - }) + choosen.set(module_name, price); + elem = $(".app_tech_name:contains('"+module_name+"')").filter(function(_, el) { + return $(el).html() == module_name + }) elem[0].previousElementSibling.style = "border: 2px solid green" } } function delete_from_basket(module_name){ if(choosen.get(module_name) !== undefined){ - choosen.delete(module_name), + choosen.delete(module_name); elem = $(".app_tech_name:contains('"+module_name+"')").filter(function(_, el) { return $(el).html() == module_name }) - elem[0].previousElementSibling.style = "border: 2px solid #FFFFFF" + elem[0].previousElementSibling.style = "border: 2px solid #FFFFFF" } } @@ -171,6 +181,9 @@ odoo.define('saas_apps.model', function (require){ // Check choosen period per_month = e.target.innerText === "Monthly" ? true : false; } + else if(e.target.id === "get-started"){ + redirect_to_build(); + } calc_price_window_vals(choosen.size); } } diff --git a/saas_apps/static/src/js/refresh_button.js b/saas_apps/static/src/js/refresh_button.js index 98b06b25f..c0705d0ba 100644 --- a/saas_apps/static/src/js/refresh_button.js +++ b/saas_apps/static/src/js/refresh_button.js @@ -1,4 +1,6 @@ -odoo.define('whatever.filter_button', function (require) { +/* Copyright 2020 Vildan Safin + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).*/ + odoo.define('whatever.filter_button', function (require) { "use strict"; var core = require('web.core'); diff --git a/saas_apps/views/calculator.xml b/saas_apps/views/calculator.xml index 88771f71e..ffbb688a7 100644 --- a/saas_apps/views/calculator.xml +++ b/saas_apps/views/calculator.xml @@ -60,7 +60,7 @@

$10 / year

- +
diff --git a/saas_apps/views/refresh.xml b/saas_apps/views/refresh.xml index f8e52de00..2a71f8d57 100644 --- a/saas_apps/views/refresh.xml +++ b/saas_apps/views/refresh.xml @@ -1,5 +1,6 @@ - + \ No newline at end of file + From 29911a75fe38389923eaf2423e322e19b0a4ed41 Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Sat, 28 Mar 2020 21:09:17 +0500 Subject: [PATCH 20/60] :bomb: Added auto authorization Signed-off-by: Vildan Safin --- saas_apps/controllers/main.py | 18 ++++++++------ saas_apps/models/saas_apps.py | 2 +- saas_apps/static/src/css/calculator.css | 4 ++++ saas_apps/static/src/js/apps.js | 32 +------------------------ saas_apps/views/calculator.xml | 4 ++-- 5 files changed, 19 insertions(+), 41 deletions(-) diff --git a/saas_apps/controllers/main.py b/saas_apps/controllers/main.py index 88b4fc515..749fb681e 100644 --- a/saas_apps/controllers/main.py +++ b/saas_apps/controllers/main.py @@ -4,6 +4,7 @@ from odoo.http import route, request, Controller from odoo import http from odoo.addons.saas_public.controllers.saas_public import SaaSPublicController +import urllib.parse DB_TEMPLATE = 'db_template_' @@ -13,17 +14,18 @@ class SaaSAppsController(Controller): @route('/price', type='http', auth='public', website=True) def user_page(self, **kw): apps = http.request.env['saas.line'].sudo() + apps.refresh() return http.request.render('saas_apps.index', { 'apps': apps.search([('allow_to_sell', '=', True)]) }) - @http.route(['/refresh'], type='json', auth='public', website=True) + @http.route(['/refresh'], type='json', auth='public') 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) + @http.route(['/what_dependencies'], type='json', auth='public') def what_dependencies(self, **kw): app_tech_name = kw['args'][0] app = http.request.env['saas.line'].sudo().search([('name', '=', app_tech_name)]) @@ -33,14 +35,14 @@ def what_dependencies(self, **kw): class SaaSAppsPublicController(SaaSPublicController): @http.route(['/create_saas_template'], type='json', auth='public', website=True) - def what_dependencies(self, **kw): + def create_saas_template(self, **kw): # import wdb # wdb.set_trace() templates = http.request.env['saas.template'] installing_modules_names = kw['args'][0] saas_template = templates.sudo().create({ 'name': 'Template ' + str(len(templates.sudo().search([])) - 1), - 'template_demo': False, + 'template_demo': True, 'public_access': True }) for name in installing_modules_names: @@ -64,17 +66,19 @@ def is_build_created(self, **kw): template = http.request.env['saas.template'].sudo().browse(kw['args'][0]['template']) template_operator = http.request.env['saas.template.operator'].sudo().browse(kw['args'][0]['template_operator']) if len(template) > 0 and template_operator.random_ready_operator_check(): - import wdb - wdb.set_trace() kwargs = {} if template and template.public_access: template_operator_id = template.operator_ids.random_ready_operator() build = template_operator_id.create_db(kwargs, with_delay=False) build_url = build.get_url() + token_obj = request.env['auth_quick_master.token'].sudo().create({ + 'build': build.id, + 'build_login': 'admin', + }) return { 'template': '0', 'template_operator': '0', - 'link': build_url, + 'link': urllib.parse.urljoin(build_url, '/auth_quick/check-token?token={}'.format(token_obj.token)), 'Error': '0' } else: diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py index 9906e7e70..364161d92 100644 --- a/saas_apps/models/saas_apps.py +++ b/saas_apps/models/saas_apps.py @@ -47,7 +47,7 @@ class SAASDependence(models.Model): name = fields.Char(default="default", string="Module technical name") module_name = fields.Char(default="default", string="Module name") icon_path = fields.Char(string="Icon path") - allow_to_sell = fields.Boolean(string="Sellable") + allow_to_sell = fields.Boolean(default=True, string="Sellable") dependencies = fields.Many2many('saas.module') 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") diff --git a/saas_apps/static/src/css/calculator.css b/saas_apps/static/src/css/calculator.css index 1d4d3e5f7..c73d6bb53 100644 --- a/saas_apps/static/src/css/calculator.css +++ b/saas_apps/static/src/css/calculator.css @@ -3,6 +3,10 @@ max-width: 100%; } +#price{ + font-size: 32px; +} + .transition { transition: 0.3s; } diff --git a/saas_apps/static/src/js/apps.js b/saas_apps/static/src/js/apps.js index 8906de9aa..077c3a1ab 100644 --- a/saas_apps/static/src/js/apps.js +++ b/saas_apps/static/src/js/apps.js @@ -201,41 +201,11 @@ odoo.define('saas_apps.model', function (require){ per_month = e.target.innerText === "Monthly" ? true : false; } else if(e.target.id === "get-started"){ + alert('We started creating the build, you will be redirected to new db webpage automaticaly. Wait a minute please.') redirect_to_build(); } calc_price_window_vals(choosen.size); } } - // var Price = Widget.extend({ - // template: 'price.template', - // init: function(){ - // this.$('p.app_tech_name').click(function() { - // // Looking at choosen period - // var price_period = per_month ? 'month' : 'year'; - // var app_name = $('p.app_tech_name')[0].innerText; - // // Getting choosen module dependecies - // session.rpc('/what_dependencies', { - // args: [app_name, price_period] - // }).then(function (result) { - // console.log(result); - // /* Be carefull with dependecies when changing programm logic, - // cause first dependence - is module himself*/ - // var i = 0; - // for(; i < result.dependencies.length; ++i) - // if(!choosen.includes(result.dependencies[i])) - // { - // choosen.push(result.dependencies[i]); - // $(".app_tech_name:contains('"+result.dependencies[i]+"')")[0].style.color = "green"; - // }else{ - // choosen.splice(choosen.indexOf(result.dependencies[i]), 1); - // if(i == 0){ - // $(".app_tech_name:contains('"+result.dependencies[i]+"')")[0].style.color = "black"; - // break; - // } - // } - // }); - // }); - // } - // }); }); diff --git a/saas_apps/views/calculator.xml b/saas_apps/views/calculator.xml index ffbb688a7..cef8b6c76 100644 --- a/saas_apps/views/calculator.xml +++ b/saas_apps/views/calculator.xml @@ -56,9 +56,9 @@
  • 1 Users
  • 10 EUR
  • -
  • 0 Apps in busket
  • +
  • 0 Apps in basket
-

$10 +

$10 / year

From 337085aa7028005bf7335ec46e73e4d57cb492b3 Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Sun, 29 Mar 2020 21:19:21 +0500 Subject: [PATCH 21/60] :bomb: Added method that collects and sends all modules dependencies with one transaction Signed-off-by: Vildan Safin --- saas_apps/controllers/main.py | 12 ++++++++++-- saas_apps/models/saas_apps.py | 3 +-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/saas_apps/controllers/main.py b/saas_apps/controllers/main.py index 749fb681e..3052b57e5 100644 --- a/saas_apps/controllers/main.py +++ b/saas_apps/controllers/main.py @@ -33,11 +33,19 @@ def what_dependencies(self, **kw): 'dependencies': app.dependencies_info('root') } + # @http.route(['/what_dependencies_optimized'], type='json', auth='public') + # def what_dependencies_optimized(self, **kw): + # apps = [] + # for app_name in kw['args'][0]: + # app = http.request.env['saas.line'].sudo().search([('name', '=', app_name)]) + # apps.append({app_name: app.dependencies_info('root')}) + # return { + # 'dependencies': apps + # } + class SaaSAppsPublicController(SaaSPublicController): @http.route(['/create_saas_template'], type='json', auth='public', website=True) def create_saas_template(self, **kw): - # import wdb - # wdb.set_trace() templates = http.request.env['saas.template'] installing_modules_names = kw['args'][0] saas_template = templates.sudo().create({ diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py index 364161d92..ccafe5969 100644 --- a/saas_apps/models/saas_apps.py +++ b/saas_apps/models/saas_apps.py @@ -94,8 +94,7 @@ def dependencies_info(self, root): 'name': self.name, 'year_price': saas_module.year_price, 'month_price': saas_module.month_price, - 'childs': childs, - 'icon_path': self.icon_path + 'childs': childs }) # Looking to the period for app in self.dependencies - saas_module: From d2aa52b1646490492d770c52fb4193722de7c941 Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Sun, 29 Mar 2020 21:50:03 +0500 Subject: [PATCH 22/60] :bomb: Fixed bug with 'default' named modules Signed-off-by: Vildan Safin --- saas_apps/models/saas_apps.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py index ccafe5969..d388b1e6d 100644 --- a/saas_apps/models/saas_apps.py +++ b/saas_apps/models/saas_apps.py @@ -3,6 +3,7 @@ from odoo import api, fields, models import logging +from slugify import slugify _logger = logging.getLogger(__name__) @@ -57,23 +58,25 @@ def refresh(self): apps.search([]).unlink() self.search([]).unlink() apps.refresh() + base_icon_path = '/base/static/description/icon.png' for app in apps.search([]): - try: - if len(self.search([('name', '=', app.name)])) == 0: - ir_module_obj = self.env["ir.module.module"].get_module_info(app.name) - if len(ir_module_obj): - new = self.create({ - 'name': app.name, - 'module_name': ir_module_obj['name'], - 'icon_path': ir_module_obj['icon'] - }) - new.dependencies += apps.search([('name', '=', app.name)]) - for dep_name in ir_module_obj['depends']: - new.dependencies += apps.search([('name', '=', dep_name)]) - else: - new = self.create({'name': app.name}) - except: - _logger.error("Fuck!Fuck!Fuck!Fuck!Fuck!Fuck!") + if len(self.search([('name', '=', app.name)])) == 0: + ir_module_obj = self.env["ir.module.module"].get_module_info(app.name) + if len(ir_module_obj): + new = self.create({ + 'name': app.name, + 'module_name': ir_module_obj['name'], + 'icon_path': ir_module_obj['icon'] + }) + new.dependencies += apps.search([('name', '=', app.name)]) + for dep_name in ir_module_obj['depends']: + new.dependencies += apps.search([('name', '=', dep_name)]) + else: + new = self.create({ + 'name': app.name, + 'module_name': app.name, + 'icon_path': base_icon_path + }) def _compute_year_price(self): for module in self.dependencies: From 787c8e1196c1432548752a1209abc3951e17a1a2 Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Mon, 30 Mar 2020 19:21:06 +0500 Subject: [PATCH 23/60] :bomb: Now applications only is visible Signed-off-by: Vildan Safin --- saas_apps/controllers/main.py | 4 +++- saas_apps/models/saas_apps.py | 26 ++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/saas_apps/controllers/main.py b/saas_apps/controllers/main.py index 3052b57e5..8a0dbf3fc 100644 --- a/saas_apps/controllers/main.py +++ b/saas_apps/controllers/main.py @@ -14,7 +14,6 @@ class SaaSAppsController(Controller): @route('/price', type='http', auth='public', website=True) def user_page(self, **kw): apps = http.request.env['saas.line'].sudo() - apps.refresh() return http.request.render('saas_apps.index', { 'apps': apps.search([('allow_to_sell', '=', True)]) }) @@ -62,6 +61,9 @@ def create_saas_template(self, **kw): 'operator_db_name': DB_TEMPLATE + str(len(http.request.env['saas.template.operator'].sudo().search([])) + 1), }) http.request.env['saas.template.operator'].sudo().preparing_template_next() + # message = '''Template\'s deployment with name {} is creating + # and will be ready in a few minutes.'''.format(r.operator_db_name) + # self.operator_id.notify_users(message, message_type='info') return { 'template': saas_template.id, 'template_operator': saas_template_operator.id, diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py index d388b1e6d..21fdb71e8 100644 --- a/saas_apps/models/saas_apps.py +++ b/saas_apps/models/saas_apps.py @@ -63,14 +63,15 @@ def refresh(self): if len(self.search([('name', '=', app.name)])) == 0: ir_module_obj = self.env["ir.module.module"].get_module_info(app.name) if len(ir_module_obj): - new = self.create({ - 'name': app.name, - 'module_name': ir_module_obj['name'], - 'icon_path': ir_module_obj['icon'] - }) - new.dependencies += apps.search([('name', '=', app.name)]) - for dep_name in ir_module_obj['depends']: - new.dependencies += apps.search([('name', '=', dep_name)]) + if ir_module_obj['application']: + new = self.create({ + 'name': app.name, + 'module_name': ir_module_obj['name'], + 'icon_path': ir_module_obj['icon'] + }) + new.dependencies += apps.search([('name', '=', app.name)]) + for dep_name in ir_module_obj['depends']: + new.dependencies += apps.search([('name', '=', dep_name)]) else: new = self.create({ 'name': app.name, @@ -91,7 +92,8 @@ def dependencies_info(self, root): childs = [] saas_module = self.dependencies.search([('name', '=', self.name)]) for child in self.dependencies - saas_module: - childs.append(child.name) + if len(self.search([('name', '=', child.name)])): + childs.append(child.name) apps.append({ 'parent': root, 'name': self.name, @@ -102,6 +104,8 @@ def dependencies_info(self, root): # Looking to the period for app in self.dependencies - saas_module: set = self.search([('name', '=', app.name)]) + if len(set) == 0: + continue leafs = set.dependencies_info(self.name) for leaf in leafs: if not(leaf in apps): @@ -115,7 +119,9 @@ def write(self, vals): if "allow_to_sell" in vals: this_app = self.dependencies.search([('name', '=', self.name)]) for app in self.dependencies - this_app: - self.search([('name', '=', app.name)]).allow_to_sell = vals['allow_to_sell'] + temp_app = self.search([('name', '=', app.name)]) + if len(temp_app) > 0: + temp_app.allow_to_sell = vals['allow_to_sell'] return res From 8147ade738cdd3ebb73346f2009c60af79d665b7 Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Tue, 31 Mar 2020 15:45:00 +0500 Subject: [PATCH 24/60] :bomb: Added loader and indent corrections Signed-off-by: Vildan Safin --- saas_apps/controllers/main.py | 14 ++++++---- saas_apps/images/attention.jpg | Bin 69376 -> 0 bytes saas_apps/static/src/css/calculator.css | 33 ++++++++++++++++++++++++ saas_apps/static/src/img/loader.gif | Bin 0 -> 41474 bytes saas_apps/static/src/js/apps.js | 8 +++--- saas_apps/views/calculator.xml | 5 ++++ 6 files changed, 52 insertions(+), 8 deletions(-) delete mode 100644 saas_apps/images/attention.jpg create mode 100644 saas_apps/static/src/img/loader.gif diff --git a/saas_apps/controllers/main.py b/saas_apps/controllers/main.py index 8a0dbf3fc..095cda768 100644 --- a/saas_apps/controllers/main.py +++ b/saas_apps/controllers/main.py @@ -6,7 +6,7 @@ from odoo.addons.saas_public.controllers.saas_public import SaaSPublicController import urllib.parse -DB_TEMPLATE = 'db_template_' +DB_TEMPLATE = 'new_build_' class SaaSAppsController(Controller): @@ -68,7 +68,8 @@ def create_saas_template(self, **kw): 'template': saas_template.id, 'template_operator': saas_template_operator.id, 'link': '0', - 'Error': '0' + 'Error': '0', + 'state': 'Draft' } @http.route(['/check_saas_template'], type='json', auth='public', website=True) @@ -89,19 +90,22 @@ def is_build_created(self, **kw): 'template': '0', 'template_operator': '0', 'link': urllib.parse.urljoin(build_url, '/auth_quick/check-token?token={}'.format(token_obj.token)), - 'Error': '0' + 'Error': '0', + 'state': template_operator.state } else: return { 'template': '0', 'template_operator': '0', 'link': '0', - 'Error': '1' + 'Error': '1', + 'state': template_operator.state } else: return { 'template': template.id, 'template_operator': template_operator.id, 'link': '0', - 'Error': '0' + 'Error': '0', + 'state': template_operator.state } diff --git a/saas_apps/images/attention.jpg b/saas_apps/images/attention.jpg deleted file mode 100644 index 6a5528b8a392c8000207c8fead3082e081a01563..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69376 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 Ly2AGoKil$eDWt(7 diff --git a/saas_apps/static/src/css/calculator.css b/saas_apps/static/src/css/calculator.css index c73d6bb53..8f130b627 100644 --- a/saas_apps/static/src/css/calculator.css +++ b/saas_apps/static/src/css/calculator.css @@ -7,6 +7,34 @@ font-size: 32px; } +.loader{ + position: fixed; + z-index: 99; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: white; + display: flex; + justify-content: center; + align-items: center; + opacity: 0.5; + visibility: hidden; +} + +.status{ + font-size: 26px; + color: black; + position: fixed; + margin-top: -70px; +} + +.loader > img { + width: 100px; + opacity: 0.6; + transform: rotate(-30deg); +} + .transition { transition: 0.3s; } @@ -48,6 +76,11 @@ margin-left: 10%; max-width: 40%; } + + .app{ + margin-left: 7px; + max-width: 31%; + } } @media (max-width: 799px) { diff --git a/saas_apps/static/src/img/loader.gif b/saas_apps/static/src/img/loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..ee9b1db7ad86ea1916d4b80dd8a5d2b4c473c3b4 GIT binary patch literal 41474 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

+
+ Stage: Draft +

Stage: Draft

+ +
From 9b5d380aab986c3197225b60c0b397794edca829 Mon Sep 17 00:00:00 2001 From: Vildan Safin Date: Tue, 31 Mar 2020 16:14:41 +0500 Subject: [PATCH 25/60] :green_heart: Signed-off-by: Vildan Safin --- saas_apps/__manifest__.py | 6 ++-- saas_apps/controllers/main.py | 2 +- saas_apps/models/saas_apps.py | 36 ++++++++++---------- saas_apps/static/src/js/apps.js | 41 ++++++++++++----------- saas_apps/static/src/js/refresh_button.js | 2 +- saas_apps/views/assets.xml | 2 +- saas_apps/views/calculator.xml | 2 +- saas_apps/views/manage.xml | 2 +- saas_apps/views/module_info.xml | 11 ------ saas_apps/views/refresh.xml | 4 +-- 10 files changed, 50 insertions(+), 58 deletions(-) delete mode 100644 saas_apps/views/module_info.xml diff --git a/saas_apps/__manifest__.py b/saas_apps/__manifest__.py index a24d55156..55dc69579 100644 --- a/saas_apps/__manifest__.py +++ b/saas_apps/__manifest__.py @@ -1,5 +1,5 @@ # Copyright 2020 Vildan Safin -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). { "name": """SaaS Apps""", @@ -13,11 +13,11 @@ "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", + "license": "AGPL-3", # "price": 9.00, # "currency": "EUR", - "depends": ['website', 'saas'], + "depends": ['website', 'saas_public'], "external_dependencies": {"python": [], "bin": []}, "data": [ 'security/ir.model.access.csv', diff --git a/saas_apps/controllers/main.py b/saas_apps/controllers/main.py index 095cda768..0b5caffca 100644 --- a/saas_apps/controllers/main.py +++ b/saas_apps/controllers/main.py @@ -21,7 +21,7 @@ def user_page(self, **kw): @http.route(['/refresh'], type='json', auth='public') def catch_app_click(self, **kw): apps = http.request.env['saas.line'] - apps.refresh() + apps.refresh_lines() return {} @http.route(['/what_dependencies'], type='json', auth='public') diff --git a/saas_apps/models/saas_apps.py b/saas_apps/models/saas_apps.py index 21fdb71e8..ddbf83e0a 100644 --- a/saas_apps/models/saas_apps.py +++ b/saas_apps/models/saas_apps.py @@ -15,17 +15,15 @@ class SAASModule(models.Model): year_price = fields.Float(default=0.0, string="Year price") saas_modules = fields.Many2many('saas.line') - @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 - - @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." + @api.constrains('month_price') + def _validate_month_price(self): + if self.month_price < 0: + raise ValidationError("Month price can't be negative.") + + @api.constrains('year_price') + def _validate_year_price(self): + if self.year_price < 0: + raise ValidationError("Year price can't be negative.") def add_new_module(self, name): self.create({ @@ -33,7 +31,9 @@ def add_new_module(self, name): }) return True - def refresh(self): + def refresh_modules(self): + for app in map(self.browse, self._search([])): + app.unlink() irmodules = self.env["ir.module.module"].search([]) for irmodule in irmodules: if len(self.search([('name', '=', irmodule.name)])) == 0: @@ -53,11 +53,11 @@ class SAASDependence(models.Model): 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): + def refresh_lines(self): apps = self.env["saas.module"] - apps.search([]).unlink() - self.search([]).unlink() - apps.refresh() + for line in map(self.browse, self._search([])): + line.unlink() + apps.refresh_modules() base_icon_path = '/base/static/description/icon.png' for app in apps.search([]): if len(self.search([('name', '=', app.name)])) == 0: @@ -80,10 +80,12 @@ def refresh(self): }) def _compute_year_price(self): + self.year_price = 0 for module in self.dependencies: self.year_price += module.year_price def _compute_month_price(self): + self.month_price = 0 for module in self.dependencies: self.month_price += module.month_price @@ -116,7 +118,7 @@ def dependencies_info(self, root): def write(self, vals): res = super(SAASDependence, self).write(vals) # If value of allow_to_sell changed, other sets allow_to_sell vars should be changed too - if "allow_to_sell" in vals: + if "allow_to_sell" in vals and vals['allow_to_sell']: this_app = self.dependencies.search([('name', '=', self.name)]) for app in self.dependencies - this_app: temp_app = self.search([('name', '=', app.name)]) diff --git a/saas_apps/static/src/js/apps.js b/saas_apps/static/src/js/apps.js index 6a8e1881b..b38a8a4a6 100644 --- a/saas_apps/static/src/js/apps.js +++ b/saas_apps/static/src/js/apps.js @@ -33,7 +33,7 @@ odoo.define('saas_apps.model', function (require){ return; } if(data.link !== '0'){ - $('.loader')[0].style = 'opacity: 0.5;z-index: 0;'; + $('.loader')[0].style = 'visibility: hidden;'; window.location.href = data.link; } else if(data.template !== '0'){ @@ -97,22 +97,22 @@ odoo.define('saas_apps.model', function (require){ prices.set(module.name, [module.month_price, module.year_price]) } + // Downloading apps dependencies window.onload = function() { - var apps = $('.app_tech_name'), i = 0; - for(; i < apps.length; ++i){ + $.each($('.app_tech_name'), function(key, app){ session.rpc('/what_dependencies', { - args: [apps[i].innerText] + args: [app.innerText] }).then(function (result) { /* Be carefull with dependecies when changing programm logic, cause first dependence - is module himself*/ - var i = 0; - for(; i < result.dependencies.length; ++i){ + var first_dependence = true; + result.dependencies.forEach(dependence => { // Add new element to the dependencies parent_tree, cause we'll restablish a path from leaf to the root // when we'll have to delete one of leafs - if(i > 0){ - var modules_parents = parent_tree.get(result.dependencies[i].name), - root_module_name = result.dependencies[i].parent, - leaf_name = result.dependencies[i].name; + if(!first_dependence){ + var modules_parents = parent_tree.get(dependence.name), + root_module_name = dependence.parent, + leaf_name = dependence.name; if(modules_parents === undefined){ parent_tree.set(leaf_name, [root_module_name]); console.log("INFO:Added new leaf '"+leaf_name+"' with root module '"+root_module_name+"'."); @@ -123,16 +123,16 @@ odoo.define('saas_apps.model', function (require){ console.log("WARNING:Root module '"+root_module_name+"' already in parent_tree!"); } } - if(result.dependencies[i].childs){ - var root = result.dependencies[i].name, + if(dependence.childs){ + var root = dependence.name, in_tree_childs = child_tree.get(root); - // Here we get new elements from result.dependencies[i].childs, difference btw - // result.dependencies[i].childs and in_tree_childs. + // Here we get new elements from dependence.childs, difference btw + // dependence.childs and in_tree_childs. if(in_tree_childs === undefined){ - child_tree.set(root, result.dependencies[i].childs); - console.log("INFO:Added new root '"+root+"' with childs '"+result.dependencies[i].childs[0]+"...'"); + child_tree.set(root, dependence.childs); + console.log("INFO:Added new root '"+root+"' with childs '"+dependence.childs[0]+"...'"); }else{ - var new_childs = result.dependencies[i].childs.filter(x => !in_tree_childs.includes(x)); + var new_childs = dependence.childs.filter(x => !in_tree_childs.includes(x)); new_childs.forEach(function(child){ in_tree_childs.push(child); console.log("INFO:Added new child module '"+child+"' to root '"+root+"'."); @@ -140,10 +140,11 @@ odoo.define('saas_apps.model', function (require){ } } - add_price(result.dependencies[i]); - } + add_price(dependence); + first_dependence = false; + }); }); - } + }); }; function add_to_basket(module_name){ diff --git a/saas_apps/static/src/js/refresh_button.js b/saas_apps/static/src/js/refresh_button.js index b13ebff86..85784b1e2 100644 --- a/saas_apps/static/src/js/refresh_button.js +++ b/saas_apps/static/src/js/refresh_button.js @@ -1,6 +1,6 @@ /* Copyright 2020 Vildan Safin License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).*/ - odoo.define('whatever.filter_button', function (require) { + odoo.define('saas_apps.filter_button', function (require) { "use strict"; var core = require('web.core'); diff --git a/saas_apps/views/assets.xml b/saas_apps/views/assets.xml index f73cb829d..17f8acfa3 100644 --- a/saas_apps/views/assets.xml +++ b/saas_apps/views/assets.xml @@ -1,6 +1,6 @@ + License AGPL-3.0 (https://www.gnu.org/licenses/lgpl.html).-->