easy_pay_u_latam 0.1.15 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ })();