contacts_events-8.x-1.x-dev/src/ContactsPaymentListBuilder.php
src/ContactsPaymentListBuilder.php
<?php
namespace Drupal\contacts_events;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_order\Entity\OrderItemInterface;
use Drupal\commerce_payment\PaymentListBuilder;
use Drupal\commerce_price\Price;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Custom ListBuilder for payments that adds additional columns.
*
* @package Drupal\contacts
*/
class ContactsPaymentListBuilder extends PaymentListBuilder {
/**
* Partial payment order item tracking, if available.
*
* @var \Drupal\commerce_partial_payments\OrderItemTracking|null
*/
protected $tracking;
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
$self = parent::createInstance($container, $entity_type);
$self->tracking = $container->get('commerce_partial_payments.order_item_tracking', ContainerInterface::NULL_ON_INVALID_REFERENCE);
return $self;
}
/**
* {@inheritdoc}
*/
public function buildHeader() {
$header = parent::buildHeader();
$header['by'] = $this->t('By');
$header['date'] = $this->t('Date');
// Ensure operations goes at the end.
$operations = $header['operations'];
unset($header['operations']);
$header['operations'] = $operations;
return $header;
}
/**
* {@inheritdoc}
*/
public function buildRow(EntityInterface $entity) {
/** @var \Drupal\commerce_payment\Entity\Payment $entity */
$row = parent::buildRow($entity);
$row['by'] = $entity->get('creator')->entity ? $entity->get('creator')->entity->label() : '';
$completed = $entity->getCompletedTime();
$row['date'] = $completed ? $this->dateFormatter->format($completed, 'short') : $this->t('Not complete');
// Ensure operations goes at the end.
$operations = $row['operations'];
unset($row['operations']);
$row['operations'] = $operations;
return $row;
}
/**
* {@inheritdoc}
*/
public function render() {
$build = parent::render();
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $this->routeMatch->getParameter('commerce_order');
$total = $order->getTotalPrice();
if ($total) {
$paid = $order->getTotalPaid();
$balance = $order->getBalance();
$build['summary'] = [
'#type' => 'container',
'#attributes' => [
'class' => ['container-inline'],
],
'#weight' => -99,
];
$build['summary']['total'] = [
'#type' => 'item',
'#title' => new TranslatableMarkup('Total'),
'#markup' => $this->currencyFormatter->format($total->getNumber(), $total->getCurrencyCode()),
];
if ($paid) {
$build['summary']['paid'] = [
'#type' => 'item',
'#title' => new TranslatableMarkup('Paid'),
'#markup' => $this->currencyFormatter->format($paid->getNumber(), $paid->getCurrencyCode()),
];
$this->validateTracking($order);
}
if ($balance) {
$build['summary']['balance'] = [
'#type' => 'item',
'#title' => new TranslatableMarkup('Balance'),
'#markup' => $this->currencyFormatter->format($balance->getNumber(), $balance->getCurrencyCode()),
];
}
}
return $build;
}
/**
* Validate payment tracking for the order if we have partial payments.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order.
*/
protected function validateTracking(OrderInterface $order): void {
// Do nothing if we don't have partial payments enabled.
if (!$this->tracking) {
return;
}
// Get the tracked amounts and find any that belong to items not on the
// order.
$tracking = $this->tracking->getTrackedAmountsForOrder($order);
$item_ids = array_fill_keys(
array_map(
function (OrderItemInterface $item) {
return $item->id();
},
$order->getItems(),
),
TRUE,
);
/** @var \Drupal\commerce_price\Price[] $missing_items */
$missing_items = array_filter(
array_diff_key($tracking, $item_ids),
function (Price $amount) {
return !$amount->isZero();
}
);
// Get a total for the tracked amounts against missing items.
/** @var \Drupal\commerce_price\Price|null $missing_total */
$missing_total = NULL;
foreach ($missing_items as $missing_item) {
if (!$missing_item->isZero()) {
$missing_total = $missing_total ?
$missing_total->add($missing_item) :
$missing_item;
}
}
// Show an error message.
if ($missing_total) {
$formatted_amount = $this->currencyFormatter->format($missing_total->getNumber(), $missing_total->getCurrencyCode());
$this->messenger()->addError($this->formatPlural(
count($missing_items),
'Payment of @amount is tracked against a missing item. Please Reallocate Funds to correct it.',
'Payment totalling @amount is tracked against @count missing item. Please Reallocate Funds to correct it.',
['@amount' => $formatted_amount],
));
}
}
}
