Plugin Directory

Changeset 3450193


Ignore:
Timestamp:
01/30/2026 07:36:20 AM (2 months ago)
Author:
enituretechnology
Message:

1.0.14 - 2026-01-30

  • Update: Added a caching mechanism to efficiently handle multiple identical quote requests and reduce redundant API calls.
  • Update: Added product-level offset days functionality to allow more granular shipment timing control.
  • Update: Introduced bulk delete functionality for warehouse and dropship locations to simplify location management.
  • Update: Updated shipment logic to treat virtual products as single-shipment cases instead of multi-shipment cases in both cart and checkout.
  • Update: Added delivery estimate options and order cutoff time functionality in the quote settings for improved delivery accuracy.
  • Update: Added parent product checks to properly handle empty variant scenarios and prevent invalid processing.

Ticket 23708293437

Location:
ltl-freight-quotes-freightview-edition
Files:
12 added
44 edited
1 copied

Legend:

Unmodified
Added
Removed
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/assets/en-freightview-admin.css

    r3386279 r3450193  
    6060    border-radius: 1px;
    6161    height: 36px !important;
     62}
     63
     64.en_quote_settings_all_shipment_days_freightview_tr td {
     65  display: flex !important;
     66  align-items: center;
     67  gap: 16px;
     68  flex-wrap: nowrap;
    6269}
    6370
     
    337344}
    338345.handling_unit_weight_freightview_tr th,
    339 .maximum_handling_weight_freightview_tr th {
     346.maximum_handling_weight_freightview_tr th,
     347.freightview_cutt_off_time_ship_date_offset th,
     348.en_quote_settings_shipment_offset_days_freightview_tr th,
     349.en_quote_settings_all_shipment_days_freightview_tr th {
    340350    padding: 15px 0 0 10px !important;
    341351    font-weight: 400;
    342352}
    343353.handling_unit_weight_freightview_tr td,
    344 .maximum_handling_weight_freightview_tr td {
     354.maximum_handling_weight_freightview_tr td,
     355.freightview_cutt_off_time_ship_date_offset td,
     356.en_quote_settings_shipment_offset_days_freightview_tr td,
     357.en_quote_settings_all_shipment_days_freightview_tr td {
    345358    padding: 10px 0 10px 10px !important;
    346359}
     
    361374.woocommerce_variable_attributes.wc-metabox-content [class^="_nmfc_number"],
    362375.woocommerce_variable_attributes.wc-metabox-content [class^="_en_product_markup"],
     376.woocommerce_variable_attributes.wc-metabox-content [class^="_eniture_product_level_fulfillment_offset_days"],
    363377.woocommerce_variable_attributes.wc-metabox-content [class^="_nestedPercentage"],
    364378.woocommerce_variable_attributes.wc-metabox-content [class^="en_flat_rate_price"],
     
    384398.woocommerce_variable_attributes.wc-metabox-content [class^="en_flat_rate_price"],
    385399.woocommerce_variable_attributes.wc-metabox-content [class^="_en_product_markup"],
     400.woocommerce_variable_attributes.wc-metabox-content [class^="_eniture_product_level_fulfillment_offset_days"],
    386401.woocommerce_variable_attributes.wc-metabox-content [class^="_nestedPercentage"],
    387402.woocommerce_variable_attributes.wc-metabox-content [class^="_nestedDimension"],
     
    393408.woocommerce_variable_attributes.wc-metabox-content .data p[class*="en_flat_rate_price"] span.woocommerce-help-tip,
    394409.woocommerce_variable_attributes.wc-metabox-content .data p[class*="_en_product_markup"] span.woocommerce-help-tip,
     410.woocommerce_variable_attributes.wc-metabox-content .data p[class*="_eniture_product_level_fulfillment_offset_days"] span.woocommerce-help-tip,
    395411.woocommerce_variable_attributes.wc-metabox-content .data p[class*="_nestedPercentage"] span.woocommerce-help-tip,
    396412.woocommerce_variable_attributes.wc-metabox-content .data p[class*="_nestedDimension"] span.woocommerce-help-tip,
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/assets/en-freightview-admin.js

    r3386279 r3450193  
    163163                if (!is_data_valid) {
    164164                    en_data_error = false;
    165                     jQuery('.subsubsub').next('.clear').after('<div class="notice notice-error en_settings_message"><p><strong>Error! </strong>' + en_error_msg + '</p></div>');
     165                    const next_elem = (jQuery('.subsubsub').next('.clear'))?.length ? '.clear' : '#en-woo-review-plugin';
     166                    jQuery('.subsubsub').next(next_elem).after('<div class="notice notice-error en_settings_message"><p><strong>Error! </strong>' + en_error_msg + '</p></div>');
    166167                }
    167168            });
     
    173174            }
    174175
     176            // Validate fullfillment offset days
     177            if (!freightviewValidateFullfillmentOffsetDays()) return false;
    175178            // Backup rates validation
    176179            if (!freightviewBackupRatesValidations()) return false;
     
    419422    // Backup rates settings
    420423    freightviewBackupRatesSettings();
     424    // Cut-off time and shipment offset days settings
     425    freightviewCutOffTimeAndShipDateSettings();
    421426});
    422427// Weight threshold for LTL freight
     
    855860    }
    856861}
     862
     863if (typeof freightviewCutOffTimeAndShipDateSettings != 'function') {
     864    function freightviewCutOffTimeAndShipDateSettings() {
     865        jQuery("#en_quote_settings_shipment_offset_days_freightview").closest('tr').addClass("en_quote_settings_shipment_offset_days_freightview_tr");
     866        jQuery("#en_quote_settings_all_shipment_days_freightview").closest('tr').addClass("en_quote_settings_all_shipment_days_freightview_tr");
     867        jQuery(".freightview_shipment_day ").closest('tr').addClass("freightview_shipment_day_tr");
     868        jQuery("#en_quote_settings_order_cut_off_time_freightview").closest('tr').addClass("freightview_cutt_off_time_ship_date_offset");
     869
     870        const freightview_current_time = en_freightview_admin_script.freightview_order_cut_off_time;
     871        if (freightview_current_time == '') {
     872            jQuery('#en_quote_settings_order_cut_off_time_freightview').wickedpicker({
     873                now: '',
     874                title: 'Cut Off Time',
     875            });
     876        } else {
     877            jQuery('#en_quote_settings_order_cut_off_time_freightview').wickedpicker({
     878                now: freightview_current_time,
     879                title: 'Cut Off Time'
     880            });
     881        }
     882
     883        const show_delivery_estimate = jQuery('input[name=en_quote_settings_delivery_estimate_options_freightview]:checked').val();
     884        if (show_delivery_estimate === 'dont_show_estimates') {
     885            jQuery("#en_quote_settings_order_cut_off_time_freightview").prop('disabled', true);
     886            jQuery("#en_quote_settings_shipment_offset_days_freightview").prop('disabled', true);
     887            jQuery("#en_quote_settings_shipment_offset_days_freightview").css("cursor", "not-allowed");
     888            jQuery("#en_quote_settings_order_cut_off_time_freightview").css("cursor", "not-allowed");
     889            jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').prop('disabled', true);
     890            jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').css("cursor", "not-allowed");
     891        } else {
     892            jQuery("#en_quote_settings_order_cut_off_time_freightview").prop('disabled', false);
     893            jQuery("#en_quote_settings_shipment_offset_days_freightview").prop('disabled', false);
     894            jQuery("#en_quote_settings_order_cut_off_time_freightview").css("cursor", "");
     895            jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').prop('disabled', false);
     896            jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').css("cursor", "");
     897        }
     898
     899        jQuery("input[name=en_quote_settings_delivery_estimate_options_freightview]").change(function () {
     900            const show_delivery_estimate = jQuery('input[name=en_quote_settings_delivery_estimate_options_freightview]:checked').val();
     901           
     902            if (show_delivery_estimate === 'dont_show_estimates') {
     903                jQuery("#en_quote_settings_order_cut_off_time_freightview").prop('disabled', true);
     904                jQuery("#en_quote_settings_shipment_offset_days_freightview").prop('disabled', true);
     905                jQuery("#en_quote_settings_order_cut_off_time_freightview").css("cursor", "not-allowed");
     906                jQuery("#en_quote_settings_shipment_offset_days_freightview").css("cursor", "not-allowed");
     907                jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').prop('disabled', true);
     908                jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').css("cursor", "not-allowed");
     909            } else {
     910                jQuery("#en_quote_settings_order_cut_off_time_freightview").prop('disabled', false);
     911                jQuery("#en_quote_settings_shipment_offset_days_freightview").prop('disabled', false);
     912                jQuery("#en_quote_settings_order_cut_off_time_freightview").css("cursor", "auto");
     913                jQuery("#en_quote_settings_shipment_offset_days_freightview").css("cursor", "auto");
     914                jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').prop('disabled', false);
     915                jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').css("cursor", "auto");
     916            }
     917        });
     918
     919        /*
     920        * Uncheck Week days Select All Checkbox
     921        */
     922        jQuery(".freightview_shipment_day").on('change load', function () {
     923
     924            const checkboxes = jQuery('.freightview_shipment_day:checked').length;
     925            const un_checkboxes = jQuery('.freightview_shipment_day').length;
     926
     927            if (checkboxes === un_checkboxes) {
     928                jQuery('.all_shipment_days_freightview_lfq').prop('checked', true);
     929            } else {
     930                jQuery('.all_shipment_days_freightview_lfq').prop('checked', false);
     931            }
     932        });
     933
     934        /*
     935        * Select All Shipment Week days
     936        */
     937
     938        const all_int_checkboxes = jQuery('.all_shipment_days_freightview_lfq');
     939        if (all_int_checkboxes.length === all_int_checkboxes.filter(":checked").length) {
     940            jQuery('.all_shipment_days_freightview_lfq').prop('checked', true);
     941        }
     942
     943        jQuery(".all_shipment_days_freightview_lfq").change(function () {
     944            if (this.checked) {
     945                jQuery(".freightview_shipment_day").each(function () {
     946                    this.checked = true;
     947                });
     948            } else {
     949                jQuery(".freightview_shipment_day").each(function () {
     950                    this.checked = false;
     951                });
     952            }
     953        });
     954
     955        const main_td = jQuery('.en_quote_settings_all_shipment_days_freightview_tr td');
     956        const rows   = jQuery('tr.freightview_shipment_day_tr');
     957
     958        if (!main_td.length || !rows.length) return;
     959
     960        // Move all day checkboxes into main row
     961        rows.each(function () {
     962            const input_wrap = jQuery(this).find('td > *').first();
     963            if (input_wrap.length) main_td.append(input_wrap);
     964        });
     965
     966        // Hide original rows
     967        rows.hide();
     968
     969        // ---- Select All sync ----
     970        const select_all = main_td.find('input[type="checkbox"]').first();
     971        const days = main_td.find('input[type="checkbox"]').not(select_all);
     972
     973        // Select all → days
     974        select_all.on('change', function () {
     975            days.prop('checked', this.checked);
     976        });
     977        // Days → select all
     978        days.on('change', function () {
     979            select_all.prop('checked', days.length === days.filter(':checked').length);
     980        });
     981    }
     982}
     983
     984if (typeof freightviewValidateFullfillmentOffsetDays !== 'function') {
     985    function freightviewValidateFullfillmentOffsetDays() {
     986        const offset_days = jQuery("#en_quote_settings_shipment_offset_days_freightview").val();
     987        const number_regex = /^[0-9]+$/;
     988        let error_msg = '';
     989       
     990        if (offset_days != "" && offset_days < 1) error_msg = 'Fulfillment Offset Days should not be less than 1.';
     991        if (!error_msg && offset_days != "" && offset_days > 20) error_msg = 'Fulfillment Offset Days should not be greater than 20.';
     992        if (!error_msg && offset_days != "" && !number_regex.test(offset_days)) error_msg = 'Fulfillment Offset Days should be a number.';
     993
     994        if (error_msg) {
     995            jQuery('.en_freightview_ltl_plan_notice').after('<div class="notice notice-error en_settings_message"><p><strong>Error! </strong>' + error_msg + '</p></div>');
     996            jQuery('#en_settings_message').delay(200).animate({scrollTop: 0}, 1000);
     997            jQuery('html, body').animate({scrollTop: 0}, 'slow');
     998            return false;
     999        }
     1000
     1001        return true;
     1002    }
     1003}
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/product/en-product-detail.php

    r3290396 r3450193  
    7777                    $custom_field = (isset($custom_field['id'])) ? $custom_field['id'] : '';
    7878                    $en_updated_product = (isset($_POST[$custom_field][$postId])) ? sanitize_text_field($_POST[$custom_field][$postId]) : '';
    79                     $en_updated_product = $custom_field == '_dropship_location' ?
    80                         (maybe_serialize(is_array($en_updated_product) ? array_map('intval', $en_updated_product) : $en_updated_product)) : esc_attr($en_updated_product);
     79
     80                    if ($custom_field == '_dropship_location') {
     81                        $en_updated_product = maybe_serialize(is_array($en_updated_product) ? array_map('intval', $en_updated_product) : $en_updated_product);
     82                    } elseif ($custom_field == '_eniture_product_level_fulfillment_offset_days') {
     83                        $en_updated_product = $this->sanitize_fulfillment_offset_days($en_updated_product);
     84                    } else {
     85                        $en_updated_product = esc_attr($en_updated_product);
     86                    }
     87
    8188                    update_post_meta($postId, $custom_field, $en_updated_product);
    8289                }
    8390            }
     91        }
     92
     93        private function sanitize_fulfillment_offset_days($value)
     94        {
     95            $value = trim($value);
     96            if ($value === '' || $value === null) return '';
     97
     98            $value = preg_replace('/[^0-9.-]/', '', $value);
     99            if (!is_numeric($value)) return '';
     100
     101            $value = intval(floor(floatval($value)));
     102            return $value < 0 ? '' : strval($value);
    84103        }
    85104
     
    178197                ],
    179198                [
     199                    'type' => 'input_field',
     200                    'input_type' => 'number',
     201                    'id' => '_eniture_product_level_fulfillment_offset_days',
     202                    'class' => '_eniture_product_level_fulfillment_offset_days short',
     203                    'label' => __( 'Fulfillment Offset Days', 'woocommerce' ),
     204                    'placeholder' => 'Fulfillment offset days, e.g. 2',
     205                    'description' => "The number of days the ship date needs to be moved to allow for the processing of the order. If set, this will override the global Fulfillment Offset Days setting for this product.",
     206                    'custom_attributes' => [
     207                        'min' => '1',
     208                        'max' => '20',
     209                        'step' => '1',
     210                        'title' => 'Value must be greater than or equal to 1 and less than or equal to 20',
     211                        'oninvalid' => "this.setCustomValidity(this.validity.rangeUnderflow ? 'Value must be greater than or equal to 1' : this.validity.rangeOverflow ? 'Value must be less than or equal to 20' : '')",
     212                        'oninput' => "this.setCustomValidity('')"
     213                    ]
     214                ],
     215                [
    180216                    'type' => 'checkbox',
    181217                    'id' => '_hazardousmaterials',
     
    292328                'label' => $custom_field['label'],
    293329                'class' => $custom_field['class'],
    294                 'placeholder' => $custom_field['label'],
     330                'placeholder' => isset($custom_field['placeholder']) ? $custom_field['placeholder'] : $custom_field['label'],
    295331                'value' => get_post_meta($postId, $custom_field['id'], true)
    296332            ];
     333
     334            // Add input type if specified (e.g., 'number')
     335            if (isset($custom_field['input_type'])) {
     336                $custom_input_field['type'] = $custom_field['input_type'];
     337            }
     338
     339            // Add custom attributes if specified (e.g., min, max, step)
     340            if (isset($custom_field['custom_attributes'])) {
     341                $custom_input_field['custom_attributes'] = $custom_field['custom_attributes'];
     342            }
    297343
    298344            if (isset($custom_field['description'])) {
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/tab/en-tab.php

    r3386279 r3450193  
    161161            $settings = $this->get_settings($current_section);
    162162
     163             // Cuttoff Time
     164            if (isset($_POST['en_quote_settings_order_cut_off_time_freightview']) && $_POST['en_quote_settings_order_cut_off_time_freightview'] != '') {
     165                $time_24_format = $this->get_time_in_24_hours($_POST['en_quote_settings_order_cut_off_time_freightview']);
     166                $_POST['en_quote_settings_order_cut_off_time_freightview'] = $time_24_format;
     167            }
     168
    163169            // backup rates
    164170            $backup_rates_fields = ['freightview_backup_rates_fixed_rate', 'freightview_backup_rates_cart_price_percentage', 'freightview_backup_rates_weight_function'];
     
    170176        }
    171177
     178         /**
     179         * Cuttoff Time
     180         * @param $timeStr
     181         * @return false|string
     182        */
     183        public function get_time_in_24_hours($timeStr)
     184        {
     185            $cutOffTime = explode(' ', $timeStr);
     186            $hours = $cutOffTime[0];
     187            $separator = $cutOffTime[1];
     188            $minutes = $cutOffTime[2];
     189            $meridiem = $cutOffTime[3];
     190            $cutOffTime = "{$hours}{$separator}{$minutes} $meridiem";
     191           
     192            return date("H:i", strtotime($cutOffTime));
     193        }
     194
    172195        /**
    173196         * Shipping Logs Section
     
    180203
    181204    $en_tab = new EnFreightviewTab();
    182     return $en_tab->en_load();
     205    $en_tab->en_load();
     206
     207    return $en_tab;
    183208}
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/tab/location/assets/css/en-freightview-location.css

    r3386279 r3450193  
    129129}
    130130
    131 .en_location_error_message {
     131.en_location_error_message,
     132.en_freightview_warehouse_error_message, .en_freightview_dropship_error_message {
    132133    background: #f1f1f1 none repeat scroll 0 0;
    133134    border-left: 4px solid #dc3232;
     
    139140}
    140141
    141 .en_location_success_message {
     142.en_freightview_warehouse_error_message, .en_freightview_dropship_error_message {
     143    background-color: #fff !important;
     144    margin: auto;
     145}
     146
     147.en_location_success_message,
     148.en_freightview_warehouse_success_message, .en_freightview_dropship_success_message{
    142149    background: #fff none repeat scroll 0 0;
    143150    border-left: 4px solid #46b450;
     
    147154    clear: both;
    148155    display: none;
     156}
     157
     158.en_freightview_warehouse_success_message, .en_freightview_dropship_success_message {
     159    margin: auto;
    149160}
    150161
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/tab/location/assets/js/en-freightview-location.js

    r3386279 r3450193  
    449449    }
    450450}
     451
     452if (typeof en_freightview_select_bulk_locations != 'function') {
     453    function en_freightview_select_bulk_locations(location_class, e) {
     454        const checked = jQuery(e).is(':checked');
     455        jQuery(`.${location_class}`).prop('checked', checked);
     456    }
     457}
     458
     459if (typeof en_freightview_toggle_select_all_locations != 'function') {
     460    function en_freightview_toggle_select_all_locations(location_class, select_all_locations) {
     461        const allChecked = jQuery(`.${location_class}:checked`).length === jQuery(`.${location_class}`).length;
     462        jQuery(`#${select_all_locations}`).prop('checked', allChecked);
     463    }
     464}
     465
     466if (typeof en_freightview_delete_bulk_locations != 'function') {
     467    function en_freightview_delete_bulk_locations(e, location_class, location_type) {
     468        e.preventDefault();
     469        const location_ids = jQuery(`.${location_class}:checked`).map(function () {
     470            return this.value;
     471        }).get();
     472
     473        // Show error message if no locations are selected
     474        if (location_ids.length === 0) {
     475            const loc_error_class = `en_freightview_${location_type}_error_message`;
     476            jQuery(`.${loc_error_class}`).show('slow').delay(3000).hide('slow');
     477            return;
     478        }
     479
     480        const postForm = {
     481            'action': 'en_freightview_wd_bulk_delete_locations',
     482            'location_ids': location_ids,
     483            'location_type': location_type,
     484            'wp_nonce': en_freightview_location_script.nonce
     485        }
     486        const delete_locs_btn = `.en_freightview_bulk_delete_${location_type}`,
     487        loc_success_class = `.en_freightview_${location_type}_success_message`,
     488        loc_error_class = `.en_freightview_${location_type}_error_message`;
     489       
     490        jQuery.ajax({
     491            type: 'POST',
     492            url: ajaxurl,
     493            data: postForm,
     494            dataType: 'json',
     495            beforeSend: function () {
     496                jQuery(delete_locs_btn).addClass('spinner_disable');
     497            },
     498            success: function (data) {
     499                if (data.error && data.message) {
     500                    jQuery(delete_locs_btn).removeClass('spinner_disable');
     501                    jQuery(loc_error_class).show('slow').delay(3000).hide('slow');
     502                } else {
     503                    jQuery(delete_locs_btn).removeClass('spinner_disable');
     504                    jQuery(data.target_location).replaceWith(data.html);
     505                    jQuery(loc_success_class).show('slow').delay(3000).hide('slow');
     506                    jQuery('.warehouse_updated, .warehouse_created, .warehouse_deleted, .dropship_deleted, .dropship_updated, .dropship_created').css('display', 'none');
     507                }
     508            },
     509            error: function (error) {
     510                jQuery(delete_locs_btn).removeClass('spinner_disable');
     511                console.log(error);
     512            }
     513        });
     514    }
     515}
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/tab/location/dropship/en-dropship.php

    r3290396 r3450193  
    4141
    4242            <h1><?php _e('Drop ships', 'eniture-technology'); ?></h1>
    43             <button type="button" onclick="en_show_popup_location(false)"
     43            <button type="button" title="Add Drop Ship" onclick="en_show_popup_location(false)"
    4444                    class="button-primary"><?php _e('Add', 'eniture-technology'); ?></button>
     45            <button type="button" class="en_freightview_bulk_delete_dropship en_wd_add_dropship_btn button-primary" title="Delete Drop Ships" onclick="return en_freightview_delete_bulk_locations(event, 'en_freightview_delete_dropship_item', 'dropship');"><?php _e('Delete', 'eniture-technology'); ?></button>
    4546            <p><?php _e('Locations that inventory specific items that are drop shipped to the destination. Use the products settings
    4647                    page to identify it as a drop shipped item and its associated drop ship location. Orders that include drop
    4748                    shipped items will display a single figure for the shipping rate estimate that is equal to the sum of the
    4849                    cheapest option of each shipment required to fulfill the order.', 'eniture-technology'); ?></p>
     50            <div class="en_freightview_dropship_success_message"><strong>Success!</strong> <span>Selected drop ships deleted successfully.</span></div>
     51            <div class="en_freightview_dropship_error_message"><strong>Error!</strong> Please select at least one drop ship to delete.</div>
    4952
    5053            <table class="en_location_table en_location_dropship_table">
    5154            <thead>
    5255            <tr>
     56                 <th class="en_wd_dropship_list_heading en_freightview_bulk_delete_col">
     57                    <!-- Bulk delete -->
     58                    <input type="checkbox" name="en_freightview_bulk_delete_dropships" id="en_freightview_bulk_delete_dropships" onclick="return en_freightview_select_bulk_locations('en_freightview_delete_dropship_item', this);" />
     59                </th>
    5360                <?php echo force_balance_tags( \EnLocation::en_arrange_table_data('th', $en_heading)); ?>
    5461                <th><?php _e('Action', 'eniture-technology'); ?></th>
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/tab/location/en-location.php

    r3386279 r3450193  
    256256
    257257                echo '<tr class="' . esc_attr($append_class) . '" id="en_location_row_id_' . esc_attr($en_location_id) . '">';
     258
     259                $_type = ($loc_type === 'wh') ? 'warehouse' : 'dropship';
     260                echo '<td class="en_wd_' . esc_attr($_type) . '_list_data en_freightview_bulk_delete_col">
     261                    <input
     262                        type="checkbox"
     263                        class="en_freightview_delete_' . esc_attr($_type) . '_item"
     264                        value="' . esc_attr($en_location_id) . '"
     265                        onclick="return en_freightview_toggle_select_all_locations(
     266                            \'en_freightview_delete_' . esc_attr($_type) . '_item\',
     267                            \'en_freightview_bulk_delete_' . esc_attr($_type) . 's\'
     268                        );"
     269                    >
     270                </td>';
    258271                echo self::en_arrange_table_data('td', $en_sorted_location);
    259272
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/tab/location/includes/en-location-ajax.php

    r3386279 r3450193  
    2323            add_action('wp_ajax_nopriv_en_freightview_location_delete_row', [$this, 'en_freightview_location_delete_row']);
    2424            add_action('wp_ajax_en_freightview_location_delete_row', [$this, 'en_freightview_location_delete_row']);
     25
     26            add_action('wp_ajax_nopriv_en_freightview_wd_bulk_delete_locations', array($this, 'en_freightview_bulk_delete_locations_ajax'));
     27            add_action('wp_ajax_en_freightview_wd_bulk_delete_locations', array($this, 'en_freightview_bulk_delete_locations_ajax'));
    2528        }
    2629
     
    251254        }
    252255
     256        function en_freightview_bulk_delete_locations_ajax()
     257        {
     258            if (!(current_user_can('manage_options') || current_user_can('manage_woocommerce')) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['wp_nonce'])), 'en_freightview_location_nonce')) {
     259                echo wp_json_encode(array('error' => true, 'message' => 'Unauthorized Access.'));
     260                exit;
     261            }
     262
     263            $location_ids = isset($_POST['location_ids']) ? $_POST['location_ids'] : array();
     264            $loc_type = isset($_POST['location_type']) ? $_POST['location_type'] : '';
     265            if (empty($location_ids)) {
     266                echo wp_json_encode(['error' => true, 'message' => "Please select at least one {$loc_type} to delete."]);
     267                exit;
     268            }
     269
     270            global $wpdb;
     271            foreach ($location_ids as $location_id) {
     272                if ($loc_type == 'dropship') {
     273                    $get_dropship_id = '';
     274                    $dropship_id = intval($location_id);
     275                    $get_dropship_array = array($dropship_id);
     276                    $ser = maybe_serialize($get_dropship_id);
     277                    $get_dropship_val = array_map('intval', $get_dropship_array);
     278                    $get_post_id = $wpdb->get_results("SELECT group_concat(post_id) as post_ids_list FROM `" . $wpdb->prefix . "postmeta` WHERE `meta_key` = '_dropship_location' AND (`meta_value` LIKE '%" . $ser . "%' OR `meta_value` = '" . $dropship_id . "')");
     279                    $post_id = reset($get_post_id)->post_ids_list;
     280
     281                    if (isset($post_id)) {
     282                        $wpdb->query("UPDATE `" . $wpdb->prefix . "postmeta` SET `meta_value` = '' WHERE `meta_key` IN('_enable_dropship','_dropship_location')  AND `post_id` IN ($post_id)");
     283                    }
     284                }
     285
     286                $wpdb->delete($wpdb->prefix . "warehouse", array('id' => intval($location_id), 'location' => $loc_type));
     287            }
     288
     289            if ($loc_type === 'warehouse') {
     290                $en_location_template_obj = new EnFreightviewWarehouseTemplate();
     291                $en_target_location = '.en_location_warehouse_main_div';
     292            } else {
     293                $en_location_template_obj = new EnFreightviewDropshipTemplate();
     294                $en_target_location = '.en_location_dropship_main_div';
     295            }
     296
     297            $html = $en_location_template_obj::en_load();
     298
     299            echo wp_json_encode(['error' => false, 'message' => 'Locations deleted successfully.', 'target_location' => $en_target_location, 'html' => $html]);
     300            exit;
     301        }
     302
    253303    }
    254304
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/tab/location/warehouse/en-warehouse.php

    r3290396 r3450193  
    3838
    3939                <h1><?php _e('Warehouses', 'eniture-technology'); ?></h1>
    40                 <button type="button" onclick="en_show_popup_location(true)"
    41                         class="button-primary <?php echo esc_attr(self::$disabled_plan); ?>"><?php _e('Add', 'eniture-technology'); ?>
    42                 </button>
    43                 <?php echo force_balance_tags(self::$plan_required); ?>
     40                <div style="display: flex; gap: 3px;">
     41                    <button type="button" title="Add Warehouse" onclick="en_show_popup_location(true)"
     42                            class="button-primary <?php echo esc_attr(self::$disabled_plan); ?>"><?php _e('Add', 'eniture-technology'); ?>
     43                    </button>
     44                    <button type="button" class="en_freightview_bulk_delete_warehouse en_wd_add_warehouse_btn button-primary" title="Delete Warehouses" onclick="return en_freightview_delete_bulk_locations(event, 'en_freightview_delete_warehouse_item', 'warehouse');"><?php _e('Delete', 'eniture-technology'); ?>
     45                    </button>
     46                    <?php echo force_balance_tags(self::$plan_required); ?>
     47                </div>
    4448
    4549                <p><?php _e('Warehouses that inventory all products not otherwise identified as drop shipped items. The warehouse closest to the shopper will be used to retrieve shipping rate estimates.', 'eniture-technology'); ?></p>
     50                <div class="en_freightview_warehouse_success_message"><strong>Success! </strong> <span>Selected warehouses deleted successfully.</span></div>
     51                <div class="en_freightview_warehouse_error_message"><strong>Error!</strong> <span>Please select at least one warehouse to delete.</span></div>
    4652
    4753                <table class="en_location_table en_location_warehouse_table">
    4854                    <thead>
    4955                        <tr>
     56                            <th class="en_wd_warehouse_list_heading en_freightview_bulk_delete_col">
     57                                <!-- Bulk delete -->
     58                                <input type="checkbox" name="en_freightview_bulk_delete_warehouses" id="en_freightview_bulk_delete_warehouses" onclick="return en_freightview_select_bulk_locations('en_freightview_delete_warehouse_item', this);" />
     59                            </th>
    5060                            <?php echo force_balance_tags(\EnLocation::en_arrange_table_data('th', $en_heading)); ?>
    5161                            <th><?php _e('Action', 'eniture-technology'); ?></th>
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/tab/logs/en-json-tree-view/en-jtv-style.css

    r2998669 r3450193  
    9797.en_jtv li.en_folder > div.en_key > span::before {
    9898  content: "\2212";
    99   opacity: 0.33;
    100   color: #111;
    101   background-color: #e0eaef;
     99  opacity: 1;
     100  color: #fff;
     101  background-color: black !important;
    102102  text-align: center;
    103103  display: inline-block;
     
    112112.en_jtv li.en_folder.en_folded > div.en_key > span::before {
    113113  content: "+";
     114  font-weight: bolder;
     115    background-color: black !important;
     116    color: #fff !important;
    114117}
    115118
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/tab/logs/en-logs.php

    r3154428 r3450193  
    4141            $url = FREIGHTVIEW_DOMAIN_HITTING_URL . '/request-log/index.php';
    4242            $obj_classs = new EnFreightviewCurl();
    43             $logs = $obj_classs->en_freightview_sent_http_request($url, $data, 'POST');
     43            $logs = $obj_classs->en_freightview_sent_http_request($url, $data, 'POST', 'Logs');
    4444            $logs = (isset($logs) && is_string($logs) && strlen($logs) > 0) ? json_decode($logs, true) : [];
    4545
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/admin/tab/quote-settings/en-quote-settings.php

    r3386279 r3450193  
    2626                }
    2727            }
     28
     29            if (get_option('en_quote_settings_show_delivery_estimate_freightview') == 'yes') {
     30                update_option('en_quote_settings_delivery_estimate_options_freightview', 'delivery_days');
     31                delete_option('en_quote_settings_show_delivery_estimate_freightview');
     32            }
     33
     34            // Cuttoff Time
     35            $freightview_disable_cutt_off_time_ship_date_offset = "";
     36            $freightview_cutt_off_time_package_required = "";
     37
     38            //  Check the cutt of time & offset days plans for disable input fields
     39            $freightview_action_cutOffTime_shipDateOffset = apply_filters('freightview_plans_suscription_and_features', 'order_cutt_off_time');
     40            if (is_array($freightview_action_cutOffTime_shipDateOffset)) {
     41                $freightview_disable_cutt_off_time_ship_date_offset = "disabled_me";
     42                $freightview_cutt_off_time_package_required = apply_filters('freightview_plans_notification_link', $freightview_action_cutOffTime_shipDateOffset);
     43            }
     44
    2845            $ltl_enable = get_option('en_plugins_return_LTL_quotes');
    2946            $weight_threshold_class = $ltl_enable == 'yes' ? 'show_en_weight_threshold_lfq' : 'hide_en_weight_threshold_lfq';
     
    8198                 * ==================================================================
    8299                 */
    83                 'en_quote_settings_show_delivery_estimate_freightview' => [
    84                     'name' => __('Show Delivery Estimate ', 'woocommerce-settings-freightview'),
    85                     'type' => 'checkbox',
    86                     'id' => 'en_quote_settings_show_delivery_estimate_freightview'
    87                 ],
     100
     101                //** Start Delivery Estimate Options - Cuttoff Time
     102                 'delivery_estimate_options_freightview' => array(
     103                    'name' => __('Delivery Estimate Options ', 'woocommerce-settings-en_woo_addons_packages_quotes'),
     104                    'type' => 'text',
     105                    'class' => 'hidden',
     106                    'id' => 'delivery_estimate_options_freightview'
     107                ),
     108                'en_quote_settings_delivery_estimate_options_freightview' => array(
     109                    'name' => '',
     110                    'type' => 'radio',
     111                    'default' => 'dont_show_estimates',
     112                    'options' => array(
     113                        'dont_show_estimates' => __("Don't display delivery estimates.", 'woocommerce'),
     114                        'delivery_days' => __("Display estimated number of days until delivery.", 'woocommerce'),
     115                        'delivery_date' => __("Display estimated delivery date.", 'woocommerce'),
     116                    ),
     117                    'id' => 'en_quote_settings_delivery_estimate_options_freightview',
     118                    'class' => 'freightview_lfq_dont_show_estimate_option',
     119                ),
     120                //** End Delivery Estimate Options
     121
     122                //**Start: Cut Off Time & Ship Date Offset
     123                'en_quote_settings_cutt_off_time_ship_date_offset_freightview' => array(
     124                    'name' => __('Cut Off Time & Ship Date Offset ', 'woocommerce-settings-en_woo_addons_packages_quotes'),
     125                    'type' => 'text',
     126                    'class' => 'hidden',
     127                    'desc' => $freightview_cutt_off_time_package_required,
     128                    'id' => 'en_quote_settings_cutt_off_time_ship_date_offset_freightview'
     129                ),
     130                'en_quote_settings_order_cut_off_time_freightview' => array(
     131                    'name' => __('Order Cut Off Time ', 'woocommerce-settings-priority-one_lfq_freight_freight_orderCutoffTime'),
     132                    'type' => 'text',
     133                    'placeholder' => '-- : -- --',
     134                    'desc' => 'Enter the cut off time (e.g. 2:00) for the orders. Orders placed after this time will be quoted as shipping the next business day.',
     135                    'id' => 'en_quote_settings_order_cut_off_time_freightview',
     136                    'class' => $freightview_disable_cutt_off_time_ship_date_offset,
     137                ),
     138                'en_quote_settings_shipment_offset_days_freightview' => array(
     139                    'name' => __('Fulfillment Offset Days ', 'woocommerce-settings-priority-one_lfq_freight_shipment_offset_days'),
     140                    'type' => 'text',
     141                    'desc' => 'The number of days the ship date needs to be moved to allow for the processing of the order.',
     142                    'placeholder' => 'Fulfillment Offset Days, e.g. 2',
     143                    'id' => 'en_quote_settings_shipment_offset_days_freightview',
     144                    'class' => $freightview_disable_cutt_off_time_ship_date_offset,
     145                ),
     146                'en_quote_settings_all_shipment_days_freightview' => array(
     147                    'name' => __("What days do you ship orders?", 'woocommerce-settings-priority-one_lfq_quotes'),
     148                    'type' => 'checkbox',
     149                    'desc' => 'Select All',
     150                    'class' => "all_shipment_days_freightview_lfq $freightview_disable_cutt_off_time_ship_date_offset",
     151                    'id' => 'en_quote_settings_all_shipment_days_freightview'
     152                ),
     153                'en_quote_settings_monday_shipment_day_freightview' => array(
     154                    'name' => __("", 'woocommerce-settings-priority-one_lfq_quotes'),
     155                    'type' => 'checkbox',
     156                    'desc' => 'Monday',
     157                    'class' => "freightview_shipment_day $freightview_disable_cutt_off_time_ship_date_offset",
     158                    'id' => 'en_quote_settings_monday_shipment_day_freightview'
     159                ),
     160                'en_quote_settings_tuesday_shipment_day_freightview' => array(
     161                    'name' => __("", 'woocommerce-settings-priority-one_lfq_quotes'),
     162                    'type' => 'checkbox',
     163                    'desc' => 'Tuesday',
     164                    'class' => "freightview_shipment_day $freightview_disable_cutt_off_time_ship_date_offset",
     165                    'id' => 'en_quote_settings_tuesday_shipment_day_freightview'
     166                ),
     167                'en_quote_settings_wednesday_shipment_day_freightview' => array(
     168                    'name' => __("", 'woocommerce-settings-priority-one_lfq_quotes'),
     169                    'type' => 'checkbox',
     170                    'desc' => 'Wednesday',
     171                    'class' => "freightview_shipment_day $freightview_disable_cutt_off_time_ship_date_offset",
     172                    'id' => 'en_quote_settings_wednesday_shipment_day_freightview'
     173                ),
     174                'en_quote_settings_thursday_shipment_day_freightview' => array(
     175                    'name' => __("", 'woocommerce-settings-priority-one_lfq_quotes'),
     176                    'type' => 'checkbox',
     177                    'desc' => 'Thursday',
     178                    'class' => "freightview_shipment_day $freightview_disable_cutt_off_time_ship_date_offset",
     179                    'id' => 'en_quote_settings_thursday_shipment_day_freightview'
     180                ),
     181                'en_quote_settings_friday_shipment_day_freightview' => array(
     182                    'name' => __("", 'woocommerce-settings-priority-one_lfq_quotes'),
     183                    'type' => 'checkbox',
     184                    'desc' => 'Friday',
     185                    'class' => "freightview_shipment_day $freightview_disable_cutt_off_time_ship_date_offset",
     186                    'id' => 'en_quote_settings_friday_shipment_day_freightview'
     187                ),
     188                'en_quote_settings_show_delivery_estimate_freightview' => array(
     189                    'title' => __('', 'woocommerce'),
     190                    'name' => __('', 'woocommerce-settings-priority-one_lfq_quotes'),
     191                    'desc' => '',
     192                    'id' => 'freightview_lfq_show_delivery_estimates',
     193                    'css' => '',
     194                    'default' => '',
     195                    'type' => 'title',
     196                ),
     197                //**End: Cut Off Time & Ship Date Offset
     198
    88199                'residential_delivery_options_label' => [
    89200                    'name' => __('Residential Delivery', 'woocommerce-settings-freightview'),
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/common/en-plans.php

    r3304871 r3450193  
    149149                'multi_warehouse' => ['2', '3'],
    150150                'multi_dropships' => ['0', '1', '2', '3'],
     151                'order_cutt_off_time' => ['2', '3']
    151152            ];
    152153
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/en-install.php

    r3386279 r3450193  
    4040        ]);
    4141
    42         wp_enqueue_script('EnFreightviewAdminJs', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/en-freightview-admin.js', [], '1.0.7');
     42        wp_enqueue_script('EnFreightviewAdminJs', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/en-freightview-admin.js', [], '1.0.8');
    4343        wp_localize_script('EnFreightviewAdminJs', 'en_freightview_admin_script', [
    4444            'pluginsUrl' => EN_FREIGHTVIEW_PLUGIN_URL,
     
    5050            'freightview_backup_rates_cart_price_percentage' => get_option("freightview_backup_rates_cart_price_percentage"),
    5151            'freightview_backup_rates_weight_function' => get_option("freightview_backup_rates_weight_function"),
     52            // Cuttoff Time
     53            'freightview_order_cut_off_time' => get_option("en_quote_settings_order_cut_off_time_freightview"),
    5254        ]);
    5355
    54         wp_enqueue_script('EnFreightviewLocationScript', EN_FREIGHTVIEW_DIR_FILE . '/admin/tab/location/assets/js/en-freightview-location.js', [], '1.0.3');
     56        wp_enqueue_script('EnFreightviewLocationScript', EN_FREIGHTVIEW_DIR_FILE . '/admin/tab/location/assets/js/en-freightview-location.js', [], '1.0.4');
    5557        wp_localize_script('EnFreightviewLocationScript', 'en_freightview_location_script', array(
    5658            'pluginsUrl' => EN_FREIGHTVIEW_PLUGIN_URL,
     
    6365        ));
    6466
    65         wp_register_style('EnFreightviewLocationStyle', EN_FREIGHTVIEW_DIR_FILE . '/admin/tab/location/assets/css/en-freightview-location.css', false, '1.0.1');
     67        wp_register_style('EnFreightviewLocationStyle', EN_FREIGHTVIEW_DIR_FILE . '/admin/tab/location/assets/css/en-freightview-location.css', false, '1.0.2');
    6668        wp_enqueue_style('EnFreightviewLocationStyle');
    6769
    68         wp_register_style('EnFreightviewAdminCss', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/en-freightview-admin.css', false, '1.0.6');
     70        wp_register_style('EnFreightviewAdminCss', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/en-freightview-admin.css', false, '1.0.7');
    6971        wp_enqueue_style('EnFreightviewAdminCss');
    7072
    7173        wp_register_style('EnFreightviewProductCss', EN_FREIGHTVIEW_DIR_FILE . '/admin/product/assets/en-custom-fields-style.css', false, '1.0.0');
    7274        wp_enqueue_style('EnFreightviewProductCss');
     75
     76          // Cuttoff Time
     77        wp_register_style('EnFreightviewWickedPickerStyle', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/wickedpicker.min.css', false, '1.0.0');
     78        wp_register_script('EnFreightviewWickedPickerScript', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/wickedpicker.js', false, '1.0.0');
     79       
     80        wp_enqueue_style('EnFreightviewWickedPickerStyle');
     81        wp_enqueue_script('EnFreightviewWickedPickerScript');
    7382    }
    7483
     
    101110    function en_freightview_shipping_sections($settings)
    102111    {
    103         $settings[] = include('admin/tab/en-tab.php');
     112        $en_tab = include('admin/tab/en-tab.php');
     113        if (is_object($en_tab)) {
     114            $settings[] = $en_tab;
     115        }
     116
    104117        return $settings;
    105118    }
     
    221234    function en_freightview_plan_status($plan_status)
    222235    {
     236        $en_plugin_name = 'LTL Freight Quotes - Freightview Edition';
    223237        $plan_required = '0';
    224         $hazardous_material_status = 'Freightview: Enabled.';
     238        $hazardous_material_status = $en_plugin_name . ': Enabled.';
    225239        $hazardous_material = apply_filters("freightview_plans_suscription_and_features", 'hazardous_material');
    226240        if (is_array($hazardous_material)) {
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/http/en-curl.php

    r3386279 r3450193  
    2626        {
    2727            $curl_response = '';
     28            $en_time_start = 0;
     29
    2830            if (strlen($url) > 0 && is_array($post_data) && !empty($post_data)) {
    2931
    3032                $post_data = self::remove_extra_request_data($post_data);
     33                $cachable_data = self::create_cachable_data($post_data);
     34                $cache_key = self::create_cache_key($cachable_data);
     35                $cache_response = get_transient($cache_key);
     36                $skip_cache = in_array($step_for, ['Plan', 'Logs', 'Address', 'Connection']);
    3137
    32                 // Eniture Execution Time
    33                 $en_time_start = microtime(true);
     38                if (false === $cache_response || $skip_cache) {
     39                    // Eniture Execution Time
     40                    $en_time_start = microtime(true);
    3441
    35                 // Eniture Debug Mood
    36                 do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Request ", $post_data);
     42                    // Eniture Debug Mood
     43                    do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Request ", $post_data);
    3744
    38                 $method == 'POST' ? $post_data = http_build_query($post_data) : '';
     45                    $method == 'POST' ? $post_data = http_build_query($post_data) : '';
    3946
    40                 // Eniture Debug Mood
    41                 do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Build Query ", $post_data);
     47                    // Eniture Debug Mood
     48                    do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Build Query ", $post_data);
    4249
    43                 $response = wp_remote_post($url, [
    44                         'method' => $method,
    45                         'timeout' => 60,
    46                         'redirection' => 5,
    47                         'blocking' => true,
    48                         'body' => $post_data,
    49                     ]
    50                 );
    51                 $curl_response = wp_remote_retrieve_body($response);
    52                 $headers = wp_remote_retrieve_headers($response);
    53                 self::eniture_check_rate_limit_headers($headers);
     50                    $response = wp_remote_post($url, [
     51                            'method' => $method,
     52                            'timeout' => 60,
     53                            'redirection' => 5,
     54                            'blocking' => true,
     55                            'body' => $post_data,
     56                        ]
     57                    );
     58                    $headers = wp_remote_retrieve_headers($response);
     59                    self::eniture_check_rate_limit_headers($headers);   
     60                    $curl_response = wp_remote_retrieve_body($response);
     61                    $resp = !empty($curl_response) && is_string($curl_response) ? json_decode($curl_response, true) : $curl_response;
     62
     63                    if (!empty($resp) && (!isset($resp['severity']) || (isset($resp['severity']) && $resp['severity'] != 'ERROR'))) {
     64                        set_transient($cache_key, $curl_response, 12 * HOUR_IN_SECONDS);
     65                    }
     66
     67                    // Eniture Debug Mode
     68                    do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Response ", json_decode($curl_response));
     69                } else {
     70                    $curl_response = $cache_response;
     71
     72                    // Eniture Debug Mode
     73                    do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Cache Response ", json_decode($curl_response));
     74                }
    5475            }
    55 
    56             // Eniture Debug Mood
    57             do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Response ", json_decode($curl_response));
    5876
    5977            // Eniture Execution Time
     
    99117        }
    100118
     119        static public function create_cachable_data($request_data)
     120        {
     121            $cache_keys = ['serverName', 'platform', 'carrierType', 'carrierName', 'carrierMode', 'requestVersion', 'paymentType', 'apiKey', 'licenseKey', 'shipment_type', 'LTL_FREIGHT', 'product_name', 'shipment_weight', 'commdityDetails', 'originAddress', 'receiverZip', 'receiverState', 'receiverCountryCode', 'receiverCity', 'instorPickupLocalDelEnable', 'accessorials', 'handlingUnitWeight', 'maxWeightPerHandlingUnit', 'shipmentOffsetDays', 'OrderCutoffTime', 'shipmentWeekDays', 'modifyShipmentDateTime'];
     122            $cachable_data = [];
     123           
     124            // get the data from the request
     125            foreach ($cache_keys as $key) {
     126                if (isset($request_data[$key])) $cachable_data[$key] = $request_data[$key];
     127            }
     128
     129            if (isset($request_data['autoResidentials']) && $request_data['autoResidentials'] == 1) {
     130                $cachable_data['autoResidentials'] = $request_data['autoResidentials'];
     131                $cachable_data['addressLine'] = $request_data['addressLine'];
     132                $cachable_data['addressLine2'] = (isset($request_data['addressLine2'])) ? $request_data['addressLine2'] : '';
     133                $cachable_data['defaultRADAddressType'] = $request_data['defaultRADAddressType'];
     134                $cachable_data['defaultRADWithoutStreetAddress'] = $request_data['defaultRADWithoutStreetAddress'];
     135                $cachable_data['poboxAddressValidation'] = $request_data['poboxAddressValidation'];
     136            }
     137
     138            if (isset($request_data['standardPackaging']) && $request_data['standardPackaging'] == 1) {
     139                $cachable_data['standardPackaging'] = $request_data['standardPackaging'];
     140                $cachable_data['pallet'] = $request_data['pallet'];
     141            }
     142
     143            return $cachable_data;
     144        }
     145
     146        static public function create_cache_key($request_data)
     147        {
     148            $request_build_query = http_build_query($request_data);
     149            return md5('eniture_freightview_' . $request_build_query);
     150        }
    101151    }
    102152
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/ltl-freight-quotes-freightview-edition.php

    r3386279 r3450193  
    44 * Plugin URI: https://eniture.com/products/
    55 * Description: Dynamically retrieves your negotiated shipping rates from Freightview and displays the results in the WooCommerce shopping cart.
    6  * Version: 1.0.13
     6 * Version: 1.0.14
    77 * Author: Eniture Technology
    88 * Author URI: http://eniture.com/
    99 * Text Domain: eniture-technology
    10  * License: GPL version 2 or later - http://www.eniture.com/
    11  * WC requires at least: 6.4
    12  * WC tested up to: 9.8.5
     10 * License: GPLv2 or later
     11 * Requires Plugins: woocommerce
    1312 */
    1413
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/readme.txt

    r3386279 r3450193  
    33Tags: eniture,Freightview,,LTL freight rates,LTL freight quotes, shipping estimates
    44Requires at least: 6.4
    5 Tested up to: 6.8
    6 Stable tag: 1.0.13
     5Tested up to: 6.9
     6Stable tag: 1.0.14
    77License: GPLv2 or later
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    147147== Changelog ==
    148148
     149= 1.0.14 - 2026-01-30 =
     150* Update: Added a **caching mechanism** to efficiently handle multiple identical quote requests and reduce redundant API calls.
     151* Update: Added **product-level offset days** functionality to allow more granular shipment timing control.
     152* Update: Introduced **bulk delete functionality** for warehouse and dropship locations to simplify location management.
     153* Update: Updated shipment logic to treat **virtual products** as single-shipment cases instead of multi-shipment cases in both cart and checkout.
     154* Update: Added **delivery estimate options** and **order cutoff time** functionality in the quote settings for improved delivery accuracy.
     155* Update: Added parent product checks to properly handle empty variant scenarios and prevent invalid processing.
     156
    149157= 1.1.13 - 2025-10-29 =
    150158* Update: Added **location-specific Residential and Liftgate Pickup** feature. 
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/server/api/en-response.php

    r3386279 r3450193  
    190190         * @param string $index
    191191         * @param dynamic $is_not_matched
    192          * @return dynamic mixed
     192         * @return dynamic|string|array mixed
    193193         */
    194194        static public function en_sanitize_rate($index, $is_not_matched)
     
    250250            $en_count_rates = 0;
    251251
    252             $handling_fee = $en_settings_label = $rating_method = $transit_days = $enable_carriers = $liftgate_resid_delivery = $liftgate_delivery_option = '';
     252            $handling_fee = $en_settings_label = $rating_method = $transit_days = $delivery_estimate_option = $enable_carriers = $liftgate_resid_delivery = $liftgate_delivery_option = '';
     253            $enable_carriers = [];
    253254            self::$en_settings = json_decode(EN_FREIGHTVIEW_SET_QUOTE_SETTINGS, true);
    254255            self::$en_accessorial = json_decode(EN_FREIGHTVIEW_ACCESSORIAL, true);
     
    303304                if ($service_type && $en_total_net_charge > 0 && in_array($carrier_scac, $enable_carriers)) {
    304305                    $label = isset($is_valid_label) && $is_valid_label ? $en_settings_label : self::en_sanitize_rate('carrierName', '');
    305                     $calculated_transit_days = self::en_sanitize_rate('transitDays', '');
    306                     $transit_time = '';
    307                     if (is_numeric($calculated_transit_days) &&
    308                         self::$en_is_shipment == 'en_single_shipment' &&
    309                         $transit_days == "yes") {
    310                         $transit_time = ' (Intransit days: ' . $calculated_transit_days . ')';
    311                     }
     306                    $calculated_transit_days = self::en_sanitize_rate('totalTransitTimeInDays', '');
     307                    $calculated_transit_date = self::en_sanitize_rate('deliveryTimestamp', '');
     308                    $transit_time = $append_transit = '';
     309
     310                    if ($rating_method != "average_rate" && isset($delivery_estimate_option) && !empty($delivery_estimate_option) && $delivery_estimate_option != 'dont_show_estimates' && self::$en_is_shipment != 'multi_shipment') {
     311
     312                        if ($delivery_estimate_option == 'delivery_date' && is_string($calculated_transit_date) && strlen($calculated_transit_date) > 0) {
     313                            $append_transit = ' (Expected delivery by ' . date('m-d-Y', strtotime($calculated_transit_date)) . ')';
     314                        } else if ($delivery_estimate_option == 'delivery_days' && is_numeric($calculated_transit_days)) {
     315                            $append_transit = ' (Intransit days: ' . $calculated_transit_days . ')';
     316                        }
     317                    }
     318
    312319                    // make data for order widget detail
    313320                    $meta_data['service_type'] = $label;
     
    327334                        'transit_days' => $transit_days,
    328335                        'transit_time' => $transit_time,
     336                        'append_transit' => $append_transit,
    329337                        'plugin_name' => EN_FREIGHTVIEW_SHIPPING_NAME,
    330338                        'plugin_type' => 'ltl',
     
    335343                        $rate['surchargesCost'] = $en_rate['surchargesCost'];
    336344                    }
     345
     346                    // Add pallet fee
     347                    $rate = has_filter('en_pallet_price') ? apply_filters('en_pallet_price', $rate) : $rate;
    337348
    338349                    foreach (self::$en_accessorial as $key => $accessorial) {
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/server/common/en-quote-settings.php

    r3386279 r3450193  
    6161            $quote_settings = [
    6262                'transit_days' => get_option('en_quote_settings_show_delivery_estimate_freightview'),
     63                'delivery_estimate_option' => get_option('en_quote_settings_delivery_estimate_options_freightview'),
    6364                'own_freight' => get_option('en_quote_settings_own_arrangment_freightview'),
    6465                'own_freight_label' => get_option('en_quote_settings_text_for_own_arrangment_freightview'),
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/server/en-shipping-rates.php

    r3386279 r3450193  
    146146
    147147                    $en_package = array_merge(json_decode(EN_FREIGHTVIEW_GET_CONNECTION_SETTINGS, true), $en_package, json_decode(EN_FREIGHTVIEW_GET_QUOTE_SETTINGS, true));
     148                    $en_package = $this->addOrderCutOffTime($en_package);
    148149
    149150                    $response = \EnFreightviewCurl\EnFreightviewCurl::en_freightview_sent_http_request(EN_FREIGHTVIEW_HITTING_API_URL, $en_package, 'POST', 'Quotes');
     
    203204                            }
    204205                            $rate['label'] .= (!empty($label_sufex)) ? ' with ' . implode(' and ', $label_sufex) : '';
    205                             (isset($rate['transit_time']) && strlen($rate['transit_time']) > 0) ? $rate['label'] .= $rate['transit_time'] : '';
     206                            $rate['label'] .= !empty($rate['append_transit']) ? $rate['append_transit'] : '';
    206207                            isset($rate['cost']) && $en_small_package_charges > 0 ?
    207208                                $rate['cost'] = $rate['cost'] + $en_small_package_charges : 0;
     
    308309            }
    309310
     311            function addOrderCutOffTime($en_package)
     312            {
     313                $shipment_week_days = [];
     314                $order_cut_off_time = $shipment_off_set_days = $modify_shipment_date_time = $store_date_time = "";
     315
     316                $delivery_estimates = get_option('en_quote_settings_delivery_estimate_options_freightview');
     317                if ($delivery_estimates == 'delivery_days' || $delivery_estimates == 'delivery_date') {
     318                    $order_cut_off_time = get_option('en_quote_settings_order_cut_off_time_freightview');
     319
     320                    // Use product-level fulfillment offset days if available, otherwise use global setting
     321                    if (isset($en_package['max_fulfillment_offset_days']) && is_numeric($en_package['max_fulfillment_offset_days']) && $en_package['max_fulfillment_offset_days'] > 0) {
     322                        $shipment_off_set_days = $en_package['max_fulfillment_offset_days'];
     323                    } else {
     324                        $shipment_off_set_days = get_option('en_quote_settings_shipment_offset_days_freightview');
     325                    }
     326
     327                    $shipment_week_days = $this->get_shipment_week_days();
     328                    $modify_shipment_date_time = ($order_cut_off_time != '' || $shipment_off_set_days != '' || (is_array($shipment_week_days) && count($shipment_week_days) > 0)) ? 1 : 0;
     329                    $store_date_time = date('Y-m-d H:i:s', current_time('timestamp'));
     330                }
     331
     332                $en_package['OrderCutoffTime'] = $order_cut_off_time;
     333                $en_package['shipmentOffsetDays'] = $shipment_off_set_days;
     334                $en_package['shipmentWeekDays'] = $shipment_week_days;
     335                $en_package['modifyShipmentDateTime'] = $modify_shipment_date_time;
     336                $en_package['storeDateTime'] = $store_date_time;
     337
     338                return $en_package;
     339            }
     340
     341            function get_shipment_week_days()
     342            {
     343                $shipment_days_of_week = ['1', '2', '3', '4', '5'];
     344                if (get_option('en_quote_settings_all_shipment_days_freightview') == 'yes') return $shipment_days_of_week;
     345
     346                $shipment_days_of_week = [];
     347                if (get_option('en_quote_settings_monday_shipment_day_freightview') == 'yes') $shipment_days_of_week[] = 1;
     348                if (get_option('en_quote_settings_tuesday_shipment_day_freightview') == 'yes') $shipment_days_of_week[] = 2;
     349                if (get_option('en_quote_settings_wednesday_shipment_day_freightview') == 'yes') $shipment_days_of_week[] = 3;
     350                if (get_option('en_quote_settings_thursday_shipment_day_freightview') == 'yes') $shipment_days_of_week[] = 4;
     351                if (get_option('en_quote_settings_friday_shipment_day_freightview') == 'yes') $shipment_days_of_week[] = 5;
     352
     353                return $shipment_days_of_week;
     354            }
     355
    310356        }
    311357
  • ltl-freight-quotes-freightview-edition/tags/1.0.14/server/package/en-package.php

    r3386279 r3450193  
    2323    {
    2424        static public $post_id;
     25        static public $parent_id;
    2526        static public $locations;
    2627        static public $product_key_name;
     
    111112                    self::$post_id = (isset($product['variation_id']) && $product['variation_id'] > 0) ?
    112113                        $product['variation_id'] : $product_data->get_id();
    113                     $parent_id = self::$post_id;
     114                    self::$parent_id = $parent_id = self::$post_id;
    114115                    if(isset($product['variation_id']) && $product['variation_id'] > 0){
    115116                        $variation = wc_get_product($product['variation_id']);
    116                         $parent_id = $variation->get_parent_id();
     117                        self::$parent_id = $parent_id = $variation->get_parent_id();
    117118                    }
    118119                    $haz_array = get_post_meta(self::$post_id, '_hazardousmaterials');
    119                     $haz_array[0] == 'yes' ? $haz_status = 'Y' : $haz_status = '';
     120                    if (isset($haz_array[0]) && empty($haz_array[0]) && self::$parent_id != self::$post_id) {
     121                        $haz_array = get_post_meta(self::$parent_id, '_hazardousmaterials');
     122                    }
     123                   
     124                    isset($haz_array[0]) && $haz_array[0] == 'yes' ? $haz_status = 'Y' : $haz_status = '';
    120125
    121126                    $nested_mat = get_post_meta(self::$post_id, '_nestedMaterials');
     127                    if (isset($nested_mat[0]) && empty($nested_mat[0]) && self::$parent_id != self::$post_id) {
     128                        $nested_mat = get_post_meta(self::$parent_id, '_nestedMaterials');
     129                    }
     130                   
    122131                    isset($nested_mat[0]) && $nested_mat[0] == 'yes' ? $doNesting = 1 : $doNesting = '';
    123132
     
    126135
    127136                    $nested_dim = get_post_meta(self::$post_id, '_nestedDimension');
     137                    if (isset($nested_dim[0]) && empty($nested_dim[0]) && self::$parent_id != self::$post_id) {
     138                        $nested_dim = get_post_meta(self::$parent_id, '_nestedDimension');
     139                    }
     140                   
    128141                    $nested_dimension = isset($nested_dim[0]) ? $nested_dim[0] : '';
    129142
    130143                    $max_nested_item = get_post_meta(self::$post_id, '_maxNestedItems');
     144                    if (isset($max_nested_item[0]) && empty($max_nested_item[0]) && self::$parent_id != self::$post_id) {
     145                        $max_nested_item = get_post_meta(self::$parent_id, '_maxNestedItems');
     146                    }
     147
    131148                    !empty($max_nested_item) ? $max_nested_items = $max_nested_item[0] : $max_nested_items = 0;
    132149
    133150                    $nested_staking = get_post_meta(self::$post_id, '_nestedStakingProperty');
    134151                    $nested_staking_property = isset($nested_staking[0]) ? $nested_staking[0] : '';
    135                     $product_title = str_replace(array("'", '"'), '', esc_attr($product_data->get_title()));
     152                    $product_title = str_replace(array("'", '"'), '', esc_attr($product_data->get_name()));
    136153                   
    137154                    // Get product level markup value
    138155                    $product_level_markup = self::en_get_product_level_markup($product_data, $product['variation_id'], $product['product_id'], $product['quantity']);
     156                    $product_level_fulfillment_offset = self::en_get_product_level_fulfillment_offset_days($product_data, $product['variation_id'], $product['product_id']);
    139157
    140158                    $product_item = [
     
    162180                        'productName' => str_replace(array("'", '"'), '', $product_data->get_name()),
    163181                        'variantId' => ($product_data->get_type() == 'variation') ? $product_data->get_id() : '',
    164                         'markup' => $product_level_markup
     182                        'markup' => $product_level_markup,
     183                        'fulfillment_offset_days' => $product_level_fulfillment_offset,
    165184                    ];
    166185
     
    279298
    280299                    if ($shipment_type && strlen($origin_zip_code) > 0) {
    281                         self::$en_request['product_name'][$origin_zip_code][] = $product_quantity . " x " . $product_data->get_title();
     300                        self::$en_request['product_name'][$origin_zip_code][] = $product_quantity . " x " . $product_data->get_name();
    282301
    283302                        self::$en_request['shipment_weight'][$origin_zip_code] = $shipment_weight;
    284303                        self::$en_request['commdityDetails'][$origin_zip_code][self::$post_id] = $product_item;
    285304                        self::$en_request['originAddress'][$origin_zip_code] = $origin_address;
     305
     306                        // Track maximum fulfillment offset days
     307                        if (is_numeric($product_level_fulfillment_offset) && $product_level_fulfillment_offset > 0) {
     308                            if (!isset(self::$en_request['max_fulfillment_offset_days']) || $product_level_fulfillment_offset > self::$en_request['max_fulfillment_offset_days']) {
     309                                self::$en_request['max_fulfillment_offset_days'] = $product_level_fulfillment_offset;
     310                            }
     311                        }
    286312                    }
    287313                }
     
    584610                case '_dropship_location':
    585611                    $enable_dropship = get_post_meta(self::$post_id, '_enable_dropship', true);
     612
     613                    if (empty($enable_dropship) && self::$parent_id > 0 && self::$parent_id != self::$post_id) {
     614                        self::$post_id = self::$parent_id;
     615                        $enable_dropship = get_post_meta(self::$post_id, '_enable_dropship', true);
     616                    }
     617
    586618                    switch ($enable_dropship) {
    587619                        case 'yes':
     
    672704            return $flat_rate_price;
    673705        }
     706
     707        static public function en_get_product_level_fulfillment_offset_days($_product, $variation_id, $product_id)
     708        {
     709            $fulfillment_offset_days = '';
     710            $field_name = '_eniture_product_level_fulfillment_offset_days';
     711
     712            if ($_product->get_type() == 'variation' && $variation_id > 0) {
     713                $fulfillment_offset_days = get_post_meta($variation_id, $field_name, true);
     714
     715                if (empty($fulfillment_offset_days) || !is_numeric($fulfillment_offset_days)) {
     716                    $parent_id = $_product->get_parent_id();
     717                    if ($parent_id > 0) {
     718                        $fulfillment_offset_days = get_post_meta($parent_id, $field_name, true);
     719                    }
     720                }
     721            } else {
     722                $fulfillment_offset_days = get_post_meta($_product->get_id(), $field_name, true);
     723            }
     724
     725            if (empty($fulfillment_offset_days) || !is_numeric($fulfillment_offset_days)) {
     726                $fulfillment_offset_days = get_post_meta($product_id, $field_name, true);
     727            }
     728
     729            // Validate and sanitize the value before returning
     730            if (is_numeric($fulfillment_offset_days)) {
     731                $value = intval($fulfillment_offset_days);
     732                return $value;
     733            }
     734
     735            // Return empty string if invalid
     736            return '';
     737        }
    674738    }
    675739
  • ltl-freight-quotes-freightview-edition/trunk/admin/assets/en-freightview-admin.css

    r3386279 r3450193  
    6060    border-radius: 1px;
    6161    height: 36px !important;
     62}
     63
     64.en_quote_settings_all_shipment_days_freightview_tr td {
     65  display: flex !important;
     66  align-items: center;
     67  gap: 16px;
     68  flex-wrap: nowrap;
    6269}
    6370
     
    337344}
    338345.handling_unit_weight_freightview_tr th,
    339 .maximum_handling_weight_freightview_tr th {
     346.maximum_handling_weight_freightview_tr th,
     347.freightview_cutt_off_time_ship_date_offset th,
     348.en_quote_settings_shipment_offset_days_freightview_tr th,
     349.en_quote_settings_all_shipment_days_freightview_tr th {
    340350    padding: 15px 0 0 10px !important;
    341351    font-weight: 400;
    342352}
    343353.handling_unit_weight_freightview_tr td,
    344 .maximum_handling_weight_freightview_tr td {
     354.maximum_handling_weight_freightview_tr td,
     355.freightview_cutt_off_time_ship_date_offset td,
     356.en_quote_settings_shipment_offset_days_freightview_tr td,
     357.en_quote_settings_all_shipment_days_freightview_tr td {
    345358    padding: 10px 0 10px 10px !important;
    346359}
     
    361374.woocommerce_variable_attributes.wc-metabox-content [class^="_nmfc_number"],
    362375.woocommerce_variable_attributes.wc-metabox-content [class^="_en_product_markup"],
     376.woocommerce_variable_attributes.wc-metabox-content [class^="_eniture_product_level_fulfillment_offset_days"],
    363377.woocommerce_variable_attributes.wc-metabox-content [class^="_nestedPercentage"],
    364378.woocommerce_variable_attributes.wc-metabox-content [class^="en_flat_rate_price"],
     
    384398.woocommerce_variable_attributes.wc-metabox-content [class^="en_flat_rate_price"],
    385399.woocommerce_variable_attributes.wc-metabox-content [class^="_en_product_markup"],
     400.woocommerce_variable_attributes.wc-metabox-content [class^="_eniture_product_level_fulfillment_offset_days"],
    386401.woocommerce_variable_attributes.wc-metabox-content [class^="_nestedPercentage"],
    387402.woocommerce_variable_attributes.wc-metabox-content [class^="_nestedDimension"],
     
    393408.woocommerce_variable_attributes.wc-metabox-content .data p[class*="en_flat_rate_price"] span.woocommerce-help-tip,
    394409.woocommerce_variable_attributes.wc-metabox-content .data p[class*="_en_product_markup"] span.woocommerce-help-tip,
     410.woocommerce_variable_attributes.wc-metabox-content .data p[class*="_eniture_product_level_fulfillment_offset_days"] span.woocommerce-help-tip,
    395411.woocommerce_variable_attributes.wc-metabox-content .data p[class*="_nestedPercentage"] span.woocommerce-help-tip,
    396412.woocommerce_variable_attributes.wc-metabox-content .data p[class*="_nestedDimension"] span.woocommerce-help-tip,
  • ltl-freight-quotes-freightview-edition/trunk/admin/assets/en-freightview-admin.js

    r3386279 r3450193  
    163163                if (!is_data_valid) {
    164164                    en_data_error = false;
    165                     jQuery('.subsubsub').next('.clear').after('<div class="notice notice-error en_settings_message"><p><strong>Error! </strong>' + en_error_msg + '</p></div>');
     165                    const next_elem = (jQuery('.subsubsub').next('.clear'))?.length ? '.clear' : '#en-woo-review-plugin';
     166                    jQuery('.subsubsub').next(next_elem).after('<div class="notice notice-error en_settings_message"><p><strong>Error! </strong>' + en_error_msg + '</p></div>');
    166167                }
    167168            });
     
    173174            }
    174175
     176            // Validate fullfillment offset days
     177            if (!freightviewValidateFullfillmentOffsetDays()) return false;
    175178            // Backup rates validation
    176179            if (!freightviewBackupRatesValidations()) return false;
     
    419422    // Backup rates settings
    420423    freightviewBackupRatesSettings();
     424    // Cut-off time and shipment offset days settings
     425    freightviewCutOffTimeAndShipDateSettings();
    421426});
    422427// Weight threshold for LTL freight
     
    855860    }
    856861}
     862
     863if (typeof freightviewCutOffTimeAndShipDateSettings != 'function') {
     864    function freightviewCutOffTimeAndShipDateSettings() {
     865        jQuery("#en_quote_settings_shipment_offset_days_freightview").closest('tr').addClass("en_quote_settings_shipment_offset_days_freightview_tr");
     866        jQuery("#en_quote_settings_all_shipment_days_freightview").closest('tr').addClass("en_quote_settings_all_shipment_days_freightview_tr");
     867        jQuery(".freightview_shipment_day ").closest('tr').addClass("freightview_shipment_day_tr");
     868        jQuery("#en_quote_settings_order_cut_off_time_freightview").closest('tr').addClass("freightview_cutt_off_time_ship_date_offset");
     869
     870        const freightview_current_time = en_freightview_admin_script.freightview_order_cut_off_time;
     871        if (freightview_current_time == '') {
     872            jQuery('#en_quote_settings_order_cut_off_time_freightview').wickedpicker({
     873                now: '',
     874                title: 'Cut Off Time',
     875            });
     876        } else {
     877            jQuery('#en_quote_settings_order_cut_off_time_freightview').wickedpicker({
     878                now: freightview_current_time,
     879                title: 'Cut Off Time'
     880            });
     881        }
     882
     883        const show_delivery_estimate = jQuery('input[name=en_quote_settings_delivery_estimate_options_freightview]:checked').val();
     884        if (show_delivery_estimate === 'dont_show_estimates') {
     885            jQuery("#en_quote_settings_order_cut_off_time_freightview").prop('disabled', true);
     886            jQuery("#en_quote_settings_shipment_offset_days_freightview").prop('disabled', true);
     887            jQuery("#en_quote_settings_shipment_offset_days_freightview").css("cursor", "not-allowed");
     888            jQuery("#en_quote_settings_order_cut_off_time_freightview").css("cursor", "not-allowed");
     889            jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').prop('disabled', true);
     890            jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').css("cursor", "not-allowed");
     891        } else {
     892            jQuery("#en_quote_settings_order_cut_off_time_freightview").prop('disabled', false);
     893            jQuery("#en_quote_settings_shipment_offset_days_freightview").prop('disabled', false);
     894            jQuery("#en_quote_settings_order_cut_off_time_freightview").css("cursor", "");
     895            jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').prop('disabled', false);
     896            jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').css("cursor", "");
     897        }
     898
     899        jQuery("input[name=en_quote_settings_delivery_estimate_options_freightview]").change(function () {
     900            const show_delivery_estimate = jQuery('input[name=en_quote_settings_delivery_estimate_options_freightview]:checked').val();
     901           
     902            if (show_delivery_estimate === 'dont_show_estimates') {
     903                jQuery("#en_quote_settings_order_cut_off_time_freightview").prop('disabled', true);
     904                jQuery("#en_quote_settings_shipment_offset_days_freightview").prop('disabled', true);
     905                jQuery("#en_quote_settings_order_cut_off_time_freightview").css("cursor", "not-allowed");
     906                jQuery("#en_quote_settings_shipment_offset_days_freightview").css("cursor", "not-allowed");
     907                jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').prop('disabled', true);
     908                jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').css("cursor", "not-allowed");
     909            } else {
     910                jQuery("#en_quote_settings_order_cut_off_time_freightview").prop('disabled', false);
     911                jQuery("#en_quote_settings_shipment_offset_days_freightview").prop('disabled', false);
     912                jQuery("#en_quote_settings_order_cut_off_time_freightview").css("cursor", "auto");
     913                jQuery("#en_quote_settings_shipment_offset_days_freightview").css("cursor", "auto");
     914                jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').prop('disabled', false);
     915                jQuery('.all_shipment_days_freightview_lfq, .freightview_shipment_day').css("cursor", "auto");
     916            }
     917        });
     918
     919        /*
     920        * Uncheck Week days Select All Checkbox
     921        */
     922        jQuery(".freightview_shipment_day").on('change load', function () {
     923
     924            const checkboxes = jQuery('.freightview_shipment_day:checked').length;
     925            const un_checkboxes = jQuery('.freightview_shipment_day').length;
     926
     927            if (checkboxes === un_checkboxes) {
     928                jQuery('.all_shipment_days_freightview_lfq').prop('checked', true);
     929            } else {
     930                jQuery('.all_shipment_days_freightview_lfq').prop('checked', false);
     931            }
     932        });
     933
     934        /*
     935        * Select All Shipment Week days
     936        */
     937
     938        const all_int_checkboxes = jQuery('.all_shipment_days_freightview_lfq');
     939        if (all_int_checkboxes.length === all_int_checkboxes.filter(":checked").length) {
     940            jQuery('.all_shipment_days_freightview_lfq').prop('checked', true);
     941        }
     942
     943        jQuery(".all_shipment_days_freightview_lfq").change(function () {
     944            if (this.checked) {
     945                jQuery(".freightview_shipment_day").each(function () {
     946                    this.checked = true;
     947                });
     948            } else {
     949                jQuery(".freightview_shipment_day").each(function () {
     950                    this.checked = false;
     951                });
     952            }
     953        });
     954
     955        const main_td = jQuery('.en_quote_settings_all_shipment_days_freightview_tr td');
     956        const rows   = jQuery('tr.freightview_shipment_day_tr');
     957
     958        if (!main_td.length || !rows.length) return;
     959
     960        // Move all day checkboxes into main row
     961        rows.each(function () {
     962            const input_wrap = jQuery(this).find('td > *').first();
     963            if (input_wrap.length) main_td.append(input_wrap);
     964        });
     965
     966        // Hide original rows
     967        rows.hide();
     968
     969        // ---- Select All sync ----
     970        const select_all = main_td.find('input[type="checkbox"]').first();
     971        const days = main_td.find('input[type="checkbox"]').not(select_all);
     972
     973        // Select all → days
     974        select_all.on('change', function () {
     975            days.prop('checked', this.checked);
     976        });
     977        // Days → select all
     978        days.on('change', function () {
     979            select_all.prop('checked', days.length === days.filter(':checked').length);
     980        });
     981    }
     982}
     983
     984if (typeof freightviewValidateFullfillmentOffsetDays !== 'function') {
     985    function freightviewValidateFullfillmentOffsetDays() {
     986        const offset_days = jQuery("#en_quote_settings_shipment_offset_days_freightview").val();
     987        const number_regex = /^[0-9]+$/;
     988        let error_msg = '';
     989       
     990        if (offset_days != "" && offset_days < 1) error_msg = 'Fulfillment Offset Days should not be less than 1.';
     991        if (!error_msg && offset_days != "" && offset_days > 20) error_msg = 'Fulfillment Offset Days should not be greater than 20.';
     992        if (!error_msg && offset_days != "" && !number_regex.test(offset_days)) error_msg = 'Fulfillment Offset Days should be a number.';
     993
     994        if (error_msg) {
     995            jQuery('.en_freightview_ltl_plan_notice').after('<div class="notice notice-error en_settings_message"><p><strong>Error! </strong>' + error_msg + '</p></div>');
     996            jQuery('#en_settings_message').delay(200).animate({scrollTop: 0}, 1000);
     997            jQuery('html, body').animate({scrollTop: 0}, 'slow');
     998            return false;
     999        }
     1000
     1001        return true;
     1002    }
     1003}
  • ltl-freight-quotes-freightview-edition/trunk/admin/product/en-product-detail.php

    r3290396 r3450193  
    7777                    $custom_field = (isset($custom_field['id'])) ? $custom_field['id'] : '';
    7878                    $en_updated_product = (isset($_POST[$custom_field][$postId])) ? sanitize_text_field($_POST[$custom_field][$postId]) : '';
    79                     $en_updated_product = $custom_field == '_dropship_location' ?
    80                         (maybe_serialize(is_array($en_updated_product) ? array_map('intval', $en_updated_product) : $en_updated_product)) : esc_attr($en_updated_product);
     79
     80                    if ($custom_field == '_dropship_location') {
     81                        $en_updated_product = maybe_serialize(is_array($en_updated_product) ? array_map('intval', $en_updated_product) : $en_updated_product);
     82                    } elseif ($custom_field == '_eniture_product_level_fulfillment_offset_days') {
     83                        $en_updated_product = $this->sanitize_fulfillment_offset_days($en_updated_product);
     84                    } else {
     85                        $en_updated_product = esc_attr($en_updated_product);
     86                    }
     87
    8188                    update_post_meta($postId, $custom_field, $en_updated_product);
    8289                }
    8390            }
     91        }
     92
     93        private function sanitize_fulfillment_offset_days($value)
     94        {
     95            $value = trim($value);
     96            if ($value === '' || $value === null) return '';
     97
     98            $value = preg_replace('/[^0-9.-]/', '', $value);
     99            if (!is_numeric($value)) return '';
     100
     101            $value = intval(floor(floatval($value)));
     102            return $value < 0 ? '' : strval($value);
    84103        }
    85104
     
    178197                ],
    179198                [
     199                    'type' => 'input_field',
     200                    'input_type' => 'number',
     201                    'id' => '_eniture_product_level_fulfillment_offset_days',
     202                    'class' => '_eniture_product_level_fulfillment_offset_days short',
     203                    'label' => __( 'Fulfillment Offset Days', 'woocommerce' ),
     204                    'placeholder' => 'Fulfillment offset days, e.g. 2',
     205                    'description' => "The number of days the ship date needs to be moved to allow for the processing of the order. If set, this will override the global Fulfillment Offset Days setting for this product.",
     206                    'custom_attributes' => [
     207                        'min' => '1',
     208                        'max' => '20',
     209                        'step' => '1',
     210                        'title' => 'Value must be greater than or equal to 1 and less than or equal to 20',
     211                        'oninvalid' => "this.setCustomValidity(this.validity.rangeUnderflow ? 'Value must be greater than or equal to 1' : this.validity.rangeOverflow ? 'Value must be less than or equal to 20' : '')",
     212                        'oninput' => "this.setCustomValidity('')"
     213                    ]
     214                ],
     215                [
    180216                    'type' => 'checkbox',
    181217                    'id' => '_hazardousmaterials',
     
    292328                'label' => $custom_field['label'],
    293329                'class' => $custom_field['class'],
    294                 'placeholder' => $custom_field['label'],
     330                'placeholder' => isset($custom_field['placeholder']) ? $custom_field['placeholder'] : $custom_field['label'],
    295331                'value' => get_post_meta($postId, $custom_field['id'], true)
    296332            ];
     333
     334            // Add input type if specified (e.g., 'number')
     335            if (isset($custom_field['input_type'])) {
     336                $custom_input_field['type'] = $custom_field['input_type'];
     337            }
     338
     339            // Add custom attributes if specified (e.g., min, max, step)
     340            if (isset($custom_field['custom_attributes'])) {
     341                $custom_input_field['custom_attributes'] = $custom_field['custom_attributes'];
     342            }
    297343
    298344            if (isset($custom_field['description'])) {
  • ltl-freight-quotes-freightview-edition/trunk/admin/tab/en-tab.php

    r3386279 r3450193  
    161161            $settings = $this->get_settings($current_section);
    162162
     163             // Cuttoff Time
     164            if (isset($_POST['en_quote_settings_order_cut_off_time_freightview']) && $_POST['en_quote_settings_order_cut_off_time_freightview'] != '') {
     165                $time_24_format = $this->get_time_in_24_hours($_POST['en_quote_settings_order_cut_off_time_freightview']);
     166                $_POST['en_quote_settings_order_cut_off_time_freightview'] = $time_24_format;
     167            }
     168
    163169            // backup rates
    164170            $backup_rates_fields = ['freightview_backup_rates_fixed_rate', 'freightview_backup_rates_cart_price_percentage', 'freightview_backup_rates_weight_function'];
     
    170176        }
    171177
     178         /**
     179         * Cuttoff Time
     180         * @param $timeStr
     181         * @return false|string
     182        */
     183        public function get_time_in_24_hours($timeStr)
     184        {
     185            $cutOffTime = explode(' ', $timeStr);
     186            $hours = $cutOffTime[0];
     187            $separator = $cutOffTime[1];
     188            $minutes = $cutOffTime[2];
     189            $meridiem = $cutOffTime[3];
     190            $cutOffTime = "{$hours}{$separator}{$minutes} $meridiem";
     191           
     192            return date("H:i", strtotime($cutOffTime));
     193        }
     194
    172195        /**
    173196         * Shipping Logs Section
     
    180203
    181204    $en_tab = new EnFreightviewTab();
    182     return $en_tab->en_load();
     205    $en_tab->en_load();
     206
     207    return $en_tab;
    183208}
  • ltl-freight-quotes-freightview-edition/trunk/admin/tab/location/assets/css/en-freightview-location.css

    r3386279 r3450193  
    129129}
    130130
    131 .en_location_error_message {
     131.en_location_error_message,
     132.en_freightview_warehouse_error_message, .en_freightview_dropship_error_message {
    132133    background: #f1f1f1 none repeat scroll 0 0;
    133134    border-left: 4px solid #dc3232;
     
    139140}
    140141
    141 .en_location_success_message {
     142.en_freightview_warehouse_error_message, .en_freightview_dropship_error_message {
     143    background-color: #fff !important;
     144    margin: auto;
     145}
     146
     147.en_location_success_message,
     148.en_freightview_warehouse_success_message, .en_freightview_dropship_success_message{
    142149    background: #fff none repeat scroll 0 0;
    143150    border-left: 4px solid #46b450;
     
    147154    clear: both;
    148155    display: none;
     156}
     157
     158.en_freightview_warehouse_success_message, .en_freightview_dropship_success_message {
     159    margin: auto;
    149160}
    150161
  • ltl-freight-quotes-freightview-edition/trunk/admin/tab/location/assets/js/en-freightview-location.js

    r3386279 r3450193  
    449449    }
    450450}
     451
     452if (typeof en_freightview_select_bulk_locations != 'function') {
     453    function en_freightview_select_bulk_locations(location_class, e) {
     454        const checked = jQuery(e).is(':checked');
     455        jQuery(`.${location_class}`).prop('checked', checked);
     456    }
     457}
     458
     459if (typeof en_freightview_toggle_select_all_locations != 'function') {
     460    function en_freightview_toggle_select_all_locations(location_class, select_all_locations) {
     461        const allChecked = jQuery(`.${location_class}:checked`).length === jQuery(`.${location_class}`).length;
     462        jQuery(`#${select_all_locations}`).prop('checked', allChecked);
     463    }
     464}
     465
     466if (typeof en_freightview_delete_bulk_locations != 'function') {
     467    function en_freightview_delete_bulk_locations(e, location_class, location_type) {
     468        e.preventDefault();
     469        const location_ids = jQuery(`.${location_class}:checked`).map(function () {
     470            return this.value;
     471        }).get();
     472
     473        // Show error message if no locations are selected
     474        if (location_ids.length === 0) {
     475            const loc_error_class = `en_freightview_${location_type}_error_message`;
     476            jQuery(`.${loc_error_class}`).show('slow').delay(3000).hide('slow');
     477            return;
     478        }
     479
     480        const postForm = {
     481            'action': 'en_freightview_wd_bulk_delete_locations',
     482            'location_ids': location_ids,
     483            'location_type': location_type,
     484            'wp_nonce': en_freightview_location_script.nonce
     485        }
     486        const delete_locs_btn = `.en_freightview_bulk_delete_${location_type}`,
     487        loc_success_class = `.en_freightview_${location_type}_success_message`,
     488        loc_error_class = `.en_freightview_${location_type}_error_message`;
     489       
     490        jQuery.ajax({
     491            type: 'POST',
     492            url: ajaxurl,
     493            data: postForm,
     494            dataType: 'json',
     495            beforeSend: function () {
     496                jQuery(delete_locs_btn).addClass('spinner_disable');
     497            },
     498            success: function (data) {
     499                if (data.error && data.message) {
     500                    jQuery(delete_locs_btn).removeClass('spinner_disable');
     501                    jQuery(loc_error_class).show('slow').delay(3000).hide('slow');
     502                } else {
     503                    jQuery(delete_locs_btn).removeClass('spinner_disable');
     504                    jQuery(data.target_location).replaceWith(data.html);
     505                    jQuery(loc_success_class).show('slow').delay(3000).hide('slow');
     506                    jQuery('.warehouse_updated, .warehouse_created, .warehouse_deleted, .dropship_deleted, .dropship_updated, .dropship_created').css('display', 'none');
     507                }
     508            },
     509            error: function (error) {
     510                jQuery(delete_locs_btn).removeClass('spinner_disable');
     511                console.log(error);
     512            }
     513        });
     514    }
     515}
  • ltl-freight-quotes-freightview-edition/trunk/admin/tab/location/dropship/en-dropship.php

    r3290396 r3450193  
    4141
    4242            <h1><?php _e('Drop ships', 'eniture-technology'); ?></h1>
    43             <button type="button" onclick="en_show_popup_location(false)"
     43            <button type="button" title="Add Drop Ship" onclick="en_show_popup_location(false)"
    4444                    class="button-primary"><?php _e('Add', 'eniture-technology'); ?></button>
     45            <button type="button" class="en_freightview_bulk_delete_dropship en_wd_add_dropship_btn button-primary" title="Delete Drop Ships" onclick="return en_freightview_delete_bulk_locations(event, 'en_freightview_delete_dropship_item', 'dropship');"><?php _e('Delete', 'eniture-technology'); ?></button>
    4546            <p><?php _e('Locations that inventory specific items that are drop shipped to the destination. Use the products settings
    4647                    page to identify it as a drop shipped item and its associated drop ship location. Orders that include drop
    4748                    shipped items will display a single figure for the shipping rate estimate that is equal to the sum of the
    4849                    cheapest option of each shipment required to fulfill the order.', 'eniture-technology'); ?></p>
     50            <div class="en_freightview_dropship_success_message"><strong>Success!</strong> <span>Selected drop ships deleted successfully.</span></div>
     51            <div class="en_freightview_dropship_error_message"><strong>Error!</strong> Please select at least one drop ship to delete.</div>
    4952
    5053            <table class="en_location_table en_location_dropship_table">
    5154            <thead>
    5255            <tr>
     56                 <th class="en_wd_dropship_list_heading en_freightview_bulk_delete_col">
     57                    <!-- Bulk delete -->
     58                    <input type="checkbox" name="en_freightview_bulk_delete_dropships" id="en_freightview_bulk_delete_dropships" onclick="return en_freightview_select_bulk_locations('en_freightview_delete_dropship_item', this);" />
     59                </th>
    5360                <?php echo force_balance_tags( \EnLocation::en_arrange_table_data('th', $en_heading)); ?>
    5461                <th><?php _e('Action', 'eniture-technology'); ?></th>
  • ltl-freight-quotes-freightview-edition/trunk/admin/tab/location/en-location.php

    r3386279 r3450193  
    256256
    257257                echo '<tr class="' . esc_attr($append_class) . '" id="en_location_row_id_' . esc_attr($en_location_id) . '">';
     258
     259                $_type = ($loc_type === 'wh') ? 'warehouse' : 'dropship';
     260                echo '<td class="en_wd_' . esc_attr($_type) . '_list_data en_freightview_bulk_delete_col">
     261                    <input
     262                        type="checkbox"
     263                        class="en_freightview_delete_' . esc_attr($_type) . '_item"
     264                        value="' . esc_attr($en_location_id) . '"
     265                        onclick="return en_freightview_toggle_select_all_locations(
     266                            \'en_freightview_delete_' . esc_attr($_type) . '_item\',
     267                            \'en_freightview_bulk_delete_' . esc_attr($_type) . 's\'
     268                        );"
     269                    >
     270                </td>';
    258271                echo self::en_arrange_table_data('td', $en_sorted_location);
    259272
  • ltl-freight-quotes-freightview-edition/trunk/admin/tab/location/includes/en-location-ajax.php

    r3386279 r3450193  
    2323            add_action('wp_ajax_nopriv_en_freightview_location_delete_row', [$this, 'en_freightview_location_delete_row']);
    2424            add_action('wp_ajax_en_freightview_location_delete_row', [$this, 'en_freightview_location_delete_row']);
     25
     26            add_action('wp_ajax_nopriv_en_freightview_wd_bulk_delete_locations', array($this, 'en_freightview_bulk_delete_locations_ajax'));
     27            add_action('wp_ajax_en_freightview_wd_bulk_delete_locations', array($this, 'en_freightview_bulk_delete_locations_ajax'));
    2528        }
    2629
     
    251254        }
    252255
     256        function en_freightview_bulk_delete_locations_ajax()
     257        {
     258            if (!(current_user_can('manage_options') || current_user_can('manage_woocommerce')) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['wp_nonce'])), 'en_freightview_location_nonce')) {
     259                echo wp_json_encode(array('error' => true, 'message' => 'Unauthorized Access.'));
     260                exit;
     261            }
     262
     263            $location_ids = isset($_POST['location_ids']) ? $_POST['location_ids'] : array();
     264            $loc_type = isset($_POST['location_type']) ? $_POST['location_type'] : '';
     265            if (empty($location_ids)) {
     266                echo wp_json_encode(['error' => true, 'message' => "Please select at least one {$loc_type} to delete."]);
     267                exit;
     268            }
     269
     270            global $wpdb;
     271            foreach ($location_ids as $location_id) {
     272                if ($loc_type == 'dropship') {
     273                    $get_dropship_id = '';
     274                    $dropship_id = intval($location_id);
     275                    $get_dropship_array = array($dropship_id);
     276                    $ser = maybe_serialize($get_dropship_id);
     277                    $get_dropship_val = array_map('intval', $get_dropship_array);
     278                    $get_post_id = $wpdb->get_results("SELECT group_concat(post_id) as post_ids_list FROM `" . $wpdb->prefix . "postmeta` WHERE `meta_key` = '_dropship_location' AND (`meta_value` LIKE '%" . $ser . "%' OR `meta_value` = '" . $dropship_id . "')");
     279                    $post_id = reset($get_post_id)->post_ids_list;
     280
     281                    if (isset($post_id)) {
     282                        $wpdb->query("UPDATE `" . $wpdb->prefix . "postmeta` SET `meta_value` = '' WHERE `meta_key` IN('_enable_dropship','_dropship_location')  AND `post_id` IN ($post_id)");
     283                    }
     284                }
     285
     286                $wpdb->delete($wpdb->prefix . "warehouse", array('id' => intval($location_id), 'location' => $loc_type));
     287            }
     288
     289            if ($loc_type === 'warehouse') {
     290                $en_location_template_obj = new EnFreightviewWarehouseTemplate();
     291                $en_target_location = '.en_location_warehouse_main_div';
     292            } else {
     293                $en_location_template_obj = new EnFreightviewDropshipTemplate();
     294                $en_target_location = '.en_location_dropship_main_div';
     295            }
     296
     297            $html = $en_location_template_obj::en_load();
     298
     299            echo wp_json_encode(['error' => false, 'message' => 'Locations deleted successfully.', 'target_location' => $en_target_location, 'html' => $html]);
     300            exit;
     301        }
     302
    253303    }
    254304
  • ltl-freight-quotes-freightview-edition/trunk/admin/tab/location/warehouse/en-warehouse.php

    r3290396 r3450193  
    3838
    3939                <h1><?php _e('Warehouses', 'eniture-technology'); ?></h1>
    40                 <button type="button" onclick="en_show_popup_location(true)"
    41                         class="button-primary <?php echo esc_attr(self::$disabled_plan); ?>"><?php _e('Add', 'eniture-technology'); ?>
    42                 </button>
    43                 <?php echo force_balance_tags(self::$plan_required); ?>
     40                <div style="display: flex; gap: 3px;">
     41                    <button type="button" title="Add Warehouse" onclick="en_show_popup_location(true)"
     42                            class="button-primary <?php echo esc_attr(self::$disabled_plan); ?>"><?php _e('Add', 'eniture-technology'); ?>
     43                    </button>
     44                    <button type="button" class="en_freightview_bulk_delete_warehouse en_wd_add_warehouse_btn button-primary" title="Delete Warehouses" onclick="return en_freightview_delete_bulk_locations(event, 'en_freightview_delete_warehouse_item', 'warehouse');"><?php _e('Delete', 'eniture-technology'); ?>
     45                    </button>
     46                    <?php echo force_balance_tags(self::$plan_required); ?>
     47                </div>
    4448
    4549                <p><?php _e('Warehouses that inventory all products not otherwise identified as drop shipped items. The warehouse closest to the shopper will be used to retrieve shipping rate estimates.', 'eniture-technology'); ?></p>
     50                <div class="en_freightview_warehouse_success_message"><strong>Success! </strong> <span>Selected warehouses deleted successfully.</span></div>
     51                <div class="en_freightview_warehouse_error_message"><strong>Error!</strong> <span>Please select at least one warehouse to delete.</span></div>
    4652
    4753                <table class="en_location_table en_location_warehouse_table">
    4854                    <thead>
    4955                        <tr>
     56                            <th class="en_wd_warehouse_list_heading en_freightview_bulk_delete_col">
     57                                <!-- Bulk delete -->
     58                                <input type="checkbox" name="en_freightview_bulk_delete_warehouses" id="en_freightview_bulk_delete_warehouses" onclick="return en_freightview_select_bulk_locations('en_freightview_delete_warehouse_item', this);" />
     59                            </th>
    5060                            <?php echo force_balance_tags(\EnLocation::en_arrange_table_data('th', $en_heading)); ?>
    5161                            <th><?php _e('Action', 'eniture-technology'); ?></th>
  • ltl-freight-quotes-freightview-edition/trunk/admin/tab/logs/en-json-tree-view/en-jtv-style.css

    r2998669 r3450193  
    9797.en_jtv li.en_folder > div.en_key > span::before {
    9898  content: "\2212";
    99   opacity: 0.33;
    100   color: #111;
    101   background-color: #e0eaef;
     99  opacity: 1;
     100  color: #fff;
     101  background-color: black !important;
    102102  text-align: center;
    103103  display: inline-block;
     
    112112.en_jtv li.en_folder.en_folded > div.en_key > span::before {
    113113  content: "+";
     114  font-weight: bolder;
     115    background-color: black !important;
     116    color: #fff !important;
    114117}
    115118
  • ltl-freight-quotes-freightview-edition/trunk/admin/tab/logs/en-logs.php

    r3154428 r3450193  
    4141            $url = FREIGHTVIEW_DOMAIN_HITTING_URL . '/request-log/index.php';
    4242            $obj_classs = new EnFreightviewCurl();
    43             $logs = $obj_classs->en_freightview_sent_http_request($url, $data, 'POST');
     43            $logs = $obj_classs->en_freightview_sent_http_request($url, $data, 'POST', 'Logs');
    4444            $logs = (isset($logs) && is_string($logs) && strlen($logs) > 0) ? json_decode($logs, true) : [];
    4545
  • ltl-freight-quotes-freightview-edition/trunk/admin/tab/quote-settings/en-quote-settings.php

    r3386279 r3450193  
    2626                }
    2727            }
     28
     29            if (get_option('en_quote_settings_show_delivery_estimate_freightview') == 'yes') {
     30                update_option('en_quote_settings_delivery_estimate_options_freightview', 'delivery_days');
     31                delete_option('en_quote_settings_show_delivery_estimate_freightview');
     32            }
     33
     34            // Cuttoff Time
     35            $freightview_disable_cutt_off_time_ship_date_offset = "";
     36            $freightview_cutt_off_time_package_required = "";
     37
     38            //  Check the cutt of time & offset days plans for disable input fields
     39            $freightview_action_cutOffTime_shipDateOffset = apply_filters('freightview_plans_suscription_and_features', 'order_cutt_off_time');
     40            if (is_array($freightview_action_cutOffTime_shipDateOffset)) {
     41                $freightview_disable_cutt_off_time_ship_date_offset = "disabled_me";
     42                $freightview_cutt_off_time_package_required = apply_filters('freightview_plans_notification_link', $freightview_action_cutOffTime_shipDateOffset);
     43            }
     44
    2845            $ltl_enable = get_option('en_plugins_return_LTL_quotes');
    2946            $weight_threshold_class = $ltl_enable == 'yes' ? 'show_en_weight_threshold_lfq' : 'hide_en_weight_threshold_lfq';
     
    8198                 * ==================================================================
    8299                 */
    83                 'en_quote_settings_show_delivery_estimate_freightview' => [
    84                     'name' => __('Show Delivery Estimate ', 'woocommerce-settings-freightview'),
    85                     'type' => 'checkbox',
    86                     'id' => 'en_quote_settings_show_delivery_estimate_freightview'
    87                 ],
     100
     101                //** Start Delivery Estimate Options - Cuttoff Time
     102                 'delivery_estimate_options_freightview' => array(
     103                    'name' => __('Delivery Estimate Options ', 'woocommerce-settings-en_woo_addons_packages_quotes'),
     104                    'type' => 'text',
     105                    'class' => 'hidden',
     106                    'id' => 'delivery_estimate_options_freightview'
     107                ),
     108                'en_quote_settings_delivery_estimate_options_freightview' => array(
     109                    'name' => '',
     110                    'type' => 'radio',
     111                    'default' => 'dont_show_estimates',
     112                    'options' => array(
     113                        'dont_show_estimates' => __("Don't display delivery estimates.", 'woocommerce'),
     114                        'delivery_days' => __("Display estimated number of days until delivery.", 'woocommerce'),
     115                        'delivery_date' => __("Display estimated delivery date.", 'woocommerce'),
     116                    ),
     117                    'id' => 'en_quote_settings_delivery_estimate_options_freightview',
     118                    'class' => 'freightview_lfq_dont_show_estimate_option',
     119                ),
     120                //** End Delivery Estimate Options
     121
     122                //**Start: Cut Off Time & Ship Date Offset
     123                'en_quote_settings_cutt_off_time_ship_date_offset_freightview' => array(
     124                    'name' => __('Cut Off Time & Ship Date Offset ', 'woocommerce-settings-en_woo_addons_packages_quotes'),
     125                    'type' => 'text',
     126                    'class' => 'hidden',
     127                    'desc' => $freightview_cutt_off_time_package_required,
     128                    'id' => 'en_quote_settings_cutt_off_time_ship_date_offset_freightview'
     129                ),
     130                'en_quote_settings_order_cut_off_time_freightview' => array(
     131                    'name' => __('Order Cut Off Time ', 'woocommerce-settings-priority-one_lfq_freight_freight_orderCutoffTime'),
     132                    'type' => 'text',
     133                    'placeholder' => '-- : -- --',
     134                    'desc' => 'Enter the cut off time (e.g. 2:00) for the orders. Orders placed after this time will be quoted as shipping the next business day.',
     135                    'id' => 'en_quote_settings_order_cut_off_time_freightview',
     136                    'class' => $freightview_disable_cutt_off_time_ship_date_offset,
     137                ),
     138                'en_quote_settings_shipment_offset_days_freightview' => array(
     139                    'name' => __('Fulfillment Offset Days ', 'woocommerce-settings-priority-one_lfq_freight_shipment_offset_days'),
     140                    'type' => 'text',
     141                    'desc' => 'The number of days the ship date needs to be moved to allow for the processing of the order.',
     142                    'placeholder' => 'Fulfillment Offset Days, e.g. 2',
     143                    'id' => 'en_quote_settings_shipment_offset_days_freightview',
     144                    'class' => $freightview_disable_cutt_off_time_ship_date_offset,
     145                ),
     146                'en_quote_settings_all_shipment_days_freightview' => array(
     147                    'name' => __("What days do you ship orders?", 'woocommerce-settings-priority-one_lfq_quotes'),
     148                    'type' => 'checkbox',
     149                    'desc' => 'Select All',
     150                    'class' => "all_shipment_days_freightview_lfq $freightview_disable_cutt_off_time_ship_date_offset",
     151                    'id' => 'en_quote_settings_all_shipment_days_freightview'
     152                ),
     153                'en_quote_settings_monday_shipment_day_freightview' => array(
     154                    'name' => __("", 'woocommerce-settings-priority-one_lfq_quotes'),
     155                    'type' => 'checkbox',
     156                    'desc' => 'Monday',
     157                    'class' => "freightview_shipment_day $freightview_disable_cutt_off_time_ship_date_offset",
     158                    'id' => 'en_quote_settings_monday_shipment_day_freightview'
     159                ),
     160                'en_quote_settings_tuesday_shipment_day_freightview' => array(
     161                    'name' => __("", 'woocommerce-settings-priority-one_lfq_quotes'),
     162                    'type' => 'checkbox',
     163                    'desc' => 'Tuesday',
     164                    'class' => "freightview_shipment_day $freightview_disable_cutt_off_time_ship_date_offset",
     165                    'id' => 'en_quote_settings_tuesday_shipment_day_freightview'
     166                ),
     167                'en_quote_settings_wednesday_shipment_day_freightview' => array(
     168                    'name' => __("", 'woocommerce-settings-priority-one_lfq_quotes'),
     169                    'type' => 'checkbox',
     170                    'desc' => 'Wednesday',
     171                    'class' => "freightview_shipment_day $freightview_disable_cutt_off_time_ship_date_offset",
     172                    'id' => 'en_quote_settings_wednesday_shipment_day_freightview'
     173                ),
     174                'en_quote_settings_thursday_shipment_day_freightview' => array(
     175                    'name' => __("", 'woocommerce-settings-priority-one_lfq_quotes'),
     176                    'type' => 'checkbox',
     177                    'desc' => 'Thursday',
     178                    'class' => "freightview_shipment_day $freightview_disable_cutt_off_time_ship_date_offset",
     179                    'id' => 'en_quote_settings_thursday_shipment_day_freightview'
     180                ),
     181                'en_quote_settings_friday_shipment_day_freightview' => array(
     182                    'name' => __("", 'woocommerce-settings-priority-one_lfq_quotes'),
     183                    'type' => 'checkbox',
     184                    'desc' => 'Friday',
     185                    'class' => "freightview_shipment_day $freightview_disable_cutt_off_time_ship_date_offset",
     186                    'id' => 'en_quote_settings_friday_shipment_day_freightview'
     187                ),
     188                'en_quote_settings_show_delivery_estimate_freightview' => array(
     189                    'title' => __('', 'woocommerce'),
     190                    'name' => __('', 'woocommerce-settings-priority-one_lfq_quotes'),
     191                    'desc' => '',
     192                    'id' => 'freightview_lfq_show_delivery_estimates',
     193                    'css' => '',
     194                    'default' => '',
     195                    'type' => 'title',
     196                ),
     197                //**End: Cut Off Time & Ship Date Offset
     198
    88199                'residential_delivery_options_label' => [
    89200                    'name' => __('Residential Delivery', 'woocommerce-settings-freightview'),
  • ltl-freight-quotes-freightview-edition/trunk/common/en-plans.php

    r3304871 r3450193  
    149149                'multi_warehouse' => ['2', '3'],
    150150                'multi_dropships' => ['0', '1', '2', '3'],
     151                'order_cutt_off_time' => ['2', '3']
    151152            ];
    152153
  • ltl-freight-quotes-freightview-edition/trunk/en-install.php

    r3386279 r3450193  
    4040        ]);
    4141
    42         wp_enqueue_script('EnFreightviewAdminJs', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/en-freightview-admin.js', [], '1.0.7');
     42        wp_enqueue_script('EnFreightviewAdminJs', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/en-freightview-admin.js', [], '1.0.8');
    4343        wp_localize_script('EnFreightviewAdminJs', 'en_freightview_admin_script', [
    4444            'pluginsUrl' => EN_FREIGHTVIEW_PLUGIN_URL,
     
    5050            'freightview_backup_rates_cart_price_percentage' => get_option("freightview_backup_rates_cart_price_percentage"),
    5151            'freightview_backup_rates_weight_function' => get_option("freightview_backup_rates_weight_function"),
     52            // Cuttoff Time
     53            'freightview_order_cut_off_time' => get_option("en_quote_settings_order_cut_off_time_freightview"),
    5254        ]);
    5355
    54         wp_enqueue_script('EnFreightviewLocationScript', EN_FREIGHTVIEW_DIR_FILE . '/admin/tab/location/assets/js/en-freightview-location.js', [], '1.0.3');
     56        wp_enqueue_script('EnFreightviewLocationScript', EN_FREIGHTVIEW_DIR_FILE . '/admin/tab/location/assets/js/en-freightview-location.js', [], '1.0.4');
    5557        wp_localize_script('EnFreightviewLocationScript', 'en_freightview_location_script', array(
    5658            'pluginsUrl' => EN_FREIGHTVIEW_PLUGIN_URL,
     
    6365        ));
    6466
    65         wp_register_style('EnFreightviewLocationStyle', EN_FREIGHTVIEW_DIR_FILE . '/admin/tab/location/assets/css/en-freightview-location.css', false, '1.0.1');
     67        wp_register_style('EnFreightviewLocationStyle', EN_FREIGHTVIEW_DIR_FILE . '/admin/tab/location/assets/css/en-freightview-location.css', false, '1.0.2');
    6668        wp_enqueue_style('EnFreightviewLocationStyle');
    6769
    68         wp_register_style('EnFreightviewAdminCss', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/en-freightview-admin.css', false, '1.0.6');
     70        wp_register_style('EnFreightviewAdminCss', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/en-freightview-admin.css', false, '1.0.7');
    6971        wp_enqueue_style('EnFreightviewAdminCss');
    7072
    7173        wp_register_style('EnFreightviewProductCss', EN_FREIGHTVIEW_DIR_FILE . '/admin/product/assets/en-custom-fields-style.css', false, '1.0.0');
    7274        wp_enqueue_style('EnFreightviewProductCss');
     75
     76          // Cuttoff Time
     77        wp_register_style('EnFreightviewWickedPickerStyle', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/wickedpicker.min.css', false, '1.0.0');
     78        wp_register_script('EnFreightviewWickedPickerScript', EN_FREIGHTVIEW_DIR_FILE . '/admin/assets/wickedpicker.js', false, '1.0.0');
     79       
     80        wp_enqueue_style('EnFreightviewWickedPickerStyle');
     81        wp_enqueue_script('EnFreightviewWickedPickerScript');
    7382    }
    7483
     
    101110    function en_freightview_shipping_sections($settings)
    102111    {
    103         $settings[] = include('admin/tab/en-tab.php');
     112        $en_tab = include('admin/tab/en-tab.php');
     113        if (is_object($en_tab)) {
     114            $settings[] = $en_tab;
     115        }
     116
    104117        return $settings;
    105118    }
     
    221234    function en_freightview_plan_status($plan_status)
    222235    {
     236        $en_plugin_name = 'LTL Freight Quotes - Freightview Edition';
    223237        $plan_required = '0';
    224         $hazardous_material_status = 'Freightview: Enabled.';
     238        $hazardous_material_status = $en_plugin_name . ': Enabled.';
    225239        $hazardous_material = apply_filters("freightview_plans_suscription_and_features", 'hazardous_material');
    226240        if (is_array($hazardous_material)) {
  • ltl-freight-quotes-freightview-edition/trunk/http/en-curl.php

    r3386279 r3450193  
    2626        {
    2727            $curl_response = '';
     28            $en_time_start = 0;
     29
    2830            if (strlen($url) > 0 && is_array($post_data) && !empty($post_data)) {
    2931
    3032                $post_data = self::remove_extra_request_data($post_data);
     33                $cachable_data = self::create_cachable_data($post_data);
     34                $cache_key = self::create_cache_key($cachable_data);
     35                $cache_response = get_transient($cache_key);
     36                $skip_cache = in_array($step_for, ['Plan', 'Logs', 'Address', 'Connection']);
    3137
    32                 // Eniture Execution Time
    33                 $en_time_start = microtime(true);
     38                if (false === $cache_response || $skip_cache) {
     39                    // Eniture Execution Time
     40                    $en_time_start = microtime(true);
    3441
    35                 // Eniture Debug Mood
    36                 do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Request ", $post_data);
     42                    // Eniture Debug Mood
     43                    do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Request ", $post_data);
    3744
    38                 $method == 'POST' ? $post_data = http_build_query($post_data) : '';
     45                    $method == 'POST' ? $post_data = http_build_query($post_data) : '';
    3946
    40                 // Eniture Debug Mood
    41                 do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Build Query ", $post_data);
     47                    // Eniture Debug Mood
     48                    do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Build Query ", $post_data);
    4249
    43                 $response = wp_remote_post($url, [
    44                         'method' => $method,
    45                         'timeout' => 60,
    46                         'redirection' => 5,
    47                         'blocking' => true,
    48                         'body' => $post_data,
    49                     ]
    50                 );
    51                 $curl_response = wp_remote_retrieve_body($response);
    52                 $headers = wp_remote_retrieve_headers($response);
    53                 self::eniture_check_rate_limit_headers($headers);
     50                    $response = wp_remote_post($url, [
     51                            'method' => $method,
     52                            'timeout' => 60,
     53                            'redirection' => 5,
     54                            'blocking' => true,
     55                            'body' => $post_data,
     56                        ]
     57                    );
     58                    $headers = wp_remote_retrieve_headers($response);
     59                    self::eniture_check_rate_limit_headers($headers);   
     60                    $curl_response = wp_remote_retrieve_body($response);
     61                    $resp = !empty($curl_response) && is_string($curl_response) ? json_decode($curl_response, true) : $curl_response;
     62
     63                    if (!empty($resp) && (!isset($resp['severity']) || (isset($resp['severity']) && $resp['severity'] != 'ERROR'))) {
     64                        set_transient($cache_key, $curl_response, 12 * HOUR_IN_SECONDS);
     65                    }
     66
     67                    // Eniture Debug Mode
     68                    do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Response ", json_decode($curl_response));
     69                } else {
     70                    $curl_response = $cache_response;
     71
     72                    // Eniture Debug Mode
     73                    do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Cache Response ", json_decode($curl_response));
     74                }
    5475            }
    55 
    56             // Eniture Debug Mood
    57             do_action("eniture_debug_mood", EN_FREIGHTVIEW_NAME . " $step_for Response ", json_decode($curl_response));
    5876
    5977            // Eniture Execution Time
     
    99117        }
    100118
     119        static public function create_cachable_data($request_data)
     120        {
     121            $cache_keys = ['serverName', 'platform', 'carrierType', 'carrierName', 'carrierMode', 'requestVersion', 'paymentType', 'apiKey', 'licenseKey', 'shipment_type', 'LTL_FREIGHT', 'product_name', 'shipment_weight', 'commdityDetails', 'originAddress', 'receiverZip', 'receiverState', 'receiverCountryCode', 'receiverCity', 'instorPickupLocalDelEnable', 'accessorials', 'handlingUnitWeight', 'maxWeightPerHandlingUnit', 'shipmentOffsetDays', 'OrderCutoffTime', 'shipmentWeekDays', 'modifyShipmentDateTime'];
     122            $cachable_data = [];
     123           
     124            // get the data from the request
     125            foreach ($cache_keys as $key) {
     126                if (isset($request_data[$key])) $cachable_data[$key] = $request_data[$key];
     127            }
     128
     129            if (isset($request_data['autoResidentials']) && $request_data['autoResidentials'] == 1) {
     130                $cachable_data['autoResidentials'] = $request_data['autoResidentials'];
     131                $cachable_data['addressLine'] = $request_data['addressLine'];
     132                $cachable_data['addressLine2'] = (isset($request_data['addressLine2'])) ? $request_data['addressLine2'] : '';
     133                $cachable_data['defaultRADAddressType'] = $request_data['defaultRADAddressType'];
     134                $cachable_data['defaultRADWithoutStreetAddress'] = $request_data['defaultRADWithoutStreetAddress'];
     135                $cachable_data['poboxAddressValidation'] = $request_data['poboxAddressValidation'];
     136            }
     137
     138            if (isset($request_data['standardPackaging']) && $request_data['standardPackaging'] == 1) {
     139                $cachable_data['standardPackaging'] = $request_data['standardPackaging'];
     140                $cachable_data['pallet'] = $request_data['pallet'];
     141            }
     142
     143            return $cachable_data;
     144        }
     145
     146        static public function create_cache_key($request_data)
     147        {
     148            $request_build_query = http_build_query($request_data);
     149            return md5('eniture_freightview_' . $request_build_query);
     150        }
    101151    }
    102152
  • ltl-freight-quotes-freightview-edition/trunk/ltl-freight-quotes-freightview-edition.php

    r3386279 r3450193  
    44 * Plugin URI: https://eniture.com/products/
    55 * Description: Dynamically retrieves your negotiated shipping rates from Freightview and displays the results in the WooCommerce shopping cart.
    6  * Version: 1.0.13
     6 * Version: 1.0.14
    77 * Author: Eniture Technology
    88 * Author URI: http://eniture.com/
    99 * Text Domain: eniture-technology
    10  * License: GPL version 2 or later - http://www.eniture.com/
    11  * WC requires at least: 6.4
    12  * WC tested up to: 9.8.5
     10 * License: GPLv2 or later
     11 * Requires Plugins: woocommerce
    1312 */
    1413
  • ltl-freight-quotes-freightview-edition/trunk/readme.txt

    r3386279 r3450193  
    33Tags: eniture,Freightview,,LTL freight rates,LTL freight quotes, shipping estimates
    44Requires at least: 6.4
    5 Tested up to: 6.8
    6 Stable tag: 1.0.13
     5Tested up to: 6.9
     6Stable tag: 1.0.14
    77License: GPLv2 or later
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    147147== Changelog ==
    148148
     149= 1.0.14 - 2026-01-30 =
     150* Update: Added a **caching mechanism** to efficiently handle multiple identical quote requests and reduce redundant API calls.
     151* Update: Added **product-level offset days** functionality to allow more granular shipment timing control.
     152* Update: Introduced **bulk delete functionality** for warehouse and dropship locations to simplify location management.
     153* Update: Updated shipment logic to treat **virtual products** as single-shipment cases instead of multi-shipment cases in both cart and checkout.
     154* Update: Added **delivery estimate options** and **order cutoff time** functionality in the quote settings for improved delivery accuracy.
     155* Update: Added parent product checks to properly handle empty variant scenarios and prevent invalid processing.
     156
    149157= 1.1.13 - 2025-10-29 =
    150158* Update: Added **location-specific Residential and Liftgate Pickup** feature. 
  • ltl-freight-quotes-freightview-edition/trunk/server/api/en-response.php

    r3386279 r3450193  
    190190         * @param string $index
    191191         * @param dynamic $is_not_matched
    192          * @return dynamic mixed
     192         * @return dynamic|string|array mixed
    193193         */
    194194        static public function en_sanitize_rate($index, $is_not_matched)
     
    250250            $en_count_rates = 0;
    251251
    252             $handling_fee = $en_settings_label = $rating_method = $transit_days = $enable_carriers = $liftgate_resid_delivery = $liftgate_delivery_option = '';
     252            $handling_fee = $en_settings_label = $rating_method = $transit_days = $delivery_estimate_option = $enable_carriers = $liftgate_resid_delivery = $liftgate_delivery_option = '';
     253            $enable_carriers = [];
    253254            self::$en_settings = json_decode(EN_FREIGHTVIEW_SET_QUOTE_SETTINGS, true);
    254255            self::$en_accessorial = json_decode(EN_FREIGHTVIEW_ACCESSORIAL, true);
     
    303304                if ($service_type && $en_total_net_charge > 0 && in_array($carrier_scac, $enable_carriers)) {
    304305                    $label = isset($is_valid_label) && $is_valid_label ? $en_settings_label : self::en_sanitize_rate('carrierName', '');
    305                     $calculated_transit_days = self::en_sanitize_rate('transitDays', '');
    306                     $transit_time = '';
    307                     if (is_numeric($calculated_transit_days) &&
    308                         self::$en_is_shipment == 'en_single_shipment' &&
    309                         $transit_days == "yes") {
    310                         $transit_time = ' (Intransit days: ' . $calculated_transit_days . ')';
    311                     }
     306                    $calculated_transit_days = self::en_sanitize_rate('totalTransitTimeInDays', '');
     307                    $calculated_transit_date = self::en_sanitize_rate('deliveryTimestamp', '');
     308                    $transit_time = $append_transit = '';
     309
     310                    if ($rating_method != "average_rate" && isset($delivery_estimate_option) && !empty($delivery_estimate_option) && $delivery_estimate_option != 'dont_show_estimates' && self::$en_is_shipment != 'multi_shipment') {
     311
     312                        if ($delivery_estimate_option == 'delivery_date' && is_string($calculated_transit_date) && strlen($calculated_transit_date) > 0) {
     313                            $append_transit = ' (Expected delivery by ' . date('m-d-Y', strtotime($calculated_transit_date)) . ')';
     314                        } else if ($delivery_estimate_option == 'delivery_days' && is_numeric($calculated_transit_days)) {
     315                            $append_transit = ' (Intransit days: ' . $calculated_transit_days . ')';
     316                        }
     317                    }
     318
    312319                    // make data for order widget detail
    313320                    $meta_data['service_type'] = $label;
     
    327334                        'transit_days' => $transit_days,
    328335                        'transit_time' => $transit_time,
     336                        'append_transit' => $append_transit,
    329337                        'plugin_name' => EN_FREIGHTVIEW_SHIPPING_NAME,
    330338                        'plugin_type' => 'ltl',
     
    335343                        $rate['surchargesCost'] = $en_rate['surchargesCost'];
    336344                    }
     345
     346                    // Add pallet fee
     347                    $rate = has_filter('en_pallet_price') ? apply_filters('en_pallet_price', $rate) : $rate;
    337348
    338349                    foreach (self::$en_accessorial as $key => $accessorial) {
  • ltl-freight-quotes-freightview-edition/trunk/server/common/en-quote-settings.php

    r3386279 r3450193  
    6161            $quote_settings = [
    6262                'transit_days' => get_option('en_quote_settings_show_delivery_estimate_freightview'),
     63                'delivery_estimate_option' => get_option('en_quote_settings_delivery_estimate_options_freightview'),
    6364                'own_freight' => get_option('en_quote_settings_own_arrangment_freightview'),
    6465                'own_freight_label' => get_option('en_quote_settings_text_for_own_arrangment_freightview'),
  • ltl-freight-quotes-freightview-edition/trunk/server/en-shipping-rates.php

    r3386279 r3450193  
    146146
    147147                    $en_package = array_merge(json_decode(EN_FREIGHTVIEW_GET_CONNECTION_SETTINGS, true), $en_package, json_decode(EN_FREIGHTVIEW_GET_QUOTE_SETTINGS, true));
     148                    $en_package = $this->addOrderCutOffTime($en_package);
    148149
    149150                    $response = \EnFreightviewCurl\EnFreightviewCurl::en_freightview_sent_http_request(EN_FREIGHTVIEW_HITTING_API_URL, $en_package, 'POST', 'Quotes');
     
    203204                            }
    204205                            $rate['label'] .= (!empty($label_sufex)) ? ' with ' . implode(' and ', $label_sufex) : '';
    205                             (isset($rate['transit_time']) && strlen($rate['transit_time']) > 0) ? $rate['label'] .= $rate['transit_time'] : '';
     206                            $rate['label'] .= !empty($rate['append_transit']) ? $rate['append_transit'] : '';
    206207                            isset($rate['cost']) && $en_small_package_charges > 0 ?
    207208                                $rate['cost'] = $rate['cost'] + $en_small_package_charges : 0;
     
    308309            }
    309310
     311            function addOrderCutOffTime($en_package)
     312            {
     313                $shipment_week_days = [];
     314                $order_cut_off_time = $shipment_off_set_days = $modify_shipment_date_time = $store_date_time = "";
     315
     316                $delivery_estimates = get_option('en_quote_settings_delivery_estimate_options_freightview');
     317                if ($delivery_estimates == 'delivery_days' || $delivery_estimates == 'delivery_date') {
     318                    $order_cut_off_time = get_option('en_quote_settings_order_cut_off_time_freightview');
     319
     320                    // Use product-level fulfillment offset days if available, otherwise use global setting
     321                    if (isset($en_package['max_fulfillment_offset_days']) && is_numeric($en_package['max_fulfillment_offset_days']) && $en_package['max_fulfillment_offset_days'] > 0) {
     322                        $shipment_off_set_days = $en_package['max_fulfillment_offset_days'];
     323                    } else {
     324                        $shipment_off_set_days = get_option('en_quote_settings_shipment_offset_days_freightview');
     325                    }
     326
     327                    $shipment_week_days = $this->get_shipment_week_days();
     328                    $modify_shipment_date_time = ($order_cut_off_time != '' || $shipment_off_set_days != '' || (is_array($shipment_week_days) && count($shipment_week_days) > 0)) ? 1 : 0;
     329                    $store_date_time = date('Y-m-d H:i:s', current_time('timestamp'));
     330                }
     331
     332                $en_package['OrderCutoffTime'] = $order_cut_off_time;
     333                $en_package['shipmentOffsetDays'] = $shipment_off_set_days;
     334                $en_package['shipmentWeekDays'] = $shipment_week_days;
     335                $en_package['modifyShipmentDateTime'] = $modify_shipment_date_time;
     336                $en_package['storeDateTime'] = $store_date_time;
     337
     338                return $en_package;
     339            }
     340
     341            function get_shipment_week_days()
     342            {
     343                $shipment_days_of_week = ['1', '2', '3', '4', '5'];
     344                if (get_option('en_quote_settings_all_shipment_days_freightview') == 'yes') return $shipment_days_of_week;
     345
     346                $shipment_days_of_week = [];
     347                if (get_option('en_quote_settings_monday_shipment_day_freightview') == 'yes') $shipment_days_of_week[] = 1;
     348                if (get_option('en_quote_settings_tuesday_shipment_day_freightview') == 'yes') $shipment_days_of_week[] = 2;
     349                if (get_option('en_quote_settings_wednesday_shipment_day_freightview') == 'yes') $shipment_days_of_week[] = 3;
     350                if (get_option('en_quote_settings_thursday_shipment_day_freightview') == 'yes') $shipment_days_of_week[] = 4;
     351                if (get_option('en_quote_settings_friday_shipment_day_freightview') == 'yes') $shipment_days_of_week[] = 5;
     352
     353                return $shipment_days_of_week;
     354            }
     355
    310356        }
    311357
  • ltl-freight-quotes-freightview-edition/trunk/server/package/en-package.php

    r3386279 r3450193  
    2323    {
    2424        static public $post_id;
     25        static public $parent_id;
    2526        static public $locations;
    2627        static public $product_key_name;
     
    111112                    self::$post_id = (isset($product['variation_id']) && $product['variation_id'] > 0) ?
    112113                        $product['variation_id'] : $product_data->get_id();
    113                     $parent_id = self::$post_id;
     114                    self::$parent_id = $parent_id = self::$post_id;
    114115                    if(isset($product['variation_id']) && $product['variation_id'] > 0){
    115116                        $variation = wc_get_product($product['variation_id']);
    116                         $parent_id = $variation->get_parent_id();
     117                        self::$parent_id = $parent_id = $variation->get_parent_id();
    117118                    }
    118119                    $haz_array = get_post_meta(self::$post_id, '_hazardousmaterials');
    119                     $haz_array[0] == 'yes' ? $haz_status = 'Y' : $haz_status = '';
     120                    if (isset($haz_array[0]) && empty($haz_array[0]) && self::$parent_id != self::$post_id) {
     121                        $haz_array = get_post_meta(self::$parent_id, '_hazardousmaterials');
     122                    }
     123                   
     124                    isset($haz_array[0]) && $haz_array[0] == 'yes' ? $haz_status = 'Y' : $haz_status = '';
    120125
    121126                    $nested_mat = get_post_meta(self::$post_id, '_nestedMaterials');
     127                    if (isset($nested_mat[0]) && empty($nested_mat[0]) && self::$parent_id != self::$post_id) {
     128                        $nested_mat = get_post_meta(self::$parent_id, '_nestedMaterials');
     129                    }
     130                   
    122131                    isset($nested_mat[0]) && $nested_mat[0] == 'yes' ? $doNesting = 1 : $doNesting = '';
    123132
     
    126135
    127136                    $nested_dim = get_post_meta(self::$post_id, '_nestedDimension');
     137                    if (isset($nested_dim[0]) && empty($nested_dim[0]) && self::$parent_id != self::$post_id) {
     138                        $nested_dim = get_post_meta(self::$parent_id, '_nestedDimension');
     139                    }
     140                   
    128141                    $nested_dimension = isset($nested_dim[0]) ? $nested_dim[0] : '';
    129142
    130143                    $max_nested_item = get_post_meta(self::$post_id, '_maxNestedItems');
     144                    if (isset($max_nested_item[0]) && empty($max_nested_item[0]) && self::$parent_id != self::$post_id) {
     145                        $max_nested_item = get_post_meta(self::$parent_id, '_maxNestedItems');
     146                    }
     147
    131148                    !empty($max_nested_item) ? $max_nested_items = $max_nested_item[0] : $max_nested_items = 0;
    132149
    133150                    $nested_staking = get_post_meta(self::$post_id, '_nestedStakingProperty');
    134151                    $nested_staking_property = isset($nested_staking[0]) ? $nested_staking[0] : '';
    135                     $product_title = str_replace(array("'", '"'), '', esc_attr($product_data->get_title()));
     152                    $product_title = str_replace(array("'", '"'), '', esc_attr($product_data->get_name()));
    136153                   
    137154                    // Get product level markup value
    138155                    $product_level_markup = self::en_get_product_level_markup($product_data, $product['variation_id'], $product['product_id'], $product['quantity']);
     156                    $product_level_fulfillment_offset = self::en_get_product_level_fulfillment_offset_days($product_data, $product['variation_id'], $product['product_id']);
    139157
    140158                    $product_item = [
     
    162180                        'productName' => str_replace(array("'", '"'), '', $product_data->get_name()),
    163181                        'variantId' => ($product_data->get_type() == 'variation') ? $product_data->get_id() : '',
    164                         'markup' => $product_level_markup
     182                        'markup' => $product_level_markup,
     183                        'fulfillment_offset_days' => $product_level_fulfillment_offset,
    165184                    ];
    166185
     
    279298
    280299                    if ($shipment_type && strlen($origin_zip_code) > 0) {
    281                         self::$en_request['product_name'][$origin_zip_code][] = $product_quantity . " x " . $product_data->get_title();
     300                        self::$en_request['product_name'][$origin_zip_code][] = $product_quantity . " x " . $product_data->get_name();
    282301
    283302                        self::$en_request['shipment_weight'][$origin_zip_code] = $shipment_weight;
    284303                        self::$en_request['commdityDetails'][$origin_zip_code][self::$post_id] = $product_item;
    285304                        self::$en_request['originAddress'][$origin_zip_code] = $origin_address;
     305
     306                        // Track maximum fulfillment offset days
     307                        if (is_numeric($product_level_fulfillment_offset) && $product_level_fulfillment_offset > 0) {
     308                            if (!isset(self::$en_request['max_fulfillment_offset_days']) || $product_level_fulfillment_offset > self::$en_request['max_fulfillment_offset_days']) {
     309                                self::$en_request['max_fulfillment_offset_days'] = $product_level_fulfillment_offset;
     310                            }
     311                        }
    286312                    }
    287313                }
     
    584610                case '_dropship_location':
    585611                    $enable_dropship = get_post_meta(self::$post_id, '_enable_dropship', true);
     612
     613                    if (empty($enable_dropship) && self::$parent_id > 0 && self::$parent_id != self::$post_id) {
     614                        self::$post_id = self::$parent_id;
     615                        $enable_dropship = get_post_meta(self::$post_id, '_enable_dropship', true);
     616                    }
     617
    586618                    switch ($enable_dropship) {
    587619                        case 'yes':
     
    672704            return $flat_rate_price;
    673705        }
     706
     707        static public function en_get_product_level_fulfillment_offset_days($_product, $variation_id, $product_id)
     708        {
     709            $fulfillment_offset_days = '';
     710            $field_name = '_eniture_product_level_fulfillment_offset_days';
     711
     712            if ($_product->get_type() == 'variation' && $variation_id > 0) {
     713                $fulfillment_offset_days = get_post_meta($variation_id, $field_name, true);
     714
     715                if (empty($fulfillment_offset_days) || !is_numeric($fulfillment_offset_days)) {
     716                    $parent_id = $_product->get_parent_id();
     717                    if ($parent_id > 0) {
     718                        $fulfillment_offset_days = get_post_meta($parent_id, $field_name, true);
     719                    }
     720                }
     721            } else {
     722                $fulfillment_offset_days = get_post_meta($_product->get_id(), $field_name, true);
     723            }
     724
     725            if (empty($fulfillment_offset_days) || !is_numeric($fulfillment_offset_days)) {
     726                $fulfillment_offset_days = get_post_meta($product_id, $field_name, true);
     727            }
     728
     729            // Validate and sanitize the value before returning
     730            if (is_numeric($fulfillment_offset_days)) {
     731                $value = intval($fulfillment_offset_days);
     732                return $value;
     733            }
     734
     735            // Return empty string if invalid
     736            return '';
     737        }
    674738    }
    675739
Note: See TracChangeset for help on using the changeset viewer.