Basic search API integration.
[sandbox/serialjaywalker/1195272.git] / modules / customer / commerce_pos_customer.module
1 <?php
2
3 /**
4 * @file
5 * Creates a POS customer type and defines a POS order action for customers.
6 */
7
8 /**
9 * Implements hook_commerce_customer_profile_type_info().
10 */
11 function commerce_pos_customer_commerce_customer_profile_type_info() {
12 return array(
13 'pos' => array(
14 'type' => 'pos',
15 'name' => t('POS profile'),
16 'description' => t('The profile used for POS orders.'),
17 'help' => '',
18 'addressfield' => FALSE,
19 ),
20 );
21 }
22
23 /**
24 * Implements hook_enable().
25 */
26 function commerce_pos_customer_enable() {
27
28 //Add the unique ID.
29 $field = field_info_field('commerce_pos_customer_number');
30 $instance = field_info_instance('commerce_customer_profile', 'commerce_pos_customer_number', 'pos');
31
32 if (empty($field)) {
33 $field = array(
34 'field_name' => 'commerce_pos_customer_number',
35 'type' => 'text',
36 'settings' => array(
37 'maxlength' => 13,
38 ),
39 );
40 $field = field_create_field($field);
41 }
42
43 if (empty($instance)) {
44 $instance = array(
45 'field_name' => 'commerce_pos_customer_number',
46 'entity_type' => 'commerce_customer_profile',
47 'bundle' => 'pos',
48 'required' => TRUE,
49 'default_value_function' => 'commerce_pos_customer_default_number',
50 'label' => t('Customer Number'),
51 'description' => t('A unique number to identify the customer.'),
52 );
53 $instance = field_create_instance($instance);
54 }
55
56 //Create the commerce_customer_pos field before the commerce_order_module
57 //can get to it. This allows us to override default settings.
58 $field_name = 'commerce_customer_pos';
59 $order_type = 'commerce_order';
60 commerce_activate_field($field_name);
61
62 $field = field_info_field($field_name);
63 $instance = field_info_instance('commerce_order', $field_name, $order_type);
64
65 if (empty($field)) {
66 $field = array(
67 'field_name' => $field_name,
68 'type' => 'commerce_customer_profile_reference',
69 'cardinality' => 1,
70 'entity_types' => array('commerce_order'),
71 'translatable' => FALSE,
72 'settings' => array(
73 'profile_type' => $customer_profile_type,
74 ),
75 );
76 $field = field_create_field($field);
77 }
78
79 if (empty($instance)) {
80 $instance = array(
81 'field_name' => $field_name,
82 'entity_type' => 'commerce_order',
83 'bundle' => $order_type,
84 'label' => $label,
85 'widget' => array(
86 'type' => 'commerce_pos_customer_value',
87 'weight' => -5,
88 ),
89 'display' => array(),
90 );
91
92 // Set the default display formatters for various view modes.
93 foreach (array('default', 'customer', 'administrator') as $view_mode) {
94 $instance['display'][$view_mode] = array(
95 'label' => 'above',
96 'type' => 'commerce_customer_profile_reference_display',
97 'weight' => -5,
98 );
99 }
100
101 field_create_instance($instance);
102
103 variable_set('commerce_customer_profile_' . $customer_profile_type . '_field', $field_name);
104 }
105 }
106
107 /**
108 * Default customer number function.
109 */
110 function commerce_pos_customer_default_number($entity_type, $entity, $field, $instance, $langcode) {
111 return array(
112 0 => array(
113 'value' => uniqid(),
114 ),
115 );
116 }
117
118 /**
119 * Implements hook_field_access().
120 */
121 function commerce_pos_customer_field_access($op, $field, $entity_type, $entity, $account) {
122 if ($field['field_name'] == 'commerce_pos_customer_number' && $op == 'edit') {
123 return user_access('edit customer numbers');
124 }
125 }
126
127 /**
128 * Implements hook_permission().
129 */
130 function commerce_pos_customer_permission() {
131 return array(
132 'edit customer numbers' => array(
133 'title' => t('Administer pos customer numbers'),
134 ),
135 );
136 }
137
138 /**
139 * Implements hook_commerce_pos_action_info().
140 */
141 function commerce_pos_customer_commerce_pos_action_info() {
142 return array(
143 'commerce_pos_customer' => array(
144 'action text' => 'ID',
145 'callbacks' => array(
146 'parse' => array('commerce_pos_customer_parse'),
147 'validate' => array('commerce_pos_order_require_modifiable_order','commerce_pos_customer_validate'),
148 'execute' => array('commerce_pos_customer_execute'),
149 'extract' => array('commerce_pos_customer_extract'),
150 'access' => array('commerce_pos_customer_access'),
151 ),
152 'weight' => 80,
153 'button' => array(
154 'title' => t('Customer'),
155 'section' => 'order',
156 'weight' => 0,
157 ),
158 ),
159 );
160 }
161
162 /**
163 * Access callback for commerce_pos_customer action.
164 */
165 function commerce_pos_customer_access($variables) {
166 //TODO: should we also check that we can load the customer profile?
167 $order = $variables['order'];
168 return commerce_order_access('update', $order);
169 }
170
171 /**
172 * Parse callback for commerce_pos_customer action.
173 */
174 function commerce_pos_customer_parse($input, $action_text = 'ID') {
175 return commerce_pos_string_ends_with($action_text, $input);
176 }
177
178 /**
179 * Extract callback for commerce_pos_customer action.
180 */
181 function commerce_pos_customer_extract(&$variables, $values) {
182 if (!empty($values['action_name']) || !empty($values['new_action_name'])) {
183 $customer_number = $variables['input'];
184 }
185 else {
186 $action_text = $variables['action']['action text'];
187 $customer_number = drupal_substr($variables['input'], 0, drupal_strlen($variables['input']) - drupal_strlen($action_text));
188 }
189 $variables['customer_number'] = $customer_number;
190 }
191
192 /**
193 * Validate callback for commerce_pos_customer order action
194 */
195 function commerce_pos_customer_validate(&$variables) {
196 if (empty($variables['order'])) {
197 return array(t('Please start an order before adding the customer.'));
198 }
199 $customer_number = $variables['customer_number'];
200 if (empty($customer_number)) {
201 $variables['profile_id'] = NULL;
202 return;
203 }
204 $profile_id = commerce_pos_customer_number_to_profile_id($customer_number);
205
206 $customer_profile = commerce_customer_profile_load($profile_id);
207 if ($customer_profile === FALSE) {
208 return array(t('Could not find that customer profile.'));
209 }
210 elseif ($customer_profile->type != 'pos') {
211 return array(t('Invalid customer profile type.'));
212 }
213 else {
214 $variables['customer_profile'] = $customer_profile;
215 }
216 }
217
218 /**
219 * Execute callback for commerce_pos_customer order action
220 */
221 function commerce_pos_customer_execute(&$variables) {
222 //Set the order's POS customer profile accordingly.
223 $profile_id = $variables['profile_id'];
224 $order = $variables['order'];
225 $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
226 $order_wrapper->commerce_customer_pos->set($variables['customer_profile']);
227 //Save twice so that prices are recalculated correctly.
228 rules_invoke_event('commerce_pos_customer_set_customer', $order_wrapper);
229 $order_wrapper->save();
230 $variables['order'] = $order_wrapper->value();
231 }
232
233 /**
234 * Returns the profile id corresponding to a given customer number.
235 */
236 function commerce_pos_customer_number_to_profile_id($customer_number) {
237 $query = new EntityFieldQuery();
238 $query->entityCondition('entity_type', 'commerce_customer_profile', '=')
239 ->entityCondition('bundle', 'pos', '=')
240 ->fieldCondition('commerce_pos_customer_number', 'value', $customer_number, '=');
241 $result = $query->execute();
242
243 $ids = array_keys($result['commerce_customer_profile']);
244 return reset($ids);
245 }
246
247 /**
248 * Implements hook_module_implements_alter().
249 */
250 function commerce_pos_customer_module_implements_alter(&$implementations, $hook) {
251 switch ($hook) {
252 case 'commerce_customer_profile_presave':
253 $group = $implementations['commerce_pos_customer'];
254 unset($implementations['commerce_pos_customer']);
255 $implementations['commerce_pos_customer'] = $group;
256 break;
257 case 'form_commerce_customer_customer_profile_form_alter':
258 $group = $implementations['commerce_pos_customer'];
259 unset($implementations['commerce_pos_customer']);
260 $implementations['commerce_pos_customer'] = $group;
261 break;
262 }
263 }
264
265 /**
266 * Implements hook_commerce_customer_profile_presave().
267 */
268 function commerce_pos_customer_commerce_customer_profile_presave($profile) {
269 if ($profile->type == 'pos') {
270 if (empty($profile->profile_id) && !empty($profile->original->profile_id)) {
271 $profile->profile_id = $profile->original->profile_id;
272 $profile->revision_id = $profile->original->revision_id;
273 }
274 }
275 }
276
277 /**
278 * Implements hook_commerce_customer_profile_form_alter().
279 */
280 function commerce_pos_customer_form_commerce_customer_customer_profile_form_alter(&$form, &$form_state) {
281 if (isset($form['clone_message']) && $form_state['customer_profile']->type == 'pos') {
282 unset($form['clone_message']);
283 }
284 }
285
286 /**
287 * Implements hook_field_widget_info().
288 */
289 function commerce_pos_customer_field_widget_info() {
290 $widgets = array();
291
292 // Define the creation / reference widget for line items.
293 $widgets['commerce_pos_customer_value'] = array(
294 'label' => t('Hidden customer profile'),
295 'description' => t('Hide the customer profile; do not allow it to be edited.'),
296 'field types' => array('commerce_customer_profile_reference'),
297 'settings' => array(),
298 'behaviors' => array(
299 'multiple values' => FIELD_BEHAVIOR_CUSTOM,
300 'default value' => FIELD_BEHAVIOR_NONE,
301 ),
302 );
303
304 return $widgets;
305 }
306
307 /**
308 * Implements hook_field_widget_form().
309 */
310 function commerce_pos_customer_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
311 if ($instance['widget']['type'] == 'commerce_pos_customer_value') {
312 $element += array(
313 '#type' => 'value',
314 '#value' => $items,
315 );
316 return $element;
317 }
318 }