5 * Allows you to define any number of Kiala shipping services
9 * Implements hook_menu().
11 function commerce_kiala_ps_menu() {
14 $items['admin/commerce/orders/%commerce_order/kiala-packship-desktop-export'] = array(
15 'title' => 'P&S Desktop Export',
16 'page callback' => 'commerce_kiala_ps_desktop_order_export_page',
17 'page arguments' => array(3),
18 'access callback' => 'commerce_kiala_ps_desktop_order_export_page_access',
19 'access arguments' => array(3),
20 'type' => MENU_LOCAL_ACTION
,
22 'context' => MENU_CONTEXT_PAGE
| MENU_CONTEXT_INLINE
,
25 $items['admin/commerce/orders/%commerce_order/kiala-packship-ws'] = array(
26 'title' => 'Pack and Ship',
27 'page callback' => 'commerce_kiala_ps_ws_order_page',
28 'page arguments' => array(3),
29 'access callback' => 'commerce_kiala_ps_ws_order_page_access',
30 'access arguments' => array(3),
31 'type' => MENU_LOCAL_TASK
,
33 'context' => MENU_CONTEXT_PAGE
| MENU_CONTEXT_INLINE
,
34 'file' => 'includes/commerce_kiala_ps.admin.inc',
36 $items['admin/commerce/orders/%commerce_order/kiala-packship-ws/dashboard'] = array(
37 'title' => 'Dashboard',
38 'type' => MENU_DEFAULT_LOCAL_TASK
,
39 'context' => MENU_CONTEXT_PAGE
| MENU_CONTEXT_INLINE
,
43 $items['admin/commerce/orders/%commerce_order/kiala-packship-ws/desktop-export'] = $items['admin/commerce/orders/%commerce_order/kiala-packship-desktop-export'];
45 $items['admin/commerce/orders/%commerce_order/kiala-packship-ws/logs/%commerce_kiala_ps_ws_log'] = array(
46 'title callback' => 'commerce_kiala_ps_ws_log_title',
47 'title arguments' => array(6),
48 'page callback' => 'commerce_kiala_ps_ws_log_view',
49 'page arguments' => array(6, 'administrator'),
50 'access callback' => 'commerce_kiala_ps_ws_log_access',
51 'access arguments' => array('view', 6),
53 $items['admin/commerce/orders/%commerce_order/kiala-packship-ws/logs/%commerce_kiala_ps_ws_log/view'] = array(
55 'type' => MENU_DEFAULT_LOCAL_TASK
,
56 'context' => MENU_CONTEXT_PAGE
| MENU_CONTEXT_INLINE
,
59 $items['admin/commerce/orders/%commerce_order/kiala-packship-ws/logs/%commerce_kiala_ps_ws_log/delete'] = array(
61 'page callback' => 'commerce_kiala_ps_ws_log_delete_form_wrapper',
62 'page arguments' => array(3, 6),
63 'access callback' => 'commerce_kiala_ps_ws_log_access',
64 'access arguments' => array('delete', 6),
65 'type' => MENU_LOCAL_TASK
,
66 'context' => MENU_CONTEXT_INLINE
,
68 'file' => 'includes/commerce_kiala_ps.admin.inc',
75 * Implements hook_views_api().
77 function commerce_kiala_ps_views_api() {
80 'path' => drupal_get_path('module', 'commerce_kiala_ps') .
'/includes/views',
85 * Access callback for packship export page
87 function commerce_kiala_ps_desktop_order_export_page_access($order) {
88 if (!user_access('administer kiala services')) {
92 return commerce_kiala_ps_desktop_order_export_access($order, TRUE
);
96 * Returns TRUE if order can use Kiala P&S Desktop
98 function commerce_kiala_ps_desktop_order_export_access($order, $exclude_warnings = FALSE
) {
99 $settings = commerce_kiala_settings(array(
100 'include_passwords' => TRUE
,
103 // DENY if not basic pack ship order access
104 if (!commerce_kiala_ps_order_access($order, $exclude_warnings)) {
108 // DENY if any warnings exist
109 if (empty($exclude_warnings)) {
110 $warnings = commerce_kiala_ps_desktop_order_warnings($order);
111 if (!empty($warnings)) {
120 * Returns an array of warnings for Pack & Ship WS for the given order
122 function commerce_kiala_ps_desktop_order_warnings($order) {
124 /** @todo: any specifc to the desktop ??? ****/
129 * Menu access callback for P&S web service page
131 function commerce_kiala_ps_ws_order_page_access($order) {
132 if (!user_access('administer kiala packship ws')) {
136 // return order access without weight check
137 return commerce_kiala_ps_ws_order_access($order, TRUE
);
141 * Returns TRUE if order can use Kiala P&S Web Service
143 function commerce_kiala_ps_ws_order_access($order, $exclude_warnings = FALSE
) {
144 $settings = commerce_kiala_settings(array(
145 'include_passwords' => TRUE
,
148 // DENY if packship type is not desktop
149 if (!isset($settings['packship_type']) || $settings['packship_type'] != 'ws') {
153 // DENY if not enough information provided
154 if (empty($settings['packship_ws_sender_id']) || empty($settings['packship_ws_password']) ||
155 empty($settings['packship_ws_url'])) {
159 // DENY if not basic pack ship order access
160 if (!commerce_kiala_ps_order_access($order, $exclude_warnings)) {
164 // DENY if any warnings exist
165 if (empty($exclude_warnings)) {
166 $warnings = commerce_kiala_ps_ws_order_warnings($order);
167 if (!empty($warnings)) {
176 * Returns an array of warnings for Pack & Ship WS for the given order
178 function commerce_kiala_ps_ws_order_warnings($order) {
180 $settings = commerce_kiala_settings();
182 // check against max weight
183 if (!empty($settings['packship_ws_max_weight'])) {
184 $weight = commerce_physical_order_weight($order, 'kg');
185 if (empty($weight['weight']) || $weight['weight'] > $settings['packship_ws_max_weight']) {
186 $warnings['max_weight'] = t('The weight of this order is over the maximum allowed @max_weight kg, current weight is @weight kg.', array(
187 '@weight' => sprintf("%01.3f", round($weight['weight'], 3)),
188 '@max_weight' => sprintf("%01.3f", round($settings['packship_ws_max_weight'], 3)),
197 * Returns TRUE if order can use Kiala P&S
199 function commerce_kiala_ps_order_access($order, $exclude_warnings = FALSE
) {
200 if (empty($order->order_id
)) {
204 $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
206 // DENY if no kiala point associated with the order
207 $point_id = $order_wrapper->kiala_point_id
->value();
208 if (empty($point_id)) {
212 $settings = commerce_kiala_settings();
214 // DENY if no sender country
215 if (empty($settings['country'])) {
219 // DENY if order has not completed checkout
220 if (!commerce_kiala_order_completed_date($order)) {
224 // DENY if there is no order weight
225 $weight = commerce_physical_order_weight($order, 'kg');
226 if (empty($weight['weight'])) {
230 // DENY if no recipient address
231 $recipient_address = commerce_kiala_order_recipient_addressfield($order);
232 if (empty($recipient_address) || empty($recipient_address['country']) ||
233 empty($recipient_address['postal_code']) || empty($recipient_address['last_name'])) {
237 // DENY if any warnings exist
238 if (empty($exclude_warnings)) {
239 $warnings = commerce_kiala_ps_order_warnings($order);
240 if (!empty($warnings)) {
249 * Returns an array of warnings for Pack & Ship for the given order
251 function commerce_kiala_ps_order_warnings($order) {
253 $recipient_address = commerce_kiala_order_recipient_addressfield($order);
255 // WARN if language mis-match
256 $language = language_default()->language
;
257 if (!commerce_kiala_ps_language_combinations_match($language, $recipient_address['country'])) {
258 $warnings['language'] = t('Language is not supported in the recipient\'s country.');
261 /** @todo: check from and to country combinations *********************/
264 $warnings['language'] = t('Cannot ship to the recipient\'s country.');
272 * Render callback for packship export page
274 function commerce_kiala_ps_desktop_order_export_page($order) {
275 $wrapper = entity_metadata_wrapper('commerce_order', $order);
276 $export = $wrapper->kiala_packship_desktop_export
->value();
278 if (is_string($export)) {
279 // Deliver the raw export text
280 drupal_add_http_header('Content-disposition', 'attachment; filename=order-' .
$order->order_id .
'.kiala');
284 foreach ($export['errors'] as
$error_msg) {
285 drupal_set_message($error_msg, 'error');
288 return t('Export failed.');
293 * Implements hook_form_FORM_ID_alter()
295 function commerce_kiala_ps_form_commerce_kiala_settings_form_alter(&$form, &$form_state, $form_id) {
296 $kiala_contact_mail = 'e-commerce@kiala.com';
297 $settings_info = commerce_kiala_settings_info();
298 $default_values = commerce_kiala_settings(array(
299 'include_passwords' => FALSE
,
302 $password_hashes = commerce_kiala_settings(array(
303 'include_passwords' => TRUE
,
304 'conditions' => array('password' => TRUE
),
308 $form['commerce_kiala_packship'] = array(
309 '#type' => 'fieldset',
310 '#title' => t('Pack and Ship'),
311 '#collapsible' => TRUE
,
312 '#group' => 'groups',
314 '#description' => t('In order to use Pack and Ship, you must have an account with Kiala. You can contact Kiala at !mail', array('!mail' => $kiala_contact_mail)),
316 $form_packship = &$form['commerce_kiala_packship'];
318 $form_packship['packship_type'] = array(
320 '#title' => t('Pack and Ship type'),
321 '#default_value' => isset($default_values['packship_type']) ?
$default_values['packship_type'] : '',
324 'desktop' => t('Desktop'),
325 'ws' => t('Web Service'),
327 '#description' => t('In order to use Desktop or Web, please contact Kiala at !mail', array('!mail' => $kiala_contact_mail)),
330 $packship_active_states = array(
332 ':input[name*="packship_type"]' => array('value' => 'ws')
335 ':input[name*="packship_type"]' => array('value' => 'desktop')
340 $form_packship['packship_ws'] = array(
341 '#type' => 'fieldset',
342 '#title' => t('Web Service Settings'),
344 'visible' => $packship_active_states['ws'],
347 $form_packship['packship_ws']['packship_ws_sender_id'] = array(
348 '#type' => 'textfield',
349 '#title' => t('Sender ID'),
350 '#default_value' => isset($default_values['packship_ws_sender_id']) ?
$default_values['packship_ws_sender_id'] : '',
351 '#description' => t('Maximum 32 characters.'),
354 'required' => $packship_active_states['ws'],
357 $form_packship['packship_ws']['packship_ws_password'] = array(
358 '#type' => 'password',
359 '#title' => t('Password'),
360 '#description' => t('Please leave blank if you do not want to update your password at this time.'),
362 if (empty($password_hashes['packship_ws_password'])) {
363 $form_packship['packship_ws']['packship_ws_password']['#states'] = array(
364 'required' => $packship_active_states['ws'],
367 $form_packship['packship_ws']['packship_ws_url'] = array(
368 '#type' => 'textfield',
369 '#title' => t('API URL'),
370 '#default_value' => isset($default_values['packship_ws_url']) ?
$default_values['packship_ws_url'] : '',
371 '#description' => t('The SOAP API url. Example: @url', array('@url' => $settings_info['packship_ws_url']['default'])),
372 //'#disabled' => TRUE,
374 'required' => $packship_active_states['ws'],
377 $form_packship['packship_ws']['packship_ws_max_weight'] = array(
378 '#type' => 'textfield',
379 '#title' => t('Max Weight'),
380 '#description' => t('If the parcel exceeds the maximum weight allowed by Kiala,
381 then Kiala will not be able to handle your shipments. To know the exact restrictions, please contact Kiala.<br />
382 Leave blank to ignore the max weight restriction.'),
383 '#field_suffix' => t('kg'),
384 '#default_value' => isset($default_values['packship_ws_max_weight']) ?
$default_values['packship_ws_max_weight'] : '',
388 if (!empty($default_values['packship_ws_params'])) {
389 $form_packship['packship_ws']['packship_ws_params'] = commerce_kiala_admin_settings_params_element($default_values['packship_ws_params']);
393 $form['#validate'][] = 'commerce_kiala_ps_settings_form_validate';
397 * Validate callback for commerce_kiala_settings_form()
399 function commerce_kiala_ps_settings_form_validate($form, &$form_state) {
400 $values = &$form_state['values'];
402 // get the stored passwords untouched from the database
403 $current_password_hashes = commerce_kiala_settings(array(
404 'include_passwords' => TRUE
,
406 'conditions' => array('password' => TRUE
),
409 // Pack & Ship conditional validation
410 if (isset($values['packship_type']) && $values['packship_type'] == 'ws') {
411 if ($values['packship_ws_max_weight'] != '') {
412 $max_weight = $values['packship_ws_max_weight'];
413 if (!is_numeric($max_weight) || $max_weight < 0) {
414 form_set_error('packship_ws_max_weight', t('Max weight must be a positive number.'));
418 if (empty($values['packship_ws_sender_id'])) {
419 form_set_error('packship_ws_sender_id', t('You must enter a Sender ID for the Pack & Ship Web Service.'));
423 if (empty($values['packship_ws_password'])) {
424 if (empty($current_password_hashes['packship_ws_password'])) {
425 form_set_error('packship_ws_password', t('You must enter a password for the Pack & Ship Web Service.'));
433 * Implements hook_theme().
435 function commerce_kiala_ps_theme() {
437 'commerce_kiala_ps_ws_log' => array(
438 'variables' => array('log' => NULL
, 'order' => NULL
, 'view_mode' => NULL
),
444 * Implements hook_permission().
446 function commerce_kiala_ps_permission() {
448 'administer kiala packship ws' => array(
449 'title' => t('Administer Kiala Pack & Ship web service'),
450 'description' => t('Allows users to perform any web service action for any order and view logs.'),
451 'restrict access' => TRUE
,
453 'view kiala packship ws logs' => array(
454 'title' => t('View Kiala Pack & Ship web service logs'),
455 'description' => t('Allows users to view the logs made to an order.'),
456 'restrict access' => TRUE
,
458 'create kiala packship ws logs' => array(
459 'title' => t('Create Kiala Pack & Ship web service logs'),
460 'description' => t('Allows users to create the logs made to an order.'),
461 'restrict access' => TRUE
,
463 'delete kiala packship ws logs' => array(
464 'title' => t('Delete Kiala Pack & Ship web service logs'),
465 'description' => t('Allows users to delete logs on orders they can access.'),
466 'restrict access' => TRUE
,
472 * Implements hook_entity_info().
474 function commerce_kiala_ps_entity_info() {
475 $return['commerce_kiala_ps_ws_log'] = array(
476 'module' => 'commerce_kiala_ps',
477 'label' => t('Commerce Kiala PS web service log'),
478 'base table' => 'commerce_kiala_ps_ws_log',
479 'entity class' => 'CommerceKialaPSWSLogEntity',
480 'controller class' => 'CommerceKialaPSWSLogEntityController',
481 'metadata controller class' => 'CommerceKialaPSWSLogMetadataController',
482 'views controller class' => FALSE
,
483 'rules controller class' => 'EntityDefaultRulesController',
484 'features controller class' => 'EntityDefaultFeaturesController',
485 'fieldable' => FALSE
,
486 'exportable' => FALSE
,
487 'entity keys' => array(
489 'bundle' => 'method',
492 'bundle keys' => array(
493 'bundle' => 'method',
496 'createOrder' => array(
497 'label' => t('createOrder'),
500 'view modes' => array(
501 'administrator' => array(
502 'label' => t('Administrator'),
503 'custom settings' => FALSE
,
506 'access callback' => 'commerce_kiala_ps_ws_log_access',
507 'load hook' => 'commerce_kiala_ps_ws_log_load',
508 'permission labels' => array(
509 'singular' => t('kiala packship ws log'),
510 'plural' => t('kiala packship ws logs'),
518 * Returns a list of web service log statuses
520 function commerce_kiala_ps_ws_log_status_options_list() {
522 'success' => t('Success'),
523 'error' => t('Error'),
530 * Load a single web service log entry
532 function commerce_kiala_ps_ws_log_load($id) {
533 return entity_load_single('commerce_kiala_ps_ws_log', $id) ;
537 * Menu item title callback: returns the web servicew log ID for its pages.
540 * The log object as loaded via the URL wildcard.
542 * A page title of the format "Web service log ##".
544 function commerce_kiala_ps_ws_log_title($log) {
545 return t('Web service log @log_id', array('@log_id' => $log->log_id
));
549 * Generate an array for rendering the given log entity.
552 * An array of entities to render.
554 * A view mode as used by this entity type, e.g. 'full', 'teaser'...
556 * (optional) A language code to use for rendering. Defaults to the global
557 * content language of the current request.
559 * (optional) If set will control if the entity is rendered: if TRUE
560 * the entity will be rendered without its title, so that it can be embeded
561 * in another context. If FALSE the entity will be displayed with its title
562 * in a mode suitable for lists.
563 * If unset, the page mode will be enabled if the current path is the URI
564 * of the entity, as returned by entity_uri().
565 * This parameter is only supported for entities which controller is a
566 * EntityAPIControllerInterface.
568 * The renderable array, keyed by the entity type and by entity identifiers,
569 * for which the entity name is used if existing - see entity_id(). If there
570 * is no information on how to view an entity, FALSE is returned.
572 function commerce_kiala_ps_ws_log_view($entity, $view_mode = 'administrator', $langcode = NULL
, $page = NULL
) {
573 $entities = array($entity->log_id
=> $entity);
574 return entity_view('commerce_kiala_ps_ws_log', $entities, $view_mode, $langcode, $page);
578 * Determines access for a variety of operations on web service logs.
581 * The operation being performed, one of view, update, create, or delete.
583 * The web service log to check.
585 * The user account attempting the operation; defaults to the current user.
588 * TRUE or FALSE indicating access for the operation.
590 function commerce_kiala_ps_ws_log_access($op, $log, $account = NULL
) {
591 if (isset($log->order_id
)) {
592 $order = commerce_order_load($log->order_id
);
601 return commerce_kiala_ps_ws_log_order_access($op, $order, $account);
605 * Determines access for a variety of operations for web service logs on a given order.
608 * The operation being performed, one of view, update, create, or delete.
610 * The order to check against (optional if $op == 'create').
612 * The user account attempting the operation; defaults to the current user.
615 * TRUE or FALSE indicating access for the operation.
617 * @see commerce_payment_transaction_order_access()
619 function commerce_kiala_ps_ws_log_order_access($op, $order, $account = NULL
) {
622 if (empty($account)) {
623 $account = clone($user);
626 // Grant administrators access to do anything.
627 if (user_access('administer kiala packship ws', $account)) {
632 // Creating new logs.
634 if (user_access('create kiala packship ws logs', $account)) {
635 // We currently allow any user to create any log,
636 // regardless of the order, because entity_access() doesn't give us a
637 // way to discriminate on the order.
638 // @todo: find a way to prevent creating a log if the
639 // user doesn't have access to the order.
640 if (!isset($order) || commerce_order_access('update', $order, $account)) {
646 // Viewing payment transactions.
648 if (user_access('view kiala packship ws logs', $account)) {
649 if (commerce_order_access('view', $order, $account)) {
656 if (user_access('update kiala packship ws logs', $account)) {
657 if (commerce_order_access('view', $order, $account)) {
664 if (user_access('delete kiala packship ws logs', $account)) {
665 if (commerce_order_access('update', $order, $account)) {
676 * Theme for commerce_kiala_ps_ws_log
678 function theme_commerce_kiala_ps_ws_log($vars) {
679 if (empty($vars['log']) || empty($vars['log']->log_id
)) {
684 return drupal_render(commerce_kiala_ps_ws_log_view($log, 'administrator', NULL
, TRUE
));
688 * Order metadata callback
690 function commerce_kiala_ps_order_property_get($entity, array $options, $name) {
692 case
'kiala_packship_desktop_export_access':
693 return commerce_kiala_ps_desktop_order_export_access($entity);
695 case
'kiala_packship_ws_access':
696 return commerce_kiala_ps_ws_order_access($entity);
698 case
'kiala_packship_desktop_export':
699 // This will either return a string or an errors array.
700 return commerce_kiala_ps_build_desktop_export(array($entity));
705 * Build the export string for a list of orders
707 * @param type $orders
710 function commerce_kiala_ps_build_desktop_export($orders) {
711 $settings = commerce_kiala_settings();
712 $countries_enabled = $settings['shipping_countries_enabled'];
714 // In the export values are keyed only by position, so this mapping makes it
715 // possible to keep track of things by name.
735 'customerStreetnumber',
736 'customerExtraAddressLine',
747 'positiveNotificationRequested',
754 foreach ($orders as
$order) {
755 $wrapper = entity_metadata_wrapper('commerce_order', $order);
758 $export['partnerId'] = $settings['dspid'];
761 $export['parcelNumber'] = $settings['dspid'] .
'_' .
$order->order_id
;
764 $export['orderNumber'] = $order->order_id
;
767 $timestamp = commerce_kiala_order_completed_date($order);
770 $errors[] = t('The customer has not completed checkout for this order.');
773 $export['orderDate'] = date('Ymd', $timestamp);
776 // CODAmount. Set to zero because commerce customer will just be paying for
777 // everything online.
778 $export['CODAmount'] = '0.00';
780 // commercialValue (order total amount)
781 $amount = commerce_currency_amount_to_decimal($wrapper->commerce_order_total
->amount
->value(), commerce_default_currency());
782 $export['commercialValue'] = number_format((float)$amount, 2, '.', '');
785 $weight = commerce_physical_order_weight($order, 'kg');
787 if (empty($weight['weight'])) {
788 $errors[] = t('A product in this order does not have a weight.');
790 $export['parcelWeight'] = number_format((float)$weight['weight'], 3, '.', '');
792 //parcelVolume (liters i.e. 1000 cc)
793 $volume = commerce_physical_order_volume($order, 'cm');
794 $liters = $volume['volume'] / 1000;
795 $export['parcelVolume'] = number_format((float)$liters, 3, '.', '');
798 if (!empty($order->commerce_customer_shipping
)) {
799 $export['customerId'] = $wrapper->commerce_customer_shipping
->profile_id
->value();
801 $address = $wrapper->commerce_customer_shipping
->commerce_customer_address
->value();
802 $export['customerName'] = commerce_kiala_ps_parse_name($address['name_line']);
803 $export['customerStreet'] = $address['thoroughfare'];
804 $export['customerExtraAddressLine'] = $address['premise'];
805 $export['customerZip'] = $address['postal_code'];
806 $export['customerCity'] = $address['locality'];
808 // customerLanguage (DSP language)
809 if (commerce_kiala_ps_language_combinations_match(language_default()->language
, $address['country'])) {
810 $export['customerLanguage'] = language_default()->language
;
813 $errors[] = t('Language is not supported.');
817 $errors[] = t('No shipping profile found.');
821 $export['customerEmail1'] = $order->mail;
823 // positiveNotificationRequested @TODO opt-in field
824 $export['positiveNotificationRequested'] = 'yes';
827 $export['kialaPoint'] = $wrapper->kiala_point_id
->value();
829 // Allow modules to add to the export
830 drupal_alter('commerce_kiala_ps_desktop_export', $export, $order);
832 // Fill in missing values and sort by mapping order
833 foreach ($map as
$key) {
834 if (isset($export[$key])) {
835 // Check for illegal characters
836 if (strstr($export[$key], '|')) {
837 $errors[] = t('Pipe character found in data, please remove and reinitiate export');
840 $output[] = $export[$key];
847 if (isset($errors)) {
848 return array('errors' => $errors);
853 return implode('|', $output);
857 * Kiala P&S Web Service request
863 * A P&S Web Service response object
865 function commerce_kiala_ps_ws_ping_create_order($order) {
866 $method = 'createOrder';
867 $handler = new
CommerceKialaPSWS($order);
868 $response = $handler->sendRequest($method);
871 'order_id' => $order->order_id
,
873 'response' => $response,
876 if (isset($response->trackingNumber
)) {
877 $log_values['tracking_number'] = $response->trackingNumber
;
880 entity_create('commerce_kiala_ps_ws_log', $log_values)->save();
886 * Return an address name line string in "lastname firstname" format.
891 function commerce_kiala_ps_parse_name($name) {
892 // For common 2 part space separated names
893 $parts = explode(' ', $name);
895 if (count($parts) == 2) {
896 return $parts[1] .
' ' .
$parts[0];
899 // Otherwise just leave as is.
904 * Return a list of support packship language-country combinations
907 * @ref http://packandship.kiala.com/desktop/doc/technical/description-of-import-fields.html
909 function commerce_kiala_ps_language_combinations() {
911 'fr' => array('BE', 'FR'),
912 'nl' => array('NL', 'BE'),
921 * Determine whether a language and a country may be exported together.
923 * @param type $lang_code
924 * @param type $country_code
927 function commerce_kiala_ps_language_combinations_match($lang_code, $country_code) {
928 $combinations = commerce_kiala_ps_language_combinations();
930 if (isset($combinations[$lang_code]) && in_array($country_code, $combinations[$lang_code])) {
936 * Fetch the date when the order became checkout complete
941 function commerce_kiala_order_completed_date($order) {
943 db_select('commerce_order_revision', 'c')
944 ->fields('c', array('revision_timestamp'))
945 ->condition('c.status', 'checkout_complete')
946 ->condition('c.order_id', $order->order_id
)
947 ->orderBy('c.revision_timestamp')
952 if (!empty($results)) {
953 $revision = reset($results);
954 return $revision->revision_timestamp
;