commerce_xero-8.x-1.x-dev/src/Plugin/CommerceXero/type/Invoice.php

src/Plugin/CommerceXero/type/Invoice.php
<?php

namespace Drupal\commerce_xero\Plugin\CommerceXero\type;

use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\commerce_order\Entity\OrderItemInterface;
use Drupal\commerce_payment\Entity\PaymentInterface;
use Drupal\commerce_xero\Attribute\CommerceXeroDataType;
use Drupal\commerce_xero\Entity\CommerceXeroStrategyInterface;
use Drupal\commerce_xero\OrderDataTransformationTrait;
use Drupal\commerce_xero\Plugin\CommerceXero\CommerceXeroDataTypePluginBase;
use Drupal\xero\TypedData\XeroItemInterface;

/**
 * Provides a commerce xero invoice type.
 *
 * @CommerceXeroDataType(
 *   id = "commerce_xero_invoice",
 *   label = @Translation("Invoice"),
 *   type = "xero_invoice",
 *   settings = { }
 * )
 */
#[CommerceXeroDataType(
  id: 'commerce_xero_invoice',
  label: new TranslatableMarkup('Invoice'),
  type: 'xero_invoice',
)]
class Invoice extends CommerceXeroDataTypePluginBase {

  use OrderDataTransformationTrait;

  /**
   * {@inheritdoc}
   */
  public function make(PaymentInterface $payment, CommerceXeroStrategyInterface $strategy): XeroItemInterface {
    $configuration = $this->getConfiguration();
    $typedDataManager = $this->getTypedDataManager();
    $definition = $this->typedDataManager
      ->createDataDefinition($configuration['type']);

    $order = $payment->getOrder();

    $data = [
      'Type' => 'ACCREC',
      'Contact' => $this->getDefaultContactValues($order),
      'Date' => date('Y-m-d', $order->getCreatedTime()),
      'DueDate' => date('Y-m-d', $order->getCreatedTime()),
      'SubTotal' => $order->getSubtotalPrice()->getNumber(),
      'Total' => $order->getTotalPrice()->getNumber(),
      'Reference' => $order->id(),
      'Status' => 'AUTHORISED',
      'CurrencyCode' => strtoupper($order->getBalance()->getCurrencyCode()),
      'Url' => Url::fromUri(
        'entity:commerce_order/' . $order->id(),
        ['absolute' => TRUE])->toString(),
      'LineAmountTypes' => 'Exclusive',
      'LineItems' => [],
    ];

    if ($order->getOrderNumber()) {
      $data['InvoiceNumber'] = $order->getOrderNumber();
    }

    foreach ($order->getItems() as $i => $orderItem) {
      $lineItem = [
        'Description' => $orderItem->getTitle(),
        'Quantity' => $orderItem->getQuantity(),
        'AccountCode' => $strategy->getRevenueAccountCode(),
        'UnitAmount' => $orderItem->getUnitPrice()->getNumber(),
      ];
      // Including line item inclusive taxes could be problematic here for VAT
      // and GST. There's not a good way to get only adjust unit price filtering
      // out just tax.
      $adjusmentTypes = $this->getNonTaxAdjustmentsForLineItem($orderItem);

      $unit_price_compare = $orderItem->getAdjustedUnitPrice($adjusmentTypes)->compareTo($orderItem->getUnitPrice());
      if ($unit_price_compare !== 0) {
        // Unit price can vary depending on if Commerce includes the discount in
        // the unit price or not.
        $lineItem['DiscountAmount'] = $orderItem
          ->getTotalPrice()
          ->subtract($orderItem->getAdjustedTotalPrice($adjusmentTypes))
          ->getNumber();
      }

      $data['LineItems'][] = $lineItem;
    }

    // Adjustments need to be added as line items unless they're included in
    // the base price as long as they are NOT manually added tax-adjustments.
    foreach ($order->getAdjustments() as $i => $adjustment) {
      if (!$adjustment->isIncluded() && $adjustment->getType() !== 'tax') {
        $data['LineItems'][] = [
          'Description' => $adjustment->getLabel(),
          'Quantity' => 1,
          'UnitAmount' => $adjustment->getAmount()->getNumber(),
          // Adjustments account code. 260 is a default "Rounding" adjustment
          // that Xero classifies as a "Current Liability" Account Type.
          'AccountCode' => '260',
          // Adjustments are added outside of tax.
          'TaxType' => 'NONE',
          'TaxAmount' => 0.00,
        ];
      }
    }

    $item = $typedDataManager->create($definition, $data);
    assert($item instanceof XeroItemInterface);
    return $item;
  }

  /**
   * Gets the non-tax adjustments for a commerce order item.
   *
   * @param \Drupal\commerce_order\Entity\OrderItemInterface $item
   *   The order item.
   *
   * @return string[]
   *   The adjustment type strings.
   */
  protected function getNonTaxAdjustmentsForLineItem(OrderItemInterface $item): array {
    $adjustments = $item->getAdjustments();
    $nonTaxAdjustments = array_filter($adjustments, fn ($a) => $a->getType() !== 'tax');
    return array_map(fn ($a) => $a->getType(), $nonTaxAdjustments);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc