Skip to content

Instantly share code, notes, and snippets.

@kelvysmoura
Last active September 6, 2024 21:07
Show Gist options
  • Select an option

  • Save kelvysmoura/e998ddba7fb45c192d4c4ab85c42ce31 to your computer and use it in GitHub Desktop.

Select an option

Save kelvysmoura/e998ddba7fb45c192d4c4ab85c42ce31 to your computer and use it in GitHub Desktop.
Partial Invoice By Amount - Magento 2 POC
<?php
require __DIR__ . '/app/bootstrap.php';
use Magento\Framework\App\Bootstrap;
use Magento\Framework\App\State;
use Magento\Framework\Registry;
use \Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\InvoiceOrder as ApiInvoiceOrder;
use Magento\Sales\Api\Data\InvoiceItemCreationInterfaceFactory;
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$execute = function (array $nsList, callable $callable) use ($objectManager) {
$objects = array_map(fn($ns) => $objectManager->get($ns), $nsList);
$callable(...$objects);
};
$execute([
State::class,
Registry::class,
OrderRepositoryInterface::class,
ApiInvoiceOrder::class,
InvoiceItemCreationInterfaceFactory::class
], function(
$state,
$registry,
$orderRepository,
$apiInvoiceOrder,
$itemFactory
) {
$registry->register('isSecureArea', true);
$state->setAreaCode('frontend');
$orderId = 000;
$amount = 100; // Amount to partial invoice
$order = $orderRepository->get($orderId);
$orderTotalDue = (float)$order->getTotalDue();
if($amount > $orderTotalDue) {
throw new \Magento\Framework\Exception\LocalizedException(
__("Invalid amount. Total due {$orderTotalDue}")
);
}
if ($order->canInvoice()) {
$itemsToInvoice = [];
foreach($order->getAllItems() as $orderItem) {
if(!$orderItem->canInvoice()) {
dump("OrderItem {$orderItem->getId()} can not be invoiced");
continue;
}
$itemsToInvoice[] = $orderItem;
}
$invoiceItems = [];
$finalResultToLog = 0;
foreach($itemsToInvoice as $orderItem) {
$itemId = $orderItem->getId();
$rowTotal = $orderItem->getRowTotal();
$rowInvoiced = $orderItem->getRowInvoiced();
$totalDue = (float)$rowTotal - (float)$rowInvoiced;
$percentDue = $totalDue / $orderTotalDue;
$amountPerItem = $amount * $percentDue;
$finalResultToLog += $amountPerItem;
$qtyDue = $orderItem->getQtyToInvoice();
$proportionalPrice = $totalDue / $qtyDue;
$qtyToInvoice = $amountPerItem / $proportionalPrice;
dump(compact(['itemId', 'amountPerItem', 'rowTotal', 'rowInvoiced', 'totalDue', 'qtyDue', 'percentDue', 'proportionalPrice', 'qtyToInvoice', 'orderTotalDue', 'finalResult']));
$item = $itemFactory->create();
$item->setOrderItemId($itemId);
$item->setQty($qtyToInvoice);
$invoiceItems[] = $item;
}
dump($invoiceItems);
if(!empty($invoiceItems)) {
$invoiceId = $apiInvoiceOrder->execute(
orderId: $orderId,
items: $invoiceItems,
notify: true
);
dump("InvoiceId {$invoiceId}");
}
}
});
dd('Finished');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment