Subversion Repositories SmartDukaan

Rev

Rev 37523 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 37523 Rev 37632
Line 763... Line 763...
763
        }
763
        }
764
    }
764
    }
765
}*/
765
}*/
766
 
766
 
767
$(document).on('click', "#confirmSign", function () {
767
$(document).on('click', "#confirmSign", function () {
-
 
768
    let btn = $(this);
768
    let loiId = $(this).val();
769
    let loiId = btn.val();
-
 
770
    if (btn.prop('disabled')) return false;
769
    let otp = prompt("Enter received OTP here");
771
    let otp = prompt("Enter received OTP here");
-
 
772
    if (otp === undefined || otp === null) {
-
 
773
        return false;
-
 
774
    }
-
 
775
    otp = otp.trim();
-
 
776
    if (!otp) {
-
 
777
        alert("Please enter the OTP received by the partner.");
-
 
778
        return false;
-
 
779
    }
770
    let validateOtpUrl = `${context}/validateLoiOtp?loiId=${loiId}&provideOtp=${otp}`;
780
    let validateOtpUrl = `${context}/validateLoiOtp?loiId=${loiId}&provideOtp=${encodeURIComponent(otp)}`;
-
 
781
 
-
 
782
    // Once the OTP is accepted the LOI is only half signed: the server has the OTP but not the
-
 
783
    // signed PDF, and the partner mail + onboarding only happen in /saveLoiDoc. Every failure from
-
 
784
    // here on must say that plainly - a silent failure here left LOIs stuck with no mail.
-
 
785
    function signNotSaved(reason) {
-
 
786
        btn.prop('disabled', false);
-
 
787
        alert("OTP was verified, but the signed LOI was NOT saved.\nReason: " + reason
-
 
788
            + "\n\nNothing has been emailed to the partner. Click Send OTP to get a new OTP, then Confirm Sign again."
-
 
789
            + " Keep this page open until you see the \"LOI has been signed successfully\" message.");
-
 
790
    }
771
 
791
 
772
    if (otp !== undefined && otp !== null) {
792
    btn.prop('disabled', true);
-
 
793
    $.ajax({
-
 
794
        url: validateOtpUrl,
-
 
795
        type: 'PUT',
-
 
796
        cache: false,
-
 
797
        suppressGlobalError: true,
773
        doPutAjaxRequestHandler(validateOtpUrl, function (response) {
798
        success: function (response) {
774
            console.log('OTP validation response:', response);
799
            console.log('OTP validation response:', response);
775
 
800
 
776
            if (response && response.response && response.response.success) {
801
            if (response && response.response && response.response.success) {
-
 
802
                // html2pdf comes from cdnjs; if that script was blocked, the old code threw a
-
 
803
                // ReferenceError right here and the operator saw nothing at all.
-
 
804
                if (typeof html2pdf !== 'function') {
-
 
805
                    signNotSaved("the PDF library did not load in this browser (check internet / try Chrome, then reload the page)");
-
 
806
                    return;
-
 
807
                }
-
 
808
                let tempContainer = null;
-
 
809
                try {
777
                const docHash = (response.response.documentHash || "");
810
                    const docHash = (response.response.documentHash || "");
778
                const ip = response.response.ipAddress || "";
811
                    const ip = response.response.ipAddress || "";
779
                const createdAt = response.response.createdAt || new Date().toLocaleString();
812
                    const createdAt = response.response.createdAt || new Date().toLocaleString();
780
                const watermarkText =
813
                    const watermarkText =
781
                    `OTP VERIFIED\n` +
814
                        `OTP VERIFIED\n` +
782
                    `DOCUMENT HASH:\n ${docHash}\n` +
815
                        `DOCUMENT HASH:\n ${docHash}\n` +
783
                    `IP ADDRESS: ${ip}\n` +
816
                        `IP ADDRESS: ${ip}\n` +
784
                    `CREATED ON: ${createdAt}`;
817
                        `CREATED ON: ${createdAt}`;
785
                const originalElement = document.getElementById('loiPDF_content');
818
                    const originalElement = document.getElementById('loiPDF_content');
786
                const clonedElement = originalElement.cloneNode(true);
819
                    const clonedElement = originalElement.cloneNode(true);
787
                const existingStyles = clonedElement.querySelectorAll('style');
820
                    const existingStyles = clonedElement.querySelectorAll('style');
788
                existingStyles.forEach(style => style.remove());
821
                    existingStyles.forEach(style => style.remove());
789
                $(clonedElement).find('.pending-badge, .pending-indicator').remove();
822
                    $(clonedElement).find('.pending-badge, .pending-indicator').remove();
790
                $(clonedElement).find('.signature-section').each(function () {
823
                    $(clonedElement).find('.signature-section').each(function () {
791
                    this.style.setProperty('position', 'relative', 'important');
824
                        this.style.setProperty('position', 'relative', 'important');
792
                    this.style.setProperty('padding', '20px', 'important');
825
                        this.style.setProperty('padding', '20px', 'important');
793
                });
-
 
794
 
-
 
795
                const signatureSections = clonedElement.querySelectorAll('.signature-section');
-
 
796
                signatureSections.forEach(section => {
-
 
797
                    const oldWatermarks = section.querySelectorAll('.watermark-overlay');
-
 
798
                    oldWatermarks.forEach(w => w.remove());
-
 
799
 
-
 
800
                    const watermarkDiv = document.createElement('div');
-
 
801
                    watermarkDiv.className = 'watermark-overlay';
-
 
802
                    watermarkDiv.textContent = watermarkText;
-
 
803
                    watermarkDiv.style.position = 'absolute';
-
 
804
                    watermarkDiv.style.fontSize = '7px';
-
 
805
                    watermarkDiv.style.top = '30px';
-
 
806
                    watermarkDiv.style.left = '1%';
-
 
807
                    watermarkDiv.style.color = 'rgb(4,97,225)';
-
 
808
                    watermarkDiv.style.fontWeight = 'bold';
-
 
809
                    watermarkDiv.style.fontFamily = 'Arial,sans-serif';
-
 
810
                    watermarkDiv.style.whiteSpace = 'pre-line';
-
 
811
                    watermarkDiv.style.textAlign = 'center';
-
 
812
                    watermarkDiv.style.pointerEvents = 'none';
-
 
813
                    watermarkDiv.style.width = '90%';
-
 
814
                    watermarkDiv.style.lineHeight = '1.7';
-
 
815
                    watermarkDiv.style.zIndex = '1';
-
 
816
                    watermarkDiv.style.userSelect = 'none';
-
 
817
 
-
 
818
                    section.style.position = 'relative';
-
 
819
                    section.appendChild(watermarkDiv);
-
 
820
                });
-
 
821
 
-
 
822
                const tempContainer = document.createElement('div');
-
 
823
                tempContainer.style.position = 'absolute';
-
 
824
                tempContainer.style.left = '-9999px';
-
 
825
                tempContainer.style.width = '800px';
-
 
826
                tempContainer.appendChild(clonedElement);
-
 
827
                document.body.appendChild(tempContainer);
-
 
828
 
-
 
829
                const opt = {
-
 
830
                    margin: [0.5, 0.5, 0.5, 0.5],
-
 
831
                    filename: `LOI_${loiId}_${new Date().getTime()}.pdf`,
-
 
832
                    image: {
-
 
833
                        type: 'jpeg',
-
 
834
                        quality: 0.98
-
 
835
                    },
-
 
836
                    html2canvas: {
-
 
837
                        scale: 1.2,
-
 
838
                        logging: false,
-
 
839
                        useCORS: true,
-
 
840
                        allowTaint: false,
-
 
841
                        backgroundColor: '#ffffff'
-
 
842
                    },
826
                    });
843
                    jsPDF: {
-
 
844
                        unit: 'in',
-
 
845
                        format: 'letter',
-
 
846
                        orientation: 'portrait'
-
 
847
                    }
-
 
848
                };
-
 
849
 
827
 
-
 
828
                    const signatureSections = clonedElement.querySelectorAll('.signature-section');
-
 
829
                    signatureSections.forEach(section => {
-
 
830
                        const oldWatermarks = section.querySelectorAll('.watermark-overlay');
-
 
831
                        oldWatermarks.forEach(w => w.remove());
-
 
832
 
-
 
833
                        const watermarkDiv = document.createElement('div');
-
 
834
                        watermarkDiv.className = 'watermark-overlay';
-
 
835
                        watermarkDiv.textContent = watermarkText;
-
 
836
                        watermarkDiv.style.position = 'absolute';
-
 
837
                        watermarkDiv.style.fontSize = '7px';
-
 
838
                        watermarkDiv.style.top = '30px';
-
 
839
                        watermarkDiv.style.left = '1%';
-
 
840
                        watermarkDiv.style.color = 'rgb(4,97,225)';
-
 
841
                        watermarkDiv.style.fontWeight = 'bold';
-
 
842
                        watermarkDiv.style.fontFamily = 'Arial,sans-serif';
-
 
843
                        watermarkDiv.style.whiteSpace = 'pre-line';
-
 
844
                        watermarkDiv.style.textAlign = 'center';
-
 
845
                        watermarkDiv.style.pointerEvents = 'none';
-
 
846
                        watermarkDiv.style.width = '90%';
-
 
847
                        watermarkDiv.style.lineHeight = '1.7';
-
 
848
                        watermarkDiv.style.zIndex = '1';
-
 
849
                        watermarkDiv.style.userSelect = 'none';
-
 
850
 
-
 
851
                        section.style.position = 'relative';
-
 
852
                        section.appendChild(watermarkDiv);
-
 
853
                    });
-
 
854
 
-
 
855
                    tempContainer = document.createElement('div');
-
 
856
                    tempContainer.style.position = 'absolute';
-
 
857
                    tempContainer.style.left = '-9999px';
-
 
858
                    tempContainer.style.width = '800px';
-
 
859
                    tempContainer.appendChild(clonedElement);
-
 
860
                    document.body.appendChild(tempContainer);
-
 
861
 
-
 
862
                    const opt = {
-
 
863
                        margin: [0.5, 0.5, 0.5, 0.5],
-
 
864
                        filename: `LOI_${loiId}_${new Date().getTime()}.pdf`,
-
 
865
                        image: {
-
 
866
                            type: 'jpeg',
-
 
867
                            quality: 0.98
-
 
868
                        },
-
 
869
                        html2canvas: {
-
 
870
                            scale: 1.2,
-
 
871
                            logging: false,
-
 
872
                            useCORS: true,
-
 
873
                            allowTaint: false,
-
 
874
                            backgroundColor: '#ffffff'
-
 
875
                        },
-
 
876
                        jsPDF: {
-
 
877
                            unit: 'in',
-
 
878
                            format: 'letter',
-
 
879
                            orientation: 'portrait'
-
 
880
                        }
-
 
881
                    };
-
 
882
 
850
                html2pdf().from(clonedElement).set(opt).outputPdf("arraybuffer")
883
                    html2pdf().from(clonedElement).set(opt).outputPdf("arraybuffer")
851
                    .then(function (pdf) {
884
                        .then(function (pdf) {
852
                        document.body.removeChild(tempContainer);
885
                            document.body.removeChild(tempContainer);
853
 
886
 
854
                        const file = new Blob([pdf], {type: 'application/pdf'});
887
                            const file = new File([pdf], `LOI_${loiId}_signed.pdf`, {type: 'application/pdf'});
855
 
888
 
856
                        uploadDocument(file, function (documentId) {
889
                            uploadDocument(file, function (documentId) {
857
                            IdempotencyKey = uuidv4();
890
                                IdempotencyKey = uuidv4();
858
                            if (documentId > 0) {
891
                                saveLoiDoc(loiId, documentId, signNotSaved);
859
                                saveLoiDoc(loiId, documentId);
892
                            }, function (message) {
860
                                alert("Document signed and saved successfully!");
893
                                signNotSaved("upload failed - " + message);
861
                            } else {
894
                            });
-
 
895
                        })
-
 
896
                        .catch(function (error) {
-
 
897
                            console.error('PDF generation failed:', error);
-
 
898
                            if (tempContainer && tempContainer.parentNode) {
862
                                alert("Something went wrong, please try again to confirm OTP");
899
                                tempContainer.parentNode.removeChild(tempContainer);
863
                            }
900
                            }
-
 
901
                            signNotSaved("the PDF could not be generated in this browser (" + (error && error.message ? error.message : error) + ")");
864
                        });
902
                        });
865
                    })
903
                } catch (error) {
866
                    .catch(function (error) {
904
                    console.error('Signed LOI build failed:', error);
867
                        console.error('PDF generation failed:', error);
905
                    if (tempContainer && tempContainer.parentNode) {
868
                        document.body.removeChild(tempContainer);
906
                        tempContainer.parentNode.removeChild(tempContainer);
-
 
907
                    }
869
                        alert("PDF generation failed. Please try again.");
908
                    signNotSaved("the signed PDF could not be prepared (" + (error && error.message ? error.message : error) + ")");
870
                    });
909
                }
871
            } else {
910
            } else {
872
                console.error('OTP validation failed:', response);
911
                console.error('OTP validation failed:', response);
-
 
912
                btn.prop('disabled', false);
873
                alert("OTP validation failed: " + (response.response?.message || "Please try again."));
913
                alert("OTP validation failed: " + (response && response.response && response.response.message ? response.response.message : "Please try again."));
874
            }
914
            }
-
 
915
        },
875
        }, function (error) {
916
        error: function (xhr) {
876
            console.error('AJAX request failed:', error);
917
            btn.prop('disabled', false);
877
            alert("Request failed. Please check your connection and try again.");
918
            alert("OTP not accepted: " + uploadErrorMessage(xhr));
878
        });
919
        }
879
    } else {
-
 
880
        return false;
-
 
881
    }
920
    });
882
});
921
});
883
 
922
 
884
 
923
 
885
function saveLoiDoc(loiId, documentId) {
924
function saveLoiDoc(loiId, documentId, onFailure) {
886
    let saveLoiDocUrl = `${context}/saveLoiDoc?loiId=` + loiId + `&loiDocId=` + documentId
925
    let saveLoiDocUrl = `${context}/saveLoiDoc?loiId=` + loiId + `&loiDocId=` + documentId;
-
 
926
    $.ajax({
887
    doPostAjaxRequestHandler(saveLoiDocUrl, function (response) {
927
        url: saveLoiDocUrl,
-
 
928
        type: 'POST',
-
 
929
        cache: false,
-
 
930
        suppressGlobalError: true,
888
        if (response) {
931
        success: function (response) {
-
 
932
            // The "response" view renders the bare boolean, so a failure arrives as the string "false".
-
 
933
            if (response === true || String(response).trim() === 'true') {
889
            alert("LOI has been signed successfully and sent to the registered email. Please check your email.");
934
                alert("LOI has been signed successfully and sent to the registered email. Please check your email.");
890
            pendingLoiForm("main-content");
935
                pendingLoiForm("main-content");
891
        } else {
936
            } else {
892
            alert("Something went wrong , Please try again to generate Loi and Validate otp");
937
                onFailure("the server did not accept the signed document");
-
 
938
            }
-
 
939
        },
-
 
940
        error: function (xhr) {
-
 
941
            onFailure("saving failed - " + uploadErrorMessage(xhr));
893
        }
942
        }
894
    });
943
    });
895
}
944
}
896
 
945
 
897
 
946