easy_pay_u_latam 0.1.15 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +15 -0
  3. data/app/assets/javascripts/easy_pay_u_latam/application.js +2 -0
  4. data/app/assets/javascripts/easy_pay_u_latam/subscriptions/angular-card.js +222 -0
  5. data/app/assets/javascripts/easy_pay_u_latam/subscriptions/application.js +8 -0
  6. data/app/assets/javascripts/easy_pay_u_latam/subscriptions/card.js +2533 -0
  7. data/app/assets/javascripts/easy_pay_u_latam/subscriptions/controllers/Main.js +158 -0
  8. data/app/assets/javascripts/easy_pay_u_latam/subscriptions/controllers/Subscriptions.js +368 -0
  9. data/app/assets/javascripts/easy_pay_u_latam/subscriptions/country-picker.min.js +1 -0
  10. data/app/assets/stylesheets/easy_pay_u_latam/styles.css +4 -0
  11. data/app/assets/stylesheets/easy_pay_u_latam/subscriptions/application.scss +1 -0
  12. data/app/assets/stylesheets/easy_pay_u_latam/subscriptions/card.css +1 -0
  13. data/app/controllers/easy_pay_u_latam/api/v1/pay_u_cards_controller.rb +80 -0
  14. data/app/controllers/easy_pay_u_latam/api/v1/pay_u_clients_controller.rb +18 -0
  15. data/app/controllers/easy_pay_u_latam/api/v1/pay_u_subscriptions_controller.rb +56 -0
  16. data/app/views/easy_pay_u_latam/pay_u_payments/_dashboard.html.erb +15 -0
  17. data/app/views/easy_pay_u_latam/pay_u_payments/cards/_form.html.erb +81 -0
  18. data/app/views/easy_pay_u_latam/pay_u_payments/cards/_list.html.erb +54 -0
  19. data/app/views/easy_pay_u_latam/pay_u_payments/plans/_list.html.erb +30 -0
  20. data/app/views/easy_pay_u_latam/pay_u_payments/subscriptions/_actual.html.erb +54 -0
  21. data/app/views/easy_pay_u_latam/pay_u_payments/{index.html.erb → subscriptions/_form.html.erb} +0 -0
  22. data/app/views/easy_pay_u_latam/pay_u_payments/subscriptions/_list.html.erb +49 -0
  23. data/app/views/easy_pay_u_latam/pay_u_payments/subscriptions/_none.html.erb +0 -0
  24. data/app/views/easy_pay_u_latam/pay_u_payments/subscriptions/_show.html.erb +0 -0
  25. data/config/routes.rb +5 -0
  26. data/lib/easy_pay_u_latam.rb +6 -0
  27. data/lib/easy_pay_u_latam/r_api.rb +47 -0
  28. data/lib/easy_pay_u_latam/r_api/card.rb +102 -0
  29. data/lib/easy_pay_u_latam/r_api/client.rb +28 -0
  30. data/lib/easy_pay_u_latam/r_api/invoice.rb +53 -0
  31. data/lib/easy_pay_u_latam/r_api/invoice_service.rb +48 -0
  32. data/lib/easy_pay_u_latam/r_api/plan.rb +71 -0
  33. data/lib/easy_pay_u_latam/r_api/request.rb +133 -0
  34. data/lib/easy_pay_u_latam/r_api/subscription.rb +41 -0
  35. data/lib/easy_pay_u_latam/r_api/subscription_interceptor.rb +51 -0
  36. data/lib/easy_pay_u_latam/r_api/subscription_service.rb +208 -0
  37. data/lib/easy_pay_u_latam/version.rb +1 -1
  38. metadata +83 -30
@@ -0,0 +1,158 @@
1
+
2
+ var EasyPayULatam = {
3
+ init: function(){
4
+ var module = angular.module('easy_pay_u_latam', ['subscriptions-module']);
5
+
6
+ document.addEventListener("turbolinks:load", function() {
7
+ var element = angular.element(document.querySelector('#easy_pay_u_latam'));
8
+
9
+ var isInitialized = element.injector();
10
+ if (!isInitialized) {
11
+ angular.bootstrap(document.querySelector('#easy_pay_u_latam'), ['easy_pay_u_latam'])
12
+ }
13
+ });
14
+
15
+ $(document).ready(function(){
16
+ var element = angular.element(document.querySelector('#easy_pay_u_latam'));
17
+
18
+ var isInitialized = element.injector();
19
+ if (!isInitialized) {
20
+ angular.bootstrap(document.querySelector('#easy_pay_u_latam'), ['easy_pay_u_latam'])
21
+ }
22
+ });
23
+
24
+ module.directive('httpRequestLoader', ['$http', function($http) {
25
+ return function(scope, element, attrs) {
26
+ scope.html_loader = "<i class='fa-spin fa-2x fas fa-circle-notch active_loader'></i>";
27
+ scope.active_loaders = [];
28
+ scope.isLoading = function() {
29
+ return {
30
+ status: $http.pendingRequests.length > 0,
31
+ requests: $http.pendingRequests
32
+ };
33
+ };
34
+ setInterval(function(){
35
+ scope.$evalAsync(function(){
36
+ var res = scope.isLoading();
37
+ //Verificar loaders ya no existentes
38
+ for (var i = 0; i < scope.active_loaders.length; i++) {
39
+ var loader = scope.active_loaders[i];
40
+ var exists = false;
41
+ for (var j = 0; j < res.requests.length; j++) {
42
+ var req = res.requests[j];
43
+ if (loader.url == req.url){
44
+ exists = true;
45
+ break;
46
+ }
47
+ }
48
+ if (exists == false){
49
+ //NO EXISTE YA LA PETICIÓN EN EL REQUESTS
50
+ //QUITAR DEL HTML
51
+ $(loader.target).find(".active_loader").remove();
52
+ }
53
+ }
54
+
55
+ //Adicionar nuevos loaders
56
+ for (var i = 0; i < res.requests.length; i++) {
57
+ var req = res.requests[i];
58
+ if (req.params != null && req.params._target != null){
59
+ scope.active_loaders.push({url: req.url, target: req.params._target});
60
+ //MOSTRAR LOADER EN HTML
61
+ if ($(req.params._target).find(".active_loader").length == 0){
62
+ $(req.params._target).append(scope.html_loader);
63
+ }
64
+ }
65
+ }
66
+ });
67
+ }, 1000);
68
+ // scope.$watch(scope.isLoading, function(res, $http) {
69
+ // if (res.status){
70
+ // console.log("FINISH LOADING: " + res.requests.length);
71
+ // element.removeClass('ng-hide');
72
+ // }
73
+ // else{
74
+ // console.log("START LOADING: " + res.requests.length);
75
+ // element.addClass('ng-hide');
76
+ // }
77
+ // });
78
+ }
79
+ }]);
80
+
81
+ module.directive("inputCurrency", ["$locale","$filter", function ($locale, $filter) {
82
+
83
+ // For input validation
84
+ var isValid = function(val) {
85
+ return angular.isNumber(val) && !isNaN(val);
86
+ };
87
+
88
+ // Helper for creating RegExp's
89
+ var toRegExp = function(val) {
90
+ var escaped = val.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
91
+ return new RegExp(escaped, 'g');
92
+ };
93
+
94
+ // Saved to your $scope/model
95
+ var toModel = function(val) {
96
+
97
+ // Locale currency support
98
+ var decimal = toRegExp($locale.NUMBER_FORMATS.DECIMAL_SEP);
99
+ var group = toRegExp($locale.NUMBER_FORMATS.GROUP_SEP);
100
+ var currency = toRegExp($locale.NUMBER_FORMATS.CURRENCY_SYM);
101
+
102
+ // Strip currency related characters from string
103
+ val = val.replace(decimal, '').replace(group, '').replace(currency, '').trim();
104
+
105
+ return parseInt(val, 10);
106
+ };
107
+
108
+ // Displayed in the input to users
109
+ var toView = function(val) {
110
+ return $filter('currency')(val, '$', 0);
111
+ };
112
+
113
+ // Link to DOM
114
+ var link = function($scope, $element, $attrs, $ngModel) {
115
+ $ngModel.$formatters.push(toView);
116
+ $ngModel.$parsers.push(toModel);
117
+ $ngModel.$validators.currency = isValid;
118
+
119
+ $element.on('keyup', function() {
120
+ $ngModel.$viewValue = toView($ngModel.$modelValue);
121
+ $ngModel.$render();
122
+ });
123
+ };
124
+
125
+ return {
126
+ restrict: 'A',
127
+ require: 'ngModel',
128
+ link: link
129
+ };
130
+ }]);
131
+
132
+
133
+ module.filter('myCurrency', ['$filter', function ($filter) {
134
+ return function(input) {
135
+ input = parseFloat(input);
136
+
137
+ if(input % 1 === 0) {
138
+ input = input.toFixed(0);
139
+ }
140
+ else {
141
+ input = input.toFixed(2);
142
+ }
143
+
144
+ return '$' + input.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
145
+ };
146
+ }]);
147
+
148
+ module.directive('onLastRepeat', function() {
149
+ return function(scope, element, attrs) {
150
+ if (scope.$last) setTimeout(function(){
151
+ scope.$emit('onRepeatLast', element, attrs);
152
+ }, 1);
153
+ };
154
+ });
155
+
156
+ }
157
+
158
+ }
@@ -0,0 +1,368 @@
1
+ (function () {
2
+ var module = angular.module("subscriptions-module", ['gavruk.card', 'puigcerber.countryPicker', 'ngSanitize']);
3
+
4
+ module.controller('SubscriptionsController', ['$http', '$scope', '$compile', '$rootScope', function ($http, $scope, $compile, $rootScope) {
5
+
6
+ var self = this;
7
+ //Atributos de Planes
8
+ this.actual_plan = null;
9
+ this.selected_plan = null;
10
+ this.plans = [];
11
+
12
+ //Atributos de Subscripciones
13
+ this.subscriptions = [];
14
+ this.subscription_loading = false;
15
+ this.create_subscription_after_new_card = false;
16
+
17
+ //Atributos de Tarjetas
18
+ this.user_default_card = null;
19
+ this.cards = [];
20
+ this.card_loading = false;
21
+
22
+ this.cardPlaceholders = {
23
+ name: 'Nombre...',
24
+ number: 'xxxx xxxx xxxx xxxx',
25
+ expiry: 'MM/YY',
26
+ cvc: 'xxx'
27
+ };
28
+
29
+ this.cardMessages = {
30
+ validDate: 'valid\nthru',
31
+ monthYear: 'MM/YYYY',
32
+ };
33
+
34
+ this.cardOptions = {
35
+ debug: false,
36
+ formatting: true,
37
+ width: 500 //optional
38
+ };
39
+
40
+ this.init = function(uuid, token, plans){
41
+ this.user_uuid = uuid;
42
+ this.user_token = token;
43
+ this.ClearCard();
44
+ this.GetClient();
45
+ //No tengo ni idea porque me toco hacer eso pero sin el timeout simplemente el ng-repeat no renderiza plans
46
+ setTimeout(function(){
47
+ $scope.$evalAsync(function(){
48
+ self.SetPlans(plans);
49
+ });
50
+ }, 100);
51
+
52
+ $('#new-credit-card-modal').on('shown.bs.modal', function () {
53
+ if (self.create_subscription_after_new_card == true){
54
+ swal({
55
+ title: 'Confirmación',
56
+ text: "Cargaremos a tu tarjeta principal mensualmente el valor del plan hasta que canceles la subscripción.",
57
+ type: 'info',
58
+ showCancelButton: true,
59
+ confirmButtonColor: '#3085d6',
60
+ cancelButtonColor: '#d33',
61
+ confirmButtonText: 'Si, continuar',
62
+ cancelButtonText: "Cancelar"
63
+ }).then((result) => {
64
+ if (result) {
65
+ $scope.$evalAsync(function(){
66
+ ('#new-credit-card-modal').modal("show");
67
+ });
68
+ }
69
+ else{
70
+ self.create_subscription_after_new_card = false;
71
+ }
72
+ });
73
+ }
74
+ })
75
+ }
76
+
77
+ //Métodos de Clientes
78
+
79
+ this.GetClient = function(){
80
+ var params = {
81
+ user_email: self.user_uuid,
82
+ user_token: self.user_token
83
+ };
84
+
85
+ $http.post("/easy_pay_u_latam/api/v1/pay_u_clients.json", params).then(
86
+ function(res, status){
87
+ self.GetCards();
88
+ self.GetSubscriptions();
89
+ },
90
+ function(res, status){
91
+ }
92
+ );
93
+ }
94
+
95
+ //Métodos de Tarjetas
96
+
97
+ this.ClearCard = function(){
98
+ this.card = {
99
+ name: '',
100
+ number: '',
101
+ expiry: '',
102
+ cvc: '',
103
+ type: '',
104
+ document: '',
105
+ address: {
106
+ line1: '',
107
+ city: '',
108
+ state: '',
109
+ country: '',
110
+ phone: ''
111
+ }
112
+ };
113
+ }
114
+
115
+ this.GetCards = function(){
116
+ var params = {
117
+ user_email: self.user_uuid,
118
+ user_token: self.user_token
119
+ };
120
+
121
+ $http.get("/easy_pay_u_latam/api/v1/pay_u_cards.json", {params: params}).then(
122
+ function(res, status){
123
+ self.cards = res.data.cards;
124
+ },
125
+ function(res, status){
126
+ }
127
+ );
128
+ }
129
+
130
+ this.GetCardType = function(){
131
+ var card_ele = $(".jp-card").first();
132
+ var classes = card_ele.prop("class");
133
+ this.card.type = classes.split(" ")[1].split("-")[2].toUpperCase();
134
+ if (this.card.type == "IDENTIFIED"){
135
+ this.card.type = classes.split(" ")[2].split("-")[2].toUpperCase();
136
+ }
137
+ }
138
+
139
+ this.CreateCards = function(){
140
+ this.GetCardType();
141
+
142
+ var params = {
143
+ user_email: self.user_uuid,
144
+ user_token: self.user_token,
145
+ card: this.card
146
+ };
147
+
148
+ this.card_loading = true;
149
+
150
+ $http.post("/easy_pay_u_latam/api/v1/pay_u_cards.json", params).then(
151
+ function(res, status){
152
+ self.card_loading = false;
153
+ self.ClearCard();
154
+ self.GetCards();
155
+ $("#new-credit-card-modal").modal("hide");
156
+ swal("¡Excelente!", "¡La tarjeta de crédito creada con éxito!", "success");
157
+
158
+ //Si el usuario seleccinó un plan se crea la subscripción automaticamente
159
+ if (self.create_subscription_after_new_card == true){
160
+ self.CreateSubscription();
161
+ }
162
+ },
163
+ function(res, status){
164
+ self.card_loading = false;
165
+ swal("¡Información!", res.data.message, "error");
166
+ }
167
+ );
168
+ }
169
+
170
+ this.MarkAsPrimaryCard = function(card){
171
+ var params = {
172
+ user_email: self.user_uuid,
173
+ user_token: self.user_token
174
+ };
175
+
176
+ $http.put("/easy_pay_u_latam/api/v1/pay_u_cards/"+card.token+".json", params).then(
177
+ function(res, status){
178
+ self.user_default_card = card.token;
179
+ swal("¡Excelente!", "¡Tarjeta marcada como primaria correctamente!", "success");
180
+ },
181
+ function(res, status){
182
+ swal("¡Información!", res.data.message, "error");
183
+ }
184
+ );
185
+ }
186
+
187
+ this.DeleteCard = function(card){
188
+ swal({
189
+ title: '¿Estás seguro(a)?',
190
+ text: "¡Está acción no se puede deshacer! Siempre puedes volver a adicionar la tarjeta como un nuevo medio de pago.",
191
+ type: 'warning',
192
+ showCancelButton: true,
193
+ confirmButtonColor: '#3085d6',
194
+ cancelButtonColor: '#d33',
195
+ confirmButtonText: 'Si, continuar',
196
+ cancelButtonText: "Cancelar"
197
+ }).then((result) => {
198
+ if (result) {
199
+ $scope.$evalAsync(function(){
200
+ var params = {
201
+ user_email: self.user_uuid,
202
+ user_token: self.user_token
203
+ };
204
+
205
+ $http.delete("/easy_pay_u_latam/api/v1/pay_u_cards/"+card.token+".json", {params: params}).then(
206
+ function(res, status){
207
+ for (var i = 0; i < self.cards.length; i++) {
208
+ if (self.cards[i].token == card.token){
209
+ self.cards.splice(i, 1);
210
+ break;
211
+ }
212
+ }
213
+ swal("¡Información!", "¡La tarjeta de crédito ha sido eliminada con éxito!", "success");
214
+ },
215
+ function(res, status){
216
+ swal("¡Información!", res.data.message, "error");
217
+ }
218
+ );
219
+ });
220
+ }
221
+ });
222
+ }
223
+
224
+ //Métodos de Subscripciones
225
+ this.GetSubscriptions = function(){
226
+ var params = {
227
+ user_email: self.user_uuid,
228
+ user_token: self.user_token
229
+ };
230
+
231
+ $http.get("/easy_pay_u_latam/api/v1/pay_u_subscriptions.json", {params: params}).then(
232
+ function(res, status){
233
+ self.subscriptions = res.data.subscriptions;
234
+ },
235
+ function(res, status){
236
+ }
237
+ );
238
+ }
239
+
240
+ this.IntToDate = function(int){
241
+ var date = new Date(int);
242
+ return date;
243
+ }
244
+
245
+ //Métodos Planes
246
+ this.SetPlans = function(plans){
247
+ this.plans = plans;
248
+ }
249
+
250
+ this.ChangePlan = function(){
251
+ this.selected_plan = null;
252
+ }
253
+
254
+ this.SelectPlan = function(plan){
255
+
256
+ if (this.actual_plan != null && this.actual_plan.id == plan.id){
257
+ swal("Información", "Actualmente estás estas suscrito a este plan.", "info");
258
+ return;
259
+ }
260
+
261
+ swal({
262
+ title: 'Confirmación',
263
+ text: "Cargaremos a tu tarjeta principal mensualmente el valor del plan hasta que canceles la subscripción.",
264
+ type: 'info',
265
+ showCancelButton: true,
266
+ confirmButtonColor: '#3085d6',
267
+ cancelButtonColor: '#d33',
268
+ confirmButtonText: 'Si, continuar',
269
+ cancelButtonText: "Cancelar"
270
+ }).then((result) => {
271
+ if (result) {
272
+ $scope.$evalAsync(function(){
273
+ self.selected_plan = plan;
274
+
275
+ if (self.cards.length > 0){
276
+ //Crear suscripcion
277
+ self.CreateSubscription();
278
+ }
279
+ else{
280
+ //Pedir creación de tarjeta (Abrir modal)
281
+ //Luego Crear suscripcion en el callback del create
282
+ self.create_subscription_after_new_card = true;
283
+ $("#new-credit-card-modal").modal("show");
284
+ }
285
+ });
286
+ }
287
+ });
288
+
289
+ }
290
+
291
+ //Métodos Subscripciones
292
+ this.CreateSubscription = function(){
293
+ var params = {
294
+ user_email: self.user_uuid,
295
+ user_token: self.user_token,
296
+ subscription: {
297
+ quantity: "1",
298
+ installments: "1",
299
+ trialDays: "15",
300
+ customer: {
301
+ id: "",
302
+ creditCards: [
303
+ {
304
+ token: ""
305
+ }
306
+ ]
307
+ },
308
+ plan: {
309
+ planCode: this.selected_plan.payu_plan_code
310
+ }
311
+ }
312
+ };
313
+
314
+ this.subscription_loading = true;
315
+
316
+ $http.post("/easy_pay_u_latam/api/v1/pay_u_subscriptions.json", params).then(
317
+ function(res, status){
318
+ self.subscription_loading = false;
319
+ //Mirar si se muestra alerta y se fuerza un refresh
320
+ //O recirbir respuesta json y actualizar variables necesarias desde el API
321
+ },
322
+ function(res, status){
323
+ self.subscription_loading = false;
324
+ }
325
+ );
326
+ }
327
+
328
+ this.DeleteSubscription = function(){
329
+ swal({
330
+ title: 'Confirmación',
331
+ text: "Volverás al plan Grátis una vez se caduque el plan que tenías.",
332
+ type: 'info',
333
+ showCancelButton: true,
334
+ confirmButtonColor: '#3085d6',
335
+ cancelButtonColor: '#d33',
336
+ confirmButtonText: 'Si, continuar',
337
+ cancelButtonText: "Cancelar"
338
+ }).then((result) => {
339
+ if (result) {
340
+ $scope.$evalAsync(function(){
341
+ var params = {
342
+ user_email: self.user_uuid,
343
+ user_token: self.user_token
344
+ };
345
+
346
+ this.subscription_loading = true;
347
+
348
+ $http.delete("/easy_pay_u_latam/api/v1/pay_u_subscriptions/0000.json", {params: params}).then(
349
+ function(res, status){
350
+ self.subscription_loading = false;
351
+ //Mirar si se muestra alerta y se fuerza un refresh
352
+ //O recirbir respuesta json y actualizar variables necesarias desde el API
353
+ },
354
+ function(res, status){
355
+ self.subscription_loading = false;
356
+ }
357
+ );
358
+ });
359
+ }
360
+ });
361
+ }
362
+
363
+ // $scope.$on("StartChangeUnit", function(event, args) {
364
+ // self.row = args.row;
365
+ // });
366
+
367
+ }]);
368
+ })();