Skip to content

Commit

Permalink
💣 Added child_tree and onload func in js
Browse files Browse the repository at this point in the history
Signed-off-by: Vildan Safin <safin@it-projects.info>
  • Loading branch information
Enigma228322 committed Mar 13, 2020
1 parent 81e4d1e commit f731737
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 119 deletions.
7 changes: 2 additions & 5 deletions saas_apps/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@ def catch_app_click(self, **kw):

@http.route(['/what_dependencies'], type='json', auth='public', website=True)
def what_dependencies(self, **kw):
app_name, which_price = kw['args']
app_name = kw['args'][0]
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)
'dependencies': app.dependencies_info('root')
}
46 changes: 17 additions & 29 deletions saas_apps/models/saas_apps.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# 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
from odoo import api, fields, models, modules
import logging

_logger = logging.getLogger(__name__)
Expand All @@ -14,12 +14,9 @@ class SAASModule(models.Model):
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")
icon_path = fields.Char(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)
Expand All @@ -42,14 +39,8 @@ 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
if len(self.search([('tech_name', '=', irmodule.name)])) == 0:
self.create({'tech_name': irmodule.name})


class SAASDependence(models.Model):
Expand Down Expand Up @@ -81,29 +72,26 @@ def _compute_month_price(self):
for module in self.dependencies:
self.month_price += module.month_price

def dependencies_info(self, for_month, deep):
def dependencies_info(self, root):
apps = []
# Root module
if not deep:
apps.append({
'parent': 'root',
'name': self.name,
'price': self.dependencies[0].cost(for_month)
})
childs = []
for child in self.dependencies - self.dependencies[0]:
childs.append(child.name)
apps.append({
'parent': root,
'name': self.name,
'year_price': self.dependencies[0].year_price,
'month_price': self.dependencies[0].month_price,
'childs': childs,
'icon_path': self.dependencies[0].icon_path
})
# 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)
leafs = set.dependencies_info(self.name)
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
Expand Down
9 changes: 8 additions & 1 deletion saas_apps/static/src/css/calculator.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
position: fixed;
right: 15%;
top: 20%;
width: 25%;
width: 20%;
z-index: 1;
}
}
Expand All @@ -40,4 +40,11 @@
width: 100%;
z-index: 1;
}
.container{
margin-left: auto !important;
}
}

.col-lg-9{
padding-left: 0px;
}
163 changes: 102 additions & 61 deletions saas_apps/static/src/js/apps.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ odoo.define('saas_apps.model', function (require){
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 = []
var tree = new Map()
var parent_tree = new Map()
var child_tree = new Map()
var prices = new Map()

// Returns element index if element exist in choosen
function includes_module(name){
Expand All @@ -21,13 +23,23 @@ odoo.define('saas_apps.model', function (require){
return -1;
}

// Finding all the links up to the tree,
function Calc_Price(){
// Calculate general price
price = 0;
var users_price_period = per_month ? 12.5 : 10.0;
for(var i = 0; i < choosen.length; ++i){
price += choosen[i].price;
}
return price + parseInt($('#users')[0].value, 10)*users_price_period;
}

// Finding all the links up to the parent_tree,
// and push them to delete_list
delete_list = [];
function leaf_to_root(name){
if(!delete_list.includes(name))
if(!delete_list.includes(name) )
delete_list.push(name);
roots = tree.get(name);
roots = parent_tree.get(name);
if(roots === undefined)
return;
if(roots.length > 0){
Expand All @@ -38,65 +50,104 @@ odoo.define('saas_apps.model', function (require){
}
}

window.onclick=function(e){
if(window.location.pathname === "/price"){
if(e.target.className.includes("application")){
// Looking at choosen period
var price_period = per_month ? 'month' : 'year';
// Getting choosen module dependecies
session.rpc('/what_dependencies', {
args: [e.target.innerText, price_period]
}).then(function (result) {
leafs = [];
function root_to_leafs(name){
if(!leafs.includes(name) )
leafs.push(name);
deps = child_tree.get(name);
if(deps === undefined)
return;
if(deps.length > 0){
deps.forEach(function(leaf){
leafs.push(leaf);
root_to_leafs(leaf);
});
}
}

/* Be carefull with dependecies when changing programm logic,
cause first dependence - is module himself*/
var i = 0, choosing_new = false;
for(; i < result.dependencies.length; ++i){
// Add new element to the dependencies tree, cause we'll restablish a path from leaf to the root
// when we'll have to delete one of leafs
if(i > 0){
modules_parents = tree.get(result.dependencies[i].name);
root_module_name = result.dependencies[i].parent;
window.onload = function() {
var apps = $('.application'), i = 0;
for(; i < apps.length; ++i){
session.rpc('/what_dependencies', {
args: [apps[i].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){
// 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(modules_parents === undefined){
tree.set(leaf_name, [root_module_name]);
console.log("INFO:Added new leaf '"+leaf_name+"' with root module '"+root_module_name+"'.");
}
else if(!modules_parents.includes(root_module_name)){
modules_parents.push(root_module_name);
console.log("INFO:Added new root module '"+root_module_name+"' to leaf '"+leaf_name+"'.");
}
else{
console.log("WARNING:Root module '"+root_module_name+"' already in tree!");
}
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+"'.");
}else if(!modules_parents.includes(root_module_name)){
modules_parents.push(root_module_name);
console.log("INFO:Added new root module '"+root_module_name+"' to leaf '"+leaf_name+"'.");
}else{
console.log("WARNING:Root module '"+root_module_name+"' already in parent_tree!");
}
leaf_name = result.dependencies[i].name;
if(includes_module(leaf_name) === -1)
{
choosen.push(result.dependencies[i]);
$(".application:contains('"+leaf_name+"')")[0].style.color = "green";
choosing_new = true;
}
if(result.dependencies[i].childs){
var root = result.dependencies[i].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.
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]+"...'");
}else{
if(choosing_new)
continue;
leaf_to_root(leaf_name);
delete_list.forEach(function(module){
choosen.splice(includes_module(module), 1);
$(".application:contains('"+module+"')")[0].style.color = "black";
var new_childs = result.dependencies[i].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+"'.");
});
delete_list = [];
break;
}
}
});
if(prices.get(result.dependencies[i].name) === undefined)
prices.set(result.dependencies[i].name, [result.dependencies[i].month_price, result.dependencies[i].year_price])
}
});
}
};

window.onclick=function(e){
if(window.location.pathname === "/price"){
if(e.target.className.includes("application")){
var app = e.target.innerText;
if(includes_module(app) === -1)
{
root_to_leafs(app);
leafs.forEach(function(leaf){
choosen.push({
'name': leaf,
'price': per_month ? prices.get(leaf)[0] : prices.get(leaf)[1]
});
$(".application:contains('"+leaf+"')")[0].style.color = "green";
});
leafs = [];
}else{
leaf_to_root(app);
delete_list.forEach(function(module){
var delete_id = includes_module(module);
if(delete_id !== -1){
choosen.splice(includes_module(module), 1);
$(".application:contains('"+module+"')")[0].style.color = "black";
}
});
delete_list = [];
}
}else if(e.target.className.includes("nav-link") && (e.target.innerText === "Annually" || e.target.innerText === "Monthly")){
// Check choosen period
per_month = e.target.innerText === "Monthly" ? true : false;
}
price = Calc_Price();
var period = per_month ? "month" : "year";
$('#price')[0].innerHTML = '<h2 id="price" class="card-title pricing-card-title">$'+String(price)+
' <small class="text-muted">/ '+ period +'</small></h2>';
var period = per_month ? "month" : "year";
$('#price')[0].innerHTML = '<h4 id="price" class="card-title pricing-card-title">$'+String(price)+
' <small class="text-muted">/ '+ period +'</small></h4>';
}
}

Expand Down Expand Up @@ -131,14 +182,4 @@ odoo.define('saas_apps.model', function (require){
// });
// }
// });

function Calc_Price(){
// Calculate general price
price = 0;
var users_price_period = per_month ? 12.5 : 10.0;
for(var i = 0; i < choosen.length; ++i){
price += choosen[i].price;
}
return price + parseInt($('#users')[0].value, 10)*users_price_period;
}
});
39 changes: 16 additions & 23 deletions saas_apps/views/calculator.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,27 @@
<t t-call="website.layout">
<title>Apps</title>
<div class="row container">
<div class="col-sm-8 center">
<div class="mx-auto">
<!-- Users qty -->
<h3 class="mt16 mb8">Choose the number of users</h3>
<div class="row" style="max-width: 30%">
<div class="col-sm">
<input class="openerp_enterprise_pricing_users form-control border text-right pr-2" min="1" id="users" type="number" style="max-width: 120px;" value="1"></input>
</div>
<div class="col-sm">
<label class="px-2 mr-1 mb-0 bg-200 border-top border-right border-bottom">Users</label>
</div>
<div class="col-sm">
<label>
<del class="text-700 ml-1 mr-2 openerp_enterprise_user_pricing_monthly d-none"><span class="openerp_enterprise_pricing_user_amount_monthly_full">15,00</span><span class="openerp_enterprise_pricing_currency">EUR</span></del>
<del class="text-700 ml-1 mr-2 openerp_enterprise_user_pricing_yearly"><span class="openerp_enterprise_pricing_user_amount_yearly_full">12,00</span><span class="openerp_enterprise_pricing_currency">EUR</span></del>
<b class="openerp_enterprise_user_pricing_monthly d-none">
<span class="openerp_enterprise_pricing_user_amount_monthly">12,50</span>;<span class="openerp_enterprise_pricing_currency">EUR</span><small class="fw_semibold">/user/month</small>
</b>
<b class="openerp_enterprise_user_pricing_yearly">
<span class="openerp_enterprise_pricing_user_amount_yearly">10,00</span>;<span class="openerp_enterprise_pricing_currency">EUR</span><small class="fw_semibold">/user/month</small>
</b>
</label>
<div class="openerp_enterprise_pricing_step mb-5">
<div class="openerp_enterprise_pricing_step_head">
<h3 class="mt16 mb8">Choose the number of <b>Users</b></h3>
</div>
<div class="openerp_enterprise_pricing_step_body d-flex align-items-stretch form-inline">
<input class="openerp_enterprise_pricing_users form-control border text-right pr-2" id="users" name="num_users" type="number" style="max-width: 100px;" min="1" value="1"/>
<label class="px-2 mr-1 mb-0 bg-200 border-top border-right border-bottom">Users</label>
<label>
<b>
<span class="openerp_enterprise_pricing_user_amount_yearly">10,00</span><span class="openerp_enterprise_pricing_currency">EUR</span><small class="fw_semibold">/user/month</small>
</b>
</label>
</div>
</div>
<div class="col-12 col-md-8 col-lg-9">
<!-- App list -->
<h3 class="mt16 mb16">Choose your Apps</h3>
<div class="openerp_enterprise_pricing_step_body mb24">
<div class="form-row">
<div class="form-row" style="min-width: 200%;">
<t t-foreach="apps" t-as="app">
<p class="col-12 col-sm-6 col-lg-4 shadow p-3 bg-white rounded price-window text-truncate application">
<img class="img"/>
Expand All @@ -59,8 +52,8 @@
</ul>
</div>
<div class="card-body">
<h2 id="price" class="card-title pricing-card-title">$15
<small class="text-muted">/ mo</small></h2>
<h4 id="price" class="card-title pricing-card-title">$15
<small class="text-muted">/ year</small></h4>
<ul class="list-unstyled mt-3 mb-4">
<li>20 users included</li>
<li>10 GB of storage</li>
Expand Down

0 comments on commit f731737

Please sign in to comment.