arch-8.x-1.x-dev/modules/order/src/Entity/Order.php
modules/order/src/Entity/Order.php
<?php
namespace Drupal\arch_order\Entity;
use Drupal\arch_cart\Cart\CartInterface;
use Drupal\arch_order\OrderAddressDataInterface;
use Drupal\arch_order\Plugin\Field\FieldType\OrderLineItemInterface;
use Drupal\arch_order\Services\OrderAddressServiceInterface;
use Drupal\arch_payment\PaymentMethodInterface;
use Drupal\arch_price\Price\ModifiedPriceInterface;
use Drupal\arch_price\Price\PriceInterface;
use Drupal\arch_product\Entity\Product;
use Drupal\arch_shipping\ShippingMethodInterface;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\RevisionableContentEntityBase;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\user\UserInterface;
/**
* Defines the order entity class.
*
* @ingroup order
*
* @ContentEntityType(
* id = "order",
* label = @Translation("Order", context = "arch_order"),
* label_collection = @Translation("Orders", context = "arch_order"),
* label_singular = @Translation("order", context = "arch_order"),
* label_plural = @Translation("orders", context = "arch_order"),
* label_count = @PluralTranslation(
* singular = "@count order",
* plural = "@count orders",
* context = "arch_order"
* ),
* handlers = {
* "storage" = "Drupal\arch_order\Entity\Storage\OrderStorage",
* "storage_schema" = "Drupal\arch_order\Entity\Storage\OrderStorageSchema",
* "view_builder" = "Drupal\arch_order\Entity\Builder\OrderViewBuilder",
* "access" = "Drupal\arch_order\Access\OrderAccessControlHandler",
* "views_data" = "Drupal\arch_order\Entity\Views\OrderViewsData",
* "form" = {
* "default" = "Drupal\arch_order\Form\OrderForm",
* "add" = "Drupal\arch_order\Form\OrderForm",
* "edit" = "Drupal\arch_order\Form\OrderForm",
* },
* "route_provider" = {
* "html" = "Drupal\arch_order\Routing\OrderRouteProvider",
* },
* "list_builder" = "Drupal\arch_order\Entity\Builder\OrderListBuilder",
* },
* base_table = "arch_order",
* revision_table = "arch_order_revision",
* show_revision_ui = TRUE,
* common_reference_target = TRUE,
* field_ui_base_route = "entity.order.admin_form",
* translatable = FALSE,
* revision_metadata_keys = {
* "revision_user" = "revision_uid",
* "revision_created" = "revision_timestamp",
* "revision_log_message" = "revision_log"
* },
* links = {
* "collection" = "/admin/store/orders",
* "canonical" = "/order/{order}",
* "add-form" = "/admin/store/order/add",
* "edit-form" = "/admin/store/order/{order}/edit",
* "version-history" = "/order/{order}/revisions",
* "revision" = "/order/{order}/revisions/{order_revision}/view"
* },
* entity_keys = {
* "id" = "oid",
* "label" = "order_number",
* "revision" = "vid",
* "status" = "status",
* "uid" = "uid",
* "langcode" = "langcode",
* "uuid" = "uuid"
* }
* )
*/
class Order extends RevisionableContentEntityBase implements OrderInterface {
use EntityChangedTrait;
/**
* Order address service.
*
* @var \Drupal\arch_order\Services\OrderAddressServiceInterface
*/
protected $orderAddressService;
/**
* Shipping method selected for the order.
*
* @var \Drupal\arch_shipping\ShippingMethodInterface
*/
protected $shippingMethod;
/**
* Payment method selected for the order.
*
* @var \Drupal\arch_payment\PaymentMethodInterface
*/
protected $paymentMethod;
/**
* Billing address.
*
* @var \Drupal\arch_order\OrderAddressDataInterface
*/
protected $billingAddress;
/**
* Shipping address.
*
* @var \Drupal\arch_order\OrderAddressDataInterface
*/
protected $shippingAddress;
/**
* {@inheritdoc}
*/
public static function createFromCart(CartInterface $cart) {
/** @var \Drupal\currency\Entity\CurrencyInterface $currency */
$currency = NULL;
// @todo Figure out something cool for this.
$order_number = time();
$order_prices = [
'currency' => NULL,
'subtotal_net' => 0.0,
'subtotal_gross' => 0.0,
'subtotal_vat_amount' => 0.0,
'grandtotal_net' => 0.0,
'grandtotal_gross' => 0.0,
'grandtotal_vat_amount' => 0.0,
];
$line_items = [];
foreach ($cart->getItems() as $item) {
if ($item['type'] == 'product') {
$product = Product::load($item['id']);
// Skip item if not a valid product.
if (!$product) {
continue;
}
/** @var \Drupal\arch_price\Price\PriceInterface $price */
$price = $product->getActivePrice();
if (empty($currency)) {
$currency = $price->getCurrency();
$order_prices['currency'] = $currency->id();
}
elseif ($price->getCurrencyId() !== $currency->id()) {
$price = $price->getExchangedPrice($currency);
}
// @todo Type value should not be fixed here.
$line_item = [
'type' => OrderLineItemInterface::ORDER_LINE_ITEM_TYPE_PRODUCT,
'product_id' => $product->id(),
'quantity' => $item['quantity'],
'product_bundle' => $product->bundle(),
'price_net' => $price->getNetPrice(),
'price_gross' => $price->getGrossPrice(),
'price_vat_rate' => $price->getVatRate(),
'price_vat_amount' => $price->getVatValue(),
'price_vat_cat_name' => $price->getVatCategoryId(),
'calculated_net' => $price->getNetPrice(),
'calculated_gross' => $price->getGrossPrice(),
'calculated_vat_rate' => $price->getVatRate(),
'calculated_vat_amount' => $price->getVatValue(),
'calculated_vat_cat_name' => $price->getVatCategoryId(),
'reason_of_diff' => $price->getReasonOfDifference(),
'data' => '',
];
if ($price instanceof ModifiedPriceInterface) {
$original_price = $price->getOriginalPrice();
$line_item['price_net'] = $original_price->getNetPrice();
$line_item['price_gross'] = $original_price->getGrossPrice();
$line_item['price_vat_rate'] = $original_price->getVatRate();
$line_item['price_vat_amount'] = $original_price->getVatValue();
$line_item['price_vat_cat_name'] = $original_price->getVatCategoryId();
}
// Subtotals only contains values from product line items.
// Otherwise, there would not be no difference between them.
$order_prices['subtotal_net'] += $line_item['quantity'] * $line_item['calculated_net'];
$order_prices['subtotal_gross'] += $line_item['quantity'] * $line_item['calculated_gross'];
$order_prices['subtotal_vat_amount'] += $line_item['quantity'] * $line_item['calculated_vat_amount'];
}
else {
// @todo This value should not be fixed here.
$type = OrderLineItemInterface::ORDER_LINE_ITEM_TYPE_DISCOUNT;
if ($item['type'] === 'shipping') {
$type = OrderLineItemInterface::ORDER_LINE_ITEM_TYPE_SHIPPING;
}
$line_item = [
'type' => $type,
'product_id' => 1,
'product_bundle' => 1,
'price_net' => 0,
'price_gross' => 0,
'price_vat_rate' => 0,
'price_vat_amount' => 0,
'price_vat_cat_name' => 0,
'calculated_net' => 0,
'calculated_gross' => 0,
'calculated_vat_rate' => 0,
'calculated_vat_amount' => 0,
'calculated_vat_cat_name' => 0,
'reason_of_diff' => '',
'data' => '',
];
}
$order_prices['grandtotal_net'] += $line_item['quantity'] * $line_item['calculated_net'];
$order_prices['grandtotal_gross'] += $line_item['quantity'] * $line_item['calculated_gross'];
$order_prices['grandtotal_vat_amount'] += $line_item['quantity'] * $line_item['calculated_vat_amount'];
$line_items[] = $line_item;
}
$data = [
'order_number' => $order_number,
'line_items' => $line_items,
] + $order_prices;
if (empty($data['currency'])) {
/** @var \Drupal\arch_price\Manager\PriceTypeManagerInterface $price_type_manager */
$price_type_manager = \Drupal::service('price_type.manager');
$default_price_type = $price_type_manager->getDefaultPriceType();
$data['currency'] = $default_price_type->getDefaultCurrency();
}
\Drupal::moduleHandler()->alter(
'arch_order_create_from_cart_data',
$data,
$cart
);
// DO NOT SAVE HERE!
return static::create($data);
}
/**
* {@inheritdoc}
*/
public static function postLoad(EntityStorageInterface $storage, array &$entities) {
parent::postLoad($storage, $entities);
foreach ($entities as $entity) {
$entity->setCalculatedValues();
}
}
/**
* {@inheritdoc}
*/
public function postCreate(EntityStorageInterface $storage) {
parent::postCreate($storage);
$this->setCalculatedValues();
}
/**
* Set calculated values.
*/
public function setCalculatedValues() {
if ($this->id()) {
$this->billingAddress = $this->getOrderAddressService()->getByType($this->id(), OrderAddressServiceInterface::TYPE_BILLING);
if ($this->billingAddress) {
$this->set('billing_address', $this->billingAddress->toArray());
}
$this->shippingAddress = $this->getOrderAddressService()->getByType($this->id(), OrderAddressServiceInterface::TYPE_SHIPPING);
if ($this->shippingAddress) {
$this->set('shipping_address', $this->shippingAddress->toArray());
}
}
}
/**
* {@inheritdoc}
*/
public function preSave(EntityStorageInterface $storage) {
if (!$this->getProductsCount()) {
throw new \LogicException('Cannot save order without products.');
}
parent::preSave($storage);
}
/**
* {@inheritdoc}
*/
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
if ($this->billingAddress) {
if (!$this->billingAddress->getOrderId()) {
$this->billingAddress->setOrderId($this->id());
}
if (!$update) {
$this->getOrderAddressService()->insertAddress(OrderAddressServiceInterface::TYPE_BILLING, $this->billingAddress);
}
else {
$this->getOrderAddressService()->updateAddress($this->billingAddress);
}
}
if ($this->shippingAddress) {
if (!$this->shippingAddress->getOrderId()) {
$this->shippingAddress->setOrderId($this->id());
}
if (!$update) {
$this->getOrderAddressService()->insertAddress(OrderAddressServiceInterface::TYPE_SHIPPING, $this->shippingAddress);
}
else {
$this->getOrderAddressService()->updateAddress($this->shippingAddress);
}
}
}
/**
* {@inheritdoc}
*/
public function setOwner(UserInterface $account) {
$this->set('uid', $account->id());
return $this;
}
/**
* {@inheritdoc}
*/
public function getOwner() {
return $this->get('uid')->entity;
}
/**
* {@inheritdoc}
*/
public function setOwnerId($uid) {
$this->set('uid', $uid);
return $this;
}
/**
* {@inheritdoc}
*/
public function getOwnerId() {
return $this->get('uid')->getString();
}
/**
* {@inheritdoc}
*/
public function setCreatedTime($timestamp) {
$this->set('created', $timestamp);
return $this;
}
/**
* {@inheritdoc}
*/
public function getCreatedTime() {
return $this->get('created')->value;
}
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
/** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
$fields = parent::baseFieldDefinitions($entity_type);
$fields['order_number'] = BaseFieldDefinition::create('string')
->setLabel(t('Order number', [], ['context' => 'arch_order']))
->addConstraint('UniqueField', [])
->setRequired(TRUE)
->setRevisionable(TRUE)
->setSetting('max_length', 56)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => 0,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => 0,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['erp_id'] = BaseFieldDefinition::create('string')
->setLabel(t('ERP ID', [], ['context' => 'arch_order']))
->setRequired(FALSE)
->setRevisionable(TRUE)
->setSetting('max_length', 255)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => 1,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => 1,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['status'] = BaseFieldDefinition::create('order_status')
->setLabel(t('Order status', [], ['context' => 'arch_order']))
->setDescription(t('The current status of the Order.', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setRevisionable(TRUE)
->setSetting('max_length', 32)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'order_status',
'weight' => 2,
])
->setDisplayOptions('form', [
'type' => 'order_statuses_select',
'weight' => 2,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['uid'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Customer ID', [], ['context' => 'arch_order']))
->setDescription(t('The (customer) user ID of the order.', [], ['context' => 'arch_order']))
->setRevisionable(TRUE)
->setDefaultValueCallback('Drupal\arch_order\Entity\Order::getCurrentUserId')
->setSetting('target_type', 'user')
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'author',
'weight' => 3,
])
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => 3,
'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'placeholder' => '',
],
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['email'] = BaseFieldDefinition::create('string')
->setLabel(t('Email', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setSetting('max_length', 255)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => 1,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => 1,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['langcode']
->setRequired(TRUE)
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['payment_method'] = BaseFieldDefinition::create('string')
->setLabel(t('Payment method', [], ['context' => 'arch_order']))
->setDescription(t('The payment method the Order has been paid.', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setRevisionable(TRUE)
->setSetting('max_length', 32)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => 5,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => 5,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['shipping_method'] = BaseFieldDefinition::create('string')
->setLabel(t('Shipping method', [], ['context' => 'arch_order']))
->setDescription(t('The shipping method with which the order was delivered.', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setRevisionable(TRUE)
->setSetting('max_length', 32)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => 6,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => 6,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['subtotal_net'] = BaseFieldDefinition::create('float')
->setLabel(t('Subtotal net', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setDefaultValue(0)
->setRevisionable(TRUE)
->setSetting('precision', 3)
->setSetting('size', 14)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'number_decimal',
'settings' => [
'thousand_separator' => ' ',
'decimal_separator' => '.',
'scale' => 3,
],
'weight' => 7,
])
->setDisplayOptions('form', [
'type' => 'number_decimal',
'weight' => 7,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['subtotal_gross'] = BaseFieldDefinition::create('float')
->setLabel(t('Subtotal gross', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setDefaultValue(0)
->setRevisionable(TRUE)
->setSetting('precision', 3)
->setSetting('size', 14)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'number_decimal',
'settings' => [
'thousand_separator' => ' ',
'decimal_separator' => '.',
'scale' => 3,
],
'weight' => 8,
])
->setDisplayOptions('form', [
'type' => 'number_decimal',
'weight' => 8,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['subtotal_vat_amount'] = BaseFieldDefinition::create('float')
->setLabel(t('Subtotal VAT amount', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setDefaultValue(0)
->setRevisionable(TRUE)
->setSetting('precision', 3)
->setSetting('size', 14)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'number_decimal',
'settings' => [
'thousand_separator' => ' ',
'decimal_separator' => '.',
'scale' => 3,
],
'weight' => 9,
])
->setDisplayOptions('form', [
'type' => 'number_decimal',
'weight' => 9,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['grandtotal_net'] = BaseFieldDefinition::create('float')
->setLabel(t('Grandtotal net', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setDefaultValue(0)
->setRevisionable(TRUE)
->setSetting('precision', 3)
->setSetting('size', 14)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'number_decimal',
'settings' => [
'thousand_separator' => ' ',
'decimal_separator' => '.',
'scale' => 3,
],
'weight' => 10,
])
->setDisplayOptions('form', [
'type' => 'number_decimal',
'weight' => 10,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['grandtotal_gross'] = BaseFieldDefinition::create('float')
->setLabel(t('Grandtotal gross', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setDefaultValue(0)
->setRevisionable(TRUE)
->setSetting('precision', 3)
->setSetting('size', 14)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'number_decimal',
'settings' => [
'thousand_separator' => ' ',
'decimal_separator' => '.',
'scale' => 3,
],
'weight' => 11,
])
->setDisplayOptions('form', [
'type' => 'number_decimal',
'weight' => 11,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['grandtotal_vat_amount'] = BaseFieldDefinition::create('float')
->setLabel(t('Grandtotal VAT amount', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setDefaultValue(0)
->setRevisionable(TRUE)
->setSetting('precision', 3)
->setSetting('size', 14)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'number_decimal',
'settings' => [
'thousand_separator' => ' ',
'decimal_separator' => '.',
'scale' => 3,
],
'weight' => 12,
])
->setDisplayOptions('form', [
'type' => 'number_decimal',
'weight' => 12,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['currency'] = BaseFieldDefinition::create('string')
->setLabel(t('Currency code', [], ['context' => 'arch_order']))
->setDescription(t('The currency code the Order has been paid. Use ISO 4217 alphabetic code (e.g.: USD, EUR, HUF etc.) for this field.', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setRevisionable(TRUE)
->setSetting('max_length', 5)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'string',
'weight' => 13,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => 13,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created on', [], ['context' => 'arch_order']))
->setDescription(t('The time that the order was created. Typically, when a cart assigned to a user.', [], ['context' => 'arch_order']))
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'timestamp',
'weight' => 14,
])
->setDisplayOptions('form', [
'type' => 'datetime_timestamp',
'weight' => 14,
])
->setDisplayConfigurable('form', TRUE);
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed', [], ['context' => 'arch_order']))
->setDescription(t('The time that the order was last edited.', [], ['context' => 'arch_order']))
->setRevisionable(TRUE)
->setTranslatable(TRUE);
$fields['billing_address'] = BaseFieldDefinition::create('address')
->setLabel(t('Billing address', [], ['context' => 'arch_order']))
->setComputed(TRUE)
->setDisplayOptions('view', [
'type' => 'address_default',
'weight' => 15,
])
->setDisplayOptions('form', [
'type' => 'address_default',
'weight' => 15,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['shipping_address'] = BaseFieldDefinition::create('address')
->setLabel(t('Shipping address', [], ['context' => 'arch_order']))
->setComputed(TRUE)
->setDisplayOptions('view', [
'type' => 'address_default',
'weight' => 16,
])
->setDisplayOptions('form', [
'type' => 'address_default',
'weight' => 16,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['line_items'] = BaseFieldDefinition::create('order_line_item')
->setLabel(t('Line items', [], ['context' => 'arch_order']))
->setDescription(t('The line items of the order.', [], ['context' => 'arch_order']))
->setRequired(TRUE)
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setRevisionable(TRUE)
->setTranslatable(FALSE)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'order_line_item_formatter',
'weight' => 20,
])
->setDisplayOptions('form', [
'type' => 'order_line_item_widget',
'weight' => 20,
])
->setDisplayConfigurable('view', TRUE)
->setDisplayConfigurable('form', TRUE);
$fields['data'] = BaseFieldDefinition::create('map')
->setLabel(t('Data', [], ['context' => 'arch_order']))
->setDescription(t('A serialized array of additional data.', [], ['context' => 'arch_order']));
return $fields;
}
/**
* {@inheritdoc}
*/
public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) {
parent::preSaveRevision($storage, $record);
if (!$this->isNewRevision() && isset($this->original) && (!isset($record->revision_log) || $record->revision_log === '')) {
// If we are updating an existing product without adding a new revision,
// we need to make sure $entity->revision_log is reset whenever it is
// empty. Therefore, this code allows us to avoid clobbering an existing
// log entry with an empty one.
$record->revision_log = $this->original->revision_log->value;
}
}
/**
* {@inheritdoc}
*/
public static function getCurrentUserId() {
return [\Drupal::currentUser()->id()];
}
/**
* {@inheritdoc}
*/
public function getLineItemsCount() {
return $this->get('line_items')->count();
}
/**
* {@inheritdoc}
*/
public function getProductsCount() {
return count($this->getProducts());
}
/**
* {@inheritdoc}
*/
public function filterLineItems($callback) {
/** @var \Drupal\Core\Field\FieldItemList $line_items */
$line_items = $this->get('line_items');
$result = [];
foreach ($line_items as $item) {
/** @var \Drupal\arch_order\Plugin\Field\FieldType\OrderLineItemFieldItem $item */
if (call_user_func($callback, $item)) {
$result[] = $item;
}
}
return $result;
}
/**
* {@inheritdoc}
*/
public function getProducts() {
return $this->filterLineItems(function ($item) {
/** @var \Drupal\arch_order\Plugin\Field\FieldType\OrderLineItemFieldItem $item */
$value = (int) $item->get('type')->getValue();
return OrderLineItemInterface::ORDER_LINE_ITEM_TYPE_PRODUCT === $value;
});
}
/**
* {@inheritdoc}
*/
public function getShippingPrices() {
return $this->filterLineItems(function ($item) {
/** @var \Drupal\arch_order\Plugin\Field\FieldType\OrderLineItemFieldItem $item */
$value = (int) $item->get('type')->getValue();
return OrderLineItemInterface::ORDER_LINE_ITEM_TYPE_SHIPPING === $value;
});
}
/**
* {@inheritdoc}
*/
public function getDiscounts() {
return $this->filterLineItems(function ($item) {
/** @var \Drupal\arch_order\Plugin\Field\FieldType\OrderLineItemFieldItem $item */
$value = (int) $item->get('type')->getValue();
return OrderLineItemInterface::ORDER_LINE_ITEM_TYPE_DISCOUNT === $value;
});
}
/**
* {@inheritdoc}
*/
public function getData() {
if ($this->get('data')->isEmpty()) {
return [];
}
return $this->get('data')->first()->getValue();
}
/**
* {@inheritdoc}
*/
public function setData(array $data) {
$this->get('data')->set(0, $data);
return $this;
}
/**
* {@inheritdoc}
*/
public function getDataKey($key, $default = NULL) {
$data = $this->getData();
return array_key_exists($key, $data) ? $data[$key] : $default;
}
/**
* {@inheritdoc}
*/
public function setDataKey($key, $value) {
$val = [];
if (!is_null($this->get('data')->first())) {
$val = $this->get('data')->first()->getValue();
}
if (isset($value)) {
$val[$key] = $value;
}
else {
unset($val[$key]);
}
return $this->setData($val);
}
/**
* {@inheritdoc}
*/
public function setShippingMethod(ShippingMethodInterface $shipping_method) {
$this->shippingMethod = $shipping_method;
return $this;
}
/**
* {@inheritdoc}
*/
public function getShippingMethod() {
return $this->shippingMethod;
}
/**
* {@inheritdoc}
*/
public function setPaymentMethod(PaymentMethodInterface $payment_method) {
$this->paymentMethod = $payment_method;
return $this;
}
/**
* {@inheritdoc}
*/
public function getPaymentMethod() {
return $this->paymentMethod;
}
/**
* {@inheritdoc}
*/
public function setOrderAddressService(OrderAddressServiceInterface $order_address_service) {
$this->orderAddressService = $order_address_service;
return $this;
}
/**
* {@inheritdoc}
*/
public function getOrderAddressService() {
if (!$this->orderAddressService) {
// @codingStandardsIgnoreStart
$this->orderAddressService = \Drupal::service('order.address');
// @codingStandardsIgnoreEnd
}
return $this->orderAddressService;
}
/**
* {@inheritdoc}
*/
public function setBillingAddress($address = NULL) {
if ($address instanceof OrderAddressDataInterface) {
$this->set('billing_address', $address->toArray());
$this->billingAddress = $address;
}
elseif (!isset($address)) {
$this->set('billing_address', NULL);
$this->billingAddress = NULL;
}
else {
throw new \InvalidArgumentException();
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getBillingAddress() {
return $this->billingAddress;
}
/**
* {@inheritdoc}
*/
public function setShippingAddress($address = NULL) {
if ($address instanceof OrderAddressDataInterface) {
$this->set('shipping_address', $address->toArray());
$this->shippingAddress = $address;
}
elseif (!isset($address)) {
$this->set('shipping_address', NULL);
$this->shippingAddress = NULL;
}
else {
throw new \InvalidArgumentException();
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getShippingAddress() {
return $this->shippingAddress;
}
/**
* {@inheritdoc}
*/
public function setShippingPrice(PriceInterface $price, $method_id) {
$original_shipping_price = $price;
if ($price instanceof ModifiedPriceInterface) {
$original_shipping_price = $price->getOriginalPrice();
}
$shipping_line_item = [
'type' => OrderLineItemInterface::ORDER_LINE_ITEM_TYPE_SHIPPING,
'product_id' => 0,
'quantity' => 1,
'product_bundle' => $method_id,
'price_net' => $original_shipping_price->getNetPrice(),
'price_gross' => $original_shipping_price->getGrossPrice(),
'price_vat_rate' => $original_shipping_price->getVatRate(),
'price_vat_amount' => $original_shipping_price->getVatValue(),
'price_vat_cat_name' => $original_shipping_price->getVatCategoryId(),
'calculated_net' => $price->getNetPrice(),
'calculated_gross' => $price->getGrossPrice(),
'calculated_vat_rate' => $price->getVatRate(),
'calculated_vat_amount' => $price->getVatValue(),
'calculated_vat_cat_name' => $price->getVatCategoryId(),
'reason_of_diff' => NULL,
'data' => NULL,
'created' => NULL,
];
/** @var \Drupal\Core\Field\FieldItemList $line_items */
$line_items = $this->get('line_items');
$line_items->appendItem($shipping_line_item);
return $this;
}
/**
* {@inheritdoc}
*/
public function setShippingExtra(PriceInterface $price, $method_id) {
$original_shipping_price = $price;
if ($price instanceof ModifiedPriceInterface) {
$original_shipping_price = $price->getOriginalPrice();
}
$shipping_line_item = [
'type' => OrderLineItemInterface::ORDER_LINE_ITEM_TYPE_SHIPPING_EXTRA,
'product_id' => 0,
'quantity' => 1,
'product_bundle' => $method_id,
'price_net' => $original_shipping_price->getNetPrice(),
'price_gross' => $original_shipping_price->getGrossPrice(),
'price_vat_rate' => $original_shipping_price->getVatRate(),
'price_vat_amount' => $original_shipping_price->getVatValue(),
'price_vat_cat_name' => $original_shipping_price->getVatCategoryId(),
'calculated_net' => $price->getNetPrice(),
'calculated_gross' => $price->getGrossPrice(),
'calculated_vat_rate' => $price->getVatRate(),
'calculated_vat_amount' => $price->getVatValue(),
'calculated_vat_cat_name' => $price->getVatCategoryId(),
'reason_of_diff' => NULL,
'data' => NULL,
'created' => NULL,
];
/** @var \Drupal\Core\Field\FieldItemList $line_items */
$line_items = $this->get('line_items');
$line_items->appendItem($shipping_line_item);
return $this;
}
/**
* {@inheritdoc}
*/
public function setPaymentFee(PriceInterface $price, $method_id) {
$original_fee = $price;
if ($price instanceof ModifiedPriceInterface) {
$original_fee = $price->getOriginalPrice();
}
$fee_line_item = [
'type' => OrderLineItemInterface::ORDER_LINE_ITEM_TYPE_PAYMENT_FEE,
'product_id' => 0,
'quantity' => 1,
'product_bundle' => $method_id,
'price_net' => $original_fee->getNetPrice(),
'price_gross' => $original_fee->getGrossPrice(),
'price_vat_rate' => $original_fee->getVatRate(),
'price_vat_amount' => $original_fee->getVatValue(),
'price_vat_cat_name' => $original_fee->getVatCategoryId(),
'calculated_net' => $price->getNetPrice(),
'calculated_gross' => $price->getGrossPrice(),
'calculated_vat_rate' => $price->getVatRate(),
'calculated_vat_amount' => $price->getVatValue(),
'calculated_vat_cat_name' => $price->getVatCategoryId(),
'reason_of_diff' => NULL,
'data' => NULL,
'created' => NULL,
];
$this->get('line_items')->appendItem($fee_line_item);
return $this;
}
/**
* {@inheritdoc}
*/
public function updateTotal() {
$order_prices = [
'subtotal_net' => 0.0,
'subtotal_gross' => 0.0,
'subtotal_vat_amount' => 0.0,
'grandtotal_net' => 0.0,
'grandtotal_gross' => 0.0,
'grandtotal_vat_amount' => 0.0,
];
/** @var \Drupal\Core\Field\FieldItemList $line_items */
$line_items = $this->get('line_items');
/** @var \Drupal\arch_order\Plugin\Field\FieldType\OrderLineItemInterface $line_item */
foreach ($line_items as $line_item) {
$quantity = $line_item->getQuantity();
if ($line_item->getLineItemTypeId() == OrderLineItemInterface::ORDER_LINE_ITEM_TYPE_PRODUCT) {
$order_prices['subtotal_net'] += $quantity * $line_item->get('calculated_net')->getValue();
$order_prices['subtotal_gross'] += $quantity * $line_item->get('calculated_gross')->getValue();
$order_prices['subtotal_vat_amount'] += $quantity * $line_item->get('calculated_vat_amount')->getValue();
}
$order_prices['grandtotal_net'] += $quantity * $line_item->get('calculated_net')->getValue();
$order_prices['grandtotal_gross'] += $quantity * $line_item->get('calculated_gross')->getValue();
$order_prices['grandtotal_vat_amount'] += $quantity * $line_item->get('calculated_vat_amount')->getValue();
}
foreach ($order_prices as $price_name => $price_value) {
$this->set($price_name, $price_value);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getStatus() {
return $this->get('status')->entity;
}
/**
* {@inheritdoc}
*/
public function getStatusId() {
return $this->get('status')->entity->id();
}
}
