file code

create_tables(); $database->update_tables(); flush_rewrite_rules(); } public function deactivate() { flush_rewrite_rules(); } public function init() { $this->load_dependencies(); if (is_admin()) { new DCM_Admin(); } new DCM_Ajax(); new DCM_Challan(); new DCM_Import_Export(); load_plugin_textdomain(‘delivery-challan’, false, dirname(plugin_basename(__FILE__)) . ‘/languages’); } private function load_dependencies() { $core_files = array( ‘includes/class-dcm-database.php’, ‘includes/class-dcm-admin.php’, ‘includes/class-dcm-ajax.php’, ‘includes/class-dcm-challan.php’ ); $additional_files = array( ‘includes/class-dcm-parties.php’, ‘includes/class-dcm-products.php’, ‘includes/class-dcm-price-list.php’, ‘includes/class-dcm-images.php’, ‘includes/class-dcm-import-export.php’ ); foreach ($core_files as $file) { if (file_exists(DCM_PLUGIN_PATH . $file)) { require_once DCM_PLUGIN_PATH . $file; } else { error_log(‘DCM Missing core file: ‘ . $file); } } foreach ($additional_files as $file) { if (file_exists(DCM_PLUGIN_PATH . $file)) { require_once DCM_PLUGIN_PATH . $file; } } } } Delivery_Challan_Manager::get_instance(); function dcm_challan_manager_shortcode($atts) { if (!is_user_logged_in()) { return ‘

Please login to access delivery challan manager.’; } ob_start(); ?>

Delivery Challan Manager

Use the admin panel to manage delivery challans.

Go to Challan Manager ${rowCount} Select Product get_results(“SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_name”); foreach ($products as $product): ?> product_name); ?> – 0.00 Remove `; $(‘#challan_items’).append(newRow); console.log(‘✅ Row added successfully! Total rows:’, rowCount); updateTotals(); } $(‘#add_item’).on(‘click’, function(e) { e.preventDefault(); console.log(‘➕ Add button clicked!’); addItemRow(); }); $(document).on(‘click’, ‘.remove-item’, function(e) { e.preventDefault(); $(this).closest(‘.item-row’).remove(); console.log(‘🗑️ Row removed’); renumberRows(); updateTotals(); }); $(document).on(‘change’, ‘.item-select’, function() { const row = $(this).closest(‘.item-row’); const productId = $(this).val(); const partyId = $(‘#party_id’).val(); const option = $(this).find(‘option:selected’); console.log(‘Product selected:’, productId); if (productId) { const itemCode = option.data(‘code’) || ”; row.find(‘.item-code’).text(itemCode); if (partyId) { console.log(‘Getting price for party:’, partyId); getProductPrice(partyId, productId, row); } else { row.find(‘.price’).val(‘0’); calculateRowAmount(row); updateTotals(); } } else { row.find(‘.item-code’).text(‘-‘); row.find(‘.price’).val(”); row.find(‘.amount’).text(‘0.00’); updateTotals(); } }); $(document).on(‘input’, ‘.quantity, .discount’, function() { const row = $(this).closest(‘.item-row’); calculateRowAmount(row); updateTotals(); }); $(‘#party_id’).on(‘change’, function() { const partyId = $(this).val(); console.log(‘Party changed to:’, partyId); if (partyId) { $(‘.item-select’).each(function() { if ($(this).val()) { $(this).trigger(‘change’); } }); } else { $(‘.item-row’).each(function() { $(this).find(‘.price’).val(‘0’); calculateRowAmount($(this)); }); updateTotals(); } }); function calculateRowAmount(row) { const quantity = parseFloat(row.find(‘.quantity’).val()) || 0; const price = parseFloat(row.find(‘.price’).val()) || 0; const discount = parseFloat(row.find(‘.discount’).val()) || 0; console.log(‘Calculating row amount:’, {quantity, price, discount}); const discountAmount = (price * quantity * discount) / 100; const amount = (price * quantity) – discountAmount; row.find(‘.amount’).text(amount.toFixed(2)); } function updateTotals() { let totalQty = 0; let totalAmount = 0; $(‘.item-row’).each(function() { const quantity = parseFloat($(this).find(‘.quantity’).val()) || 0; const amount = parseFloat($(this).find(‘.amount’).text()) || 0; totalQty += quantity; totalAmount += amount; }); $(‘#total_qty’).text(totalQty); $(‘#total_amount’).text(totalAmount.toFixed(2)); console.log(‘📊 Totals updated – Qty:’, totalQty, ‘Amount:’, totalAmount); updateAmountInWords(totalAmount); } function updateAmountInWords(amount) { if (amount > 0) { const words = convertNumberToWords(amount); $(‘#amount_in_words’).val(‘Rupees ‘ + words + ‘ Only’); } else { $(‘#amount_in_words’).val(”); } } function convertNumberToWords(num) { if (num === 0) return ‘Zero’; const ones = [”, ‘One’, ‘Two’, ‘Three’, ‘Four’, ‘Five’, ‘Six’, ‘Seven’, ‘Eight’, ‘Nine’]; const teens = [‘Ten’, ‘Eleven’, ‘Twelve’, ‘Thirteen’, ‘Fourteen’, ‘Fifteen’, ‘Sixteen’, ‘Seventeen’, ‘Eighteen’, ‘Nineteen’]; const tens = [”, ”, ‘Twenty’, ‘Thirty’, ‘Forty’, ‘Fifty’, ‘Sixty’, ‘Seventy’, ‘Eighty’, ‘Ninety’]; function convertHundreds(n) { let str = ”; if (n >= 100) { str += ones[Math.floor(n / 100)] + ‘ Hundred ‘; n %= 100; } if (n >= 20) { str += tens[Math.floor(n / 10)] + ‘ ‘; n %= 10; } else if (n >= 10) { str += teens[n – 10] + ‘ ‘; n = 0; } if (n > 0) { str += ones[n] + ‘ ‘; } return str.trim(); } let words = ”; let n = Math.floor(num); if (n >= 10000000) { words += convertHundreds(Math.floor(n / 10000000)) + ‘ Crore ‘; n %= 10000000; } if (n >= 100000) { words += convertHundreds(Math.floor(n / 100000)) + ‘ Lakh ‘; n %= 100000; } if (n >= 1000) { words += convertHundreds(Math.floor(n / 1000)) + ‘ Thousand ‘; n %= 1000; } words += convertHundreds(n); return words.trim(); } function renumberRows() { rowCount = 0; $(‘.item-row’).each(function() { rowCount++; $(this).find(‘.sr-no’).text(rowCount); }); console.log(‘🔢 Rows renumbered. Total:’, rowCount); } function getProductPrice(partyId, productId, row) { console.log(‘💰 Fetching price for product:’, productId, ‘party:’, partyId); $.ajax({ url: dcm_ajax.ajax_url, type: ‘POST’, data: { action: ‘get_product_price’, party_id: partyId, product_id: productId, nonce: dcm_ajax.nonce }, beforeSend: function() { row.addClass(‘dcm-loading’); }, success: function(response) { if (response.success) { const price = response.data.price || 0; console.log(‘✅ Price received:’, price); row.find(‘.price’).val(price); calculateRowAmount(row); updateTotals(); if (price === 0) { console.log(‘⚠️ No price found for this product’); } } else { console.log(‘❌ Error in response’); row.find(‘.price’).val(‘0’); calculateRowAmount(row); updateTotals(); } }, error: function(xhr, status, error) { console.log(‘❌ AJAX Error:’, error); row.find(‘.price’).val(‘0’); calculateRowAmount(row); updateTotals(); }, complete: function() { row.removeClass(‘dcm-loading’); } }); } $(‘#save_challan’).on(‘click’, function(e) { e.preventDefault(); console.log(‘💾 Save challan clicked’); if (!$(‘#party_id’).val()) { alert(‘❌ Please select a party.’); return; } const hasItems = $(‘.item-select’).filter(function() { return $(this).val() !== ”; }).length > 0; if (!hasItems) { alert(‘❌ Please add at least one item to the challan.’); return; } let valid = true; $(‘.item-row’).each(function() { const productId = $(this).find(‘.item-select’).val(); const quantity = $(this).find(‘.quantity’).val(); if (productId && (!quantity || quantity <= 0)) { alert(‘❌ Please enter a valid quantity for all items.’); $(this).find(‘.quantity’).focus(); valid = false; return false; } }); if (!valid) return; const formData = new FormData(); formData.append(‘action’, ‘save_challan’); formData.append(‘nonce’, dcm_ajax.nonce); formData.append(‘challan_number’, $(‘#challan_number’).val()); formData.append(‘party_id’, $(‘#party_id’).val()); formData.append(‘challan_date’, $(‘#challan_date’).val()); formData.append(‘total_amount’, $(‘#total_amount’).text()); formData.append(‘amount_in_words’, $(‘#amount_in_words’).val()); formData.append(‘remarks’, $(‘#remarks’).val()); let itemIndex = 0; $(‘.item-row’).each(function() { const productId = $(this).find(‘.item-select’).val(); if (productId) { formData.append(`items[${itemIndex}][product_id]`, productId); formData.append(`items[${itemIndex}][quantity]`, $(this).find(‘.quantity’).val()); formData.append(`items[${itemIndex}][price]`, $(this).find(‘.price’).val()); formData.append(`items[${itemIndex}][discount]`, $(this).find(‘.discount’).val()); formData.append(`items[${itemIndex}][amount]`, $(this).find(‘.amount’).text()); itemIndex++; } }); $.ajax({ url: dcm_ajax.ajax_url, type: ‘POST’, data: formData, processData: false, contentType: false, beforeSend: function() { $(‘#save_challan’).prop(‘disabled’, true).text(‘Saving…’); }, success: function(response) { console.log(‘Save response:’, response); if (response.success) { alert(‘✅ Challan saved successfully!’); if (response.data.redirect_url) { window.location.href = response.data.redirect_url; } } else { alert(‘❌ Error saving challan: ‘ + (response.data || ‘Unknown error’)); } }, error: function(xhr, status, error) { console.error(‘Save error:’, error); alert(‘❌ Error saving challan. Please try again.’); }, complete: function() { $(‘#save_challan’).prop(‘disabled’, false).text(‘Save Challan’); } }); }); $(‘#preview_challan’).on(‘click’, function(e) { e.preventDefault(); alert(‘📋 Please save the challan first, then use the preview option from the challan list.’); }); $(‘#print_challan’).on(‘click’, function(e) { e.preventDefault(); alert(‘🖨️ Please save the challan first, then use the print option from the challan list.’); }); $(‘#export_pdf’).on(‘click’, function(e) { e.preventDefault(); alert(‘📄 PDF export feature will be available in the next update.’); }); $(‘.dcm-datepicker’).datepicker({ dateFormat: ‘yy-mm-dd’, showButtonPanel: true, changeMonth: true, changeYear: true }); addItemRow(); console.log(‘🎉 Delivery Challan Manager initialized successfully!’); console.log(‘✅ Add button ready:’, $(‘#add_item’).length > 0); }); //////////////////////////////////////////////////////////////////////////////// // File: class-dcm-admin.php (4 of 23) // Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/includes/class-dcm-admin.php // Type: php //////////////////////////////////////////////////////////////////////////////// class DCM_Admin { public function __construct() { add_action(‘admin_menu’, array($this, ‘add_admin_menu’)); add_action(‘admin_enqueue_scripts’, array($this, ‘enqueue_admin_scripts’)); add_action(‘admin_init’, array($this, ‘handle_form_submissions’)); } public function add_admin_menu() { add_menu_page( ‘Delivery Challan Manager’, ‘Challan Manager’, ‘manage_options’, ‘delivery-challan-manager’, array($this, ‘admin_dashboard’), ‘dashicons-media-text’, 30 ); add_submenu_page( ‘delivery-challan-manager’, ‘Create Challan’, ‘Create Challan’, ‘manage_options’, ‘create-challan’, array($this, ‘create_challan_page’) ); add_submenu_page( ‘delivery-challan-manager’, ‘Manage Challans’, ‘All Challans’, ‘manage_options’, ‘manage-challans’, array($this, ‘manage_challans_page’) ); add_submenu_page( ‘delivery-challan-manager’, ‘Manage Parties’, ‘Parties’, ‘manage_options’, ‘manage-parties’, array($this, ‘manage_parties_page’) ); add_submenu_page( ‘delivery-challan-manager’, ‘Manage Products’, ‘Products’, ‘manage_options’, ‘manage-products’, array($this, ‘manage_products_page’) ); add_submenu_page( ‘delivery-challan-manager’, ‘Price List’, ‘Price List’, ‘manage_options’, ‘price-list’, array($this, ‘price_list_page’) ); add_submenu_page( ‘delivery-challan-manager’, ‘Reports’, ‘Reports’, ‘manage_options’, ‘challan-reports’, array($this, ‘reports_page’) ); add_submenu_page( ‘delivery-challan-manager’, ‘Import/Export’, ‘Import/Export’, ‘manage_options’, ‘import-export’, array($this, ‘import_export_page’) ); add_submenu_page( ‘delivery-challan-manager’, ‘Comprehensive Price List’, ‘Comprehensive Prices’, ‘manage_options’, ‘comprehensive-price-list’, array($this, ‘comprehensive_price_list_page’) ); add_submenu_page( ‘delivery-challan-manager’, ‘Line Item Report’, ‘Line Item Report’, ‘manage_options’, ‘line-item-report’, array($this, ‘line_item_report_page’) ); } public function enqueue_admin_scripts($hook) { if (strpos($hook, ‘delivery-challan-manager’) === false) { return; } wp_enqueue_script(‘jquery’); wp_enqueue_script(‘jquery-ui-datepicker’); wp_enqueue_style(‘jquery-ui-css’, ‘https: wp_enqueue_style(‘select2-css’, ‘https: wp_enqueue_script(‘select2-js’, ‘https: wp_enqueue_style(‘dcm-admin-css’, DCM_PLUGIN_URL . ‘assets/admin.css’, array(), DCM_PLUGIN_VERSION); wp_enqueue_script(‘dcm-admin-js’, DCM_PLUGIN_URL . ‘assets/admin.js’, array(‘jquery’, ‘select2-js’), DCM_PLUGIN_VERSION, true); wp_localize_script(‘dcm-admin-js’, ‘dcm_ajax’, array( ‘ajax_url’ => admin_url(‘admin-ajax.php’), ‘nonce’ => wp_create_nonce(‘dcm_nonce’), ‘plugin_url’ => DCM_PLUGIN_URL )); } public function handle_form_submissions() { if (isset($_POST[‘dcm_action’])) { switch ($_POST[‘dcm_action’]) { case ‘add_party’: $this->handle_add_party(); break; case ‘update_party’: $this->handle_update_party(); break; case ‘add_product’: $this->handle_add_product(); break; } } } private function handle_add_party() { if (!isset($_POST[‘_wpnonce’]) || !wp_verify_nonce($_POST[‘_wpnonce’], ‘dcm_party_nonce’)) { wp_die(‘Security verification failed.’); } global $wpdb; $party_name = sanitize_text_field($_POST[‘party_name’]); if (empty($party_name)) { wp_die(‘Party name is required.’); } $existing = $wpdb->get_var($wpdb->prepare( “SELECT id FROM {$wpdb->prefix}dcm_parties WHERE party_name = %s”, $party_name )); if ($existing) { wp_die(‘A party with this name already exists.’); } $data = array( ‘party_name’ => $party_name, ‘address’ => sanitize_textarea_field($_POST[‘address’]), ‘phone’ => sanitize_text_field($_POST[‘phone’]), ’email’ => sanitize_email($_POST[’email’]), ‘gstin’ => sanitize_text_field($_POST[‘gstin’]), ‘transport_name’ => sanitize_text_field($_POST[‘transport_name’]), ‘transport_id’ => sanitize_text_field($_POST[‘transport_id’]), ‘default_packing_type’ => sanitize_text_field($_POST[‘default_packing_type’]), ‘default_stickers’ => sanitize_text_field($_POST[‘default_stickers’]), ‘remarks’ => sanitize_textarea_field($_POST[‘remarks’]) ); $result = $wpdb->insert(“{$wpdb->prefix}dcm_parties”, $data); if ($result !== false) { wp_redirect(admin_url(‘admin.php?page=manage-parties&message=added’)); exit; } else { wp_die(‘Error adding party: ‘ . $wpdb->last_error); } } private function handle_update_party() { if (!isset($_POST[‘_wpnonce’]) || !wp_verify_nonce($_POST[‘_wpnonce’], ‘dcm_party_nonce’)) { wp_die(‘Security verification failed.’); } global $wpdb; $party_id = intval($_POST[‘party_id’]); $party_name = sanitize_text_field($_POST[‘party_name’]); if (empty($party_name)) { wp_die(‘Party name is required.’); } $existing = $wpdb->get_var($wpdb->prepare( “SELECT id FROM {$wpdb->prefix}dcm_parties WHERE party_name = %s AND id != %d”, $party_name, $party_id )); if ($existing) { wp_die(‘A party with this name already exists.’); } $data = array( ‘party_name’ => $party_name, ‘address’ => sanitize_textarea_field($_POST[‘address’]), ‘phone’ => sanitize_text_field($_POST[‘phone’]), ’email’ => sanitize_email($_POST[’email’]), ‘gstin’ => sanitize_text_field($_POST[‘gstin’]), ‘transport_name’ => sanitize_text_field($_POST[‘transport_name’]), ‘transport_id’ => sanitize_text_field($_POST[‘transport_id’]), ‘default_packing_type’ => sanitize_text_field($_POST[‘default_packing_type’]), ‘default_stickers’ => sanitize_text_field($_POST[‘default_stickers’]), ‘remarks’ => sanitize_textarea_field($_POST[‘remarks’]) ); $result = $wpdb->update( “{$wpdb->prefix}dcm_parties”, $data, array(‘id’ => $party_id), array(‘%s’, ‘%s’, ‘%s’, ‘%s’, ‘%s’, ‘%s’, ‘%s’, ‘%s’, ‘%s’, ‘%s’), array(‘%d’) ); if ($result !== false) { wp_redirect(admin_url(‘admin.php?page=manage-parties&message=updated’)); exit; } else { wp_die(‘Error updating party: ‘ . $wpdb->last_error); } } private function handle_add_product() { if (!isset($_POST[‘_wpnonce’]) || !wp_verify_nonce($_POST[‘_wpnonce’], ‘dcm_add_product’)) { wp_die(‘Security verification failed.’); } global $wpdb; $product_name = sanitize_text_field($_POST[‘product_name’]); $product_code = sanitize_text_field($_POST[‘product_code’]); if (empty($product_name) || empty($product_code)) { wp_die(‘Product name and code are required.’); } $existing = $wpdb->get_var($wpdb->prepare( “SELECT id FROM {$wpdb->prefix}dcm_products WHERE product_code = %s”, $product_code )); if ($existing) { wp_die(‘A product with this code already exists.’); } $data = array( ‘product_name’ => $product_name, ‘product_code’ => $product_code, ‘description’ => sanitize_textarea_field($_POST[‘description’]) ); if (!empty($_FILES[‘product_image’][‘name’])) { if (!function_exists(‘wp_handle_upload’)) { require_once(ABSPATH . ‘wp-admin/includes/file.php’); } $uploadedfile = $_FILES[‘product_image’]; $upload_overrides = array(‘test_form’ => false); $movefile = wp_handle_upload($uploadedfile, $upload_overrides); if ($movefile && !isset($movefile[‘error’])) { $data[‘product_image’] = $movefile[‘url’]; } } $result = $wpdb->insert(“{$wpdb->prefix}dcm_products”, $data); if ($result !== false) { wp_redirect(admin_url(‘admin.php?page=manage-products&message=added’)); exit; } else { wp_die(‘Error adding product: ‘ . $wpdb->last_error); } } public function admin_dashboard() { global $wpdb; $challan_count = $wpdb->get_var(“SELECT COUNT(*) FROM {$wpdb->prefix}dcm_challans”); $party_count = $wpdb->get_var(“SELECT COUNT(*) FROM {$wpdb->prefix}dcm_parties”); $product_count = $wpdb->get_var(“SELECT COUNT(*) FROM {$wpdb->prefix}dcm_products”); include DCM_PLUGIN_PATH . ‘templates/admin-dashboard.php’; } public function create_challan_page() { include DCM_PLUGIN_PATH . ‘templates/create-challan.php’; } public function manage_challans_page() { include DCM_PLUGIN_PATH . ‘templates/manage-challans.php’; } public function manage_parties_page() { include DCM_PLUGIN_PATH . ‘templates/manage-parties.php’; } public function manage_products_page() { include DCM_PLUGIN_PATH . ‘templates/manage-products.php’; } public function price_list_page() { include DCM_PLUGIN_PATH . ‘templates/price-list.php’; } public function reports_page() { include DCM_PLUGIN_PATH . ‘templates/reports.php’; } public function import_export_page() { include DCM_PLUGIN_PATH . ‘templates/import-export.php’; } public function comprehensive_price_list_page() { include DCM_PLUGIN_PATH . ‘templates/comprehensive-price-list.php’; } public function line_item_report_page() { include DCM_PLUGIN_PATH . ‘templates/line-item-report.php’; } } //////////////////////////////////////////////////////////////////////////////// // File: class-dcm-ajax.php (5 of 23) // Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/includes/class-dcm-ajax.php // Type: php //////////////////////////////////////////////////////////////////////////////// class DCM_Ajax { public function __construct() { add_action(‘wp_ajax_get_product_price’, array($this, ‘get_product_price’)); add_action(‘wp_ajax_save_challan’, array($this, ‘save_challan’)); add_action(‘wp_ajax_print_challan’, array($this, ‘print_challan’)); add_action(‘wp_ajax_generate_challan_number’, array($this, ‘generate_challan_number’)); add_action(‘wp_ajax_delete_challan’, array($this, ‘delete_challan’)); add_action(‘wp_ajax_search_parties’, array($this, ‘search_parties’)); add_action(‘wp_ajax_search_products’, array($this, ‘search_products’)); add_action(‘wp_ajax_delete_party’, array($this, ‘delete_party’)); add_action(‘wp_ajax_get_parties’, array($this, ‘get_parties’)); add_action(‘wp_ajax_delete_product’, array($this, ‘delete_product’)); add_action(‘wp_ajax_get_products’, array($this, ‘get_products’)); } public function generate_challan_number() { check_ajax_referer(‘dcm_nonce’, ‘nonce’); global $wpdb; $last_challan = $wpdb->get_var(“SELECT challan_number FROM {$wpdb->prefix}dcm_challans ORDER BY id DESC LIMIT 1″); if ($last_challan) { $last_number = intval(preg_replace(‘/[^0-9]/’, ”, $last_challan)); $new_number = $last_number + 3; } else { $new_number = 4035; } $challan_number = ‘CH’ . $new_number; wp_send_json_success(array(‘challan_number’ => $challan_number)); } public function get_product_price() { if (!wp_verify_nonce($_POST[‘nonce’], ‘dcm_nonce’)) { wp_send_json_error(‘Security verification failed’); return; } $party_id = intval($_POST[‘party_id’]); $product_id = intval($_POST[‘product_id’]); $price_type = isset($_POST[‘price_type’]) ? sanitize_text_field($_POST[‘price_type’]) : ‘without_packing’; $challan_date = isset($_POST[‘challan_date’]) ? sanitize_text_field($_POST[‘challan_date’]) : date(‘Y-m-d’); global $wpdb; error_log(“DCM DEBUG: Getting price for party_id: $party_id, product_id: $product_id, price_type: $price_type, challan_date: $challan_date”); $price_data = $wpdb->get_row($wpdb->prepare( “SELECT price, discount_percent FROM {$wpdb->prefix}dcm_price_list WHERE party_id = %d AND product_id = %d AND price_type = %s AND effective_date <= %s ORDER BY effective_date DESC LIMIT 1”, $party_id, $product_id, $price_type, $challan_date )); error_log(“DCM DEBUG: Price data found: ” . ($price_data ? ‘YES’ : ‘NO’)); if ($price_data === null) { $price_data = $wpdb->get_row($wpdb->prepare( “SELECT price, discount_percent FROM {$wpdb->prefix}dcm_price_list WHERE party_id = %d AND product_id = %d AND price_type = %s ORDER BY effective_date DESC LIMIT 1”, $party_id, $product_id, $price_type )); error_log(“DCM DEBUG: Fallback price data found: ” . ($price_data ? ‘YES’ : ‘NO’)); } if ($price_data === null) { $price_data = $wpdb->get_row($wpdb->prepare( “SELECT price, discount_percent FROM {$wpdb->prefix}dcm_price_list WHERE party_id = %d AND product_id = %d ORDER BY effective_date DESC LIMIT 1”, $party_id, $product_id )); error_log(“DCM DEBUG: Generic price data found: ” . ($price_data ? ‘YES’ : ‘NO’)); } if ($price_data === null) { error_log(“DCM DEBUG: No price found for party:$party_id, product:$product_id, type:$price_type”); wp_send_json_success(array(‘price’ => 0, ‘discount’ => 0)); } else { error_log(“DCM DEBUG: Price found – Price: {$price_data->price}, Discount: {$price_data->discount_percent}”); wp_send_json_success(array( ‘price’ => floatval($price_data->price), ‘discount’ => floatval($price_data->discount_percent) )); } } public function save_challan() { check_ajax_referer(‘dcm_nonce’, ‘nonce’); global $wpdb; $original_challan_id = isset($_POST[‘original_challan_id’]) ? intval($_POST[‘original_challan_id’]) : 0; $challan_number = sanitize_text_field($_POST[‘challan_number’]); $party_id = intval($_POST[‘party_id’]); $challan_date = sanitize_text_field($_POST[‘challan_date’]); $total_amount = floatval($_POST[‘total_amount’]); $amount_in_words = sanitize_text_field($_POST[‘amount_in_words’]); $remarks = sanitize_textarea_field($_POST[‘remarks’]); if ($original_challan_id == 0) { $existing_challan = $wpdb->get_row($wpdb->prepare( “SELECT id FROM {$wpdb->prefix}dcm_challans WHERE challan_number = %s”, $challan_number )); if ($existing_challan) { wp_send_json_error(‘Challan number already exists. Please generate a new challan number.’); return; } } $challan_data = array( ‘challan_number’ => $challan_number, ‘party_id’ => $party_id, ‘challan_date’ => $challan_date, ‘total_amount’ => $total_amount, ‘amount_in_words’ => $amount_in_words, ‘remarks’ => $remarks, ‘created_by’ => get_current_user_id() ); if ($original_challan_id > 0) { $result = $wpdb->update( “{$wpdb->prefix}dcm_challans”, $challan_data, array(‘id’ => $original_challan_id), array(‘%s’, ‘%d’, ‘%s’, ‘%f’, ‘%s’, ‘%s’, ‘%d’), array(‘%d’) ); $challan_id = $original_challan_id; if ($result !== false) { $wpdb->delete( “{$wpdb->prefix}dcm_challan_items”, array(‘challan_id’ => $challan_id), array(‘%d’) ); } } else { $result = $wpdb->insert( “{$wpdb->prefix}dcm_challans”, $challan_data, array(‘%s’, ‘%d’, ‘%s’, ‘%f’, ‘%s’, ‘%s’, ‘%d’) ); $challan_id = $wpdb->insert_id; } if ($result !== false) { if (!empty($_POST[‘items’])) { foreach ($_POST[‘items’] as $index => $item) { if (!empty($item[‘product_id’])) { $item_data = array( ‘challan_id’ => $challan_id, ‘product_id’ => intval($item[‘product_id’]), ‘packing_type’ => sanitize_text_field($item[‘packing_type’]), ‘quantity’ => intval($item[‘quantity’]), ‘price’ => floatval($item[‘price’]), ‘discount_percent’ => floatval($item[‘discount’]), ‘amount’ => floatval($item[‘amount’]), ‘item_order’ => $index + 1 ); $wpdb->insert(“{$wpdb->prefix}dcm_challan_items”, $item_data); } } } $action = $original_challan_id > 0 ? ‘updated’ : ‘saved’; wp_send_json_success(array( ‘challan_id’ => $challan_id, ‘message’ => “Challan {$action} successfully!”, ‘redirect_url’ => admin_url(‘admin.php?page=manage-challans&message=’ . $action) )); } else { wp_send_json_error(‘Error saving challan to database.’); } } public function print_challan() { check_ajax_referer(‘dcm_nonce’, ‘nonce’); $challan_id = intval($_POST[‘challan_id’]); $challan_html = $this->generate_challan_html($challan_id); wp_send_json_success(array(‘html’ => $challan_html)); } public function delete_challan() { check_ajax_referer(‘dcm_nonce’, ‘nonce’); global $wpdb; $challan_id = intval($_POST[‘challan_id’]); $challan = $wpdb->get_row($wpdb->prepare( “SELECT * FROM {$wpdb->prefix}dcm_challans WHERE id = %d”, $challan_id )); if (!$challan) { wp_send_json_error(array(‘message’ => ‘Challan not found.’)); } $challan_number = $challan->challan_number; $wpdb->query(‘START TRANSACTION’); try { $items_deleted = $wpdb->delete( “{$wpdb->prefix}dcm_challan_items”, array(‘challan_id’ => $challan_id), array(‘%d’) ); $challan_deleted = $wpdb->delete( “{$wpdb->prefix}dcm_challans”, array(‘id’ => $challan_id), array(‘%d’) ); if ($challan_deleted !== false) { $wpdb->query(‘COMMIT’); wp_send_json_success(array( ‘message’ => ‘Challan ‘ . $challan_number . ‘ deleted successfully!’, ‘challan_id’ => $challan_id, ‘challan_number’ => $challan_number )); } else { $wpdb->query(‘ROLLBACK’); wp_send_json_error(array(‘message’ => ‘Error deleting challan from database.’)); } } catch (Exception $e) { $wpdb->query(‘ROLLBACK’); wp_send_json_error(array(‘message’ => ‘Database error: ‘ . $e->getMessage())); } } private function generate_challan_html($challan_id) { global $wpdb; $challan = $wpdb->get_row($wpdb->prepare( “SELECT c.*, p.party_name, p.address, p.phone, p.email, p.gstin FROM {$wpdb->prefix}dcm_challans c LEFT JOIN {$wpdb->prefix}dcm_parties p ON c.party_id = p.id WHERE c.id = %d”, $challan_id )); if (!$challan) { return ‘

Challan not found!’; } $items = $wpdb->get_results($wpdb->prepare( “SELECT ci.*, p.product_name, p.product_code, p.product_image FROM {$wpdb->prefix}dcm_challan_items ci LEFT JOIN {$wpdb->prefix}dcm_products p ON ci.product_id = p.id WHERE ci.challan_id = %d ORDER BY ci.item_order”, $challan_id )); ob_start(); ?> Delivery Challan – <?php echo $challan->challan_number; ?> Print ChallanClose

H A R I K

Delivery Challan

M/s party_name); ?>
address): ?> Address: address); ?>
gstin): ?> GSTIN: gstin); ?>

$item): $total_qty += $item->quantity; $total_amount += $item->amount; ?>

                        <?php for ($i = count($items); $i < 10; $i++): ?>
                        <tr>
                            <td>&nbsp;</td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                        </tr>
                        <?php endfor; ?>
                    </tbody>
                    <tfoot>
                        <tr class="totals-row">
                            <td colspan="3">Total</td>
                            <td><?php echo $total_qty; ?></td>
                            <td></td>
                            <td></td>
                            <td><?php echo number_format($total_amount, 2); ?></td>
                        </tr>
                    </tfoot>
                </table>

                <div class="amount-words">
                    <strong>Amount in Words:-</strong><br>
                    <?php echo esc_html($challan->amount_in_words); ?>
                </div>

                <?php if ($challan->remarks): ?>
                <div class="remarks">
                    <strong>Remarks:-</strong> <?php echo esc_html($challan->remarks); ?>
                </div>
                <?php endif; ?>

                <div class="footer">
                    <em>Thanks for your Business</em>
                </div>
            </div>
            <?php endfor; ?>
        </div>

        <script>
            window.onload = function() {
                setTimeout(function() {
                    window.print();
                }, 500);
            };
        </script>
    </body>
    </html>
    <?php
    return ob_get_clean();
}

public function delete_party() {
    check_ajax_referer('dcm_nonce', 'nonce');

    global $wpdb;
    $party_id = intval($_POST['party_id']);

    $party = $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}dcm_parties WHERE id = %d",
        $party_id
    ));

    if (!$party) {
        wp_send_json_error(array('message' => 'Party not found.'));
    }

    $challan_count = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->prefix}dcm_challans WHERE party_id = %d",
        $party_id
    ));

    if ($challan_count > 0) {
        wp_send_json_error(array('message' => 'Cannot delete party. It is used in ' . $challan_count . ' challan(s).'));
    }

    $result = $wpdb->delete(
        "{$wpdb->prefix}dcm_parties",
        array('id' => $party_id),
        array('%d')
    );

    if ($result !== false) {
        wp_send_json_success(array('message' => 'Party deleted successfully!'));
    } else {
        wp_send_json_error(array('message' => 'Error deleting party.'));
    }
}

public function delete_product() {
    check_ajax_referer('dcm_nonce', 'nonce');

    global $wpdb;
    $product_id = intval($_POST['product_id']);

    $product = $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}dcm_products WHERE id = %d",
        $product_id
    ));

    if (!$product) {
        wp_send_json_error(array('message' => 'Product not found.'));
    }

    $challan_item_count = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->prefix}dcm_challan_items WHERE product_id = %d",
        $product_id
    ));

    if ($challan_item_count > 0) {
        wp_send_json_error(array('message' => 'Cannot delete product. It is used in ' . $challan_item_count . ' challan item(s).'));
    }

    $price_list_count = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->prefix}dcm_price_list WHERE product_id = %d",
        $product_id
    ));

    if ($price_list_count > 0) {
        wp_send_json_error(array('message' => 'Cannot delete product. It is used in price list entries.'));
    }

    $result = $wpdb->delete(
        "{$wpdb->prefix}dcm_products",
        array('id' => $product_id),
        array('%d')
    );

    if ($result !== false) {
        wp_send_json_success(array('message' => 'Product deleted successfully!'));
    } else {
        wp_send_json_error(array('message' => 'Error deleting product.'));
    }
}

public function get_parties() {
    check_ajax_referer('dcm_nonce', 'nonce');

    global $wpdb;
    $parties = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_parties ORDER BY party_name");

    wp_send_json_success($parties);
}

public function get_products() {
    check_ajax_referer('dcm_nonce', 'nonce');

    global $wpdb;
    $products = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_name");

    wp_send_json_success($products);
}

public function search_parties() {
check_ajax_referer(‘dcm_nonce’, ‘nonce’);

global $wpdb;

$search_term = isset($_GET['q']) ? sanitize_text_field($_GET['q']) : '';
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$per_page = 10;
$offset = ($page - 1) * $per_page;

$where = '';
if (!empty($search_term)) {
    $where = $wpdb->prepare(" WHERE party_name LIKE %s OR phone LIKE %s OR email LIKE %s", 
        '%' . $wpdb->esc_like($search_term) . '%',
        '%' . $wpdb->esc_like($search_term) . '%',
        '%' . $wpdb->esc_like($search_term) . '%'
    );
}

$parties = $wpdb->get_results(
    "SELECT * FROM {$wpdb->prefix}dcm_parties 
     {$where} 
     ORDER BY party_name 
     LIMIT {$offset}, {$per_page}"
);

$total = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}dcm_parties {$where}");

$results = array();
foreach ($parties as $party) {
    $results[] = array(
        'id' => $party->id,
        'text' => $party->party_name,
        'address' => $party->address,
        'phone' => $party->phone,
        'email' => $party->email,
        'gstin' => $party->gstin,
        'transport_name' => isset($party->transport_name) ? $party->transport_name : '',
        'transport_id' => isset($party->transport_id) ? $party->transport_id : '',
        'default_packing_type' => isset($party->default_packing_type) ? $party->default_packing_type : 'without_packing',
        'default_stickers' => isset($party->default_stickers) ? $party->default_stickers : 'no_stickers'
    );
}

wp_send_json(array(
    'results' => $results,
    'pagination' => array(
        'more' => ($offset + count($parties)) < $total
    )
));

}

public function search_products() {
check_ajax_referer(‘dcm_nonce’, ‘nonce’);

global $wpdb;

$search_term = isset($_GET['q']) ? sanitize_text_field($_GET['q']) : '';
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$per_page = 10;
$offset = ($page - 1) * $per_page;

$where = '';
if (!empty($search_term)) {
    $where = $wpdb->prepare(" WHERE product_name LIKE %s OR product_code LIKE %s", 
        '%' . $wpdb->esc_like($search_term) . '%',
        '%' . $wpdb->esc_like($search_term) . '%'
    );
}

$products = $wpdb->get_results(
    "SELECT * FROM {$wpdb->prefix}dcm_products 
     {$where} 
     ORDER BY product_name 
     LIMIT {$offset}, {$per_page}"
);

$total = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}dcm_products {$where}");

$results = array();
foreach ($products as $product) {
    $results[] = array(
        'id' => $product->id,
        'text' => $product->product_name,
        'code' => $product->product_code,
        'image' => $product->product_image
    );
}

wp_send_json(array(
    'results' => $results,
    'pagination' => array(
        'more' => ($offset + count($products)) < $total
    )
));

}
}

new DCM_Ajax();

////////////////////////////////////////////////////////////////////////////////
// File: class-dcm-challan.php (6 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/includes/class-dcm-challan.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

class DCM_Challan {

public function __construct() {
    add_action('wp_ajax_generate_challan_number', array($this, 'generate_challan_number'));
    add_action('wp_ajax_get_product_price', array($this, 'get_product_price'));
    add_action('wp_ajax_save_challan', array($this, 'save_challan'));
    add_action('wp_ajax_print_challan', array($this, 'print_challan'));
}

public function generate_challan_number() {
    check_ajax_referer('dcm_nonce', 'nonce');

    global $wpdb;

    $last_challan = $wpdb->get_var("SELECT challan_number FROM {$wpdb->prefix}dcm_challans ORDER BY id DESC LIMIT 1");

    if ($last_challan) {
        $last_number = intval(preg_replace('/[^0-9]/', '', $last_challan));
        $new_number = $last_number + 3; 
    } else {
        $new_number = 4035; 
    }

    $challan_number = 'CH' . $new_number;

    wp_send_json_success(array('challan_number' => $challan_number));
}

public function get_product_price() {
    check_ajax_referer('dcm_nonce', 'nonce');

    $party_id = intval($_POST['party_id']);
    $product_id = intval($_POST['product_id']);

    global $wpdb;

    $price = $wpdb->get_var($wpdb->prepare(
        "SELECT price FROM {$wpdb->prefix}dcm_price_list 
        WHERE party_id = %d AND product_id = %d 
        ORDER BY effective_date DESC LIMIT 1",
        $party_id, $product_id
    ));

    wp_send_json_success(array('price' => $price ? floatval($price) : 0));
}

public function save_challan() {
    check_ajax_referer('dcm_nonce', 'nonce');

    global $wpdb;

    $challan_data = array(
        'challan_number' => sanitize_text_field($_POST['challan_number']),
        'party_id' => intval($_POST['party_id']),
        'challan_date' => sanitize_text_field($_POST['challan_date']),
        'total_amount' => floatval($_POST['total_amount']),
        'amount_in_words' => sanitize_text_field($_POST['amount_in_words']),
        'remarks' => sanitize_textarea_field($_POST['remarks']),
        'created_by' => get_current_user_id()
    );

    $wpdb->insert("{$wpdb->prefix}dcm_challans", $challan_data);
    $challan_id = $wpdb->insert_id;

    if (!empty($_POST['items'])) {
        foreach ($_POST['items'] as $index => $item) {
            $item_data = array(
                'challan_id' => $challan_id,
                'product_id' => intval($item['product_id']),
                'quantity' => intval($item['quantity']),
                'price' => floatval($item['price']),
                'discount_percent' => floatval($item['discount']),
                'amount' => floatval($item['amount']),
                'item_order' => $index + 1
            );

            $wpdb->insert("{$wpdb->prefix}dcm_challan_items", $item_data);
        }
    }

    wp_send_json_success(array('challan_id' => $challan_id, 'message' => 'Challan saved successfully!'));
}

public function print_challan() {
    check_ajax_referer('dcm_nonce', 'nonce');

    $challan_id = intval($_POST['challan_id']);

    $challan_html = $this->generate_challan_html($challan_id, 'print');

    wp_send_json_success(array('html' => $challan_html));
}

private function generate_challan_html($challan_id, $type = 'print') {
    global $wpdb;

    $challan = $wpdb->get_row($wpdb->prepare(
        "SELECT c.*, p.party_name, p.address, p.phone, p.email, p.gstin 
        FROM {$wpdb->prefix}dcm_challans c 
        LEFT JOIN {$wpdb->prefix}dcm_parties p ON c.party_id = p.id 
        WHERE c.id = %d",
        $challan_id
    ));

    if (!$challan) {
        return '<p>Challan not found!</p>';
    }

    $items = $wpdb->get_results($wpdb->prepare(
        "SELECT ci.*, p.product_name, p.product_code, p.product_image 
        FROM {$wpdb->prefix}dcm_challan_items ci 
        LEFT JOIN {$wpdb->prefix}dcm_products p ON ci.product_id = p.id 
        WHERE ci.challan_id = %d 
        ORDER BY ci.item_order",
        $challan_id
    ));

    ob_start();
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <title>Delivery Challan - <?php echo $challan->challan_number; ?></title>
        <style>
            @media print {
                body { margin: 0; padding: 0; }
                .challan-copy { break-after: always; }
                .challan-copy:last-child { break-after: avoid; }
            }

            body { 
                font-family: Arial, sans-serif; 
                margin: 0;
                padding: 0;
                font-size: 12px;
            }

            .challan-container {
                width: 29.7cm;
                height: 21cm;
                margin: 0;
                padding: 0.5cm;
                box-sizing: border-box;
            }

            .challan-copy {
                height: 7cm;
                margin-bottom: 0.5cm;
                border: 1px solid #000;
                padding: 10px;
                position: relative;
            }

            .copy-label {
                position: absolute;
                top: 5px;
                right: 10px;
                font-weight: bold;
                background: #000;
                color: #fff;
                padding: 2px 5px;
                border-radius: 3px;
            }

            .company-header {
                text-align: center;
                margin-bottom: 10px;
                border-bottom: 2px solid #000;
                padding-bottom: 5px;
            }

            .company-name {
                font-size: 24px;
                font-weight: bold;
                letter-spacing: 5px;
            }

            .challan-title {
                font-size: 18px;
                font-weight: bold;
                margin: 5px 0;
            }

            .party-details {
                margin-bottom: 10px;
            }

            .challan-table {
                width: 100%;
                border-collapse: collapse;
                margin-bottom: 10px;
            }

            .challan-table th,
            .challan-table td {
                border: 1px solid #000;
                padding: 3px 5px;
                text-align: left;
            }

            .challan-table th {
                background-color: #f0f0f0;
                font-weight: bold;
            }

            .totals-row {
                font-weight: bold;
            }

            .amount-words {
                margin: 5px 0;
                font-style: italic;
            }

            .footer {
                margin-top: 10px;
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div class="challan-container">
            <?php for ($copy = 1; $copy <= 3; $copy++): ?>
            <div class="challan-copy">
                <div class="copy-label">
                    <?php 
                    if ($copy == 1) echo 'ORIGINAL';
                    elseif ($copy == 2) echo 'DUPLICATE';
                    else echo 'TRIPLICATE';
                    ?>
                </div>

                <div class="company-header">
                    <div class="company-name">H A R I K</div>
                    <div class="challan-title">Delivery Challan</div>
                </div>

                <div class="party-details">
                    <strong>M/s <?php echo esc_html($challan->party_name); ?></strong><br>
                    <?php if ($challan->address): ?>
                    Address: <?php echo esc_html($challan->address); ?><br>
                    <?php endif; ?>
                    <?php if ($challan->gstin): ?>
                    GSTIN: <?php echo esc_html($challan->gstin); ?>
                    <?php endif; ?>
                </div>

                <table class="challan-table">
                    <thead>
                        <tr>
                            <th width="5%">Sr.</th>
                            <th width="35%">Item Name</th>
                            <th width="10%">Item Code</th>
                            <th width="10%">Qty.</th>
                            <th width="10%">Price</th>
                            <th width="10%">Disc.%</th>
                            <th width="20%">Amount</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        $total_qty = 0;
                        $total_amount = 0;
                        foreach ($items as $index => $item): 
                            $total_qty += $item->quantity;
                            $total_amount += $item->amount;
                        ?>
                        <tr>
                            <td><?php echo $index + 1; ?></td>
                            <td><?php echo esc_html($item->product_name); ?></td>
                            <td><?php echo esc_html($item->product_code); ?></td>
                            <td><?php echo $item->quantity; ?></td>
                            <td><?php echo number_format($item->price, 2); ?></td>
                            <td><?php echo $item->discount_percent; ?>%</td>
                            <td><?php echo number_format($item->amount, 2); ?></td>
                        </tr>
                        <?php endforeach; ?>

                        <?php for ($i = count($items); $i < 10; $i++): ?>
                        <tr>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                        </tr>
                        <?php endfor; ?>
                    </tbody>
                    <tfoot>
                        <tr class="totals-row">
                            <td colspan="3">Total</td>
                            <td><?php echo $total_qty; ?></td>
                            <td></td>
                            <td></td>
                            <td><?php echo number_format($total_amount, 2); ?></td>
                        </tr>
                    </tfoot>
                </table>

                <div class="amount-words">
                    <strong>Amount in Words:-</strong><br>
                    <?php echo esc_html($challan->amount_in_words); ?>
                </div>

                <?php if ($challan->remarks): ?>
                <div class="remarks">
                    <strong>Remarks:-</strong> <?php echo esc_html($challan->remarks); ?>
                </div>
                <?php endif; ?>

                <div class="footer">
                    <em>Thanks for your Business</em>
                </div>
            </div>
            <?php endfor; ?>
        </div>

        <?php if ($type == 'print'): ?>
        <script>
            window.onload = function() {
                window.print();
            };
        </script>
        <?php endif; ?>
    </body>
    </html>
    <?php
    return ob_get_clean();
}

public function number_to_words($number) {

    $ones = array("", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine");
    $tens = array("", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety");
    $teens = array("Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen");

    return "Rupee " . ucwords($this->convert_number($number)) . " Only";
}

private function convert_number($number) {

    if ($number == 0) return "Zero";

    $words = "";
    if ($number >= 1000) {
        $words .= $this->convert_number(floor($number / 1000)) . " Thousand ";
        $number %= 1000;
    }
    if ($number >= 100) {
        $words .= $this->convert_number(floor($number / 100)) . " Hundred ";
        $number %= 100;
    }
    if ($number >= 20) {
        $words .= $this->get_tens(floor($number / 10)) . " ";
        $number %= 10;
    }
    if ($number > 0) {
        $words .= $this->get_ones($number);
    }

    return trim($words);
}

private function get_ones($num) {
    $ones = array("", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine");
    return $ones[$num];
}

private function get_tens($num) {
    $tens = array("", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety");
    return $tens[$num];
}

}

////////////////////////////////////////////////////////////////////////////////
// File: class-dcm-database.php (7 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/includes/class-dcm-database.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

class DCM_Database {

public function create_tables() {
    global $wpdb;

    $charset_collate = $wpdb->get_charset_collate();

    $sql = array();

    $sql[] = "CREATE TABLE {$wpdb->prefix}dcm_parties (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        party_name varchar(255) NOT NULL,
        address text,
        phone varchar(50),
        email varchar(100),
        gstin varchar(50),
        transport_name varchar(255),
        transport_id varchar(100),
        default_packing_type enum('with_packing','without_packing') DEFAULT 'without_packing',
        default_stickers enum('price_stickers','without_price_stickers','customer_stickers','harik_stickers','no_stickers') DEFAULT 'no_stickers',
        remarks text,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id)
    ) $charset_collate;";

    $sql[] = "CREATE TABLE {$wpdb->prefix}dcm_products (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        product_name varchar(255) NOT NULL,
        product_code varchar(100) NOT NULL,
        product_image varchar(255),
        description text,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        UNIQUE KEY product_code (product_code)
    ) $charset_collate;";

    $sql[] = "CREATE TABLE {$wpdb->prefix}dcm_price_list (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        party_id mediumint(9) NOT NULL,
        product_id mediumint(9) NOT NULL,
        price_type enum('with_packing','without_packing') NOT NULL DEFAULT 'without_packing',
        price decimal(10,2) NOT NULL,
        discount_percent decimal(5,2) DEFAULT 0,
        effective_date date NOT NULL,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY party_id (party_id),
        KEY product_id (product_id),
        KEY price_type (price_type),
        KEY effective_date (effective_date)
    ) $charset_collate;";

    $sql[] = "CREATE TABLE {$wpdb->prefix}dcm_challans (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        challan_number varchar(50) NOT NULL,
        party_id mediumint(9) NOT NULL,
        challan_date date NOT NULL,
        total_amount decimal(10,2) NOT NULL,
        amount_in_words text,
        remarks text,
        created_by bigint(20) NOT NULL,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        UNIQUE KEY challan_number (challan_number),
        KEY party_id (party_id)
    ) $charset_collate;";

    $sql[] = "CREATE TABLE {$wpdb->prefix}dcm_challan_items (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        challan_id mediumint(9) NOT NULL,
        product_id mediumint(9) NOT NULL,
        quantity int(11) NOT NULL,
        price decimal(10,2) NOT NULL,
        discount_percent decimal(5,2) DEFAULT 0,
        amount decimal(10,2) NOT NULL,
        item_order int(11) NOT NULL,
        PRIMARY KEY (id),
        KEY challan_id (challan_id)
    ) $charset_collate;";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');

    foreach ($sql as $query) {
        dbDelta($query);
    }

    $this->insert_sample_data();

    if (!empty($wpdb->last_error)) {
        error_log('DCM Database Error: ' . $wpdb->last_error);
    }

    $this->update_tables();
}

public function update_tables() {
    global $wpdb;

    error_log('DCM: Starting database table updates');

    $price_columns = $wpdb->get_col("DESCRIBE {$wpdb->prefix}dcm_price_list");

    if (!in_array('price_type', $price_columns)) {
        error_log('DCM: Adding price_type column to price_list table');
        $result = $wpdb->query("ALTER TABLE {$wpdb->prefix}dcm_price_list ADD price_type enum('with_packing','without_packing') NOT NULL DEFAULT 'without_packing' AFTER product_id");
        if ($result === false) {
            error_log('DCM Error: Failed to add price_type column - ' . $wpdb->last_error);
        } else {
            error_log('DCM: Successfully added price_type column');
        }
    }

    if (!in_array('discount_percent', $price_columns)) {
        error_log('DCM: Adding discount_percent column to price_list table');
        $result = $wpdb->query("ALTER TABLE {$wpdb->prefix}dcm_price_list ADD discount_percent decimal(5,2) DEFAULT 0 AFTER price");
        if ($result === false) {
            error_log('DCM Error: Failed to add discount_percent column - ' . $wpdb->last_error);
        } else {
            error_log('DCM: Successfully added discount_percent column');
        }
    }

    $party_columns = $wpdb->get_col("DESCRIBE {$wpdb->prefix}dcm_parties");

    $new_party_columns = [
        'transport_name' => "ALTER TABLE {$wpdb->prefix}dcm_parties ADD transport_name varchar(255) AFTER gstin",
        'transport_id' => "ALTER TABLE {$wpdb->prefix}dcm_parties ADD transport_id varchar(100) AFTER transport_name",
        'default_packing_type' => "ALTER TABLE {$wpdb->prefix}dcm_parties ADD default_packing_type enum('with_packing','without_packing') DEFAULT 'without_packing' AFTER transport_id",
        'default_stickers' => "ALTER TABLE {$wpdb->prefix}dcm_parties ADD default_stickers enum('price_stickers','without_price_stickers','customer_stickers','harik_stickers','no_stickers') DEFAULT 'no_stickers' AFTER default_packing_type",
        'remarks' => "ALTER TABLE {$wpdb->prefix}dcm_parties ADD remarks text AFTER default_stickers"
    ];

    foreach ($new_party_columns as $column => $sql) {
        if (!in_array($column, $party_columns)) {
            error_log("DCM: Adding $column column to parties table");
            $result = $wpdb->query($sql);
            if ($result === false) {
                error_log("DCM Error: Failed to add $column column - " . $wpdb->last_error);
            } else {
                error_log("DCM: Successfully added $column column");
            }
        }
    }

    $challan_items_columns = $wpdb->get_col("DESCRIBE {$wpdb->prefix}dcm_challan_items");
    if (!in_array('discount_percent', $challan_items_columns)) {
        error_log('DCM: Adding discount_percent column to challan_items table');
        $result = $wpdb->query("ALTER TABLE {$wpdb->prefix}dcm_challan_items ADD discount_percent decimal(5,2) DEFAULT 0 AFTER price");
        if ($result === false) {
            error_log('DCM Error: Failed to add discount_percent column to challan_items - ' . $wpdb->last_error);
        } else {
            error_log('DCM: Successfully added discount_percent column to challan_items');
        }
    }

$challan_items_columns = $wpdb->get_col("DESCRIBE {$wpdb->prefix}dcm_challan_items");
if (!in_array('packing_type', $challan_items_columns)) {
    error_log('DCM: Adding packing_type column to challan_items table');
    $result = $wpdb->query("ALTER TABLE {$wpdb->prefix}dcm_challan_items ADD packing_type enum('with_packing','without_packing') DEFAULT 'without_packing' AFTER product_id");
    if ($result === false) {
        error_log('DCM Error: Failed to add packing_type column to challan_items - ' . $wpdb->last_error);
    } else {
        error_log('DCM: Successfully added packing_type column to challan_items');
    }
}

    error_log('DCM: Database table updates completed');

    return true;
}

private function insert_sample_data() {
    global $wpdb;

    $party_count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}dcm_parties");

    if ($party_count == 0) {

        $wpdb->insert(
            "{$wpdb->prefix}dcm_parties",
            array(
                'party_name' => 'A.H.B. International',
                'address' => 'Sample Address, City - 123456',
                'phone' => '1234567890',
                'email' => 'contact@ahbinternational.com',
                'gstin' => 'GSTIN123456789',
                'transport_name' => 'ABC Transport',
                'transport_id' => 'TRANS123',
                'default_packing_type' => 'without_packing',
                'default_stickers' => 'no_stickers',
                'remarks' => 'Sample customer'
            )
        );

        $party_id = $wpdb->insert_id;

        $products = array(
            array('Urea Cap New Model - UCNM', 'UCNM', 'New model urea cap'),
            array('Urea Cap for BS6- UOBS6 I', 'UOBS6', 'BS6 compatible urea cap'),
            array('Urea Cap Premium Model', 'UCPM', 'Premium urea cap with enhanced features')
        );

        foreach ($products as $product) {
            $wpdb->insert(
                "{$wpdb->prefix}dcm_products",
                array(
                    'product_name' => $product[0],
                    'product_code' => $product[1],
                    'description' => $product[2]
                )
            );

            $product_id = $wpdb->insert_id;

            $wpdb->insert(
                "{$wpdb->prefix}dcm_price_list",
                array(
                    'party_id' => $party_id,
                    'product_id' => $product_id,
                    'price_type' => 'without_packing',
                    'price' => ($product[1] == 'UCNM') ? 125.00 : (($product[1] == 'UOBS6') ? 110.00 : 150.00),
                    'discount_percent' => 5.00,
                    'effective_date' => current_time('mysql')
                )
            );

            $wpdb->insert(
                "{$wpdb->prefix}dcm_price_list",
                array(
                    'party_id' => $party_id,
                    'product_id' => $product_id,
                    'price_type' => 'with_packing',
                    'price' => ($product[1] == 'UCNM') ? 135.00 : (($product[1] == 'UOBS6') ? 120.00 : 160.00),
                    'discount_percent' => 5.00,
                    'effective_date' => current_time('mysql')
                )
            );
        }

        error_log('DCM: Sample data inserted successfully');
    }
}

public function get_db_version() {
    return get_option('dcm_db_version', '1.0.0');
}

public function update_db_version($version) {
    update_option('dcm_db_version', $version);
}

public function needs_update() {
    $current_version = $this->get_db_version();
    $latest_version = '1.1.0'; 

    return version_compare($current_version, $latest_version, '<');
}

}

////////////////////////////////////////////////////////////////////////////////
// File: class-dcm-images.php (8 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/includes/class-dcm-images.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

class DCM_Images {

public function __construct() {
    add_action('wp_ajax_upload_product_image', array($this, 'upload_product_image'));
    add_action('wp_ajax_get_product_image', array($this, 'get_product_image'));
}

public function upload_product_image() {
    check_ajax_referer('dcm_nonce', 'nonce');

    if (!current_user_can('upload_files')) {
        wp_send_json_error('You do not have permission to upload files.');
    }

    if (!function_exists('wp_handle_upload')) {
        require_once(ABSPATH . 'wp-admin/includes/file.php');
    }

    $uploadedfile = $_FILES['product_image'];
    $upload_overrides = array(
        'test_form' => false,
        'mimes' => array(
            'jpg|jpeg' => 'image/jpeg',
            'png' => 'image/png',
            'gif' => 'image/gif'
        )
    );

    $movefile = wp_handle_upload($uploadedfile, $upload_overrides);

    if ($movefile && !isset($movefile['error'])) {
        wp_send_json_success(array(
            'image_url' => $movefile['url'],
            'message' => 'Image uploaded successfully!'
        ));
    } else {
        wp_send_json_error($movefile['error']);
    }
}

public function get_product_image() {
    check_ajax_referer('dcm_nonce', 'nonce');

    $product_id = intval($_POST['product_id']);

    global $wpdb;
    $image_url = $wpdb->get_var($wpdb->prepare(
        "SELECT product_image FROM {$wpdb->prefix}dcm_products WHERE id = %d",
        $product_id
    ));

    wp_send_json_success(array('image_url' => $image_url ? $image_url : ''));
}

}

new DCM_Images();

////////////////////////////////////////////////////////////////////////////////
// File: class-dcm-price-list.php (9 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/includes/class-dcm-price-list.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

class DCM_Price_List {

public function __construct() {
    add_action('wp_ajax_update_price', array($this, 'update_price_ajax'));
    add_action('wp_ajax_get_party_prices', array($this, 'get_party_prices_ajax'));
}

public function update_price_ajax() {
    check_ajax_referer('dcm_nonce', 'nonce');

    $party_id = intval($_POST['party_id']);
    $product_id = intval($_POST['product_id']);
    $price = floatval($_POST['price']);
    $effective_date = sanitize_text_field($_POST['effective_date']);

    global $wpdb;

    $existing = $wpdb->get_row($wpdb->prepare(
        "SELECT id FROM {$wpdb->prefix}dcm_price_list 
        WHERE party_id = %d AND product_id = %d AND effective_date = %s",
        $party_id, $product_id, $effective_date
    ));

    if ($existing) {

        $result = $wpdb->update(
            "{$wpdb->prefix}dcm_price_list",
            array('price' => $price),
            array('id' => $existing->id)
        );
    } else {

        $result = $wpdb->insert(
            "{$wpdb->prefix}dcm_price_list",
            array(
                'party_id' => $party_id,
                'product_id' => $product_id,
                'price' => $price,
                'effective_date' => $effective_date
            )
        );
    }

    if ($result !== false) {
        wp_send_json_success(array('message' => 'Price updated successfully!'));
    } else {
        wp_send_json_error(array('message' => 'Error updating price.'));
    }
}

public function get_party_prices_ajax() {
    check_ajax_referer('dcm_nonce', 'nonce');

    $party_id = intval($_POST['party_id']);
    $effective_date = sanitize_text_field($_POST['effective_date']);

    global $wpdb;

    $prices = $wpdb->get_results($wpdb->prepare(
        "SELECT pl.*, p.product_name, p.product_code 
        FROM {$wpdb->prefix}dcm_price_list pl
        LEFT JOIN {$wpdb->prefix}dcm_products p ON pl.product_id = p.id
        WHERE pl.party_id = %d AND pl.effective_date = %s
        ORDER BY p.product_name",
        $party_id, $effective_date
    ));

    wp_send_json_success($prices);
}

public static function get_current_price($party_id, $product_id) {
    global $wpdb;

    return $wpdb->get_var($wpdb->prepare(
        "SELECT price FROM {$wpdb->prefix}dcm_price_list 
        WHERE party_id = %d AND product_id = %d 
        ORDER BY effective_date DESC LIMIT 1",
        $party_id, $product_id
    ));
}

public static function get_price_history($party_id, $product_id) {
    global $wpdb;

    return $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}dcm_price_list 
        WHERE party_id = %d AND product_id = %d 
        ORDER BY effective_date DESC",
        $party_id, $product_id
    ));
}

}

new DCM_Price_List();

////////////////////////////////////////////////////////////////////////////////
// File: class-dcm-parties.php (10 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/includes/class-dcm-parties.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

class DCM_Parties {

public function __construct() {
    add_action('wp_ajax_get_parties', array($this, 'get_parties_ajax'));
    add_action('wp_ajax_search_parties', array($this, 'search_parties_ajax'));
}

public function get_parties_ajax() {
    check_ajax_referer('dcm_nonce', 'nonce');

    global $wpdb;
    $parties = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_parties ORDER BY party_name");

    wp_send_json_success($parties);
}

public function search_parties_ajax() {
    check_ajax_referer('dcm_nonce', 'nonce');

    $search_term = sanitize_text_field($_POST['search_term']);

    global $wpdb;
    $parties = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}dcm_parties 
        WHERE party_name LIKE %s OR phone LIKE %s OR email LIKE %s 
        ORDER BY party_name",
        '%' . $wpdb->esc_like($search_term) . '%',
        '%' . $wpdb->esc_like($search_term) . '%',
        '%' . $wpdb->esc_like($search_term) . '%'
    ));

    wp_send_json_success($parties);
}

public static function get_all_parties() {
    global $wpdb;
    return $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_parties ORDER BY party_name");
}

public static function get_party($party_id) {
    global $wpdb;
    return $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}dcm_parties WHERE id = %d",
        $party_id
    ));
}

}

new DCM_Parties();

////////////////////////////////////////////////////////////////////////////////
// File: class-dcm-import-export.php (11 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/includes/class-dcm-import-export.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

class DCM_Import_Export {

public function __construct() {
    add_action('admin_init', array($this, 'handle_import_export'));
    add_action('wp_ajax_export_masters', array($this, 'export_masters_ajax'));
    add_action('wp_ajax_import_masters', array($this, 'import_masters_ajax'));

    add_action('admin_init', array($this, 'download_template'));
}

public function handle_import_export() {
    if (isset($_POST['dcm_export_action'])) {
        $this->handle_export();
    }

    if (isset($_FILES['import_file']) && isset($_POST['dcm_import_action'])) {
        $this->handle_import();
    }
}

public function download_template() {
    if (isset($_GET['download_template']) && isset($_GET['page']) && $_GET['page'] === 'import-export') {
        $template = sanitize_text_field($_GET['download_template']);
        $this->generate_template($template);
    }
}

public function handle_export() {

    if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'dcm_export')) {
        wp_die('Security verification failed.');
    }

    $type = sanitize_text_field($_POST['export_type']);
    $format = sanitize_text_field($_POST['export_format']);

    switch ($type) {
        case 'parties':
            $this->export_parties($format);
            break;
        case 'products':
            $this->export_products($format);
            break;
        case 'price_list':
            $this->export_price_list_wide_format($format);
            break;
        case 'all':
            $this->export_all_masters($format);
            break;
    }
}

public function handle_import() {

    if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'dcm_import')) {
        wp_die('Security verification failed.');
    }

    $type = sanitize_text_field($_POST['import_type']);
    $file = $_FILES['import_file'];

    if ($file['error'] !== UPLOAD_ERR_OK) {
        $this->redirect_with_message('File upload error: ' . $file['error'], 'error');
    }

    $file_path = $file['tmp_name'];
    $file_type = pathinfo($file['name'], PATHINFO_EXTENSION);

    if (!in_array($file_type, ['csv', 'xlsx', 'xls'])) {
        $this->redirect_with_message('Invalid file type. Please upload CSV or Excel files only.', 'error');
    }

    switch ($type) {
        case 'parties':
            $result = $this->import_parties($file_path, $file_type);
            break;
        case 'products':
            $result = $this->import_products($file_path, $file_type);
            break;
        case 'price_list':
            $result = $this->import_price_list_wide_format($file_path, $file_type);
            break;
        default:
            $this->redirect_with_message('Invalid import type.', 'error');
    }

    if ($result['success']) {
        $this->redirect_with_message($result['message'], 'success', $result['imported']);
    } else {
        $this->redirect_with_message('Import failed: ' . $result['message'], 'error');
    }
}

private function redirect_with_message($message, $type = 'success', $imported = 0) {
    $url = admin_url('admin.php?page=import-export');
    $url .= '&import_message=' . urlencode($message);
    $url .= '&message_type=' . $type;
    if ($imported > 0) {
        $url .= '&imported=' . $imported;
    }
    wp_redirect($url);
    exit;
}

private function generate_template($type) {
    global $wpdb;

    $headers = array();
    $filename = '';
    $sample_data = array();

    switch ($type) {
        case 'parties':
            $headers = array('Party Name', 'Address', 'Phone', 'Email', 'GSTIN', 'Transport Name', 'Transport ID', 'Default Packing Type', 'Default Stickers', 'Remarks');
            $filename = 'parties_template.csv';
            $sample_data = array(
                array('A.H.B. International', 'Sample Address, City - 123456', '1234567890', 'contact@ahb.com', 'GSTIN123456789', 'ABC Transport', 'TRANS123', 'without_packing', 'no_stickers', 'Sample customer'),
                array('Another Party', 'Another Address, City - 654321', '9876543210', 'info@another.com', 'GSTIN987654321', 'XYZ Transport', 'TRANS456', 'with_packing', 'price_stickers', 'Another customer')
            );
            break;

        case 'products':
            $headers = array('Product Name', 'Product Code', 'Description');
            $filename = 'products_template.csv';
            $sample_data = array(
                array('Urea Cap New Model - UCNM', 'UCNM', 'New model urea cap'),
                array('Urea Cap for BS6- UOBS6 I', 'UOBS6', 'BS6 compatible urea cap')
            );
            break;

        case 'price_list':

            $products = $wpdb->get_results("SELECT product_code FROM {$wpdb->prefix}dcm_products ORDER BY product_code");

            $headers = array('Party', 'Discount (%)', 'Effective Date');
            foreach ($products as $product) {
                $headers[] = $product->product_code . ' Without Packing';
                $headers[] = $product->product_code . ' With Packing';
            }

            $filename = 'price_list_template.csv';

            $sample_data = array(
                array('A.H.B. International', '5.00', '2024-01-01', '125.00', '135.00', '110.00', '120.00', '150.00', '160.00'),
                array('Another Party', '10.00', '2024-01-01', '130.00', '140.00', '115.00', '125.00', '155.00', '165.00')
            );
            break;

        default:
            wp_die('Invalid template type.');
    }

    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="' . $filename . '"');

    $output = fopen('php:

    fputs($output, $bom = (chr(0xEF) . chr(0xBB) . chr(0xBF)));

    fputcsv($output, $headers);

    foreach ($sample_data as $row) {
        fputcsv($output, $row);
    }

    fclose($output);
    exit;
}

private function export_price_list_wide_format($format = 'csv') {
    global $wpdb;

    $products = $wpdb->get_results("SELECT id, product_code FROM {$wpdb->prefix}dcm_products ORDER BY product_code");
    $product_codes = array();
    foreach ($products as $product) {
        $product_codes[$product->id] = $product->product_code;
    }

    $parties = $wpdb->get_results("
        SELECT DISTINCT p.id, p.party_name 
        FROM {$wpdb->prefix}dcm_parties p 
        ORDER BY p.party_name
    ");

    $latest_dates = $wpdb->get_results("
        SELECT party_id, MAX(effective_date) as latest_date 
        FROM {$wpdb->prefix}dcm_price_list 
        GROUP BY party_id
    ");

    $latest_date_map = array();
    foreach ($latest_dates as $date) {
        $latest_date_map[$date->party_id] = $date->latest_date;
    }

    $export_data = array();

    foreach ($parties as $party) {
        $latest_date = isset($latest_date_map[$party->id]) ? $latest_date_map[$party->id] : date('Y-m-d');

        $discount_data = $wpdb->get_row($wpdb->prepare("
            SELECT discount_percent 
            FROM {$wpdb->prefix}dcm_price_list 
            WHERE party_id = %d AND effective_date = %s 
            LIMIT 1
        ", $party->id, $latest_date));

        $discount = $discount_data ? $discount_data->discount_percent : 0;

        $row_data = array(
            'party' => $party->party_name,
            'discount' => $discount,
            'effective_date' => $latest_date
        );

        foreach ($products as $product) {

            $price_without = $wpdb->get_var($wpdb->prepare("
                SELECT price 
                FROM {$wpdb->prefix}dcm_price_list 
                WHERE party_id = %d AND product_id = %d AND price_type = 'without_packing' AND effective_date = %s
            ", $party->id, $product->id, $latest_date));

            $price_with = $wpdb->get_var($wpdb->prepare("
                SELECT price 
                FROM {$wpdb->prefix}dcm_price_list 
                WHERE party_id = %d AND product_id = %d AND price_type = 'with_packing' AND effective_date = %s
            ", $party->id, $product->id, $latest_date));

            $row_data[$product->product_code . '_without'] = $price_without ?: '';
            $row_data[$product->product_code . '_with'] = $price_with ?: '';
        }

        $export_data[] = $row_data;
    }

    $headers = array('Party', 'Discount (%)', 'Effective Date');
    foreach ($products as $product) {
        $headers[] = $product->product_code . ' Without Packing';
        $headers[] = $product->product_code . ' With Packing';
    }

    $filename = 'price_list_' . date('Y-m-d') . '.' . $format;

    if ($format === 'csv') {
        $this->export_wide_csv($export_data, $filename, $headers);
    } else {
        $this->export_wide_excel($export_data, $filename, 'Price List', $headers);
    }
}

private function import_price_list_wide_format($file_path, $file_type) {
    global $wpdb;

    $data = $this->read_file($file_path, $file_type);
    $imported = 0;
    $errors = array();

    $products = $wpdb->get_results("SELECT id, product_code FROM {$wpdb->prefix}dcm_products");
    $product_map = array();
    foreach ($products as $product) {
        $product_map[$product->product_code] = $product->id;
    }

    foreach ($data as $index => $row) {

        if ($index === 0 && (isset($row['Party']) || isset($row[0]))) continue;

        if (isset($row['Party'])) {

            $party_name = sanitize_text_field($row['Party']);
            $discount = floatval($row['Discount (%)'] ?? 0);
            $effective_date = sanitize_text_field($row['Effective Date'] ?? date('Y-m-d'));

            foreach ($row as $column => $value) {
                if ($column === 'Party' || $column === 'Discount (%)' || $column === 'Effective Date') continue;

                if (strpos($column, ' Without Packing') !== false) {
                    $product_code = str_replace(' Without Packing', '', $column);
                    $price_type = 'without_packing';
                } elseif (strpos($column, ' With Packing') !== false) {
                    $product_code = str_replace(' With Packing', '', $column);
                    $price_type = 'with_packing';
                } else {
                    continue;
                }

                $price = floatval($value);
                if ($price > 0) {
                    $result = $this->process_price_entry($party_name, $product_code, $price_type, $price, $discount, $effective_date);
                    if ($result) $imported++;
                }
            }
        } else {

            $party_name = sanitize_text_field($row[0] ?? '');
            $discount = floatval($row[1] ?? 0);
            $effective_date = sanitize_text_field($row[2] ?? date('Y-m-d'));

            if (empty($party_name)) {
                $errors[] = "Row " . ($index + 1) . ": Party Name is required";
                continue;
            }

            $column_index = 3;
            foreach ($products as $product) {
                $price_without = floatval($row[$column_index++] ?? 0);
                $price_with = floatval($row[$column_index++] ?? 0);

                if ($price_without > 0) {
                    $result = $this->process_price_entry($party_name, $product->product_code, 'without_packing', $price_without, $discount, $effective_date);
                    if ($result) $imported++;
                }

                if ($price_with > 0) {
                    $result = $this->process_price_entry($party_name, $product->product_code, 'with_packing', $price_with, $discount, $effective_date);
                    if ($result) $imported++;
                }
            }
        }
    }

    return array(
        'success' => empty($errors),
        'imported' => $imported,
        'errors' => $errors,
        'message' => empty($errors) ? "Successfully imported {$imported} price entries" : implode(', ', $errors)
    );
}

private function process_price_entry($party_name, $product_code, $price_type, $price, $discount, $effective_date) {
    global $wpdb;

    $party_id = $wpdb->get_var($wpdb->prepare(
        "SELECT id FROM {$wpdb->prefix}dcm_parties WHERE party_name = %s",
        $party_name
    ));

    if (!$party_id) {
        error_log("DCM Import: Party not found - " . $party_name);
        return false;
    }

    $product_id = $wpdb->get_var($wpdb->prepare(
        "SELECT id FROM {$wpdb->prefix}dcm_products WHERE product_code = %s",
        $product_code
    ));

    if (!$product_id) {
        error_log("DCM Import: Product not found - " . $product_code);
        return false;
    }

    $existing = $wpdb->get_row($wpdb->prepare(
        "SELECT id FROM {$wpdb->prefix}dcm_price_list 
        WHERE party_id = %d AND product_id = %d AND price_type = %s AND effective_date = %s",
        $party_id, $product_id, $price_type, $effective_date
    ));

    if ($existing) {

        $result = $wpdb->update(
            "{$wpdb->prefix}dcm_price_list",
            array(
                'price' => $price,
                'discount_percent' => $discount
            ),
            array('id' => $existing->id),
            array('%f', '%f'),
            array('%d')
        );
    } else {

        $result = $wpdb->insert(
            "{$wpdb->prefix}dcm_price_list",
            array(
                'party_id' => $party_id,
                'product_id' => $product_id,
                'price_type' => $price_type,
                'price' => $price,
                'discount_percent' => $discount,
                'effective_date' => $effective_date,
                'created_at' => current_time('mysql')
            ),
            array('%d', '%d', '%s', '%f', '%f', '%s', '%s')
        );
    }

    return $result !== false;
}

private function export_wide_csv($data, $filename, $headers) {
    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="' . $filename . '"');

    $output = fopen('php:

    fputs($output, $bom = (chr(0xEF) . chr(0xBB) . chr(0xBF)));

    fputcsv($output, $headers);

    foreach ($data as $row) {
        $csv_row = array();
        foreach ($headers as $header) {

            if ($header === 'Party') {
                $csv_row[] = $row['party'] ?? '';
            } elseif ($header === 'Discount (%)') {
                $csv_row[] = $row['discount'] ?? '';
            } elseif ($header === 'Effective Date') {
                $csv_row[] = $row['effective_date'] ?? '';
            } else {

                if (strpos($header, ' Without Packing') !== false) {
                    $product_code = str_replace(' Without Packing', '', $header);
                    $key = $product_code . '_without';
                } elseif (strpos($header, ' With Packing') !== false) {
                    $product_code = str_replace(' With Packing', '', $header);
                    $key = $product_code . '_with';
                } else {
                    $key = $header;
                }
                $csv_row[] = $row[$key] ?? '';
            }
        }
        fputcsv($output, $csv_row);
    }

    fclose($output);
    exit;
}

private function export_parties($format = 'csv') {
    global $wpdb;

    $parties = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_parties ORDER BY party_name");

    $filename = 'parties_' . date('Y-m-d') . '.' . $format;

    if ($format === 'csv') {
        $this->export_csv($parties, $filename, array(
            'party_name' => 'Party Name',
            'address' => 'Address',
            'phone' => 'Phone',
            'email' => 'Email',
            'gstin' => 'GSTIN',
            'transport_name' => 'Transport Name',
            'transport_id' => 'Transport ID',
            'default_packing_type' => 'Default Packing Type',
            'default_stickers' => 'Default Stickers',
            'remarks' => 'Remarks'
        ));
    } else {
        $this->export_excel($parties, $filename, 'Parties', array(
            'party_name' => 'Party Name',
            'address' => 'Address',
            'phone' => 'Phone',
            'email' => 'Email',
            'gstin' => 'GSTIN',
            'transport_name' => 'Transport Name',
            'transport_id' => 'Transport ID',
            'default_packing_type' => 'Default Packing Type',
            'default_stickers' => 'Default Stickers',
            'remarks' => 'Remarks'
        ));
    }
}

private function export_products($format = 'csv') {
    global $wpdb;

    $products = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_name");

    $filename = 'products_' . date('Y-m-d') . '.' . $format;

    if ($format === 'csv') {
        $this->export_csv($products, $filename, array(
            'product_name' => 'Product Name',
            'product_code' => 'Product Code',
            'description' => 'Description'
        ));
    } else {
        $this->export_excel($products, $filename, 'Products', array(
            'product_name' => 'Product Name',
            'product_code' => 'Product Code',
            'description' => 'Description'
        ));
    }
}

private function export_csv($data, $filename, $headers) {
    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="' . $filename . '"');

    $output = fopen('php:

    fputs($output, $bom = (chr(0xEF) . chr(0xBB) . chr(0xBF)));

    fputcsv($output, array_values($headers));

    foreach ($data as $row) {
        $csv_row = array();
        foreach (array_keys($headers) as $key) {
            $csv_row[] = $row->$key ?? '';
        }
        fputcsv($output, $csv_row);
    }

    fclose($output);
    exit;
}

private function export_wide_excel($data, $filename, $sheet_name, $headers) {

    $this->export_wide_csv($data, $filename, $headers);
}

private function export_excel($data, $filename, $sheet_name, $headers) {

    $this->export_csv($data, $filename, $headers);
}

private function export_all_csv() {

    $this->export_parties('csv');
}

private function export_all_excel() {

    $this->export_parties('xlsx');
}

private function import_parties($file_path, $file_type) {
    global $wpdb;

    $data = $this->read_file($file_path, $file_type);
    $imported = 0;
    $errors = array();

    foreach ($data as $index => $row) {

        if ($index === 0 && isset($row['Party Name'])) continue;

        $party_name = '';
        if (isset($row['Party Name'])) {
            $party_name = sanitize_text_field($row['Party Name'] ?? '');
        } elseif (isset($row[0])) {
            $party_name = sanitize_text_field($row[0] ?? '');
        }

        if (empty($party_name)) {
            $errors[] = "Row " . ($index + 1) . ": Party Name is required";
            continue;
        }

        $party_data = array(
            'party_name' => $party_name,
            'address' => sanitize_textarea_field($row['Address'] ?? $row['address'] ?? $row[1] ?? ''),
            'phone' => sanitize_text_field($row['Phone'] ?? $row['phone'] ?? $row[2] ?? ''),
            'email' => sanitize_email($row['Email'] ?? $row['email'] ?? $row[3] ?? ''),
            'gstin' => sanitize_text_field($row['GSTIN'] ?? $row['gstin'] ?? $row[4] ?? ''),
            'transport_name' => sanitize_text_field($row['Transport Name'] ?? $row['transport_name'] ?? $row[5] ?? ''),
            'transport_id' => sanitize_text_field($row['Transport ID'] ?? $row['transport_id'] ?? $row[6] ?? ''),
            'default_packing_type' => sanitize_text_field($row['Default Packing Type'] ?? $row['default_packing_type'] ?? $row[7] ?? 'without_packing'),
            'default_stickers' => sanitize_text_field($row['Default Stickers'] ?? $row['default_stickers'] ?? $row[8] ?? 'no_stickers'),
            'remarks' => sanitize_textarea_field($row['Remarks'] ?? $row['remarks'] ?? $row[9] ?? '')
        );

        if (!in_array($party_data['default_packing_type'], ['with_packing', 'without_packing'])) {
            $party_data['default_packing_type'] = 'without_packing';
        }

        $valid_stickers = ['no_stickers', 'price_stickers', 'without_price_stickers', 'customer_stickers', 'harik_stickers'];
        if (!in_array($party_data['default_stickers'], $valid_stickers)) {
            $party_data['default_stickers'] = 'no_stickers';
        }

        $existing = $wpdb->get_var($wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}dcm_parties WHERE party_name = %s",
            $party_data['party_name']
        ));

        if ($existing) {

            $result = $wpdb->update(
                "{$wpdb->prefix}dcm_parties",
                $party_data,
                array('id' => $existing)
            );
        } else {

            $result = $wpdb->insert(
                "{$wpdb->prefix}dcm_parties",
                $party_data
            );
        }

        if ($result !== false) {
            $imported++;
        } else {
            $errors[] = "Row " . ($index + 1) . ": " . $wpdb->last_error;
        }
    }

    return array(
        'success' => empty($errors),
        'imported' => $imported,
        'errors' => $errors,
        'message' => empty($errors) ? "Successfully imported {$imported} parties" : implode(', ', $errors)
    );
}

private function import_products($file_path, $file_type) {
    global $wpdb;

    $data = $this->read_file($file_path, $file_type);
    $imported = 0;
    $errors = array();

    foreach ($data as $index => $row) {

        if ($index === 0 && isset($row['Product Name'])) continue;

        $product_name = '';
        $product_code = '';

        if (isset($row['Product Name'])) {
            $product_name = sanitize_text_field($row['Product Name'] ?? '');
            $product_code = sanitize_text_field($row['Product Code'] ?? $row['product_code'] ?? '');
        } elseif (isset($row[0])) {
            $product_name = sanitize_text_field($row[0] ?? '');
            $product_code = sanitize_text_field($row[1] ?? '');
        }

        if (empty($product_name)) {
            $errors[] = "Row " . ($index + 1) . ": Product Name is required";
            continue;
        }

        if (empty($product_code)) {
            $errors[] = "Row " . ($index + 1) . ": Product Code is required";
            continue;
        }

        $product_data = array(
            'product_name' => $product_name,
            'product_code' => $product_code,
            'description' => sanitize_textarea_field($row['Description'] ?? $row['description'] ?? $row[2] ?? '')
        );

        $existing = $wpdb->get_var($wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}dcm_products WHERE product_code = %s",
            $product_data['product_code']
        ));

        if ($existing) {

            $result = $wpdb->update(
                "{$wpdb->prefix}dcm_products",
                $product_data,
                array('id' => $existing)
            );
        } else {

            $result = $wpdb->insert(
                "{$wpdb->prefix}dcm_products",
                $product_data
            );
        }

        if ($result !== false) {
            $imported++;
        } else {
            $errors[] = "Row " . ($index + 1) . ": " . $wpdb->last_error;
        }
    }

    return array(
        'success' => empty($errors),
        'imported' => $imported,
        'errors' => $errors,
        'message' => empty($errors) ? "Successfully imported {$imported} products" : implode(', ', $errors)
    );
}

private function read_file($file_path, $file_type) {
    $data = array();

    if ($file_type === 'csv') {
        $data = $this->read_csv($file_path);
    } elseif (in_array($file_type, ['xlsx', 'xls'])) {
        $data = $this->read_excel($file_path);
    }

    return $data;
}

private function read_csv($file_path) {
    $data = array();

    if (($handle = fopen($file_path, 'r')) !== FALSE) {
        $headers = fgetcsv($handle);

        if ($headers !== FALSE) {
            while (($row = fgetcsv($handle)) !== FALSE) {
                if (count($row) === count($headers)) {
                    $data[] = array_combine($headers, $row);
                }
            }
        }

        fclose($handle);
    }

    return $data;
}

private function read_excel($file_path) {

    return $this->read_csv($file_path);
}

public function export_masters_ajax() {
    check_ajax_referer('dcm_nonce', 'nonce');
    $this->handle_export();
}

public function import_masters_ajax() {
    check_ajax_referer('dcm_nonce', 'nonce');
    $this->handle_import();
}

}

new DCM_Import_Export();

////////////////////////////////////////////////////////////////////////////////
// File: class-dcm-products.php (12 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/includes/class-dcm-products.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

class DCM_Products {

public function __construct() {
    add_action('wp_ajax_get_products', array($this, 'get_products_ajax'));
    add_action('wp_ajax_search_products', array($this, 'search_products_ajax'));
}

public function get_products_ajax() {
    check_ajax_referer('dcm_nonce', 'nonce');

    global $wpdb;
    $products = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_name");

    wp_send_json_success($products);
}

public function search_products_ajax() {
    check_ajax_referer('dcm_nonce', 'nonce');

    $search_term = sanitize_text_field($_POST['search_term']);

    global $wpdb;
    $products = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}dcm_products 
        WHERE product_name LIKE %s OR product_code LIKE %s 
        ORDER BY product_name",
        '%' . $wpdb->esc_like($search_term) . '%',
        '%' . $wpdb->esc_like($search_term) . '%'
    ));

    wp_send_json_success($products);
}

public static function get_all_products() {
    global $wpdb;
    return $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_name");
}

public static function get_product($product_id) {
    global $wpdb;
    return $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}dcm_products WHERE id = %d",
        $product_id
    ));
}

public static function get_product_by_code($product_code) {
    global $wpdb;
    return $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}dcm_products WHERE product_code = %s",
        $product_code
    ));
}

}

new DCM_Products();

////////////////////////////////////////////////////////////////////////////////
// File: admin-dashboard.php (13 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/templates/admin-dashboard.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

Delivery Challan Manager

Total Challans

Total Parties

Total Products

Quick Actions

Create New ChallanManage PartiesManage ProductsPrice List

Recent Challans

get_results(” SELECT c.*, p.party_name FROM {$wpdb->prefix}dcm_challans c LEFT JOIN {$wpdb->prefix}dcm_parties p ON c.party_id = p.id ORDER BY c.created_at DESC LIMIT 5 “); if ($recent_challans) { echo ‘

Sr.Item NameItem CodeQty.PriceDisc.%Amount
product_name); ?>product_code); ?>quantity; ?>price, 2); ?>discount_percent; ?>%amount, 2); ?>

‘; echo ”; echo ”; foreach ($recent_challans as $challan) { echo ”; echo ”; echo ”; echo ”; echo ”; echo ”; echo ”; } echo ‘

Challan NoPartyDateAmountActions
‘ . esc_html($challan->challan_number) . ‘‘ . esc_html($challan->party_name) . ‘‘ . esc_html($challan->challan_date) . ‘‘ . number_format($challan->total_amount, 2) . ‘‘; echo ‘Edit ‘; echo ‘Print‘; echo ‘

‘; } else { echo ‘

No challans found. Create your first challan.’; } ?>

////////////////////////////////////////////////////////////////////////////////
// File: challan-print.php (14 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/templates/challan-print.php
// Type: php
////////////////////////////////////////////////////////////////////////////////




Delivery Challan – <?php echo $challan->challan_number; ?>

////////////////////////////////////////////////////////////////////////////////
// File: price-list.php (16 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/templates/price-list.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

global $wpdb;

$parties = $wpdb->get_results(“SELECT * FROM {$wpdb->prefix}dcm_parties ORDER BY party_name”);
$products = $wpdb->get_results(“SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_name”);

if (isset($_POST[‘dcm_action’]) && $_POST[‘dcm_action’] === ‘update_prices’) {
$result = handle_update_prices();
if ($result[‘success’]) {
echo ‘

‘ . $result[‘message’] . ”;
} else {
echo ‘

‘ . $result[‘message’] . ”;
}
}

function handle_update_prices() {
global $wpdb;

if (!wp_verify_nonce($_POST['_wpnonce'], 'dcm_update_prices')) {
    return ['success' => false, 'message' => 'Security verification failed.'];
}

$party_id = intval($_POST['party_id']);
$effective_date = sanitize_text_field($_POST['effective_date']);
$prices_with_packing = $_POST['prices_with_packing'] ?? [];
$prices_without_packing = $_POST['prices_without_packing'] ?? [];
$discounts = $_POST['discounts'] ?? [];

if (empty($party_id) || empty($effective_date)) {
    return ['success' => false, 'message' => 'Party and effective date are required.'];
}

$updated_count = 0;
$error_count = 0;
$debug_info = [];

foreach ($prices_without_packing as $product_id => $price_value) {
    $product_id = intval($product_id);

    if (empty($price_value) || floatval($price_value) == 0) {
        continue;
    }

    $price = floatval($price_value);
    $discount = isset($discounts[$product_id]) ? floatval($discounts[$product_id]) : 0;

    if ($discount < 0 || $discount > 100) {
        $error_count++;
        continue;
    }

    $existing = $wpdb->get_row($wpdb->prepare(
        "SELECT id FROM {$wpdb->prefix}dcm_price_list 
        WHERE party_id = %d AND product_id = %d AND price_type = 'without_packing' AND effective_date = %s",
        $party_id, $product_id, $effective_date
    ));

    if ($existing) {

        $result = $wpdb->update(
            "{$wpdb->prefix}dcm_price_list",
            array(
                'price' => $price,
                'discount_percent' => $discount
            ),
            array('id' => $existing->id),
            array('%f', '%f'),
            array('%d')
        );
    } else {

        $result = $wpdb->insert(
            "{$wpdb->prefix}dcm_price_list",
            array(
                'party_id' => $party_id,
                'product_id' => $product_id,
                'price_type' => 'without_packing',
                'price' => $price,
                'discount_percent' => $discount,
                'effective_date' => $effective_date,
                'created_at' => current_time('mysql')
            ),
            array('%d', '%d', '%s', '%f', '%f', '%s', '%s')
        );
    }

    if ($result !== false) {
        $updated_count++;
        $debug_info[] = "Updated without packing: Product $product_id - Price: $price, Discount: $discount";
    } else {
        $error_count++;
        $debug_info[] = "Error without packing: Product $product_id - " . $wpdb->last_error;
    }
}

foreach ($prices_with_packing as $product_id => $price_value) {
    $product_id = intval($product_id);

    if (empty($price_value) || floatval($price_value) == 0) {
        continue;
    }

    $price = floatval($price_value);
    $discount = isset($discounts[$product_id]) ? floatval($discounts[$product_id]) : 0;

    if ($discount < 0 || $discount > 100) {
        $error_count++;
        continue;
    }

    $existing = $wpdb->get_row($wpdb->prepare(
        "SELECT id FROM {$wpdb->prefix}dcm_price_list 
        WHERE party_id = %d AND product_id = %d AND price_type = 'with_packing' AND effective_date = %s",
        $party_id, $product_id, $effective_date
    ));

    if ($existing) {

        $result = $wpdb->update(
            "{$wpdb->prefix}dcm_price_list",
            array(
                'price' => $price,
                'discount_percent' => $discount
            ),
            array('id' => $existing->id),
            array('%f', '%f'),
            array('%d')
        );
    } else {

        $result = $wpdb->insert(
            "{$wpdb->prefix}dcm_price_list",
            array(
                'party_id' => $party_id,
                'product_id' => $product_id,
                'price_type' => 'with_packing',
                'price' => $price,
                'discount_percent' => $discount,
                'effective_date' => $effective_date,
                'created_at' => current_time('mysql')
            ),
            array('%d', '%d', '%s', '%f', '%f', '%s', '%s')
        );
    }

    if ($result !== false) {
        $updated_count++;
        $debug_info[] = "Updated with packing: Product $product_id - Price: $price, Discount: $discount";
    } else {
        $error_count++;
        $debug_info[] = "Error with packing: Product $product_id - " . $wpdb->last_error;
    }
}

error_log('DCM Price Update Debug: ' . implode(' | ', $debug_info));
error_log('DCM Price Update Summary: Updated=' . $updated_count . ', Errors=' . $error_count);

if ($updated_count > 0) {
    return [
        'success' => true, 
        'message' => "Prices updated successfully! Updated: {$updated_count}, Errors: {$error_count}"
    ];
} else {
    return [
        'success' => false, 
        'message' => 'No prices were updated. Please check your input. Make sure you enter valid prices (numbers greater than 0). Debug: ' . implode(', ', $debug_info)
    ];
}

}

$effective_date = isset($_GET[‘effective_date’]) ? sanitize_text_field($_GET[‘effective_date’]) : date(‘Y-m-d’);
$party_id = isset($_GET[‘party_id’]) ? intval($_GET[‘party_id’]) : 0;

$prices_with_packing = array();
$prices_without_packing = array();
$discounts_data = array();

if ($party_id) {

$prices_with = $wpdb->get_results($wpdb->prepare(
    "SELECT pl.*, p.product_name, p.product_code 
    FROM {$wpdb->prefix}dcm_price_list pl
    LEFT JOIN {$wpdb->prefix}dcm_products p ON pl.product_id = p.id
    WHERE pl.party_id = %d AND pl.price_type = 'with_packing' AND pl.effective_date = %s
    ORDER BY p.product_name",
    $party_id, $effective_date
));

$prices_without = $wpdb->get_results($wpdb->prepare(
    "SELECT pl.*, p.product_name, p.product_code 
    FROM {$wpdb->prefix}dcm_price_list pl
    LEFT JOIN {$wpdb->prefix}dcm_products p ON pl.product_id = p.id
    WHERE pl.party_id = %d AND pl.price_type = 'without_packing' AND pl.effective_date = %s
    ORDER BY p.product_name",
    $party_id, $effective_date
));

foreach ($prices_with as $price) {
    $prices_with_packing[$price->product_id] = $price->price;
    $discounts_data[$price->product_id] = $price->discount_percent;
}

foreach ($prices_without as $price) {
    $prices_without_packing[$price->product_id] = $price->price;

    if (!isset($discounts_data[$price->product_id])) {
        $discounts_data[$price->product_id] = $price->discount_percent;
    }
}

}
?>

Price List Management

Select Party: Select Party id); ?>> party_name); ?> Effective Date: Load Prices

Price List for get_var($wpdb->prepare( “SELECT party_name FROM {$wpdb->prefix}dcm_parties WHERE id = %d”, $party_id )); echo esc_html($selected_party); ?> (Effective: )

id]) ? $prices_without_packing[$product->id] : ”; $current_price_with = isset($prices_with_packing[$product->id]) ? $prices_with_packing[$product->id] : ”; $current_discount = isset($discounts_data[$product->id]) ? $discounts_data[$product->id] : ”; $current_price_data = $wpdb->get_row($wpdb->prepare( “SELECT price, price_type FROM {$wpdb->prefix}dcm_price_list WHERE party_id = %d AND product_id = %d ORDER BY effective_date DESC, created_at DESC LIMIT 1″, $party_id, $product->id )); $current_price = $current_price_data ? $current_price_data->price : ”; $current_price_type = $current_price_data ? $current_price_data->price_type : ”; $last_updated = $wpdb->get_var($wpdb->prepare( “SELECT created_at FROM {$wpdb->prefix}dcm_price_list WHERE party_id = %d AND product_id = %d ORDER BY effective_date DESC LIMIT 1”, $party_id, $product->id )); ?>

Sr.Product NameProduct CodeCurrent PricePrice (Without Packing)Price (With Packing)Discount (%)Last UpdatedActions
product_name); ?> description): ?>
description); ?>
product_code); ?>
No price set
Must be > 0Must be > 00-100%Copy →
No products found. Add products first.

Update All PricesBulk Update Without PackingBulk Update With PackingAuto Calculate With PackingClear All

Price History

Click on any price field to view its history…

Select a Party

Please select a party and effective date to view and manage the price list.

////////////////////////////////////////////////////////////////////////////////
// File: manage-products.php (17 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/templates/manage-products.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

global $wpdb;
$products = $wpdb->get_results(“SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_name”);

if (isset($_POST[‘dcm_action’]) && $_POST[‘dcm_action’] === ‘add_product’) {
$result = handle_add_product();
if ($result[‘success’]) {
echo ‘

‘ . $result[‘message’] . ”;

    $products = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_name");
} else {
    echo '<div class="notice notice-error is-dismissible"><p>' . $result['message'] . '</p></div>';
}

}

if (isset($_POST[‘dcm_action’]) && $_POST[‘dcm_action’] === ‘edit_product’) {
$result = handle_edit_product();
if ($result[‘success’]) {
echo ‘

‘ . $result[‘message’] . ”;

    $products = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_name");
} else {
    echo '<div class="notice notice-error is-dismissible"><p>' . $result['message'] . '</p></div>';
}

}

if (isset($_POST[‘dcm_action’]) && $_POST[‘dcm_action’] === ‘bulk_import_products’) {
$result = handle_bulk_import();
if ($result[‘success’]) {
echo ‘

‘ . $result[‘message’] . ”;

    $products = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_name");
} else {
    echo '<div class="notice notice-error is-dismissible"><p>' . $result['message'] . '</p></div>';
}

}

$editing_product = null;
if (isset($_GET[‘edit_product’])) {
$product_id = intval($_GET[‘edit_product’]);
$editing_product = $wpdb->get_row($wpdb->prepare(
“SELECT * FROM {$wpdb->prefix}dcm_products WHERE id = %d”,
$product_id
));
}

function handle_add_product() {
global $wpdb;

if (!wp_verify_nonce($_POST['_wpnonce'], 'dcm_add_product')) {
    return ['success' => false, 'message' => 'Security verification failed.'];
}

$product_name = sanitize_text_field($_POST['product_name']);
$product_code = sanitize_text_field($_POST['product_code']);
$description = sanitize_textarea_field($_POST['description']);

if (empty($product_name) || empty($product_code)) {
    return ['success' => false, 'message' => 'Product name and code are required.'];
}

$existing = $wpdb->get_var($wpdb->prepare(
    "SELECT id FROM {$wpdb->prefix}dcm_products WHERE product_code = %s",
    $product_code
));

if ($existing) {
    return ['success' => false, 'message' => 'Product code already exists. Please use a unique code.'];
}

$product_image = '';
if (!empty($_FILES['product_image']['name'])) {
    $upload = handle_image_upload($_FILES['product_image']);
    if ($upload['success']) {
        $product_image = $upload['url'];
    } else {
        return ['success' => false, 'message' => $upload['message']];
    }
}

$result = $wpdb->insert(
    "{$wpdb->prefix}dcm_products",
    array(
        'product_name' => $product_name,
        'product_code' => $product_code,
        'product_image' => $product_image,
        'description' => $description,
        'created_at' => current_time('mysql'),
        'updated_at' => current_time('mysql')
    ),
    array('%s', '%s', '%s', '%s', '%s', '%s')
);

if ($result) {
    return ['success' => true, 'message' => 'Product added successfully!'];
} else {
    return ['success' => false, 'message' => 'Error adding product. Please try again.'];
}

}

function handle_edit_product() {
global $wpdb;

if (!wp_verify_nonce($_POST['_wpnonce'], 'dcm_edit_product')) {
    return ['success' => false, 'message' => 'Security verification failed.'];
}

$product_id = intval($_POST['product_id']);
$product_name = sanitize_text_field($_POST['product_name']);
$product_code = sanitize_text_field($_POST['product_code']);
$description = sanitize_textarea_field($_POST['description']);

if (empty($product_name) || empty($product_code)) {
    return ['success' => false, 'message' => 'Product name and code are required.'];
}

$existing = $wpdb->get_var($wpdb->prepare(
    "SELECT id FROM {$wpdb->prefix}dcm_products WHERE product_code = %s AND id != %d",
    $product_code, $product_id
));

if ($existing) {
    return ['success' => false, 'message' => 'Product code already exists. Please use a unique code.'];
}

$current_product = $wpdb->get_row($wpdb->prepare(
    "SELECT product_image FROM {$wpdb->prefix}dcm_products WHERE id = %d",
    $product_id
));

$product_image = $current_product->product_image;

if (!empty($_FILES['product_image']['name'])) {
    $upload = handle_image_upload($_FILES['product_image']);
    if ($upload['success']) {
        $product_image = $upload['url'];
    } else {
        return ['success' => false, 'message' => $upload['message']];
    }
}

$result = $wpdb->update(
    "{$wpdb->prefix}dcm_products",
    array(
        'product_name' => $product_name,
        'product_code' => $product_code,
        'product_image' => $product_image,
        'description' => $description,
        'updated_at' => current_time('mysql')
    ),
    array('id' => $product_id),
    array('%s', '%s', '%s', '%s', '%s'),
    array('%d')
);

if ($result !== false) {
    return ['success' => true, 'message' => 'Product updated successfully!'];
} else {
    return ['success' => false, 'message' => 'Error updating product. Please try again.'];
}

}

function handle_image_upload($file) {

$file_type = wp_check_filetype($file['name']);
$allowed_types = array('jpg', 'jpeg', 'png', 'gif', 'webp');

if (!in_array(strtolower($file_type['ext']), $allowed_types)) {
    return ['success' => false, 'message' => 'Only JPG, PNG, GIF, and WebP images are allowed.'];
}

if ($file['size'] > 2 * 1024 * 1024) {
    return ['success' => false, 'message' => 'Image size must be less than 2MB.'];
}

require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
require_once(ABSPATH . 'wp-admin/includes/media.php');

$upload = wp_handle_upload($file, array('test_form' => false));

if (isset($upload['error'])) {
    return ['success' => false, 'message' => $upload['error']];
}

return ['success' => true, 'url' => $upload['url']];

}

function handle_bulk_import() {
global $wpdb;

if (!wp_verify_nonce($_POST['_wpnonce'], 'dcm_bulk_import_products')) {
    return ['success' => false, 'message' => 'Security verification failed.'];
}

if (!isset($_FILES['csv_file']) || $_FILES['csv_file']['error'] !== UPLOAD_ERR_OK) {
    return ['success' => false, 'message' => 'Please select a valid CSV file.'];
}

$csv_file = $_FILES['csv_file']['tmp_name'];

if (($handle = fopen($csv_file, 'r')) !== FALSE) {
    $row = 0;
    $success_count = 0;
    $error_count = 0;

    while (($data = fgetcsv($handle, 1000, ',')) !== FALSE) {
        $row++;

        if ($row === 1) continue;

        if (count($data) < 2) {
            $error_count++;
            continue;
        }

        $product_name = sanitize_text_field($data[0]);
        $product_code = sanitize_text_field($data[1]);
        $description = isset($data[2]) ? sanitize_textarea_field($data[2]) : '';

        if (empty($product_name) || empty($product_code)) {
            $error_count++;
            continue;
        }

        $existing = $wpdb->get_var($wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}dcm_products WHERE product_code = %s",
            $product_code
        ));

        if ($existing) {
            $error_count++;
            continue;
        }

        $result = $wpdb->insert(
            "{$wpdb->prefix}dcm_products",
            array(
                'product_name' => $product_name,
                'product_code' => $product_code,
                'description' => $description,
                'created_at' => current_time('mysql'),
                'updated_at' => current_time('mysql')
            )
        );

        if ($result) {
            $success_count++;
        } else {
            $error_count++;
        }
    }
    fclose($handle);

    return [
        'success' => true, 
        'message' => "Bulk import completed! Success: {$success_count}, Failed: {$error_count}"
    ];
} else {
    return ['success' => false, 'message' => 'Error reading CSV file.'];
}

}
?>

Manage Products

<div class="dcm-tab-wrapper">
    <h2 class="nav-tab-wrapper">
        <a href="#products-list" class="nav-tab <?php echo !$editing_product ? 'nav-tab-active' : ''; ?>">All Products</a>
        <a href="#add-product" class="nav-tab <?php echo !$editing_product ? '' : 'nav-tab-active'; ?>">
            <?php echo $editing_product ? 'Edit Product' : 'Add New Product'; ?>
        </a>
        <a href="#bulk-import" class="nav-tab">Bulk Import</a>
    </h2>

    

> Search

ImageProduct NameProduct CodeDescriptionActions
product_image): ?> <?php echo esc_attr($product->product_name); ?> No Imageproduct_name); ?>product_code); ?>description ? $product->description : ‘No description’); ?>Edit Delete

No products found. Add your first product.

    <div id="add-product" class="dcm-tab-content" <?php echo $editing_product ? '' : 'style="display: none;"'; ?>>
        <form method="post" action="" enctype="multipart/form-data">
            <?php if ($editing_product): ?>
                <?php wp_nonce_field('dcm_edit_product'); ?>
                <input type="hidden" name="dcm_action" value="edit_product">
                <input type="hidden" name="product_id" value="<?php echo $editing_product->id; ?>">
                <h2>Edit Product</h2>
            <?php else: ?>
                <?php wp_nonce_field('dcm_add_product'); ?>
                <input type="hidden" name="dcm_action" value="add_product">
                <h2>Add New Product</h2>
            <?php endif; ?>

            <table class="form-table">
                <tr>
                    <th scope="row"><label for="product_name">Product Name *</label></th>
                    <td>
                        <input type="text" id="product_name" name="product_name" class="regular-text" required 
                               value="<?php echo $editing_product ? esc_attr($editing_product->product_name) : (isset($_POST['product_name']) ? esc_attr($_POST['product_name']) : ''); ?>">
                        <p class="description">Enter the full product name</p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><label for="product_code">Product Code *</label></th>
                    <td>
                        <input type="text" id="product_code" name="product_code" class="regular-text" required 
                               value="<?php echo $editing_product ? esc_attr($editing_product->product_code) : (isset($_POST['product_code']) ? esc_attr($_POST['product_code']) : ''); ?>">
                        <p class="description">Unique code for the product (e.g., UCNM, UOBS6)</p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><label for="product_image">Product Image</label></th>
                    <td>
                        <input type="file" id="product_image" name="product_image" accept="image

image-preview {

border: 2px dashed #ddd;
padding: 10px;
border-radius: 4px;
text-align: center;

}

preview-img {

max-width: 100%;
height: auto;

}

////////////////////////////////////////////////////////////////////////////////
// File: manage-parties.php (18 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/templates/manage-parties.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

global $wpdb;

$message = ”;
$message_type = ”;

if (isset($_POST[‘dcm_action’]) && ($_POST[‘dcm_action’] === ‘add_party’ || $_POST[‘dcm_action’] === ‘update_party’)) {

if (!wp_verify_nonce($_POST['_wpnonce'], 'dcm_party_nonce')) {
    $message = 'Security verification failed.';
    $message_type = 'error';
} else {
    $party_name = sanitize_text_field($_POST['party_name']);
    $address = sanitize_textarea_field($_POST['address']);
    $phone = sanitize_text_field($_POST['phone']);
    $email = sanitize_email($_POST['email']);
    $gstin = sanitize_text_field($_POST['gstin']);
    $transport_name = sanitize_text_field($_POST['transport_name']);
    $transport_id = sanitize_text_field($_POST['transport_id']);
    $default_packing_type = sanitize_text_field($_POST['default_packing_type']);
    $default_stickers = sanitize_text_field($_POST['default_stickers']);
    $remarks = sanitize_textarea_field($_POST['remarks']);

    if (empty($party_name)) {
        $message = 'Party name is required.';
        $message_type = 'error';
    } else {
        $party_data = array(
            'party_name' => $party_name,
            'address' => $address,
            'phone' => $phone,
            'email' => $email,
            'gstin' => $gstin,
            'transport_name' => $transport_name,
            'transport_id' => $transport_id,
            'default_packing_type' => $default_packing_type,
            'default_stickers' => $default_stickers,
            'remarks' => $remarks
        );

        if ($_POST['dcm_action'] === 'add_party') {

            $existing = $wpdb->get_var($wpdb->prepare(
                "SELECT id FROM {$wpdb->prefix}dcm_parties WHERE party_name = %s",
                $party_name
            ));

            if ($existing) {
                $message = 'A party with this name already exists.';
                $message_type = 'error';
            } else {
                $result = $wpdb->insert(
                    "{$wpdb->prefix}dcm_parties",
                    $party_data,
                    array('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
                );

                if ($result !== false) {
                    $message = 'Party added successfully!';
                    $message_type = 'success';
                } else {
                    $message = 'Error adding party: ' . $wpdb->last_error;
                    $message_type = 'error';
                }
            }
        } else {

            $party_id = intval($_POST['party_id']);

            $existing = $wpdb->get_var($wpdb->prepare(
                "SELECT id FROM {$wpdb->prefix}dcm_parties WHERE party_name = %s AND id != %d",
                $party_name, $party_id
            ));

            if ($existing) {
                $message = 'A party with this name already exists.';
                $message_type = 'error';
            } else {
                $result = $wpdb->update(
                    "{$wpdb->prefix}dcm_parties",
                    $party_data,
                    array('id' => $party_id),
                    array('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'),
                    array('%d')
                );

                if ($result !== false) {
                    $message = 'Party updated successfully!';
                    $message_type = 'success';
                } else {
                    $message = 'Error updating party: ' . $wpdb->last_error;
                    $message_type = 'error';
                }
            }
        }
    }
}

}

if (isset($_GET[‘action’]) && $_GET[‘action’] === ‘delete’ && isset($_GET[‘party_id’])) {
$party_id = intval($_GET[‘party_id’]);

if (wp_verify_nonce($_GET['_wpnonce'], 'delete_party_' . $party_id)) {

    $challan_count = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->prefix}dcm_challans WHERE party_id = %d",
        $party_id
    ));

    if ($challan_count > 0) {
        $message = 'Cannot delete party. It is used in ' . $challan_count . ' challan(s).';
        $message_type = 'error';
    } else {
        $result = $wpdb->delete(
            "{$wpdb->prefix}dcm_parties",
            array('id' => $party_id),
            array('%d')
        );

        if ($result !== false) {
            $message = 'Party deleted successfully!';
            $message_type = 'success';
        } else {
            $message = 'Error deleting party: ' . $wpdb->last_error;
            $message_type = 'error';
        }
    }
} else {
    $message = 'Security verification failed.';
    $message_type = 'error';
}

}

$edit_party = null;
if (isset($_GET[‘action’]) && $_GET[‘action’] === ‘edit’ && isset($_GET[‘party_id’])) {
$party_id = intval($_GET[‘party_id’]);
$edit_party = $wpdb->get_row($wpdb->prepare(
“SELECT * FROM {$wpdb->prefix}dcm_parties WHERE id = %d”,
$party_id
));

if (!$edit_party) {
    $message = 'Party not found.';
    $message_type = 'error';
}

}

$parties = $wpdb->get_results(“SELECT * FROM {$wpdb->prefix}dcm_parties ORDER BY party_name”);
?>

Manage Parties

All Parties

>

Party NameContact InfoTransport DetailsDefault SettingsGSTINActions
party_name); ?> address): ?>
address); ?>
phone): ?> 📞 phone); ?>
email): ?> ✉️ email); ?>
transport_name): ?> Transport: transport_name); ?>
transport_id): ?> ID: transport_id); ?>
Packing: default_packing_type)); ?>
Stickers: default_stickers)); ?>
gstin ? esc_html($party->gstin) : ‘Not provided‘; ?>Edit Delete

No parties found. Add your first party.

>

Edit Party: party_name); ?>

Add New Party

Party Name *Enter the full name of the party
Address<?php echo $edit_party ? esc_textarea($edit_party->address) : ”; ?> Complete address of the party
PhonePhone number with country code
EmailEmail address of the party
GSTINGST Identification Number
Transport NameName of the transport company
Transport IDTransport identification number
Default Packing Typedefault_packing_type === ‘without_packing’) ? ‘selected’ : ”; ?>>Without Packing default_packing_type === ‘with_packing’) ? ‘selected’ : ”; ?>>With Packing Default packing type for this party
Default Stickersdefault_stickers === ‘no_stickers’) ? ‘selected’ : ”; ?>>No Stickers default_stickers === ‘price_stickers’) ? ‘selected’ : ”; ?>>Price Stickers default_stickers === ‘without_price_stickers’) ? ‘selected’ : ”; ?>>Without Price Stickers default_stickers === ‘customer_stickers’) ? ‘selected’ : ”; ?>>Customer Stickers default_stickers === ‘harik_stickers’) ? ‘selected’ : ”; ?>>Harik Stickers Default stickers type for this party
Remarks<?php echo $edit_party ? esc_textarea($edit_party->remarks) : ”; ?> Additional remarks or notes

Cancel

////////////////////////////////////////////////////////////////////////////////
// File: manage-challans.php (19 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/templates/manage-challans.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

global $wpdb;

if (isset($_POST[‘dcm_bulk_action’]) && isset($_POST[‘challan_ids’])) {
check_admin_referer(‘dcm_bulk_action’);

$challan_ids = array_map('intval', $_POST['challan_ids']);
$placeholders = implode(',', array_fill(0, count($challan_ids), '%d'));

switch ($_POST['dcm_bulk_action']) {
    case 'delete':
        $wpdb->query($wpdb->prepare(
            "DELETE FROM {$wpdb->prefix}dcm_challans WHERE id IN ($placeholders)",
            $challan_ids
        ));
        $wpdb->query($wpdb->prepare(
            "DELETE FROM {$wpdb->prefix}dcm_challan_items WHERE challan_id IN ($placeholders)",
            $challan_ids
        ));
        $message = 'Challans deleted successfully!';
        $message_type = 'success';
        break;
}

}

global $wpdb;

if (isset($_GET[‘delete_challan’]) && wp_verify_nonce($_GET[‘_wpnonce’], ‘delete_challan’)) {
$challan_id = intval($_GET[‘delete_challan’]);

$wpdb->delete(
    "{$wpdb->prefix}dcm_challan_items",
    array('challan_id' => $challan_id),
    array('%d')
);

$result = $wpdb->delete(
    "{$wpdb->prefix}dcm_challans",
    array('id' => $challan_id),
    array('%d')
);

if ($result !== false) {
    $message = 'Challan deleted successfully!';
    $message_type = 'success';
} else {
    $message = 'Error deleting challan.';
    $message_type = 'error';
}

wp_redirect(admin_url('admin.php?page=manage-challans&message=' . ($result !== false ? 'deleted' : 'error')));
exit;

}

if (isset($_POST[‘dcm_bulk_action’]) && isset($_POST[‘challan_ids’])) {

}

$date_from = isset($_GET[‘date_from’]) ? sanitize_text_field($_GET[‘date_from’]) : ”;
$date_to = isset($_GET[‘date_from’]) ? sanitize_text_field($_GET[‘date_to’]) : date(‘Y-m-d’);
$party_id = isset($_GET[‘party_id’]) ? intval($_GET[‘party_id’]) : 0;

$where = array();
$params = array();

if ($date_from) {
$where[] = “c.challan_date >= %s”;
$params[] = $date_from;
}

if ($date_to) {
$where[] = “c.challan_date <= %s”;
$params[] = $date_to;
}

if ($party_id) {
$where[] = “c.party_id = %d”;
$params[] = $party_id;
}

$where_sql = $where ? “WHERE ” . implode(” AND “, $where) : “”;

$challans = $wpdb->get_results($wpdb->prepare(
“SELECT c.*, p.party_name
FROM {$wpdb->prefix}dcm_challans c
LEFT JOIN {$wpdb->prefix}dcm_parties p ON c.party_id = p.id
$where_sql
ORDER BY c.created_at DESC”,
…$params
));

$parties = $wpdb->get_results(“SELECT id, party_name FROM {$wpdb->prefix}dcm_parties ORDER BY party_name”);
?>

Manage Challans

From Date:To Date:Party: All Parties id); ?>> party_name); ?>  Filter

Reset Bulk Actions Delete Print Selected Export as PDF Apply created_by); $user_name = $user ? $user->display_name : ‘Unknown’; ?>

Challan NoParty NameDateTotal AmountCreated ByActions
challan_number); ?>party_name); ?>challan_date); ?>₹total_amount, 2); ?>Edit Print Delete
Total:

No challans found. Create your first challan.

////////////////////////////////////////////////////////////////////////////////
// File: reports.php (20 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/templates/reports.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

global $wpdb;

$date_from = isset($_GET[‘date_from’]) ? sanitize_text_field($_GET[‘date_from’]) : date(‘Y-m-d’, strtotime(‘-30 days’));
$date_to = isset($_GET[‘date_to’]) ? sanitize_text_field($_GET[‘date_to’]) : date(‘Y-m-d’);
$report_type = isset($_GET[‘report_type’]) ? sanitize_text_field($_GET[‘report_type’]) : ‘challan_summary’;

$parties = $wpdb->get_results(“SELECT id, party_name FROM {$wpdb->prefix}dcm_parties ORDER BY party_name”);

$report_data = array();
$report_title = ”;

$chart_data = array();

switch ($report_type) {
case ‘challan_summary’:
$report_title = ‘Challan Summary Report’;
$report_data = $wpdb->get_results($wpdb->prepare(
“SELECT c.*, p.party_name
FROM {$wpdb->prefix}dcm_challans c
LEFT JOIN {$wpdb->prefix}dcm_parties p ON c.party_id = p.id
WHERE c.challan_date BETWEEN %s AND %s
ORDER BY c.challan_date DESC”,
$date_from, $date_to
));

    $daily_challans = $wpdb->get_results($wpdb->prepare(
        "SELECT challan_date, COUNT(*) as count, SUM(total_amount) as amount
        FROM {$wpdb->prefix}dcm_challans 
        WHERE challan_date BETWEEN %s AND %s 
        GROUP BY challan_date 
        ORDER BY challan_date",
        $date_from, $date_to
    ));

    $chart_data['daily_challans'] = $daily_challans;
    break;

case 'party_wise':
    $report_title = 'Party-wise Summary';
    $report_data = $wpdb->get_results($wpdb->prepare(
        "SELECT p.party_name, 
                COUNT(c.id) as challan_count,
                SUM(c.total_amount) as total_amount
        FROM {$wpdb->prefix}dcm_parties p
        LEFT JOIN {$wpdb->prefix}dcm_challans c ON p.id = c.party_id 
            AND c.challan_date BETWEEN %s AND %s
        GROUP BY p.id, p.party_name
        HAVING total_amount > 0 OR challan_count > 0
        ORDER BY total_amount DESC",
        $date_from, $date_to
    ));

    $top_parties = array_slice($report_data, 0, 10); 
    $chart_data['top_parties'] = $top_parties;
    break;

case 'product_wise':
    $report_title = 'Product-wise Summary';
    $report_data = $wpdb->get_results($wpdb->prepare(
        "SELECT pr.product_name, 
                pr.product_code,
                pr.product_image,
                SUM(ci.quantity) as total_quantity,
                SUM(ci.amount) as total_amount
        FROM {$wpdb->prefix}dcm_products pr
        LEFT JOIN {$wpdb->prefix}dcm_challan_items ci ON pr.id = ci.product_id
        LEFT JOIN {$wpdb->prefix}dcm_challans c ON ci.challan_id = c.id 
            AND c.challan_date BETWEEN %s AND %s
        GROUP BY pr.id, pr.product_name, pr.product_code, pr.product_image
        HAVING total_amount > 0 OR total_quantity > 0
        ORDER BY total_amount DESC",
        $date_from, $date_to
    ));

    $top_products = array_slice($report_data, 0, 10); 
    $chart_data['top_products'] = $top_products;
    break;

case 'party_product_wise':
    $report_title = 'Party-wise Product Quantity Report';

    $all_products = $wpdb->get_results("SELECT id, product_code, product_name, product_image FROM {$wpdb->prefix}dcm_products ORDER BY product_code");

    $all_parties = $wpdb->get_results("SELECT id, party_name FROM {$wpdb->prefix}dcm_parties ORDER BY party_name");

    $party_product_data = $wpdb->get_results($wpdb->prepare(
        "SELECT 
            p.id as party_id,
            p.party_name,
            pr.id as product_id,
            pr.product_code,
            pr.product_name,
            pr.product_image,
            SUM(ci.quantity) as total_quantity
        FROM {$wpdb->prefix}dcm_parties p
        LEFT JOIN {$wpdb->prefix}dcm_challans c ON p.id = c.party_id 
            AND c.challan_date BETWEEN %s AND %s
        LEFT JOIN {$wpdb->prefix}dcm_challan_items ci ON c.id = ci.challan_id
        LEFT JOIN {$wpdb->prefix}dcm_products pr ON ci.product_id = pr.id
        GROUP BY p.id, p.party_name, pr.id, pr.product_code, pr.product_name, pr.product_image
        HAVING total_quantity > 0
        ORDER BY p.party_name, pr.product_code",
        $date_from, $date_to
    ));

    $report_data = array();
    $party_totals = array();

    foreach ($all_parties as $party) {
        $party_row = array(
            'party_id' => $party->id,
            'party_name' => $party->party_name,
            'products' => array(),
            'party_total' => 0
        );

        foreach ($all_products as $product) {
            $party_row['products'][$product->id] = array(
                'quantity' => 0,
                'product_code' => $product->product_code,
                'product_name' => $product->product_name,
                'product_image' => $product->product_image
            );
        }

        foreach ($party_product_data as $item) {
            if ($item->party_id == $party->id && isset($party_row['products'][$item->product_id])) {
                $party_row['products'][$item->product_id]['quantity'] = $item->total_quantity;
                $party_row['party_total'] += $item->total_quantity;
            }
        }

        if ($party_row['party_total'] > 0) {
            $report_data[] = $party_row;
        }
    }

    $chart_data['all_products'] = $all_products;
    $chart_data['party_product_data'] = $party_product_data;
    break;

}

$grand_total = 0;
$total_challans = 0;
$total_amount = 0;
$total_quantity = 0;

if ($report_type == ‘challan_summary’) {
foreach ($report_data as $challan) {
$grand_total += $challan->total_amount;
}
} elseif ($report_type == ‘party_wise’) {
foreach ($report_data as $party) {
$total_challans += $party->challan_count;
$total_amount += $party->total_amount;
}
} elseif ($report_type == ‘product_wise’) {
foreach ($report_data as $product) {
$total_quantity += $product->total_quantity;
$total_amount += $product->total_amount;
}
} elseif ($report_type == ‘party_product_wise’) {
foreach ($report_data as $party) {
$total_quantity += $party[‘party_total’];
}
}

$js_chart_data = array();
if ($report_type == ‘challan_summary’ && !empty($chart_data[‘daily_challans’])) {
$js_chart_data[‘daily_challans’] = $chart_data[‘daily_challans’];
} elseif ($report_type == ‘party_wise’ && !empty($chart_data[‘top_parties’])) {
$js_chart_data[‘top_parties’] = $chart_data[‘top_parties’];
} elseif ($report_type == ‘product_wise’ && !empty($chart_data[‘top_products’])) {
$js_chart_data[‘top_products’] = $chart_data[‘top_products’];
} elseif ($report_type == ‘party_product_wise’ && !empty($chart_data[‘all_products’])) {
$js_chart_data[‘all_products’] = $chart_data[‘all_products’];
}
?>

Reports

Report Type: >Challan Summary >Party-wise Summary >Product-wise Summary >Party-Product Quantity Report From Date:To Date: Generate ReportExport ExcelExport PDF

Period: to

Visual Reports & Analytics

Daily Challan Trend

Challan Amount Distribution

Top Parties by Revenue

Party-wise Challan Count

Top Products by Revenue

Product-wise Quantity Sold

Top Selling Products

Top Parties by Quantity

No chart data available for the selected criteria.

📊

Total Challans

💰

Total Revenue

📅

Date Range

👥

Total Parties

📋

Total Challans

💰

Total Revenue

📦

Total Products

🔢

Total Quantity

💰

Total Revenue

👥

Total Parties

📦

Total Products

🔢

Total Quantity

total_amount; $user = get_userdata($challan->created_by); ?>

Challan NoParty NameDateTotal AmountCreated By
challan_number); ?>party_name); ?>challan_date); ?>₹total_amount, 2); ?>display_name) : ‘Unknown’; ?>
Grand Total:

challan_count; $total_amount += $party->total_amount; $average = $party->challan_count > 0 ? $party->total_amount / $party->challan_count : 0; ?>

Party NameChallan CountTotal AmountAverage per Challan
party_name); ?>challan_count); ?>₹total_amount, 2); ?>
Total₹ 0 ? $total_amount / $total_challans : 0, 2); ?>

total_quantity; $total_amount += $product->total_amount; $average_price = $product->total_quantity > 0 ? $product->total_amount / $product->total_quantity : 0; ?>

Product CodeProduct NameTotal QuantityTotal AmountAverage Price
product_code); ?>product_name); ?>total_quantity); ?>₹total_amount, 2); ?>
Total

id; }, $chart_data[‘all_products’]), 0); $grand_total = 0; foreach ($report_data as $party): $grand_total += $party[‘party_total’]; ?> id][‘quantity’]; $product_totals[$product->id] += $quantity; ?>

Party Nameproduct_image): ?> <?php echo esc_attr($product->product_name); ?>No Imageproduct_code); ?>Total
0): ?> –
Totalid]); ?>

Report Notes

  • This report shows the total quantity of each product sold to each party
  • Empty cells (-) indicate no sales of that product to that party
  • Product codes are displayed in column headers with product images
  • Totals are shown for each party and each product

Report Summary

Total Records:

Total Amount:

Total Quantity:

No data found for the selected criteria.

////////////////////////////////////////////////////////////////////////////////
// File: line-item-report.php (21 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/templates/line-item-report.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

global $wpdb;

$date_from = isset($_GET[‘date_from’]) ? sanitize_text_field($_GET[‘date_from’]) : date(‘Y-m-d’, strtotime(‘-30 days’));
$date_to = isset($_GET[‘date_to’]) ? sanitize_text_field($_GET[‘date_to’]) : date(‘Y-m-d’);
$party_id = isset($_GET[‘party_id’]) ? intval($_GET[‘party_id’]) : 0;
$product_id = isset($_GET[‘product_id’]) ? intval($_GET[‘product_id’]) : 0;

$sort_by = isset($_GET[‘sort_by’]) ? sanitize_text_field($_GET[‘sort_by’]) : ‘challan_date’;
$sort_order = isset($_GET[‘sort_order’]) ? sanitize_text_field($_GET[‘sort_order’]) : ‘DESC’;

$allowed_sort_columns = [
‘challan_date’, ‘product_code’, ‘product_name’, ‘party_name’,
‘packing_type’, ‘price’, ‘quantity’, ‘discount_percent’,
‘gst_amount’, ‘billing_amount’, ‘challan_number’
];
$sort_by = in_array($sort_by, $allowed_sort_columns) ? $sort_by : ‘challan_date’;
$sort_order = in_array($sort_order, [‘ASC’, ‘DESC’]) ? $sort_order : ‘DESC’;

$where_conditions = array();
$params = array();

$where_conditions[] = “c.challan_date BETWEEN %s AND %s”;
$params[] = $date_from;
$params[] = $date_to;

if ($party_id) {
$where_conditions[] = “c.party_id = %d”;
$params[] = $party_id;
}

if ($product_id) {
$where_conditions[] = “ci.product_id = %d”;
$params[] = $product_id;
}

$where_sql = $where_conditions ? “WHERE ” . implode(” AND “, $where_conditions) : “”;

$line_items = $wpdb->get_results($wpdb->prepare(
“SELECT
c.challan_date,
p.product_code,
p.product_name,
party.party_name,
ci.packing_type,
ci.price,
ci.quantity,
ci.discount_percent,
(ci.amount * 0.18) as gst_amount, — Assuming 18% GST, adjust as needed
ci.amount as billing_amount,
c.challan_number,
c.remarks
FROM {$wpdb->prefix}dcm_challan_items ci
LEFT JOIN {$wpdb->prefix}dcm_challans c ON ci.challan_id = c.id
LEFT JOIN {$wpdb->prefix}dcm_products p ON ci.product_id = p.id
LEFT JOIN {$wpdb->prefix}dcm_parties party ON c.party_id = party.id
{$where_sql}
ORDER BY {$sort_by} {$sort_order}”,
…$params
));

$parties = $wpdb->get_results(“SELECT id, party_name FROM {$wpdb->prefix}dcm_parties ORDER BY party_name”);
$products = $wpdb->get_results(“SELECT id, product_name, product_code FROM {$wpdb->prefix}dcm_products ORDER BY product_name”);

$total_qty = 0;
$total_discount_amount = 0;
$total_gst = 0;
$total_billing = 0;

foreach ($line_items as $item) {
$total_qty += $item->quantity;
$total_discount_amount += ($item->price * $item->quantity * $item->discount_percent / 100);
$total_gst += $item->gst_amount;
$total_billing += $item->billing_amount;
}

function get_sortable_header($title, $sort_field, $current_sort, $current_order, $base_url) {
$new_order = ($current_sort == $sort_field && $current_order == ‘ASC’) ? ‘DESC’ : ‘ASC’;
$url = add_query_arg(array(
‘sort_by’ => $sort_field,
‘sort_order’ => $new_order
), $base_url);

$indicator = '';
if ($current_sort == $sort_field) {
    $indicator = $current_order == 'ASC' ? ' ↑' : ' ↓';
}

return '<a href="' . esc_url($url) . '" class="sortable-header" data-sort="' . esc_attr($sort_field) . '">' . 
       esc_html($title) . $indicator . '</a>';

}

$base_url = remove_query_arg(array(‘sort_by’, ‘sort_order’));
?>

Line Item Challan Report

From Date:To Date:Party: All Parties id); ?>> party_name); ?> Product: All Products id); ?>> product_name . ‘ (‘ . $product->product_code . ‘)’); ?>  Generate ReportExport Excel

Reset

Line Item Report (Sorted by: )

Period: to

Remarks
challan_date); ?>product_code); ?>product_name); ?>party_name); ?>packing_type)); ?>₹price, 2); ?>quantity); ?>discount_percent, 1); ?>%₹gst_amount, 2); ?>₹billing_amount, 2); ?>challan_number); ?>remarks); ?>
Grand Totals:

Report Summary

Total Line Items:

Total Quantity:

Total Discount Amount:₹

Total Billing Amount:₹

No line items found for the selected criteria.

////////////////////////////////////////////////////////////////////////////////
// File: import-export.php (22 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/templates/import-export.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

if (isset($_GET[‘import_message’])) {
$message_type = isset($_GET[‘message_type’]) ? $_GET[‘message_type’] : ‘success’;
$imported = isset($_GET[‘imported’]) ? intval($_GET[‘imported’]) : 0;
$message = esc_html(urldecode($_GET[‘import_message’]));

$message_class = 'notice-' . $message_type;
if ($message_type === 'error') {
    $message_class = 'notice-error';
} elseif ($message_type === 'success') {
    $message_class = 'notice-success';
} elseif ($message_type === 'warning') {
    $message_class = 'notice-warning';
} else {
    $message_class = 'notice-info';
}

echo '

‘ . $message . ‘

‘;
}

if (isset($_GET[‘import_success’]) && isset($_GET[‘imported’])) {
$imported = intval($_GET[‘imported’]);
echo ‘

Successfully imported ‘ . $imported . ‘ records!

‘;
}
?>

Import/Export Masters

Export Masters

Export your parties, products, and price list to CSV or Excel format for backup or editing in spreadsheet software.

Export TypeParties Only Products Only Price List Only All Masters
Export FormatCSV (Compatible with Google Sheets) Excel Format

Export Data

Import Masters

Import parties, products, and price list from CSV or Excel files. Files should follow the format of exported files.

Import TypeParties Products Price List
Select FileSupported formats: CSV, XLSX, XLS (Max: 8MB)

Import Data

Download Templates

Download template files to ensure your import files have the correct format.

Download Parties TemplateDownload Products TemplateDownload Price List Template

File Format Guidelines:

Parties CSV Format:

Party Name,Address,Phone,Email,GSTIN,Transport Name,Transport ID,Default Packing Type,Default Stickers,Remarks
A.H.B. International,"Sample Address, City - 123456",1234567890,contact@ahb.com,GSTIN123456789,ABC Transport,TRANS123,without_packing,no_stickers,Sample customer
Another Party,"Another Address, City - 654321",9876543210,info@another.com,GSTIN987654321,XYZ Transport,TRANS456,with_packing,price_stickers,Another customer

Products CSV Format:

Product Name,Product Code,Description
Urea Cap New Model - UCNM,UCNM,New model urea cap
Urea Cap for BS6- UOBS6 I,UOBS6,BS6 compatible urea cap

Price List CSV Format (Wide Format):

Party,Discount (%),Effective Date,UCNM Without Packing,UCNM With Packing,UOBS6 Without Packing,UOBS6 With Packing
A.H.B. International,5.00,2024-01-01,125.00,135.00,110.00,120.00
Another Party,10.00,2024-01-01,130.00,140.00,115.00,125.00

Note for Price List: The template uses wide format where each row represents a party, and columns are organized by product codes with separate columns for both packing types. The discount percentage applies to all products for that party.

Import Instructions:

  1. Download the appropriate template for the data you want to import
  2. Fill in your data following the template format
  3. Save the file as CSV format
  4. Use the import form above to upload your file
  5. Check the import results message that appears at the top of the page

Important Notes:

  • Party Name must be unique – duplicates will be updated
  • Product Code must be unique – duplicates will be updated
  • For Price List, make sure party and product names/codes match existing records
  • Empty price values will be skipped during import
  • Default values will be used for missing optional fields

Google Sheets Integration

Connect with Google Sheets for real-time synchronization (Advanced Feature).

Setup Instructions:

  1. Export your data using the export feature above
  2. Upload the CSV to Google Sheets
  3. Make your changes in Google Sheets
  4. Download as CSV and import back using the import feature

Note: Full Google Sheets API integration requires additional setup and is available in the premium version.

////////////////////////////////////////////////////////////////////////////////
// File: comprehensive-price-list.php (23 of 23)
// Path: /home/u329631886/domains/challan.pghut.com/public_html//wp-content/plugins/delivery-challan-manager-1-2-5-6-2-2-1-1-2/templates/comprehensive-price-list.php
// Type: php
////////////////////////////////////////////////////////////////////////////////

global $wpdb;

$parties = $wpdb->get_results(“SELECT * FROM {$wpdb->prefix}dcm_parties ORDER BY party_name”);
$products = $wpdb->get_results(“SELECT * FROM {$wpdb->prefix}dcm_products ORDER BY product_code”);

$effective_date = isset($_GET[‘effective_date’]) ? sanitize_text_field($_GET[‘effective_date’]) : date(‘Y-m-d’);

$prices_data = array();

foreach ($parties as $party) {
$party_prices = array();

foreach ($products as $product) {

    $price_without = $wpdb->get_row($wpdb->prepare("
        SELECT price, discount_percent 
        FROM {$wpdb->prefix}dcm_price_list 
        WHERE party_id = %d AND product_id = %d AND price_type = 'without_packing' AND effective_date <= %s
        ORDER BY effective_date DESC LIMIT 1
    ", $party->id, $product->id, $effective_date));

    $price_with = $wpdb->get_row($wpdb->prepare("
        SELECT price, discount_percent 
        FROM {$wpdb->prefix}dcm_price_list 
        WHERE party_id = %d AND product_id = %d AND price_type = 'with_packing' AND effective_date <= %s
        ORDER BY effective_date DESC LIMIT 1
    ", $party->id, $product->id, $effective_date));

    $party_prices[$product->id] = array(
        'without_packing' => $price_without ? $price_without->price : null,
        'with_packing' => $price_with ? $price_with->price : null,
        'discount' => $price_without ? $price_without->discount_percent : ($price_with ? $price_with->discount_percent : 0)
    );
}

$prices_data[$party->id] = $party_prices;

}

$first_column_width = ‘300px’;
$second_column_width = ‘200px’;
$product_column_width = ‘150px’;
$total_columns = 2 + count($products);
?>

Comprehensive Price List

Effective Date: Load Prices

Reset

id][$product->id] ?? array(); $price_without = $price_data[‘without_packing’] ?? null; $price_with = $price_data[‘with_packing’] ?? null; $discount = $price_data[‘discount’] ?? 0; ?>

Party DetailsTransport & Settingsproduct_image): ?> <?php echo esc_attr($product->product_name); ?>No Imageproduct_code); ?>product_name); ?>
W/O PackWith PackDisc %
party_name); ?> gstin): ?> GSTIN: gstin); ?> phone): ?> 📞 phone); ?> email): ?> ✉️ email); ?> address): ?> 📍 address); ?>transport_name): ?> Transport:transport_name); ?> transport_id): ?> ID: transport_id); ?> Packing: default_packing_type)); ?> Stickers: default_stickers)); ?> remarks): ?> Remarks:remarks); ?>₹ – ₹ – % Edit

Total Parties

Total Products

Effective Date

No Data Available

No parties found. Add parties first. No products found. Add products first.

Scroll to Top