Unable to disable Rounding after Saving

Tags: #<Tag:0x00007f8b2b176778>

Dear HandsonTable Community,

I hope you’re all fine an in good health.

I am currently using a script to create Purchase orders that has been developed using HandsonTable. The script works absolutely fine, however I am having issues with some rounding and decimals, especially for the field quantity. If I am to enter a straight value such as 10 it all works fine, however I sometimes have values that come with decimals, such as 10.45 and I would like to enter this value, however it always ends up as a rounded value (and also no decimals) once I end up saving the actual order.

Here how I enter my data:

Result after saving:

As you can see, the value 40.25 became 40. I have tried a few things looking around the web, such as adding matissa in the number value and I’ve also tried to find some freelancer but none of them were able to help me get this resolved.

Please find below the code I was told is responsible for this - some expert help would be immensely appreciated, thank you.

    <script>

function removeCommas(str) {
  "use strict";
  return(str.replace(/,/g,''));
}

function dc_percent_change(invoker){
  "use strict";
  var total_mn = $('input[name="total_mn"]').val();
  var t_mn = (removeCommas(total_mn));
  var rs = (t_mn*invoker.value)/100;

  $('input[name="dc_total"]').val(numberWithCommas(rs));
  $('input[name="after_discount"]').val(numberWithCommas(t_mn - rs));

}

function dc_total_change(invoker){
  "use strict";
  var total_mn = $('input[name="total_mn"]').val();
  var t_mn = (removeCommas(total_mn));
  var rs = t_mn - (removeCommas(invoker.value));

  $('input[name="after_discount"]').val(numberWithCommas(rs));
}

$(function(){
  "use strict";
    validate_purorder_form();
    function validate_purorder_form(selector) {

        selector = typeof(selector) == 'undefined' ? '#pur_order-form' : selector;

        appValidateForm($(selector), {
            pur_order_name: 'required',
            pur_order_number: 'required',
            order_date: 'required',
            vendor: 'required',
        });
    }


});
function estimate_by_vendor(invoker){
  "use strict";
  if(invoker.value != 0){
    $.post(admin_url + 'purchase/estimate_by_vendor/'+invoker.value).done(function(response){
      response = JSON.parse(response);
      $('select[name="estimate"]').html('');
      $('select[name="estimate"]').append(response.result);
      $('select[name="estimate"]').selectpicker('refresh');
      $('#dropdown_menu_tax_total_type1').html('');
      $('#dropdown_menu_tax_total_type1').append('<span class="discount-type-selected">' + response.currency + '</span>');
      $('#dropdown_menu_tax_total_type2').html('');
      $('#dropdown_menu_tax_total_type2').append('<span class="discount-type-selected">' + response.currency + '</span>');
      $('#dropdown_menu_tax_total_type3').html('');
      $('#dropdown_menu_tax_total_type3').append('<span class="discount-type-selected">' + response.currency + '</span>');
    });

  }
}

<?php if(!isset($pur_order)){
?>	
function numberWithCommas(x) {
  "use strict";
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
var dataObject = [
      
    ];
  var hotElement = document.querySelector('#example');
    var hotElementContainer = hotElement.parentNode;
    var hotSettings = {
      data: dataObject,
      columns: [
        {
          data: 'item_code',
          renderer: customDropdownRenderer,
          editor: "chosen",
          width: 150,
          chosenOptions: {
              data: <?php echo json_encode($items); ?>
          }
        },
        {
          data: 'unit_id',
          renderer: customDropdownRenderer,
          editor: "chosen",
          width: 50,
          chosenOptions: {
              data: <?php echo json_encode($units); ?>
          },
          readOnly: true
    
        },
        {
          data: 'unit_price',
          type: 'numeric',
          numericFormat: {
            pattern: '0,0'
          },
          readOnly: true
        },
        {
          data: 'quantity',
          type: 'numeric',
      
        },
        {
          data: 'into_money',
          type: 'numeric',
          numericFormat: {
            pattern: '0,0'
          },
          readOnly: true
        },
        {
          data: 'tax',
          renderer: customDropdownRenderer,
          editor: "chosen",
          multiSelect:true,
          width: 50,
          chosenOptions: {
              multiple: true,
              data: <?php echo json_encode($taxes); ?>
          }
        },
        {
          data: 'total',
          type: 'numeric',
          numericFormat: {
            pattern: '0,0'
          },
          readOnly: true
        },{
          data: 'discount_%',
          type: 'numeric',
          renderer: customRenderer
        },
        {
          data: 'discount_money',
          type: 'numeric',
          numericFormat: {
            pattern: '0,0'
          }
        },
        {
          data: 'total_money',
          type: 'numeric',
          numericFormat: {
            pattern: '0,0'
          }
      
        }
      
      ],
      licenseKey: 'non-commercial-and-evaluation',
      stretchH: 'all',
      width: '100%',
      autoWrapRow: true,
      rowHeights: 30,
      columnHeaderHeight: 40,
      minRows: 10,
      maxRows: 40,
      rowHeaders: true,
      colWidths: [200,10,100,50,100,50,100,50,100,100],
      colHeaders: [
        '<?php echo _l('items'); ?>',
        '<?php echo _l('unit'); ?>',
        '<?php echo _l('unit_price'); ?>',
        '<?php echo _l('quantity'); ?>',
        '<?php echo _l('subtotal'); ?>',
        '<?php echo _l('tax'); ?>',
        '<?php echo _l('subtotal_after_tax'); ?>',
        '<?php echo _l('discount(%)').'(%)'; ?>',
        '<?php echo _l('discount(money)'); ?>',
        '<?php echo _l('total'); ?>',
      ],
      columnSorting: {
        indicator: true
      },
      autoColumnSize: {
        samplingRatio: 23
      },
      dropdownMenu: true,
      mergeCells: true,
      contextMenu: true,
      manualRowMove: true,
      manualColumnMove: true,
      multiColumnSorting: {
        indicator: true
      },
      filters: true,
      manualRowResize: true,
      manualColumnResize: true
    };


var hot = new Handsontable(hotElement, hotSettings);
hot.addHook('afterChange', function(changes, src) {
  if(changes !== null){
      changes.forEach(([row, prop, oldValue, newValue]) => {
        if(newValue != ''){
          if(prop == 'item_code'){
            $.post(admin_url + 'purchase/items_change/'+newValue).done(function(response){
              response = JSON.parse(response);

              hot.setDataAtCell(row,1, response.value.unit_id);
              hot.setDataAtCell(row,2, response.value.purchase_price);
              hot.setDataAtCell(row,4, response.value.purchase_price*hot.getDataAtCell(row,3));
            });
          }else if(prop == 'quantity'){
            hot.setDataAtCell(row,4, newValue*hot.getDataAtCell(row,2));
            hot.setDataAtCell(row,6, newValue*hot.getDataAtCell(row,2));
            hot.setDataAtCell(row,9, newValue*hot.getDataAtCell(row,2));
          }else if(prop == 'tax'){
            $.post(admin_url + 'purchase/tax_change/'+newValue).done(function(response){
              response = JSON.parse(response);
              hot.setDataAtCell(row,6, (response.total_tax*(hot.getDataAtCell(row,4)))/100 + (hot.getDataAtCell(row,4)));
              hot.setDataAtCell(row,9, (response.total_tax*(hot.getDataAtCell(row,4)))/100 + (hot.getDataAtCell(row,4)));
            });
          }else if(prop == 'discount_%'){
            hot.setDataAtCell(row,8, (newValue*(hot.getDataAtCell(row,6)))/100 );

          }else if(prop == 'discount_money'){
            hot.setDataAtCell(row,9, ((hot.getDataAtCell(row,6)) - newValue));
          }else if(prop == 'total_money'){
          var total_money = 0;
            for (var row_index = 0; row_index <= 40; row_index++) {
              if((hot.getDataAtCell(row_index, 9)) > 0){
                total_money += ((hot.getDataAtCell(row_index, 9)));
              }
            }
            $('input[name="total_mn"]').val(numberWithCommas(total_money));
          }
        }
      });
  }
  });
$('.save_detail').on('click', function() {
  $('input[name="pur_order_detail"]').val(hot.getData());   
});

function coppy_pur_estimate(){
  "use strict";
  var pur_estimate = $('select[name="estimate"]').val();
  if(pur_estimate != ''){
    hot.alter('remove_row',0,hot.countRows ());
    $.post(admin_url + 'purchase/coppy_pur_estimate/'+pur_estimate).done(function(response){
          response = JSON.parse(response);
          hot.updateSettings({
        data: response.result,
        });

          var total_money = 0;
          for (var row_index = 0; row_index <= 40; row_index++) {
            if((hot.getDataAtCell(row_index, 9)) > 0){
              total_money += ((hot.getDataAtCell(row_index, 9)));
            }
          }
          $('input[name="total_mn"]').val(numberWithCommas(total_money));
          $('input[name="dc_percent"]').val(numberWithCommas(response.dc_percent));
          $('input[name="dc_total"]').val(numberWithCommas(response.dc_total));
          $('input[name="after_discount"]').val(numberWithCommas(total_money - response.dc_total));
    });

    
  }else{
    alert_float('warning', '<?php echo _l('please_chose_pur_estimate'); ?>')
  }
}


<?php } else{ ?>

function numberWithCommas(x) {
  "use strict";
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

  var dataObject = <?php echo html_entity_decode($pur_order_detail); ?>;
  var hotElement = document.querySelector('#example');
    var hotElementContainer = hotElement.parentNode;
    var hotSettings = {
      data: dataObject,
      columns: [
        {
          data: 'id',
          type: 'numeric',
      
        },
        {
          data: 'pur_order',
          type: 'numeric',
      
        },
        {
          data: 'item_code',
          renderer: customDropdownRenderer,
          editor: "chosen",
          width: 150,
          chosenOptions: {
              data: <?php echo json_encode($items); ?>
          }
        },
        {
          data: 'unit_id',
          renderer: customDropdownRenderer,
          editor: "chosen",
          width: 50,
          chosenOptions: {
              data: <?php echo json_encode($units); ?>
          },
          readOnly: true
    
        },
        {
          data: 'unit_price',
          type: 'numeric',
          numericFormat: {
            pattern: '0,0'
          },
          readOnly: true
        },
        {
          data: 'quantity',
          type: 'numeric',
      
        },
        {
          data: 'into_money',
          type: 'numeric',
          numericFormat: {
            pattern: '0,0'
          },
          readOnly: true
        },
        {
          data: 'tax',
          renderer: customDropdownRenderer,
          editor: "chosen",
          multiSelect:true,
          width: 50,
          chosenOptions: {
              multiple: true,
              data: <?php echo json_encode($taxes); ?>
          }
        },
        {
          data: 'total',
          type: 'numeric',
          numericFormat: {
            pattern: '0,0'
          },
          readOnly: true
        },{
          data: 'discount_%',
          type: 'numeric',
          renderer: customRenderer
        },
        {
          data: 'discount_money',
          type: 'numeric',
          numericFormat: {
            pattern: '0,0'
          }
        },
        {
          data: 'total_money',
          type: 'numeric',
          numericFormat: {
            pattern: '0,0'
          }
      
        }
      
      ],
      licenseKey: 'non-commercial-and-evaluation',
      stretchH: 'all',
      width: '100%',
      autoWrapRow: true,
      rowHeights: 30,
      columnHeaderHeight: 40,
      minRows: 10,
      maxRows: 40,
      rowHeaders: true,
      colWidths: [0,0,200,50,100,50,100,50,100,50,100,100],
      colHeaders: [
        '',
        '',
        '<?php echo _l('items'); ?>',
        '<?php echo _l('unit'); ?>',
        '<?php echo _l('unit_price'); ?>',
        '<?php echo _l('quantity'); ?>',
        '<?php echo _l('subtotal'); ?>',
        '<?php echo _l('tax'); ?>',
        '<?php echo _l('subtotal_after_tax'); ?>',
        '<?php echo _l('discount(%)').'(%)'; ?>',
        '<?php echo _l('discount(money)'); ?>',
        '<?php echo _l('total'); ?>',
      ],
      columnSorting: {
        indicator: true
      },
      autoColumnSize: {
        samplingRatio: 23
      },
      dropdownMenu: true,
      mergeCells: true,
      contextMenu: true,
      manualRowMove: true,
      manualColumnMove: true,
      multiColumnSorting: {
        indicator: true
      },
      hiddenColumns: {
        columns: [0,1],
        indicators: true
      },
      filters: true,
      manualRowResize: true,
      manualColumnResize: true
    };


var hot = new Handsontable(hotElement, hotSettings);
hot.addHook('afterChange', function(changes, src) {
  if(changes !== null){
      changes.forEach(([row, prop, oldValue, newValue]) => {
        if(newValue != ''){
        if(prop == 'item_code'){
          $.post(admin_url + 'purchase/items_change/'+newValue).done(function(response){
            response = JSON.parse(response);

            hot.setDataAtCell(row,3, response.value.unit_id);
            hot.setDataAtCell(row,4, response.value.purchase_price);
            hot.setDataAtCell(row,6, response.value.purchase_price*hot.getDataAtCell(row,5));
          });
        }else if(prop == 'quantity'){
          hot.setDataAtCell(row,6, newValue*hot.getDataAtCell(row,4));
          hot.setDataAtCell(row,8, newValue*hot.getDataAtCell(row,4));
          hot.setDataAtCell(row,11, newValue*hot.getDataAtCell(row,4));
        }else if(prop == 'tax'){
          $.post(admin_url + 'purchase/tax_change/'+newValue).done(function(response){
            response = JSON.parse(response);
            hot.setDataAtCell(row,8, (response.total_tax*(hot.getDataAtCell(row,6)))/100 + (hot.getDataAtCell(row,6)));
            hot.setDataAtCell(row,11, (response.total_tax*(hot.getDataAtCell(row,6)))/100 + (hot.getDataAtCell(row,6)));
          });
        }else if(prop == 'discount_%'){
          hot.setDataAtCell(row,10, (newValue*(hot.getDataAtCell(row,8)))/100 );

        }else if(prop == 'discount_money'){
          hot.setDataAtCell(row,11, ((hot.getDataAtCell(row,8)) - newValue));
        }else if(prop == 'total_money'){
        var total_money = 0;
          for (var row_index = 0; row_index <= 40; row_index++) {
            if((hot.getDataAtCell(row_index, 11)) > 0){
              total_money += ((hot.getDataAtCell(row_index, 11)));
            }
          }
          $('input[name="total_mn"]').val(numberWithCommas(total_money));
        }
      }
      });
  }
  });
$('.save_detail').on('click', function() {
  $('input[name="pur_order_detail"]').val(hot.getData());   
});

id = $('select[name="vendor"]').val();
$.post(admin_url + 'purchase/estimate_by_vendor/'+id).done(function(response){
  response = JSON.parse(response);
  $('select[name="estimate"]').html('');
  $('select[name="estimate"]').append(response.result);
  $('select[name="estimate"]').val(<?php echo html_entity_decode($pur_order->estimate); ?>).change();
  $('select[name="estimate"]').selectpicker('refresh');
});

var total_money = 0;
for (var row_index = 0; row_index <= 40; row_index++) {
  if((hot.getDataAtCell(row_index, 11)) > 0){
    total_money += ((hot.getDataAtCell(row_index, 11)));
  }
  

}
$('input[name="total_mn"]').val(numberWithCommas(total_money));

function coppy_pur_estimate(){
  "use strict";
  var pur_estimate = $('select[name="estimate"]').val();
  if(pur_estimate != ''){
    hot.alter('remove_row',0,hot.countRows ());
    $.post(admin_url + 'purchase/coppy_pur_estimate/'+pur_estimate).done(function(response){
          response = JSON.parse(response);
          hot.updateSettings({
        data: response.result,
        });
        var total_money = 0;
        for (var row_index = 0; row_index <= 40; row_index++) {
          if((hot.getDataAtCell(row_index, 11)) > 0){
            total_money += ((hot.getDataAtCell(row_index, 11)));
          }
        }
        $('input[name="total_mn"]').val(numberWithCommas(total_money));
        $('input[name="dc_percent"]').val(numberWithCommas(response.dc_percent));
        $('input[name="dc_total"]').val(numberWithCommas(response.dc_total));
        $('input[name="after_discount"]').val(numberWithCommas(total_money - response.dc_total));  
    });
  }else{
    alert_float('warning', '<?php echo _l('please_chose_pur_estimate'); ?>')
  }
}

<?php } ?>
function customRenderer(instance, td, row, col, prop, value, cellProperties) {
  "use strict";
    Handsontable.renderers.TextRenderer.apply(this, arguments);
    if(td.innerHTML != ''){
      td.innerHTML = td.innerHTML + '%'
      td.className = 'htRight';
    }
}

function customDropdownRenderer(instance, td, row, col, prop, value, cellProperties) {
  "use strict";
    var selectedId;
    var optionsList = cellProperties.chosenOptions.data;
    
    if(typeof optionsList === "undefined" || typeof optionsList.length === "undefined" || !optionsList.length) {
        Handsontable.cellTypes.text.renderer(instance, td, row, col, prop, value, cellProperties);
        return td;
    }

    var values = (value + "").split("|");
    value = [];
    for (var index = 0; index < optionsList.length; index++) {

        if (values.indexOf(optionsList[index].id + "") > -1) {
            selectedId = optionsList[index].id;
            value.push(optionsList[index].label);
        }
    }
    value = value.join(", ");

    Handsontable.cellTypes.text.renderer(instance, td, row, col, prop, value, cellProperties);
    return td;
}

</script>

Hi @davidsierrahome

I was trying to recreate your issue with minimal settings taken from your code but I wasn’t able to achieve that error. I cannot reproduce the whole table with that code, can you please simplify it enough to the part where the issue is replicable?

Dear @adrian.szymanski thank you very much for getting back at me, appreciated. Could it be version related? I have just checked and my script is using Version: 7.4.2

Please kindly advise and thank you very much for your time

You can try to update the version to 8.0 at first, as this is the version where we introduced a lot of breaking changes. Here’s a migration guide: https://handsontable.com/docs/migration-from-7.4-to-8.0/#overview