From 7f5a20aa40c00fea42c68211f311b6b24ad64c9e Mon Sep 17 00:00:00 2001
From: rsanchez <rsanchez@curisit.net>
Date: Mon, 27 Oct 2014 18:17:26 +0000
Subject: [PATCH] #2021 feature - Added frontend validations and confirmations on sensitive actions.

---
 securis/src/main/resources/static/licenses.html                         |   40 +++++++++
 securis/src/main/java/net/curisit/securis/services/LicenseResource.java |   10 ++
 securis/src/main/resources/static/js/licenses.js                        |  143 +++++++++++++++++++++++++++++------
 securis/src/main/java/net/curisit/securis/db/Pack.java                  |   12 +++
 securis/src/main/resources/db/schema.sql                                |    1 
 securis/src/main/java/net/curisit/securis/services/PackResource.java    |   11 ++
 6 files changed, 188 insertions(+), 29 deletions(-)

diff --git a/securis/src/main/java/net/curisit/securis/db/Pack.java b/securis/src/main/java/net/curisit/securis/db/Pack.java
index f3477fc..1cd05ca 100644
--- a/securis/src/main/java/net/curisit/securis/db/Pack.java
+++ b/securis/src/main/java/net/curisit/securis/db/Pack.java
@@ -95,6 +95,10 @@
     @JsonProperty("license_preactivation")
     private boolean licensePreactivation;
 
+    @Column(name = "default_valid_period")
+    @JsonProperty("default_valid_period")
+    private Integer defaultValidPeriod;
+
     @OneToMany(fetch = FetchType.LAZY, mappedBy = "pack")
     private Set<PackMetadata> metadata;
 
@@ -327,6 +331,14 @@
         return (id == null ? 0 : id.hashCode());
     }
 
+    public Integer getDefaultValidPeriod() {
+        return defaultValidPeriod;
+    }
+
+    public void setDefaultValidPeriod(Integer defaultValidPeriod) {
+        this.defaultValidPeriod = defaultValidPeriod;
+    }
+
     public static class Action {
         public static final int CREATE = 1;
         public static final int ACTIVATION = 2;
diff --git a/securis/src/main/java/net/curisit/securis/services/LicenseResource.java b/securis/src/main/java/net/curisit/securis/services/LicenseResource.java
index 351500f..ae36938 100644
--- a/securis/src/main/java/net/curisit/securis/services/LicenseResource.java
+++ b/securis/src/main/java/net/curisit/securis/services/LicenseResource.java
@@ -310,6 +310,16 @@
         return Response.ok(lic).build();
     }
 
+    /**
+     * Cancel the license
+     * 
+     * @param lic
+     * @param em
+     */
+    public static void cancelLicense(License lic, EntityManager em) throws SeCurisServiceException {
+
+    }
+
     @POST
     @Path("/")
     @Consumes(MediaType.APPLICATION_JSON)
diff --git a/securis/src/main/java/net/curisit/securis/services/PackResource.java b/securis/src/main/java/net/curisit/securis/services/PackResource.java
index e876cb5..a3b65a9 100644
--- a/securis/src/main/java/net/curisit/securis/services/PackResource.java
+++ b/securis/src/main/java/net/curisit/securis/services/PackResource.java
@@ -337,14 +337,19 @@
     public Response delete(@PathParam("packId") String packId) {
         LOG.info("Deleting pack with id: {}", packId);
         EntityManager em = emProvider.get();
-        Pack org = em.find(Pack.class, Integer.parseInt(packId));
-        if (org == null) {
+        Pack pack = em.find(Pack.class, Integer.parseInt(packId));
+        if (pack == null) {
             LOG.error("Pack with id {} can not be deleted, It was not found in DB", packId);
             return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Pack was not found, ID: " + packId)
                     .build();
         }
+        if (pack.getMetadata() != null) {
+            for (PackMetadata md : pack.getMetadata()) {
+                em.remove(md);
+            }
+        }
 
-        em.remove(org);
+        em.remove(pack);
         return Response.ok(Utils.createMap("success", true, "id", packId)).build();
     }
 
diff --git a/securis/src/main/resources/db/schema.sql b/securis/src/main/resources/db/schema.sql
index 0f448ea..cac2f67 100644
--- a/securis/src/main/resources/db/schema.sql
+++ b/securis/src/main/resources/db/schema.sql
@@ -84,6 +84,7 @@
   license_type_id INT NOT NULL,  
   organization_id INT NOT NULL,  
   license_preactivation BOOLEAN NOT NULL DEFAULT true,  
+  default_valid_period INT NOT NULL DEFAULT 60,  
   created_by varchar(45) NULL ,  
   creation_timestamp DATETIME NOT NULL ,  
   PRIMARY KEY (id));
diff --git a/securis/src/main/resources/static/js/licenses.js b/securis/src/main/resources/static/js/licenses.js
index 7617858..6dfe849 100644
--- a/securis/src/main/resources/static/js/licenses.js
+++ b/securis/src/main/resources/static/js/licenses.js
@@ -159,6 +159,53 @@
 			return LIC_STATUSES[status];
 		}
 
+		var _createSuccessCallback = function(actionName, message, _innerCallback) {
+			return function() {
+				_innerCallback && _innerCallback();
+				toaster.pop('success', actionName, message);
+			}
+		}
+		var _createErrorCallback = function(pack, actionName, _innerCallback) {
+			return function(error) {
+	            console.log(error);
+	            _innerCallback && _innerCallback();
+				toaster.pop('error', actionName, $L.get("Error on action '{0}', pack '{1}'. Reason: {2}", actionName, pack.code, $L.get(error.headers('X-SECURIS-ERROR'))));
+			}
+		}
+		this.getPacksList = function(pack, _onsuccess, _onerror) {
+			return packResource.query(_onsuccess, _onerror);
+		}
+		this.activate = function(license, _onsuccess, _onerror) {
+			console.log('Activation on license: ' + license.id);
+			var _success = _createSuccessCallback($L.get('Activation'), $L.get("License '{0}' {1} successfully", license.code, $L.get("activated")), _onsuccess);
+			var _error = _createErrorCallback(license, $L.get('Activation'), _onerror);
+			licenseResource.activate({id: license.id}, _success, _error);
+		}
+		this.block = function(license, _onsuccess, _onerror) {
+			console.log('Block on license: ' + license.id);
+			var _success = _createSuccessCallback($L.get('Block'), $L.get("License '{0}' {1} successfully", license.code, $L.get("blocked")), _onsuccess);
+			var _error = _createErrorCallback(license, $L.get('Block'), _onerror);
+			licenseResource.putonhold({id: license.id}, _success, _error);
+		}
+		this.unblock = function(license, _onsuccess, _onerror) {
+			console.log('Unblock on license: ' + license.id);
+			var _success = _createSuccessCallback($L.get('Unblock'), $L.get("License '{0}' {1} successfully", license.code, $L.get("unblocked")), _onsuccess);
+			var _error = _createErrorCallback(license, $L.get('Unblock'), _onerror);
+			licenseResource.putonhold({id: license.id}, _success, _error);
+		}
+		this.cancel = function(license, extra_data, _onsuccess, _onerror) {
+			console.log('Cancellation on license: ' + license.id);
+			var _success = _createSuccessCallback($L.get('Cancellation'), $L.get("License '{0}' {1} successfully", license.code, $L.get("cancelled")), _onsuccess);
+			var _error = _createErrorCallback(license, $L.get('Cancellation'), _onerror);
+			var params = angular.extend({id: license.id}, extra_data);
+			licenseResource.cancel(params, _success, _error);
+		}
+		this.delete = function(license, _onsuccess, _onerror) {
+			console.log('Delete on license: ' + license.id);
+			var _success = _createSuccessCallback($L.get('Deletion'), $L.get("License '{0}' {1} successfully", license.code, $L.get("deleted")), _onsuccess);
+			var _error = _createErrorCallback(license, $L.get('Deletion'), _onerror);
+			licenseResource.delete({licenseId: license.id}, _success, _error);
+		}
 	}]);
 	
 	app.directive('fileLoader',
@@ -217,6 +264,9 @@
         				$scope.mandatoryFieldErrorMsg = function(displayname) {
         					return $L.get("'{0}' is required.", $L.get(displayname));
         				}
+        				$scope.field1ShouldBeGreaterThanField2 = function(field1, field2) {
+        					return $L.get("{0} should be greater than {1}", $L.get(field1), $L.get(field2));
+        				}
         				$scope.ellipsis = function(txt, len) {
         					if (!txt || txt.length <= len) return txt;
         					return txt.substring(0, len) + '...';
@@ -269,36 +319,79 @@
 				$scope.packs = Packs.getPacksList();
 				
 				$scope.save = function() {
-					if ($scope.pack.num_activations > 0) {
-						BootstrapDialog.confirm($L.get("The pack '{0}' has active licenses, Do you want to modify it ?", $scope.pack.code), function(answer){
-	                        if (answer) {
-	                        	Packs.savePackData($scope.pack, $scope.isNew, function() {
-	                			    if (!$scope.isNew) $scope.showForm = false;
-	                				$scope.packs = Packs.getPacksList();
-	                        	});
-	                        }
-	                    });
-					} else {
-                    	Packs.savePackData($scope.pack, $scope.isNew, function() {
-            			    if (!$scope.isNew) {
-            			    	$scope.showForm = false;
-            			    } else {
-            			    	$scope.newPack();
-            			    }
-            				$scope.packs = Packs.getPacksList();
-                    	});
-				    }
+                	Packs.savePackData($scope.pack, $scope.isNew, function() {
+        			    if (!$scope.isNew) {
+        			    	$scope.showForm = false;
+        			    } else {
+        			    	$scope.newPack();
+        			    }
+        				$scope.packs = Packs.getPacksList();
+                	});
 				}
 
 				/**
 				 * Execute an action over the pack, activation, onhold, cancellation
 				 */
 				$scope.execute = function(action, pack) {
-					
-					Packs[action](pack || $scope.pack, function() {
-					    if (!$scope.isNew) $scope.showForm = false;
-						$scope.packs = Packs.getPacksList();
-					});
+					var _execute = function(extra_data) {
+						Packs[action](pack || $scope.pack, extra_data, function() {
+						    if (!$scope.isNew) $scope.showForm = false;
+							$scope.packs = Packs.getPacksList();
+						});
+					}
+					if (action === 'delete') {
+						BootstrapDialog.confirm($L.get("The pack '{0}' will be deleted, are you sure ?", $scope.pack.code), function(answer) {
+	                        if (answer) {
+	                        	_execute();
+	                        }
+	                    });
+					} else {
+						if (action === 'cancel') {
+							BootstrapDialog.show({
+								title: $L.get("Pack cancellation"),
+								type: BootstrapDialog.TYPE_DANGER,
+								message: function(dialog) {
+									var $content = $('<div></div>');
+									var $message = $('<div></div>');
+					                var pageToLoad = dialog.getData('pageToLoad');
+					                $message.append($('<label/>').text($L.get("The pack '{0}' and all its licenses will be cancelled, this action cannot be undone", $scope.pack.code)));
+					                $content.append($message);
+
+									var $message = $('<div style="margin-top:10pt;"/>');
+					                var pageToLoad = dialog.getData('pageToLoad');
+					                $message.append($('<label style="margin-right:5pt;"/>').text($L.get("Cancellation reason:") + " "));
+					                $message.append($('<input type="text" style="width:100%;" maxlength="512" id="_cancellation_reason"/>'));
+					                $content.append($message);
+					            	return $content;								 
+								},
+								closable: true,
+								buttons: [{
+							        id: 'btn-cancel',   
+							        label: $L.get('Close'),
+							        cssClass: 'btn-default', 
+							        action: function(dialogRef) {    
+							            dialogRef.close();
+							        }
+							    }, {
+							        id: 'btn-ok',   
+							        label: $L.get('Cancel pack'),
+							        cssClass: 'btn-primary', 
+							        action: function(dialogRef){
+							        	var reason = $('#_cancellation_reason').val();
+							        	console.log('Ready to cancel pack, by reason: ' + reason);
+							            if (!reason) {
+							            	$('#_cancellation_reason').focus();
+							            } else {
+							            	_execute({reason: reason});
+								            dialogRef.close();
+							            }
+							        }
+							    }]
+							});
+						} else {
+							_execute();
+						}
+					}
 				}
 				
 
@@ -309,6 +402,8 @@
                             license_preactivation: true,
                             status: 'CR',
                             num_licenses: 1,
+                            init_valid_date: new Date(),
+                            default_valid_period: 30,
                             license_type_id: null,
                             organization_id: null  //!$scope.refs.organization_id || !$scope.refs.organization_id.length ? null : $scope.refs.organization_id[0].id
 					}
diff --git a/securis/src/main/resources/static/licenses.html b/securis/src/main/resources/static/licenses.html
index 819d20b..977f1e3 100644
--- a/securis/src/main/resources/static/licenses.html
+++ b/securis/src/main/resources/static/licenses.html
@@ -79,12 +79,15 @@
 					<div class="col-md-4">
 						<input type="date" id="end_valid_date" name="end_valid_date" placeholder=""
 							class="form-control" ng-model="pack.end_valid_date"
+							min="{{pack.init_valid_date  | date: 'yyyy-MM-dd'}}"
 							ng-required="mandatory.end_valid_date"  />
 						<div class="alert inline-alert alert-warning"
-							ng-show="packForm.initValidDate.$invalid">
+							ng-show="packForm.end_valid_date.$invalid">
 							<span class="glyphicon glyphicon-warning-sign"></span> 
 							<span ng-show="packForm.end_valid_date.$error.required"
 								ng-bind="mandatoryFieldErrorMsg('End valid date')"></span>
+							<span ng-show="packForm.end_valid_date.$error.min"
+								ng-bind="field1ShouldBeGreaterThanField2('End date', 'Init date')"></span>
 						</div>
 					</div>
 				</div>
@@ -163,6 +166,23 @@
 					<div class="col-md-8">
 						<input type="checkbox" class="form-control"
 							ng-model="pack.license_preactivation" />
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="col-md-3 control-label" for="license_preactivation"
+						i18n>Default valid period (days)</label>
+					<div class="col-md-8">
+						<input type="number" id="default_valid_period" name="default_valid_period"
+						    min="1" class="form-control" ng-model="pack.default_valid_period"
+							ng-required="pack.license_preactivation" />
+						<div class="alert inline-alert alert-warning"
+							ng-show="packForm.default_valid_period.$invalid">
+							<span class="glyphicon glyphicon-warning-sign"></span> 
+							<span ng-show="packForm.default_valid_period.$error.required"
+								ng-bind="mandatoryFieldErrorMsg('Default valid period')"></span>
+							<span ng-show="packForm.default_valid_period.$error.min"
+								ng-bind="field1ShouldBeGreaterThanField2('The default valid period', '0')"></span>
+						</div>
 					</div>
 				</div>
 
@@ -246,6 +266,23 @@
 			</form>
 		</div>
 
+<div class="modal fade" id="cancellationReasonDialog" tabindex="-1" role="dialog" aria-labelledby="cancelDialogLabel" aria-hidden="true">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
+        <h4 class="modal-title" id="cancelDialogLabel" i18n>Pack cancellation</h4>
+      </div>
+      <div class="modal-body">
+        	
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal" i18n>Close</button>
+        <button type="button" class="btn btn-primary" i18n>Cancel pack</button>
+      </div>
+    </div>
+  </div>
+</div>
 
 		<div class="panel panel-default">
 			<div class="panel-heading">
@@ -625,4 +662,3 @@
 
 	</div>
 </div>
-

--
Gitblit v1.3.2