Coder Social home page Coder Social logo

Comments (11)

mauveine avatar mauveine commented on July 23, 2024 4

I have the same issue, but while using a coupon code.
The error appears when I go on checkout page and I get a blank.

from klarna.

fme-tahir avatar fme-tahir commented on July 23, 2024

I was able to fix the issue, it was matter of going through the logic used by Klarna, you have to use klarna.xml in youmodule/etc that should inject the custom total to payment and then place the model file of that injection at yourmodule/Model/..
The format of both files can be copied from core klarna files.

from klarna.

bzneil avatar bzneil commented on July 23, 2024

I was able to fix the issue, it was matter of going through the logic used by Klarna, you have to use klarna.xml in youmodule/etc that should inject the custom total to payment and then place the model file of that injection at yourmodule/Model/..
The format of both files can be copied from core klarna files.

Hi - don't suppose you'd care to expand on this. I'm having the same issue but didn't quite follow your solution. Thanks

from klarna.

fme-tahir avatar fme-tahir commented on July 23, 2024

Hi - don't suppose you'd care to expand on this. I'm having the same issue but didn't quite follow your solution. Thanks

create klarna.xml in etc folder, with code as below:

<klarna xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Klarna_Core:etc/klarna.xsd">
    <order_lines id="payments">
        <line id="custom_fee" class="YourVendor\CustomFee\Model\Klarna\Orderline\CustomFee"/>
    </order_lines>
</klarna>

Then create a Model Class mentioned above named CustomFee.php

namespace YourVendor\CustomFee\Model\Klarna\Orderline;

use Klarna\Core\Api\BuilderInterface;
use Klarna\Core\Helper\ConfigHelper;
use Klarna\Core\Helper\DataConverter;
use Klarna\Core\Helper\KlarnaConfig;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\DataObjectFactory;
use Magento\Tax\Model\Calculation;
use Klarna\Core\Model\Fpt\Rate;

/**
 * Class CustomFee
 *
 * @package Klarna\Core\Model\Checkout\Orderline
 */
class CustomFee extends \Klarna\Core\Model\Checkout\Orderline\AbstractLine
{

    const ITEM_TYPE_SURCHARGE = 'custom_fee';
    /** @var Rate $rate */
    private $rate;
    /** @var ConfigHelper $configHelper */
    private $configHelper;
    private $customHelper;

    /**
     * AbstractLine constructor.
     *
     * @param DataConverter        $helper
     * @param Calculation          $calculator
     * @param ScopeConfigInterface $config
     * @param DataObjectFactory    $dataObjectFactory
     * @param KlarnaConfig         $klarnaConfig
     * @param Rate                 $rate
     */
    public function __construct(
        DataConverter $helper,
        Calculation $calculator,
        ScopeConfigInterface $config,
        DataObjectFactory $dataObjectFactory,
        KlarnaConfig $klarnaConfig,
        ConfigHelper $configHelper,
        Rate $rate
    ) {
        parent::__construct(
            $helper,
            $calculator,
            $config,
            $dataObjectFactory,
            $klarnaConfig
        );
        $this->configHelper = $configHelper;
        $this->rate = $rate;
    }

    /**
     * Collect totals process.
     *
     * @param BuilderInterface $checkout
     *
     * @return $this
     * @throws \Klarna\Core\Exception
     */
    public function collect(BuilderInterface $checkout)
    {
        /** @var \Magento\Sales\Model\AbstractModel|\Magento\Quote\Model\Quote $object */
        $object = $checkout->getObject();
       
        $address = $this->getAddress($object);
        $store = $this->getStore($object, $address);
        $totals = $address->getTotals();
        
        if (is_array($totals) && isset($totals['custom_fee'])) {
            $CustomFee = $this->processCustomFeeFromTotals($checkout, $totals, $object, $store);
            $checkout->addData($CustomFee);
        } elseif ($object->getCustomFee() > 0) {
            $CustomFee = $this->processCustomFeeWithoutTotals($checkout, $object, $store);
            $checkout->addData($CustomFee);
        }

    }
    private function processCustomFeeWithoutTotals(BuilderInterface $checkout, $object, $store)
    {
        $CustomFeeLabel = "Custom Fee";

        $amount = $object->getCustomFee();

        /** @noinspection IsEmptyFunctionUsageInspection */
        if (empty($amount) && !empty($object->getCustomFee())) {
            $amount = $object->getBaseSubtotal() - $object->getCustomFee();
        }

        $taxRate = $this->getCustomFeeTaxRate($checkout, $object->getAllVisibleItems());

        if ($taxRate > 100) {
            $taxRate = $taxRate / 100;
        }

        if ($taxRate > 1) {
            $taxRate = $taxRate / 100;
        }

        $taxAmount = 0;

        $unitPrice = $amount;
        $totalAmount = $amount;
        if ($this->klarnaConfig->isSeparateTaxLine($store)) {
            $taxRate = 0;
            $taxAmount = 0;
        } else {
            if ($this->isPriceExcludesVat($store)) {
                $unitPrice += $taxAmount;
                $totalAmount += $taxAmount;
            }
        }
        return [
            'custom_fee_unit_price'   => -abs($this->helper->toApiFloat($unitPrice)),
            'custom_fee_tax_rate'     => $this->helper->toApiFloat($taxRate * 100),
            'custom_fee_total_amount' => -abs($this->helper->toApiFloat($totalAmount)),
            'custom_fee_tax_amount'   => $this->helper->toApiFloat($taxAmount),
            'custom_fee_title'        => $CustomFeeLabel,
            'custom_fee_reference'    => 'custom_fee'

        ];
    }
    private function processCustomFeeFromTotals(BuilderInterface $checkout, $totals, $object, $store)
    {
        $total = $totals['custom_fee'];

        $taxAmount = 0;

        $amount = $total->getValue();
        $taxRate = 0; 

        $unitPrice = $amount;
        $totalAmount = $amount;
        
        
        $unitPrice += $taxAmount;
        $totalAmount += $taxAmount;

        return [
            'custom_fee_unit_price'   => -$this->helper->toApiFloat($unitPrice),
            'custom_fee_tax_rate'     => $this->helper->toApiFloat($taxRate),
            'custom_fee_total_amount' => -$this->helper->toApiFloat($totalAmount),
            'custom_fee_tax_amount'   => -$this->helper->toApiFloat($taxAmount),
            'custom_fee_title'        => (string)$total->getTitle(),
            'custom_fee_reference'    => $total->getCode()

        ];
    }
    private function isPriceExcludesVat($store = null)
    {
        $scope = ($store === null ? ScopeConfigInterface::SCOPE_TYPE_DEFAULT : ScopeInterface::SCOPE_STORES);
        return !$this->config->isSetFlag('tax/calculation/price_includes_tax', $scope, $store);
    }
    /**
     * @param $object
     * @return mixed
     */
    private function getAddress($object)
    {
        $address = $object->getShippingAddress();
        if ($address) {
            return $address;
        }
        return $object->getBillingAddress();
    }

    /**
     * @param $object
     * @param $address
     * @return mixed
     */
    private function getStore($object, $address)
    {
        $store = $object->getStore();
        if (!$store && $address->getQuote()) {
            $store = $address->getQuote()->getStore();
        }
        return $store;
    }

    /**
     * Add order details to checkout request
     *
     * @param BuilderInterface $checkout
     *
     * @return $this
     */
    public function fetch(BuilderInterface $checkout)
    {

        if ($checkout->getCustomFeeUnitPrice() != 0) {
            $checkout->addOrderLine(
                [
                    'type'             => 'surchage',
                    'reference'        => $checkout->getCustomFeeReference(),
                    'name'             => $checkout->getCustomFeeTitle(),
                    'quantity'         => 1,
                    'unit_price'       => $checkout->getCustomFeeUnitPrice(),
                    'tax_rate'         => $checkout->getCustomFeeTaxRate(),
                    'total_amount'     => $checkout->getCustomFeeTotalAmount(),
                    'total_tax_amount' => $checkout->getCustomFeeTaxAmount(),
                ]
            );
        }

        return $this;
    }
}

from klarna.

like-vyk avatar like-vyk commented on July 23, 2024

I have the same issue, but while using a coupon code.
The error appears when I go on checkout page and I get a blank.

We have the same issue. Did you find a fix for it?

from klarna.

opaque01 avatar opaque01 commented on July 23, 2024

I have the same issue with configurable products.
Magento 2.4.3 p2
Any fixes?

from klarna.

bzneil avatar bzneil commented on July 23, 2024

from klarna.

opaque01 avatar opaque01 commented on July 23, 2024

> I have the same issue with configurable products. Magento 2.4.3 p2 Any fixes?

It is not a problem with configurable products!
I also use the extension "Add Free Product to Cart for Magento 2". If a free product is inside the cart the checkout page wont work.

from klarna.

fme-tahir avatar fme-tahir commented on July 23, 2024

> I have the same issue with configurable products. Magento 2.4.3 p2 Any fixes?

It is not a problem with configurable products! I also use the extension "Add Free Product to Cart for Magento 2". If a free product is inside the cart the checkout page wont work.

For any custom fee, you have to follow the steps I mentioned above, that's how it worked for me.

from klarna.

hannes011 avatar hannes011 commented on July 23, 2024

Hi everyone,

I have the same error, even though I'm not using a custom total line.

My error occurs when \Klarna\Base\Helper\KlarnaConfig::isSeparateTaxLine is set to true only and if a discount (normal cart rule is sufficient) is applied and prices are configured to include tax! It is caused by the fact, that base_discount_amount contains tax while base_row_total does not - this leads to a partial mix of tax and non-tax prices.

I put quite some effort and time into debugging this issue. The following fix would solve that matter for me (and hopefully also for everyone).

Patch for klarna/module-orderlines in version 1.0.11 (klarna version 1.1.9 / base module version 9.1.10):

diff --git a/Model/Calculator/Item.php b/Model/Calculator/Item.php
index d3ccd66..3c7c567 100644
--- a/Model/Calculator/Item.php
+++ b/Model/Calculator/Item.php
@@ -74,6 +74,11 @@ class Item
         $itemResult['total_amount'] = $this->helper->toApiFloat(
             $item['base_row_total'] - $item['base_discount_amount']
         );
+        if ($this->taxConfig->priceIncludesTax($item['store'])) {  // needed since "base_discount_amount" contains tax if priceIncludesTax == true
+            $itemResult['total_amount'] = $this->helper->toApiFloat(
+                $item['base_row_total_incl_tax'] - $item['base_discount_amount'] - $item['base_tax_amount']
+            );
+        }
         $itemResult['total_discount_amount'] = $this->helper->toApiFloat($item['base_discount_amount']);
 
         if (!$this->klarnaConfig->isSeparateTaxLine($store)) {

For previous versions of Klarna (e.g. 8.3.6 with core 6.2.4) a similar fix would have to be made to Model/Checkout/Orderline/Items.php in klarna/module-core

I hope this fixes also the custom total line issue... but at least it solves a core bug in Klarna

from klarna.

itsbreadd avatar itsbreadd commented on July 23, 2024

Hi everyone,

Also come across this issue. Might be worth searching isSeparateTaxLine in your entire code base.
We had a free gift module setting this value to true unnecessarily, possibly similar to @opaque01

In our case, it only needs to be true when using the NA Klarna API Endpoint which the Klarna module handles anyway.

Also if you are using a free gift module and sending zero priced products to Klarna instead of products with a 100% discount, you will probably face issues with unit_price.

$_item['unit_price'] = $this->helper->toApiFloat($item->getBasePrice()) ?: $this->helper->toApiFloat($item->getBaseOriginalPrice());

If the getBasePrice is zero it resorts to getBaseOriginalPrice (which contains the full price) but the order line total in the request will still be zero, so Klevu rejects it and the payment method wont show on checkout.

Hope this helps someone.

from klarna.

Related Issues (9)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.