InvoiceQuantityValidator.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sales\Model\Order;
  7. use Magento\Sales\Api\Data\InvoiceInterface;
  8. use Magento\Sales\Api\Data\InvoiceItemInterface;
  9. use Magento\Sales\Api\Data\OrderInterface;
  10. use Magento\Sales\Api\OrderRepositoryInterface;
  11. use Magento\Sales\Model\ValidatorInterface;
  12. /**
  13. * Interface InvoiceValidatorInterface
  14. */
  15. class InvoiceQuantityValidator implements ValidatorInterface
  16. {
  17. /**
  18. * @var OrderRepositoryInterface
  19. */
  20. private $orderRepository;
  21. /**
  22. * InvoiceValidator constructor.
  23. * @param OrderRepositoryInterface $orderRepository
  24. */
  25. public function __construct(OrderRepositoryInterface $orderRepository)
  26. {
  27. $this->orderRepository = $orderRepository;
  28. }
  29. /**
  30. * @inheritdoc
  31. */
  32. public function validate($invoice)
  33. {
  34. if ($invoice->getOrderId() === null) {
  35. return [__('Order Id is required for invoice document')];
  36. }
  37. $order = $this->orderRepository->get($invoice->getOrderId());
  38. return $this->checkQtyAvailability($invoice, $order);
  39. }
  40. /**
  41. * Check qty availability
  42. *
  43. * @param InvoiceInterface $invoice
  44. * @param OrderInterface $order
  45. * @return array
  46. */
  47. private function checkQtyAvailability(InvoiceInterface $invoice, OrderInterface $order)
  48. {
  49. $messages = [];
  50. $qtys = $this->getInvoiceQty($invoice);
  51. $totalQty = 0;
  52. if ($qtys) {
  53. /** @var \Magento\Sales\Model\Order\Item $orderItem */
  54. foreach ($order->getItems() as $orderItem) {
  55. if (isset($qtys[$orderItem->getId()])) {
  56. if ($qtys[$orderItem->getId()] > $orderItem->getQtyToInvoice() && !$orderItem->isDummy()) {
  57. $messages[] = __(
  58. 'The quantity to invoice must not be greater than the uninvoiced quantity'
  59. . ' for product SKU "%1".',
  60. $orderItem->getSku()
  61. );
  62. }
  63. $totalQty += $qtys[$orderItem->getId()];
  64. unset($qtys[$orderItem->getId()]);
  65. }
  66. }
  67. }
  68. if ($qtys) {
  69. $messages[] = __('The invoice contains one or more items that are not part of the original order.');
  70. } elseif ($totalQty <= 0) {
  71. $messages[] = __("The invoice can't be created without products. Add products and try again.");
  72. }
  73. return $messages;
  74. }
  75. /**
  76. * @param InvoiceInterface $invoice
  77. * @return array
  78. */
  79. private function getInvoiceQty(InvoiceInterface $invoice)
  80. {
  81. $qtys = [];
  82. /** @var InvoiceItemInterface $item */
  83. foreach ($invoice->getItems() as $item) {
  84. $qtys[$item->getOrderItemId()] = $item->getQty();
  85. }
  86. return $qtys;
  87. }
  88. }