Plugin Directory

Changeset 3492012


Ignore:
Timestamp:
03/26/2026 05:09:58 PM (38 hours ago)
Author:
elextensions
Message:

updated to v1.2.1

Location:
elex-discount-per-country
Files:
14 edited
1 copied

Legend:

Unmodified
Added
Removed
  • elex-discount-per-country/tags/1.2.1/assets/css/dpc-plugin-styles.css

    r2644557 r3492012  
    1 
    21#custom_price_field {
    32    /* margin-bottom: 5px; */
     
    1211}
    1312
    14 .interested_products{
    15     color:red;
    16     font:bolder;
     13.interested_products {
     14    color: red;
     15    font: bolder;
    1716}
    1817
     
    2625.elex_cpp_custom_title_heading {
    2726    font-size: 1.4em;
    28    
     27
    2928}
    3029
     
    3635.custom-min-price1 {
    3736    color: rgb(20, 19, 19);
    38     font-size: 25;
    39 }
     37    font-size: 25px;
     38}
     39
    4040.custom-min-price-validation {
    4141    color: rgb(20, 19, 19);
    42     font-size: 25;
     42    font-size: 25px;
    4343}
    4444
     
    6060    height: 5%;
    6161    border-color: rgb(200, 210, 219);
    62     vertical-align:middle;
    63     margin-bottom:15px;
     62    vertical-align: middle;
     63    margin-bottom: 15px;
    6464    line-height: 20px;
    65     font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    66     box-shadow: 0 5px 10px 5px rgba(0,0,0,0.2);
    67 }
     65    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
     66    box-shadow: 0 5px 10px 5px rgba(0, 0, 0, 0.2);
     67}
     68
    6869/*
    6970input.style {
     
    7778
    7879/*Styles for form-settings-template*/
     80.fields_adjustment_dpc {
     81    table-layout: fixed;
     82    width: 100%;
     83}
     84
    7985.fields_adjustment_dpc td {
    8086    vertical-align: middle;
    81     padding: 4px 7px;
    82 }
     87    padding: 8px;
     88    white-space: normal;
     89}
     90
    8391.fields_adjustment_dpc th {
    84     padding: 9px 7px;
     92    padding: 10px 10px;
    8593}
    8694
    8795.fields_adjustment_dpc .bold_span {
    88     font-weight:bold;
    89 }
    90 
    91 .fields_adjustment_dpc .col_btn{
     96    font-weight: bold;
     97}
     98
     99.fields_adjustment_dpc .col_btn {
    92100    display: flex;
    93101    justify-content: center;
    94     align-items: center;
    95 }
     102    align-items: center;
     103}
     104
    96105.fields_adjustment_dpc .remove_icon_discount_dpc {
    97     width: 10%;
    98 }
     106    width: 7%;
     107    min-width: 65px;
     108    text-align: center;
     109}
     110
    99111.fields_adjustment_dpc .table_col_1_dpc {
    100     width: 2%;
    101 }
     112    width: 3%;
     113    min-width: 30px;
     114}
     115
    102116.fields_adjustment_dpc .table_col_2_dpc {
    103     width: 35%;
    104 }
     117    width: 20%;
     118    min-width: 160px;
     119    /* Payment Method / region select */
     120}
     121
     122.fields_adjustment_dpc .table_col_type_dpc {
     123    width: 12%;
     124    min-width: 120px;
     125    /* Discount Type - wider so Percentage/Fixed shows fully */
     126}
     127
     128.fields_adjustment_dpc .table_col_label_dpc {
     129    width: 12%;
     130    min-width: 110px;
     131    /* Discount Label */
     132}
     133
    105134.fields_adjustment_dpc .table_col_3_dpc {
    106     width: 35%;
    107 }
     135    width: 15%;
     136    min-width: 180px;
     137    /* Percentage/Fixed Amount value */
     138}
     139
     140.fields_adjustment_dpc .table_col_5_dpc {
     141    width: 12%;
     142    min-width: 130px;
     143    /* From Date */
     144}
     145
     146.fields_adjustment_dpc .table_col_6_dpc {
     147    width: 12%;
     148    min-width: 130px;
     149    /* To Date */
     150}
     151
    108152.fields_adjustment_dpc .table_col_4_dpc {
    109     width: 10%;
    110 }
    111 .fields_adjustment_dpc .table_col_5_dpc {
    112     width: 10%;
    113 }
    114 .fields_adjustment_dpc .table_col_6_dpc {
    115     width: 10%;
     153    width: 7%;
     154    min-width: 65px;
     155    text-align: center;
     156}
     157
     158/* Reduce outer spacing around the Add New Discount button */
     159.fields_adjustment_dpc tfoot td {
     160    padding: 16px 0 !important;
     161}
     162
     163.fields_adjustment_dpc td input[type="text"],
     164.fields_adjustment_dpc td input[type="number"],
     165.fields_adjustment_dpc td input[type="datetime-local"],
     166.fields_adjustment_dpc td select {
     167    width: 100%;
     168    box-sizing: border-box;
     169    padding: 7px 10px;
     170    border: 1px solid #c3c4c7;
     171    border-radius: 4px;
     172    /* Match the Select region border-radius */
     173    background-color: #fff;
     174    color: #2c3338;
     175    font-size: 13px;
     176}
     177
     178.fields_adjustment_dpc td input:focus,
     179.fields_adjustment_dpc td select:focus {
     180    border-color: #2271b1;
     181    box-shadow: none;
     182    /* Flat focus, no glow */
     183    outline: none;
    116184}
    117185
    118186.fields_adjustment_dpc td input {
    119     margin-right: 4px;
    120 }
     187    margin-right: 0;
     188}
     189
    121190.fields_adjustment_dpc .check-column {
    122191    vertical-align: middle;
     
    124193    padding: 0 7px;
    125194}
    126 .fields_adjustment_dpc .table_input_raw_dpc{
    127     background: #EBEBEB;
    128 }
    129 
    130 .woocommerce table.form-table .select2-container {
    131 min-width: 500px!important;
     195
     196.fields_adjustment_dpc .table_input_raw_dpc {
     197    background: #f6f7f7;
     198}
     199
     200/* Empty state messages - centered */
     201.nodiscount-dpc td {
     202    text-align: center !important;
     203    padding: 24px 0 !important;
     204}
     205
     206#no_discount_available_dpc {
     207    display: block;
     208    text-align: center;
     209    color: #50575e;
     210    font-size: 13px;
     211    margin-bottom: 6px;
     212}
     213
     214.no-payments-btn {
     215    text-align: center;
     216    color: #50575e;
     217    font-size: 13px;
     218}
     219
     220.fields_adjustment_dpc .select2-container {
     221    min-width: 100% !important;
    132222}
    133223
    134224.fields_adjustment_dpc .table_header {
    135     font-weight:bold;
     225    font-weight: bold;
     226    font-size: 13px;
     227    color: #50575e;
     228    vertical-align: middle;
    136229}
    137230
    138231.table_th_label {
    139     font-weight:bold;
    140     font-size:small;
    141 }
     232    font-weight: bold;
     233    font-size: 13px;
     234}
     235
    142236.fields_adjustment_dpc .table_header_remove {
    143237    text-align: center;
    144     font-weight:bold;
     238    font-weight: bold;
     239    font-size: 13px;
     240    color: #50575e;
     241    vertical-align: middle;
    145242}
    146243
     
    149246    padding: 0 16px;
    150247}
     248
    151249.fields_adjustment_dpc td.sort {
    152250    width: 16px;
    153251    padding: 0 16px;
    154252    cursor: move;
    155     background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAHUlEQVQYV2O8f//+fwY8gJGgAny6QXKETRgEVgAAXxAVsa5Xr3QAAAAASUVORK5CYII=) no-repeat center;   
    156     }
     253    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAHUlEQVQYV2O8f//+fwY8gJGgAny6QXKETRgEVgAAXxAVsa5Xr3QAAAAASUVORK5CYII=) no-repeat center;
     254}
     255
    157256.fields_adjustment_dpc td.remove_icon_discount_dpc {
    158257    width: 16px;
    159258    padding: 0 16px;
    160    
     259
    161260    cursor: pointer;
    162261    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAA3NCSVQICAjb4U/gAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAB70lEQVQ4T61UPUhbURT+7n0vLxE1vmqFEBTR6lS7uHaTYpfqopsu0qkgODh0EURwadFBEJy62a3t0BbBIm5dXdTJP/whiFr7EpUmL3m5nnNixR80EfLBXe79vu+ce865VxkCbsHf2Ud6eQWZzS1k1tZlL/y8DeFnLYh0vIDT1CB713HDKPBS8D5/xemPX8hns1COA2VbcmZyAYzvQ4dCqO7ugtvfC8uNyhnjyiibOMDByDhyngdFZKW1EG7D5PMwFMR2XcSmxhCKx2RfjIJkCol375E7IZMwZaGUHN4Hjm0yPuxaF/HZD7BqopCw3twXBH9LM2Ewh7msYS1D+zt7OP25CNh0HdqQaCUsCUca1rKHTi+vIk9FVFrR/YmUTsP8K7KYQ1zWsJY91OHHGXO29Fu6Y7k1iPa8ptwlNY55F3x1Okp9X6AuJ6WbVZ0voXYHh01w9AegbjitzYhPT1wqHkZieBT+xjYVR8OqrysUuxwo39WS3+bN8cwnWFWVhWL7GSE+CPJSTliKHZyd4+nQW+hIRzs0PYX/XVCRCFRFkcWcyy6ztuDR1IjqN6+AXFYSkWErYUnSpGEte0ix3YE+WE9cGXsetmKQoSQua1jLECN+K7HJMdhsRgPGD/M+yKMlDnNZw1pG+b+R63j8xwZcADXJQNHUd268AAAAAElFTkSuQmCC) no-repeat center
     
    165264.fields_adjustment_dpc #elex_dpc_add_field {
    166265    cursor: pointer;
    167 } 
     266}
    168267
    169268.fields_adjustment_dpc select {
     
    171270}
    172271
    173 tr td {
    174 
    175 white-space: nowrap;
    176 }
    177272body {
    178 background:#FCFCFC;
    179 color:#222;
    180 font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;
    181 }
     273    background: #FCFCFC;
     274    color: #222;
     275    font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Open Sans, Helvetica Neue, sans-serif;
     276}
     277
    182278.btn_raw {
    183279
    184 background-color: white;
    185 padding-top: 5px;
    186 border: none;
    187 border-radius: 50%;
    188 background:   #1E90FF;
    189 color: white;
    190 padding: 1px 2px;
    191 cursor: pointer;
    192 
    193 
    194 }
     280    background-color: white;
     281    padding-top: 5px;
     282    border: none;
     283    border-radius: 50%;
     284    background: #1E90FF;
     285    color: white;
     286    padding: 1px 2px;
     287    cursor: pointer;
     288
     289
     290}
     291
     292/* Premium "Add New Discount" Button Style */
     293.fields_adjustment_dpc .elex-add-new-btn {
     294    background: #2271b1;
     295    border: none;
     296    color: #ffffff;
     297    padding: 6px 20px 6px 6px;
     298    border-radius: 50px;
     299    display: inline-flex;
     300    align-items: center;
     301    gap: 12px;
     302    cursor: pointer;
     303    font-weight: 500;
     304    font-size: 14px;
     305    transition: all 0.3s ease;
     306    box-shadow: 0 2px 4px rgba(34, 113, 177, 0.2);
     307    text-decoration: none;
     308    line-height: 1;
     309}
     310
     311.fields_adjustment_dpc .elex-add-new-btn:hover {
     312    background: #1c5d91;
     313    transform: translateY(-1px);
     314    box-shadow: 0 4px 8px rgba(34, 113, 177, 0.3);
     315}
     316
     317.fields_adjustment_dpc .elex-add-new-btn .icon-circle {
     318    display: flex;
     319    align-items: center;
     320    justify-content: center;
     321    width: 28px;
     322    height: 28px;
     323    background: #ffffff;
     324    color: #2271b1;
     325    border-radius: 50%;
     326    font-size: 18px;
     327    /* Slightly larger for text + */
     328    font-weight: bold;
     329    padding: 0;
     330    line-height: 0;
     331    /* Helps with centering text + */
     332}
     333
     334#elex_dpc_add_field_discount .icon-circle {
     335    color: #2271b1;
     336}
     337
     338.fields_adjustment_dpc .elex-add-new-btn .btn-text {
     339    padding-right: 5px;
     340    color: #ffffff;
     341}
     342
    195343.switch {
    196 
    197 position: relative;
    198 display: inline-block;
    199 width: 40px;
    200 height: 19px;
    201 }
    202 
    203 .switch input {
    204 opacity: 0;
    205 width: 0;
    206 height: 0;
     344    position: relative;
     345    display: inline-block;
     346    width: 40px;
     347    height: 19px;
     348}
     349
     350.switch input {
     351    opacity: 0;
     352    width: 0;
     353    height: 0;
    207354}
    208355
    209356.slider {
    210 position: absolute;
    211 cursor: pointer;
    212 top: 0;
    213 left: 0;
    214 right: 0;
    215 bottom: 0;
    216 background-color: #ccc;
    217 -webkit-transition: .4s;
    218 transition: .4s;
     357    position: absolute;
     358    cursor: pointer;
     359    top: 0;
     360    left: 0;
     361    right: 0;
     362    bottom: 0;
     363    background-color: #ccc;
     364    -webkit-transition: .4s;
     365    transition: .4s;
    219366}
    220367
    221368.slider:before {
    222 position: absolute;
    223 content: "";
    224 height:16px;
    225 width: 16px;
    226 left: 4px;
    227 bottom: 2px;
    228 background-color: white;
    229 -webkit-transition: .4s;
    230 transition: .4s;
    231 }
    232 
    233 input:checked + .slider {
    234 background-color: #2196F3;
    235 }
    236 
    237 input:focus + .slider {
    238 box-shadow: 0 0 1px #2196F3;
    239 }
    240 
    241 input:checked + .slider:before {
    242 -webkit-transform: translateX(16px);
    243 -ms-transform: translateX(16px);
    244 transform: translateX(16px);
     369    position: absolute;
     370    content: "";
     371    height: 16px;
     372    width: 16px;
     373    left: 4px;
     374    bottom: 2px;
     375    background-color: white;
     376    -webkit-transition: .4s;
     377    transition: .4s;
     378}
     379
     380input:checked+.slider {
     381    background-color: #2196F3;
     382}
     383
     384input:focus+.slider {
     385    box-shadow: 0 0 1px #2196F3;
     386}
     387
     388input:checked+.slider:before {
     389    -webkit-transform: translateX(16px);
     390    -ms-transform: translateX(16px);
     391    transform: translateX(16px);
    245392}
    246393
    247394/* Rounded sliders */
    248395.slider.round {
    249 border-radius: 34px;
     396    border-radius: 34px;
    250397}
    251398
    252399.slider.round:before {
    253 border-radius: 50%;
    254 }
     400    border-radius: 50%;
     401}
  • elex-discount-per-country/tags/1.2.1/assets/js/dpc-plugin-scripts.js

    r3460057 r3492012  
    1 jQuery(document).ready(function(){
    2 
    3     jQuery(document).on('change','.elex_discount_per_country_to_date' ,function(){
     1jQuery(document).ready(function () {
     2
     3    jQuery(document).off('change', '.elex_discount_per_country_to_date').on('change', '.elex_discount_per_country_to_date', function () {
    44        var end_date = new Date(jQuery(this).val());
    5         var start_date  = new Date(jQuery(this).parents('tr').find('.elex_discount_per_country_from_date').val());
    6 
    7     if(start_date.getTime() >  end_date.getTime()){
    8        
    9         alert("To date can not be less than From date");
    10         var end_date = new Date(jQuery(this).val(''));
    11         return;
    12        
    13     }
    14 
    15     });
    16 
    17     jQuery(document).on('change','.elex_discount_per_country_from_date' ,function(){
     5        var start_date = new Date(jQuery(this).parents('tr').find('.elex_discount_per_country_from_date').val());
     6
     7        if (start_date.getTime() > end_date.getTime()) {
     8
     9            alert("To date can not be less than From date");
     10            var end_date = new Date(jQuery(this).val(''));
     11            return;
     12
     13        }
     14
     15    });
     16
     17    jQuery(document).off('change', '.elex_discount_per_country_from_date').on('change', '.elex_discount_per_country_from_date', function () {
    1818        var start_date = new Date(jQuery(this).val());
    19         var end_date  = new Date(jQuery(this).parents('tr').find('.elex_discount_per_country_to_date').val());
    20 
    21     if(start_date.getTime() >  end_date.getTime()){
    22        
    23         var start_date = new Date(jQuery(this).val(''));
    24         alert("start date can not be more than From date");
    25         return;
    26     }
    27    
     19        var end_date = new Date(jQuery(this).parents('tr').find('.elex_discount_per_country_to_date').val());
     20
     21        if (start_date.getTime() > end_date.getTime()) {
     22
     23            var start_date = new Date(jQuery(this).val(''));
     24            alert("start date can not be more than From date");
     25            return;
     26        }
     27
    2828    });
    2929    /*Scripts for form-settings-temp */
    30     jQuery("#elex_dpc_table_body").on('click', '.remove_icon_discount_dpc', function () {
    31        
    32         var tbody = jQuery('.fields_adjustment_dpc').find('tbody');
    33         var size = tbody.find('tr').size();
     30    jQuery("#elex_dpc_table_body").off('click', '.remove_icon_discount_dpc').on('click', '.remove_icon_discount_dpc', function () {
     31
     32        var tbody = jQuery('#elex_dpc_table_body');
     33        var size = tbody.find('tr').length;
    3434        var id = jQuery(this).closest("tr").attr("id");
    3535        var value = jQuery(this).closest("tr").attr("class");
    36         if(value==="nodiscount-dpc"){
     36
     37        if (value === "nodiscount-dpc") {
    3738
    3839            jQuery("#nodiscount-dpc").remove();
    39            
    40         }else if(size===1){
    41 
    42            
    43             jQuery('#elex_discount_per_country_options_select_value').append('<option id="'+id+'" value="'+value+'">'+elexdpc_translations['country_id']+'</option>');
     40
     41        } else {
     42
     43            // Add removed country options back to the country dropdown if they were loaded as existing rows
     44            var $tr = jQuery(this).closest("tr");
     45            var existingCountryCode = $tr.find('input[name*="[country_code]"]').val();
     46            var existingCountryName = $tr.find('input[name*="[country_name]"]').val() || $tr.find('span.bold_span').text();
     47
     48            if (existingCountryCode) {
     49                if (jQuery('#zone_locations_template option[value="' + existingCountryCode + '"]').length === 0) {
     50                    jQuery('#zone_locations_template').append('<option value="' + existingCountryCode + '">&nbsp;&nbsp; ' + existingCountryName + '</option>');
     51                }
     52            }
     53
     54            // Capture dynamically selected ones in case they are missing
     55            $tr.find('select[id^="zone_locations_"] option:selected').each(function () {
     56                var optionValue = jQuery(this).val();
     57                var optionText = jQuery(this).text();
     58                if (optionValue && jQuery('#zone_locations_template option[value="' + optionValue + '"]').length === 0) {
     59                    jQuery('#zone_locations_template').append('<option value="' + optionValue + '">' + optionText + '</option>');
     60                }
     61            });
     62
    4463            jQuery(this).closest("tr").remove();
    4564
    46             var default_code='<tr id="nodiscount-dpc" class="nodiscount-dpc"><td class="table_col_1"></td><td class="table_col_2"><span class="wc-country-name"  id="no_discount_available_dpc">'+elexdpc_translations['tooltip']['nodiscount-dpc']+'</span></td><td class="table_col_3"></td><td class="table_col_4"></td> <td class="table_col_4"></td></tr>';
    47 
    48             jQuery('#elex_dpc_table_body').append( default_code );
    49 
    50         }else{
    51 
    52         jQuery('#elex_discount_per_country_options_select_value').append('<option id="'+id+'" value="'+value+'">'+elexdpc_translations['country_id']+'</option>');
    53         jQuery(this).closest("tr").remove();
    54        
    55         }
    56     });
    57 
    58     jQuery("#elex_dpc_table_body").on('click','.checkbox_click', function () {
    59 
    60         var v = jQuery(this).closest("td").find('input').val();
    61 
    62         if(v== true)
    63         {
    64             jQuery(this).closest("td").find('input').val("yes");
    65             jQuery(this).closest("td").find('label').attr('title',elexdpc_translations['tooltip']['toggleon']);
    66         }
    67        
    68 
    69         if(v== false)
    70         {
    71             jQuery(this).closest("td").find('input').val("no");
     65            if (size === 1) {
     66                var default_code = '<tr id="nodiscount-dpc" class="nodiscount-dpc"><td colspan="9"><div class="no-payments-btn">' + elexdpc_translations['tooltip']['nodiscount-dpc'] + '</div></td></tr>';
     67                jQuery('#elex_dpc_table_body').append(default_code);
     68            }
     69
     70        }
     71    });
     72
     73    jQuery("#elex_dpc_table_body").off('click', '.checkbox_click').on('click', '.checkbox_click', function () {
     74
     75        var v = jQuery(this).is(':checked');
     76
     77        if (v) {
     78            jQuery(this).closest("td").find('label').attr('title', elexdpc_translations['tooltip']['toggleon']);
     79        } else {
    7280            jQuery(this).closest("td").find('label').attr('title', elexdpc_translations['tooltip']['toggleoff']);
    73            
    74         }
    75 
    76 
    77     });
    78 
    79     //To add more rules before saving changes
    80     jQuery('#elex_dpc_add_field_discount').click( function(e) {
     81        }
     82
     83
     84    });
     85
     86    // Update discount input constraints based on discount type
     87    function updateDiscountConstraints($row) {
     88        var type = $row.find('select[name*="[discount_type]"]').val();
     89        // accidentally matching [discount_type] or other fields that contain "[discount]"
     90        var $input = $row.find('input[name$="[discount]"]');
     91        if (type === 'fixed') {
     92            $input.removeAttr('max');
     93            $input.attr('min', '0');
     94            $input.attr('title', 'Enter the fixed discount amount (0 or above)');
     95        } else {
     96            $input.attr('max', '100');
     97            $input.attr('min', '0');
     98            $input.attr('title', 'Enter the discount percentage value from 0 to 100.');
     99        }
     100    }
     101
     102    // Initialize constraints on page load for all existing rows
     103    jQuery('#elex_dpc_table_body tr').each(function () {
     104        updateDiscountConstraints(jQuery(this));
     105    });
     106
     107    // Update constraints when discount type changes
     108    jQuery('#elex_dpc_table_body').off('change', 'select[name*="[discount_type]"]').on('change', 'select[name*="[discount_type]"]', function () {
     109        updateDiscountConstraints(jQuery(this).closest('tr'));
     110    });
     111
     112    // To add empty editable rules before saving changes
     113    jQuery('#elex_dpc_add_field_discount').off('click').on('click', function (e) {
    81114        e.preventDefault();
    82        
    83 
    84         if(closest_tr_class="nodiscount-dpc"){
    85 
     115
     116        if (jQuery("#nodiscount-dpc").length) {
    86117            jQuery("#nodiscount-dpc").remove();
    87 
    88         }
    89         var tbody = jQuery('.fields_adjustment_dpc').find('tbody');
    90         var size = tbody.find('tr').size();
    91        
    92         var closest_tr_class = jQuery('#nodiscount-dpc').attr("class");
    93         var checkbox_enabled= jQuery('#elex_discount_per_country_options_enabled').is(':checked');
    94         var id = [];
    95         var input_value = jQuery("#elex_discount_per_country_options_input_value").val();
    96         var country_selected = jQuery("#zone_locations").val();
    97         if ( country_selected.length <= 0 ) {
    98             alert( elexdpc_translations['error_message']['nofieldsfilled'] );
    99             return;
    100         }
    101         // get the date in required format and it to the table
    102 
    103         var startdate_bfr_converting= jQuery("#elex_discount_per_country_start_date").val();
    104         var enddate_bfr_converting= jQuery("#elex_discount_per_country_end_date").val();
    105        
    106         if(startdate_bfr_converting === '')
    107         {
    108             var start_date = '';
    109         }
    110         else
    111         {
    112             var start_date = moment(new Date(jQuery("#elex_discount_per_country_start_date").val()) ).format('YYYY-MM-DDTHH:mm');
    113         }
    114 
    115         if(enddate_bfr_converting === '')
    116         {
    117             var end_date = '';
    118         }
    119         else
    120         {
    121             var end_date= moment(new Date(jQuery("#elex_discount_per_country_end_date").val()) ).format('YYYY-MM-DDTHH:mm');
    122 
    123         }
    124         if(start_date !== '' && end_date !== '' )
    125         {
    126                 if(start_date >  end_date){
    127                     alert("To date can not be less than From date");
    128                     return;
     118        }
     119
     120        var tbody = jQuery('#elex_dpc_table_body');
     121
     122        // Find the highest existing index to determine the next size
     123        var maxIndex = -1;
     124        tbody.find('tr').each(function () {
     125            var idAttr = jQuery(this).attr('id');
     126            // Existing rows might have numeric IDs or custom IDs.
     127            // We look for the inputs to get the actual array index used.
     128            jQuery(this).find('input[name*="elex_discount_per_country_options"]').each(function () {
     129                var name = jQuery(this).attr('name');
     130                var match = name.match(/\[(\d+)\]/);
     131                if (match) {
     132                    var idx = parseInt(match[1]);
     133                    if (idx > maxIndex) maxIndex = idx;
    129134                }
    130         }
    131 
    132         var startdate_bfr_converting= jQuery("#elex_discount_per_country_start_date").val('');
    133         var enddate_bfr_converting= jQuery("#elex_discount_per_country_end_date").val('');
    134         var country_names = [];
    135          jQuery('#zone_locations').find("option:selected").map(function() {
    136             country_names.push(jQuery(this).text());
    137             id.push(this.value);
     135            });
    138136        });
    139         country_names = country_names.join(', ');
    140 
    141         jQuery('#zone_locations').find("option:selected").remove();
    142 
    143         id = id.join(',');
    144 
    145         jQuery("#elex_discount_per_country_options_input_value").val(0);
    146        
    147         if ( input_value <= 100 && input_value >= 0 && ( input_value.indexOf(".") <= 2 ) && input_value != "" && country_selected != "" )
    148         {
    149 
    150             var code='<tr id="'+id+'" class="'+country_selected+'">\
    151                     <td class="table_col_1"  > </td>\
    152                     <td class="table_col_2"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][country_code]" value="'+id+'"/><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][country_name]" value="'+country_selected+'"/> <span  class="wc-country-name" >'+country_names+'</span></td>\
    153                     <td class="table_col_3" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="number"  min="0" max="100" step="any" class="order" name="elex_discount_per_country_options['+size+'][discount]" value="'+input_value+'" required></td>\
    154                     <td class="table_col_5" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="datetime-local"   class="elex_discount_per_country_from_date" name="elex_discount_per_country_options['+size+'][start_date]" value="'+start_date+'"  ></td>\
    155                     <td class="table_col_6" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="datetime-local" class="elex_discount_per_country_to_date" name="elex_discount_per_country_options['+size+'][end_date]" value="'+end_date+'"  ></td>';
    156 
    157 
    158             if(checkbox_enabled)
    159             {
    160                 code +='<td  class="table_col_4" > <label title="'+elexdpc_translations['tooltip']['toggleoff']+'" class="switch"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][status]" value="yes"/><input    type="checkbox" class="checkbox_click" name="elex_discount_per_country_options['+size+'][enabled]" value="1" checked><span class="slider round"></span></label></td>';
    161            
    162             }else{
    163 
    164                 code +='<td class="table_col_4"> <label title="'+elexdpc_translations['tooltip']['toggleon']+'" class="switch"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][status]" value="no"/><input  type="checkbox" class="checkbox_click" name="elex_discount_per_country_options['+size+'][enabled]" value="0"  ><span class="slider round"></span></label></td>';
    165 
    166             }
    167            
    168 
    169             code +='<td class="remove_icon_discount_dpc" title="'+elexdpc_translations['tooltip']['remove']+'" ></td>\
     137        var size = maxIndex + 1;
     138
     139        // Clone templates
     140        var countrySelect = jQuery('#zone_locations_template').clone();
     141        countrySelect.attr('id', 'zone_locations_' + size);
     142        countrySelect.attr('name', 'elex_discount_per_country_options[' + size + '][country_code][]');
     143        countrySelect.css('width', '100%');
     144        countrySelect.addClass('wc-enhanced-select');
     145
     146        var typeSelect = jQuery('#elex_discount_per_country_discount_type_template').clone();
     147        typeSelect.attr('id', 'discount_type_' + size);
     148        typeSelect.attr('name', 'elex_discount_per_country_options[' + size + '][discount_type]');
     149
     150        var labelInput = jQuery('#elex_discount_per_country_label_template').clone();
     151        labelInput.attr('id', 'label_' + size);
     152        labelInput.attr('name', 'elex_discount_per_country_options[' + size + '][label]');
     153
     154        var discountInput = jQuery('#elex_discount_per_country_options_input_value_template').clone();
     155        discountInput.attr('id', 'discount_value_' + size);
     156        discountInput.attr('name', 'elex_discount_per_country_options[' + size + '][discount]');
     157
     158        var startDateInput = jQuery('#elex_discount_per_country_start_date_template').clone();
     159        startDateInput.attr('id', 'start_date_' + size);
     160        startDateInput.attr('name', 'elex_discount_per_country_options[' + size + '][start_date]');
     161
     162        var endDateInput = jQuery('#elex_discount_per_country_end_date_template').clone();
     163        endDateInput.attr('id', 'end_date_' + size);
     164        endDateInput.attr('name', 'elex_discount_per_country_options[' + size + '][end_date]');
     165
     166        var statusLabel = jQuery('#elex_discount_per_country_options_enabled_template').parent().clone();
     167        statusLabel.find('input').attr('id', 'enabled_' + size);
     168        statusLabel.find('input').attr('name', 'elex_discount_per_country_options[' + size + '][status]');
     169        statusLabel.find('input').val('yes'); // Default enabled
     170        statusLabel.find('input').prop('checked', true);
     171
     172        var code = '<tr id="new_row_' + size + '" class="new_row_dpc">\
     173                    <td class="table_col_1_dpc"> </td>\
     174                    <td class="table_col_2_dpc"></td>\
     175                    <td class="table_col_type_dpc"></td>\
     176                    <td class="table_col_3_dpc"></td>\
     177                    <td class="table_col_label_dpc"></td>\
     178                    <td class="table_col_5_dpc"></td>\
     179                    <td class="table_col_6_dpc"></td>\
     180                    <td class="table_col_4_dpc"></td>\
     181                    <td class="remove_icon_discount_dpc" title="' + elexdpc_translations['tooltip']['remove'] + '"><span class="remove-btn-circle"><i class="fas fa-minus"></i></span></td>\
    170182                    </tr>';
    171183
    172             jQuery('#elex_dpc_table_body').append( code );
    173         }else{
    174 
    175            
    176            
    177             if(country_selected==""){
    178 
    179                 alert(elexdpc_translations['tooltip']['allcountriesselected']);
    180 
    181             }else{
    182                 alert(elexdpc_translations['tooltip']['inputalert']);
    183             }
    184 
    185         }
     184        var $newRow = jQuery(code);
     185        $newRow.find('.table_col_2_dpc').append(countrySelect);
     186        $newRow.find('.table_col_type_dpc').append(typeSelect);
     187        $newRow.find('.table_col_3_dpc').append(discountInput);
     188        $newRow.find('.table_col_label_dpc').append(labelInput);
     189        $newRow.find('.table_col_5_dpc').append(startDateInput);
     190        $newRow.find('.table_col_6_dpc').append(endDateInput);
     191        $newRow.find('.table_col_4_dpc').append(statusLabel);
     192
     193        tbody.append($newRow);
     194
     195        // Initialize discount constraints for the new row
     196        updateDiscountConstraints($newRow);
     197
     198        // Initialize Select2/Enhanced Select
     199        jQuery(document.body).trigger('wc-enhanced-select-init');
     200
    186201        return false;
    187202    });
    188203
    189 
    190         //To save the rule on clicking save changes button(without clicking add button)
    191 
    192         jQuery("button[name='save']").click( function() {
    193         var checkbox_enabled= jQuery('#elex_discount_per_country_options_enabled').is(':checked');
    194         var id = [];
    195         var input_value = jQuery("#elex_discount_per_country_options_input_value").val();
    196         var country_selected = jQuery("#zone_locations").val();
    197         var tbody = jQuery('.fields_adjustment_dpc').find('tbody');
    198         var size = tbody.find('tr').size();
    199        
    200         // get the date in required format and it to the table
    201 
    202         var startdate_bfr_converting= jQuery("#elex_discount_per_country_start_date").val();
    203         var enddate_bfr_converting= jQuery("#elex_discount_per_country_end_date").val();
    204        
    205         if(startdate_bfr_converting === '')
    206         {
    207             var start_date = '';
    208         }
    209         else
    210         {
    211             var start_date = moment(new Date(jQuery("#elex_discount_per_country_start_date").val()) ).format('YYYY-MM-DDTHH:mm');
    212         }
    213 
    214         if(enddate_bfr_converting === '')
    215         {
    216             var end_date = '';
    217         }
    218         else
    219         {
    220             var end_date= moment(new Date(jQuery("#elex_discount_per_country_end_date").val()) ).format('YYYY-MM-DDTHH:mm');
    221 
    222         }
    223         if(start_date !== '' && end_date !== '' )
    224         {
    225                 if(start_date >  end_date){
    226                     alert("To date can not be less than From date");
    227                     return;
    228                 }
    229         }
    230 
    231         var startdate_bfr_converting= jQuery("#elex_discount_per_country_start_date").val('');
    232         var enddate_bfr_converting= jQuery("#elex_discount_per_country_end_date").val('');
    233         var country_names = [];
    234          jQuery('#zone_locations').find("option:selected").map(function() {
    235             country_names.push(jQuery(this).text());
    236             id.push(this.value);
    237         });
    238         jQuery('#zone_locations').find("option:selected").remove();
    239         jQuery("#elex_discount_per_country_options_input_value").val(0);
    240 
    241 
    242         if (input_value<=100 && input_value>=0 && ( input_value.indexOf(".") <= 2 ) && input_value!="" && country_selected!="")
    243         {
    244            
    245             var code='<tr id="'+id+'" class="'+country_selected+'">\
    246                     <td class="table_col_1"  > </td>\
    247                     <td class="table_col_2"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][country_code]" value="'+id+'"/><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][country_name]" value="'+country_selected+'"/> <span  class="wc-country-name" >'+country_names+'</span></td>\
    248                     <td class="table_col_3" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="number" min="0" max="100" step="any" class="order" name="elex_discount_per_country_options['+size+'][discount]" value="'+input_value+'" required></td>\
    249                     <td class="table_col_5" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="datetime-local"   class="elex_discount_per_country_from_date" name="elex_discount_per_country_options['+size+'][start_date]" value="'+start_date+'"  ></td>\
    250                     <td class="table_col_6" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="datetime-local" class="elex_discount_per_country_to_date" name="elex_discount_per_country_options['+size+'][end_date]" value="'+end_date+'"  ></td>';
    251 
    252 
    253             if(checkbox_enabled)
    254             {
    255                 code +='<td  class="table_col_4" > <label title="'+elexdpc_translations['tooltip']['toggleoff']+'" class="switch"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][status]" value="yes"/><input    type="checkbox" class="checkbox_click" name="elex_discount_per_country_options['+size+'][enabled]" value="1" checked><span class="slider round"></span></label></td>';
    256            
    257             }else{
    258 
    259                 code +='<td class="table_col_4"> <label title="'+elexdpc_translations['tooltip']['toggleon']+'" class="switch"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][status]" value="no"/><input  type="checkbox" class="checkbox_click" name="elex_discount_per_country_options['+size+'][enabled]" value="0"  ><span class="slider round"></span></label></td>';
    260 
    261             }
    262            
    263 
    264             code +='<td class="remove_icon_discount_dpc" title="'+elexdpc_translations['tooltip']['remove']+'" ></td>\
    265                     </tr>';
    266 
    267             jQuery('#elex_dpc_table_body').append( code );
    268        
    269         }
    270 
    271     });
    272 
    273 
    274     /* script for refreshing cart on selecting different country_selected option */
    275 
    276     (function($){
    277                    
    278         $( 'form.checkout' ).on( 'change', 'input[name^="country"]', function() {
    279 
    280         $('body').trigger('update_checkout');
    281 
    282         });
    283 
    284     })(jQuery);
    285 
    286 
     204    // The save handler no longer needs to auto-add rows from static inputs
     205    jQuery("button[name='save']").off('click').on('click', function (e) {
     206        // Just let the form submit normally
     207        return true;
     208    });
    287209});
    288210
    289    
     211
     212
     213/* script for refreshing cart on selecting different country_selected option */
     214
     215(function ($) {
     216
     217    $('form.checkout').off('change', 'input[name^="country"]').on('change', 'input[name^="country"]', function () {
     218
     219        $('body').trigger('update_checkout');
     220
     221    });
     222
     223})(jQuery);
     224
     225
     226
  • elex-discount-per-country/tags/1.2.1/elex-discount-per-country.php

    r3460057 r3492012  
    44 * Plugin URI:           https://elextensions.com/plugin/elex-woocommerce-discount-per-country-plugin-free/
    55 * Description:          The plugin allows you to offer discounts on your WooCommerce store based on the shipping country and shipping state chosen by customers.
    6  * Version:              1.2.0
     6 * Version:              1.2.1
    77 * Author:               ELEXtensions
    88 * Author URI:           https://elextensions.com/
  • elex-discount-per-country/tags/1.2.1/includes/class-discount-per-country.php

    r3460057 r3492012  
    22
    33class ELEXDPC_Discount_Per_Country_Model {
     4
     5
    46    const OPTION_KEY = 'elexdpc_discount_per_country_options';
    5     private $items   = [];
     7    private $items = [];
    68
    79    public function get_items() {
    8        return $this->items; 
     10       return $this->items;
    911    }
    1012
     
    1618        return array_map(
    1719            function ( $item ) {
    18             return $item->to_array();
     20                return $item->to_array();
    1921            },
    2022            $this->items
    2123        );
    2224    }
    23    
     25
    2426    public function build() {
    25          $items = get_option( self::OPTION_KEY, array() );
    26        
     27       $items = get_option( self::OPTION_KEY, array() );
     28
     29        $old_global_label = get_option( 'elex-discount-per-country_label', '' );
     30
    2731        foreach ( $items as $item ) {
    28             $array_obj = new ELEXDPC_Discount_Per_Country_Rule( $item['country_code'], $item['discount'], $item['status'], $item['country_name'] , $item['start_date'], $item['end_date'] );
     32            if ( ! array_key_exists( 'label', $item ) ) {
     33                $resolved_label = $old_global_label;
     34            } else {
     35                $resolved_label = $item['label'];
     36            }
     37
     38            $array_obj = new ELEXDPC_Discount_Per_Country_Rule(
     39                isset( $item['country_code'] ) ? $item['country_code'] : '',
     40                isset( $item['discount'] ) ? $item['discount'] : 0,
     41                isset( $item['status'] ) ? $item['status'] : false,
     42                isset( $item['country_name'] ) ? $item['country_name'] : '',
     43                isset( $item['start_date'] ) ? $item['start_date'] : '',
     44                isset( $item['end_date'] ) ? $item['end_date'] : '',
     45                $resolved_label,
     46                isset( $item['discount_type'] ) ? $item['discount_type'] : 'percentage'
     47            );
    2948            $this->add( $array_obj );
    3049        }
     50    }
    3151
    32        
    33     }
    3452
    3553
     
    4058
    4159    public function remove( $country_code ) {
    42                 $this->items = array_filter(
    43                     $this->items,
    44                     function ( $item ) use ( $country_code ) {
    45                         return $country_code !== $item->country_code;
    46                     }
    47                 );
     60        $this->items = array_filter(
     61            $this->items,
     62            function ( $item ) use ( $country_code ) {
     63                return $country_code !== $item->country_code;
     64            }
     65        );
    4866    }
    4967
     
    5977class ELEXDPC_Discount_Per_Country_Rule {
    6078
    61     const STATUS_ENABLE  = true;
     79
     80
     81    const STATUS_ENABLE = true;
    6282    const STATUS_DISABLE = false;
    6383
    6484    public $country_code;
    6585    public $discount;
     86    public $discount_type;
    6687    public $status;
    6788    public $country_name;
    6889    public $start_date;
    6990    public $end_date;
     91    public $label;
    7092
    7193
    72     public function __construct( $country_code, $discount, $status, $country_name, $start_date, $end_date ) {
     94    public function __construct( $country_code, $discount, $status, $country_name, $start_date, $end_date, $label = '', $discount_type = 'percentage' ) {
    7395        $this->country_code = $country_code;
    74         $this->discount     = $discount;
    75         $this->status       = $status;
     96        $this->discount = $discount;
     97        $this->discount_type = $discount_type;
     98        $this->status = $status;
    7699        $this->country_name = $country_name;
    77         $this->start_date   = $start_date;
    78         $this->end_date     = $end_date;
     100        $this->start_date = $start_date;
     101        $this->end_date = $end_date;
     102        $this->label = $label;
    79103
    80104    }
     
    87111            $data['country_name'],
    88112            $data['start_date'],
    89             $data['end_date']
     113            $data['end_date'],
     114            isset( $data['label'] ) ? $data['label'] : '',
     115            isset( $data['discount_type'] ) ? $data['discount_type'] : 'percentage'
    90116        );
    91117    }
    92118
    93119    public function is_enabled() {
    94         return self::STATUS_ENABLE === $this->status;
     120      return self::STATUS_ENABLE === $this->status;
    95121    }
    96122
    97123    public function disable() {
    98         $this->status = self::STATUS_DISABLE;
     124         $this->status = self::STATUS_DISABLE;
    99125    }
    100126    public function enable() {
    101         $this->status = self::STATUS_ENABLE;
     127      $this->status = self::STATUS_ENABLE;
    102128    }
    103129
     
    105131        return [
    106132            'country_code' => $this->country_code,
    107             'discount'     => $this->discount,
    108             'status'       => $this->status,
     133            'discount' => $this->discount,
     134            'discount_type' => $this->discount_type,
     135            'status' => $this->status,
    109136            'country_name' => $this->country_name,
    110             'start_date'   => $this->start_date,
    111             'end_date'     => $this->end_date,
     137            'start_date' => $this->start_date,
     138            'end_date' => $this->end_date,
     139            'label' => $this->label,
    112140        ];
    113141    }
  • elex-discount-per-country/tags/1.2.1/includes/elex-discount-per-country-admin-settings.php

    r3460057 r3492012  
    55}
    66
    7 require_once  WP_PLUGIN_DIR . '/woocommerce/includes/admin/settings/class-wc-settings-page.php' ;
    8 require_once  ABSPATH . 'wp-admin/includes/plugin.php' ;
    9 require_once  __DIR__ . '/class-discount-per-country.php';
     7require_once WP_PLUGIN_DIR . '/woocommerce/includes/admin/settings/class-wc-settings-page.php';
     8require_once ABSPATH . 'wp-admin/includes/plugin.php';
     9require_once __DIR__ . '/class-discount-per-country.php';
    1010
    1111class ELEXDPC_Admin_Settings extends WC_Settings_Page {
    1212
    1313
     14
     15
    1416    public function __construct() {
    15         //registering and loading scripts
    16            
    17         $this->id    = 'elex-discount-per-country';
     17         //registering and loading scripts
     18
     19        $this->id = 'elex-discount-per-country';
    1820        $this->label = __( 'ELEX Woo Discount Per Country', 'elex-discount-per-country' );
    1921        add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_settings_page' ), 99 );
     
    2325        add_action( 'woocommerce_cart_calculate_fees', array( $this, 'calculate_fees' ) );
    2426        add_action( 'admin_enqueue_scripts', array( $this, 'load_assets' ) );
    25        
     27
    2628    }
    2729
    2830    public function load_assets() {
    29         wp_nonce_field( 'elex_dpc_ajax_nonce', '_elex_dpc_ajax_nonce' );
     31         wp_nonce_field( 'elex_dpc_ajax_nonce', '_elex_dpc_ajax_nonce' );
    3032        wp_verify_nonce( 'elex_dpc_ajax_nonce', '_elex_dpc_ajax_nonce' );
    31          
     33
    3234        global $woocommerce;
    33         $woocommerce_version = function_exists( 'WC' ) ? WC()->version : $woocommerce->version; 
    34         $page                = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
    35         $tab                 = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
    36         $section             = isset( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : '';
     35        $woocommerce_version = function_exists( 'WC' ) ? WC()->version : $woocommerce->version;
     36        $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
     37        $tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
     38        $section = isset( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : '';
    3739        if ( 'wc-settings' === $page && 'elex-discount-per-country' === $tab && '' === $section ) {
    38                 wp_enqueue_style( 'woocommerce_admin_styles', $woocommerce->plugin_url() . '/assets/css/admin.css', array(), $woocommerce_version, false );
    39                 wp_register_style( 'elex-dpc-plugin-styles', ELEX_DISCOUNT_PER_COUNTRY_MAIN_URL_PATH . '/assets/css/dpc-plugin-styles.css', array(), $woocommerce_version, false );
    40                 wp_enqueue_style( 'elex-dpc-plugin-styles' );
    41                 wp_register_script( 'elex-dpc-custom-jquery', ELEX_DISCOUNT_PER_COUNTRY_MAIN_URL_PATH . '/assets/js/dpc-plugin-scripts.js', array( 'jquery' ), '1.0', false );
    42                 wp_enqueue_script( 'elex-dpc-custom-jquery' );
    43         } 
    44               $countries_available = array();
    45               $countries_obj      = new WC_Countries();
     40            wp_enqueue_style( 'woocommerce_admin_styles', $woocommerce->plugin_url() . '/assets/css/admin.css', array(), $woocommerce_version, false );
     41            wp_register_style( 'elex-dpc-plugin-styles', ELEX_DISCOUNT_PER_COUNTRY_MAIN_URL_PATH . '/assets/css/dpc-plugin-styles.css', array(), $woocommerce_version, false );
     42            wp_enqueue_style( 'elex-dpc-plugin-styles' );
     43            wp_register_script( 'elex-dpc-custom-jquery', ELEX_DISCOUNT_PER_COUNTRY_MAIN_URL_PATH . '/assets/js/dpc-plugin-scripts.js', array( 'jquery' ), '1.0', false );
     44            wp_enqueue_script( 'elex-dpc-custom-jquery' );
     45        }
     46        $countries_available = array();
     47        $countries_obj = new WC_Countries();
    4648        foreach ( $countries_obj->__get( 'countries' ) as $allowed_c ) {
    4749            $countries_available['country_id'] = $allowed_c;
    4850        }
    49                  
    50               $countries_available['tooltip']['nodiscount']           = __( 'No country discounts have been specified. Select a country from the drop-down to set up a discount.', 'elex-discount-per-country' );
    51               $countries_available['tooltip']['allcountriesselected'] = __( 'All available country have been selected', 'elex-discount-per-country' );
    52               $countries_available['tooltip']['inputalert']           = __( 'Please enter value between 0 to 100', 'elex-discount-per-country' );
    53               $countries_available['tooltip']['toggleon']             = __( 'Click here to enable the discount', 'elex-discount-per-country' );
    54               $countries_available['tooltip']['toggleoff']            = __( 'Click here to disable the discount', 'elex-discount-per-country' );
    55               $countries_available['tooltip']['inputtooltip']         = __( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' );
    56               $countries_available['tooltip']['remove']               = __( 'Click here to remove the discount.', 'elex-discount-per-country' );
    57               $countries_available['error_message']['nofieldsfilled'] = __( 'Please fill in the fields before adding a discount rule', 'elex-discount-per-country' );
    58          
    59               wp_localize_script( 'elex-dpc-custom-jquery', 'elexdpc_translations', $countries_available );
    60     }
    61        
     51
     52        $countries_available['tooltip']['nodiscount'] = __( 'No country discounts have been specified. Select a country from the drop-down to set up a discount.', 'elex-discount-per-country' );
     53        $countries_available['tooltip']['allcountriesselected'] = __( 'All available country have been selected', 'elex-discount-per-country' );
     54        $countries_available['tooltip']['inputalert'] = __( 'Please enter value between 0 to 100', 'elex-discount-per-country' );
     55        $countries_available['tooltip']['toggleon'] = __( 'Click here to enable the discount', 'elex-discount-per-country' );
     56        $countries_available['tooltip']['toggleoff'] = __( 'Click here to disable the discount', 'elex-discount-per-country' );
     57        $countries_available['tooltip']['inputtooltip'] = __( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' );
     58        $countries_available['tooltip']['remove'] = __( 'Click here to remove the discount.', 'elex-discount-per-country' );
     59        $countries_available['tooltip']['nodiscount-dpc'] = __( 'No Payments', 'elex-discount-per-country' );
     60        $countries_available['error_message']['nofieldsfilled'] = __( 'Please fill in the fields before adding a discount rule', 'elex-discount-per-country' );
     61
     62        wp_localize_script( 'elex-dpc-custom-jquery', 'elexdpc_translations', $countries_available );
     63    }
     64
    6265
    6366    public function get_sections() {
    64        
    6567        $sections = array(
    66             ''                    => __( 'General Settings', 'elex-discount-per-country' ),
     68            '' => __( 'General Settings', 'elex-discount-per-country' ),
    6769            'interested_products' => __( 'Related Products!', 'elex-discount-per-country' ),
    68            
     70
    6971        );
    7072        /**
     
    7779
    7880    public function output_sections() {
    79         global $current_section;
     81         global $current_section;
    8082        $sections = $this->get_sections();
    8183        if ( empty( $sections ) || 1 === count( $sections ) ) {
     
    9496        $settings = array();
    9597
    96                        
     98
    9799        if ( 'interested_products' === $current_section ) {
    98100            $settings = array();
     
    105107                    'type' => 'title',
    106108                    'desc' => __( 'Helps you configure and apply a discount on the Checkout page based on the shipping states/country selected by the customer.' ),
    107                     'id'   => 'elex-discount-per-country_title',
     109                    'id' => 'elex-discount-per-country_title',
    108110                ),
    109                 'section'       => array(
    110                     'name'        => __( 'Checkout discount label', 'elex-discount-per-country' ),
    111                     'type'        => 'text',
    112                     'placeholder' => __( 'Enter custom discount label', 'elex-discount-per-country' ),
    113                     'desc_tip'    => true,
    114                     'css'         => 'width:300px',
    115                     'desc'        => __( 'Enter the text to be displayed on checkout. The default text is <strong> Discount per country</strong>.', 'elex-discount-per-country' ),
    116                     'id'          => 'elex-discount-per-country_label',
     111
     112                'section_end' => array(
     113                    'type' => 'sectionend',
     114                    'id' => 'elex-discount-per-country_end',
    117115                ),
    118        
    119                 'section_end'   => array(
    120                     'type' => 'sectionend',
    121                     'id'   => 'elex-discount-per-country_end',
    122                 ),
    123            
    124                
    125                
    126                                
     116
     117
     118
     119
    127120            );
    128121        }
     
    135128
    136129    }
    137    
     130
    138131
    139132    public function output() {
    140         global $current_section;
    141        
     133      global $current_section;
     134
    142135
    143136        if ( 'interested_products' === $current_section ) {
     
    145138            include_once __DIR__ . '/market.php';
    146139        } else {
    147        
     140
    148141
    149142            $countries_obj = new WC_Countries();
    150             $countries     = $countries_obj->__get( 'countries' );
    151             $settings      = $this->get_settings();
     143            $countries = $countries_obj->__get( 'countries' );
     144            $settings = $this->get_settings();
    152145            WC_Admin_Settings::output_fields( $settings );
    153                        
     146
    154147            $countries_available = array();
    155148            foreach ( $countries_obj->__get( 'countries' ) as $allowed_c ) {
     
    165158        // Prepare the data
    166159        // save it
    167         $nonce  = isset( $_POST['nounce_verify'] ) ? sanitize_text_field( wp_unslash( $_POST['nounce_verify'] ) ) : '';
     160        $nonce = isset( $_POST['nounce_verify'] ) ? sanitize_text_field( wp_unslash( $_POST['nounce_verify'] ) ) : '';
    168161        $verify = wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nounce_verify'] ) ), 'form_data' );
    169162
     
    174167
    175168        $countries_obj = new WC_Countries();
    176         $countries     = $countries_obj->__get( 'countries' );
     169        $countries = $countries_obj->__get( 'countries' );
    177170        global $current_section;
    178171        $settings = $this->get_settings();
    179172        WC_Admin_Settings::save_fields( $settings );
    180         $repo        = new ELEXDPC_Discount_Per_Country_Model();
    181         $items_count = isset( $_POST['elex_discount_per_country_options'] ) ? count( $_POST['elex_discount_per_country_options'] ) : 0;
    182         $i           = -1;
    183         $items_added = 0;
    184            
    185         while ( $items_added < $items_count ) {
    186             $i++;
    187             if ( ! isset( $_POST['elex_discount_per_country_options'][ $i ] ) ) {
    188                 continue;
    189             }
    190             $country_codes = isset( $_POST['elex_discount_per_country_options'][ $i ]['country_code'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['country_code'] ) ) : '';
    191             $country_codes = explode( ',', $country_codes );
    192            
     173        $repo = new ELEXDPC_Discount_Per_Country_Model();
     174        // Use filter_input to retrieve POSTed array safely when available, fall back to wp_unslash.
     175        $raw_options = filter_input( INPUT_POST, 'elex_discount_per_country_options', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
     176        if ( null === $raw_options || false === $raw_options ) {
     177            // Avoid direct $_POST usage to satisfy PHPCS; fall back to empty array.
     178            $raw_options = array();
     179        }
     180
     181        // Recursively sanitize the incoming options to satisfy PHPCS/WPCS checks.
     182        $sanitize_recursive = function ( $value ) use ( &$sanitize_recursive ) {
     183            if ( is_array( $value ) ) {
     184                return array_map( $sanitize_recursive, $value );
     185            }
     186            return is_string( $value ) ? sanitize_text_field( $value ) : $value;
     187        };
     188
     189        $options = is_array( $raw_options ) ? $sanitize_recursive( $raw_options ) : array();
     190
     191        foreach ( $options as $option ) {
     192            $post_country_codes = isset( $option['country_code'] ) ? $option['country_code'] : '';
     193
     194            if ( is_array( $post_country_codes ) ) {
     195                $country_codes = array_map( 'sanitize_text_field', $post_country_codes );
     196            } else {
     197                $country_codes = explode( ',', sanitize_text_field( $post_country_codes ) );
     198            }
     199
    193200            foreach ( $country_codes as $country_code ) {
    194                 if ( ! $country_code ) {
     201                if ( empty( $country_code ) ) {
    195202                    continue;
    196203                }
    197204                $discount_per_country = array();
    198                 $state_code           = strpos( $country_code, ':' );
    199                 if ( false === $state_code ) {
    200                     $state_code = 0;
     205                $state_code_pos = strpos( $country_code, ':' );
     206
     207                if ( false === $state_code_pos ) {
     208                    $discount_per_country['country_code'] = $country_code;
     209                    $discount_per_country['status'] = isset( $option['status'] ) ? ELEXDPC_Discount_Per_Country_Rule::STATUS_ENABLE : ELEXDPC_Discount_Per_Country_Rule::STATUS_DISABLE;
     210
     211                    $discount_per_country['country_name'] = isset( $countries[ $country_code ] ) ? $countries[ $country_code ] : $country_code;
     212                    $discount_per_country['discount'] = isset( $option['discount'] ) ? sanitize_text_field( $option['discount'] ) : '';
     213                    $discount_per_country['discount_type'] = isset( $option['discount_type'] ) ? sanitize_text_field( $option['discount_type'] ) : 'percentage';
     214                    $discount_per_country['start_date'] = isset( $option['start_date'] ) ? sanitize_text_field( $option['start_date'] ) : '';
     215                    $discount_per_country['end_date'] = isset( $option['end_date'] ) ? sanitize_text_field( $option['end_date'] ) : '';
     216                    $discount_per_country['label'] = isset( $option['label'] ) ? sanitize_text_field( $option['label'] ) : '';
     217
     218                    $repo->add( ELEXDPC_Discount_Per_Country_Rule::build( $discount_per_country ) );
     219
    201220                } else {
    202                    $state_code = substr( $country_code, strpos( $country_code, ':' ) + 1 );
     221                    $state_code = substr( $country_code, $state_code_pos + 1 );
     222                    $countrycode = substr( $country_code, 0, $state_code_pos );
     223                    $states = WC()->countries->get_states( $countrycode );
     224                    $statename = isset( $states[ $state_code ] ) ? $states[ $state_code ] : $state_code;
     225
     226                    $discount_per_country['country_code'] = $countrycode . ':' . $state_code;
     227                    $discount_per_country['status'] = isset( $option['status'] ) ? ELEXDPC_Discount_Per_Country_Rule::STATUS_ENABLE : ELEXDPC_Discount_Per_Country_Rule::STATUS_DISABLE;
     228
     229                    $discount_per_country['country_name'] = $statename . ', ' . ( isset( $countries[ $countrycode ] ) ? $countries[ $countrycode ] : $countrycode );
     230                    $discount_per_country['discount'] = isset( $option['discount'] ) ? sanitize_text_field( $option['discount'] ) : '';
     231                    $discount_per_country['discount_type'] = isset( $option['discount_type'] ) ? sanitize_text_field( $option['discount_type'] ) : 'percentage';
     232                    $discount_per_country['start_date'] = isset( $option['start_date'] ) ? sanitize_text_field( $option['start_date'] ) : '';
     233                    $discount_per_country['end_date'] = isset( $option['end_date'] ) ? sanitize_text_field( $option['end_date'] ) : '';
     234                    $discount_per_country['label'] = isset( $option['label'] ) ? sanitize_text_field( $option['label'] ) : '';
     235
     236                    $repo->add( ELEXDPC_Discount_Per_Country_Rule::build( $discount_per_country ) );
    203237                }
    204 
    205                 if ( 0 !== $state_code ) {
    206                     $countrycode                          = substr( $country_code, 0, strpos( $country_code, ':' ) );
    207                     $states                               = WC()->countries->get_states( $countrycode );
    208                     $statename                            = $states[ $state_code ];
    209                     $discount_per_country['country_code'] = $countrycode . ':' . $state_code;
    210                     $discount_per_country['status']       = isset( $_POST['elex_discount_per_country_options'][ $i ]['status'] ) ? ELEXDPC_Discount_Per_Country_Rule::STATUS_ENABLE : ELEXDPC_Discount_Per_Country_Rule::STATUS_DISABLE;
    211                    
    212                     $discount_per_country['country_name'] = $statename . ',' . $countries[ $countrycode ];
    213                     $discount_per_country['discount']     = isset( $_POST['elex_discount_per_country_options'][ $i ]['discount'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['discount'] ) ) : '';
    214                     $discount_per_country['start_date']   = isset( $_POST['elex_discount_per_country_options'][ $i ]['start_date'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['start_date'] ) ) : '';
    215                     $discount_per_country['end_date']     = isset( $_POST['elex_discount_per_country_options'][ $i ]['end_date'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['end_date'] ) ) : '';
    216                    
    217 
    218                     $repo->add( ELEXDPC_Discount_Per_Country_Rule::build( $discount_per_country ) );
    219 
    220                 } else {
    221                     $discount_per_country['country_code'] = $country_code;
    222                     $discount_per_country['status']       = isset( $_POST['elex_discount_per_country_options'][ $i ]['status'] ) ? ELEXDPC_Discount_Per_Country_Rule::STATUS_ENABLE : ELEXDPC_Discount_Per_Country_Rule::STATUS_DISABLE;
    223                    
    224                     $discount_per_country['country_name'] = $countries[ $country_code ];
    225                     $discount_per_country['discount']     = isset( $_POST['elex_discount_per_country_options'][ $i ]['discount'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['discount'] ) ) : '';
    226                     $discount_per_country['start_date']   = isset( $_POST['elex_discount_per_country_options'][ $i ]['start_date'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['start_date'] ) ) : '';
    227                     $discount_per_country['end_date']     = isset( $_POST['elex_discount_per_country_options'][ $i ]['end_date'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['end_date'] ) ) : '';
    228                     $repo->add( ELEXDPC_Discount_Per_Country_Rule::build( $discount_per_country ) );
    229 
    230                 } 
    231             }
    232             $items_added++;
    233 
    234         }                   
     238            }
     239        }
    235240        $repo->save();
    236            
    237        
     241
     242
    238243        if ( $current_section ) {
    239244            /**
     
    254259        }
    255260
    256         $order_date                  = strtotime( wp_date( 'd-m-Y\TH:i' ) );
    257         $PWD_Selected_Country_id     = WC()->customer->get_shipping_country();
    258         $shipping_state              = WC()->customer->get_shipping_state();
     261        $order_date = strtotime( wp_date( 'd-m-Y\TH:i' ) );
     262        $PWD_Selected_Country_id = WC()->customer->get_shipping_country();
     263        $shipping_state = WC()->customer->get_shipping_state();
    259264        $selected_country_with_state = $PWD_Selected_Country_id . ':' . $shipping_state;
     265
    260266        if ( empty( $PWD_Selected_Country_id ) ) {
    261267            return 0;
     
    264270        $repo = new ELEXDPC_Discount_Per_Country_Model();
    265271        $repo->build();
    266         $PWD_subtotal      = $PWD_cart->subtotal;
    267         $PWD_label_default = 'Discount per country';
    268 
    269         $PWD_label            = ! empty( get_option( 'elex-discount-per-country_label' ) ) ? get_option( 'elex-discount-per-country_label' ) : $PWD_label_default;
     272        $PWD_subtotal = $PWD_cart->subtotal;
     273
    270274        $discount_per_country = $repo->find( $PWD_Selected_Country_id );
    271         $country_with_state   = $repo->find( $selected_country_with_state );
    272 
    273         if ( $discount_per_country ) { 
    274            
    275             if ( ( $discount_per_country && $discount_per_country->is_enabled() &&
    276             $order_date >= strtotime( $discount_per_country->start_date ) &&
    277             $order_date <= strtotime( $discount_per_country->end_date ) ) ||
    278             ( $discount_per_country && $discount_per_country->is_enabled() &&
    279              '' === $discount_per_country->start_date && '' === $discount_per_country->end_date ) ||
    280              ( $discount_per_country && $discount_per_country->is_enabled() &&
    281               ( '' === $discount_per_country->start_date && $order_date <= strtotime( $discount_per_country->end_date ) ) ||
    282              ( '' === $discount_per_country->end_date && $order_date >= strtotime( $discount_per_country->start_date ) ) ) ) {
    283 
    284                 if ( $country_with_state && $country_with_state->is_enabled() ) {
    285                     if ( ( $country_with_state && $country_with_state->is_enabled() &&
    286                     $order_date >= strtotime( $country_with_state->start_date ) &&
    287                     $order_date <= strtotime( $country_with_state->end_date ) ) ||
    288                     ( $country_with_state && $country_with_state->is_enabled() &&
    289                  '' === $country_with_state->start_date && '' === $country_with_state->end_date ) ||
    290                  ( $country_with_state && $country_with_state->is_enabled() &&
    291                   ( '' === $country_with_state->start_date && $order_date <= strtotime( $country_with_state->end_date ) ) ||
    292                  ( '' === $country_with_state->end_date && $order_date >= strtotime( $country_with_state->start_date ) ) ) ) {
    293                         $PWD_discount = ( $country_with_state->discount ) * $PWD_subtotal / 100;
    294                         $PWD_cart -> add_fee( $PWD_label, -$PWD_discount );
    295    
    296                     } else {
    297                         $PWD_discount = ( $discount_per_country->discount ) * $PWD_subtotal / 100;
    298                         $PWD_cart -> add_fee( $PWD_label, -$PWD_discount );
    299                     }               
    300                 } else {
    301 
    302                     $PWD_discount = ( $discount_per_country->discount ) * $PWD_subtotal / 100;
    303                     $PWD_cart->add_fee( $PWD_label, -$PWD_discount );
    304                 }   
    305             }       
    306         }
    307 
    308         if ( $country_with_state && $country_with_state->is_enabled() ) {
    309             if ( ( $country_with_state && $country_with_state->is_enabled() &&
    310             $order_date >= strtotime( $country_with_state->start_date ) &&
    311             $order_date <= strtotime( $country_with_state->end_date ) ) ||
    312             ( $country_with_state && $country_with_state->is_enabled() &&
    313              '' === $country_with_state->start_date && '' === $country_with_state->end_date ) ||
    314              ( $country_with_state && $country_with_state->is_enabled() &&
    315               ( '' === $country_with_state->start_date && $order_date <= strtotime( $country_with_state->end_date ) ) ||
    316              ( '' === $country_with_state->end_date && $order_date >= strtotime( $country_with_state->start_date ) ) ) ) {
    317                         $PWD_discount = ( $country_with_state->discount ) * $PWD_subtotal / 100;
    318                         $PWD_cart -> add_fee( __( $PWD_label, 'elex-discount-per-country' ), -$PWD_discount );
    319    
    320             }       
    321         }
    322     }
     275        $country_with_state = $repo->find( $selected_country_with_state );
     276
     277        $rule_to_apply = null;
     278
     279        $is_valid_rule = function ( $rule, $order_date ) {
     280            if ( ! $rule || ! $rule->is_enabled() ) {
     281                return false;
     282            }
     283            $start = strtotime( $rule->start_date );
     284            $end = strtotime( $rule->end_date );
     285
     286            if ( ! empty( $rule->start_date ) && ! empty( $rule->end_date ) ) {
     287                return ( $order_date >= $start && $order_date <= $end );
     288            } elseif ( ! empty( $rule->start_date ) ) {
     289                return ( $order_date >= $start );
     290            } elseif ( ! empty( $rule->end_date ) ) {
     291                return ( $order_date <= $end );
     292            }
     293            return true;
     294        };
     295
     296        // Prioritize country+state specific rule over a general country rule
     297        if ( $is_valid_rule( $country_with_state, $order_date ) ) {
     298            $rule_to_apply = $country_with_state;
     299        } elseif ( $is_valid_rule( $discount_per_country, $order_date ) ) {
     300            $rule_to_apply = $discount_per_country;
     301        }
     302
     303        if ( $rule_to_apply ) {
     304            // build() already resolved the per-row label → old global label → ''
     305            // Just use it directly; fall back to 'Discount per country' if still empty.
     306            $label_text = trim( $rule_to_apply->label );
     307            if ( '' === $label_text ) {
     308                $label_text = __( 'Discount per country', 'elex-discount-per-country' );
     309            }
     310            $label = $label_text;
     311
     312            if ( 'fixed' === $rule_to_apply->discount_type ) {
     313                $PWD_discount = floatval( $rule_to_apply->discount );
     314            } else {
     315                $PWD_discount = ( floatval( $rule_to_apply->discount ) * $PWD_subtotal ) / 100;
     316            }
     317
     318            // Ensure discount doesn't exceed the subtotal negatively
     319            if ( $PWD_subtotal < $PWD_discount ) {
     320                $PWD_discount = $PWD_subtotal;
     321            }
     322
     323            // Yoda conditions preferred by WPCS for literal comparisons.
     324            if ( 0 < $PWD_discount ) {
     325                $PWD_cart->add_fee( __( $label, 'elex-discount-per-country' ), -$PWD_discount );
     326            }
     327        }
     328    }
    323329
    324330    public function add_action_links( $links ) {
     
    329335        return array_merge( $plugin_links, $links );
    330336    }
    331    
     337
    332338}
    333339
  • elex-discount-per-country/tags/1.2.1/includes/form-settings-template-dpc.php

    r3460057 r3492012  
    77 */
    88
    9 require_once  __DIR__ . '/class-discount-per-country.php';
     9require_once __DIR__ . '/class-discount-per-country.php';
    1010$repo = new ELEXDPC_Discount_Per_Country_Model();
    1111$repo->build();
     
    1818global $woocommerce;
    1919
    20 $allowed_countries   = WC()->countries->get_shipping_countries();
     20$allowed_countries = WC()->countries->get_shipping_countries();
    2121$shipping_continents = WC()->countries->get_shipping_continents();
    22 $zone                = new WC_Shipping_Zone();
    23 $locations           = array();
    24 $postcodes           = array();
     22$zone = new WC_Shipping_Zone();
     23$locations = array();
     24$postcodes = array();
    2525
    2626foreach ( $zone->get_zone_locations() as $location ) {
     
    3333?>
    3434
    35 <tr valign="top" >
     35<tr valign="top">
    3636    <td class="forminp" colspan="3" style="padding-left:0px">
    3737        <table class="fields_adjustment_dpc widefat" id="elex_discount_per_country_options">
    38         <input type="hidden" name="nounce_verify" value="<?php echo esc_attr( $nonce ); ?>">
     38            <input type="hidden" name="nounce_verify" value="<?php echo esc_attr( $nonce ); ?>">
    3939            <thead>
    40                 <th class="table_header" >&nbsp;<i class="fas fa-toggle-off"></i></th>
    41                 <th class="table_header"  ><?php esc_html_e( 'Shipping State/Country', 'elex-discount-per-country' ); ?></th>
    42                 <th class="table_header" ><?php esc_html_e( 'Discount(%)', 'elex-discount-per-country' ); ?></th>
    43                 <th class="table_header" ><?php esc_html_e( 'From date', 'elex-discount-per-country' ); ?></th>
    44                 <th class="table_header" ><?php esc_html_e( 'To date', 'elex-discount-per-country' ); ?></th>
    45                 <th class="table_header" ><?php esc_html_e( 'Status', 'elex-discount-per-country' ); ?></th>
    46                 <th class="table_header_remove" ><?php esc_html_e( 'Actions', 'elex-discount-per-country' ); ?></th>
     40                <th class="table_header table_col_1_dpc">&nbsp;<i class="fas fa-toggle-off"></i></th>
     41                <th class="table_header table_col_2_dpc">
     42                    <?php esc_html_e( 'Shipping State/Country', 'elex-discount-per-country' ); ?>
     43                </th>
     44                <th class="table_header table_col_type_dpc">
     45                    <?php esc_html_e( 'Discount type', 'elex-discount-per-country' ); ?>
     46                </th>
     47                <th class="table_header table_col_3_dpc">
     48                    <?php esc_html_e( 'Percentage / fixed amount', 'elex-discount-per-country' ); ?>
     49                </th>
     50                <th class="table_header table_col_label_dpc">
     51                    <?php esc_html_e( 'Discount label', 'elex-discount-per-country' ); ?>
     52                </th>
     53                <th class="table_header table_col_5_dpc">
     54                    <?php esc_html_e( 'From date', 'elex-discount-per-country' ); ?>
     55                </th>
     56                <th class="table_header table_col_6_dpc"><?php esc_html_e( 'To date', 'elex-discount-per-country' ); ?>
     57                </th>
     58                <th class="table_header table_col_4_dpc"><?php esc_html_e( 'Enable', 'elex-discount-per-country' ); ?>
     59                </th>
     60                <th class="table_header_remove remove_icon_discount_dpc">
     61                    <?php esc_html_e( 'Remove', 'elex-discount-per-country' ); ?>
     62                </th>
    4763            </thead>
    4864            <tbody id='elex_dpc_table_body'>
     
    5066
    5167                foreach ( $repo->get_items() as $key => $discount_per_country ) {
    52                        
     68
    5369                    ?>
    54                         <tr id='<?php echo esc_attr( $discount_per_country->country_code ); ?>' class='<?php echo esc_attr( $discount_per_country->country_name ); ?>'>
    55                         <td  class='table_col_1_dpc' ></td>
    56                         <td  class='table_col_2_dpc'>
    57                             <input type='hidden'  name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][country_code]' value='<?php echo esc_attr( $discount_per_country->country_code ); ?>' />
    58                             <input type='hidden' class='order' name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][country_name]' value='<?php echo esc_attr( $discount_per_country->country_name ); ?>' />
    59                            
    60                             <span class="bold_span" ><?php echo esc_html( $discount_per_country->country_name ); ?></span>
    61                         </td>
    62                         <td class='table_col_3_dpc' title='<?php esc_html_e( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' ); ?>' >
    63                             <input type='number'  min='0' max='100' step="any" class='order' name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][discount]' value='<?php echo esc_attr( $discount_per_country->discount ); ?>' required>
    64                         </td>
    65                         <td class='table_col_5_dpc'    title="<?php esc_html_e( 'Start Date from which discount will be applied,Leave blank if you do not restrict based on  date', 'elex-discount-per-country' ); ?>">
    66                         <input type='datetime-local'  class='elex_discount_per_country_from_date' name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][start_date]' value='<?php echo esc_attr( $discount_per_country->start_date ); ?>' >
    67 
    68                         </td>
    69                         <td class='table_col_6_dpc'  title="<?php esc_html_e( 'Discount will not be applied after this date,Leave blank if you do not restrict based on date', 'elex-discount-per-country' ); ?>">
    70                         <input type='datetime-local'  class='elex_discount_per_country_to_date' name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][end_date]' value='<?php echo esc_attr( $discount_per_country->end_date ); ?>' >
    71 
    72                         </td>
    73            
    74                             <td class='table_col_4_dpc' >
    75                                 <label title='<?php esc_html_e( 'Click here to disable the discount.', 'elex-discount-per-country' ); ?>' class='switch'>
    76                                    
    77                                     <input
    78                                         type='checkbox'
    79                                         class='checkbox_click'
    80                                         <?php echo esc_html( $discount_per_country->is_enabled() ? 'checked' : '' ); ?>
    81                                         name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][status]'
    82                                         value= 'yes' />
    83                                     <span class='slider round'></span>
    84                                 </label>
    85                             </td>
    86 
    87                             <td class='remove_icon_discount_dpc' title='<?php esc_html_e( 'Click here to remove the discount.', 'elex-discount-per-country' ); ?>'></td>
    88                         </tr>
    89                         <?php
     70                    <tr id='<?php echo esc_attr( $discount_per_country->country_code ); ?>'
     71                        class='<?php echo esc_attr( $discount_per_country->country_name ); ?>'>
     72                        <td class='table_col_1_dpc'></td>
     73                        <td class='table_col_2_dpc'>
     74                            <input type='hidden'
     75                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][country_code]'
     76                                value='<?php echo esc_attr( $discount_per_country->country_code ); ?>' />
     77                            <input type='hidden' class='order'
     78                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][country_name]'
     79                                value='<?php echo esc_attr( $discount_per_country->country_name ); ?>' />
     80
     81                            <span class="bold_span"><?php echo esc_html( $discount_per_country->country_name ); ?></span>
     82                        </td>
     83                        <td class='table_col_type_dpc'>
     84                            <select
     85                                name="elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][discount_type]">
     86                                <option value="percentage" <?php selected( $discount_per_country->discount_type, 'percentage' ); ?>><?php esc_html_e( 'Percentage', 'elex-discount-per-country' ); ?>
     87                                </option>
     88                                <option value="fixed" <?php selected( $discount_per_country->discount_type, 'fixed' ); ?>>
     89                                    <?php esc_html_e( 'Fixed Amount', 'elex-discount-per-country' ); ?>
     90                                </option>
     91                            </select>
     92                        </td>
     93                        <td class='table_col_3_dpc'
     94                            title='<?php esc_html_e( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' ); ?>'>
     95                            <input type='number' min='0' max='100' step="any" class='order dpc-discount-input'
     96                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][discount]'
     97                                value='<?php echo esc_attr( $discount_per_country->discount ); ?>' required>
     98                        </td>
     99                        <td class='table_col_label_dpc'>
     100                            <input type='text'
     101                                placeholder="<?php esc_html_e( 'Discount label', 'elex-discount-per-country' ); ?>"
     102                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][label]'
     103                                value='<?php echo esc_attr( $discount_per_country->label ); ?>'>
     104                        </td>
     105                        <td class='table_col_5_dpc'
     106                            title="<?php esc_html_e( 'Start Date from which discount will be applied,Leave blank if you do not restrict based on  date', 'elex-discount-per-country' ); ?>">
     107                            <input type='datetime-local' class='elex_discount_per_country_from_date'
     108                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][start_date]'
     109                                value='<?php echo esc_attr( $discount_per_country->start_date ); ?>'>
     110
     111                        </td>
     112                        <td class='table_col_6_dpc'
     113                            title="<?php esc_html_e( 'Discount will not be applied after this date,Leave blank if you do not restrict based on date', 'elex-discount-per-country' ); ?>">
     114                            <input type='datetime-local' class='elex_discount_per_country_to_date'
     115                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][end_date]'
     116                                value='<?php echo esc_attr( $discount_per_country->end_date ); ?>'>
     117
     118                        </td>
     119
     120                        <td class='table_col_4_dpc'>
     121                            <label
     122                                title='<?php esc_html_e( 'Click here to disable the discount.', 'elex-discount-per-country' ); ?>'
     123                                class='switch'>
     124
     125                                <input type='checkbox' class='checkbox_click' <?php echo esc_html( $discount_per_country->is_enabled() ? 'checked' : '' ); ?>
     126                                    name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][status]'
     127                                    value='yes' />
     128                                <span class='slider round'></span>
     129                            </label>
     130                        </td>
     131
     132                        <td class='remove_icon_discount_dpc'
     133                            title='<?php esc_html_e( 'Click here to remove the discount.', 'elex-discount-per-country' ); ?>'>
     134                            <span class="remove-btn-circle"><i class="fas fa-minus"></i></span>
     135                        </td>
     136                    </tr>
     137                    <?php
    90138                }
    91            
     139
    92140                if ( empty( $repo->get_items() ) ) {
    93141                    ?>
    94142
    95143                    <tr id='nodiscount-dpc' class='nodiscount-dpc'>
    96                     <td class='table_col_1_dpc'></td>
    97                     <td class='table_col_2_dpc'>
    98                         <span class='wc-country-name' id='no_discount_available_dpc'><?php esc_html_e( 'No  discounts have been specified. Select a country from the drop-down to set up a discount.', 'elex-discount-per-country' ); ?></span>
    99                     </td>
    100                     <td class='table_col_3_dpc'></td>
    101                     <td class='table_col_5_dpc'></td>
    102                     <td class='table_col_6_dpc'></td>
    103                     <td class='table_col_4_dpc'></td>
    104 
     144                        <td colspan="9" style="text-align: center; padding: 24px 0;">
     145                            <span
     146                                id='no_discount_available_dpc'><?php esc_html_e( 'No  discounts have been specified. Select a country from the drop-down to set up a discount.', 'elex-discount-per-country' ); ?></span>
     147                            <div class="no-payments-btn">
     148                                <script>document.write(elexdpc_translations['tooltip']['nodiscount-dpc']);</script>
     149                            </div>
     150                        </td>
    105151                    </tr>
    106 
    107152                    <?php
    108153                }
    109            
    110 
    111154                ?>
    112 
    113155            </tbody>
    114             <br><br>
    115             <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
    116             <tr  class="table_input_raw_dpc">
    117            
    118                 <td></td>
    119                 <td>
    120                 <select title='<?php esc_html_e( 'Select zone for which you want to apply discount', 'elex-discount-per-country' ); ?>'  multiple="multiple" data-attribute="zone_locations" id="zone_locations" name="zone_locations" data-placeholder="<?php esc_attr_e( 'Select region', 'elex-discount-per-country' ); ?>" class="wc-shipping-zone-region-select chosen_select">
    121                         <?php
    122                    
    123                         foreach ( $shipping_continents as $continent_code => $continent ) {
    124 
    125                             $countries = array_intersect( array_keys( $allowed_countries ), $continent['countries'] );
    126 
    127                             foreach ( $countries as $country_code ) {
    128                             $flag = 1;
    129 
    130                             $discount_per_country = $repo->find( $country_code );
     156            <tfoot>
     157                <tr>
     158                    <td colspan="9" style="text-align: center; padding: 16px 0;">
     159                        <button type="button" id="elex_dpc_add_field_discount" class="elex-add-new-btn">
     160                            <span class="icon-circle">+</span>
     161                            <span
     162                                class="btn-text"><?php esc_html_e( 'Add New Discount', 'elex-discount-per-country' ); ?></span>
     163                        </button>
     164                    </td>
     165                </tr>
     166            </tfoot>
     167        </table>
     168
     169        <div id="elex_dpc_add_new_discount_template" style="display: none;">
     170            <select
     171                title='<?php esc_html_e( 'Select zone for which you want to apply discount', 'elex-discount-per-country' ); ?>'
     172                multiple="multiple" data-attribute="zone_locations" id="zone_locations_template"
     173                name="zone_locations_template"
     174                data-placeholder="<?php esc_attr_e( 'Select region', 'elex-discount-per-country' ); ?>"
     175                class="wc-shipping-zone-region-select" style="width: 100%;">
     176                <?php
     177
     178                foreach ( $shipping_continents as $continent_code => $continent ) {
     179
     180                    $countries = array_intersect( array_keys( $allowed_countries ), $continent['countries'] );
     181
     182                    foreach ( $countries as $country_code ) {
     183                        $flag = 1;
     184
     185                        $discount_per_country = $repo->find( $country_code );
     186                        if ( $discount_per_country ) {
     187                            $flag = 0;
     188
     189                        }
     190                        if ( 1 === $flag ) {
     191                            echo '<option  value="' . esc_attr( $country_code ) . '"' . wc_selected( "country:$country_code", $locations ) . '>' . esc_html( '&nbsp;&nbsp; ' . $allowed_countries[ $country_code ] ) . '</option>';
     192                        }
     193                        $states = WC()->countries->get_states( $country_code );
     194
     195                        if ( $states ) {
     196                            foreach ( $states as $state_code => $state_name ) {
     197                                $country_with_state = $country_code . ':' . $state_code;
     198                                $discount_per_country = $repo->find( $country_with_state );
     199                                $flag = 1;
    131200                                if ( $discount_per_country ) {
    132201                                    $flag = 0;
    133                                    
    134202                                }
    135203                                if ( 1 === $flag ) {
    136                                     echo '<option  value="' . esc_attr( $country_code ) . '"' . wc_selected( "country:$country_code", $locations ) . '>' . esc_html( '&nbsp;&nbsp; ' . $allowed_countries[ $country_code ] ) . '</option>';
     204                                    echo '<option value="' . esc_attr( $country_code . ':' . $state_code ) . '"' . wc_selected( "state:$country_code:$state_code", $locations ) . '>' . esc_html( '&nbsp;&nbsp;&nbsp;&nbsp; ' . $state_name . ', ' . $allowed_countries[ $country_code ] ) . '</option>';
     205
    137206                                }
    138                                     $states = WC()->countries->get_states( $country_code );
    139 
    140                                 if ( $states ) {
    141                                     foreach ( $states as $state_code => $state_name ) {
    142                                         $country_with_state   = $country_code . ':' . $state_code;
    143                                         $discount_per_country = $repo->find( $country_with_state );
    144                                         $flag                 = 1;
    145                                         if ( $discount_per_country ) {
    146                                             $flag = 0;
    147                                         }
    148                                         if ( 1 === $flag ) {
    149                                             echo '<option value="' . esc_attr( $country_code . ':' . $state_code ) . '"' . wc_selected( "state:$country_code:$state_code", $locations ) . '>' . esc_html( '&nbsp;&nbsp;&nbsp;&nbsp; ' . $state_name . ', ' . $allowed_countries[ $country_code ] ) . '</option>';
    150 
    151                                         }                                       
    152                                     }
    153                                 }                           
    154207                            }
    155208                        }
    156                         ?>
    157                     </select>
    158 
    159                 </td>
    160                
    161                 <td>
    162                    
    163                     <input type='number' class='eraq_input_label' title="<?php esc_html_e( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' ); ?>" id="elex_discount_per_country_options_input_value"  value="0" min="0" max="100" step="any" >
    164                 </td>
    165                 <td>
    166                 <input type='datetime-local' value="" class='elex_discount_per_country_from_date' title="<?php esc_html_e( 'Start Date from which discount will be applied,Leave blank if you do not restrict based on  date', 'elex-discount-per-country' ); ?>" id="elex_discount_per_country_start_date"  min="<?php echo esc_attr( wp_date( 'Y-m-d\TH:i' ) ); ?>" >
    167                    
    168                 </td>
    169                 <td>
    170                 <input type='datetime-local' value="" class='elex_discount_per_country_to_date' title="<?php esc_html_e( 'Discount will not be applied after this date,Leave blank if you do not restrict based on date', 'elex-discount-per-country' ); ?>" id="elex_discount_per_country_end_date"  min="<?php echo esc_attr( wp_date( 'Y-m-d\TH:i' ) ); ?>"   >
    171 
    172                 </td>
    173                 <td>
    174                     <label class="switch" title='<?php esc_html_e( 'Click to enable or disable the discount', 'elex-discount-per-country' ); ?>'>
    175                       <input id="elex_discount_per_country_options_enabled" type="checkbox" checked>
    176                       <span class="slider round"></span>
    177                     </label>
    178                 </td>
    179                
    180                 <td>
    181                     <button name="submit" type="button" class="elex-dpc-btn-primary button-primary" title="<?php esc_html_e( 'Click here to add more discount.', 'elex-discount-per-country' ); ?>"  id="elex_dpc_add_field_discount"  >
    182                         <?php esc_html_e( 'Add', 'elex-discount-per-country' ); ?>
    183                     </button>
    184                 </td>
    185             </tr>
    186            
    187         </table>
    188        
     209                    }
     210                }
     211                ?>
     212            </select>
     213            <select id="elex_discount_per_country_discount_type_template" class="dpc-discount-type-select"
     214                name="elex_discount_per_country_discount_type_template">
     215                <option value="percentage">
     216                    <?php esc_html_e( 'Percentage', 'elex-discount-per-country' ); ?>
     217                </option>
     218                <option value="fixed">
     219                    <?php esc_html_e( 'Fixed Amount', 'elex-discount-per-country' ); ?>
     220                </option>
     221            </select>
     222            <input type="number" step="any" min="0" id="elex_discount_per_country_options_input_value_template"
     223                class="dpc-discount-input" name="elex_discount_per_country_options_input_value_template" value="0">
     224            <input type="text" id="elex_discount_per_country_label_template"
     225                placeholder="<?php esc_html_e( 'Discount label', 'elex-discount-per-country' ); ?>"
     226                name="elex_discount_per_country_label_template" value="">
     227            <input type='datetime-local' value="" class='elex_discount_per_country_from_date'
     228                title="<?php esc_html_e( 'Start Date from which discount will be applied,Leave blank if you do not restrict based on  date', 'elex-discount-per-country' ); ?>"
     229                id="elex_discount_per_country_start_date_template"
     230                min="<?php echo esc_attr( wp_date( 'Y-m-d\TH:i' ) ); ?>">
     231            <input type='datetime-local' value="" class='elex_discount_per_country_to_date'
     232                title="<?php esc_html_e( 'Discount will not be applied after this date,Leave blank if you do not restrict based on date', 'elex-discount-per-country' ); ?>"
     233                id="elex_discount_per_country_end_date_template"
     234                min="<?php echo esc_attr( wp_date( 'Y-m-d\TH:i' ) ); ?>">
     235            <label class="switch"
     236                title='<?php esc_html_e( 'Click to enable or disable the discount', 'elex-discount-per-country' ); ?>'>
     237                <input id="elex_discount_per_country_options_enabled_template" type="checkbox" checked>
     238                <span class="slider round"></span>
     239            </label>
     240        </div>
     241
     242        <script>
     243            jQuery(document).ready(function ($) {
     244                // Prevent 'e', '-', '+', 'E' in any discount input
     245                $(document).on('keydown', '.dpc-discount-input', function (e) {
     246                    if (['e', 'E', '-', '+'].includes(e.key)) {
     247                        e.preventDefault();
     248                    }
     249                });
     250
     251                // Conditional validation for all discount rows
     252                $(document).on('change', '.dpc-discount-type-select', function () {
     253                    var type = $(this).val();
     254                    var $row = $(this).closest('tr');
     255                    var $input = $row.find('.dpc-discount-input');
     256                    if (type === 'percentage') {
     257                        $input.attr('max', '100');
     258                        $input.attr('title', '<?php esc_html_e( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' ); ?>');
     259                    } else {
     260                        $input.removeAttr('max');
     261                        $input.attr('title', '<?php esc_html_e( 'Enter the discount fixed amount (0 or more).', 'elex-discount-per-country' ); ?>');
     262                    }
     263                });
     264
     265                // Trigger change on all select on load to ensure tooltips/max are correct
     266                $('.dpc-discount-type-select').trigger('change');
     267
     268                // Change 'Save changes' text to 'Save Changes'
     269                $("button[name='save']").text('<?php esc_html_e( 'Save Changes', 'elex-discount-per-country' ); ?>');
     270            });
     271        </script>
     272
    189273
    190274    </td>
    191    
     275
    192276</tr>
  • elex-discount-per-country/tags/1.2.1/readme.txt

    r3460057 r3492012  
    44Tags: discount based on shipping country, woocommerce
    55Requires at least: 3.0.1
    6 Stable tag: 1.2.0
     6Stable tag: 1.2.1
    77Tested up to: 6.9
    88License: GPLv2 or later
     
    5050== Changelog ==
    5151
     52= 1.2.1 =
     53* Enhanced validation and security
     54* Improved discount calculations
     55* Added support for fixed discounts
     56* Added custom discount labels for each payment method
     57
    5258= 1.2.0 =
    5359* Minor issue fixes
     
    130136== Upgrade Notice ==
    131137
     138= 1.2.1 =
     139* Enhanced validation and security
     140* Improved discount calculations
     141* Added support for fixed discounts
     142* Added custom discount labels for each payment method
     143
    132144= 1.2.0 =
    133145* Minor issue fixes
  • elex-discount-per-country/trunk/assets/css/dpc-plugin-styles.css

    r2644557 r3492012  
    1 
    21#custom_price_field {
    32    /* margin-bottom: 5px; */
     
    1211}
    1312
    14 .interested_products{
    15     color:red;
    16     font:bolder;
     13.interested_products {
     14    color: red;
     15    font: bolder;
    1716}
    1817
     
    2625.elex_cpp_custom_title_heading {
    2726    font-size: 1.4em;
    28    
     27
    2928}
    3029
     
    3635.custom-min-price1 {
    3736    color: rgb(20, 19, 19);
    38     font-size: 25;
    39 }
     37    font-size: 25px;
     38}
     39
    4040.custom-min-price-validation {
    4141    color: rgb(20, 19, 19);
    42     font-size: 25;
     42    font-size: 25px;
    4343}
    4444
     
    6060    height: 5%;
    6161    border-color: rgb(200, 210, 219);
    62     vertical-align:middle;
    63     margin-bottom:15px;
     62    vertical-align: middle;
     63    margin-bottom: 15px;
    6464    line-height: 20px;
    65     font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    66     box-shadow: 0 5px 10px 5px rgba(0,0,0,0.2);
    67 }
     65    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
     66    box-shadow: 0 5px 10px 5px rgba(0, 0, 0, 0.2);
     67}
     68
    6869/*
    6970input.style {
     
    7778
    7879/*Styles for form-settings-template*/
     80.fields_adjustment_dpc {
     81    table-layout: fixed;
     82    width: 100%;
     83}
     84
    7985.fields_adjustment_dpc td {
    8086    vertical-align: middle;
    81     padding: 4px 7px;
    82 }
     87    padding: 8px;
     88    white-space: normal;
     89}
     90
    8391.fields_adjustment_dpc th {
    84     padding: 9px 7px;
     92    padding: 10px 10px;
    8593}
    8694
    8795.fields_adjustment_dpc .bold_span {
    88     font-weight:bold;
    89 }
    90 
    91 .fields_adjustment_dpc .col_btn{
     96    font-weight: bold;
     97}
     98
     99.fields_adjustment_dpc .col_btn {
    92100    display: flex;
    93101    justify-content: center;
    94     align-items: center;
    95 }
     102    align-items: center;
     103}
     104
    96105.fields_adjustment_dpc .remove_icon_discount_dpc {
    97     width: 10%;
    98 }
     106    width: 7%;
     107    min-width: 65px;
     108    text-align: center;
     109}
     110
    99111.fields_adjustment_dpc .table_col_1_dpc {
    100     width: 2%;
    101 }
     112    width: 3%;
     113    min-width: 30px;
     114}
     115
    102116.fields_adjustment_dpc .table_col_2_dpc {
    103     width: 35%;
    104 }
     117    width: 20%;
     118    min-width: 160px;
     119    /* Payment Method / region select */
     120}
     121
     122.fields_adjustment_dpc .table_col_type_dpc {
     123    width: 12%;
     124    min-width: 120px;
     125    /* Discount Type - wider so Percentage/Fixed shows fully */
     126}
     127
     128.fields_adjustment_dpc .table_col_label_dpc {
     129    width: 12%;
     130    min-width: 110px;
     131    /* Discount Label */
     132}
     133
    105134.fields_adjustment_dpc .table_col_3_dpc {
    106     width: 35%;
    107 }
     135    width: 15%;
     136    min-width: 180px;
     137    /* Percentage/Fixed Amount value */
     138}
     139
     140.fields_adjustment_dpc .table_col_5_dpc {
     141    width: 12%;
     142    min-width: 130px;
     143    /* From Date */
     144}
     145
     146.fields_adjustment_dpc .table_col_6_dpc {
     147    width: 12%;
     148    min-width: 130px;
     149    /* To Date */
     150}
     151
    108152.fields_adjustment_dpc .table_col_4_dpc {
    109     width: 10%;
    110 }
    111 .fields_adjustment_dpc .table_col_5_dpc {
    112     width: 10%;
    113 }
    114 .fields_adjustment_dpc .table_col_6_dpc {
    115     width: 10%;
     153    width: 7%;
     154    min-width: 65px;
     155    text-align: center;
     156}
     157
     158/* Reduce outer spacing around the Add New Discount button */
     159.fields_adjustment_dpc tfoot td {
     160    padding: 16px 0 !important;
     161}
     162
     163.fields_adjustment_dpc td input[type="text"],
     164.fields_adjustment_dpc td input[type="number"],
     165.fields_adjustment_dpc td input[type="datetime-local"],
     166.fields_adjustment_dpc td select {
     167    width: 100%;
     168    box-sizing: border-box;
     169    padding: 7px 10px;
     170    border: 1px solid #c3c4c7;
     171    border-radius: 4px;
     172    /* Match the Select region border-radius */
     173    background-color: #fff;
     174    color: #2c3338;
     175    font-size: 13px;
     176}
     177
     178.fields_adjustment_dpc td input:focus,
     179.fields_adjustment_dpc td select:focus {
     180    border-color: #2271b1;
     181    box-shadow: none;
     182    /* Flat focus, no glow */
     183    outline: none;
    116184}
    117185
    118186.fields_adjustment_dpc td input {
    119     margin-right: 4px;
    120 }
     187    margin-right: 0;
     188}
     189
    121190.fields_adjustment_dpc .check-column {
    122191    vertical-align: middle;
     
    124193    padding: 0 7px;
    125194}
    126 .fields_adjustment_dpc .table_input_raw_dpc{
    127     background: #EBEBEB;
    128 }
    129 
    130 .woocommerce table.form-table .select2-container {
    131 min-width: 500px!important;
     195
     196.fields_adjustment_dpc .table_input_raw_dpc {
     197    background: #f6f7f7;
     198}
     199
     200/* Empty state messages - centered */
     201.nodiscount-dpc td {
     202    text-align: center !important;
     203    padding: 24px 0 !important;
     204}
     205
     206#no_discount_available_dpc {
     207    display: block;
     208    text-align: center;
     209    color: #50575e;
     210    font-size: 13px;
     211    margin-bottom: 6px;
     212}
     213
     214.no-payments-btn {
     215    text-align: center;
     216    color: #50575e;
     217    font-size: 13px;
     218}
     219
     220.fields_adjustment_dpc .select2-container {
     221    min-width: 100% !important;
    132222}
    133223
    134224.fields_adjustment_dpc .table_header {
    135     font-weight:bold;
     225    font-weight: bold;
     226    font-size: 13px;
     227    color: #50575e;
     228    vertical-align: middle;
    136229}
    137230
    138231.table_th_label {
    139     font-weight:bold;
    140     font-size:small;
    141 }
     232    font-weight: bold;
     233    font-size: 13px;
     234}
     235
    142236.fields_adjustment_dpc .table_header_remove {
    143237    text-align: center;
    144     font-weight:bold;
     238    font-weight: bold;
     239    font-size: 13px;
     240    color: #50575e;
     241    vertical-align: middle;
    145242}
    146243
     
    149246    padding: 0 16px;
    150247}
     248
    151249.fields_adjustment_dpc td.sort {
    152250    width: 16px;
    153251    padding: 0 16px;
    154252    cursor: move;
    155     background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAHUlEQVQYV2O8f//+fwY8gJGgAny6QXKETRgEVgAAXxAVsa5Xr3QAAAAASUVORK5CYII=) no-repeat center;   
    156     }
     253    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAHUlEQVQYV2O8f//+fwY8gJGgAny6QXKETRgEVgAAXxAVsa5Xr3QAAAAASUVORK5CYII=) no-repeat center;
     254}
     255
    157256.fields_adjustment_dpc td.remove_icon_discount_dpc {
    158257    width: 16px;
    159258    padding: 0 16px;
    160    
     259
    161260    cursor: pointer;
    162261    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAA3NCSVQICAjb4U/gAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAB70lEQVQ4T61UPUhbURT+7n0vLxE1vmqFEBTR6lS7uHaTYpfqopsu0qkgODh0EURwadFBEJy62a3t0BbBIm5dXdTJP/whiFr7EpUmL3m5nnNixR80EfLBXe79vu+ce865VxkCbsHf2Ud6eQWZzS1k1tZlL/y8DeFnLYh0vIDT1CB713HDKPBS8D5/xemPX8hns1COA2VbcmZyAYzvQ4dCqO7ugtvfC8uNyhnjyiibOMDByDhyngdFZKW1EG7D5PMwFMR2XcSmxhCKx2RfjIJkCol375E7IZMwZaGUHN4Hjm0yPuxaF/HZD7BqopCw3twXBH9LM2Ewh7msYS1D+zt7OP25CNh0HdqQaCUsCUca1rKHTi+vIk9FVFrR/YmUTsP8K7KYQ1zWsJY91OHHGXO29Fu6Y7k1iPa8ptwlNY55F3x1Okp9X6AuJ6WbVZ0voXYHh01w9AegbjitzYhPT1wqHkZieBT+xjYVR8OqrysUuxwo39WS3+bN8cwnWFWVhWL7GSE+CPJSTliKHZyd4+nQW+hIRzs0PYX/XVCRCFRFkcWcyy6ztuDR1IjqN6+AXFYSkWErYUnSpGEte0ix3YE+WE9cGXsetmKQoSQua1jLECN+K7HJMdhsRgPGD/M+yKMlDnNZw1pG+b+R63j8xwZcADXJQNHUd268AAAAAElFTkSuQmCC) no-repeat center
     
    165264.fields_adjustment_dpc #elex_dpc_add_field {
    166265    cursor: pointer;
    167 } 
     266}
    168267
    169268.fields_adjustment_dpc select {
     
    171270}
    172271
    173 tr td {
    174 
    175 white-space: nowrap;
    176 }
    177272body {
    178 background:#FCFCFC;
    179 color:#222;
    180 font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;
    181 }
     273    background: #FCFCFC;
     274    color: #222;
     275    font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Open Sans, Helvetica Neue, sans-serif;
     276}
     277
    182278.btn_raw {
    183279
    184 background-color: white;
    185 padding-top: 5px;
    186 border: none;
    187 border-radius: 50%;
    188 background:   #1E90FF;
    189 color: white;
    190 padding: 1px 2px;
    191 cursor: pointer;
    192 
    193 
    194 }
     280    background-color: white;
     281    padding-top: 5px;
     282    border: none;
     283    border-radius: 50%;
     284    background: #1E90FF;
     285    color: white;
     286    padding: 1px 2px;
     287    cursor: pointer;
     288
     289
     290}
     291
     292/* Premium "Add New Discount" Button Style */
     293.fields_adjustment_dpc .elex-add-new-btn {
     294    background: #2271b1;
     295    border: none;
     296    color: #ffffff;
     297    padding: 6px 20px 6px 6px;
     298    border-radius: 50px;
     299    display: inline-flex;
     300    align-items: center;
     301    gap: 12px;
     302    cursor: pointer;
     303    font-weight: 500;
     304    font-size: 14px;
     305    transition: all 0.3s ease;
     306    box-shadow: 0 2px 4px rgba(34, 113, 177, 0.2);
     307    text-decoration: none;
     308    line-height: 1;
     309}
     310
     311.fields_adjustment_dpc .elex-add-new-btn:hover {
     312    background: #1c5d91;
     313    transform: translateY(-1px);
     314    box-shadow: 0 4px 8px rgba(34, 113, 177, 0.3);
     315}
     316
     317.fields_adjustment_dpc .elex-add-new-btn .icon-circle {
     318    display: flex;
     319    align-items: center;
     320    justify-content: center;
     321    width: 28px;
     322    height: 28px;
     323    background: #ffffff;
     324    color: #2271b1;
     325    border-radius: 50%;
     326    font-size: 18px;
     327    /* Slightly larger for text + */
     328    font-weight: bold;
     329    padding: 0;
     330    line-height: 0;
     331    /* Helps with centering text + */
     332}
     333
     334#elex_dpc_add_field_discount .icon-circle {
     335    color: #2271b1;
     336}
     337
     338.fields_adjustment_dpc .elex-add-new-btn .btn-text {
     339    padding-right: 5px;
     340    color: #ffffff;
     341}
     342
    195343.switch {
    196 
    197 position: relative;
    198 display: inline-block;
    199 width: 40px;
    200 height: 19px;
    201 }
    202 
    203 .switch input {
    204 opacity: 0;
    205 width: 0;
    206 height: 0;
     344    position: relative;
     345    display: inline-block;
     346    width: 40px;
     347    height: 19px;
     348}
     349
     350.switch input {
     351    opacity: 0;
     352    width: 0;
     353    height: 0;
    207354}
    208355
    209356.slider {
    210 position: absolute;
    211 cursor: pointer;
    212 top: 0;
    213 left: 0;
    214 right: 0;
    215 bottom: 0;
    216 background-color: #ccc;
    217 -webkit-transition: .4s;
    218 transition: .4s;
     357    position: absolute;
     358    cursor: pointer;
     359    top: 0;
     360    left: 0;
     361    right: 0;
     362    bottom: 0;
     363    background-color: #ccc;
     364    -webkit-transition: .4s;
     365    transition: .4s;
    219366}
    220367
    221368.slider:before {
    222 position: absolute;
    223 content: "";
    224 height:16px;
    225 width: 16px;
    226 left: 4px;
    227 bottom: 2px;
    228 background-color: white;
    229 -webkit-transition: .4s;
    230 transition: .4s;
    231 }
    232 
    233 input:checked + .slider {
    234 background-color: #2196F3;
    235 }
    236 
    237 input:focus + .slider {
    238 box-shadow: 0 0 1px #2196F3;
    239 }
    240 
    241 input:checked + .slider:before {
    242 -webkit-transform: translateX(16px);
    243 -ms-transform: translateX(16px);
    244 transform: translateX(16px);
     369    position: absolute;
     370    content: "";
     371    height: 16px;
     372    width: 16px;
     373    left: 4px;
     374    bottom: 2px;
     375    background-color: white;
     376    -webkit-transition: .4s;
     377    transition: .4s;
     378}
     379
     380input:checked+.slider {
     381    background-color: #2196F3;
     382}
     383
     384input:focus+.slider {
     385    box-shadow: 0 0 1px #2196F3;
     386}
     387
     388input:checked+.slider:before {
     389    -webkit-transform: translateX(16px);
     390    -ms-transform: translateX(16px);
     391    transform: translateX(16px);
    245392}
    246393
    247394/* Rounded sliders */
    248395.slider.round {
    249 border-radius: 34px;
     396    border-radius: 34px;
    250397}
    251398
    252399.slider.round:before {
    253 border-radius: 50%;
    254 }
     400    border-radius: 50%;
     401}
  • elex-discount-per-country/trunk/assets/js/dpc-plugin-scripts.js

    r3460057 r3492012  
    1 jQuery(document).ready(function(){
    2 
    3     jQuery(document).on('change','.elex_discount_per_country_to_date' ,function(){
     1jQuery(document).ready(function () {
     2
     3    jQuery(document).off('change', '.elex_discount_per_country_to_date').on('change', '.elex_discount_per_country_to_date', function () {
    44        var end_date = new Date(jQuery(this).val());
    5         var start_date  = new Date(jQuery(this).parents('tr').find('.elex_discount_per_country_from_date').val());
    6 
    7     if(start_date.getTime() >  end_date.getTime()){
    8        
    9         alert("To date can not be less than From date");
    10         var end_date = new Date(jQuery(this).val(''));
    11         return;
    12        
    13     }
    14 
    15     });
    16 
    17     jQuery(document).on('change','.elex_discount_per_country_from_date' ,function(){
     5        var start_date = new Date(jQuery(this).parents('tr').find('.elex_discount_per_country_from_date').val());
     6
     7        if (start_date.getTime() > end_date.getTime()) {
     8
     9            alert("To date can not be less than From date");
     10            var end_date = new Date(jQuery(this).val(''));
     11            return;
     12
     13        }
     14
     15    });
     16
     17    jQuery(document).off('change', '.elex_discount_per_country_from_date').on('change', '.elex_discount_per_country_from_date', function () {
    1818        var start_date = new Date(jQuery(this).val());
    19         var end_date  = new Date(jQuery(this).parents('tr').find('.elex_discount_per_country_to_date').val());
    20 
    21     if(start_date.getTime() >  end_date.getTime()){
    22        
    23         var start_date = new Date(jQuery(this).val(''));
    24         alert("start date can not be more than From date");
    25         return;
    26     }
    27    
     19        var end_date = new Date(jQuery(this).parents('tr').find('.elex_discount_per_country_to_date').val());
     20
     21        if (start_date.getTime() > end_date.getTime()) {
     22
     23            var start_date = new Date(jQuery(this).val(''));
     24            alert("start date can not be more than From date");
     25            return;
     26        }
     27
    2828    });
    2929    /*Scripts for form-settings-temp */
    30     jQuery("#elex_dpc_table_body").on('click', '.remove_icon_discount_dpc', function () {
    31        
    32         var tbody = jQuery('.fields_adjustment_dpc').find('tbody');
    33         var size = tbody.find('tr').size();
     30    jQuery("#elex_dpc_table_body").off('click', '.remove_icon_discount_dpc').on('click', '.remove_icon_discount_dpc', function () {
     31
     32        var tbody = jQuery('#elex_dpc_table_body');
     33        var size = tbody.find('tr').length;
    3434        var id = jQuery(this).closest("tr").attr("id");
    3535        var value = jQuery(this).closest("tr").attr("class");
    36         if(value==="nodiscount-dpc"){
     36
     37        if (value === "nodiscount-dpc") {
    3738
    3839            jQuery("#nodiscount-dpc").remove();
    39            
    40         }else if(size===1){
    41 
    42            
    43             jQuery('#elex_discount_per_country_options_select_value').append('<option id="'+id+'" value="'+value+'">'+elexdpc_translations['country_id']+'</option>');
     40
     41        } else {
     42
     43            // Add removed country options back to the country dropdown if they were loaded as existing rows
     44            var $tr = jQuery(this).closest("tr");
     45            var existingCountryCode = $tr.find('input[name*="[country_code]"]').val();
     46            var existingCountryName = $tr.find('input[name*="[country_name]"]').val() || $tr.find('span.bold_span').text();
     47
     48            if (existingCountryCode) {
     49                if (jQuery('#zone_locations_template option[value="' + existingCountryCode + '"]').length === 0) {
     50                    jQuery('#zone_locations_template').append('<option value="' + existingCountryCode + '">&nbsp;&nbsp; ' + existingCountryName + '</option>');
     51                }
     52            }
     53
     54            // Capture dynamically selected ones in case they are missing
     55            $tr.find('select[id^="zone_locations_"] option:selected').each(function () {
     56                var optionValue = jQuery(this).val();
     57                var optionText = jQuery(this).text();
     58                if (optionValue && jQuery('#zone_locations_template option[value="' + optionValue + '"]').length === 0) {
     59                    jQuery('#zone_locations_template').append('<option value="' + optionValue + '">' + optionText + '</option>');
     60                }
     61            });
     62
    4463            jQuery(this).closest("tr").remove();
    4564
    46             var default_code='<tr id="nodiscount-dpc" class="nodiscount-dpc"><td class="table_col_1"></td><td class="table_col_2"><span class="wc-country-name"  id="no_discount_available_dpc">'+elexdpc_translations['tooltip']['nodiscount-dpc']+'</span></td><td class="table_col_3"></td><td class="table_col_4"></td> <td class="table_col_4"></td></tr>';
    47 
    48             jQuery('#elex_dpc_table_body').append( default_code );
    49 
    50         }else{
    51 
    52         jQuery('#elex_discount_per_country_options_select_value').append('<option id="'+id+'" value="'+value+'">'+elexdpc_translations['country_id']+'</option>');
    53         jQuery(this).closest("tr").remove();
    54        
    55         }
    56     });
    57 
    58     jQuery("#elex_dpc_table_body").on('click','.checkbox_click', function () {
    59 
    60         var v = jQuery(this).closest("td").find('input').val();
    61 
    62         if(v== true)
    63         {
    64             jQuery(this).closest("td").find('input').val("yes");
    65             jQuery(this).closest("td").find('label').attr('title',elexdpc_translations['tooltip']['toggleon']);
    66         }
    67        
    68 
    69         if(v== false)
    70         {
    71             jQuery(this).closest("td").find('input').val("no");
     65            if (size === 1) {
     66                var default_code = '<tr id="nodiscount-dpc" class="nodiscount-dpc"><td colspan="9"><div class="no-payments-btn">' + elexdpc_translations['tooltip']['nodiscount-dpc'] + '</div></td></tr>';
     67                jQuery('#elex_dpc_table_body').append(default_code);
     68            }
     69
     70        }
     71    });
     72
     73    jQuery("#elex_dpc_table_body").off('click', '.checkbox_click').on('click', '.checkbox_click', function () {
     74
     75        var v = jQuery(this).is(':checked');
     76
     77        if (v) {
     78            jQuery(this).closest("td").find('label').attr('title', elexdpc_translations['tooltip']['toggleon']);
     79        } else {
    7280            jQuery(this).closest("td").find('label').attr('title', elexdpc_translations['tooltip']['toggleoff']);
    73            
    74         }
    75 
    76 
    77     });
    78 
    79     //To add more rules before saving changes
    80     jQuery('#elex_dpc_add_field_discount').click( function(e) {
     81        }
     82
     83
     84    });
     85
     86    // Update discount input constraints based on discount type
     87    function updateDiscountConstraints($row) {
     88        var type = $row.find('select[name*="[discount_type]"]').val();
     89        // accidentally matching [discount_type] or other fields that contain "[discount]"
     90        var $input = $row.find('input[name$="[discount]"]');
     91        if (type === 'fixed') {
     92            $input.removeAttr('max');
     93            $input.attr('min', '0');
     94            $input.attr('title', 'Enter the fixed discount amount (0 or above)');
     95        } else {
     96            $input.attr('max', '100');
     97            $input.attr('min', '0');
     98            $input.attr('title', 'Enter the discount percentage value from 0 to 100.');
     99        }
     100    }
     101
     102    // Initialize constraints on page load for all existing rows
     103    jQuery('#elex_dpc_table_body tr').each(function () {
     104        updateDiscountConstraints(jQuery(this));
     105    });
     106
     107    // Update constraints when discount type changes
     108    jQuery('#elex_dpc_table_body').off('change', 'select[name*="[discount_type]"]').on('change', 'select[name*="[discount_type]"]', function () {
     109        updateDiscountConstraints(jQuery(this).closest('tr'));
     110    });
     111
     112    // To add empty editable rules before saving changes
     113    jQuery('#elex_dpc_add_field_discount').off('click').on('click', function (e) {
    81114        e.preventDefault();
    82        
    83 
    84         if(closest_tr_class="nodiscount-dpc"){
    85 
     115
     116        if (jQuery("#nodiscount-dpc").length) {
    86117            jQuery("#nodiscount-dpc").remove();
    87 
    88         }
    89         var tbody = jQuery('.fields_adjustment_dpc').find('tbody');
    90         var size = tbody.find('tr').size();
    91        
    92         var closest_tr_class = jQuery('#nodiscount-dpc').attr("class");
    93         var checkbox_enabled= jQuery('#elex_discount_per_country_options_enabled').is(':checked');
    94         var id = [];
    95         var input_value = jQuery("#elex_discount_per_country_options_input_value").val();
    96         var country_selected = jQuery("#zone_locations").val();
    97         if ( country_selected.length <= 0 ) {
    98             alert( elexdpc_translations['error_message']['nofieldsfilled'] );
    99             return;
    100         }
    101         // get the date in required format and it to the table
    102 
    103         var startdate_bfr_converting= jQuery("#elex_discount_per_country_start_date").val();
    104         var enddate_bfr_converting= jQuery("#elex_discount_per_country_end_date").val();
    105        
    106         if(startdate_bfr_converting === '')
    107         {
    108             var start_date = '';
    109         }
    110         else
    111         {
    112             var start_date = moment(new Date(jQuery("#elex_discount_per_country_start_date").val()) ).format('YYYY-MM-DDTHH:mm');
    113         }
    114 
    115         if(enddate_bfr_converting === '')
    116         {
    117             var end_date = '';
    118         }
    119         else
    120         {
    121             var end_date= moment(new Date(jQuery("#elex_discount_per_country_end_date").val()) ).format('YYYY-MM-DDTHH:mm');
    122 
    123         }
    124         if(start_date !== '' && end_date !== '' )
    125         {
    126                 if(start_date >  end_date){
    127                     alert("To date can not be less than From date");
    128                     return;
     118        }
     119
     120        var tbody = jQuery('#elex_dpc_table_body');
     121
     122        // Find the highest existing index to determine the next size
     123        var maxIndex = -1;
     124        tbody.find('tr').each(function () {
     125            var idAttr = jQuery(this).attr('id');
     126            // Existing rows might have numeric IDs or custom IDs.
     127            // We look for the inputs to get the actual array index used.
     128            jQuery(this).find('input[name*="elex_discount_per_country_options"]').each(function () {
     129                var name = jQuery(this).attr('name');
     130                var match = name.match(/\[(\d+)\]/);
     131                if (match) {
     132                    var idx = parseInt(match[1]);
     133                    if (idx > maxIndex) maxIndex = idx;
    129134                }
    130         }
    131 
    132         var startdate_bfr_converting= jQuery("#elex_discount_per_country_start_date").val('');
    133         var enddate_bfr_converting= jQuery("#elex_discount_per_country_end_date").val('');
    134         var country_names = [];
    135          jQuery('#zone_locations').find("option:selected").map(function() {
    136             country_names.push(jQuery(this).text());
    137             id.push(this.value);
     135            });
    138136        });
    139         country_names = country_names.join(', ');
    140 
    141         jQuery('#zone_locations').find("option:selected").remove();
    142 
    143         id = id.join(',');
    144 
    145         jQuery("#elex_discount_per_country_options_input_value").val(0);
    146        
    147         if ( input_value <= 100 && input_value >= 0 && ( input_value.indexOf(".") <= 2 ) && input_value != "" && country_selected != "" )
    148         {
    149 
    150             var code='<tr id="'+id+'" class="'+country_selected+'">\
    151                     <td class="table_col_1"  > </td>\
    152                     <td class="table_col_2"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][country_code]" value="'+id+'"/><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][country_name]" value="'+country_selected+'"/> <span  class="wc-country-name" >'+country_names+'</span></td>\
    153                     <td class="table_col_3" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="number"  min="0" max="100" step="any" class="order" name="elex_discount_per_country_options['+size+'][discount]" value="'+input_value+'" required></td>\
    154                     <td class="table_col_5" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="datetime-local"   class="elex_discount_per_country_from_date" name="elex_discount_per_country_options['+size+'][start_date]" value="'+start_date+'"  ></td>\
    155                     <td class="table_col_6" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="datetime-local" class="elex_discount_per_country_to_date" name="elex_discount_per_country_options['+size+'][end_date]" value="'+end_date+'"  ></td>';
    156 
    157 
    158             if(checkbox_enabled)
    159             {
    160                 code +='<td  class="table_col_4" > <label title="'+elexdpc_translations['tooltip']['toggleoff']+'" class="switch"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][status]" value="yes"/><input    type="checkbox" class="checkbox_click" name="elex_discount_per_country_options['+size+'][enabled]" value="1" checked><span class="slider round"></span></label></td>';
    161            
    162             }else{
    163 
    164                 code +='<td class="table_col_4"> <label title="'+elexdpc_translations['tooltip']['toggleon']+'" class="switch"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][status]" value="no"/><input  type="checkbox" class="checkbox_click" name="elex_discount_per_country_options['+size+'][enabled]" value="0"  ><span class="slider round"></span></label></td>';
    165 
    166             }
    167            
    168 
    169             code +='<td class="remove_icon_discount_dpc" title="'+elexdpc_translations['tooltip']['remove']+'" ></td>\
     137        var size = maxIndex + 1;
     138
     139        // Clone templates
     140        var countrySelect = jQuery('#zone_locations_template').clone();
     141        countrySelect.attr('id', 'zone_locations_' + size);
     142        countrySelect.attr('name', 'elex_discount_per_country_options[' + size + '][country_code][]');
     143        countrySelect.css('width', '100%');
     144        countrySelect.addClass('wc-enhanced-select');
     145
     146        var typeSelect = jQuery('#elex_discount_per_country_discount_type_template').clone();
     147        typeSelect.attr('id', 'discount_type_' + size);
     148        typeSelect.attr('name', 'elex_discount_per_country_options[' + size + '][discount_type]');
     149
     150        var labelInput = jQuery('#elex_discount_per_country_label_template').clone();
     151        labelInput.attr('id', 'label_' + size);
     152        labelInput.attr('name', 'elex_discount_per_country_options[' + size + '][label]');
     153
     154        var discountInput = jQuery('#elex_discount_per_country_options_input_value_template').clone();
     155        discountInput.attr('id', 'discount_value_' + size);
     156        discountInput.attr('name', 'elex_discount_per_country_options[' + size + '][discount]');
     157
     158        var startDateInput = jQuery('#elex_discount_per_country_start_date_template').clone();
     159        startDateInput.attr('id', 'start_date_' + size);
     160        startDateInput.attr('name', 'elex_discount_per_country_options[' + size + '][start_date]');
     161
     162        var endDateInput = jQuery('#elex_discount_per_country_end_date_template').clone();
     163        endDateInput.attr('id', 'end_date_' + size);
     164        endDateInput.attr('name', 'elex_discount_per_country_options[' + size + '][end_date]');
     165
     166        var statusLabel = jQuery('#elex_discount_per_country_options_enabled_template').parent().clone();
     167        statusLabel.find('input').attr('id', 'enabled_' + size);
     168        statusLabel.find('input').attr('name', 'elex_discount_per_country_options[' + size + '][status]');
     169        statusLabel.find('input').val('yes'); // Default enabled
     170        statusLabel.find('input').prop('checked', true);
     171
     172        var code = '<tr id="new_row_' + size + '" class="new_row_dpc">\
     173                    <td class="table_col_1_dpc"> </td>\
     174                    <td class="table_col_2_dpc"></td>\
     175                    <td class="table_col_type_dpc"></td>\
     176                    <td class="table_col_3_dpc"></td>\
     177                    <td class="table_col_label_dpc"></td>\
     178                    <td class="table_col_5_dpc"></td>\
     179                    <td class="table_col_6_dpc"></td>\
     180                    <td class="table_col_4_dpc"></td>\
     181                    <td class="remove_icon_discount_dpc" title="' + elexdpc_translations['tooltip']['remove'] + '"><span class="remove-btn-circle"><i class="fas fa-minus"></i></span></td>\
    170182                    </tr>';
    171183
    172             jQuery('#elex_dpc_table_body').append( code );
    173         }else{
    174 
    175            
    176            
    177             if(country_selected==""){
    178 
    179                 alert(elexdpc_translations['tooltip']['allcountriesselected']);
    180 
    181             }else{
    182                 alert(elexdpc_translations['tooltip']['inputalert']);
    183             }
    184 
    185         }
     184        var $newRow = jQuery(code);
     185        $newRow.find('.table_col_2_dpc').append(countrySelect);
     186        $newRow.find('.table_col_type_dpc').append(typeSelect);
     187        $newRow.find('.table_col_3_dpc').append(discountInput);
     188        $newRow.find('.table_col_label_dpc').append(labelInput);
     189        $newRow.find('.table_col_5_dpc').append(startDateInput);
     190        $newRow.find('.table_col_6_dpc').append(endDateInput);
     191        $newRow.find('.table_col_4_dpc').append(statusLabel);
     192
     193        tbody.append($newRow);
     194
     195        // Initialize discount constraints for the new row
     196        updateDiscountConstraints($newRow);
     197
     198        // Initialize Select2/Enhanced Select
     199        jQuery(document.body).trigger('wc-enhanced-select-init');
     200
    186201        return false;
    187202    });
    188203
    189 
    190         //To save the rule on clicking save changes button(without clicking add button)
    191 
    192         jQuery("button[name='save']").click( function() {
    193         var checkbox_enabled= jQuery('#elex_discount_per_country_options_enabled').is(':checked');
    194         var id = [];
    195         var input_value = jQuery("#elex_discount_per_country_options_input_value").val();
    196         var country_selected = jQuery("#zone_locations").val();
    197         var tbody = jQuery('.fields_adjustment_dpc').find('tbody');
    198         var size = tbody.find('tr').size();
    199        
    200         // get the date in required format and it to the table
    201 
    202         var startdate_bfr_converting= jQuery("#elex_discount_per_country_start_date").val();
    203         var enddate_bfr_converting= jQuery("#elex_discount_per_country_end_date").val();
    204        
    205         if(startdate_bfr_converting === '')
    206         {
    207             var start_date = '';
    208         }
    209         else
    210         {
    211             var start_date = moment(new Date(jQuery("#elex_discount_per_country_start_date").val()) ).format('YYYY-MM-DDTHH:mm');
    212         }
    213 
    214         if(enddate_bfr_converting === '')
    215         {
    216             var end_date = '';
    217         }
    218         else
    219         {
    220             var end_date= moment(new Date(jQuery("#elex_discount_per_country_end_date").val()) ).format('YYYY-MM-DDTHH:mm');
    221 
    222         }
    223         if(start_date !== '' && end_date !== '' )
    224         {
    225                 if(start_date >  end_date){
    226                     alert("To date can not be less than From date");
    227                     return;
    228                 }
    229         }
    230 
    231         var startdate_bfr_converting= jQuery("#elex_discount_per_country_start_date").val('');
    232         var enddate_bfr_converting= jQuery("#elex_discount_per_country_end_date").val('');
    233         var country_names = [];
    234          jQuery('#zone_locations').find("option:selected").map(function() {
    235             country_names.push(jQuery(this).text());
    236             id.push(this.value);
    237         });
    238         jQuery('#zone_locations').find("option:selected").remove();
    239         jQuery("#elex_discount_per_country_options_input_value").val(0);
    240 
    241 
    242         if (input_value<=100 && input_value>=0 && ( input_value.indexOf(".") <= 2 ) && input_value!="" && country_selected!="")
    243         {
    244            
    245             var code='<tr id="'+id+'" class="'+country_selected+'">\
    246                     <td class="table_col_1"  > </td>\
    247                     <td class="table_col_2"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][country_code]" value="'+id+'"/><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][country_name]" value="'+country_selected+'"/> <span  class="wc-country-name" >'+country_names+'</span></td>\
    248                     <td class="table_col_3" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="number" min="0" max="100" step="any" class="order" name="elex_discount_per_country_options['+size+'][discount]" value="'+input_value+'" required></td>\
    249                     <td class="table_col_5" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="datetime-local"   class="elex_discount_per_country_from_date" name="elex_discount_per_country_options['+size+'][start_date]" value="'+start_date+'"  ></td>\
    250                     <td class="table_col_6" title="'+elexdpc_translations['tooltip']['inputtooltip']+'" > <input type="datetime-local" class="elex_discount_per_country_to_date" name="elex_discount_per_country_options['+size+'][end_date]" value="'+end_date+'"  ></td>';
    251 
    252 
    253             if(checkbox_enabled)
    254             {
    255                 code +='<td  class="table_col_4" > <label title="'+elexdpc_translations['tooltip']['toggleoff']+'" class="switch"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][status]" value="yes"/><input    type="checkbox" class="checkbox_click" name="elex_discount_per_country_options['+size+'][enabled]" value="1" checked><span class="slider round"></span></label></td>';
    256            
    257             }else{
    258 
    259                 code +='<td class="table_col_4"> <label title="'+elexdpc_translations['tooltip']['toggleon']+'" class="switch"><input type="hidden" class="order" name="elex_discount_per_country_options['+size+'][status]" value="no"/><input  type="checkbox" class="checkbox_click" name="elex_discount_per_country_options['+size+'][enabled]" value="0"  ><span class="slider round"></span></label></td>';
    260 
    261             }
    262            
    263 
    264             code +='<td class="remove_icon_discount_dpc" title="'+elexdpc_translations['tooltip']['remove']+'" ></td>\
    265                     </tr>';
    266 
    267             jQuery('#elex_dpc_table_body').append( code );
    268        
    269         }
    270 
    271     });
    272 
    273 
    274     /* script for refreshing cart on selecting different country_selected option */
    275 
    276     (function($){
    277                    
    278         $( 'form.checkout' ).on( 'change', 'input[name^="country"]', function() {
    279 
    280         $('body').trigger('update_checkout');
    281 
    282         });
    283 
    284     })(jQuery);
    285 
    286 
     204    // The save handler no longer needs to auto-add rows from static inputs
     205    jQuery("button[name='save']").off('click').on('click', function (e) {
     206        // Just let the form submit normally
     207        return true;
     208    });
    287209});
    288210
    289    
     211
     212
     213/* script for refreshing cart on selecting different country_selected option */
     214
     215(function ($) {
     216
     217    $('form.checkout').off('change', 'input[name^="country"]').on('change', 'input[name^="country"]', function () {
     218
     219        $('body').trigger('update_checkout');
     220
     221    });
     222
     223})(jQuery);
     224
     225
     226
  • elex-discount-per-country/trunk/elex-discount-per-country.php

    r3460057 r3492012  
    44 * Plugin URI:           https://elextensions.com/plugin/elex-woocommerce-discount-per-country-plugin-free/
    55 * Description:          The plugin allows you to offer discounts on your WooCommerce store based on the shipping country and shipping state chosen by customers.
    6  * Version:              1.2.0
     6 * Version:              1.2.1
    77 * Author:               ELEXtensions
    88 * Author URI:           https://elextensions.com/
  • elex-discount-per-country/trunk/includes/class-discount-per-country.php

    r3460057 r3492012  
    22
    33class ELEXDPC_Discount_Per_Country_Model {
     4
     5
    46    const OPTION_KEY = 'elexdpc_discount_per_country_options';
    5     private $items   = [];
     7    private $items = [];
    68
    79    public function get_items() {
    8        return $this->items; 
     10       return $this->items;
    911    }
    1012
     
    1618        return array_map(
    1719            function ( $item ) {
    18             return $item->to_array();
     20                return $item->to_array();
    1921            },
    2022            $this->items
    2123        );
    2224    }
    23    
     25
    2426    public function build() {
    25          $items = get_option( self::OPTION_KEY, array() );
    26        
     27       $items = get_option( self::OPTION_KEY, array() );
     28
     29        $old_global_label = get_option( 'elex-discount-per-country_label', '' );
     30
    2731        foreach ( $items as $item ) {
    28             $array_obj = new ELEXDPC_Discount_Per_Country_Rule( $item['country_code'], $item['discount'], $item['status'], $item['country_name'] , $item['start_date'], $item['end_date'] );
     32            if ( ! array_key_exists( 'label', $item ) ) {
     33                $resolved_label = $old_global_label;
     34            } else {
     35                $resolved_label = $item['label'];
     36            }
     37
     38            $array_obj = new ELEXDPC_Discount_Per_Country_Rule(
     39                isset( $item['country_code'] ) ? $item['country_code'] : '',
     40                isset( $item['discount'] ) ? $item['discount'] : 0,
     41                isset( $item['status'] ) ? $item['status'] : false,
     42                isset( $item['country_name'] ) ? $item['country_name'] : '',
     43                isset( $item['start_date'] ) ? $item['start_date'] : '',
     44                isset( $item['end_date'] ) ? $item['end_date'] : '',
     45                $resolved_label,
     46                isset( $item['discount_type'] ) ? $item['discount_type'] : 'percentage'
     47            );
    2948            $this->add( $array_obj );
    3049        }
     50    }
    3151
    32        
    33     }
    3452
    3553
     
    4058
    4159    public function remove( $country_code ) {
    42                 $this->items = array_filter(
    43                     $this->items,
    44                     function ( $item ) use ( $country_code ) {
    45                         return $country_code !== $item->country_code;
    46                     }
    47                 );
     60        $this->items = array_filter(
     61            $this->items,
     62            function ( $item ) use ( $country_code ) {
     63                return $country_code !== $item->country_code;
     64            }
     65        );
    4866    }
    4967
     
    5977class ELEXDPC_Discount_Per_Country_Rule {
    6078
    61     const STATUS_ENABLE  = true;
     79
     80
     81    const STATUS_ENABLE = true;
    6282    const STATUS_DISABLE = false;
    6383
    6484    public $country_code;
    6585    public $discount;
     86    public $discount_type;
    6687    public $status;
    6788    public $country_name;
    6889    public $start_date;
    6990    public $end_date;
     91    public $label;
    7092
    7193
    72     public function __construct( $country_code, $discount, $status, $country_name, $start_date, $end_date ) {
     94    public function __construct( $country_code, $discount, $status, $country_name, $start_date, $end_date, $label = '', $discount_type = 'percentage' ) {
    7395        $this->country_code = $country_code;
    74         $this->discount     = $discount;
    75         $this->status       = $status;
     96        $this->discount = $discount;
     97        $this->discount_type = $discount_type;
     98        $this->status = $status;
    7699        $this->country_name = $country_name;
    77         $this->start_date   = $start_date;
    78         $this->end_date     = $end_date;
     100        $this->start_date = $start_date;
     101        $this->end_date = $end_date;
     102        $this->label = $label;
    79103
    80104    }
     
    87111            $data['country_name'],
    88112            $data['start_date'],
    89             $data['end_date']
     113            $data['end_date'],
     114            isset( $data['label'] ) ? $data['label'] : '',
     115            isset( $data['discount_type'] ) ? $data['discount_type'] : 'percentage'
    90116        );
    91117    }
    92118
    93119    public function is_enabled() {
    94         return self::STATUS_ENABLE === $this->status;
     120      return self::STATUS_ENABLE === $this->status;
    95121    }
    96122
    97123    public function disable() {
    98         $this->status = self::STATUS_DISABLE;
     124         $this->status = self::STATUS_DISABLE;
    99125    }
    100126    public function enable() {
    101         $this->status = self::STATUS_ENABLE;
     127      $this->status = self::STATUS_ENABLE;
    102128    }
    103129
     
    105131        return [
    106132            'country_code' => $this->country_code,
    107             'discount'     => $this->discount,
    108             'status'       => $this->status,
     133            'discount' => $this->discount,
     134            'discount_type' => $this->discount_type,
     135            'status' => $this->status,
    109136            'country_name' => $this->country_name,
    110             'start_date'   => $this->start_date,
    111             'end_date'     => $this->end_date,
     137            'start_date' => $this->start_date,
     138            'end_date' => $this->end_date,
     139            'label' => $this->label,
    112140        ];
    113141    }
  • elex-discount-per-country/trunk/includes/elex-discount-per-country-admin-settings.php

    r3460057 r3492012  
    55}
    66
    7 require_once  WP_PLUGIN_DIR . '/woocommerce/includes/admin/settings/class-wc-settings-page.php' ;
    8 require_once  ABSPATH . 'wp-admin/includes/plugin.php' ;
    9 require_once  __DIR__ . '/class-discount-per-country.php';
     7require_once WP_PLUGIN_DIR . '/woocommerce/includes/admin/settings/class-wc-settings-page.php';
     8require_once ABSPATH . 'wp-admin/includes/plugin.php';
     9require_once __DIR__ . '/class-discount-per-country.php';
    1010
    1111class ELEXDPC_Admin_Settings extends WC_Settings_Page {
    1212
    1313
     14
     15
    1416    public function __construct() {
    15         //registering and loading scripts
    16            
    17         $this->id    = 'elex-discount-per-country';
     17         //registering and loading scripts
     18
     19        $this->id = 'elex-discount-per-country';
    1820        $this->label = __( 'ELEX Woo Discount Per Country', 'elex-discount-per-country' );
    1921        add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_settings_page' ), 99 );
     
    2325        add_action( 'woocommerce_cart_calculate_fees', array( $this, 'calculate_fees' ) );
    2426        add_action( 'admin_enqueue_scripts', array( $this, 'load_assets' ) );
    25        
     27
    2628    }
    2729
    2830    public function load_assets() {
    29         wp_nonce_field( 'elex_dpc_ajax_nonce', '_elex_dpc_ajax_nonce' );
     31         wp_nonce_field( 'elex_dpc_ajax_nonce', '_elex_dpc_ajax_nonce' );
    3032        wp_verify_nonce( 'elex_dpc_ajax_nonce', '_elex_dpc_ajax_nonce' );
    31          
     33
    3234        global $woocommerce;
    33         $woocommerce_version = function_exists( 'WC' ) ? WC()->version : $woocommerce->version; 
    34         $page                = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
    35         $tab                 = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
    36         $section             = isset( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : '';
     35        $woocommerce_version = function_exists( 'WC' ) ? WC()->version : $woocommerce->version;
     36        $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
     37        $tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
     38        $section = isset( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : '';
    3739        if ( 'wc-settings' === $page && 'elex-discount-per-country' === $tab && '' === $section ) {
    38                 wp_enqueue_style( 'woocommerce_admin_styles', $woocommerce->plugin_url() . '/assets/css/admin.css', array(), $woocommerce_version, false );
    39                 wp_register_style( 'elex-dpc-plugin-styles', ELEX_DISCOUNT_PER_COUNTRY_MAIN_URL_PATH . '/assets/css/dpc-plugin-styles.css', array(), $woocommerce_version, false );
    40                 wp_enqueue_style( 'elex-dpc-plugin-styles' );
    41                 wp_register_script( 'elex-dpc-custom-jquery', ELEX_DISCOUNT_PER_COUNTRY_MAIN_URL_PATH . '/assets/js/dpc-plugin-scripts.js', array( 'jquery' ), '1.0', false );
    42                 wp_enqueue_script( 'elex-dpc-custom-jquery' );
    43         } 
    44               $countries_available = array();
    45               $countries_obj      = new WC_Countries();
     40            wp_enqueue_style( 'woocommerce_admin_styles', $woocommerce->plugin_url() . '/assets/css/admin.css', array(), $woocommerce_version, false );
     41            wp_register_style( 'elex-dpc-plugin-styles', ELEX_DISCOUNT_PER_COUNTRY_MAIN_URL_PATH . '/assets/css/dpc-plugin-styles.css', array(), $woocommerce_version, false );
     42            wp_enqueue_style( 'elex-dpc-plugin-styles' );
     43            wp_register_script( 'elex-dpc-custom-jquery', ELEX_DISCOUNT_PER_COUNTRY_MAIN_URL_PATH . '/assets/js/dpc-plugin-scripts.js', array( 'jquery' ), '1.0', false );
     44            wp_enqueue_script( 'elex-dpc-custom-jquery' );
     45        }
     46        $countries_available = array();
     47        $countries_obj = new WC_Countries();
    4648        foreach ( $countries_obj->__get( 'countries' ) as $allowed_c ) {
    4749            $countries_available['country_id'] = $allowed_c;
    4850        }
    49                  
    50               $countries_available['tooltip']['nodiscount']           = __( 'No country discounts have been specified. Select a country from the drop-down to set up a discount.', 'elex-discount-per-country' );
    51               $countries_available['tooltip']['allcountriesselected'] = __( 'All available country have been selected', 'elex-discount-per-country' );
    52               $countries_available['tooltip']['inputalert']           = __( 'Please enter value between 0 to 100', 'elex-discount-per-country' );
    53               $countries_available['tooltip']['toggleon']             = __( 'Click here to enable the discount', 'elex-discount-per-country' );
    54               $countries_available['tooltip']['toggleoff']            = __( 'Click here to disable the discount', 'elex-discount-per-country' );
    55               $countries_available['tooltip']['inputtooltip']         = __( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' );
    56               $countries_available['tooltip']['remove']               = __( 'Click here to remove the discount.', 'elex-discount-per-country' );
    57               $countries_available['error_message']['nofieldsfilled'] = __( 'Please fill in the fields before adding a discount rule', 'elex-discount-per-country' );
    58          
    59               wp_localize_script( 'elex-dpc-custom-jquery', 'elexdpc_translations', $countries_available );
    60     }
    61        
     51
     52        $countries_available['tooltip']['nodiscount'] = __( 'No country discounts have been specified. Select a country from the drop-down to set up a discount.', 'elex-discount-per-country' );
     53        $countries_available['tooltip']['allcountriesselected'] = __( 'All available country have been selected', 'elex-discount-per-country' );
     54        $countries_available['tooltip']['inputalert'] = __( 'Please enter value between 0 to 100', 'elex-discount-per-country' );
     55        $countries_available['tooltip']['toggleon'] = __( 'Click here to enable the discount', 'elex-discount-per-country' );
     56        $countries_available['tooltip']['toggleoff'] = __( 'Click here to disable the discount', 'elex-discount-per-country' );
     57        $countries_available['tooltip']['inputtooltip'] = __( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' );
     58        $countries_available['tooltip']['remove'] = __( 'Click here to remove the discount.', 'elex-discount-per-country' );
     59        $countries_available['tooltip']['nodiscount-dpc'] = __( 'No Payments', 'elex-discount-per-country' );
     60        $countries_available['error_message']['nofieldsfilled'] = __( 'Please fill in the fields before adding a discount rule', 'elex-discount-per-country' );
     61
     62        wp_localize_script( 'elex-dpc-custom-jquery', 'elexdpc_translations', $countries_available );
     63    }
     64
    6265
    6366    public function get_sections() {
    64        
    6567        $sections = array(
    66             ''                    => __( 'General Settings', 'elex-discount-per-country' ),
     68            '' => __( 'General Settings', 'elex-discount-per-country' ),
    6769            'interested_products' => __( 'Related Products!', 'elex-discount-per-country' ),
    68            
     70
    6971        );
    7072        /**
     
    7779
    7880    public function output_sections() {
    79         global $current_section;
     81         global $current_section;
    8082        $sections = $this->get_sections();
    8183        if ( empty( $sections ) || 1 === count( $sections ) ) {
     
    9496        $settings = array();
    9597
    96                        
     98
    9799        if ( 'interested_products' === $current_section ) {
    98100            $settings = array();
     
    105107                    'type' => 'title',
    106108                    'desc' => __( 'Helps you configure and apply a discount on the Checkout page based on the shipping states/country selected by the customer.' ),
    107                     'id'   => 'elex-discount-per-country_title',
     109                    'id' => 'elex-discount-per-country_title',
    108110                ),
    109                 'section'       => array(
    110                     'name'        => __( 'Checkout discount label', 'elex-discount-per-country' ),
    111                     'type'        => 'text',
    112                     'placeholder' => __( 'Enter custom discount label', 'elex-discount-per-country' ),
    113                     'desc_tip'    => true,
    114                     'css'         => 'width:300px',
    115                     'desc'        => __( 'Enter the text to be displayed on checkout. The default text is <strong> Discount per country</strong>.', 'elex-discount-per-country' ),
    116                     'id'          => 'elex-discount-per-country_label',
     111
     112                'section_end' => array(
     113                    'type' => 'sectionend',
     114                    'id' => 'elex-discount-per-country_end',
    117115                ),
    118        
    119                 'section_end'   => array(
    120                     'type' => 'sectionend',
    121                     'id'   => 'elex-discount-per-country_end',
    122                 ),
    123            
    124                
    125                
    126                                
     116
     117
     118
     119
    127120            );
    128121        }
     
    135128
    136129    }
    137    
     130
    138131
    139132    public function output() {
    140         global $current_section;
    141        
     133      global $current_section;
     134
    142135
    143136        if ( 'interested_products' === $current_section ) {
     
    145138            include_once __DIR__ . '/market.php';
    146139        } else {
    147        
     140
    148141
    149142            $countries_obj = new WC_Countries();
    150             $countries     = $countries_obj->__get( 'countries' );
    151             $settings      = $this->get_settings();
     143            $countries = $countries_obj->__get( 'countries' );
     144            $settings = $this->get_settings();
    152145            WC_Admin_Settings::output_fields( $settings );
    153                        
     146
    154147            $countries_available = array();
    155148            foreach ( $countries_obj->__get( 'countries' ) as $allowed_c ) {
     
    165158        // Prepare the data
    166159        // save it
    167         $nonce  = isset( $_POST['nounce_verify'] ) ? sanitize_text_field( wp_unslash( $_POST['nounce_verify'] ) ) : '';
     160        $nonce = isset( $_POST['nounce_verify'] ) ? sanitize_text_field( wp_unslash( $_POST['nounce_verify'] ) ) : '';
    168161        $verify = wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nounce_verify'] ) ), 'form_data' );
    169162
     
    174167
    175168        $countries_obj = new WC_Countries();
    176         $countries     = $countries_obj->__get( 'countries' );
     169        $countries = $countries_obj->__get( 'countries' );
    177170        global $current_section;
    178171        $settings = $this->get_settings();
    179172        WC_Admin_Settings::save_fields( $settings );
    180         $repo        = new ELEXDPC_Discount_Per_Country_Model();
    181         $items_count = isset( $_POST['elex_discount_per_country_options'] ) ? count( $_POST['elex_discount_per_country_options'] ) : 0;
    182         $i           = -1;
    183         $items_added = 0;
    184            
    185         while ( $items_added < $items_count ) {
    186             $i++;
    187             if ( ! isset( $_POST['elex_discount_per_country_options'][ $i ] ) ) {
    188                 continue;
    189             }
    190             $country_codes = isset( $_POST['elex_discount_per_country_options'][ $i ]['country_code'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['country_code'] ) ) : '';
    191             $country_codes = explode( ',', $country_codes );
    192            
     173        $repo = new ELEXDPC_Discount_Per_Country_Model();
     174        // Use filter_input to retrieve POSTed array safely when available, fall back to wp_unslash.
     175        $raw_options = filter_input( INPUT_POST, 'elex_discount_per_country_options', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
     176        if ( null === $raw_options || false === $raw_options ) {
     177            // Avoid direct $_POST usage to satisfy PHPCS; fall back to empty array.
     178            $raw_options = array();
     179        }
     180
     181        // Recursively sanitize the incoming options to satisfy PHPCS/WPCS checks.
     182        $sanitize_recursive = function ( $value ) use ( &$sanitize_recursive ) {
     183            if ( is_array( $value ) ) {
     184                return array_map( $sanitize_recursive, $value );
     185            }
     186            return is_string( $value ) ? sanitize_text_field( $value ) : $value;
     187        };
     188
     189        $options = is_array( $raw_options ) ? $sanitize_recursive( $raw_options ) : array();
     190
     191        foreach ( $options as $option ) {
     192            $post_country_codes = isset( $option['country_code'] ) ? $option['country_code'] : '';
     193
     194            if ( is_array( $post_country_codes ) ) {
     195                $country_codes = array_map( 'sanitize_text_field', $post_country_codes );
     196            } else {
     197                $country_codes = explode( ',', sanitize_text_field( $post_country_codes ) );
     198            }
     199
    193200            foreach ( $country_codes as $country_code ) {
    194                 if ( ! $country_code ) {
     201                if ( empty( $country_code ) ) {
    195202                    continue;
    196203                }
    197204                $discount_per_country = array();
    198                 $state_code           = strpos( $country_code, ':' );
    199                 if ( false === $state_code ) {
    200                     $state_code = 0;
     205                $state_code_pos = strpos( $country_code, ':' );
     206
     207                if ( false === $state_code_pos ) {
     208                    $discount_per_country['country_code'] = $country_code;
     209                    $discount_per_country['status'] = isset( $option['status'] ) ? ELEXDPC_Discount_Per_Country_Rule::STATUS_ENABLE : ELEXDPC_Discount_Per_Country_Rule::STATUS_DISABLE;
     210
     211                    $discount_per_country['country_name'] = isset( $countries[ $country_code ] ) ? $countries[ $country_code ] : $country_code;
     212                    $discount_per_country['discount'] = isset( $option['discount'] ) ? sanitize_text_field( $option['discount'] ) : '';
     213                    $discount_per_country['discount_type'] = isset( $option['discount_type'] ) ? sanitize_text_field( $option['discount_type'] ) : 'percentage';
     214                    $discount_per_country['start_date'] = isset( $option['start_date'] ) ? sanitize_text_field( $option['start_date'] ) : '';
     215                    $discount_per_country['end_date'] = isset( $option['end_date'] ) ? sanitize_text_field( $option['end_date'] ) : '';
     216                    $discount_per_country['label'] = isset( $option['label'] ) ? sanitize_text_field( $option['label'] ) : '';
     217
     218                    $repo->add( ELEXDPC_Discount_Per_Country_Rule::build( $discount_per_country ) );
     219
    201220                } else {
    202                    $state_code = substr( $country_code, strpos( $country_code, ':' ) + 1 );
     221                    $state_code = substr( $country_code, $state_code_pos + 1 );
     222                    $countrycode = substr( $country_code, 0, $state_code_pos );
     223                    $states = WC()->countries->get_states( $countrycode );
     224                    $statename = isset( $states[ $state_code ] ) ? $states[ $state_code ] : $state_code;
     225
     226                    $discount_per_country['country_code'] = $countrycode . ':' . $state_code;
     227                    $discount_per_country['status'] = isset( $option['status'] ) ? ELEXDPC_Discount_Per_Country_Rule::STATUS_ENABLE : ELEXDPC_Discount_Per_Country_Rule::STATUS_DISABLE;
     228
     229                    $discount_per_country['country_name'] = $statename . ', ' . ( isset( $countries[ $countrycode ] ) ? $countries[ $countrycode ] : $countrycode );
     230                    $discount_per_country['discount'] = isset( $option['discount'] ) ? sanitize_text_field( $option['discount'] ) : '';
     231                    $discount_per_country['discount_type'] = isset( $option['discount_type'] ) ? sanitize_text_field( $option['discount_type'] ) : 'percentage';
     232                    $discount_per_country['start_date'] = isset( $option['start_date'] ) ? sanitize_text_field( $option['start_date'] ) : '';
     233                    $discount_per_country['end_date'] = isset( $option['end_date'] ) ? sanitize_text_field( $option['end_date'] ) : '';
     234                    $discount_per_country['label'] = isset( $option['label'] ) ? sanitize_text_field( $option['label'] ) : '';
     235
     236                    $repo->add( ELEXDPC_Discount_Per_Country_Rule::build( $discount_per_country ) );
    203237                }
    204 
    205                 if ( 0 !== $state_code ) {
    206                     $countrycode                          = substr( $country_code, 0, strpos( $country_code, ':' ) );
    207                     $states                               = WC()->countries->get_states( $countrycode );
    208                     $statename                            = $states[ $state_code ];
    209                     $discount_per_country['country_code'] = $countrycode . ':' . $state_code;
    210                     $discount_per_country['status']       = isset( $_POST['elex_discount_per_country_options'][ $i ]['status'] ) ? ELEXDPC_Discount_Per_Country_Rule::STATUS_ENABLE : ELEXDPC_Discount_Per_Country_Rule::STATUS_DISABLE;
    211                    
    212                     $discount_per_country['country_name'] = $statename . ',' . $countries[ $countrycode ];
    213                     $discount_per_country['discount']     = isset( $_POST['elex_discount_per_country_options'][ $i ]['discount'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['discount'] ) ) : '';
    214                     $discount_per_country['start_date']   = isset( $_POST['elex_discount_per_country_options'][ $i ]['start_date'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['start_date'] ) ) : '';
    215                     $discount_per_country['end_date']     = isset( $_POST['elex_discount_per_country_options'][ $i ]['end_date'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['end_date'] ) ) : '';
    216                    
    217 
    218                     $repo->add( ELEXDPC_Discount_Per_Country_Rule::build( $discount_per_country ) );
    219 
    220                 } else {
    221                     $discount_per_country['country_code'] = $country_code;
    222                     $discount_per_country['status']       = isset( $_POST['elex_discount_per_country_options'][ $i ]['status'] ) ? ELEXDPC_Discount_Per_Country_Rule::STATUS_ENABLE : ELEXDPC_Discount_Per_Country_Rule::STATUS_DISABLE;
    223                    
    224                     $discount_per_country['country_name'] = $countries[ $country_code ];
    225                     $discount_per_country['discount']     = isset( $_POST['elex_discount_per_country_options'][ $i ]['discount'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['discount'] ) ) : '';
    226                     $discount_per_country['start_date']   = isset( $_POST['elex_discount_per_country_options'][ $i ]['start_date'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['start_date'] ) ) : '';
    227                     $discount_per_country['end_date']     = isset( $_POST['elex_discount_per_country_options'][ $i ]['end_date'] ) ? sanitize_text_field( wp_unslash( $_POST['elex_discount_per_country_options'][ $i ]['end_date'] ) ) : '';
    228                     $repo->add( ELEXDPC_Discount_Per_Country_Rule::build( $discount_per_country ) );
    229 
    230                 } 
    231             }
    232             $items_added++;
    233 
    234         }                   
     238            }
     239        }
    235240        $repo->save();
    236            
    237        
     241
     242
    238243        if ( $current_section ) {
    239244            /**
     
    254259        }
    255260
    256         $order_date                  = strtotime( wp_date( 'd-m-Y\TH:i' ) );
    257         $PWD_Selected_Country_id     = WC()->customer->get_shipping_country();
    258         $shipping_state              = WC()->customer->get_shipping_state();
     261        $order_date = strtotime( wp_date( 'd-m-Y\TH:i' ) );
     262        $PWD_Selected_Country_id = WC()->customer->get_shipping_country();
     263        $shipping_state = WC()->customer->get_shipping_state();
    259264        $selected_country_with_state = $PWD_Selected_Country_id . ':' . $shipping_state;
     265
    260266        if ( empty( $PWD_Selected_Country_id ) ) {
    261267            return 0;
     
    264270        $repo = new ELEXDPC_Discount_Per_Country_Model();
    265271        $repo->build();
    266         $PWD_subtotal      = $PWD_cart->subtotal;
    267         $PWD_label_default = 'Discount per country';
    268 
    269         $PWD_label            = ! empty( get_option( 'elex-discount-per-country_label' ) ) ? get_option( 'elex-discount-per-country_label' ) : $PWD_label_default;
     272        $PWD_subtotal = $PWD_cart->subtotal;
     273
    270274        $discount_per_country = $repo->find( $PWD_Selected_Country_id );
    271         $country_with_state   = $repo->find( $selected_country_with_state );
    272 
    273         if ( $discount_per_country ) { 
    274            
    275             if ( ( $discount_per_country && $discount_per_country->is_enabled() &&
    276             $order_date >= strtotime( $discount_per_country->start_date ) &&
    277             $order_date <= strtotime( $discount_per_country->end_date ) ) ||
    278             ( $discount_per_country && $discount_per_country->is_enabled() &&
    279              '' === $discount_per_country->start_date && '' === $discount_per_country->end_date ) ||
    280              ( $discount_per_country && $discount_per_country->is_enabled() &&
    281               ( '' === $discount_per_country->start_date && $order_date <= strtotime( $discount_per_country->end_date ) ) ||
    282              ( '' === $discount_per_country->end_date && $order_date >= strtotime( $discount_per_country->start_date ) ) ) ) {
    283 
    284                 if ( $country_with_state && $country_with_state->is_enabled() ) {
    285                     if ( ( $country_with_state && $country_with_state->is_enabled() &&
    286                     $order_date >= strtotime( $country_with_state->start_date ) &&
    287                     $order_date <= strtotime( $country_with_state->end_date ) ) ||
    288                     ( $country_with_state && $country_with_state->is_enabled() &&
    289                  '' === $country_with_state->start_date && '' === $country_with_state->end_date ) ||
    290                  ( $country_with_state && $country_with_state->is_enabled() &&
    291                   ( '' === $country_with_state->start_date && $order_date <= strtotime( $country_with_state->end_date ) ) ||
    292                  ( '' === $country_with_state->end_date && $order_date >= strtotime( $country_with_state->start_date ) ) ) ) {
    293                         $PWD_discount = ( $country_with_state->discount ) * $PWD_subtotal / 100;
    294                         $PWD_cart -> add_fee( $PWD_label, -$PWD_discount );
    295    
    296                     } else {
    297                         $PWD_discount = ( $discount_per_country->discount ) * $PWD_subtotal / 100;
    298                         $PWD_cart -> add_fee( $PWD_label, -$PWD_discount );
    299                     }               
    300                 } else {
    301 
    302                     $PWD_discount = ( $discount_per_country->discount ) * $PWD_subtotal / 100;
    303                     $PWD_cart->add_fee( $PWD_label, -$PWD_discount );
    304                 }   
    305             }       
    306         }
    307 
    308         if ( $country_with_state && $country_with_state->is_enabled() ) {
    309             if ( ( $country_with_state && $country_with_state->is_enabled() &&
    310             $order_date >= strtotime( $country_with_state->start_date ) &&
    311             $order_date <= strtotime( $country_with_state->end_date ) ) ||
    312             ( $country_with_state && $country_with_state->is_enabled() &&
    313              '' === $country_with_state->start_date && '' === $country_with_state->end_date ) ||
    314              ( $country_with_state && $country_with_state->is_enabled() &&
    315               ( '' === $country_with_state->start_date && $order_date <= strtotime( $country_with_state->end_date ) ) ||
    316              ( '' === $country_with_state->end_date && $order_date >= strtotime( $country_with_state->start_date ) ) ) ) {
    317                         $PWD_discount = ( $country_with_state->discount ) * $PWD_subtotal / 100;
    318                         $PWD_cart -> add_fee( __( $PWD_label, 'elex-discount-per-country' ), -$PWD_discount );
    319    
    320             }       
    321         }
    322     }
     275        $country_with_state = $repo->find( $selected_country_with_state );
     276
     277        $rule_to_apply = null;
     278
     279        $is_valid_rule = function ( $rule, $order_date ) {
     280            if ( ! $rule || ! $rule->is_enabled() ) {
     281                return false;
     282            }
     283            $start = strtotime( $rule->start_date );
     284            $end = strtotime( $rule->end_date );
     285
     286            if ( ! empty( $rule->start_date ) && ! empty( $rule->end_date ) ) {
     287                return ( $order_date >= $start && $order_date <= $end );
     288            } elseif ( ! empty( $rule->start_date ) ) {
     289                return ( $order_date >= $start );
     290            } elseif ( ! empty( $rule->end_date ) ) {
     291                return ( $order_date <= $end );
     292            }
     293            return true;
     294        };
     295
     296        // Prioritize country+state specific rule over a general country rule
     297        if ( $is_valid_rule( $country_with_state, $order_date ) ) {
     298            $rule_to_apply = $country_with_state;
     299        } elseif ( $is_valid_rule( $discount_per_country, $order_date ) ) {
     300            $rule_to_apply = $discount_per_country;
     301        }
     302
     303        if ( $rule_to_apply ) {
     304            // build() already resolved the per-row label → old global label → ''
     305            // Just use it directly; fall back to 'Discount per country' if still empty.
     306            $label_text = trim( $rule_to_apply->label );
     307            if ( '' === $label_text ) {
     308                $label_text = __( 'Discount per country', 'elex-discount-per-country' );
     309            }
     310            $label = $label_text;
     311
     312            if ( 'fixed' === $rule_to_apply->discount_type ) {
     313                $PWD_discount = floatval( $rule_to_apply->discount );
     314            } else {
     315                $PWD_discount = ( floatval( $rule_to_apply->discount ) * $PWD_subtotal ) / 100;
     316            }
     317
     318            // Ensure discount doesn't exceed the subtotal negatively
     319            if ( $PWD_subtotal < $PWD_discount ) {
     320                $PWD_discount = $PWD_subtotal;
     321            }
     322
     323            // Yoda conditions preferred by WPCS for literal comparisons.
     324            if ( 0 < $PWD_discount ) {
     325                $PWD_cart->add_fee( __( $label, 'elex-discount-per-country' ), -$PWD_discount );
     326            }
     327        }
     328    }
    323329
    324330    public function add_action_links( $links ) {
     
    329335        return array_merge( $plugin_links, $links );
    330336    }
    331    
     337
    332338}
    333339
  • elex-discount-per-country/trunk/includes/form-settings-template-dpc.php

    r3460057 r3492012  
    77 */
    88
    9 require_once  __DIR__ . '/class-discount-per-country.php';
     9require_once __DIR__ . '/class-discount-per-country.php';
    1010$repo = new ELEXDPC_Discount_Per_Country_Model();
    1111$repo->build();
     
    1818global $woocommerce;
    1919
    20 $allowed_countries   = WC()->countries->get_shipping_countries();
     20$allowed_countries = WC()->countries->get_shipping_countries();
    2121$shipping_continents = WC()->countries->get_shipping_continents();
    22 $zone                = new WC_Shipping_Zone();
    23 $locations           = array();
    24 $postcodes           = array();
     22$zone = new WC_Shipping_Zone();
     23$locations = array();
     24$postcodes = array();
    2525
    2626foreach ( $zone->get_zone_locations() as $location ) {
     
    3333?>
    3434
    35 <tr valign="top" >
     35<tr valign="top">
    3636    <td class="forminp" colspan="3" style="padding-left:0px">
    3737        <table class="fields_adjustment_dpc widefat" id="elex_discount_per_country_options">
    38         <input type="hidden" name="nounce_verify" value="<?php echo esc_attr( $nonce ); ?>">
     38            <input type="hidden" name="nounce_verify" value="<?php echo esc_attr( $nonce ); ?>">
    3939            <thead>
    40                 <th class="table_header" >&nbsp;<i class="fas fa-toggle-off"></i></th>
    41                 <th class="table_header"  ><?php esc_html_e( 'Shipping State/Country', 'elex-discount-per-country' ); ?></th>
    42                 <th class="table_header" ><?php esc_html_e( 'Discount(%)', 'elex-discount-per-country' ); ?></th>
    43                 <th class="table_header" ><?php esc_html_e( 'From date', 'elex-discount-per-country' ); ?></th>
    44                 <th class="table_header" ><?php esc_html_e( 'To date', 'elex-discount-per-country' ); ?></th>
    45                 <th class="table_header" ><?php esc_html_e( 'Status', 'elex-discount-per-country' ); ?></th>
    46                 <th class="table_header_remove" ><?php esc_html_e( 'Actions', 'elex-discount-per-country' ); ?></th>
     40                <th class="table_header table_col_1_dpc">&nbsp;<i class="fas fa-toggle-off"></i></th>
     41                <th class="table_header table_col_2_dpc">
     42                    <?php esc_html_e( 'Shipping State/Country', 'elex-discount-per-country' ); ?>
     43                </th>
     44                <th class="table_header table_col_type_dpc">
     45                    <?php esc_html_e( 'Discount type', 'elex-discount-per-country' ); ?>
     46                </th>
     47                <th class="table_header table_col_3_dpc">
     48                    <?php esc_html_e( 'Percentage / fixed amount', 'elex-discount-per-country' ); ?>
     49                </th>
     50                <th class="table_header table_col_label_dpc">
     51                    <?php esc_html_e( 'Discount label', 'elex-discount-per-country' ); ?>
     52                </th>
     53                <th class="table_header table_col_5_dpc">
     54                    <?php esc_html_e( 'From date', 'elex-discount-per-country' ); ?>
     55                </th>
     56                <th class="table_header table_col_6_dpc"><?php esc_html_e( 'To date', 'elex-discount-per-country' ); ?>
     57                </th>
     58                <th class="table_header table_col_4_dpc"><?php esc_html_e( 'Enable', 'elex-discount-per-country' ); ?>
     59                </th>
     60                <th class="table_header_remove remove_icon_discount_dpc">
     61                    <?php esc_html_e( 'Remove', 'elex-discount-per-country' ); ?>
     62                </th>
    4763            </thead>
    4864            <tbody id='elex_dpc_table_body'>
     
    5066
    5167                foreach ( $repo->get_items() as $key => $discount_per_country ) {
    52                        
     68
    5369                    ?>
    54                         <tr id='<?php echo esc_attr( $discount_per_country->country_code ); ?>' class='<?php echo esc_attr( $discount_per_country->country_name ); ?>'>
    55                         <td  class='table_col_1_dpc' ></td>
    56                         <td  class='table_col_2_dpc'>
    57                             <input type='hidden'  name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][country_code]' value='<?php echo esc_attr( $discount_per_country->country_code ); ?>' />
    58                             <input type='hidden' class='order' name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][country_name]' value='<?php echo esc_attr( $discount_per_country->country_name ); ?>' />
    59                            
    60                             <span class="bold_span" ><?php echo esc_html( $discount_per_country->country_name ); ?></span>
    61                         </td>
    62                         <td class='table_col_3_dpc' title='<?php esc_html_e( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' ); ?>' >
    63                             <input type='number'  min='0' max='100' step="any" class='order' name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][discount]' value='<?php echo esc_attr( $discount_per_country->discount ); ?>' required>
    64                         </td>
    65                         <td class='table_col_5_dpc'    title="<?php esc_html_e( 'Start Date from which discount will be applied,Leave blank if you do not restrict based on  date', 'elex-discount-per-country' ); ?>">
    66                         <input type='datetime-local'  class='elex_discount_per_country_from_date' name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][start_date]' value='<?php echo esc_attr( $discount_per_country->start_date ); ?>' >
    67 
    68                         </td>
    69                         <td class='table_col_6_dpc'  title="<?php esc_html_e( 'Discount will not be applied after this date,Leave blank if you do not restrict based on date', 'elex-discount-per-country' ); ?>">
    70                         <input type='datetime-local'  class='elex_discount_per_country_to_date' name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][end_date]' value='<?php echo esc_attr( $discount_per_country->end_date ); ?>' >
    71 
    72                         </td>
    73            
    74                             <td class='table_col_4_dpc' >
    75                                 <label title='<?php esc_html_e( 'Click here to disable the discount.', 'elex-discount-per-country' ); ?>' class='switch'>
    76                                    
    77                                     <input
    78                                         type='checkbox'
    79                                         class='checkbox_click'
    80                                         <?php echo esc_html( $discount_per_country->is_enabled() ? 'checked' : '' ); ?>
    81                                         name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][status]'
    82                                         value= 'yes' />
    83                                     <span class='slider round'></span>
    84                                 </label>
    85                             </td>
    86 
    87                             <td class='remove_icon_discount_dpc' title='<?php esc_html_e( 'Click here to remove the discount.', 'elex-discount-per-country' ); ?>'></td>
    88                         </tr>
    89                         <?php
     70                    <tr id='<?php echo esc_attr( $discount_per_country->country_code ); ?>'
     71                        class='<?php echo esc_attr( $discount_per_country->country_name ); ?>'>
     72                        <td class='table_col_1_dpc'></td>
     73                        <td class='table_col_2_dpc'>
     74                            <input type='hidden'
     75                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][country_code]'
     76                                value='<?php echo esc_attr( $discount_per_country->country_code ); ?>' />
     77                            <input type='hidden' class='order'
     78                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][country_name]'
     79                                value='<?php echo esc_attr( $discount_per_country->country_name ); ?>' />
     80
     81                            <span class="bold_span"><?php echo esc_html( $discount_per_country->country_name ); ?></span>
     82                        </td>
     83                        <td class='table_col_type_dpc'>
     84                            <select
     85                                name="elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][discount_type]">
     86                                <option value="percentage" <?php selected( $discount_per_country->discount_type, 'percentage' ); ?>><?php esc_html_e( 'Percentage', 'elex-discount-per-country' ); ?>
     87                                </option>
     88                                <option value="fixed" <?php selected( $discount_per_country->discount_type, 'fixed' ); ?>>
     89                                    <?php esc_html_e( 'Fixed Amount', 'elex-discount-per-country' ); ?>
     90                                </option>
     91                            </select>
     92                        </td>
     93                        <td class='table_col_3_dpc'
     94                            title='<?php esc_html_e( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' ); ?>'>
     95                            <input type='number' min='0' max='100' step="any" class='order dpc-discount-input'
     96                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][discount]'
     97                                value='<?php echo esc_attr( $discount_per_country->discount ); ?>' required>
     98                        </td>
     99                        <td class='table_col_label_dpc'>
     100                            <input type='text'
     101                                placeholder="<?php esc_html_e( 'Discount label', 'elex-discount-per-country' ); ?>"
     102                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][label]'
     103                                value='<?php echo esc_attr( $discount_per_country->label ); ?>'>
     104                        </td>
     105                        <td class='table_col_5_dpc'
     106                            title="<?php esc_html_e( 'Start Date from which discount will be applied,Leave blank if you do not restrict based on  date', 'elex-discount-per-country' ); ?>">
     107                            <input type='datetime-local' class='elex_discount_per_country_from_date'
     108                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][start_date]'
     109                                value='<?php echo esc_attr( $discount_per_country->start_date ); ?>'>
     110
     111                        </td>
     112                        <td class='table_col_6_dpc'
     113                            title="<?php esc_html_e( 'Discount will not be applied after this date,Leave blank if you do not restrict based on date', 'elex-discount-per-country' ); ?>">
     114                            <input type='datetime-local' class='elex_discount_per_country_to_date'
     115                                name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][end_date]'
     116                                value='<?php echo esc_attr( $discount_per_country->end_date ); ?>'>
     117
     118                        </td>
     119
     120                        <td class='table_col_4_dpc'>
     121                            <label
     122                                title='<?php esc_html_e( 'Click here to disable the discount.', 'elex-discount-per-country' ); ?>'
     123                                class='switch'>
     124
     125                                <input type='checkbox' class='checkbox_click' <?php echo esc_html( $discount_per_country->is_enabled() ? 'checked' : '' ); ?>
     126                                    name='elex_discount_per_country_options[<?php echo esc_attr( $key ); ?>][status]'
     127                                    value='yes' />
     128                                <span class='slider round'></span>
     129                            </label>
     130                        </td>
     131
     132                        <td class='remove_icon_discount_dpc'
     133                            title='<?php esc_html_e( 'Click here to remove the discount.', 'elex-discount-per-country' ); ?>'>
     134                            <span class="remove-btn-circle"><i class="fas fa-minus"></i></span>
     135                        </td>
     136                    </tr>
     137                    <?php
    90138                }
    91            
     139
    92140                if ( empty( $repo->get_items() ) ) {
    93141                    ?>
    94142
    95143                    <tr id='nodiscount-dpc' class='nodiscount-dpc'>
    96                     <td class='table_col_1_dpc'></td>
    97                     <td class='table_col_2_dpc'>
    98                         <span class='wc-country-name' id='no_discount_available_dpc'><?php esc_html_e( 'No  discounts have been specified. Select a country from the drop-down to set up a discount.', 'elex-discount-per-country' ); ?></span>
    99                     </td>
    100                     <td class='table_col_3_dpc'></td>
    101                     <td class='table_col_5_dpc'></td>
    102                     <td class='table_col_6_dpc'></td>
    103                     <td class='table_col_4_dpc'></td>
    104 
     144                        <td colspan="9" style="text-align: center; padding: 24px 0;">
     145                            <span
     146                                id='no_discount_available_dpc'><?php esc_html_e( 'No  discounts have been specified. Select a country from the drop-down to set up a discount.', 'elex-discount-per-country' ); ?></span>
     147                            <div class="no-payments-btn">
     148                                <script>document.write(elexdpc_translations['tooltip']['nodiscount-dpc']);</script>
     149                            </div>
     150                        </td>
    105151                    </tr>
    106 
    107152                    <?php
    108153                }
    109            
    110 
    111154                ?>
    112 
    113155            </tbody>
    114             <br><br>
    115             <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
    116             <tr  class="table_input_raw_dpc">
    117            
    118                 <td></td>
    119                 <td>
    120                 <select title='<?php esc_html_e( 'Select zone for which you want to apply discount', 'elex-discount-per-country' ); ?>'  multiple="multiple" data-attribute="zone_locations" id="zone_locations" name="zone_locations" data-placeholder="<?php esc_attr_e( 'Select region', 'elex-discount-per-country' ); ?>" class="wc-shipping-zone-region-select chosen_select">
    121                         <?php
    122                    
    123                         foreach ( $shipping_continents as $continent_code => $continent ) {
    124 
    125                             $countries = array_intersect( array_keys( $allowed_countries ), $continent['countries'] );
    126 
    127                             foreach ( $countries as $country_code ) {
    128                             $flag = 1;
    129 
    130                             $discount_per_country = $repo->find( $country_code );
     156            <tfoot>
     157                <tr>
     158                    <td colspan="9" style="text-align: center; padding: 16px 0;">
     159                        <button type="button" id="elex_dpc_add_field_discount" class="elex-add-new-btn">
     160                            <span class="icon-circle">+</span>
     161                            <span
     162                                class="btn-text"><?php esc_html_e( 'Add New Discount', 'elex-discount-per-country' ); ?></span>
     163                        </button>
     164                    </td>
     165                </tr>
     166            </tfoot>
     167        </table>
     168
     169        <div id="elex_dpc_add_new_discount_template" style="display: none;">
     170            <select
     171                title='<?php esc_html_e( 'Select zone for which you want to apply discount', 'elex-discount-per-country' ); ?>'
     172                multiple="multiple" data-attribute="zone_locations" id="zone_locations_template"
     173                name="zone_locations_template"
     174                data-placeholder="<?php esc_attr_e( 'Select region', 'elex-discount-per-country' ); ?>"
     175                class="wc-shipping-zone-region-select" style="width: 100%;">
     176                <?php
     177
     178                foreach ( $shipping_continents as $continent_code => $continent ) {
     179
     180                    $countries = array_intersect( array_keys( $allowed_countries ), $continent['countries'] );
     181
     182                    foreach ( $countries as $country_code ) {
     183                        $flag = 1;
     184
     185                        $discount_per_country = $repo->find( $country_code );
     186                        if ( $discount_per_country ) {
     187                            $flag = 0;
     188
     189                        }
     190                        if ( 1 === $flag ) {
     191                            echo '<option  value="' . esc_attr( $country_code ) . '"' . wc_selected( "country:$country_code", $locations ) . '>' . esc_html( '&nbsp;&nbsp; ' . $allowed_countries[ $country_code ] ) . '</option>';
     192                        }
     193                        $states = WC()->countries->get_states( $country_code );
     194
     195                        if ( $states ) {
     196                            foreach ( $states as $state_code => $state_name ) {
     197                                $country_with_state = $country_code . ':' . $state_code;
     198                                $discount_per_country = $repo->find( $country_with_state );
     199                                $flag = 1;
    131200                                if ( $discount_per_country ) {
    132201                                    $flag = 0;
    133                                    
    134202                                }
    135203                                if ( 1 === $flag ) {
    136                                     echo '<option  value="' . esc_attr( $country_code ) . '"' . wc_selected( "country:$country_code", $locations ) . '>' . esc_html( '&nbsp;&nbsp; ' . $allowed_countries[ $country_code ] ) . '</option>';
     204                                    echo '<option value="' . esc_attr( $country_code . ':' . $state_code ) . '"' . wc_selected( "state:$country_code:$state_code", $locations ) . '>' . esc_html( '&nbsp;&nbsp;&nbsp;&nbsp; ' . $state_name . ', ' . $allowed_countries[ $country_code ] ) . '</option>';
     205
    137206                                }
    138                                     $states = WC()->countries->get_states( $country_code );
    139 
    140                                 if ( $states ) {
    141                                     foreach ( $states as $state_code => $state_name ) {
    142                                         $country_with_state   = $country_code . ':' . $state_code;
    143                                         $discount_per_country = $repo->find( $country_with_state );
    144                                         $flag                 = 1;
    145                                         if ( $discount_per_country ) {
    146                                             $flag = 0;
    147                                         }
    148                                         if ( 1 === $flag ) {
    149                                             echo '<option value="' . esc_attr( $country_code . ':' . $state_code ) . '"' . wc_selected( "state:$country_code:$state_code", $locations ) . '>' . esc_html( '&nbsp;&nbsp;&nbsp;&nbsp; ' . $state_name . ', ' . $allowed_countries[ $country_code ] ) . '</option>';
    150 
    151                                         }                                       
    152                                     }
    153                                 }                           
    154207                            }
    155208                        }
    156                         ?>
    157                     </select>
    158 
    159                 </td>
    160                
    161                 <td>
    162                    
    163                     <input type='number' class='eraq_input_label' title="<?php esc_html_e( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' ); ?>" id="elex_discount_per_country_options_input_value"  value="0" min="0" max="100" step="any" >
    164                 </td>
    165                 <td>
    166                 <input type='datetime-local' value="" class='elex_discount_per_country_from_date' title="<?php esc_html_e( 'Start Date from which discount will be applied,Leave blank if you do not restrict based on  date', 'elex-discount-per-country' ); ?>" id="elex_discount_per_country_start_date"  min="<?php echo esc_attr( wp_date( 'Y-m-d\TH:i' ) ); ?>" >
    167                    
    168                 </td>
    169                 <td>
    170                 <input type='datetime-local' value="" class='elex_discount_per_country_to_date' title="<?php esc_html_e( 'Discount will not be applied after this date,Leave blank if you do not restrict based on date', 'elex-discount-per-country' ); ?>" id="elex_discount_per_country_end_date"  min="<?php echo esc_attr( wp_date( 'Y-m-d\TH:i' ) ); ?>"   >
    171 
    172                 </td>
    173                 <td>
    174                     <label class="switch" title='<?php esc_html_e( 'Click to enable or disable the discount', 'elex-discount-per-country' ); ?>'>
    175                       <input id="elex_discount_per_country_options_enabled" type="checkbox" checked>
    176                       <span class="slider round"></span>
    177                     </label>
    178                 </td>
    179                
    180                 <td>
    181                     <button name="submit" type="button" class="elex-dpc-btn-primary button-primary" title="<?php esc_html_e( 'Click here to add more discount.', 'elex-discount-per-country' ); ?>"  id="elex_dpc_add_field_discount"  >
    182                         <?php esc_html_e( 'Add', 'elex-discount-per-country' ); ?>
    183                     </button>
    184                 </td>
    185             </tr>
    186            
    187         </table>
    188        
     209                    }
     210                }
     211                ?>
     212            </select>
     213            <select id="elex_discount_per_country_discount_type_template" class="dpc-discount-type-select"
     214                name="elex_discount_per_country_discount_type_template">
     215                <option value="percentage">
     216                    <?php esc_html_e( 'Percentage', 'elex-discount-per-country' ); ?>
     217                </option>
     218                <option value="fixed">
     219                    <?php esc_html_e( 'Fixed Amount', 'elex-discount-per-country' ); ?>
     220                </option>
     221            </select>
     222            <input type="number" step="any" min="0" id="elex_discount_per_country_options_input_value_template"
     223                class="dpc-discount-input" name="elex_discount_per_country_options_input_value_template" value="0">
     224            <input type="text" id="elex_discount_per_country_label_template"
     225                placeholder="<?php esc_html_e( 'Discount label', 'elex-discount-per-country' ); ?>"
     226                name="elex_discount_per_country_label_template" value="">
     227            <input type='datetime-local' value="" class='elex_discount_per_country_from_date'
     228                title="<?php esc_html_e( 'Start Date from which discount will be applied,Leave blank if you do not restrict based on  date', 'elex-discount-per-country' ); ?>"
     229                id="elex_discount_per_country_start_date_template"
     230                min="<?php echo esc_attr( wp_date( 'Y-m-d\TH:i' ) ); ?>">
     231            <input type='datetime-local' value="" class='elex_discount_per_country_to_date'
     232                title="<?php esc_html_e( 'Discount will not be applied after this date,Leave blank if you do not restrict based on date', 'elex-discount-per-country' ); ?>"
     233                id="elex_discount_per_country_end_date_template"
     234                min="<?php echo esc_attr( wp_date( 'Y-m-d\TH:i' ) ); ?>">
     235            <label class="switch"
     236                title='<?php esc_html_e( 'Click to enable or disable the discount', 'elex-discount-per-country' ); ?>'>
     237                <input id="elex_discount_per_country_options_enabled_template" type="checkbox" checked>
     238                <span class="slider round"></span>
     239            </label>
     240        </div>
     241
     242        <script>
     243            jQuery(document).ready(function ($) {
     244                // Prevent 'e', '-', '+', 'E' in any discount input
     245                $(document).on('keydown', '.dpc-discount-input', function (e) {
     246                    if (['e', 'E', '-', '+'].includes(e.key)) {
     247                        e.preventDefault();
     248                    }
     249                });
     250
     251                // Conditional validation for all discount rows
     252                $(document).on('change', '.dpc-discount-type-select', function () {
     253                    var type = $(this).val();
     254                    var $row = $(this).closest('tr');
     255                    var $input = $row.find('.dpc-discount-input');
     256                    if (type === 'percentage') {
     257                        $input.attr('max', '100');
     258                        $input.attr('title', '<?php esc_html_e( 'Enter the discount percentage value from 0 to 100.', 'elex-discount-per-country' ); ?>');
     259                    } else {
     260                        $input.removeAttr('max');
     261                        $input.attr('title', '<?php esc_html_e( 'Enter the discount fixed amount (0 or more).', 'elex-discount-per-country' ); ?>');
     262                    }
     263                });
     264
     265                // Trigger change on all select on load to ensure tooltips/max are correct
     266                $('.dpc-discount-type-select').trigger('change');
     267
     268                // Change 'Save changes' text to 'Save Changes'
     269                $("button[name='save']").text('<?php esc_html_e( 'Save Changes', 'elex-discount-per-country' ); ?>');
     270            });
     271        </script>
     272
    189273
    190274    </td>
    191    
     275
    192276</tr>
  • elex-discount-per-country/trunk/readme.txt

    r3460057 r3492012  
    44Tags: discount based on shipping country, woocommerce
    55Requires at least: 3.0.1
    6 Stable tag: 1.2.0
     6Stable tag: 1.2.1
    77Tested up to: 6.9
    88License: GPLv2 or later
     
    5050== Changelog ==
    5151
     52= 1.2.1 =
     53* Enhanced validation and security
     54* Improved discount calculations
     55* Added support for fixed discounts
     56* Added custom discount labels for each payment method
     57
    5258= 1.2.0 =
    5359* Minor issue fixes
     
    130136== Upgrade Notice ==
    131137
     138= 1.2.1 =
     139* Enhanced validation and security
     140* Improved discount calculations
     141* Added support for fixed discounts
     142* Added custom discount labels for each payment method
     143
    132144= 1.2.0 =
    133145* Minor issue fixes
Note: See TracChangeset for help on using the changeset viewer.