2015-07-02 5 views
0

У меня есть неприятный баг с платежами в Magento, Paybox и SOAP веб-служб, идея заключается в следующем:Как изменить цену заказа Magento в центах?

  1. Оплата производится в центах $ 36,37 = 3637cents (Paybox - API)
  2. Что я пытаясь сделать это, чтобы превратить свою цену заказа в центах следующим образом:

    $cents = $order->getBaseGrandTotal() * 100;

  3. Также у меня есть мы b сервис SOAP (строгие типы), который respond этот $cents сумма, но он подтверждает это (int), то иногда магия происходит, а конвертированная сумма не является ожидаемой, конвертированный результат меньше, чем в процентах, в моем случае это может быть 3736.

    $prices = array(39.8699, 12.3299, 11.3211); 
    
    foreach ($prices as $price) { 
        $stuff = round($price, 2) * 100; 
    
        echo $stuff . PHP_EOL; 
    } 
    
    echo "After int conversion" . PHP_EOL; 
    
    foreach ($prices as $price) { 
        $stuff = (int) (round($price, 2) * 100); 
    
        echo $stuff . PHP_EOL; 
    } 
    

В результате получается следующее:

3987 
1233 
1132 
After int conversion 
3986 
1233 
1132 

Вопрос Есть ли способ, чтобы исправить эту ошибку, это кажется PHP ошибка?

+1

Подсказка: 'ini_set ('precision', 20); var_dump ($ цены); '. Не ошибка PHP: так работают компьютеры. –

+1

Это не ошибка в php, это ошибка в вашей логике. Вам придется иметь дело с четвертой и пятой цифрами. Очевидным ответом будет округление более 50 (4-я и 5-я цифры). И не делайте ничего меньше 50 (4-й и 5-й цифры). – Andrew

ответ

1

Ваш алгоритм обобщает как это:

  1. $price = 39.8699; // 39.869900000000001228
  2. round($price, 2) * 100; // 3986.9999999999995453
  3. (int)3986.9999999999995453; // 3986

Вы округление правильно везде, за исключением того, что в последней стадии, где ваши (int) литье обрезает. Округление будет более подходящим:

round($price * 100) 

сказал, что корень проблемы в том, что компьютеры используют двоичную логику и обычно хранить числа как основание 2, в то время как мы, люди используют нечеткую логику и предпочитают базу 10. Существует не так много проблем с «малыми» целыми числами, потому что существует соответствие 1 к 1, но сохранение произвольных чисел с плавающей запятой из базы 10 в представлении базы 2 фиксированного размера обычно является просто приближением. Классический пример является 1,1, который имеет две цифры в основании 10, но periodic в базе 2:

1.0001100110011001100110011001100110011001100110011001100110011001101... 

Вот почему общий совет включает в себя использование точных типов данных при доступных (DECIMAL в реляционной базе данных, целых чисел в клиенте код).

+0

Кастинг не сделан мной, созданным Magento SOAP Handler, он меняет «float» на «int», а иногда и меньше, чем на цент. По причине того, что вы описали ... –

+0

Хорошо, я ничего не знаю о Magento.Я предполагаю, что вы не поделились конкретным кодом, потому что все прозрачно или что-то в этом роде. Если это ошибка платформы, возможно, вам следует сообщить об этом в свой трекер ошибок. –

Смежные вопросы