Projet

Général

Profil

Paste
Télécharger (17,2 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / commerce / modules / tax / includes / commerce_tax_ui.admin.inc @ b858700c

1
<?php
2

    
3
/**
4
 * @file
5
 * Administrative callbacks and form builder functions for the Tax UI module.
6
 */
7

    
8

    
9
/**
10
 * Displays an overview of Tax UI defined tax rates.
11
 */
12
function commerce_tax_ui_overview($type) {
13
  drupal_add_css(drupal_get_path('module', 'commerce_tax') . '/theme/commerce_tax.admin.css');
14

    
15
  // Load the items that will be represented in the overview table.
16
  if ($type == 'rates') {
17
    $items = commerce_tax_rates();
18
  }
19
  else {
20
    $items = commerce_tax_types();
21
  }
22

    
23
  $header = array(
24
    t('Name'),
25
    t('Operations'),
26
  );
27

    
28
  $rows = array();
29

    
30
  // Loop through all of the items to include in the overview.
31
  foreach ($items as $name => $item) {
32
    if ($item['admin_list']) {
33
      // Build the operation links for the current item.
34
      $links = menu_contextual_links('commerce-tax-' . $type, 'admin/commerce/config/taxes/' . $type, array(strtr($name, '_', '-')));
35

    
36
      // Add the item's row to the table's rows array.
37
      $rows[] = array(
38
        ($type == 'rates') ? theme('tax_rate_admin_overview', array('tax_rate' => $item)) : theme('tax_type_admin_overview', array('tax_type' => $item)),
39
        theme('links', array('links' => $links, 'attributes' => array('class' => 'links inline operations'))),
40
      );
41
    }
42
  }
43

    
44
  // If no items are defined...
45
  if (empty($rows)) {
46
    // Add a standard empty row with a link to add a new item.
47
    if ($type == 'rates') {
48
      $empty_text = t('There are no tax rates yet. <a href="@link">Add a tax rate</a>.', array('@link' => url('admin/commerce/config/taxes/rates/add')));
49
    }
50
    else {
51
      $empty_text = t('There are no tax types yet. <a href="@link">Add a tax type</a>.', array('@link' => url('admin/commerce/config/taxes/types/add')));
52
    }
53

    
54
    $rows[] = array(
55
      array(
56
        'data' => $empty_text,
57
        'colspan' => 2,
58
      )
59
    );
60
  }
61

    
62
  return theme('table', array('header' => $header, 'rows' => $rows));
63
}
64

    
65
/**
66
 * Builds an overview of a tax rate for display to an administrator.
67
 *
68
 * @param $variables
69
 *   An array of variables used to generate the display; by default includes the
70
 *     tax rate key with a value of the tax rate array.
71
 *
72
 * @ingroup themeable
73
 */
74
function theme_tax_rate_admin_overview($variables) {
75
  $tax_rate = $variables['tax_rate'];
76

    
77
  // Build the description as an array so we can skip the actual tax rate
78
  // description if it isn't set and just include the rate.
79
  $description = array();
80

    
81
  if (!empty($tax_rate['description'])) {
82
    $description[] = filter_xss_admin($tax_rate['description']);
83
  }
84

    
85
  $description[] = t('Rate: @rate', array('@rate' => $tax_rate['rate']), array('context' => 'tax rate'));
86

    
87
  // Build the actual output.
88
  $output = check_plain($tax_rate['title']);
89
  $output .= ' <small>' . t('(Machine name: @type)', array('@type' => $tax_rate['name'])) . '</small>';
90
  $output .= '<div class="description">' . implode('<br />', $description) . '</div>';
91

    
92
  return $output;
93
}
94

    
95
/**
96
 * Builds an overview of a tax type for display to an administrator.
97
 *
98
 * @param $variables
99
 *   An array of variables used to generate the display; by default includes the
100
 *     tax type key with a value of the tax type array.
101
 *
102
 * @ingroup themeable
103
 */
104
function theme_tax_type_admin_overview($variables) {
105
  $tax_type = $variables['tax_type'];
106

    
107
  $output = check_plain($tax_type['title']);
108
  $output .= ' <small>' . t('(Machine name: @type)', array('@type' => $tax_type['name'])) . '</small>';
109
  $output .= '<div class="description">' . filter_xss_admin($tax_type['description']) . '</div>';
110

    
111
  return $output;
112
}
113

    
114
/**
115
 * Form callback wrapper: ensure tax types exist before going to the add form.
116
 */
117
function commerce_tax_ui_tax_rate_add_form_wrapper($tax_rate) {
118
  if (count(commerce_tax_type_titles()) == 0) {
119
    drupal_set_message(t('You must define at least one tax type before you can start adding tax rates.'), 'error');
120
    drupal_goto('admin/commerce/config/taxes/types');
121
  }
122

    
123
  return drupal_get_form('commerce_tax_ui_tax_rate_form', $tax_rate);
124
}
125

    
126
/**
127
 * Form callback: create or edit a tax rate.
128
 *
129
 * @param $tax_rate
130
 *   The tax rate array to edit or for a create form an empty tax rate
131
 *     array with properties instantiated but not populated.
132
 */
133
function commerce_tax_ui_tax_rate_form($form, &$form_state, $tax_rate) {
134
  // Store the initial tax rate in the form state.
135
  $form_state['tax_rate'] = $tax_rate;
136

    
137
  $form['tax_rate'] = array(
138
    '#tree' => TRUE,
139
  );
140

    
141
  $form['tax_rate']['title'] = array(
142
    '#type' => 'textfield',
143
    '#title' => t('Title'),
144
    '#default_value' => $tax_rate['title'],
145
    '#description' => t('The administrative title of this tax rate. It is recommended that this title begin with a capital letter and contain only letters, numbers, and spaces.'),
146
    '#required' => TRUE,
147
    '#size' => 32,
148
    '#field_suffix' => ' <small id="edit-tax-rate-title-suffix">' . t('Machine name: @name', array('@name' => $tax_rate['name'])) . '</small>',
149
  );
150

    
151
  if (empty($tax_rate['name'])) {
152
    $form['tax_rate']['name'] = array(
153
      '#type' => 'machine_name',
154
      '#title' => t('Machine name'),
155
      '#default_value' => $tax_rate['name'],
156
      '#maxlength' => 46,
157
      '#required' => TRUE,
158
      '#machine_name' => array(
159
        'exists' => 'commerce_tax_rate_load',
160
        'source' => array('tax_rate', 'title'),
161
      ),
162
      '#description' => t('The machine-name of this tax rate. This name must contain only lowercase letters, numbers, and underscores. It must be unique.'),
163
    );
164
  }
165

    
166
  $form['tax_rate']['display_title'] = array(
167
    '#type' => 'textfield',
168
    '#title' => t('Display title'),
169
    '#default_value' => $tax_rate['display_title'],
170
    '#description' => t('The front end display title of this tax rate shown to customers. Leave blank to default to the <em>Title</em> from above.'),
171
    '#size' => 32,
172
  );
173

    
174
  $form['tax_rate']['description'] = array(
175
    '#type' => 'textarea',
176
    '#title' => t('Description'),
177
    '#description' => t('Describe this tax rate if necessary. The text will be displayed in the tax rate overview table.'),
178
    '#default_value' => $tax_rate['description'],
179
    '#rows' => 3,
180
  );
181

    
182
  $form['tax_rate']['rate'] = array(
183
    '#type' => 'textfield',
184
    '#title' => t('Rate', array(), array('context' => 'tax rate')),
185
    '#description' => t('The percentage used to calculate this tax expressed as a decimal, e.g. .06 for a rate of 6%.'),
186
    '#default_value' => $tax_rate['rate'],
187
    '#size' => 16,
188
    '#required' => TRUE,
189
  );
190

    
191
  $form['tax_rate']['type'] = array(
192
    '#type' => 'select',
193
    '#title' => t('Type'),
194
    '#description' => t('The tax type for this rate.'),
195
    '#options' => commerce_tax_type_titles(),
196
    '#default_value' => $tax_rate['type'],
197
    '#required' => TRUE,
198
  );
199

    
200
  $form['actions'] = array(
201
    '#type' => 'actions',
202
    '#weight' => 40,
203
  );
204

    
205
  $form['actions']['submit'] = array(
206
    '#type' => 'submit',
207
    '#value' => t('Save tax rate'),
208
  );
209

    
210
  if (!empty($form_state['tax_rate']['name'])) {
211
    $form['actions']['delete'] = array(
212
      '#type' => 'submit',
213
      '#value' => t('Delete tax rate'),
214
      '#suffix' => l(t('Cancel'), 'admin/commerce/config/taxes'),
215
      '#submit' => array('commerce_tax_ui_tax_rate_form_delete_submit'),
216
      '#weight' => 45,
217
    );
218
  }
219
  else {
220
    $form['actions']['submit']['#suffix'] = l(t('Cancel'), 'admin/commerce/config/taxes');
221
  }
222

    
223
  return $form;
224
}
225

    
226
/**
227
 * Validation callback for commerce_tax_ui_tax_rate_form().
228
 */
229
function commerce_tax_ui_tax_rate_form_validate($form, &$form_state) {
230
  $tax_rate = $form_state['tax_rate'];
231

    
232
  // If saving a new tax rate, ensure it has a unique machine name.
233
  if (empty($tax_rate['name'])) {
234
    if (commerce_tax_rate_load($form_state['values']['tax_rate']['name']) != FALSE) {
235
      form_set_error('tax_rate][name', t('The machine-name specified is already in use.'));
236
    }
237
  }
238

    
239
  // Validate the data type of the tax rate.
240
  if (!is_numeric($form_state['values']['tax_rate']['rate'])) {
241
    form_set_error('tax_rate][rate', t('You must specify a numeric rate value.', array(), array('context' => 'tax rate')));
242
  }
243
}
244

    
245
/**
246
 * Form submit handler: save a tax rate.
247
 */
248
function commerce_tax_ui_tax_rate_form_submit($form, &$form_state) {
249
  $tax_rate = $form_state['tax_rate'];
250
  $updated = !empty($tax_rate['name']);
251

    
252
  foreach ($form_state['values']['tax_rate'] as $key => $value) {
253
    $tax_rate[$key] = $value;
254
  }
255

    
256
  // Default the display title to the title if empty.
257
  if (empty($tax_rate['display_title'])) {
258
    $tax_rate['display_title'] = $tax_rate['title'];
259
  }
260

    
261
  // Write the tax rate to the database.
262
  $tax_rate['is_new'] = !$updated;
263
  commerce_tax_ui_tax_rate_save($tax_rate);
264

    
265
  // Redirect based on the button clicked.
266
  drupal_set_message(t('Tax rate saved.'));
267

    
268
  $form_state['redirect'] = 'admin/commerce/config/taxes';
269
}
270

    
271
/**
272
 * Submit callback for delete button on commerce_tax_ui_tax_rate_form().
273
 *
274
 * @see commerce_tax_ui_tax_rate_form()
275
 */
276
function commerce_tax_ui_tax_rate_form_delete_submit($form, &$form_state) {
277
  $form_state['redirect'] = 'admin/commerce/config/taxes/rates/' . strtr($form_state['tax_rate']['name'], '_', '-') . '/delete';
278
}
279

    
280
/**
281
 * Form callback: confirmation form for deleting a tax rate.
282
 *
283
 * @param $tax_rate
284
 *   The tax rate array to be deleted.
285
 *
286
 * @see confirm_form()
287
 */
288
function commerce_tax_ui_tax_rate_delete_form($form, &$form_state, $tax_rate) {
289
  $form_state['tax_rate'] = $tax_rate;
290

    
291
  $form = confirm_form($form,
292
    t('Are you sure you want to delete the %title tax rate?', array('%title' => $tax_rate['title'])),
293
    'admin/commerce/config/taxes',
294
    '<p>' . t('This action cannot be undone.') . '</p>',
295
    t('Delete'),
296
    t('Cancel'),
297
    'confirm'
298
  );
299

    
300
  return $form;
301
}
302

    
303
/**
304
 * Submit callback for commerce_tax_ui_tax_rate_delete_form().
305
 */
306
function commerce_tax_ui_tax_rate_delete_form_submit($form, &$form_state) {
307
  $tax_rate = $form_state['tax_rate'];
308

    
309
  commerce_tax_ui_tax_rate_delete($tax_rate['name']);
310

    
311
  drupal_set_message(t('The tax rate %title has been deleted.', array('%title' => $tax_rate['title'])));
312
  watchdog('commerce_tax', 'Deleted tax rate %title.', array('%title' => $tax_rate['title']), WATCHDOG_NOTICE);
313

    
314
  $form_state['redirect'] = 'admin/commerce/config/taxes';
315
}
316

    
317
/**
318
 * Form callback: create or edit a tax type.
319
 *
320
 * @param $tax_type
321
 *   The tax type array to edit or for a create form an empty tax type
322
 *     array with properties instantiated but not populated.
323
 */
324
function commerce_tax_ui_tax_type_form($form, &$form_state, $tax_type) {
325
  // Store the initial tax type in the form state.
326
  $form_state['tax_type'] = $tax_type;
327

    
328
  $form['tax_type'] = array(
329
    '#tree' => TRUE,
330
  );
331

    
332
  $form['tax_type']['title'] = array(
333
    '#type' => 'textfield',
334
    '#title' => t('Title'),
335
    '#default_value' => $tax_type['title'],
336
    '#description' => t('The administrative title of this tax type. It is recommended that this title begin with a capital letter and contain only letters, numbers, and spaces.'),
337
    '#required' => TRUE,
338
    '#size' => 32,
339
    '#field_suffix' => ' <small id="edit-tax-rate-title-suffix">' . t('Machine name: @name', array('@name' => $tax_type['name'])) . '</small>',
340
  );
341

    
342
  if (empty($tax_type['name'])) {
343
    $form['tax_type']['name'] = array(
344
      '#type' => 'machine_name',
345
      '#title' => t('Machine name'),
346
      '#default_value' => $tax_type['name'],
347
      '#maxlength' => 46,
348
      '#required' => TRUE,
349
      '#machine_name' => array(
350
        'exists' => 'commerce_tax_type_load',
351
        'source' => array('tax_type', 'title'),
352
      ),
353
      '#description' => t('The machine-name of this tax type. This name must contain only lowercase letters, numbers, and underscores. It must be unique.'),
354
    );
355
  }
356

    
357
  $form['tax_type']['display_title'] = array(
358
    '#type' => 'textfield',
359
    '#title' => t('Display title'),
360
    '#default_value' => $tax_type['display_title'],
361
    '#description' => t('The front end display title of this tax type shown to customers. Leave blank to default to the <em>Title</em> from above.'),
362
    '#size' => 32,
363
  );
364

    
365
  $form['tax_type']['description'] = array(
366
    '#type' => 'textarea',
367
    '#title' => t('Description'),
368
    '#description' => t('Describe this tax type if necessary. The text will be displayed in the tax type overview table.'),
369
    '#default_value' => $tax_type['description'],
370
    '#rows' => 3,
371
  );
372

    
373
  $form['tax_type']['display_inclusive'] = array(
374
    '#type' => 'checkbox',
375
    '#title' => t('Display taxes of this type inclusive in product prices.'),
376
    '#default_value' => $tax_type['display_inclusive'],
377
  );
378

    
379
  $form['tax_type']['round_mode'] = array(
380
    '#type' => 'radios',
381
    '#title' => t('Tax amount rounding mode'),
382
    '#description' => t('Specify what type of rounding should occur when tax rates of this type are calculated for the unit price of a line item. Sales taxes will generally not round these amounts at the unit price level, while VAT style taxes will generally round the half up.'),
383
    '#options' => commerce_round_mode_options_list(),
384
    '#default_value' => $tax_type['round_mode'],
385
  );
386

    
387
  $form['actions'] = array(
388
    '#type' => 'actions',
389
    '#weight' => 40,
390
  );
391

    
392
  $form['actions']['submit'] = array(
393
    '#type' => 'submit',
394
    '#value' => t('Save tax type'),
395
  );
396

    
397
  if (!empty($form_state['tax_type']['name'])) {
398
    $form['actions']['delete'] = array(
399
      '#type' => 'submit',
400
      '#value' => t('Delete tax type'),
401
      '#suffix' => l(t('Cancel'), 'admin/commerce/config/taxes/types'),
402
      '#submit' => array('commerce_tax_ui_tax_type_form_delete_submit'),
403
      '#weight' => 45,
404
    );
405
  }
406
  else {
407
    $form['actions']['submit']['#suffix'] = l(t('Cancel'), 'admin/commerce/config/taxes/types');
408
  }
409

    
410
  return $form;
411
}
412

    
413
/**
414
 * Validation callback for commerce_tax_ui_tax_type_form().
415
 */
416
function commerce_tax_ui_tax_type_form_validate($form, &$form_state) {
417
  $tax_type = $form_state['tax_type'];
418

    
419
  // If saving a new tax type, ensure it has a unique machine name.
420
  if (empty($tax_type['name'])) {
421
    if (commerce_tax_type_load($form_state['values']['tax_type']['name']) != FALSE) {
422
      form_set_error('tax_type][name', t('The machine-name specified is already in use.'));
423
    }
424
  }
425
}
426

    
427
/**
428
 * Form submit handler: save a tax type.
429
 */
430
function commerce_tax_ui_tax_type_form_submit($form, &$form_state) {
431
  $tax_type = $form_state['tax_type'];
432
  $updated = !empty($tax_type['name']);
433

    
434
  foreach ($form_state['values']['tax_type'] as $key => $value) {
435
    $tax_type[$key] = $value;
436
  }
437

    
438
  // Default the display title to the title if empty.
439
  if (empty($tax_type['display_title'])) {
440
    $tax_type['display_title'] = $tax_type['title'];
441
  }
442

    
443
  // Write the tax type to the database.
444
  $tax_type['is_new'] = !$updated;
445
  commerce_tax_ui_tax_type_save($tax_type);
446

    
447
  // Clear the field cache if the round mode changed.
448
  if ($form_state['tax_type']['round_mode'] != $tax_type['round_mode']) {
449
    field_cache_clear();
450
  }
451

    
452
  // Redirect based on the button clicked.
453
  drupal_set_message(t('Tax type saved.'));
454

    
455
  $form_state['redirect'] = 'admin/commerce/config/taxes/types';
456
}
457

    
458
/**
459
 * Submit callback for delete button on commerce_tax_ui_tax_type_form().
460
 *
461
 * @see commerce_tax_ui_tax_type_form()
462
 */
463
function commerce_tax_ui_tax_type_form_delete_submit($form, &$form_state) {
464
  $form_state['redirect'] = 'admin/commerce/config/taxes/types/' . strtr($form_state['tax_type']['name'], '_', '-') . '/delete';
465
}
466

    
467
/**
468
 * Form callback wrapper: confirmation form for deleting a tax type.
469
 *
470
 * @param $tax_type
471
 *   The tax type array being deleted by this form.
472
 *
473
 * @see commerce_tax_ui_tax_type_delete_form()
474
 */
475
function commerce_tax_ui_tax_type_delete_form_wrapper($tax_type) {
476
  // Return a message if the taxtype is not governed by Tax UI.
477
  if ($tax_type['module'] != 'commerce_tax_ui') {
478
    return t('This tax type cannot be deleted, because it is not defined by the Tax UI module.');
479
  }
480

    
481
  // Don't allow deletion of tax types that have tax rates.
482
  $query = db_select('commerce_tax_rate')
483
    ->condition('type', $tax_type['name'])
484
    ->countQuery()
485
    ->execute();
486

    
487
  $count = $query->fetchField();
488

    
489
  if ($count > 0) {
490
    drupal_set_title(t('Cannot delete the %title tax type', array('%title' => $tax_type['title'])), PASS_THROUGH);
491

    
492
    return format_plural($count,
493
      'There is a tax rate of this type. It cannot be deleted.',
494
      'There are @count tax rates of this type. It cannot be deleted.'
495
    );
496
  }
497

    
498
  return drupal_get_form('commerce_tax_ui_tax_type_delete_form', $tax_type);
499
}
500

    
501
/**
502
 * Form callback: confirmation form for deleting a tax type.
503
 *
504
 * @param $tax_type
505
 *   The tax type array to be deleted.
506
 *
507
 * @see confirm_form()
508
 */
509
function commerce_tax_ui_tax_type_delete_form($form, &$form_state, $tax_type) {
510
  $form_state['tax_type'] = $tax_type;
511

    
512
  $form = confirm_form($form,
513
    t('Are you sure you want to delete the %title tax type?', array('%title' => $tax_type['title'])),
514
    'admin/commerce/config/taxes/types',
515
    '<p>' . t('This action cannot be undone.') . '</p>',
516
    t('Delete'),
517
    t('Cancel'),
518
    'confirm'
519
  );
520

    
521
  return $form;
522
}
523

    
524
/**
525
 * Submit callback for commerce_tax_ui_tax_type_delete_form().
526
 */
527
function commerce_tax_ui_tax_type_delete_form_submit($form, &$form_state) {
528
  $tax_type = $form_state['tax_type'];
529

    
530
  commerce_tax_ui_tax_type_delete($tax_type['name']);
531

    
532
  drupal_set_message(t('The tax type %title has been deleted.', array('%title' => $tax_type['title'])));
533
  watchdog('commerce_tax', 'Deleted tax type %title.', array('%title' => $tax_type['title']), WATCHDOG_NOTICE);
534

    
535
  $form_state['redirect'] = 'admin/commerce/config/taxes/types';
536
}