You are here

function merci_line_item_merci_line_item_validate in MERCI (Manage Equipment Reservations, Checkout and Inventory) 7.3

File

merci_line_item/merci_line_item.module, line 739
Defines the core MERCI line item entity and API functions interact with line items.

Code

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);
}