From e70468294b7411c12fb8b253cf3172f9bb306513 Mon Sep 17 00:00:00 2001 From: Pablo Pazos Gutierrez Date: Tue, 6 Mar 2018 23:17:27 -0300 Subject: [PATCH] closes #867 --- grails-app/conf/BootStrap.groovy | 4 +- grails-app/conf/BuildConfig.groovy | 18 ++++---- .../ehrserver/account/StatsController.groovy | 35 +++++++++++++- .../ehr/OperationalTemplateController.groovy | 16 ++++++- grails-app/i18n/messages.properties | 2 + grails-app/i18n/messages_es.properties | 2 + grails-app/views/account/index.gsp | 10 ++-- grails-app/views/account/show.gsp | 46 ++++++++++++++----- grails-app/views/organization/_form.gsp | 2 +- lrun.sh | 2 +- 10 files changed, 105 insertions(+), 32 deletions(-) diff --git a/grails-app/conf/BootStrap.groovy b/grails-app/conf/BootStrap.groovy index 0f508afe6..a6619ab1c 100644 --- a/grails-app/conf/BootStrap.groovy +++ b/grails-app/conf/BootStrap.groovy @@ -689,7 +689,7 @@ class BootStrap { new RequestMap(url: '/account/index', configAttribute: 'ROLE_ADMIN').save() new RequestMap(url: '/account/create', configAttribute: 'ROLE_ADMIN').save() new RequestMap(url: '/account/save', configAttribute: 'ROLE_ADMIN').save() - new RequestMap(url: '/account/edit', configAttribute: 'ROLE_ADMIN').save() + new RequestMap(url: '/account/edit/**', configAttribute: 'ROLE_ADMIN').save() new RequestMap(url: '/account/update', configAttribute: 'ROLE_ADMIN').save() new RequestMap(url: '/account/show/**', configAttribute: 'ROLE_ADMIN,ROLE_ACCOUNT_MANAGER,ROLE_ORG_MANAGER').save() @@ -991,7 +991,7 @@ gr_account.save(failOnError:true, flush:true) max_organizations: 3, max_opts_per_organization: 3, max_api_tokens_per_organization: 3, - repo_total_size_in_kb: 900, // low for testing! (1MB in KB) + repo_total_size_in_kb: 2000, // low for testing! (1MB in KB) period: Plan.periods.MONTHLY ) ] diff --git a/grails-app/conf/BuildConfig.groovy b/grails-app/conf/BuildConfig.groovy index 53a16765b..bbf8a2249 100644 --- a/grails-app/conf/BuildConfig.groovy +++ b/grails-app/conf/BuildConfig.groovy @@ -32,7 +32,7 @@ grails.reload.enabled = true forkConfig = [maxMemory: 1024, minMemory: 64, debug: false, maxPerm: 512] grails.project.fork = [ test: forkConfig, // configure settings for the test-app JVM - run: false, // configure settings for the run-app JVM + run: forkConfig, // configure settings for the run-app JVM war: forkConfig, // configure settings for the run-war JVM console: forkConfig // configure settings for the Swing console JVM ] @@ -73,7 +73,7 @@ grails.project.dependency.resolution = { mavenLocal() mavenCentral() - + mavenRepo "http://repo.spring.io/milestone/" //mavenRepo "https://oss.sonatype.org/content/repositories/snapshots/" @@ -87,7 +87,7 @@ grails.project.dependency.resolution = { // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg. // runtime 'mysql:mysql-connector-java:5.1.20' - + // Este error da si uso http-builder 0.6 con 0.5.2 anda ok // FIX: Me da un error luego de poner referencia a http-builder // http://jira.grails.org/browse/GPEXPORT-18?focusedCommentId=69307&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-69307 @@ -100,7 +100,7 @@ grails.project.dependency.resolution = { excludes 'xmlbeans' } */ - + /* runtime('com.thoughtworks.xstream:xstream:1.4.3') { // loader constraint violation: loader (instance of ) previously @@ -108,18 +108,18 @@ grails.project.dependency.resolution = { //excludes 'xmlbeans' } */ - + runtime('org.codehaus.groovy.modules.http-builder:http-builder:0.5.2') { excludes "commons-logging", "xml-apis", "groovy", "nekohtml" } test "org.grails:grails-datastore-test-support:1.0-grails-2.4" - + //compile 'xerces:xercesImpl:2.11.0' compile group: 'de.odysseus.staxon', name: 'staxon', version: '1.2' - + compile "mysql:mysql-connector-java:5.1.43" //"mysql:mysql-connector-java:5.1.22" - + //compile "org.springframework.security:spring-security-crypto:4.0.2-RELEASE" //compile 'org.pac4j:pac4j-core:1.7.1' } @@ -146,7 +146,7 @@ grails.project.dependency.resolution = { runtime ':hibernate4:4.3.10' // or ':hibernate:3.6.10.14' runtime ':database-migration:1.4.0' runtime ':jquery:1.11.1' - + // https://github.com/davidtinker/grails-cors runtime ":cors:1.1.8" diff --git a/grails-app/controllers/com/cabolabs/ehrserver/account/StatsController.groovy b/grails-app/controllers/com/cabolabs/ehrserver/account/StatsController.groovy index 3809cc2a9..6759948c9 100644 --- a/grails-app/controllers/com/cabolabs/ehrserver/account/StatsController.groovy +++ b/grails-app/controllers/com/cabolabs/ehrserver/account/StatsController.groovy @@ -24,6 +24,7 @@ package com.cabolabs.ehrserver.account import net.kaleidos.grails.plugin.security.stateless.annotation.SecuredStateless +import com.cabolabs.ehrserver.ehr.clinical_documents.OperationalTemplateIndex import com.cabolabs.ehrserver.openehr.common.change_control.Contribution import com.cabolabs.ehrserver.openehr.common.change_control.Version import com.cabolabs.security.* @@ -149,6 +150,7 @@ class StatsController { from: from, to: to] } + // disk usage for all the organizations in the account // results are in KB def accountRepoUsage(Account account) { @@ -173,9 +175,40 @@ class StatsController { // size is set in KB stats[org.uid] = size - if (!plan_repo_total_size) max_repo_size += stats[org.name] + // if there is no plan, we set the max to the current size + if (!plan_repo_total_size) max_repo_size += size } render(text: [max_repo_size: max_repo_size, usage: stats] as JSON, contentType:"application/json", encoding:"UTF-8") } + + /** + * Stats abuot the number of templates loaded, returns also the max templates per org. + */ + def accountTemplatesLoaded(Account account) + { + def plan_association = Plan.active(account) // can be null! + def max_opts_per_org = 0 + + def plan_max_opts = false + if (plan_association) + { + max_opts_per_org = plan_association.plan.max_opts_per_organization + plan_max_opts = true + } + + def stats = [:] // org name => repo size + def count + + account.organizations.each { org -> + + count = OperationalTemplateIndex.forOrg(org).lastVersions.count() + stats[org.uid] = count + + // if there is no plan, we set the max to the current amount + if (!plan_max_opts) max_opts_per_org += count + } + + render(text: [max_opts_per_org: max_opts_per_org, usage: stats] as JSON, contentType:"application/json", encoding:"UTF-8") + } } diff --git a/grails-app/controllers/com/cabolabs/ehrserver/openehr/ehr/OperationalTemplateController.groovy b/grails-app/controllers/com/cabolabs/ehrserver/openehr/ehr/OperationalTemplateController.groovy index 244a538e0..8d1e0d7e2 100644 --- a/grails-app/controllers/com/cabolabs/ehrserver/openehr/ehr/OperationalTemplateController.groovy +++ b/grails-app/controllers/com/cabolabs/ehrserver/openehr/ehr/OperationalTemplateController.groovy @@ -91,7 +91,7 @@ class OperationalTemplateController { def user = springSecurityService.getCurrentUser() - // Repo size check + // Repo size check and max opt check max_opts_per_organization def account = user.account def plan_assoc = Plan.active(account) // can be null on dev envs, size check is not done on that case. if (plan_assoc) @@ -102,14 +102,25 @@ class OperationalTemplateController { render(text: res as JSON, contentType:"application/json", encoding:"UTF-8") return } + + def opt_count = OperationalTemplateIndex.forOrg(session.organization).lastVersions.count() + + if (plan_assoc.plan.max_opts_per_organization <= opt_count) + { + res = [status:'error', message:message(code:'opt.upload.error.max_opt_reached'), errors: errors] + render(text: res as JSON, contentType:"application/json", encoding:"UTF-8") + return + } } + + // PROCESS FILE // http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/multipart/commons/CommonsMultipartFile.html def f = request.getFile('opt') - // Add file empty check + // file empty check if(f.empty) { errors << message(code:"opt.upload.error.noOPT") @@ -142,6 +153,7 @@ class OperationalTemplateController { // /PROCESS FILE + // ROOT VALIDATION // Parse to get the template id diff --git a/grails-app/i18n/messages.properties b/grails-app/i18n/messages.properties index c7dce4bf1..30f7ad94f 100644 --- a/grails-app/i18n/messages.properties +++ b/grails-app/i18n/messages.properties @@ -374,6 +374,7 @@ opt.upload.label.overwrite=Overwrite if template exists opt.upload.label.opt=Operational Template opt.upload.label.upload=Upload opt.upload.error.insufficient_storage=You have reached the storage limit for your account. If you need more storage, please upgrade your plan. Contact admin@cloudehrserver.com for more information. +opt.upload.error.max_opt_reached=You have reached the maximum amount of templates for this organization. If you need more, please upgrade your plan. Contact admin@cloudehrserver.com for more information. template.show.title=Template details template.templateId.label=Template ID @@ -687,6 +688,7 @@ account.update.planNotFound=Plan not found account.update.errorAssigningPlan=Plan assignment returned an error account.update.ok=Account updated! account.stats.repo_usage=Disk usage +account.stats.uploaded_opts=Uploaded templates account.create.title=Create account account.attr.companyName=Company name diff --git a/grails-app/i18n/messages_es.properties b/grails-app/i18n/messages_es.properties index e8faebdb4..a0417c587 100644 --- a/grails-app/i18n/messages_es.properties +++ b/grails-app/i18n/messages_es.properties @@ -374,6 +374,7 @@ opt.upload.label.overwrite=Sobreescribir si existe opt.upload.label.opt=Plantilla opt.upload.label.upload=Cargar opt.upload.error.insufficient_storagee=Ha alcanzado el límite de almacenamiento para su cuenta. Si necesita más espacio de almacenamiento, por favor mejore su plan. Contacte admin@cloudehrserver.com para más información. +opt.upload.error.max_opt_reached=Ha alcanzado el número máximo de plantillas para esta organización. Si necesita más, por favor mejore su plan. Contacte admin@cloudehrserver.com para más información. template.show.title=Plantilla template.templateId.label=ID @@ -687,6 +688,7 @@ account.update.planNotFound=El plan no existe account.update.errorAssigningPlan=Ocurrió un error al asignar el plan account.update.ok=Cuenta actualizada con éxito account.stats.repo_usage=Uso de disco +account.stats.uploaded_opts=Plantillas cargadas account.create.title=Crear cuenta account.attr.companyName=Nombre de la empresa diff --git a/grails-app/views/account/index.gsp b/grails-app/views/account/index.gsp index f9e3c5dea..b6c33a255 100644 --- a/grails-app/views/account/index.gsp +++ b/grails-app/views/account/index.gsp @@ -6,13 +6,13 @@ <g:message code="account.index.title" /> - +

- +
- +
@@ -37,6 +37,7 @@ + @@ -44,7 +45,8 @@ - + + diff --git a/grails-app/views/account/show.gsp b/grails-app/views/account/show.gsp index fca2dbe01..1a7eb6c90 100644 --- a/grails-app/views/account/show.gsp +++ b/grails-app/views/account/show.gsp @@ -43,14 +43,26 @@
${fieldValue(bean: accountInstance, field: "contact")}${accountInstance.companyName}${accountInstance.contact}
-
    - -
  • - ${org.name} - -
  • -
    -
+
+ + + + + + + + + + + + + + + + + +
${org.name}
+
@@ -82,20 +94,30 @@ .done( function(json) { console.log('stats', json); - var classes = ['success', 'info', 'warning', 'danger']; - var bar = $('
'); var org_count = Object.keys(json.usage).length; var i = 0; for (org_uid in json.usage) { percent = precisionRound( json.usage[org_uid] * 100 / json.max_repo_size, 1); - $('#'+ org_uid).text(percent +'%').append(' '); + $('#stats-storage-'+ org_uid).text(percent +'%').append(' '); i++; } + }); - $('#account_stats').append(bar); + $.ajax({ + url: '${createLink(controller:"stats", action:"accountTemplatesLoaded", id:account.id)}', + method: 'GET', + dataType: 'json' + }) + .done( function(json) { + console.log('stats', json); + + for (org_uid in json.usage) + { + $('#stats-opts-'+ org_uid).text(json.usage[org_uid] +' / '+ json.max_opts_per_org).append(' '); + } }); }); diff --git a/grails-app/views/organization/_form.gsp b/grails-app/views/organization/_form.gsp index 296ce1e01..60f99a1b4 100644 --- a/grails-app/views/organization/_form.gsp +++ b/grails-app/views/organization/_form.gsp @@ -20,7 +20,7 @@ - +
diff --git a/lrun.sh b/lrun.sh index 29eea76a5..3ccc86db1 100755 --- a/lrun.sh +++ b/lrun.sh @@ -1 +1 @@ -grails -Dserver.port=8090 -Duser.timezone=UTC run-app +grails -Dserver.port=8090 -Duser.timezone=UTC -reloading run-app