public function AvataxLib::prepareTransactionsCreate in Drupal Commerce Connector for AvaTax 8
Prepares the transaction request body. (This method should not be public but that makes the tests easier).
Parameters
\Drupal\commerce_order\Entity\OrderInterface $order: The order.
string $type: The transactions type (e.g SalesOrder|SalesInvoice).
Return value
array The request parameters array.
Overrides AvataxLibInterface::prepareTransactionsCreate
1 call to AvataxLib::prepareTransactionsCreate()
- AvataxLib::transactionsCreate in src/
AvataxLib.php - Creates a new transaction (/api/v2/transactions/create).
File
- src/
AvataxLib.php, line 178
Class
- AvataxLib
- The AvaTax integration library.
Namespace
Drupal\commerce_avataxCode
public function prepareTransactionsCreate(OrderInterface $order, $type = 'SalesOrder') {
$store = $order
->getStore();
// Attempt to get company code for specific store, otherwise, fallback to
// the company code configured in the settings.
if ($store
->get('avatax_company_code')
->isEmpty()) {
$company_code = $this->config
->get('company_code');
}
else {
$company_code = $store
->get('avatax_company_code')->value;
}
$date = new DrupalDateTime();
// Gather all the adjustment types.
$adjustment_types = array_keys($this->adjustmentTypeManager
->getDefinitions());
$customer = $order
->getCustomer();
$currency_code = $order
->getTotalPrice() ? $order
->getTotalPrice()
->getCurrencyCode() : $store
->getDefaultCurrencyCode();
$request_body = [
'type' => $type,
'companyCode' => $company_code,
'date' => $date
->format('c'),
'code' => 'DC-' . $order
->uuid(),
'currencyCode' => $currency_code,
'lines' => [],
];
// Pass the tax exemption number|type if not empty.
if (!$customer
->isAnonymous()) {
if ($customer
->hasField('avatax_tax_exemption_number') && !$customer
->get('avatax_tax_exemption_number')
->isEmpty()) {
$request_body['ExemptionNo'] = $customer
->get('avatax_tax_exemption_number')->value;
}
if ($customer
->hasField('avatax_tax_exemption_type') && !$customer
->get('avatax_tax_exemption_type')
->isEmpty()) {
$request_body['CustomerUsageType'] = $customer
->get('avatax_tax_exemption_type')->value;
}
if ($customer
->hasField('avatax_customer_code') && !$customer
->get('avatax_customer_code')
->isEmpty()) {
$request_body['customerCode'] = $customer
->get('avatax_customer_code')->value;
}
else {
$customer_code_field = $this->config
->get('customer_code_field');
// For authenticated users, if the avatax_customer_code field is empty,
// use the field configured in config (mail|uid).
if ($order
->hasField($customer_code_field) && !$order
->get($customer_code_field)
->isEmpty()) {
$customer_code = $customer_code_field === 'mail' ? $order
->getEmail() : $order
->getCustomerId();
$request_body['customerCode'] = $customer_code;
}
}
}
// If the customer code could not be determined (either because the customer
// is anonymous or the mail is empty, fallback to the logic below).
if (!isset($request_body['customerCode'])) {
$request_body['customerCode'] = $order
->getEmail() ?: 'anonymous-' . $order
->id();
}
$has_shipments = $order
->hasField('shipments') && !$order
->get('shipments')
->isEmpty();
foreach ($order
->getItems() as $order_item) {
$profile = $this
->resolveCustomerProfile($order_item);
// If we could not resolve a profile for the order item, do not add it
// to the API request. There may not be an address available yet, or the
// item may not be shippable and not attached to a shipment.
if (!$profile) {
continue;
}
$purchased_entity = $order_item
->getPurchasedEntity();
/** @var \Drupal\address\Plugin\Field\FieldType\AddressItem $address */
$address = $profile
->get('address')
->first();
$line_item = [
'number' => $order_item
->uuid(),
'quantity' => $order_item
->getQuantity(),
// When the transaction request is performed when an order is placed,
// the order item already has a tax adjustment that we shouldn't send
// to AvaTax.
'amount' => $order_item
->getAdjustedTotalPrice(array_diff($adjustment_types, [
'tax',
]))
->getNumber(),
];
// Send the "SKU" as the "itemCode".
if ($purchased_entity instanceof ProductVariationInterface) {
$line_item['itemCode'] = $purchased_entity
->getSku();
}
if ($has_shipments) {
$line_item['addresses'] = [
'shipFrom' => self::formatAddress($store
->getAddress()),
'shipTo' => self::formatAddress($address),
];
}
else {
$line_item['addresses']['singleLocation'] = self::formatAddress($address);
}
$line_item['taxCode'] = $this->chainTaxCodeResolver
->resolve($order_item);
$request_body['lines'][] = $line_item;
}
if ($has_shipments) {
/** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment */
foreach ($order
->get('shipments')
->referencedEntities() as $shipment) {
if (is_null($shipment
->getAmount())) {
continue;
}
$request_body['lines'][] = [
'taxCode' => $this->config
->get('shipping_tax_code'),
'number' => $shipment
->uuid(),
'description' => $shipment
->label(),
'amount' => $shipment
->getAmount()
->getNumber(),
'quantity' => 1,
'addresses' => [
'shipFrom' => self::formatAddress($store
->getAddress()),
'shipTo' => self::formatAddress($shipment
->getShippingProfile()
->get('address')
->first()),
],
];
}
}
// Send additional order adjustments as separate lines.
foreach ($order
->getAdjustments() as $adjustment) {
// Skip shipping, fees and tax adjustments.
if (in_array($adjustment
->getType(), [
'shipping',
'fee',
'tax',
])) {
continue;
}
$line_item = [
// @todo: Figure out which taxCode to use here.
'taxCode' => 'P0000000',
'description' => $adjustment
->getLabel(),
'amount' => $adjustment
->getAmount()
->getNumber(),
'quantity' => 1,
'addresses' => [
'shipFrom' => self::formatAddress($store
->getAddress()),
],
];
// Take the "shipTo" from the first line if present, otherwise just ignore
// the adjustment, because sending lines without an "addresses" key
// is only possible when a global "addresses" is specified at the
// document level, which isn't the case here.
if (isset($request_body['lines'][0]['addresses']['shipTo'])) {
$line_item['addresses']['shipTo'] = $request_body['lines'][0]['addresses']['shipTo'];
$request_body['lines'][] = $line_item;
}
}
if ($request_body['type'] === 'SalesInvoice') {
$request_body['commit'] = TRUE;
}
$this->moduleHandler
->alter('commerce_avatax_order_request', $request_body, $order);
return $request_body;
}