You are here

merci_line_item.module in MERCI (Manage Equipment Reservations, Checkout and Inventory) 7.3

Defines the core MERCI line item entity and API functions interact with line items.

File

merci_line_item/merci_line_item.module
View source
<?php

/**
 * @file
 * Defines the core MERCI line item entity and API functions interact with
 * line items.
 */

// Bundles
define('MERCI_LINE_ITEM', 'merci_line_item');
define('MERCI_LINE_ITEM_REFERENCE', 'merci_line_item_reference');
define('MERCI_RESOURCE_DISPLAY_BUNDLE', 'merci_resource_display');

// Fields
define('MERCI_RESOURCE_DISPLAY', 'merci_resource_display');
define('MERCI_RESOURCE_REFERENCE', 'merci_resource_reference');
define('MERCI_CHECKOUT_DATES', 'merci_checkout_dates');
define('MERCI_RETURN_DATE', 'merci_return_date');
define('MERCI_RETURNED_ACCESSORIES', 'merci_returned_accessories');
define('MERCI_CHECKED_OUT_ACCESSORIES', 'merci_checked_out_accessories');
define('MERCI_CHECKOUT_STATUS', 'merci_checkout_status');
define('MERCI_NOTES', 'merci_notes');

// Taxonomy
define('MERCI_ACCESSORY_TAXONOMY', 'merci_accessory_taxonomy');

// Paths
define('MERCI_LINE_ITEM_TYPE_PATH', MERCI_ADMIN_CONFIG_PATH . '/merci-line_items');
define('MERCI_LINE_ITEM_PATH', MERCI_LINE_ITEM_TYPE_PATH);

/**
 * Implements hook_ctools_plugin_directory().
 */
function merci_line_item_ctools_plugin_directory($module, $plugin) {
  if ($module == 'entity_validator') {
    return 'plugins/' . $plugin;
  }
}

/*
 * Save the parent_id to the merci_line_item_id entity_id property.
 */
function merci_line_item_entity_insert($entity, $type) {
  $field_items = field_get_items($type, $entity, MERCI_LINE_ITEM_REFERENCE);
  if ($field_items) {
    $entity_wrapper = entity_metadata_wrapper($type, $entity);
    $line_item_ids = array();
    foreach ($field_items as $item) {
      $line_item_ids[] = $item['target_id'];
    }
    $line_items = merci_line_item_load_multiple($line_item_ids);
    foreach ($line_items as $line_item) {
      $line_item->entity_id = $entity_wrapper
        ->getIdentifier();
      merci_line_item_save($line_item);
    }
  }
}

/*
 * Add default fields.
 */
function merci_line_item_merci_line_item_type_insert($entity) {
  merci_line_item_configuration($entity);
}

/**
 * Implements hook_entity_info().
 */
function merci_line_item_entity_info() {
  $entities['merci_line_item'] = array(
    'label' => t('MERCI Line Item'),
    'plural label' => t('MERCI Line Items'),
    'entity class' => 'MerciLineItem',
    'controller class' => 'MerciLineItemController',
    'module' => 'merci_line_item',
    'base table' => 'merci_line_item',
    'fieldable' => TRUE,
    'entity keys' => array(
      'id' => 'line_item_id',
      'bundle' => 'type',
    ),
    'bundle keys' => array(
      'bundle' => 'type',
    ),
    'access callback' => 'merci_line_item_access',
    /*
        'admin ui' => array(
     'path' => 'admin/merci/merci_line_items',
     'file' => 'merci_line_item.admin.inc',
        ),
    */
    'label callback' => 'entity_class_label',
    'uri callback' => 'entity_class_uri',
    'view modes' => array(
      'display' => array(
        'label' => t('Display'),
        'custom settings' => FALSE,
      ),
      'add_form' => array(
        'label' => t('Add form'),
        'custom settings' => TRUE,
      ),
      'list' => array(
        'label' => t('List'),
        'custom settings' => TRUE,
      ),
    ),
  );
  $entities['merci_line_item_type'] = array(
    'label' => t('MERCI Line Item Type'),
    'plural label' => t('MERCI Line Item Types'),
    'entity class' => 'MerciLineItemType',
    'controller class' => 'MerciLineItemTypeController',
    'module' => 'merci_line_item',
    'base table' => 'merci_line_item_type',
    'fieldable' => FALSE,
    'entity keys' => array(
      'id' => 'id',
      'name' => 'type',
      'label' => 'label',
    ),
    'bundle of' => 'merci_line_item',
    'exportable' => TRUE,
    'access callback' => 'merci_line_item_type_access',
    'admin ui' => array(
      'path' => 'admin/merci/merci-line-item-types',
      'file' => 'merci_line_item_type.admin.inc',
      'controller class' => 'MerciLineItemTypeUIController',
      'menu_wildcard' => '%merci_line_item_type',
    ),
    'label callback' => 'entity_class_label',
    'uri callback' => 'entity_class_uri',
  );
  return $entities;
}

/**
* implements hook_entity_info_alter().
*/
function merci_line_item_entity_info_alter(&$entity_info) {
  foreach (merci_line_item_types() as $type => $info) {
    $entity_info['merci_line_item']['bundles'][$type] = array(
      'label' => $info->label,
      'admin' => array(
        'path' => 'admin/merci/merci-line-item-types/manage/%merci_line_item_type',
        'real path' => 'admin/merci/merci-line-item-types/manage/' . $type,
        'bundle argument' => 4,
        'access arguments' => array(
          'administer merci line item types',
        ),
      ),
    );
  }
}

/**
 * Implements hook_entity_property_info().
 */
function merci_line_item_entity_property_info_alter(&$info) {
  $properties =& $info['merci_line_item']['properties'];
  $properties['entity'] = array(
    'label' => t('Entity', array(), array(
      'context' => 'a drupal entity',
    )),
    'type' => 'entity',
    'description' => t('The entity the line item belongs to.'),
    'getter callback' => 'merci_line_item_get_properties',
    'setter callback' => 'merci_line_item_set_properties',
    'setter permission' => 'administer merci line items',
    'required' => TRUE,
    'computed' => TRUE,
    'clear' => array(
      'entity_id',
    ),
  );
  $properties['created'] = array(
    'label' => t('Date created'),
    'description' => t('The date the line item was created.'),
    'type' => 'date',
    'setter callback' => 'entity_metadata_verbatim_set',
    'setter permission' => 'administer merci line items',
    'schema field' => 'created',
  );
  $properties['changed'] = array(
    'label' => t('Date changed'),
    'description' => t('The date the line item was most recently updated.'),
    'type' => 'date',
    'schema field' => 'changed',
  );
  $properties['line_item_label'] = array(
    'label' => t('Line item label'),
    'description' => t('The label displayed with the line item.'),
    'type' => 'text',
    'setter callback' => 'entity_property_verbatim_set',
    'required' => TRUE,
    'schema field' => 'line_item_label',
  );
  $properties['owner'] = array(
    'label' => t('Owner'),
    'description' => t('The owner of the reservation.'),
    'type' => 'user',
    'schema field' => 'uid',
  );
}

/**
 * Callback for getting line item properties.
 *
 * @see commerce_line_item_entity_property_info()
 */
function merci_line_item_get_properties($line_item, array $options, $name) {
  switch ($name) {
    case 'entity':
      return !empty($line_item->entity_id) ? $line_item->entity_id : 0;
  }
}

/**
 * Callback for setting line item properties.
 *
 * @see commerce_line_item_entity_property_info()
 */
function merci_line_item_set_properties($line_item, $name, $value) {
  switch ($name) {
    case 'entity':
      $line_item->entity_id = $value;
      break;
  }
}

/**
 * Implements hook_enable().
 */
function merci_line_item_enable() {

  //merci_line_item_configure_line_item_types();
  $line_item_types = merci_line_item_types_info();
  foreach ($line_item_types as $type => $options) {
    $entity = entity_create('merci_line_item_type', $options);
    entity_save('merci_line_item_type', $entity);
  }
}

/**
 * Implements hook_field_extra_fields().
 */
function merci_line_item_field_extra_fields() {
  $extra = array();
  foreach (merci_line_item_types() as $type => $line_item_type) {
    $extra['merci_line_item'][$type] = array(
      'form' => array(
        'line_item_label' => array(
          'label' => t('Line item label'),
          'description' => t('Line item module label form element'),
          'weight' => -10,
        ),
        'quantity' => array(
          'label' => t('Quantity'),
          'description' => t('Line item module quantity form element'),
          'weight' => -5,
        ),
      ),
      'display' => array(
        'line_item_label' => array(
          'label' => t('Line item label'),
          'description' => t('Short descriptive label for the line item'),
          'weight' => -10,
        ),
        'quantity' => array(
          'label' => t('Quantity'),
          'description' => t('Quantity associated with this line item'),
          'weight' => -5,
        ),
      ),
    );
  }
  return $extra;
}

/**
 * Returns an array of line item type arrays keyed by type.
 */
function merci_line_item_types_info() {

  // First check the static cache for a line item types array.
  $line_item_types =& drupal_static(__FUNCTION__);

  // If it did not exist, fetch the types now.
  if (!isset($line_item_types)) {
    $line_item_types = module_invoke_all('merci_line_item_type_info');
    drupal_alter('merci_line_item_type_info', $line_item_types);
    foreach ($line_item_types as $type => &$line_item_type) {
      $defaults = array(
        'type' => $type,
        'base' => $type,
        'callbacks' => array(),
      );
      $line_item_type += $defaults;

      // Merge in default callbacks.
      foreach (array(
        'configuration',
        'title',
        'add_form',
        'add_form_submit',
      ) as $callback) {
        if (!isset($line_item_type['callbacks'][$callback])) {
          $line_item_type['callbacks'][$callback] = $line_item_type['base'] . '_' . $callback;
        }
      }
    }
  }
  return $line_item_types;
}

/**
 *  * Implements hook_merci_line_item_type_info().
 *   */
function merci_line_item_merci_line_item_type_info() {
  $line_item_types = array();
  $line_item_types[MERCI_LINE_ITEM] = array(
    'label' => t('Checkout Line Item'),
    //'description' => t('References a resource and displays it with the SKU as the label.'),
    'module' => 'merci_line_item',
    'base' => 'merci_line_item',
    'add_form_submit_value' => t('Checkout item'),
  );
  return $line_item_types;
}

/**
 * Implements hook_merci_fields_info().
 */
function merci_line_item_merci_fields_info() {
  $fields = array();
  module_load_include('inc', 'merci_line_item', 'merci_line_item_fields');
  $field_bases = merci_line_item_fields();
  $instances = merci_line_item_instances();
  foreach ($field_bases as $field_name => $field) {
    $fields[$field_name] = array(
      'field' => $field,
      'instance' => $instances[$field_name],
    );
  }
  return $fields;
}

/**
 * Ensures the product line item type contains a product reference field.
 *
 * This function is called by the line item module when it is enabled or this
 * module is enabled. It invokes this function using the configuration_callback
 * as specified above. Other modules defining product line item types should
 * use this function to ensure their types have the required fields.
 *
 * @param $line_item_type
 *   The info array of the line item type being configured.
 */
function merci_line_item_configuration($merci_line_item_type) {
  $type = $merci_line_item_type->type;

  // Create the product reference field for the line item type.

  //commerce_product_reference_create_instance('commerce_product', 'commerce_line_item', $type, t('Product'));
  merci_core_create_field(MERCI_CHECKOUT_DATES, 'merci_line_item', $type);
  merci_core_create_field(MERCI_RETURNED_ACCESSORIES, 'merci_line_item', $type);
  merci_core_create_field(MERCI_CHECKED_OUT_ACCESSORIES, 'merci_line_item', $type);
  merci_core_create_field(MERCI_CHECKOUT_STATUS, 'merci_line_item', $type);
  merci_core_create_field(MERCI_NOTES, 'merci_line_item', $type);
  merci_core_create_field(MERCI_RETURN_DATE, 'merci_line_item', $type);
  merci_core_create_field(MERCI_RESOURCE_REFERENCE, 'merci_line_item', $type);
  merci_core_create_field(MERCI_RESOURCE_DISPLAY, 'merci_line_item', $type);
}

/**
 * Implements hook_permission().
 */
function merci_line_item_permission() {
  $permissions = array(
    'administer merci line item types' => array(
      'title' => t('Administer MERCI line item types'),
      'description' => t('View and configure fields attached to module defined line item types.'),
      'restrict access' => TRUE,
    ),
    'administer merci line items' => array(
      'title' => t('Administer MERCI line items'),
      'description' => t('Update and delete any line item on the site.'),
      'restrict access' => TRUE,
    ),
    'create own merci line item' => array(
      'title' => t('Create own MERCI line item'),
      'description' => t('View and configure fields attached to module defined line item types.'),
    ),
    'create any merci line item' => array(
      'title' => t('Create any MERCI line item'),
      'description' => t('Update and delete any line item on the site.'),
      'restrict access' => TRUE,
    ),
    'view own merci line item' => array(
      'title' => t('View own MERCI line item'),
      'description' => t('View and configure fields attached to module defined line item types.'),
    ),
    'view any merci line item' => array(
      'title' => t('View any MERCI line item'),
      'description' => t('Update and delete any line item on the site.'),
      'restrict access' => TRUE,
    ),
  );
  return $permissions;
}

/**
 * Determines access to perform an operation on a particular line item.
 *
 * @param $op
 *   The operation to perform on the line item, either 'update' or 'delete'.
 * @param $line_item
 *   The line item object in question.
 * @param $account
 *   The user account whose access should be checked; defaults to the current
 *   user if left NULL.
 *
 * @return
 *   TRUE or FALSE indicating whether or not access should be granted.
 */
function merci_line_item_type_access($op, $line_item, $account = NULL) {
  global $user;
  $account = isset($account) ? $account : clone $user;

  // If the user has the administration permission, return TRUE now.
  if (user_access('administer merci line items', $account)) {
    return TRUE;
  }

  // For users who don't have the general administration permission, we have to
  // determine access to update or delete a given line item through a connection
  // to an Order.

  /* TODO
    if (!empty($line_item->order_id) && module_exists('commerce_order')) {
      $order = commerce_order_load($line_item->order_id);
      return commerce_order_access($op, $order, $account);
    }
     */

  // Issue a blanket refusal of access in the event the order module is not
  // enabled, as we have no other way of determining line item access outside of
  // the 'administer line items' permission.
  return FALSE;
}

/**
 * Determines access to perform an operation on a particular line item.
 *
 * @param $op
 *   The operation to perform on the line item, either 'update' or 'delete'.
 * @param $line_item
 *   The line item object in question.
 * @param $account
 *   The user account whose access should be checked; defaults to the current
 *   user if left NULL.
 *
 * @return
 *   TRUE or FALSE indicating whether or not access should be granted.
 */
function merci_line_item_access($op, $line_item, $account = NULL) {
  global $user;
  $account = isset($account) ? $account : clone $user;

  // If the user has the administration permission, return TRUE now.
  if (user_access('create any merci line item', $account) or user_access('administer merci line items', $account)) {
    return TRUE;
  }
  if (user_access('create any merci line item', $account)) {
    return TRUE;
  }
  if (user_access('create own merci line item', $account)) {
    return TRUE;
  }

  // For users who don't have the general administration permission, we have to
  // determine access to update or delete a given line item through a connection
  // to an Order.

  /* TODO
    if (!empty($line_item->order_id) && module_exists('commerce_order')) {
      $order = commerce_order_load($line_item->order_id);
      return commerce_order_access($op, $order, $account);
    }
     */

  // Issue a blanket refusal of access in the event the order module is not
  // enabled, as we have no other way of determining line item access outside of
  // the 'administer line items' permission.
  return FALSE;
}

/**
 * Returns a single line item type array.
 *
 * @param $type
 *   The machine-readable name of the line item type.
 *
 * @return
 *   The specified line item type array or FALSE if it does not exist.
 */
function merci_line_item_type_load($type) {
  $line_item_types = merci_line_item_types();
  return isset($line_item_types[$type]) ? $line_item_types[$type] : FALSE;
}

/**
 * Saves a line item.
 *
 * @param $line_item
 *   The full line item object to save.
 *
 * @return
 *   SAVED_NEW or SAVED_UPDATED depending on the operation performed.
 */
function merci_line_item_save($line_item) {
  return entity_get_controller('merci_line_item')
    ->save($line_item);
}

/**
 * Validates a line item.
 *
 * @param $line_item
 *   The full line item object to save.
 *
 */
function merci_line_item_validate($line_item) {
  return entity_get_controller('merci_line_item')
    ->validate($line_item);
}

/**
 * Loads a line item by ID.
 */
function merci_line_item_load($line_item_id) {
  $line_items = merci_line_item_load_multiple(array(
    $line_item_id,
  ), array());
  return $line_items ? reset($line_items) : FALSE;
}

/**
 * Loads multiple line items by ID or based on a set of matching conditions.
 *
 * @see entity_load()
 *
 * @param $line_item_ids
 *   An array of line item IDs.
 * @param $conditions
 *   An array of conditions on the {commerce_line_item} table in the form
 *     'field' => $value.
 * @param $reset
 *   Whether to reset the internal line item loading cache.
 *
 * @return
 *   An array of line item objects indexed by line_item_id.
 */
function merci_line_item_load_multiple($line_item_ids = array(), $conditions = array(), $reset = FALSE) {
  return entity_load('merci_line_item', $line_item_ids, $conditions, $reset);
}

/**
 * Deletes a line item by ID.
 *
 * @param $line_item_id
 *   The ID of the line item to delete.
 *
 * @return
 *   TRUE on success, FALSE otherwise.
 */
function merci_line_item_delete($line_item_id) {
  return merci_line_item_delete_multiple(array(
    $line_item_id,
  ));
}

/**
 * Deletes multiple line items by ID.
 *
 * @param $line_item_ids
 *   An array of line item IDs to delete.
 *
 * @return
 *   TRUE on success, FALSE otherwise.
 */
function merci_line_item_delete_multiple($line_item_ids) {
  return entity_get_controller('merci_line_item')
    ->delete($line_item_ids);
}

/**
 * List of task Types.
 */
function merci_line_item_types($type_name = NULL) {
  $types = entity_load_multiple_by_name('merci_line_item_type', isset($type_name) ? array(
    $type_name,
  ) : FALSE);
  return isset($type_name) ? reset($types) : $types;
}

/**
 * Resets the cached list of line item types.
 */
function merci_line_item_types_reset() {
  $line_item_types =& drupal_static('merci_line_item_types');
  $line_item_types = NULL;
  entity_info_cache_clear();
}

/**
 * Returns the human readable name of any or all line item types.
 *
 * @param $type
 *   Optional parameter specifying the type whose name to return.
 *
 * @return
 *   Either an array of all line item type names keyed by the machine name or a
 *     string containing the human readable name for the specified type. If a
 *     type is specified that does not exist, this function returns FALSE.
 */
function merci_line_item_type_get_name($type = NULL) {
  $line_item_types = merci_line_item_types();

  // Return a type name if specified and it exists.
  if (!empty($type)) {
    if (isset($line_item_types[$type])) {
      return $line_item_types[$type]->name;
    }
    else {

      // Return FALSE if it does not exist.
      return FALSE;
    }
  }

  // Otherwise turn the array values into the type name only.
  $line_item_type_names = array();
  foreach ((array) $line_item_types as $key => $value) {
    $line_item_type_names[$key] = $value->name;
  }
  return $line_item_type_names;
}

/**
 * Implements hook_field_formatter_info().
 */
function merci_line_item_field_formatter_info() {
  return array(
    'merci_line_item_label' => array(
      'label' => t('Label with statuses'),
      'description' => t('Display the label of the referenced line items sorted by statuses.'),
      'field types' => array(
        'entityreference',
      ),
      'settings' => array(
        'link' => FALSE,
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function merci_line_item_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $result = array();

  // Collect the list of line item IDs.
  $line_item_ids = array();
  foreach ($items as $delta => $item) {
    $line_item_ids[] = $item['target_id'];
  }
  switch ($display['type']) {
    case 'merci_line_item_label':
      if ($line_item_ids) {
        $target_entities = entity_load('merci_line_item', $line_item_ids);
      }
      else {
        $target_entities = array();
      }
      foreach ($items as $delta => $item) {
        $line_item = $target_entities[$item['target_id']];
        $label = $line_item->line_item_label;
        $status = $line_item->{MERCI_CHECKOUT_STATUS}['und'][0]['value'];
        if (!array_key_exists($status, $result)) {
          $result[$status] = array();
        }

        // If the link is to be displayed and the entity has a uri, display a link.
        // Note the assignment ($url = ) here is intended to be an assignment.
        if ($display['settings']['link'] && ($uri = entity_uri($field['settings']['target_type'], $item['entity']))) {
          $result[$status][$delta] = array(
            '#markup' => l($label, $uri['path'], $uri['options']),
          );
        }
        else {

          //$result[$status][$delta] = array('#markup' => check_plain($label));
          $result[$status][$delta] = check_plain($label);
        }
      }
      $output = array();
      foreach ($result as $status => $fields) {
        $output[] = $status . ': ' . implode(', ', $fields);
      }
      $result = array();
      $result[0] = array(
        '#markup' => implode('<br>', $output),
      );
      break;
  }
  return $result;
}

/**
 *  * Implements hook_views_api().
 *   */
function merci_line_item_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'merci_line_item') . '/includes/views',
  );
}

/*
 Check for any conflicts.

 Also set status and add/remove line_items as quantity changes.
*/
function merci_line_item_merci_line_item_validate($line_item, $form, &$form_state) {
  $field_status = MERCI_CHECKOUT_STATUS;
  $field_date = MERCI_CHECKOUT_DATES;
  $field_resource = MERCI_RESOURCE_REFERENCE;
  $line_item_wrapper = entity_metadata_wrapper('merci_line_item', $line_item);

  // No conflict checking or returned, missing or broken items.
  $status = $line_item_wrapper->{$field_status}
    ->value();
  if (!empty($status) and in_array($status, array(
    'returned',
    'missing',
    'broken',
  ))) {
    return;
  }

  // Check of conflicts.
  $context = array(
    'quantity_field' => 'quantity',
    'date_field' => $field_date,
    'item_field' => $field_resource,
    'status_field' => $field_status,
  );
  $controller = merci_get_controller('non_inventory', $context);
  $resource = $line_item_wrapper->{$context['item_field']};

  // Determine if the quantity field exists.  If so use it.
  try {
    $quantity = $resource->{$context['quantity_field']}
      ->value();
  } catch (EntityMetadataWrapperException $e) {
    $quantity = 1;
  }

  // Returns array of $product_id => $line_item_id
  $conflicts = $controller
    ->conflicts($line_item_wrapper);
  if (count($conflicts) + $line_item_wrapper->quantity
    ->value() > $quantity) {
    $orders = array();
    $ids = array();
    foreach ($conflicts as $line_items) {
      foreach ($line_items as $item) {
        $line_item_single = entity_load_single('merci_line_item', $item->parent_id);
        $ids[] = $line_item_single->entity_id;
      }
    }

    // Display an error with links to the conflicting reservations.
    if (count($conflicts) and count($ids)) {

      // Load the parent entities which hold the conflicting line item.
      $entities = entity_load($form_state['complete form']['#entity_type'], $ids);
      foreach ($entities as $id => $entity) {
        $entity_uri = entity_uri($form_state['complete form']['#entity_type'], $entity);
        $entity_label = entity_label($form_state['complete form']['#entity_type'], $entity);
        $orders[] = l(t("@label", array(
          '@label' => $entity_label,
        )), $entity_uri['path']);
      }

      // $entity_uri = entity_uri($form_state['complete form']['#entity_type'], $form_state['complete form']['#entity']);
      $parents_path = implode('][', $form['#parents']) . '][' . MERCI_RESOURCE_REFERENCE;
      form_set_error($parents_path, t('%name is already checked out or reserved by: !orders', array(
        '%name' => $resource
          ->label(),
        '!orders' => implode(', ', $orders),
      )));
    }

    // Display an error for not enough available items.
    if (count($conflicts) < $quantity) {
      $available = $quantity - count($conflicts);
      $parents_path = implode('][', $form['#parents']) . '][' . MERCI_RESOURCE_REFERENCE;
      form_set_error($parents_path, t('You reserved %count but only %available are available.', array(
        '%count' => $line_item_wrapper->quantity
          ->value(),
        '%available' => $available,
      )));
    }
  }

  // Return if any errors from validation.
  if (form_get_errors()) {
    return t('Form error');
  }

  // Set the checkout status based on the reservation date.
  if ($line_item->is_new) {
    $now = new DateObject('now');

    //,'UTC');
    $start_date = new DateObject($line_item_wrapper->{MERCI_CHECKOUT_DATES}->value
      ->value());

    //, 'UTC');
    $end_date = new DateObject($line_item_wrapper->{MERCI_CHECKOUT_DATES}->value2
      ->value());

    //, 'UTC');
    $start_date = $start_date
      ->modify('-8 min');
    if ($start_date <= $now and $end_date > $now) {
      $line_item_wrapper->{MERCI_CHECKOUT_STATUS} = 'checked out';
    }
    else {
      if ($start_date > $now) {
        $line_item_wrapper->{MERCI_CHECKOUT_STATUS} = 'reserved';
      }
      else {
        $line_item_wrapper->{MERCI_CHECKOUT_STATUS} = 'pending';
      }
    }
  }
  else {

    // Modify attached line items if the quantity changes.
    //
    $line_item_unchanged = entity_load_unchanged('merci_line_item', $line_item->line_item_id);
    $line_item_unchanged_wrapper = entity_metadata_wrapper('merci_line_item', $line_item_unchanged);

    // Only matters if quantity is lowered.
    if ($line_item->quantity < $line_item_unchanged->quantity) {

      // Check if Date is changed.
      $date_diff = array_diff_assoc($line_item_wrapper->{MERCI_CHECKOUT_DATES}
        ->value(), $line_item_unchanged_wrapper->{MERCI_CHECKOUT_DATES}
        ->value());
      if (!empty($date_diff) or $line_item_wrapper->{MERCI_CHECKOUT_STATUS} != $line_item_unchanged_wrapper->{MERCI_CHECKOUT_STATUS}) {

        // Create a new line_item entry for non-inventory items which are not changed by this update.
        $line_item_unchanged->quantity = $line_item_unchanged->quantity - $line_item->quantity;
        unset($line_item_unchanged->line_item_id);
        $line_item_unchanged->is_new = TRUE;
        $context = array(
          'parent_entity_type' => $form_state['complete form']['#entity_type'],
          'parent_entity' => $form_state['complete form']['#entity'],
        );

        // Save both entites now.
        $this
          ->save($line_item, $context);
        $this
          ->save($line_item_unchanged, $context);
        $ief_id = $form['#ief_id'];

        // Determine the correct weight of the new element.
        $weight = 0;
        if (!empty($form_state['inline_entity_form'][$ief_id]['entities'])) {
          $weight = max(array_keys($form_state['inline_entity_form'][$ief_id]['entities'])) + 1;
        }

        // Add the entity to form state, mark it for saving, and close the form.
        $form_state['inline_entity_form'][$ief_id]['entities'][] = array(
          'entity' => $line_item_unchanged,
          'weight' => $weight,
          'form' => NULL,
          'needs_save' => false,
        );
      }
    }
  }
  $line_item_values = drupal_array_get_nested_value($form_state['values'], $form['#parents']);

  // Set the checkout status if it was changed.
  if (!empty($line_item_values[MERCI_CHECKOUT_STATUS]['und'][0]['value'])) {
    $line_item_wrapper->{MERCI_CHECKOUT_STATUS} = $line_item_values[MERCI_CHECKOUT_STATUS]['und'][0]['value'];
  }

  // Set the title of the resource.
  $line_item_wrapper->line_item_label
    ->set($resource
    ->label());
  drupal_array_set_nested_value($form_state['values'], $form['#parents'], (array) $line_item);
}

Functions

Namesort descending Description
merci_line_item_access Determines access to perform an operation on a particular line item.
merci_line_item_configuration Ensures the product line item type contains a product reference field.
merci_line_item_ctools_plugin_directory Implements hook_ctools_plugin_directory().
merci_line_item_delete Deletes a line item by ID.
merci_line_item_delete_multiple Deletes multiple line items by ID.
merci_line_item_enable Implements hook_enable().
merci_line_item_entity_info Implements hook_entity_info().
merci_line_item_entity_info_alter implements hook_entity_info_alter().
merci_line_item_entity_insert
merci_line_item_entity_property_info_alter Implements hook_entity_property_info().
merci_line_item_field_extra_fields Implements hook_field_extra_fields().
merci_line_item_field_formatter_info Implements hook_field_formatter_info().
merci_line_item_field_formatter_view Implements hook_field_formatter_view().
merci_line_item_get_properties Callback for getting line item properties.
merci_line_item_load Loads a line item by ID.
merci_line_item_load_multiple Loads multiple line items by ID or based on a set of matching conditions.
merci_line_item_merci_fields_info Implements hook_merci_fields_info().
merci_line_item_merci_line_item_type_info Implements hook_merci_line_item_type_info().
merci_line_item_merci_line_item_type_insert
merci_line_item_merci_line_item_validate
merci_line_item_permission Implements hook_permission().
merci_line_item_save Saves a line item.
merci_line_item_set_properties Callback for setting line item properties.
merci_line_item_types List of task Types.
merci_line_item_types_info Returns an array of line item type arrays keyed by type.
merci_line_item_types_reset Resets the cached list of line item types.
merci_line_item_type_access Determines access to perform an operation on a particular line item.
merci_line_item_type_get_name Returns the human readable name of any or all line item types.
merci_line_item_type_load Returns a single line item type array.
merci_line_item_validate Validates a line item.
merci_line_item_views_api Implements hook_views_api().

Constants