Skip to content

Instantly share code, notes, and snippets.

@andyg5000
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andyg5000/ba1c437ee815b29bdb66 to your computer and use it in GitHub Desktop.
Save andyg5000/ba1c437ee815b29bdb66 to your computer and use it in GitHub Desktop.
Commerce Box Utility Functions patch
diff --git a/commerce_box.module b/commerce_box.module
index 823b130..057c2a1 100644
--- a/commerce_box.module
+++ b/commerce_box.module
@@ -525,3 +525,371 @@ function commerce_box_get_statuses() {
function commerce_box_status_options_list() {
return commerce_box_get_statuses();
}
+
+/**
+ * Determines if there is room in the box for a product by volume.
+ * @param object $product
+ * A commerce product object.
+ * @param object $box
+ * A commerce box object.
+ * @param integer $offset
+ * An offset to subtract from the box volume.
+ * @return boolean
+ */
+function commerce_box_box_has_room_by_volume($product, $box, $offset = 0) {
+ $product->volume = commerce_box_get_entity_volume($product, 'commerce_product');
+ $box->volume = commerce_box_get_entity_volume($box, 'commerce_box');
+
+ if (!empty($product->volume) && !empty($box->volume)) {
+ return ($box->volume - $offset >= $product->volume) >= 0;
+ }
+
+ return FALSE;
+}
+
+/**
+ * Determines number of boxes required to pack product volume.
+ * @param integer $box_volume
+ * Volume of the box.
+ * @param integer $contents_volume
+ * Volume of the contents that should fit in the box volume.
+ * @return integer
+ * The number of contents that will fit in the box.
+ */
+function commerce_box_box_count_by_volume($box_volume, $contents_volume) {
+ if ((int) $box_volume > 0 && (int) $contents_volume > 0) {
+ return ceil($contents_volume / $box_volume);
+ }
+ return 0;
+}
+
+/**
+ * Returns a non-unique array of product ids on an order.
+ */
+function commerce_box_product_id_list_from_order_line_items($order) {
+ $line_items = array();
+ if (!empty($order->commerce_line_items)) {
+ $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
+ foreach ($order_wrapper->commerce_line_items->value() as $line_item) {
+ if (!empty($line_item->commerce_product)) {
+ $line_items[] = $line_item;
+ }
+ }
+ }
+ return commerce_box_product_id_list_from_line_items($line_items);
+}
+
+/**
+ * Returns a non-unique array of product ids for each line item.
+ * @param array $line_items
+ * An array of commerce line item objects.
+ * @return array
+ * An array of non-unique product ids for each quantity item.
+ */
+function commerce_box_product_id_list_from_line_items($line_items) {
+ $product_ids = array();
+ foreach ($line_items as $line_item) {
+ $line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
+
+ $product = $line_item_wrapper->commerce_product->value();
+
+ $dimensions = commerce_box_get_entity_dimensions($product, 'commerce_product');
+
+ // Do not add products without dimensions to the array.
+ if (empty($dimensions)) {
+ continue;
+ }
+
+ for ($i = 0; $i < $line_item->quantity; $i++) {
+ $product_ids[] = $line_item_wrapper->commerce_product->product_id->value();
+ }
+ }
+ return $product_ids;
+}
+
+/**
+ * Helper function to return product id list from shipments on an order.
+ */
+function commerce_box_product_id_list_from_order_shipments($order) {
+ $shipments = array();
+ if (!empty($order->commerce_shipments)) {
+ $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
+ $shipments = $order_wrapper->commerce_shipments->value();
+ }
+ return commerce_box_product_id_list_from_shipment($shipments);
+}
+
+/**
+ * Returns a non-unique array of product ids for each shipment.
+ */
+function commerce_box_product_id_list_from_shipment($shipments) {
+ $product_ids = array();
+ $field_name = commerce_box_shipment_product_reference_field();
+ foreach ($shipments as $shipment) {
+ if (!empty($shipment->{$field_name})) {
+ $shipment_wrapper = entity_metadata_wrapper('commerce_shipment', $shipment);
+ foreach ($shipment_wrapper->{$field_name}->value() as $product) {
+ $product_ids[] = $product->product_id;
+ }
+ }
+ }
+ return $product_ids;
+}
+
+/**
+ * Wrapper function to create a commerce_shipment entitiy.
+ * @param object $order
+ * A commerce order object.
+ * @param object $box
+ * A commerce box object.
+ * @param array $product_ids
+ * An array of product_ids that are included in the shipment.
+ * @param array $data
+ * An array of metadata to save with the shipment
+ * @return object
+ * A commerce shipment object.
+ */
+function commerce_box_create_shipment($order, $box, $product_ids, $data = array()) {
+
+ $values = array(
+ 'type' => 'shipment',
+ 'order_id' => $order->order_id,
+ 'data' => array(
+ 'shipment_weight' => 0,
+ ) + $data,
+ );
+
+ $product_reference = commerce_box_shipment_product_reference_field();
+ $box_reference = commerce_box_shipment_box_reference_field();
+
+ // Calculate the total weight of the shipment.
+ foreach ($product_ids as $product_id) {
+ $product = commerce_product_load($product_id);
+ $values['data']['shipment_weight'] += commerce_box_get_entity_weight($product, 'commerce_product');
+ }
+
+ $shipment = entity_create('commerce_shipment', $values);
+ $shipment_wrapper = entity_metadata_wrapper('commerce_shipment', $shipment);
+ $shipment_products = array();
+ foreach ($product_ids as $product_id) {
+ $shipment_wrapper->{$product_reference}[] = $product_id;
+ }
+
+ if (!empty($box->box_id)) {
+ $shipment_wrapper->{$box_reference}->set($box);
+ }
+
+ return $shipment;
+}
+
+/**
+ * Determines if a product will physically fit in a box.
+ * @param object $product
+ * A commerce product object.
+ * @param object $box
+ * A commerce box object.
+ * @return boolean
+ * TRUE if a product will fit into a box.
+ */
+function commerce_box_product_fits_in_box($product, $box) {
+ $product->dimensions = commerce_box_get_entity_dimensions($product, 'commerce_product');
+ $product->volume = commerce_box_get_entity_volume($product, 'commerce_product');
+ $box->dimensions = commerce_box_get_entity_dimensions($box, 'commerce_box');
+ $box->volume = commerce_box_get_entity_volume($box, 'commerce_box');
+
+ // Return false if the product volume is greater than that of the box.
+ if ($box->volume < $product->volume) {
+ return FALSE;
+ }
+
+ if (!empty($box->dimensions) && !empty($product->dimensions)) {
+ unset($product->dimensions['unit']);
+ unset($box->dimensions['unit']);
+
+ arsort($product->dimensions);
+ arsort($box->dimensions);
+
+ $sides = array('length', 'width', 'height');
+
+ // Loop through each dimensional side to make sure that the product will
+ // physically fit in the box.
+ foreach ($sides as $side) {
+ if ($product->dimensions[$side] > $box->dimensions[$side]) {
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * Returns the weight of an entity containing physical weight field.
+ * @param object $entity
+ * A Drupal entity object.
+ * @param string $type
+ * The entity type.
+ * @param string $field_name
+ * An optional field name (useful when more than one field exists).
+ *
+ * @return integer
+ * The weight of the entity.
+ */
+function commerce_box_get_entity_weight(&$entity, $type, $field_name = NULL) {
+
+ // Check to see if we've already set the weight value.
+ if (!empty($entity->weight)) {
+ return $entity->weight;
+ }
+
+ $weight = 0;
+
+ if (empty($field_name)) {
+ $field_name = commerce_physical_entity_weight_field_name($type, $entity);
+ }
+
+ if (!empty($field_name) && !empty($entity->{$field_name})) {
+ // Extract the dimensions value from the entity.
+ $wrapper = entity_metadata_wrapper($type, $entity);
+ $value = $wrapper->{$field_name}->value();
+ $weight = !empty($value['weight']) ? $value['weight'] : 0;
+ $entity->weight = $weight;
+ }
+
+ return $weight;
+}
+
+/**
+ * Returns the volume of an entity containing physical weight field.
+ * @param object $entity
+ * A Drupal entity object.
+ * @param string $type
+ * The entity type.
+ * @param string $field_name
+ * An optional field name (useful when more than one field exists).
+ *
+ * @return integer
+ * The volume of the entity.
+ */
+function commerce_box_get_entity_volume(&$entity, $type, $field_name = NULL) {
+
+ // Check to see if we've already set the volume value.
+ if (!empty($entity->volume)) {
+ return $entity->volume;
+ }
+
+ $volume = 0;
+ $dimensions = commerce_box_get_entity_dimensions($entity, $type, $field_name);
+ if (!empty($dimensions)) {
+ $volume = $dimensions['length'] * $dimensions['width'] * $dimensions['height'];
+ $entity->volume = $volume;
+ }
+
+ return $volume;
+}
+
+/**
+ * Returns the dimensions of an entity containing physical dimensions field.
+ * @param object $entity
+ * A Drupal entity object.
+ * @param string $type
+ * The entity type.
+ * @param string $field_name
+ * An optional field name (useful when more than one field exists).
+ *
+ * @return array
+ * The array returned from the physical dimensions field value.
+ */
+function commerce_box_get_entity_dimensions(&$entity, $type, $field_name = NULL) {
+
+ // Check to see if we've alredy set the dimension value.
+ if (!empty($entity->dimensions)) {
+ return $entity->dimensions;
+ }
+
+ $dimensions = array();
+
+ if (empty($field_name)) {
+ $field_name = commerce_physical_entity_dimensions_field_name($type, $entity);
+ }
+
+ if (!empty($field_name) && !empty($entity->{$field_name})) {
+ // Extract the dimensions value from the entity.
+ $wrapper = entity_metadata_wrapper($type, $entity);
+ $dimensions = $wrapper->{$field_name}->value();
+
+ // Save the value to the entity object.
+ $entity->dimensions = $dimensions;
+ }
+
+ return $dimensions;
+}
+
+/**
+ * Returns the elements of an array that exist in array1, but not in array2.
+ * @param array $array1
+ * The larger array (ie: all order products).
+ * @param array $array2
+ * The smaller array (ie: products in a shipment).
+ * @return array
+ * The values present in array1, but not in array2.
+ */
+function commerce_box_product_array_diff($array1, $array2) {
+ foreach ($array1 as $key => $value) {
+ if (in_array($value, $array2)) {
+ unset($array1[$key]);
+ $key2 = array_search($value, $array2);
+ unset($array2[$key2]);
+ }
+ }
+ return $array1;
+}
+
+/**
+ * Sorts products from largest to smallest.
+ */
+function commerce_box_products_sort_by_dimensions($product1, $product2) {
+ $dimensions1 = commerce_box_get_entity_dimensions($product1, 'commerce_product');
+ $dimensions2 = commerce_box_get_entity_dimensions($product2, 'commerce_product');
+
+ unset($dimensions1['unit']);
+ unset($dimensions2['unit']);
+
+ // Sort by the largest to smallest side.
+ arsort($dimensions1);
+ arsort($dimensions2);
+
+ // Disregard the array keys.
+ $dimensions1 = array_values($dimensions1);
+ $dimensions2 = array_values($dimensions2);
+
+ // Return the inverse of the longest side.
+ return $dimensions1[0] < $dimensions2[0];
+}
+
+/**
+ * Sorts commerce box entities from smallest to largest.
+ */
+function commerce_box_boxes_by_volume($box1, $box2) {
+ $volume1 = commerce_box_get_entity_volume($box1, 'commerce_box');
+ $volume2 = commerce_box_get_entity_volume($box2, 'commerce_box');
+ return $volume1 > $volume2;
+}
+
+/**
+ * Defines the product reference field on shipments.
+ */
+function commerce_box_shipment_product_reference_field() {
+ $field_name = 'field_shipment_products';
+ drupal_alter('commerce_box_shipment_product_reference_field', $field_name);
+ return $field_name;
+}
+
+/**
+ * Defines the product reference field on shipments.
+ */
+function commerce_box_shipment_box_reference_field() {
+ $field_name = 'field_box';
+ drupal_alter('commerce_box_shipment_box_reference_field', $field_name);
+ return $field_name;
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment