<?php
/**
* @file
* Provides a bb2b_order.
*/
use Drupal\block\Entity\Block;
use Drupal\commerce_order\Entity\Order;
use Drupal\commerce_shipping\Entity\ShipmentInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\AppendCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Ajax\RedirectCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\bb2b_order\Plugin\Commerce\CheckoutPane\OrderTypePane;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\views\Form\ViewsForm;
use Drupal\views\ViewExecutable;
use Drupal\Core\Entity\EntityInterface;
/**
* Implements hook_cron().
*/
function bb2b_order_cron() {
$request_time = \Drupal::time()->getRequestTime();
$state_key = 'bb2b_order.last_queue_time';
$last_queue_time = \Drupal::state()->get($state_key, 0);
// Once daily.
if ($request_time - $last_queue_time >= (24 * 60 * 60)) {
\Drupal::service('bb2b_order.order_reservation_cron')->run();
\Drupal::state()->set($state_key, $request_time);
}
}
/**
* Implements hook_form_alter().
*/
function bb2b_order_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Add to cart on product page. This page will be deactivated.
if (strpos($form_id, 'commerce_order_item_add_to_cart_form') !== FALSE) {
array_unshift($form['#validate'], 'validate_available_quantity');
}
// Cart page.
if (strpos($form_id, 'views_form_commerce_cart_form_') !== FALSE) {
array_unshift($form['#validate'], 'validate_min_quantity');
}
// Quick order page.
if ($form_state->getFormObject() instanceof ViewsForm) {
/** @var \Drupal\views\ViewExecutable $view */
$view = reset($form_state->getBuildInfo()['args']);
if ($view->storage->get('id') == 'quick_order' && !empty($view->result)) {
$order_id = \Drupal::service('commerce_cart.cart_provider')->getCartIds(\Drupal::currentUser());
$order_id = reset($order_id);
$order = \Drupal::entityTypeManager()->getStorage('commerce_order')
->load($order_id);
$form['ddp_package_list'] = [
'#type' => 'details',
'#title' => t('At DDP orders, every box must be filled with the MOQ / box quantity.'),
'#weight' => -2,
'#open' => FALSE,
];
$form['ddp_package_list']['block'] = [
'#type' => 'container',
'block' => [
'#markup' => bb2b_order_render_shipment_package_block(),
],
];
$name = 'field_order_type';
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
$form_display = \Drupal::entityTypeManager()->getStorage('entity_form_display')
->load('commerce_order.default.default');
$widget = $form_display->getRenderer($name);
$roles = \Drupal::currentUser()->getRoles();
$is_admin = in_array('administrator', $roles) || in_array('site_administrator', $roles);
if ($widget) {
$items = $order->get($name);
$items->filterEmptyItems();
$store = \Drupal::service('commerce_store.current_store')->getStore();
$cart_provider = \Drupal::service('commerce_cart.cart_provider');
$cart = $cart_provider->getCart('default', $store);
if (!$cart) {
$cart = $cart_provider->createCart('default', $store);
}
$order_type = $cart->get('field_order_type')->value;
$form[$name] = $widget->form($items, $form, $form_state);
$form[$name]['#access'] = $items->access('edit');
$form[$name]['#required'] = TRUE;
$form[$name]['#weight'] = -1;
$form[$name]['widget']['#default_value'] = $order_type ?? 'ddp';
$form[$name]['widget']['#ajax'] = [
'callback' => 'bb2b_order_update_min_values',
];
if ($is_admin) {
unset($form[$name]['widget']['#options']['ddp_reservation']);
}
else {
$form[$name]['widget']['ddp_reservation'] = [
'#description' => t('You have 5 days to pay the order, otherwise it will be canceled.'),
];
}
}
$options = [];
$companies = \Drupal::entityTypeManager()
->getStorage('company')
->loadMultiple();
foreach ($companies as $company) {
if ($employee = $company->getEmployeeByRole('company_manager')) {
$options[$employee->id()] = $employee->getDisplayName() . ' (' . $company->getName() . ')';
}
}
$form['client'] = [
'#type' => 'select2',
'#id' => 'update-client',
'#options' => $options,
'#title' => t('Client'),
'#required' => FALSE,
'#weight' => -2,
'#access' => $is_admin,
'#ajax' => [
'callback' => 'bb2b_order_update_client',
],
];
if ($client_id = $order->getData('client_id')) {
$form['client']['#default_value'] = $client_id;
}
$form['actions']['checkout'] = [
'#type' => 'submit',
'#value' => t('Delivery data'),
'#weight' => 5,
'#access' => \Drupal::currentUser()->hasPermission('access checkout'),
'#submit' => array_merge($form['#submit'], ['bb2b_order_checkout_views_form_submit']),
'#order_id' => $order_id,
];
}
}
if ($form_id == 'commerce_shipping_method_edit_form') {
$form['plugin']['widget'][0]['target_plugin_configuration']['form']['rate_label']['#attributes'] = ['readonly' => 'readonly'];
$form['plugin']['widget'][0]['target_plugin_configuration']['form']['rate_label']['#description'] = t('Shown to customers during checkout. This value cannot be changed because we need it to match the name in Linker.');
}
}
/**
* Implements hook_views_pre_render().
*/
function bb2b_order_views_pre_render(ViewExecutable $view) {
if ($view->id() == 'commerce_cart_form') {
$order_id = $view->args[0];
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = Order::load($order_id);
/** @var \Drupal\bb2b_order\OrderServiceInterface $order_service */
$order_service = \Drupal::service('bb2b_order.order_service');
if (!$order_service->packageMinQuantityIsValid($order)) {
$view->build_info['substitutions']['{{ admin_shipment_packages_block }}'] = bb2b_order_render_shipment_package_block();
}
}
if ($view->id() === 'quick_order') {
//@todo: This will go to history when we create stock base field on product.
//@todo: Query will be in the StockStatus filter.
$input = $view->getExposedInput();
if (isset($input['stock_status']) && $input['stock_status'] === 'only_available') {
// Get products from the view.
$products = [];
foreach ($view->result as $key => $product) {
$products[$key] = $product->_entity;
}
// Check if those products are available.
$order_service = \Drupal::service('bb2b_order.order_service');
foreach ($products as $key => $product) {
if (!$order_service->checkAccessForProduct($product))
unset($view->result[$key]);
}
}
}
}
/**
* Gets the cart order for the given store and user.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The user. If empty, the current user is assumed.
*
* @return \Drupal\commerce_order\Entity\OrderInterface|null
* The cart order, or NULL if none found.
*/
function bb2b_order_get_cart(AccountInterface $account = NULL) {
$store = \Drupal::service('commerce_store.current_store')->getStore();
$cart_provider = \Drupal::service('commerce_cart.cart_provider');
$cart = $cart_provider->getCart('default', $store, $account);
if (!$cart) {
$cart = $cart_provider->createCart('default', $store, $account);
}
return $cart;
}
/**
* Ajax handler used to remove min values validation for drop shipping.
*/
function bb2b_order_update_client($form, FormStateInterface $form_state) {
$response = new AjaxResponse();
$triggering_element = $form_state->getTriggeringElement();
$trigger_name = array_shift($triggering_element['#parents']);
if ($trigger_name === 'client') {
$client_id = $triggering_element['#value'];
$cart = bb2b_order_get_cart();
$user = \Drupal::entityTypeManager()
->getStorage('user')
->load($client_id);
$email = $user ? $user->getEmail() : NULL;
$cart->setData('client_id', $client_id);
$cart->setData('client_email', $email);
$cart->save();
$content = '<div class="ajax-progress-throbber"></div>';
$response->addCommand(new AppendCommand('body', $content));
$response->addCommand(new RedirectCommand(Url::fromUri('internal:/orders/quick-order')->toString()));
}
return $response;
}
/**
* Ajax handler used to remove min values validation for drop shipping.
*/
function bb2b_order_update_min_values($form, FormStateInterface $form_state) {
$response = new AjaxResponse();
$triggering_element = $form_state->getTriggeringElement();
$trigger_name = array_shift($triggering_element['#parents']);
if ($trigger_name === 'field_order_type') {
$order_type = $triggering_element['#value'];
$rows = $form['output'][0]['#rows'];
/** @var \Drupal\bb2b_order\OrderServiceInterface $order_service */
$order_service = \Drupal::service('bb2b_order.order_service');
$cart = bb2b_order_get_cart();
/*if ($order_type !== 'drop_shipping') {
$cart->setData('client_id', NULL);
$cart->setData('client_email', NULL);
}*/
$cart->set('field_order_type', $order_type);
$cart->save();
foreach ($rows as $key => $row) {
$field_stock = $form['warehouse_stock'][$key];
$field_quantity = $form['edit_quantity'][$key];
$field_chk = $form['chk_add_to_cart'][$key];
$field_price = $form['price_group_price'][$key];
$add_to_cart_button = $form['add_to_cart_button'][$key];
/** @var \Drupal\commerce_product\Entity\ProductInterface $product */
$product = $row->_entity;
$access = $order_service->checkAccessForProduct($product);
$available = $order_service->getAvailableStock($product);
if ($order_type === 'drop_shipping') {
$class = $field_quantity['#attributes']['class'] ?? [];
$key = array_search('visually-hidden', $class);
if ($key !== FALSE && $available > 0) {
unset($field_quantity['#attributes']['class'][$key]);
}
$class = $field_chk['#attributes']['class'] ?? [];
$key = array_search('visually-hidden', $class);
if ($key !== FALSE && $available > 0) {
unset($field_chk['#attributes']['class'][$key]);
}
$class = $add_to_cart_button['#attributes']['class'] ?? [];
$key = array_search('visually-hidden', $class);
if ($key !== FALSE && $available > 0) {
unset($add_to_cart_button['#attributes']['class'][$key]);
}
}
else {
if (!$access || $available == 0) {
if (!isset($field_quantity['#attributes']['class']['visually-hidden'])) {
$field_quantity['#attributes']['class'][] = 'visually-hidden';
}
if (!isset($field_chk['#attributes']['class']['visually-hidden'])) {
$field_chk['#attributes']['class'][] = 'visually-hidden';
}
$field_chk['#value'] = 0;
if (!isset($add_to_cart_button['#attributes']['class']['visually-hidden'])) {
$add_to_cart_button['#attributes']['class'][] = 'visually-hidden';
}
}
}
$method = $order_type === 'drop_shipping' ? 'addClass' : 'removeClass';
$response->addCommand(new InvokeCommand('.min-qty', $method, ['visually-hidden']));
$selector = $field_quantity['#attributes']['data-drupal-selector'];
$quantity_selector = 'div[class*="' . preg_replace('/edit/', 'form-item', $selector, 1) . '"]';
$response->addCommand(new ReplaceCommand($quantity_selector, $field_quantity));
$selector = $field_chk['#attributes']['data-drupal-selector'];
$chk_selector = 'div[class*="' . preg_replace('/edit/', 'form-item', $selector, 1) . '"]';
$response->addCommand(new ReplaceCommand($chk_selector, $field_chk));
$selector = $field_stock['#attributes']['data-drupal-selector'];
$stock_selector = 'div[id="' . preg_replace('/edit/', 'form-item', $selector, 1) . '"]';
$response->addCommand(new ReplaceCommand($stock_selector, $field_stock));
$company = $order_service->getCompanyForClient($cart);
$price = $order_service->getProductPriceForClient($product->getDefaultVariation(), $cart, $company);
$field_price['list_price']['#value'] = $price['list_price'];
$field_price['price']['#value'] = $price['price'];
$selector = $field_price['#attributes']['data-drupal-selector'];
$price_selector = 'div[id="' . preg_replace('/edit/', 'form-item', $selector, 1) . '"]';
$response->addCommand(new ReplaceCommand($price_selector, $field_price));
$button_selector = 'button[name="' . $add_to_cart_button['#name'] . '"]';
$response->addCommand(new ReplaceCommand($button_selector, $add_to_cart_button));
// Cart block.
/** @var \Drupal\Core\Block\BlockPluginInterface $cart_block */
$cart_block = \Drupal::service('plugin.manager.block')->createInstance('commerce_cart', []);
if ($cart_block) {
$response->addCommand(new ReplaceCommand('.cart--cart-block', $cart_block->build()));
}
}
}
return $response;
}
/**
* Submit handler used to redirect to the checkout page.
*/
function bb2b_order_checkout_views_form_submit($form, FormStateInterface $form_state) {
$order_id = $form_state->getTriggeringElement()['#order_id'];
$form_state->setRedirect('commerce_checkout.form', ['commerce_order' => $order_id]);
}
/**
* Form validation handler for commerce_order_item_add_to_cart_form*().
*
* @param array $form
* A build form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*/
function validate_available_quantity(array $form, FormStateInterface $form_state) {
$product = $form_state->get('product');
$quantity = (int) $form_state->getValue('quantity')[0]['value'];
/** @var \Drupal\bb2b_order\OrderServiceInterface $order_service */
$order_service = \Drupal::service('bb2b_order.order_service');
$available = $order_service->getAvailableStock($product);
if ($available < $quantity) {
$form_state->setErrorByName('quantity][0][value', t('There are not enough quantity on the stock. Available: @available', [
'@available' => $available,
]));
}
}
/**
* Form validation handler for views_form_commerce_cart_form_*().
*
* @param array $form
* A build form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*/
function validate_min_quantity(array $form, FormStateInterface $form_state) {
$quantity = $form_state->getValue('edit_quantity');
$rows = $form['output'][0]['#rows'];
$triggering_element = $form_state->getTriggeringElement();
$trigger_name = array_shift($triggering_element['#parents']);
if ($trigger_name !== 'remove_button') {
foreach ($rows as $key => $row) {
/** @var \Drupal\commerce_product\Entity\ProductVariationInterface $product_variation */
$product_variation = $row->_relationship_entities['commerce_product_variation'];
/** @var \Drupal\commerce_product\Entity\ProductInterface $product */
$product = $product_variation->getProduct();
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $row->_entity;
/** @var \Drupal\bb2b_order\OrderServiceInterface $order_service */
$order_service = \Drupal::service('bb2b_order.order_service');
$available = $order_service->getAvailableStock($product);
foreach ($order->getItems() as $order_item) {
if ($order_item->getPurchasedEntityId() == $product_variation->id()) {
$order_quantity = (int) $order_item->getQuantity();
$diff_quantity = $quantity[$key] - $order_quantity;
if ($available < $diff_quantity || ($diff_quantity == 0 && $available < $order_quantity)) {
$form_state->setErrorByName('edit_quantity][' . $key, t('There are not enough quantity on the stock for product: @product_title. Available: @available', [
'@product_title' => $product->getTitle(),
'@available' => $diff_quantity == 0 ? $available : $available + $order_quantity,
]));
}
}
}
}
}
}
/**
* Implements hook_commerce_inline_form_PLUGIN_ID_alter().
*/
function bb2b_order_commerce_inline_form_customer_profile_alter(array &$inline_form, FormStateInterface $form_state, array &$complete_form) {
if ($inline_form['#profile_scope'] === 'checkout' && !isset($inline_form['rendered'])) {
$inline_form['address']['widget'][0]['address']['#after_build'] = [
'change_country_code_ajax_callback',
['\Drupal\address\Element\Address', 'clearValues'],
];
}
}
/**
* Form API callback: Change ajax callback on country select.
*
* @param array $element
* The element array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state object.
*
* @return array
* The element array.
*/
function change_country_code_ajax_callback(array $element, FormStateInterface &$form_state) {
$element['country_code']['country_code']['#ajax']['callback'] = [
OrderTypePane::class,
'ajaxRefresh',
];
if ($form_state->getTriggeringElement()) {
if ($form_state->getTriggeringElement()['#name'] === $element['country_code']['country_code']['#name']) {
$form_state->setTriggeringElement($element['country_code']['country_code']);
}
}
return $element;
}
/**
* Implements hook_mail_alter().
*/
function bb2b_order_mail_alter(&$message) {
if ($message['key'] == 'order_receipt' && !empty($message['params']['order'])) {
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $message['params']['order'];
$message['from'] = 'noreply@bescool.net';
$subject_order_number = $order->getOrderNumber();
if ($order->get('field_your_order_id')->isEmpty() === FALSE) {
$client_order_number = $order->get('field_your_order_id')->value;
$subject_order_number .= ' (' . $client_order_number . ')';
}
$message['subject'] = t('Order confirmation ID: @number', [
'@number' => $subject_order_number,
]);
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function bb2b_order_form_views_exposed_form_alter(&$form, FormStateInterface $form_state) {
$view = $form_state->get('view');
if ($view && in_array($view->id(), ['ongoing_orders', 'orders'])) {
$form['search']['#placeholder'] = t('By email, order IDs, recipient name');
}
}
/**
* Implements hook_views_data_alter().
*/
function bb2b_order_views_data_alter(array &$data) {
$data['commerce_order']['own_company_orders'] = [
'title' => t('Own company orders'),
'help' => t('Filter orders by own company for company managers.'),
'filter' => [
'group' => 'Order',
'field' => 'uid',
'id' => 'own_company_orders_filter',
'entity_type' => 'commerce_order',
],
];
}
/**
* Implements hook_views_data().
*/
function bb2b_order_views_data() {
$data = [];
//@todo: Maybe we could put ["products"] instead of ["views"].
$data['views']['stock_status'] = [
'title' => t('Stock status - Custom Filter'),
'filter' => [
'title' => t('Stock status - Custom Filter'),
'field' => 'id',
'id' => 'stock_status',
]
];
return $data;
}
/**
* Implements hook_ENTITY_TYPE_presave().
*/
function bb2b_order_commerce_order_presave(EntityInterface $entity) {
if ($entity->get('field_created_invoice')->isEmpty()) {
$entity->set('field_created_invoice', 'no');
}
// In case the your_order_id is edited after the order has been created,
// and before the order is being shipped.
if (!empty($entity->get('placed')->value)) {
$order_service = \Drupal::service('bb2b_order.order_service');
$order_service->resolveShipping($entity);
}
}
/**
* Implements hook_entity_access().
*/
function bb2b_order_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
$allowed_entities = [
'commerce_order',
'commerce_order_item',
'commerce_shipment',
];
if (in_array($entity->getEntityTypeId(), $allowed_entities)) {
if ($account->hasPermission('update default commerce_order')) {
return AccessResult::allowed();
}
}
return AccessResult::neutral();
}
/**
* Implements hook_form_BASE_FORM_ID_alter().
*/
function bb2b_order_form_commerce_shipment_default_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (!\Drupal::currentUser()->hasPermission('access commerce administration pages')) {
$form['title']['#access'] = FALSE;
$form['shipping_method']['#access'] = FALSE;
$form['tracking_code']['#access'] = FALSE;
$form['shipment_items']['#access'] = FALSE;
$form['recalculate_shipping']['#access'] = FALSE;
$form['actions']['delete']['#access'] = FALSE;
$request = \Drupal::requestStack()->getCurrentRequest();
$shipment = $request->get('commerce_shipment');
$form_state->set('shipment', $shipment);
$shipment->setData('shipping_force_resolve', TRUE);
if (isset($form['shipping_profile']['widget'][0]['profile']['edit_button'])) {
$form['shipping_profile']['widget'][0]['profile']['edit_button']['#attributes']['class'][] = 'button-secondary';
}
// Redirect user to order view.
$form['actions']['submit']['#submit'][] = 'bb2b_order_shipment_edit_form_submit';
}
}
/**
* Custom submit handler for the shipment edit form.
*/
function bb2b_order_shipment_edit_form_submit($form, FormStateInterface $form_state) {
$shipment = $form_state->get('shipment');
$account = \Drupal::currentUser();
if ($shipment) {
$admin_permission = $account
->hasPermission($shipment->getEntityType()->getAdminPermission());
$order = $shipment->getOrder();
if ($order && !$admin_permission) {
/*$form_state->setRedirect('entity.commerce_order.user_view', [
'commerce_order' => $order->id(),
'user' => $order->getCustomerId(),
]);*/
$form_state->setRedirect('entity.commerce_order.edit_form', [
'commerce_order' => $order->id(),
]);
}
}
}
/**
* Implements hook_form_BASE_FORM_ID_alter().
*/
function bb2b_order_form_commerce_order_default_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$user = \Drupal::currentUser();
if (!$user->hasPermission('access commerce administration pages')) {
$form['field_credit_note']['#access'] = FALSE;
$form['field_internal_note']['#access'] = FALSE;
$form['field_order_notes']['#access'] = FALSE;
$form['field_order_type']['#access'] = FALSE;
$form['field_vat_verified']['#access'] = FALSE;
$form['field_tracking_code_date']['#access'] = FALSE;
$form['coupons']['#access'] = FALSE;
$form['billing_profile']['widget'][0]['profile']['select_address']['#access'] = FALSE;
$form['billing_profile']['widget'][0]['profile']['edit_button']['#access'] = FALSE;
$form['billing_profile']['widget'][0]['profile']['copy_fields']['enable']['#access'] = FALSE;
$form['shipments']['#access'] = FALSE;
$form['order_items']['widget']['actions']['ief_add']['#attributes']['class'][] = 'button-secondary';
if (isset($form['order_items']['widget']['entities'])) {
foreach ($form['order_items']['widget']['entities'] as $key => &$entity) {
if (is_numeric($key)) {
$entity['actions']['ief_entity_edit']['#attributes']['class'][] = 'button-secondary';
$entity['actions']['ief_entity_remove']['#attributes']['class'][] = 'delete-order-item';
}
}
}
$form['ddp_package_list'] = [
'#type' => 'details',
'#title' => t('At DDP orders, every box must be filled with the MOQ / box quantity.'),
'#weight' => -2,
'#open' => FALSE,
];
$form['ddp_package_list']['block'] = [
'#type' => 'container',
'block' => [
'#markup' => bb2b_order_render_shipment_package_block(),
],
];
$header = [t('Title'), t('Shipping method'), t('Price'), t('Actions')];
$rows = [];
$request = \Drupal::requestStack()->getCurrentRequest();
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $request->get('commerce_order');
if ($order && $user->hasPermission('update default commerce_order')) {
$form_state->set('order', $order);
/** @var \Drupal\commerce_shipping\Entity\ShipmentInterface[] $shipments */
$shipments = $order->get('shipments')->referencedEntities();
foreach ($shipments as $shipment) {
$row = $links = [];
$links['edit'] = [
'title' => t('Edit'),
'url' => $shipment->toUrl('edit-form'),
'attributes' => [
'role' => 'button',
'class' => ['button button-secondary'],
// 'target' => '_blank',
],
];
$row[] = [
'data' => [
'#type' => 'markup',
'#markup' => $shipment->label(),
],
];
$row[] = [
'data' => [
'#type' => 'markup',
'#markup' => $shipment->getShippingMethod()->label(),
],
];
$row[] = [
'data' => [
'#type' => 'markup',
'#markup' => $shipment->getAmount(),
],
];
$row[] = [
'data' => [
'#type' => 'operations',
'#links' => $links,
],
];
$rows[] = $row;
}
}
$form['shipments_list'] = [
'#type' => 'container',
'#weight' => $form['shipments']['#weight'] ?? 0,
'shipments' => [
'#type' => 'fieldset',
'#title' => t('Shipments'),
'entities' => [
'#theme' => 'table',
'#rows' => $rows,
'#header' => $header,
],
],
];
array_unshift($form['#validate'], 'validate_first_package_is_full');
// Redirect user to order view.
$form['actions']['submit']['#submit'][] = 'bb2b_order_order_edit_form_submit';
}
}
/**
* Custom submit handler for the order edit form.
*/
function bb2b_order_order_edit_form_submit($form, FormStateInterface $form_state) {
$order = $form_state->get('order');
if ($order) {
$form_state->setRedirect('entity.commerce_order.user_view', [
'commerce_order' => $order->id(),
'user' => $order->getCustomerId(),
]);
}
}
/**
* Render shipment packages block content.
*
* @return mixed
* The rendered content.
*/
function bb2b_order_render_shipment_package_block() {
$shipment_package_view = views_embed_view('shipment_package_list', 'block_1');
return \Drupal::service('renderer')
->render($shipment_package_view);
}
/**
* Form validation handler for commerce_order_default_edit_form().
*
* @param array $form
* A build form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*/
function validate_first_package_is_full(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
$parents = $triggering_element['#array_parents'];
$triggering_element_name = array_pop($parents);
if ($triggering_element_name === 'submit') {
$storage = $form_state->getStorage();
$order_items_array = $storage['inline_entity_form']['order_items-form']['entities'] ?? [];
/** @var \Drupal\bb2b_order\OrderServiceInterface $order_service */
$order_service = \Drupal::service('bb2b_order.order_service');
$order_type = NULL;
$order_items = [];
foreach ($order_items_array as $order_item_array) {
if (isset($order_item_array['entity'])) {
$order_items[] = $order_item_array['entity'];
if (!$order_type) {
$order = $order_item_array['entity']->getOrder();
$order_type = $order ? $order->get('field_order_type')->value : NULL;
}
}
}
if ($order_items && $order_type !== 'drop_shipping') {
$quantities = $order_service->getOrderedQuantitiesByTag($order_items);
if ($order_service->minQuantityIsNotValid($quantities)) {
$form_state->setErrorByName('full_package', t('Your order can not be completed because the conditions for minimum order quantity is not met.'));
}
}
}
}
/**
* Implements hook_inline_entity_form_entity_form_alter().
*/
function bb2b_order_inline_entity_form_entity_form_alter(&$entity_form, &$form_state) {
$access_commerce_admin_pages = \Drupal::currentUser()
->hasPermission('access commerce administration pages');
if (!$access_commerce_admin_pages) {
if ($entity_form['#entity_type'] === 'commerce_shipment') {
$entity_form['title']['#access'] = FALSE;
$entity_form['shipping_method']['#access'] = FALSE;
$entity_form['tracking_code']['#access'] = FALSE;
}
elseif ($entity_form['#entity_type'] === 'commerce_order_item') {
$entity_form['unit_price']['#access'] = FALSE;
$default_quantity = (int) ($entity_form['quantity']['widget'][0]['value']['#default_value'] ?? 0);
$entity_form['quantity']['widget'][0]['value']['#default_value'] = $default_quantity;
$entity_form['purchased_entity']['widget'][0]['target_id']['#attributes']['class'][] = 'form-order-item-autocomplete';
}
}
}
/**
* Implements hook_entity_base_field_info_alter().
*/
function bb2b_order_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
if ($entity_type->id() === 'commerce_order_item' && isset($fields['quantity'])) {
$fields['quantity']->addConstraint('CheckAvailable');
}
}
/**
* Implements hook_ENTITY_TYPE_presave().
*/
function bb2b_order_commerce_shipment_presave(ShipmentInterface $shipment) {
$order = $shipment->getOrder();
$pending_order = $order && $order->getState()->getId() === 'pending';
$shipping_force_resolve = $shipment->getData('shipping_force_resolve', FALSE);
if ($shipment->original && $pending_order && $shipping_force_resolve) {
/** @var \Drupal\bb2b_order\OrderServiceInterface $order_service */
$order_service = \Drupal::service('bb2b_order.order_service');
$order = $shipment->getOrder();
$shipping_method = $order_service
->getShippingMethodForOrder($order, $shipment->getShippingProfile());
if ($shipping_method) {
$adjustments = $order->getAdjustments();
$order_service->setShippingMethodForShipment($shipment, $shipping_method, 0, $adjustments);
$order->set('adjustments', $adjustments);
}
$shipment->setData('shipping_force_resolve', FALSE);
}
}
/**
* Implements hook_theme().
*/
function bb2b_order_theme($existing, $type, $theme, $path) {
return [
'commerce_checkout_form__with_sidebar' => [
'base hook' => 'commerce_checkout_form',
'variables' => [
'ordered_products' => NULL,
],
],
];
}
/**
* Implements hook_preprocess_HOOK().
*/
function bb2b_order_preprocess_commerce_checkout_form__with_sidebar(&$variables) {
$block = Block::load('views_block__ordered_products_block_2');
$step = $variables['form']['#step_id'] ?? NULL;
if ($block && $step === 'complete') {
$variables['ordered_products'] = $block->getPlugin()->build();
$variables['ordered_products']['#attributes']['class'][] = 'ordered-products-block';
}
}
/**
* Implements hook_tokens_alter().
*/
function bb2b_order_tokens_alter(array &$replacements, array $context, BubbleableMetadata $bubbleable_metadata) {
// Clear empty token.
if (isset($context['data']['entity_type']) &&
$context['data']['entity_type'] === 'commerce_order'
) {
foreach ($context['tokens'] as $token) {
if (!isset($replacements[$token])) {
$replacements[$token] = '';
}
}
}
}
/**
* Implements hook_entity_view_alter().
*/
function bb2b_order_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
if ($build['#view_mode'] === 'user' &&
$build['#entity_type'] === 'commerce_order'
) {
/** @var \Drupal\commerce_order\Entity\OrderInterface $entity */
$entity_state = $entity->getState()->getId();
if ($entity_state === 'pending') {
$order = $build['#commerce_order'];
$vat_verified = $order->get('field_vat_verified')->value;
if (($vat_verified === '1') || ($vat_verified === '0')) {
$ship_uri = '/orders/' . $entity->id() . '/send';
$ship_url = Url::fromUri('internal:' . $ship_uri);
$build['ship_the_order_link'] = [
'#type' => 'link',
'#title' => t('Ship the order'),
'#url' => $ship_url,
'#weight' => -11,
'#attributes' => [
'class' => ['button button-secondary'],
],
];
}
$user = $entity->getCustomer();
if ($user->hasPermission('update default commerce_order')) {
$build['edit_link'] = [
'#type' => 'link',
'#title' => t('Edit order'),
'#url' => $entity->toUrl('edit-form'),
'#weight' => -10,
'#attributes' => [
'class' => ['button button-secondary'],
],
];
}
}
}
}