Uname:Linux ip-11-115-0-196 6.8.0-1039-aws #41~22.04.1-Ubuntu SMP Thu Sep 11 10:54:48 UTC 2025 x86_64

403WebShell
403Webshell
Server IP : 13.126.101.145  /  Your IP : 216.73.217.33
Web Server : Apache/2.4.52 (Ubuntu)
System : Linux ip-11-115-0-196 6.8.0-1039-aws #41~22.04.1-Ubuntu SMP Thu Sep 11 10:54:48 UTC 2025 x86_64
User : www-data ( 33)
PHP Version : 8.3.17
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/html/rentals_updated/wp-content/plugins/woocommerce-rfq/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/rentals_updated/wp-content/plugins/woocommerce-rfq/rfq-for-myaccount.php
<?php
function th_enqueue_rfq_styles()
{
    wp_enqueue_style(
        "rfq-style",
        plugin_dir_url(__FILE__) . "css/custom-style.css"
    );
}
add_action('wp_enqueue_scripts', 'th_enqueue_rfq_styles');

// Add new endpoint for RFQ
function th_add_rfq_endpoint()
{
    add_rewrite_endpoint('rfq', EP_ROOT | EP_PAGES);
    flush_rewrite_rules(); // Ensure that the rewrite rules are updated
}
add_action('init', 'th_add_rfq_endpoint');

// Add new query var for RFQ
function th_rfq_query_vars($vars)
{
    $vars[] = 'rfq';
    return $vars;
}
add_filter('query_vars', 'th_rfq_query_vars', 0);

// Add RFQ link to My Account menu
function th_add_rfq_link_my_account($items)
{
    $items['rfq'] = 'RFQ';
    return $items;
}
add_filter('woocommerce_account_menu_items', 'th_add_rfq_link_my_account');

// Display RFQ content on My Account RFQ endpoint
function th_rfq_content()
{
    global $wpdb;
    $user_id = get_current_user_id();
    $rfqs = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}request_quote WHERE user_id = %d", $user_id));

    if (empty($rfqs)) {
        wc_add_notice('No RFQs found.', 'notice');
        return;
    }

    echo '<table id="rfqTable" class="shop_table shop_table_responsive my_account_orders">';
    echo '<thead>';
    echo '<tr>';
    echo '<th class="rfq-sr-no woocommerce-rfq-table__header">Sr. No.</th>';
    echo '<th class="rfq-start-date woocommerce-rfq-table__header">Start Date</th>';
    echo '<th class="rfq-end-date woocommerce-rfq-table__header">End Date</th>';
    echo '<th class="rfq-product-name woocommerce-rfq-table__header">Product Name</th>';
//     echo '<th class="rfq-shift woocommerce-rfq-table__header">Shift</th>';
    echo '<th class="rfq-status woocommerce-rfq-table__header">Status</th>';
    echo '</tr>';
    echo '</thead>';
    echo '<tbody>';
    $sr_no = 1;

    usort($rfqs, function($a, $b) {
        return $b->id <=> $a->id; // or use start_date as shown above
    });

    foreach ($rfqs as $rfq) {
        $quotation = $wpdb->get_row($wpdb->prepare("SELECT qt_status FROM {$wpdb->prefix}quotation WHERE rfq_id = %d", $rfq->id));
        $status = $quotation ? ' ' . $quotation->qt_status : $rfq->rfq_status;

        echo '<tr class="woocommerce-orders-table__row">';
        echo '<td class="rfq-sr-no woocommerce-rfq-table__cell-sr-no">' . esc_html($sr_no) . '</td>';
        echo '<td class="rfq-start-date">' . esc_html(date('F j, Y', strtotime($rfq->start_date))) . '</td>';
        echo '<td class="rfq-end-date">' . esc_html(date('F j, Y', strtotime($rfq->end_date))) . '</td>';
        echo '<td class="rfq-product-name">' . esc_html($rfq->product_name) . '</td>';
//         echo '<td class="rfq-shift">' . esc_html($rfq->shift) . '</td>';
        // Check and modify the status based on given conditions
        if ($status === ' Quote Send to Coustmer') {
            $display_status = 'Quote Generated';
        } elseif ($status === ' Revised') {
            $display_status = ' Completed';
        } elseif ($status === ' Accepted' || $status === ' Cancelled') {
            $display_status = 'Completed';
        } else {
            $display_status = $status; // Default to the original status if no conditions are met
        }
        // Output the modified status
        echo '<td class="rfq-status">' . esc_html($display_status) . '</td>';
        echo '</tr>';
        $sr_no++;
    }

    echo '</tbody>';
    echo '</table>';
}
add_action('woocommerce_account_rfq_endpoint', 'th_rfq_content');

// Add new endpoint for Quotations
function th_add_quotation_endpoint()
{
    add_rewrite_endpoint('quotation', EP_ROOT | EP_PAGES);
    flush_rewrite_rules();
}
add_action('init', 'th_add_quotation_endpoint');

// Add new query var for Quotations
function th_quotation_query_vars($vars)
{
    $vars[] = 'quotation';
    return $vars;
}
add_filter('query_vars', 'th_quotation_query_vars', 0);

// Add Quotation link to My Account menu
function th_add_quotation_link_my_account($items)
{
    $items['quotation'] = 'Quotation';
    return $items;
}
add_filter('woocommerce_account_menu_items', 'th_add_quotation_link_my_account');

// Display quotations on My Account page with nonce
function th_quotation_content()
{

    $user_id = get_current_user_id();
    global $wpdb;
    $quotation_table = $wpdb->prefix . 'quotation';
    $assigned_terms_table = $wpdb->prefix . 'assigned_terms';

    // Retrieve user data
    $user_info = get_userdata($user_id);

    // Get the user's first name
    $user_name = $user_info->first_name;

    // Escape the user name for safe use in JavaScript
    $user_name_js = esc_js($user_name);
   

    // Fetch quotation data from the wp_quotation table and hide inprogress status quote
    $quotations = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM $quotation_table WHERE user_id = %d ORDER BY id DESC",
// 		"SELECT * FROM $quotation_table WHERE user_id = %d AND cs_view != '0' ORDER BY id DESC",
        $user_id
    ));
    if (empty($quotations)) {
        wc_add_notice('No Quotations found.', 'notice');
        return;
    }

    // Start building the table
    echo '<table id="quotationTable" class="shop_table shop_table_responsive my_account_orders">';
    echo '<thead>';
    echo '<tr style="text-wrap:nowrap;">';
    echo '<th class="order-number woocommerce-orders-table__header"><span class="nobr">Sr. No</span></th>';
    echo '<th class="order-number woocommerce-orders-table__header"><span class="nobr">Product Name</span></th>';
    echo '<th class="order-date woocommerce-orders-table__header"><span class="nobr">Start Date</span></th>';
    echo '<th class="order-date woocommerce-orders-table__header"><span class="nobr">End Date</span></th>';
//     echo '<th class="order-status woocommerce-orders-table__header"><span class="nobr">Shift</span></th>';
    // echo '<th class="order-status woocommerce-orders-table__header"><span class="nobr">Discount</span></th>';
    echo '<th class="order-total woocommerce-orders-table__header"><span class="nobr">Offered Price</span></th>';
    echo '<th class="order-total woocommerce-orders-table__header"><span class="nobr">Final Price</span></th>';
    echo '<th class="order-status woocommerce-orders-table__header"><span class="nobr">Status</span></th>';
    echo '<th class="order-actions woocommerce-orders-table__header"><span class="nobr">Actions</span></th>';
    echo '</tr>';
    echo '</thead>';
    echo '<tbody>';
    $sr_no = 1;

    // Loop through each quotation and create a table row
    foreach ($quotations as $quotation) {


        // Fetch qt_id from wp_assigned_terms
        // $assigned_term = $wpdb->get_var($wpdb->prepare("SELECT qt_id FROM $assigned_terms_table WHERE qt_id = %d", $quotation->id));


        echo '<tr class="woocommerce-orders-table__row">';
        echo '<td class="order-number" data-title="Sr. No"><span class="nobr">' . esc_html($sr_no) . '</span></td>';
        echo '<td class="order-number" data-title="Product Name"><span class="nobr">' . esc_html($quotation->product_name) . '</span></td>';
        echo '<td class="order-date" data-title="Start Date"><time datetime="' . esc_attr(date('Y-m-d', strtotime($quotation->start_date))) . '">' . esc_html(date('F j, Y', strtotime($quotation->start_date))) . '</time></td>';
        echo '<td class="order-date" data-title="End Date"><time datetime="' . esc_attr(date('Y-m-d', strtotime($quotation->end_date))) . '">' . esc_html(date('F j, Y', strtotime($quotation->end_date))) . '</time></td>';
//         echo '<td class="order-status" data-title="Shift"><span class="nobr">' . esc_html($quotation->shift) . '</span></td>';
        // echo '<td class="order-status" data-title="Discount"><span class="nobr">' . esc_html($quotation->rfqdiscount) . '%</span></td>';
        echo '<td class="order-total" data-title="Final Price"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">&#8377;</span>' . esc_html($quotation->calculated_price) . '</bdi></span></td>';
        echo '<td class="order-total" data-title="Final Price"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">&#8377;</span>' . esc_html($quotation->final_price) . '</bdi></span></td>';
        // Check if the quotation status is "Quote Send to Customer" and set it to "In Progress" if true
        $status_display = $quotation->qt_status === 'Quote Send to Coustmer' ? 'In Progress' : $quotation->qt_status;

        // Output the status with the updated value
        echo '<td class="order-status" data-title="Status" style="text-align: center;">
        <mark class="order-status status-' . esc_html($quotation->qt_status) . '" style="display: block; text-align: center;">
            <span>' . esc_html($status_display) . '</span>';

        // Check if the status is "Accepted" and display the accepted_at timestamp
        if ($quotation->qt_status === 'Accepted' && !empty($quotation->accepted_at)) {
            // Format the accepted_at timestamp as 'Day Month Year Time' (numeric month)
            $formatted_date = date('d-m-Y H:i', strtotime($quotation->accepted_at));
            echo '<br><span class="accepted-at">' . esc_html($formatted_date) . '</span>';
        }

        echo '</mark>
            </td>';


        echo '<td class="order-actions" data-title="Actions">';
        echo '<form method="post" style="display:flex; flex-direction: row;gap: 10px;">';
        echo '<input type="hidden" name="quotation_id" value="' . esc_attr($quotation->id) . '">';
        echo '<input type="hidden" name="_wpnonce" value="' . wp_create_nonce('accept_quotation_nonce') . '">';

        // Add input for comments above the buttons
        if ($quotation->qt_status !== 'Accepted') : ?>
    <div class="quotation-comment-wrapper">
        <!-- Image icon -->
        <img src="/wp-content/uploads/2025/09/textarea.png" 
             alt="Edit Comments" 
             style="cursor:pointer; width:24px; height:24px;" 
             onclick="this.nextElementSibling.style.display='block'; this.style.display='none';">

        <!-- Hidden textarea -->
        <textarea name="quotation_comments" 
                  onfocus="this.value='';" 
                  placeholder="Add comments" 
                  class="input-text" 
                  style="display:none;width: 130px;font-size: 12px;"><?php echo esc_html($quotation->comments); ?></textarea>
    </div>
<?php else : ?>
<!--     <div class="quotation-comment-wrapper">
        <img src="/wp-content/uploads/2025/09/textarea.png" 
             alt="View Comments" 
             style="cursor:pointer; width:24px;" 
             onclick="this.nextElementSibling.style.display='block'; this.style.display='none';">

        <textarea name="quotation_comments" 
                  placeholder="Add comments" 
                  class="input-text" 
                  style="display:none;width: 130px;font-size: 12px;" 
                  readonly><?php echo esc_html($quotation->comments); ?></textarea>
    </div> -->
<?php endif; 


        // Add a button to update comments
        if ($quotation->qt_status !== 'Accepted') {
        echo '<input class="my-qt-buttons" type="submit" name="update_comments" value="Request For Revision" class="button qt-button" style="margin-bottom: 10px;">';
        }

        echo '<button style="width:20px;" class="download-terms-btn button qt-button" data-quotation-id="' . esc_attr($quotation->id) . '" id="download-each-quotation-' . esc_attr($quotation->id) . '"><img src="/wp-content/uploads/2025/09/download-pdf.png" alt="download-icon" /></button>';




        // Include jsPDF library and script to generate PDFs
        ?>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>

        <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js" integrity="sha512-GsLlZN/3F2ErC5ifS5QtgpiJtWd43JWSuIgh7mbzZ8zBps+dvLusV+eNQATqgA/HdeKFVgA5v3S/cIrLF7QnIg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

        <!-- <script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function() {
        // Ensure the jsPDF library is loaded
        if (window.jspdf) {
            // Access jsPDF from the global object
            const { jsPDF } = window.jspdf;

            // Add event listener to all buttons with the class 'download-terms-btn'
            document.querySelectorAll(".download-terms-btn").forEach(button => {
                button.addEventListener("click", function() {
                    // Get the quotation ID from data attribute
                    const quotationId = this.getAttribute("data-quotation-id");

                    // Create a new PDF document
                    const doc = new jsPDF();
                    
                    // Add content to the PDF based on the quotation ID or any other data
                    doc.text(`This is a demo PDF content for quotation ID: ${quotationId}`, 10, 10);
                    
                    // Save the PDF with a specified filename
                    doc.save(`terms_${quotationId}.pdf`);
                });
            });
        } else {
            console.error("jsPDF library is not loaded.");
        }
    });
</script> -->


        <script type="text/javascript">
       document.addEventListener("DOMContentLoaded", function () {
    // Ensure the html2pdf library is loaded
    if (window.html2pdf) {
       // Initialize flag to track if a request is already in progress
let isRequestInProgress = false;

// Get the button element by its id
const downloadButton = document.getElementById('download-each-quotation-<?php echo esc_attr($quotation->id); ?>');

// Add click event listener
downloadButton.addEventListener("click", function (event) {

    // Prevent default behavior
    event.preventDefault();

    // Check if a request is already in progress
    if (isRequestInProgress) {
        console.log("Request is already in progress. Ignoring subsequent request.");
        return; // Ignore the click if a request is already in progress
    }

    // Set flag to true to block further requests
    isRequestInProgress = true;

    // Capture the quotation ID from the data attribute
    const quotationId = downloadButton.getAttribute("data-quotation-id");
    var userName = "<?php echo $user_name_js; ?>";

    // Make an AJAX request to fetch the dynamic terms content
    const xhr = new XMLHttpRequest();
    xhr.open("GET", `<?php echo esc_url(admin_url('admin-ajax.php')); ?>?action=get_dynamic_terms&quotation_id=${quotationId}`, true);

    xhr.onload = function () {
        if (xhr.status === 200) {
            console.log("Dynamic terms content fetched successfully.");

            // Create a container to hold the dynamic PDF content
            const pdfContent = xhr.responseText;
            const container = document.createElement('div');
            container.innerHTML = pdfContent;

            // Define options for html2pdf
            const options = {
                margin: [20, 20, 20, 20], // Top, Left, Bottom, Right margins
                filename: `Gmmco_${userName}_Quotation.pdf`,
                image: { type: 'jpeg', quality: 0.98 },
                html2canvas: { scale: 2 },
                jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
                pagebreak: { mode: ['avoid-all', 'css', 'legacy'] } // Ensures proper page breaks
            };

            // Generate PDF with footer on every page
            html2pdf().from(container).set(options).toPdf().get('pdf').then(function (pdf) {
                const totalPages = pdf.internal.getNumberOfPages();

                for (let i = 1; i <= totalPages; i++) {
                    pdf.setFontSize(9);

                    const margin = 10; // Margin for the border
                    pdf.rect(margin, margin, pdf.internal.pageSize.getWidth() - 2 * margin, pdf.internal.pageSize.getHeight() - 2 * margin);

                    const bottomPadding = 16; // Bottom padding

                    pdf.setPage(i);

                    // Adjust the footer text positions to accommodate the bottom padding
                    pdf.text('(Registered Office: No 9/1 R N Mukherjee Road Kolkata 700001 INDIA)', 
                        pdf.internal.pageSize.getWidth() / 2, 
                        pdf.internal.pageSize.getHeight() - bottomPadding - 10, // Adjust position with padding
                        { align: 'center' }
                    );

                    pdf.text('Head Quarters: No 6, GST Road, St.Thomas Mount, Chennai - 600016, Tamil Nadu, India', 
                        pdf.internal.pageSize.getWidth() / 2, 
                        pdf.internal.pageSize.getHeight() - bottomPadding - 5, // Adjust position with padding
                        { align: 'center' }
                    );

                    pdf.text('Email: contactus@gmmcoindia.com | Website: www.gmmco.in | Phone: +91 44 2267 6000', 
                        pdf.internal.pageSize.getWidth() / 2, 
                        pdf.internal.pageSize.getHeight() - bottomPadding - 1, // Adjust position with padding
                        { align: 'center' }
                    );
                }
            }).save().then(() => {
                console.log("PDF successfully generated.");
                isRequestInProgress = false; // Reset flag after the PDF is saved
            }).catch(() => {
                console.error("Failed to generate PDF.");
                isRequestInProgress = false; // Reset flag if PDF generation fails
            });
        } else {
            console.error('Failed to fetch dynamic terms.');
            isRequestInProgress = false; // Reset flag in case of error
        }
    };

    xhr.onerror = function () {
        console.error('Request failed.');
        isRequestInProgress = false; // Reset flag if the request fails
    };

    xhr.send(); // Send the AJAX request
});



        
    } else {
        console.error("html2pdf library is not loaded.");
    }
});






        </script>

        <?php

        // Conditionally display the "View Terms" button and "Accept" button based on the presence of assigned terms
        // if ($assigned_term) {
        //     echo '<a class="my-qt-buttons" href="#" onclick="display_terms(' . esc_attr($quotation->id) . '); return false;" class="button" style="margin-bottom: 10px;">View Terms</a>';

        if ($quotation->qt_status !== 'Accepted') {
            echo '<input class="my-qt-buttons" type="submit" name="accept_quotation" value="Accept" class="button qt-button">';
        }
        // }
        // Conditionally display the "Accept" button based on the status and qt_id presence

        echo '</form>';
        echo '</td>';
        echo '</tr>';
        // Increment the serial number counter
        $sr_no++;
    }

    echo '</tbody>';
    echo '</table>';

    // Display terms in a hidden popup with preloader
    echo '<div id="terms-popup" class="terms-content" style="display:none; position:fixed; top:10%; left:10%; width:80%; height:80%; background:white; border:1px solid #ccc; padding:20px; z-index:1000;">
    <button class="qt-pp-cl-button" onclick="document.getElementById(\'terms-popup\').style.display=\'none\'" style="position:absolute; top:10px; right:10px;">Close</button>
    <div id="preloader" style="display:none; text-align:center; margin-top:20%;">
        <img style="width:22px;" src="' . esc_url(plugin_dir_url(__FILE__) . 'spinner.gif') . '" alt="Loading...">
    </div>
    <div id="terms-content" style="overflow:auto; max-height:90%;"></div>
    </div>';





    echo '<script>
    function display_terms(quotation_id) {
    document.getElementById("preloader").style.display = "block";
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "' . esc_url(admin_url('admin-ajax.php')) . '?action=get_terms&quotation_id=" + quotation_id, true);
    xhr.onload = function() {
        if (xhr.status === 200) {
            var terms = xhr.responseText;
            var termsContent = document.getElementById("terms-content");
            termsContent.innerHTML = "<h2>Terms and Conditions</h2>" + terms;
            document.getElementById("preloader").style.display = "none";
            document.getElementById("terms-popup").style.display = "block";
        } else {
            alert("Failed to load terms and conditions. Please try again.");
            document.getElementById("preloader").style.display = "none";
        }
    };
    xhr.onerror = function() {
        alert("An error occurred while processing the request.");
        document.getElementById("preloader").style.display = "none";
    };
    xhr.send();
    }
    </script>';
}


add_action('woocommerce_account_quotation_endpoint', 'th_quotation_content');


// Handle button actions
function th_quotation_buttons()
{
    if (isset($_POST['accept_quotation']) && isset($_POST['quotation_id'])) {
        // Verify nonce for security
        if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'accept_quotation_nonce')) {
            wc_add_notice('Nonce verification failed.', 'error');
            return;
        }

        global $wpdb;
        $table_name = $wpdb->prefix . 'quotation';
        $quotation_id = intval($_POST['quotation_id']);

        // Update the quotation status and accepted_at timestamp
        $updated = $wpdb->update(
            $table_name, 
            array(
                'qt_status' => 'Accepted', 
            ), 
            array('id' => $quotation_id)
        );


        if ($updated !== false) {
            wc_add_notice('Quotation accepted successfully.', 'success');
        } else {
            wc_add_notice('Failed to update quotation status.', 'error');
        }

        wp_redirect(wc_get_account_endpoint_url('quotation'));
        exit;
    }

    if (isset($_POST['update_comments']) && isset($_POST['quotation_id']) && isset($_POST['quotation_comments'])) {
        // Verify nonce for security
        if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'accept_quotation_nonce')) {
            wc_add_notice('Nonce verification failed.', 'error');
            return;
        }

        global $wpdb;
        $table_name = $wpdb->prefix . 'quotation';
        $quotation_id = intval($_POST['quotation_id']);
        $comments = sanitize_text_field($_POST['quotation_comments']);

        // Update the quotation comments
        $updated = $wpdb->update(
            $table_name, // The table name
            array( // Array of columns to update
                'comments' => $comments,
                'qt_status' => 'Requested For Revision' // Additional column update
            ),
            array( 'id' => $quotation_id ) // The WHERE clause (which row to update)
        );

         // In App Notification
         $edit_url = admin_url('admin.php?page=edit-quotation&id=' . $quotation_id);
         create_notification(
             'Customer accepted quotation',
             'Customer accepted quotation for "' . $quotation_id . '". <a target="_blank" href="' . $edit_url . '" style="color: blue; text-decoration: underline;">Click here</a> to view/edit.',
             array(
                 'meta_input' => array(
                     'user_id' => 'test',
                     'action' => 'qt accepted',
                 )
             )
         );
        

        if ($updated !== false) {
            wc_add_notice('Comments updated successfully.', 'success');
        } else {
            wc_add_notice('Failed to update comments.', 'error');
        }

        wp_redirect(wc_get_account_endpoint_url('quotation'));
        exit;
    }
}
add_action('wp', 'th_quotation_buttons');

// Handle AJAX request for terms and conditions
add_action('wp_ajax_get_terms', 'th_get_terms');
function th_get_terms()
{
    global $wpdb;
    $quotation_id = intval($_GET['quotation_id']);
    $terms_table = $wpdb->prefix . 'assigned_terms'; // Update to the new table name

    // Fetch terms and conditions from the assigned_terms table using qt_id
    $terms_data = $wpdb->get_row($wpdb->prepare("SELECT static_part_1, static_part_2, static_part_3, static_part_4, static_part_5, static_part_6, static_part_7, dynamic_part_1, dynamic_part_2, dynamic_part_3, dynamic_part_4, dynamic_part_5 FROM $terms_table WHERE qt_id = %d", $quotation_id));

    if ($terms_data) {
        $terms_content = '';

        // Iterate over each field and add to terms content if it is not empty
        foreach ($terms_data as $value) {
            if (!empty($value)) {
                $terms_content .= wp_kses_post($value) . "\n";
            }
        }

        echo $terms_content;
    } else {
        echo 'No terms and conditions found.';
    }

    wp_die();
}

/// Handle AJAX request for dynamic terms
add_action('wp_ajax_get_dynamic_terms', 'th_get_dynamic_terms');

function th_get_dynamic_terms()
{
    global $wpdb;
    $quotation_id = intval($_GET['quotation_id']);
    $quotation_table = $wpdb->prefix . 'quotation';
    $terms_conditions_table = $wpdb->prefix . 'terms_conditions';

    // Fetch product_name, dynamic_terms_1, dynamic_terms_2, shift, final_price, user_name, and user_email from the wp_quotation table
    $quotation = $wpdb->get_row($wpdb->prepare("SELECT * FROM $quotation_table WHERE id = %d", $quotation_id));

    // Fetch static_content_1 to static_content_10 from the wp_terms_conditions table
    // $terms_conditions = $wpdb->get_row("SELECT static_content_1, static_content_2, static_content_3, static_content_4, static_content_5, static_content_6, static_content_7, static_content_8, static_content_9, static_content_10 FROM $terms_conditions_table LIMIT 1");

    if ($quotation) {
        $product_name = esc_html($quotation->product_name);
        $assign_location_id = esc_html($quotation->assign_location_id);
        $location_name = $wpdb->get_results( 
            $wpdb->prepare(
                "SELECT * FROM wp_zone_address WHERE id = %d",
                $assign_location_id
            ), 
            OBJECT 
        );

        $assign_location_name = esc_attr( $location_name[0]->address );
        $assign_location_gst = esc_attr( $location_name[0]->gst_no );
        $version_number = esc_html( $quotation->revised_count - 1 );
        $dynamic_terms = wp_kses_post($quotation->dynamic_terms_1);
        $dynamic_terms_2 = wp_kses_post($quotation->dynamic_terms_2);
        $shift = esc_html($quotation->shift);
        $final_price = esc_html($quotation->final_price);
        // $user_email = esc_html($quotation->user_email);
        $user_name = esc_html($quotation->user_name);

        // Logic for total hours
        $start_date = esc_html(date('Y-m-d', strtotime($quotation->start_date)));
        $end_date = esc_html(date('Y-m-d', strtotime($quotation->end_date)));
        // Number of shifts per day
        $shifts_per_day = $shift;
        // Define shift duration (8 hours per shift)
        $shift_duration = 8;  // Hours
        // Convert to DateTime objects
        $start = new DateTime($start_date);
        $end = new DateTime($end_date);
        // Calculate the difference in days between the dates (include the end date by adding 1 day)
        $interval = $start->diff($end);
        $total_days = $interval->days + 1;  // Adding 1 to include the end date
        // Calculate total duration in hours based on the number of shifts per day
        $total_hours = $total_days * $shifts_per_day * $shift_duration;
        // gst calculation
        $gst_percentage = 18;
		$price_wo_gst = round($final_price / 1.18, 2);
        $gst_amount = round((($price_wo_gst * $gst_percentage) / 100), 2);
        // Calculate the final price including GST
        $final_price_with_gst = $price_wo_gst + $gst_amount;
        $final_price_with_gst = round($final_price_with_gst, 2);
        // User billing address
        $user_id = esc_html($quotation->user_id);
        // Get user data
        $user_info = get_userdata($user_id);
        // Retrieve the first name
        $user_name = $user_info->first_name;
        $quote_date =  date('d.m.Y');
        $quote_number = $quotation->id;
        // $billing_first_name = get_user_meta($user_id, 'billing_first_name', true);
        // $billing_last_name = get_user_meta($user_id, 'billing_last_name', true);
        $billing_company = get_user_meta($user_id, 'billing_company', true);
        $billing_address_1 = get_user_meta($user_id, 'billing_address_1', true);
        $billing_address_2 = get_user_meta($user_id, 'billing_address_2', true);
        $billing_city = get_user_meta($user_id, 'billing_city', true);
        $billing_postcode = get_user_meta($user_id, 'billing_postcode', true);
        $billing_state = get_user_meta($user_id, 'billing_state', true);
        $billing_country = get_user_meta($user_id, 'billing_country', true);
        // Combine address fields to match the desired format
        $billing_address = '';
        if (!empty($billing_company)) {
            $billing_address .= $billing_company . "\n";
        }

        if (!empty($billing_address_1)) {
            $billing_address .= $billing_address_1;
        }

        if (!empty($billing_address_2)) {
            $billing_address .= " " . $billing_address_2;
        }

        if (!empty($billing_city)) {
            $billing_address .= "\n" . $billing_city . ' ' . $billing_postcode;
        }

        if (!empty($billing_state)) {
            $billing_address .= "\n" . $billing_state;
        }

        // Output the address
        $billing_address = nl2br($billing_address);

        // Price in words
        function convert_number_to_words($number) {
            $hyphen      = '-';
            $conjunction = ' and ';
            $separator   = ', ';
            $negative    = 'negative ';
            $decimal     = ' point ';
            $dictionary  = [
                0 => 'Zero',
                1 => 'One',
                2 => 'Two',
                3 => 'Three',
                4 => 'Four',
                5 => 'Five',
                6 => 'Six',
                7 => 'Seven',
                8 => 'Eight',
                9 => 'Nine',
                10 => 'Ten',
                11 => 'Eleven',
                12 => 'Twelve',
                13 => 'Thirteen',
                14 => 'Fourteen',
                15 => 'Fifteen',
                16 => 'Sixteen',
                17 => 'Seventeen',
                18 => 'Eighteen',
                19 => 'Nineteen',
                20 => 'Twenty',
                30 => 'Thirty',
                40 => 'Forty',
                50 => 'Fifty',
                60 => 'Sixty',
                70 => 'Seventy',
                80 => 'Eighty',
                90 => 'Ninety',
                100 => 'Hundred',
                1000 => 'Thousand',
                100000 => 'Lakh',
                10000000 => 'Crore'
            ];
        
            if (!is_numeric($number)) {
                return false;
            }
        
            if (($number >= 0 && (int) $number < 0) || (int) $number < 0 - PHP_INT_MAX) {
                // Overflow
                trigger_error(
                    'convert_number_to_words only accepts numbers between -' . PHP_INT_MAX . ' and ' . PHP_INT_MAX,
                    E_USER_WARNING
                );
                return false;
            }
        
            if ($number < 0) {
                return $negative . convert_number_to_words(abs($number));
            }
        
            $string = $fraction = null;
        
            if (strpos($number, '.') !== false) {
                list($number, $fraction) = explode('.', $number);
            }
        
            switch (true) {
                case $number < 21:
                    $string = $dictionary[$number];
                    break;
                case $number < 100:
                    $tens   = ((int) ($number / 10)) * 10;
                    $units  = $number % 10;
                    $string = $dictionary[$tens];
                    if ($units) {
                        $string .= $hyphen . $dictionary[$units];
                    }
                    break;
                case $number < 1000:
                    $hundreds  = $number / 100;
                    $remainder = $number % 100;
                    $string = $dictionary[(int) $hundreds] . ' ' . $dictionary[100];
                    if ($remainder) {
                        $string .= $conjunction . convert_number_to_words($remainder);
                    }
                    break;
                case $number < 100000:
                    $thousands = $number / 1000;
                    $remainder = $number % 1000;
                    $string = convert_number_to_words((int) $thousands) . ' ' . $dictionary[1000];
                    if ($remainder) {
                        $string .= $remainder < 100 ? $conjunction : $separator;
                        $string .= convert_number_to_words($remainder);
                    }
                    break;
                case $number < 10000000:
                    $lakhs = $number / 100000;
                    $remainder = $number % 100000;
                    $string = convert_number_to_words((int) $lakhs) . ' ' . $dictionary[100000];
                    if ($remainder) {
                        $string .= $remainder < 100 ? $conjunction : $separator;
                        $string .= convert_number_to_words($remainder);
                    }
                    break;
                default:
                    $crores = $number / 10000000;
                    $remainder = $number % 10000000;
                    $string = convert_number_to_words((int) $crores) . ' ' . $dictionary[10000000];
                    if ($remainder) {
                        $string .= $remainder < 100 ? $conjunction : $separator;
                        $string .= convert_number_to_words($remainder);
                    }
                    break;
            }
        
            if (null !== $fraction && is_numeric($fraction)) {
                $string .= $decimal;
                $words = [];
                foreach (str_split((string) $fraction) as $number) {
                    $words[] = $dictionary[$number];
                }
                $string .= implode(' ', $words);
            }
        
            return $string;
        }
        
        $total_price_in_words = convert_number_to_words($final_price_with_gst);
        $final_price_with_gst = number_format($final_price_with_gst, 2);

        // Get the URL of the custom logo
        $custom_logo_id = get_theme_mod('custom_logo');
        $logo_url = wp_get_attachment_image_url($custom_logo_id, 'full');

        // Format the data for PDF
        $response = '
        <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>Quotation</title>
                <style>
                    @page {
                            size: A4;
                            margin: 20mm 15mm; /* Adjust margins to accommodate footer */
                        }
                        @page :left {
                            @bottom-left {
                                content: "Page " counter(page) " of " counter(pages);
                                font-size: 10px;
                                color: #000;
                            }
                        }
                        @page :right {
                            @bottom-left {
                                content: "Page " counter(page) " of " counter(pages);
                                font-size: 10px;
                                color: #000;
                            }
                        }
                        body {
                            margin: 0;
                            padding: 0;
                            font-family: sans-serif;
                            position: relative; /* Ensure body is positioned relative */
                            min-height: 297mm; /* Ensure body is at least the height of A4 */
                        }
                        h3 {
                            color:#000;
                            font-weight:600;
                        }
                        p {
                            margin: 5px 0;
                        }
                        table {
                            width: 100%;
                            border-collapse: collapse;
                            margin-bottom: 15px;
                            font-size: 12px;
                        }
                        th, td {
                            border: 1px solid #000;
                            padding: 5px; /* Adjusted padding for tighter look */
                            text-align: center; /* Centered text in table */
                            vertical-align: middle; /* Vertically align text */
                            color:#000;
                            font-size:12px;
                        }
                        .table-title {
                            text-align: left;
                            padding-left: 5px;
                            font-weight: bold;
                        }
                        .no-border {
                            border-left: none;
                            border-right: none;
                        }
                        .header{
                            display: flex;
                            justify-content: space-between;
                            align-items: center;
                            margin-bottom: 20px;
                            margin-top: 10px;
                        }

                        .header-left{
                            text-align: left;
                        }

                        .header-right{
                            text-align: right;
                        }

                        .header h2 {
                            margin: 0;
                            text-align: center;
                            width: 100%;
                        }
                        .content {
                            margin-top: 20px;
                        }

                        p {
                            page-break-inside: avoid;
                            margin-top: 0;
                            margin-bottom: 5px;
                            color:#000;
                            font-weight:600;
                        }

                        .avoid-page-break {
                            page-break-inside: avoid;
                        }

                        .page-break {
                            page-break-before: always;
                        }
                        .avoid-page-break {
                            page-break-inside: avoid;
                        }
                        footer {
                            position: absolute;
                            bottom: 0;
                            left: 0;
                            right: 0;
                            height: 30px; /* Adjust height as needed */
                            background-color: #f0f0f0;
                            text-align: center;
                            padding: 5px;
                        }
                    .bottom-align {
                        position: absolute;
                        bottom: 0;
                        left: 0;
                        width: 100%;
                        padding: 10px; /* Add padding if necessary */
                        box-sizing: border-box; /* Include padding and border in the element"s total width and height */
                        background: white; /* Ensure the background is set so text is visible */
                    }
                </style>
            </head>
                <body style="margin:0px 0px; padding:0px 0px;">
                    <section>
                        <div class="header">
                            <div class="header-left">
                                <img src="' . esc_url($logo_url) . '" width="150" height="auto" />
                            </div>
                        </div>
                        <div class="content">
                            <div style="text-align:center;">
                                <h3 style="font-size:18px; font-weight:800; margin:22px 0px px 0px;">QUOTATION</h3>
                                <p style="font-size:12px; padding:0px 40px;">'.$assign_location_name.'</p>
                            </div>
                            <div class="header">
                                <div class="header-left">
                                    <p style="font-size:12px;"><strong>GSTIN :'.$assign_location_gst.'</strong></p>
                                    <p style="font-size:12px;"><strong>UPID :GMMCOLTD34959@HDFCBANK</strong></p>
                                    <p style="font-size:12px;">Customer Name : ' . $user_name . '</p>
                                    <p style="font-size:12px;">Address: '. $billing_address .'</p>
                                </div>
                                <div class="header-right">
                                    <p style="font-size:12px;">Virtual Account No: NA</p>
                                    <p style="font-size:12px;">IFSC Code: NA</p>
                                    <p style="font-size:12px;">Quote Number: '. $quote_number .'</p>
                                    <p style="font-size:12px;">Quote Date: '. $quote_date .'</p>
                                    <p style="font-size:12px;">Version Number: 00'.$version_number.'</p>
                                </div>
                            </div>
                            <p style="font-size:12px;"><strong>Kind Attn: ' . $user_name . '</strong></p>
                            <p style="font-size:12px;">Dear Sir/Madam,</p>
                            <p style="font-size:12px;"><strong>Subject: Quotation for renting ' . $product_name . '</strong></p>
                            <p style="font-size:12px;">At the outset, we thank you very much for your enquiry and interest for acquiring our rental services. Further to our discussions, we are pleased to forward our best offer.</p>
                            <table class="avoid-page-break">
                            <h3 style="font-size:18px; font-weight:800; margin:25px 0px 18px 0px;">Product Description:</h3>
                                <thead>
                                    <tr>
                                        <th style="font-weight:700;">S.No</th>
                                        <th style="font-weight:700;">Model of Equipment Description HSN</th>
                                        <th style="font-weight:700;">Qty (UOM)</th>
                                        <th style="font-weight:700;">Hours of Operation</th>
                                        <th style="font-weight:700;">Rental Charges</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr>
                                        <td style="font-size:12px;>">1</td>
                                        <td style="font-size:12px;>">
                                        ' . $product_name . '
                                        </td>
                                        <td style="font-size:12px;>">1 EA</td>
//                                         <td style="font-size:12px;>">'. $total_hours .'</td>
                                        <td style="font-size:12px;>">'. $price_wo_gst .'</td>
                                    </tr>
                                    <tr>
                                        <td colspan="3" rowspan="2" style="text-align:left;">Total Price in Words (INR):<br><br>
                                            '. $total_price_in_words .' rupees.</td>
                                        <td>GST @ 18.00%</td>
                                        <td style="font-size:12px;>">'. $gst_amount .'</td>
                                    </tr>
                                    <tr>
                                        <td>Net Value</td>
                                        <td style="font-size:12px;>">'. $final_price_with_gst. '</td>
                                    </tr>
                                </tbody>
                            </table>
                            <div class="avoid-page-break">
                                <h2 style="font-size:20px; font-weight:800;margin:22px 0px 15px 0px;">Terms and conditions</h2>
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Hire Charges</h3>
                                <p style="font-size:12px;">'.nl2br($dynamic_terms).' </p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Validity of Quotation</h3>
                                <p style="font-size:12px;">1) Our offer is valid for a period of 15 days from the date of quotation. Please ensure to have the latest quotation at the time of placing the order.</p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Taxes & Duties</h3>
                                <p style="font-size:12px;">1) GST as applicable will be charged separately on invoice value and will be payable by the hirer extra at actual.</p>
                                <p style="font-size:12px;">2) Any other taxes, duties or levies as applicable will be borne by the hirer at actual.</p>
                                <p style="font-size:12px;">3) The hirer will issue TDS Certificate at the end of each quarter and immediately on closure of the agreement.</p>
                                <p style="font-size:12px;">4) Hirer will furnish TAN/GST Number.</p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Security Deposit</h3>
                                <p style="font-size:12px;">1) The Hirer shall pay an amount equal to Rental Charges as security deposit along with the Order.</p>
                                <p style="font-size:12px;">2) Gmmco will dispatch & commission the equipment to the hirer only on receipt of the security deposit above.</p>
                                <p style="font-size:12px;">3) The Security Deposit shall not carry any interest and will be refunded at the time of dehiring of the Equipment after adjusting pending hire charges if any or any other dues payable by the Hirer to Gmmco.</p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Transportation</h3>
                                <p style="font-size:12px;">1) To & Fro Transportation will be Borne by Hirer Scope (Contact Period below 6 months Mob & De-mob Hirer scope / If above 6 months Mob (Hirer) & De-Mob (Gmmco)).</p>
                                <p style="font-size:12px;">2) Transit insurance will be Gmmco"s responsibility.</p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Delivery & Commissioning</h3>
                                <p style="font-size:12px;">1) Gmmco will dispatch the equipment after getting confirmed order with security advance.</p>
                                <p style="font-size:12px;">2) Gmmco will arrange for commissioning of the Equipment free of cost. The Hirer will provide the necessary semi-skilled labor and the cranage for loading and unloading the equipment at the site.</p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Operators</h3>
                                <p style="font-size:12px;">1) Each Equipment will be supported by One Operator for Day Operation & Operator charges will be borne by Gmmco.</p>
                                <p style="font-size:12px;">2) For extra Operator requirement charges will be as applicable.</p>
                                <p style="font-size:12px;">3) Food and accommodation and Transportation for the Operators to site will be borne by the hirer.</p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Fuel</h3>
                                <p style="font-size:12px;">1) Uncontaminated High-Speed Diesel required for the operation of the equipment shall be provided by the hirer at the site at his costs.</p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Maintenance and Repairs</h3>
                                <p style="font-size:12px;">1) The routine maintenance and repairs of the equipment will be carried out by Gmmco personnel by providing the necessary parts or lubricating oil as may be required.</p>
                                <p style="font-size:12px;">2) The Hirer shall spare the equipment for carrying out routine maintenance without delay.</p>
                                <p style="font-size:12px;">3) Gmmco will arrange for the necessary spare parts as may be required for carrying out the repairs and maintenance subject to proper operation of the equipment.</p>
                                <p style="font-size:12px;">4) The Hirer agrees to provide unskilled labor as and when required for maintenance of the equipment at their own costs.</p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Invoicing</h3>
                                <p style="font-size:12px;">1) The hire charges will be invoiced monthly in advance by Gmmco and the hirer shall make payment for the same within 7 days of receipt of invoice.</p>
                                <p style="font-size:12px;">2) No reduction in hire charges is permitted for a breakdown lasting less than 24 hours.</p>
                                <p style="font-size:12px;">3) However, deductions in hire charges will be permissible on a pro-rata basis only if the breakdown lasts for more than 24 hours.</p>
                                <p style="font-size:12px;">4) The hirer will not be entitled to make any deduction in Log sheet for the following reasons:</p>
                                <p style="font-size:12px;">a) Delay in reporting the breakdown to Gmmco.</p>
                                <p style="font-size:12px;">b) Major Breakdown due to fuel contamination or misuse/abuse or accident.</p>
                                <p style="font-size:12px;">5) Payment Terms: Hire Charges will be payable within 7 days from the date of invoice. In case of delay in payment beyond 30 days from the date of Invoice the hirer shall be liable to pay penal interest @ 2% p.m. from the due date till the date of receipt of payment.</p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Dispute Resolution</h3>
                                <p style="font-size:12px;">1) Any Dispute arising out of this agreement shall be settled by mutual discussions failing which the courts at Bangalore will have the Jurisdiction to adjudicate the Dispute.</p>
                            </div>

                            <div class="avoid-page-break">
                                <h3 style="font-size:18px; font-weight:800;margin:22px 0px 15px 0px;">Other Terms</h3>
                                <p style="font-size:12px;">'.nl2br($dynamic_terms_2).' </p>
                            </div>
                        </div>
                    
                    </section>
            </body>
        </html>';

        echo $response;
    } else {
        echo '
            <html>
            <body>
                <p style="font-size:12px;">No product name found.</p>
                <p>No dynamic terms found.</p>
            </body>
            </html>
        ';
    }

    wp_die();
}

// quotation notification
function quotationNotification() {
    if (is_user_logged_in()) {
        global $wpdb;
        $user_id = get_current_user_id();
        
        // Fetch the latest quotation id and qt_status based on the most recent update_at timestamp
        $quotation = $wpdb->get_row($wpdb->prepare("
            SELECT id, qt_status FROM wp_quotation 
            WHERE user_id = %d 
            AND cs_view = 1
            ORDER BY updated_at DESC 
            LIMIT 1
        ", $user_id));

        // Check if a quotation exists and if the status is "Revised" or "Quote Send to Customer"
        if ($quotation && ($quotation->qt_status === "Revised" || $quotation->qt_status === "Quote Send to Customer")) {
            // Generate message based on status
            if ($quotation->qt_status === "Quote Send to Customer") {
               $message = "New qutation is created";
           } elseif ($quotation->qt_status === "Revised") {
               $message = "Qutation is revised";
           }
           
           $quotation_url = esc_url(site_url('/my-account/quotation/')); 
           $button_html = '<a href="' . $quotation_url . '" class="button wc-forward" style="display: inline-block; background-color:#000;padding:5px 10px;border-radius:5px;font-size:13px;">View Quotations</a>';
           echo '<div class="woocommerce-info">';
           echo "<span>{$message}</span>";
           echo $button_html;
           echo '</div>';
        } 
    } else {
        echo "<p>Please log in to view notifications.</p>";
    }
}
add_action('woocommerce_account_notification_endpoint', 'quotationNotification');

Youez - 2016 - github.com/yon3zu
LinuXploit