CreditmemoShippingProcessor.php 2.94 KB
Newer Older
Ketan's avatar
Ketan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
<?php
/**
 * @copyright  Vertex. All rights reserved.  https://www.vertexinc.com/
 * @author     Mediotype                     https://www.mediotype.com/
 */

namespace Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder;

use Magento\Sales\Api\Data\CreditmemoInterface;
use Magento\Sales\Api\Data\CreditmemoItemInterface;
use Vertex\Data\LineItemInterface;
use Vertex\Services\Invoice\RequestInterface;

/**
 * Processes Shipping on a Creditmemo and adds it to a Vertex Invoice's LineItems
 */
class CreditmemoShippingProcessor implements CreditmemoProcessorInterface
{
    /** @var ShippingProcessor */
    private $shippingProcessor;

    /**
     * @param ShippingProcessor $shippingProcessor
     */
    public function __construct(ShippingProcessor $shippingProcessor)
    {
        $this->shippingProcessor = $shippingProcessor;
    }

    /**
     * @inheritdoc
     */
    public function process(RequestInterface $request, CreditmemoInterface $creditmemo)
    {
        if (!$creditmemo->getBaseShippingAmount()) {
            return $request;
        }

        /** @var LineItemInterface[] $lineItems */
        $lineItems = array_map(
            function (LineItemInterface $lineItem) {
                // Since we are creating an Invoice record, make these negative
                $lineItem->setUnitPrice(-1 * $lineItem->getUnitPrice());
                $lineItem->setExtendedPrice(-1 * $lineItem->getExtendedPrice());
                return $lineItem;
            },
            $this->shippingProcessor->getShippingLineItems(
                $creditmemo->getOrderId(),
                $creditmemo->getBaseShippingAmount() - $this->getBaseShippingDiscountAmount($creditmemo)
            )
        );

        $request->setLineItems(array_merge($request->getLineItems(), $lineItems));
        return $request;
    }

    /**
     * Retrieve total discount less line item discounts
     *
     * At the time of this writing, Magento only applies discounts to line items
     * and to the shipping.  Unfortunately for invoices and creditmemos it does
     * not record the amount of shipping being discounted at the time of invoice
     * or credit.  As such, to attempt to figure out what that is, we have to
     * remove the line item discounts from the total discount.
     *
     * This code will break if Magento ever allows discounts to apply to other
     * items like Giftwrapping and Printed Cards
     *
     * @param CreditmemoInterface $creditmemo
     * @return float
     */
    private function getBaseShippingDiscountAmount(CreditmemoInterface $creditmemo)
    {
        $totalDiscount = $creditmemo->getBaseDiscountAmount() * -1; // discount is stored as a negative here
        $lineItemDiscount = array_reduce(
            $creditmemo->getItems(),
            function ($result, CreditmemoItemInterface $item) {
                return $result + (float)$item->getDiscountAmount();
            },
            0
        );

        return $totalDiscount - $lineItemDiscount;
    }
}