djgentelella 0.4.30__py3-none-any.whl → 0.5.1__py3-none-any.whl

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 (66) hide show
  1. djgentelella/__init__.py +4 -1
  2. djgentelella/admin.py +41 -2
  3. djgentelella/firmador_digital/consumers/sign.py +24 -3
  4. djgentelella/firmador_digital/forms.py +140 -0
  5. djgentelella/firmador_digital/models.py +19 -24
  6. djgentelella/firmador_digital/utils.py +11 -0
  7. djgentelella/firmador_digital/views.py +31 -0
  8. djgentelella/firmador_digital/viewsets.py +15 -4
  9. djgentelella/forms/forms.py +10 -2
  10. djgentelella/groute.py +4 -1
  11. djgentelella/history/api.py +145 -0
  12. djgentelella/history/filterset.py +23 -0
  13. djgentelella/history/serializers.py +50 -0
  14. djgentelella/history/utils.py +70 -0
  15. djgentelella/locale/es/LC_MESSAGES/django.mo +0 -0
  16. djgentelella/locale/es/LC_MESSAGES/django.po +105 -0
  17. djgentelella/locale/es/LC_MESSAGES/djangojs.mo +0 -0
  18. djgentelella/locale/es/LC_MESSAGES/djangojs.po +46 -0
  19. djgentelella/migrations/0014_trash.py +31 -0
  20. djgentelella/migrations/0015_trash_deleted_by.py +21 -0
  21. djgentelella/migrations/0016_trash_created_at.py +20 -0
  22. djgentelella/migrations/0017_alter_chunkedupload_status.py +18 -0
  23. djgentelella/migrations/0018_alter_chunkedupload_status.py +18 -0
  24. djgentelella/models.py +97 -0
  25. djgentelella/models_manager.py +40 -0
  26. djgentelella/serializers/firmador_digital.py +9 -1
  27. djgentelella/serializers/selects.py +14 -0
  28. djgentelella/static/djgentelella.readonly.vendors.min.css +9 -5
  29. djgentelella/static/djgentelella.readonly.vendors.min.js +1 -1
  30. djgentelella/static/gentelella/css/custom.css +23 -2
  31. djgentelella/static/gentelella/css/modern.css +15 -0
  32. djgentelella/static/gentelella/css/modern_black_white.css +15 -0
  33. djgentelella/static/gentelella/css/pdfviewer.css +43 -1
  34. djgentelella/static/gentelella/images/default.png +0 -0
  35. djgentelella/static/gentelella/js/base/digital_signature.js +318 -79
  36. djgentelella/static/gentelella/js/base/form.common.js +9 -4
  37. djgentelella/static/gentelella/js/base/select2_wrap.js +15 -1
  38. djgentelella/static/gentelella/js/base/select2related.js +5 -0
  39. djgentelella/static/gentelella/js/base.js +347 -83
  40. djgentelella/static/gentelella/js/custom.js +6 -1
  41. djgentelella/static/gentelella/js/datatables.js +15 -0
  42. djgentelella/static/gentelella/js/digital_signature_update.js +29 -0
  43. djgentelella/static/gentelella/js/obj_api_management.js +403 -344
  44. djgentelella/static/gentelella/js/widgets.js +10 -1
  45. djgentelella/static/vendors/timeline/css/timeline.css +9 -5
  46. djgentelella/static/vendors/timeline/js/timeline.js +1 -1
  47. djgentelella/templates/forms/as_grid.html +2 -2
  48. djgentelella/templates/forms/as_inline.html +3 -5
  49. djgentelella/templates/gentelella/app/sidebar.html +16 -13
  50. djgentelella/templates/gentelella/digital_signature/update_signature_settings.html +45 -0
  51. djgentelella/templates/gentelella/registration/reset_done.html +24 -0
  52. djgentelella/templates/gentelella/widgets/digital_signature.html +47 -11
  53. djgentelella/trash/api.py +77 -0
  54. djgentelella/trash/filterset.py +20 -0
  55. djgentelella/trash/serializer.py +45 -0
  56. djgentelella/urls.py +13 -2
  57. djgentelella/views/select2autocomplete.py +40 -0
  58. djgentelella/widgets/core.py +6 -5
  59. djgentelella/widgets/digital_signature.py +5 -21
  60. djgentelella/widgets/selects.py +47 -0
  61. {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/METADATA +2 -2
  62. {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/RECORD +66 -48
  63. {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/AUTHORS +0 -0
  64. {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/LICENSE.txt +0 -0
  65. {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/WHEEL +0 -0
  66. {djgentelella-0.4.30.dist-info → djgentelella-0.5.1.dist-info}/top_level.txt +0 -0
@@ -553,6 +553,11 @@ function extract_select2_context(context, instance){
553
553
  }else{
554
554
  context.theme='bootstrap-5'
555
555
  }
556
+ let template = data.templateresult;
557
+ if(template != undefined){
558
+ context.templateResult=window[template];
559
+ context.templateSelection=window[template];
560
+ }
556
561
  }
557
562
 
558
563
  function add_selected_option(item, data){
@@ -828,7 +833,10 @@ function clear_action_form(form) {
828
833
  });
829
834
  $(form).find('[data-widget="TaggingInput"],[data-widget="EmailTaggingInput"]').each(function (i, e) {
830
835
  var tg = $(e).data().tagify;
831
- tg.removeAllTags();
836
+ if(tg != undefined){
837
+ tg.removeAllTags();
838
+ }
839
+
832
840
  });
833
841
  $(form).find('[data-widget="FileChunkedUpload"],[data-widget="FileInput"]').each(function (i, e) {
834
842
  var tg = $(e).data().fileUploadWidget;
@@ -909,9 +917,11 @@ function updateInstanceValuesForm(form, name, value) {
909
917
  }
910
918
  if (inputfield.data().widget === "TaggingInput" || inputfield.data().widget === "EmailTaggingInput") {
911
919
  var tagifyelement = inputfield.data().tagify;
912
- tagifyelement.removeAllTags();
913
- tagifyelement.loadOriginalValues(value);
914
- done = true;
920
+ if(tagifyelement!=undefined){
921
+ tagifyelement.removeAllTags();
922
+ tagifyelement.loadOriginalValues(value);
923
+ }
924
+ done = false;
915
925
  }
916
926
 
917
927
 
@@ -1529,6 +1539,21 @@ function decore_select2 (data) {
1529
1539
  return $wrapper;
1530
1540
  }
1531
1541
 
1542
+ function decore_img_select2 (data) {
1543
+ if(!data.url && data.text){
1544
+ return $('<span>'+data.text+'</span>');
1545
+ }
1546
+ if (!data.url) {
1547
+ return "";
1548
+ }
1549
+ let img_width = "2em"; let img_height="2em;";
1550
+ if(data.img_width != undefined){img_width=data.img_width;}
1551
+ if(data.img_height != undefined){ img_height=data.img_height; }
1552
+ var $state = $('<span><img style="width: '+img_width+'; height: '+img_height+';" src="' + data.url+ '" class="img-flag" /> ' + data.text + '</span>');
1553
+ return $state;
1554
+ };
1555
+
1556
+
1532
1557
  function load_date_range(instance, format='DD/MM/YYYY') {
1533
1558
  var options = {
1534
1559
  'autoUpdateInput': false,
@@ -2251,17 +2276,43 @@ function getMediaRecord(element, mediatype){
2251
2276
  ///////////////////////////////////////////////
2252
2277
  // Init widgets digital signature
2253
2278
  ///////////////////////////////////////////////
2279
+ var socket_connections = {};
2280
+ var socket_manager_instances = {};
2281
+ const max_close_inicialice = 5;
2282
+ var count_close_inicialice = 0;
2283
+
2284
+ // Configuración del MutationObserver
2285
+ const observer = new MutationObserver((mutations) => {
2286
+ mutations.forEach((mutation) => {
2287
+ if (mutation.type === 'attributes' && mutation.attributeName === 'data-port') {
2288
+ let port = mutation.target.getAttribute('data-port');
2289
+ mutation.target.setAttribute("href",
2290
+ "firmador:" + window.location.protocol + "//" + window.location.host + "#" + port);
2291
+ }
2292
+ });
2293
+ });
2294
+
2295
+ build_cors_headers = function (instance) {
2296
+ let port = instance.getAttribute('data-port');
2297
+ instance.setAttribute("href", "firmador:" + window.location.protocol + "//" + window.location.host + "#" + port);
2298
+ observer.observe(instance, {attributes: true});
2299
+ }
2300
+
2301
+ build_ws_url = function (base) {
2302
+ return base;
2303
+ }
2304
+
2254
2305
  build_digital_signature = function (instance) {
2255
2306
 
2256
2307
  const widgetId = instance.getAttribute("id");
2257
- const url_ws = instance.getAttribute("data-ws-url");
2308
+ const url_ws = build_ws_url(instance.getAttribute("data-ws-url"));
2258
2309
  const container = instance.closest(".widget-digital-signature");
2259
2310
  const container_tag = `container-${widgetId}`;
2260
2311
  const doc_instance = {
2261
- "pk": instance.getAttribute("data-pk"),
2262
- "cc": instance.getAttribute("data-cc"),
2263
- "value": instance.getAttribute("data-value")
2264
- }
2312
+ "pk": instance.getAttribute("data-pk"),
2313
+ "cc": instance.getAttribute("data-cc"),
2314
+ "value": instance.getAttribute("data-value")
2315
+ }
2265
2316
  const urls = {
2266
2317
  "logo": instance.getAttribute("data-logo"),
2267
2318
  "sign_doc": instance.getAttribute("data-renderurl"),
@@ -2280,8 +2331,17 @@ build_digital_signature = function (instance) {
2280
2331
  return;
2281
2332
  }
2282
2333
 
2334
+ //Custom Event
2335
+ const event = new CustomEvent("document:signed", {
2336
+ bubbles: true, // Important for global handlers
2337
+ detail: {
2338
+ message: "Signed document",
2339
+ instance: doc_instance,
2340
+ }
2341
+ });
2342
+
2283
2343
  // Signature
2284
- let signatureManager = new SignatureManager(widgetId, container, url_ws, pdfInstance);
2344
+ let signatureManager = new SignatureManager(widgetId, container, url_ws, pdfInstance, event);
2285
2345
  signatureManager.startSign(doc_instance, urls['logo']);
2286
2346
 
2287
2347
  // Store the instance in a global object with key per widget ID
@@ -2294,6 +2354,7 @@ build_digital_signature = function (instance) {
2294
2354
  window.pdfSignatureComponents[container_tag] = pdfInstance;
2295
2355
  }
2296
2356
 
2357
+
2297
2358
  }
2298
2359
 
2299
2360
  ///////////////////////////////////////////////
@@ -2304,8 +2365,8 @@ class PdfSignatureComponent {
2304
2365
  this.container = container;
2305
2366
  this.defaultPage = defaultPage;
2306
2367
  this.widgetId = container.getAttribute("data-widget-id");
2307
- this.urls=urls;
2308
- this.doc_instance=doc_instance;
2368
+ this.urls = urls;
2369
+ this.doc_instance = doc_instance;
2309
2370
 
2310
2371
  // Internal elements
2311
2372
  this.signature = container.querySelector('.signature');
@@ -2314,8 +2375,13 @@ class PdfSignatureComponent {
2314
2375
  this.btn_next = container.querySelector('.next');
2315
2376
  this.page_num = container.querySelector('.page_num');
2316
2377
  this.page_number = container.querySelector('.page_number');
2378
+ this.btn_expand = container.querySelector('.btn_expand');
2317
2379
  this.page_count = container.querySelector('.page_count');
2318
2380
  this.sub_canvas_container = container.querySelector('.sub_canvas_container');
2381
+ this.pdfSignatureContainer = container.querySelector('.pdf-signature-container');
2382
+ this.digitalSignatureCard = container.querySelector('.digital-signature-card');
2383
+ this.btns_expand = container.querySelector('.container_select_card_expanded');
2384
+ this.expandHelpMessage = container.querySelector('.expand-help-message');
2319
2385
 
2320
2386
  // Verify that all required elements are present
2321
2387
  if (!this.signature || !this.canvas || !this.btn_prev || !this.btn_next || !this.page_num || !this.page_number || !this.page_count || !this.sub_canvas_container) {
@@ -2333,6 +2399,7 @@ class PdfSignatureComponent {
2333
2399
  this.signY = 198;
2334
2400
  this.signWidth = 133;
2335
2401
  this.signHeight = 133;
2402
+ this.expanded = false;
2336
2403
 
2337
2404
  // Initializes the processes
2338
2405
  this.initEvents();
@@ -2347,6 +2414,7 @@ class PdfSignatureComponent {
2347
2414
  this.btn_next.addEventListener('click', () => this.onNextPage());
2348
2415
  this.page_number.addEventListener('change', (e) => this.renderPage(e.target.value));
2349
2416
  this.page_number.addEventListener('keyup', (e) => this.renderPage(e.target.value));
2417
+ this.btn_expand.addEventListener('click', () => this.expand());
2350
2418
  }
2351
2419
 
2352
2420
  initPDFViewer() {
@@ -2355,7 +2423,7 @@ class PdfSignatureComponent {
2355
2423
  console.warn("The variable 'sign_doc' is not defined.");
2356
2424
  return;
2357
2425
  }
2358
- pdfjsLib.getDocument(this.urls['sign_doc']+"?"+this.urls['renderattr']).promise.then((pdfDoc_) => {
2426
+ pdfjsLib.getDocument(this.urls['sign_doc'] + "?" + this.urls['renderattr']).promise.then((pdfDoc_) => {
2359
2427
  this.pdfDoc = pdfDoc_;
2360
2428
  this.page_count.textContent = pdfDoc_.numPages;
2361
2429
 
@@ -2399,6 +2467,44 @@ class PdfSignatureComponent {
2399
2467
  }
2400
2468
  }
2401
2469
 
2470
+ expand() {
2471
+ this.expanded = !this.expanded;
2472
+ if (this.expanded) {
2473
+ this.pdfSignatureContainer.classList.add('expanded-viewer');
2474
+ this.sub_canvas_container.classList.add('expanded-canvas-container');
2475
+ this.digitalSignatureCard.classList.add('hide');
2476
+ this.expandHelpMessage.classList.add('hide');
2477
+ this.btns_expand.classList.remove('hide');
2478
+
2479
+ requestAnimationFrame(() => {
2480
+ this.adjustScaleToContainer().then(() => {
2481
+ this.renderPage(this.pageNum);
2482
+ this.sub_canvas_container.scrollTop = (this.canvas.height / 2) - (this.sub_canvas_container.clientHeight / 2);
2483
+ });
2484
+ });
2485
+ } else {
2486
+ this.pdfSignatureContainer.classList.remove('expanded-viewer');
2487
+ this.sub_canvas_container.classList.remove('expanded-canvas-container');
2488
+ this.digitalSignatureCard.classList.remove('hide');
2489
+ this.expandHelpMessage.classList.remove('hide');
2490
+ this.btns_expand.classList.add('hide');
2491
+ this.scale = 1.2;
2492
+ this.renderPage(this.pageNum);
2493
+ }
2494
+
2495
+
2496
+ }
2497
+
2498
+ adjustScaleToContainer() {
2499
+ return this.pdfDoc.getPage(this.pageNum).then((page) => {
2500
+ const containerWidth = Math.min(this.sub_canvas_container.offsetWidth, 1200);
2501
+ const viewport = page.getViewport({scale: 1});
2502
+ let nextScale = (containerWidth * 0.95) / viewport.width;
2503
+ this.scale = Math.min(nextScale, 2.0);
2504
+ });
2505
+ }
2506
+
2507
+
2402
2508
  renderPage(num) {
2403
2509
  this.pageRendering = true;
2404
2510
  this.pdfDoc.getPage(num).then((page) => {
@@ -2571,7 +2677,7 @@ class PdfSignatureComponent {
2571
2677
  return tempSignature;
2572
2678
  }
2573
2679
 
2574
- // If required, you can define a method for loading an image
2680
+ // If required, you can define a method for loading an image
2575
2681
  loadSignatureImage(signatureImage, imageContainer) {
2576
2682
  return new Promise((resolve, reject) => {
2577
2683
  if (!signatureImage) {
@@ -2617,14 +2723,14 @@ class PdfSignatureComponent {
2617
2723
  // Signature manager Digital Signature
2618
2724
  ///////////////////////////////////////////////
2619
2725
  class SignatureManager {
2620
- constructor(input_id, container, url_ws, pdfvisor) {
2621
- this.input_id=input_id;
2726
+ constructor(input_id, container, url_ws, pdfvisor, custom_event) {
2727
+ this.input_id = input_id;
2622
2728
  this.container = container;
2623
2729
  this.modal = new bootstrap.Modal(container.querySelector("#loading_sign"));
2624
- this.firmador = new DocumentClient(container, container.getAttribute("data-widget-id"), this, url_ws, this.doc_instance);
2625
- this.signerBtn = container.querySelector(".btn_signer");
2730
+ this.firmador = new DocumentClient(container, container.getAttribute("data-widget-id"), this, url_ws, custom_event, this.doc_instance);
2731
+ this.signerBtn = container.querySelectorAll(".btn_signer");
2626
2732
  this.errorsContainer = container.querySelector(".errors_signer");
2627
- this.refreshBtn = container.querySelector(".btn_signer_refresh");
2733
+ this.refreshBtn = container.querySelectorAll(".btn_signer_refresh");
2628
2734
  this.socketError = false;
2629
2735
  this.pdfvisor = pdfvisor;
2630
2736
 
@@ -2632,11 +2738,15 @@ class SignatureManager {
2632
2738
  }
2633
2739
 
2634
2740
  initEvents() {
2635
- if (this.signerBtn) {
2636
- this.signerBtn.addEventListener('click', () => this.sign());
2741
+ if (this.signerBtn && this.signerBtn.length) {
2742
+ this.signerBtn.forEach(btn => {
2743
+ btn.addEventListener('click', () => this.sign());
2744
+ });
2637
2745
  }
2638
- if (this.refreshBtn) {
2639
- this.refreshBtn.addEventListener('click', () => this.refresh());
2746
+ if (this.refreshBtn && this.refreshBtn.length) {
2747
+ this.refreshBtn.forEach(btn => {
2748
+ btn.addEventListener('click', () => this.refresh());
2749
+ });
2640
2750
  }
2641
2751
  }
2642
2752
 
@@ -2725,25 +2835,83 @@ function responseManageTypeData(instance, err_json_fn, error_text_fn) {
2725
2835
  }
2726
2836
  }
2727
2837
 
2728
- function SocketManager(socket, signatureManager) {
2729
- // If an error occurs during the connection
2730
- socket.onerror = (event) => {
2731
- // console.error("WebSocket error");
2732
- signatureManager.hideLoading();
2733
- alertSimple(errorInterpreter(3), gettext("Error"), "error");
2734
- signatureManager.socketError = true;
2735
- };
2838
+ class SocketManager {
2839
+ constructor(url, signatureManager, instance) {
2840
+ this.url = url;
2841
+ this.signatureManager = signatureManager;
2842
+ this.instance = instance;
2736
2843
 
2737
- // If the connection is closed
2738
- socket.onclose = (event) => {
2739
- // console.warn("WebSocket cerrado");
2740
- };
2844
+ this.connect();
2845
+ }
2741
2846
 
2742
- // If the connection is opened
2743
- socket.onopen = (event) => {
2744
- // console.log("WebSocket conectado");
2745
- signatureManager.socket_error = false;
2746
- };
2847
+ connect() {
2848
+ socket_manager_instances[this.instance.socket_id] = this.instance;
2849
+ if (!socket_connections.hasOwnProperty(this.url)) {
2850
+ let ws = new WebSocket(this.url);
2851
+ ws.onerror = this.fn_error(this);
2852
+ ws.onclose = this.fn_close(this);
2853
+ ws.onopen = this.fn_open(this);
2854
+ ws.onmessage = this.fn_messages(this);
2855
+ socket_connections[this.url] = ws;
2856
+ }
2857
+ }
2858
+
2859
+ fn_error(element) {
2860
+ return (event) => {
2861
+ // console.error("WebSocket error");
2862
+ element.signatureManager.hideLoading();
2863
+ alertSimple(errorInterpreter(3), gettext("Error"), "error");
2864
+ element.signatureManager.socketError = true;
2865
+ }
2866
+ }
2867
+
2868
+ fn_close(element) {
2869
+ return (event) => {
2870
+ console.warn("WebSocket cerrado " + event.type);
2871
+ Reflect.deleteProperty(socket_connections, event.currentTarget.url);
2872
+ if (count_close_inicialice < max_close_inicialice) {
2873
+ count_close_inicialice += 1;
2874
+ element.instance.inicialize();
2875
+ }
2876
+ };
2877
+ }
2878
+
2879
+ fn_open(element) {
2880
+ return (event) => {
2881
+ // console.log("WebSocket conectado");
2882
+ element.signatureManager.socket_error = false;
2883
+ count_close_inicialice = 0;
2884
+ };
2885
+ }
2886
+
2887
+ fn_messages(element) {
2888
+ return (event) => {
2889
+ try {
2890
+ const data = JSON.parse(event.data);
2891
+ if (data.hasOwnProperty("socket_id") && socket_manager_instances.hasOwnProperty(data["socket_id"])) {
2892
+ socket_manager_instances[data["socket_id"]].receive_json(data);
2893
+ } else {
2894
+ console.error("Socket id not found");
2895
+ }
2896
+ } catch (err) {
2897
+ console.error("Error al parsear mensaje WS:", err);
2898
+ }
2899
+ };
2900
+ }
2901
+
2902
+ send(str) {
2903
+ if (!socket_connections.hasOwnProperty(this.url)) {
2904
+ this.connect();
2905
+ } else {
2906
+ if (socket_connections[this.url].readyState != WebSocket.OPEN) {
2907
+ Reflect.deleteProperty(socket_connections, this.url);
2908
+ this.connect();
2909
+ }
2910
+ }
2911
+ if (socket_connections.hasOwnProperty(this.url)) {
2912
+ socket_connections[this.url].send(str);
2913
+ }
2914
+ }
2747
2915
  }
2748
2916
 
2749
2917
  function callFetch(instance) {
@@ -2795,6 +2963,9 @@ function FirmadorLibreLocal(docmanager, signatureManager) {
2795
2963
  callFetch(instance);
2796
2964
  },
2797
2965
  "sign": function (data) {
2966
+ if (data.hasOwnProperty("socket_id")) {
2967
+ Reflect.deleteProperty(data, "socket_id");
2968
+ }
2798
2969
  let json = JSON.stringify(data);
2799
2970
  let manager = docmanager;
2800
2971
 
@@ -2835,21 +3006,16 @@ function FirmadorLibreLocal(docmanager, signatureManager) {
2835
3006
  }
2836
3007
  }
2837
3008
 
3009
+ const generateRandomString = () => {
3010
+ return Math.floor(Math.random() * Date.now()).toString(36);
3011
+ };
3012
+
2838
3013
  function FirmadorLibreWS(docmanager, url, signatureManager) {
2839
3014
  var firmador = {
2840
3015
  "url": url,
2841
3016
  "websocket": null,
2842
3017
  "firmador_url": "http://localhost:3516",
2843
- "trans_received": function (instance) {
2844
- return function (event) {
2845
- try {
2846
- const data = JSON.parse(event.data);
2847
- instance.receive_json(data);
2848
- } catch (err) {
2849
- console.error("Error al parsear mensaje WS:", err);
2850
- }
2851
- };
2852
- },
3018
+ "socket_id": generateRandomString(),
2853
3019
  "receive_json": function (data) {
2854
3020
  // validate socket errors
2855
3021
  if (data.result === false && data.error) {
@@ -2901,11 +3067,13 @@ function FirmadorLibreWS(docmanager, url, signatureManager) {
2901
3067
  break;
2902
3068
  }
2903
3069
  }
2904
- }else{
3070
+ } else {
2905
3071
 
2906
- if(data.hasOwnProperty('tobesigned')){
3072
+ if (data.hasOwnProperty('report')) {
3073
+ docmanager.validate_document_remote_done(data['report']);
3074
+ } else if (data.hasOwnProperty('tobesigned')) {
2907
3075
  docmanager.do_sign_local(data);
2908
- }else{
3076
+ } else {
2909
3077
  docmanager.remote_done(data)
2910
3078
  }
2911
3079
 
@@ -2913,15 +3081,15 @@ function FirmadorLibreWS(docmanager, url, signatureManager) {
2913
3081
  },
2914
3082
 
2915
3083
  "inicialize": function () {
2916
- this.websocket = new WebSocket(url);
2917
- SocketManager(this.websocket, signatureManager);
2918
- this.websocket.onmessage = this.trans_received(this);
3084
+ this.websocket = new SocketManager(url, signatureManager, this);
3085
+
2919
3086
  },
2920
3087
  "local_done": function (data) {
2921
3088
  // console.log("local_done", data);
2922
3089
  },
2923
3090
  "sign": function (data) {
2924
3091
  data["action"] = "initial_signature";
3092
+ data["socket_id"] = this.socket_id;
2925
3093
  if (data.card !== undefined) {
2926
3094
  this.websocket.send(JSON.stringify(data));
2927
3095
  signatureManager.showLoading();
@@ -2932,7 +3100,7 @@ function FirmadorLibreWS(docmanager, url, signatureManager) {
2932
3100
  },
2933
3101
  "complete_sign": function (data) {
2934
3102
  data["action"] = "complete_signature";
2935
-
3103
+ data["socket_id"] = this.socket_id;
2936
3104
  try {
2937
3105
  this.websocket.send(JSON.stringify(data));
2938
3106
  } catch (e) {
@@ -2941,12 +3109,24 @@ function FirmadorLibreWS(docmanager, url, signatureManager) {
2941
3109
  alertFunction(errorInterpreter(3), gettext("Error"), "error", false, closeModalSignature);
2942
3110
  }
2943
3111
  },
3112
+
3113
+ "validate_document": function (data) {
3114
+ data["action"] = "validate_document";
3115
+ data["socket_id"] = this.socket_id;
3116
+ signatureManager.showLoading();
3117
+ try {
3118
+ this.websocket.send(JSON.stringify(data));
3119
+ } catch (e) {
3120
+ signatureManager.hideLoading();
3121
+ alertFunction(errorInterpreter(3), gettext("Error"), "error", false, closeModalSignature);
3122
+ }
3123
+ }
2944
3124
  };
2945
3125
  firmador.inicialize();
2946
3126
  return firmador;
2947
3127
  }
2948
3128
 
2949
- function DocumentClient(container, widgetId, signatureManager, url_ws) {
3129
+ function DocumentClient(container, widgetId, signatureManager, url_ws, custom_event) {
2950
3130
  const docmanager = {
2951
3131
  "widgetId": widgetId,
2952
3132
  "container": container,
@@ -2956,6 +3136,7 @@ function DocumentClient(container, widgetId, signatureManager, url_ws) {
2956
3136
  "certificates": null,
2957
3137
  "doc_instance": null,
2958
3138
  "logo_url": null,
3139
+ "custom_event": custom_event,
2959
3140
 
2960
3141
  "start_sign": function (doc_instance, logo_url = null) {
2961
3142
  this.doc_instance = doc_instance;
@@ -2964,37 +3145,49 @@ function DocumentClient(container, widgetId, signatureManager, url_ws) {
2964
3145
  this.signatureManager.clearErrors();
2965
3146
  },
2966
3147
  "success_certificates": function (data) {
2967
-
2968
3148
  if (data.length > 0) {
2969
- container.querySelector("#container_select_card").classList.remove("d-none");
2970
- container.querySelector("#container_select_card_tem").classList.add("d-none");
2971
-
2972
- let select_card = container.querySelector(".select_card");
3149
+ container.querySelectorAll("#container_select_card, #container_select_card_expanded_hide").forEach(el => {
3150
+ el.classList.remove("d-none");
3151
+ el.classList.remove("hide");
3152
+ });
3153
+ container.querySelectorAll("#container_select_card_tem").forEach(el => {
3154
+ el.classList.add("d-none");
3155
+ el.classList.add("hide");
3156
+ });
2973
3157
 
2974
- if (!select_card) {
3158
+ let select_cards = container.querySelectorAll(".select_card");
3159
+ if (!select_cards.length) {
2975
3160
  console.error(`Select not found for widget ${widgetId}`);
2976
3161
  return;
2977
3162
  }
2978
- select_card.innerHTML = "";
2979
3163
  this.certificates = {};
2980
-
2981
- data.forEach((element) => {
2982
- this.certificates[element.tokenSerialNumber] = element;
2983
- let start_token = element.tokenSerialNumber.substring(0, 4);
2984
- let newOption = new Option(
2985
- `${start_token} ${element.commonName}`,
2986
- element.tokenSerialNumber,
2987
- false, false
2988
- );
2989
- select_card.appendChild(newOption);
3164
+ select_cards.forEach(select_card => {
3165
+ select_card.innerHTML = "";
3166
+ data.forEach((element) => {
3167
+ this.certificates[element.tokenSerialNumber] = element;
3168
+ let start_token = element.tokenSerialNumber.substring(0, 4);
3169
+ let newOption = new Option(
3170
+ `${start_token} ${element.commonName}`,
3171
+ element.tokenSerialNumber,
3172
+ false, false
3173
+ );
3174
+ select_card.appendChild(newOption);
3175
+ });
2990
3176
  });
2991
3177
  } else {
2992
- container.querySelector("#container_select_card").classList.add("d-none");
2993
- container.querySelector("#container_select_card_tem").classList.remove("d-none");
3178
+ container.querySelectorAll("#container_select_card, #container_select_card_expanded_hide").forEach(el => {
3179
+ el.classList.add("d-none");
3180
+ el.classList.add("hide");
3181
+ });
3182
+ container.querySelectorAll("#container_select_card_tem").forEach(el => {
3183
+ el.classList.remove("d-none");
3184
+ el.classList.remove("hide");
3185
+ });
2994
3186
  this.signatureManager.addError(2);
2995
3187
  }
2996
3188
  },
2997
3189
 
3190
+
2998
3191
  "do_sign_remote": function () {
2999
3192
  let select = container.querySelector(".select_card");
3000
3193
  let selected_card = select ? select.value : null;
@@ -3018,6 +3211,7 @@ function DocumentClient(container, widgetId, signatureManager, url_ws) {
3018
3211
  }
3019
3212
 
3020
3213
  },
3214
+
3021
3215
  "do_sign_local": function (data) {
3022
3216
  this.localsigner.sign(data);
3023
3217
  },
@@ -3027,21 +3221,91 @@ function DocumentClient(container, widgetId, signatureManager, url_ws) {
3027
3221
  this.remotesigner.complete_sign(data);
3028
3222
  },
3029
3223
  "remote_done": function (data) {
3030
- if(data.result !== null ){
3224
+ if (data.result !== null) {
3031
3225
  const l = btoa(JSON.stringify({'token': data.result}));
3032
- this.signatureManager.doc_instance['value'] =l;
3033
- this.signatureManager.pdfvisor.urls['renderattr']="value="+l;
3034
- document.getElementById(this.signatureManager.input_id).value=l;
3226
+ this.signatureManager.doc_instance['value'] = l;
3227
+ this.signatureManager.pdfvisor.urls['renderattr'] = "value=" + l;
3228
+ document.getElementById(this.signatureManager.input_id).value = l;
3035
3229
  this.signatureManager.pdfvisor.initPDFViewer();
3036
3230
  signatureManager.hideLoading();
3231
+ document.dispatchEvent(this.custom_event);
3037
3232
  alertFunction(
3038
3233
  gettext("The signing was successfully completed."),
3039
3234
  gettext("Success"),
3040
- "success", false, function(){}
3235
+ "success", false, function () {
3236
+ }
3041
3237
  );
3042
- }
3238
+ }
3043
3239
  },
3044
3240
 
3241
+ "validate_document_remote": function () {
3242
+ data = {
3243
+ "instance": this.doc_instance,
3244
+ }
3245
+ document.dispatchEvent(this.custom_event);
3246
+ //this.remotesigner.validate_document(data);
3247
+ },
3248
+
3249
+ "validate_document_remote_done": function (reportData) {
3250
+ signatureManager.hideLoading();
3251
+ if (!reportData || typeof reportData !== 'string') {
3252
+ alertFunction(
3253
+ gettext("Please, sign the document before saving"),
3254
+ gettext("Warning"),
3255
+ "warning", false, function () {
3256
+ }
3257
+ );
3258
+ return;
3259
+ }
3260
+
3261
+ if (reportData.includes("no est&aacute; firmado digitalmente")) {
3262
+ alertFunction(
3263
+ gettext("The document is not digitally signed. Please sign the document before saving."),
3264
+ gettext("Warning"),
3265
+ "warning", false,
3266
+ function () {
3267
+ }
3268
+ );
3269
+ return;
3270
+ }
3271
+
3272
+ const firmasMatch = reportData.match(/Contiene\s*([\d]+)\s*firma/);
3273
+ let numFirmas = 0;
3274
+ if (firmasMatch && firmasMatch[1]) {
3275
+ numFirmas = parseInt(firmasMatch[1], 10);
3276
+ }
3277
+
3278
+ if (numFirmas > 0) {
3279
+ if (typeof update_signed_document === "function") {
3280
+ update_signed_document(this.doc_instance);
3281
+ } else {
3282
+ console.log("warning: update_signed_document function not defined, using default action");
3283
+ alertFunction(
3284
+ gettext(`The document was saved`),
3285
+ gettext("Success"),
3286
+ "success", false,
3287
+ function () {
3288
+ const container = this.signatureManager.container;
3289
+ const form = container.closest('form');
3290
+ if (form) {
3291
+ form.submit();
3292
+ }
3293
+ }.bind(this)
3294
+ );
3295
+ }
3296
+
3297
+ } else {
3298
+ alertFunction(
3299
+ gettext("The document is not digitally signed. Please sign the document before saving."),
3300
+ gettext("Warning"),
3301
+ "warning", false,
3302
+ function () {
3303
+ }
3304
+ );
3305
+ }
3306
+ }
3307
+
3308
+
3045
3309
  };
3046
3310
 
3047
3311
  docmanager["remotesigner"] = new FirmadorLibreWS(docmanager, url_ws, signatureManager);