CreditmemoShippingProcessor.php 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <?php
  2. /**
  3. * @copyright Vertex. All rights reserved. https://www.vertexinc.com/
  4. * @author Mediotype https://www.mediotype.com/
  5. */
  6. namespace Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder;
  7. use Magento\Sales\Api\Data\CreditmemoInterface;
  8. use Magento\Sales\Api\Data\CreditmemoItemInterface;
  9. use Vertex\Data\LineItemInterface;
  10. use Vertex\Services\Invoice\RequestInterface;
  11. /**
  12. * Processes Shipping on a Creditmemo and adds it to a Vertex Invoice's LineItems
  13. */
  14. class CreditmemoShippingProcessor implements CreditmemoProcessorInterface
  15. {
  16. /** @var ShippingProcessor */
  17. private $shippingProcessor;
  18. /**
  19. * @param ShippingProcessor $shippingProcessor
  20. */
  21. public function __construct(ShippingProcessor $shippingProcessor)
  22. {
  23. $this->shippingProcessor = $shippingProcessor;
  24. }
  25. /**
  26. * @inheritdoc
  27. */
  28. public function process(RequestInterface $request, CreditmemoInterface $creditmemo)
  29. {
  30. if (!$creditmemo->getBaseShippingAmount()) {
  31. return $request;
  32. }
  33. /** @var LineItemInterface[] $lineItems */
  34. $lineItems = array_map(
  35. function (LineItemInterface $lineItem) {
  36. // Since we are creating an Invoice record, make these negative
  37. $lineItem->setUnitPrice(-1 * $lineItem->getUnitPrice());
  38. $lineItem->setExtendedPrice(-1 * $lineItem->getExtendedPrice());
  39. return $lineItem;
  40. },
  41. $this->shippingProcessor->getShippingLineItems(
  42. $creditmemo->getOrderId(),
  43. $creditmemo->getBaseShippingAmount() - $this->getBaseShippingDiscountAmount($creditmemo)
  44. )
  45. );
  46. $request->setLineItems(array_merge($request->getLineItems(), $lineItems));
  47. return $request;
  48. }
  49. /**
  50. * Retrieve total discount less line item discounts
  51. *
  52. * At the time of this writing, Magento only applies discounts to line items
  53. * and to the shipping. Unfortunately for invoices and creditmemos it does
  54. * not record the amount of shipping being discounted at the time of invoice
  55. * or credit. As such, to attempt to figure out what that is, we have to
  56. * remove the line item discounts from the total discount.
  57. *
  58. * This code will break if Magento ever allows discounts to apply to other
  59. * items like Giftwrapping and Printed Cards
  60. *
  61. * @param CreditmemoInterface $creditmemo
  62. * @return float
  63. */
  64. private function getBaseShippingDiscountAmount(CreditmemoInterface $creditmemo)
  65. {
  66. $totalDiscount = $creditmemo->getBaseDiscountAmount() * -1; // discount is stored as a negative here
  67. $lineItemDiscount = array_reduce(
  68. $creditmemo->getItems(),
  69. function ($result, CreditmemoItemInterface $item) {
  70. return $result + (float)$item->getDiscountAmount();
  71. },
  72. 0
  73. );
  74. return $totalDiscount - $lineItemDiscount;
  75. }
  76. }