|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* Manage Taxes. |
|
5
|
|
|
* |
|
6
|
|
|
* @since 2.5.0 |
|
7
|
|
|
* @package WooCommerce/CLI |
|
8
|
|
|
* @category CLI |
|
9
|
|
|
* @author WooThemes |
|
10
|
|
|
*/ |
|
11
|
|
|
class WC_CLI_Tax extends WC_CLI_Command { |
|
12
|
|
|
|
|
13
|
|
|
/** |
|
14
|
|
|
* Create a tax rate. |
|
15
|
|
|
* |
|
16
|
|
|
* ## OPTIONS |
|
17
|
|
|
* |
|
18
|
|
|
* [--<field>=<value>] |
|
19
|
|
|
* : Associative args for the new tax rate. |
|
20
|
|
|
* |
|
21
|
|
|
* [--porcelain] |
|
22
|
|
|
* : Outputs just the new tax rate id. |
|
23
|
|
|
* |
|
24
|
|
|
* ## AVAILABLE FIELDS |
|
25
|
|
|
* |
|
26
|
|
|
* These fields are available for create command: |
|
27
|
|
|
* |
|
28
|
|
|
* * country |
|
29
|
|
|
* * state |
|
30
|
|
|
* * postcode |
|
31
|
|
|
* * city |
|
32
|
|
|
* * rate |
|
33
|
|
|
* * name |
|
34
|
|
|
* * priority |
|
35
|
|
|
* * compound |
|
36
|
|
|
* * shipping |
|
37
|
|
|
* * class |
|
38
|
|
|
* * order |
|
39
|
|
|
* |
|
40
|
|
|
* ## EXAMPLES |
|
41
|
|
|
* |
|
42
|
|
|
* wp wc tax create --country=US --rate=5 --class=standard --type=percent |
|
43
|
|
|
* |
|
44
|
|
|
* @since 2.5.0 |
|
45
|
|
|
*/ |
|
46
|
|
|
public function create( $__, $assoc_args ) { |
|
47
|
|
|
$porcelain = isset( $assoc_args['porcelain'] ); |
|
48
|
|
|
unset( $assoc_args['porcelain'] ); |
|
49
|
|
|
|
|
50
|
|
|
$assoc_args = apply_filters( 'woocommerce_cli_create_tax_rate_data', $assoc_args ); |
|
51
|
|
|
|
|
52
|
|
|
$tax_data = array( |
|
53
|
|
|
'tax_rate_country' => '', |
|
54
|
|
|
'tax_rate_state' => '', |
|
55
|
|
|
'tax_rate' => '', |
|
56
|
|
|
'tax_rate_name' => '', |
|
57
|
|
|
'tax_rate_priority' => 1, |
|
58
|
|
|
'tax_rate_compound' => 0, |
|
59
|
|
|
'tax_rate_shipping' => 1, |
|
60
|
|
|
'tax_rate_order' => 0, |
|
61
|
|
|
'tax_rate_class' => '', |
|
62
|
|
|
); |
|
63
|
|
|
|
|
64
|
|
|
foreach ( $tax_data as $key => $value ) { |
|
65
|
|
|
$new_key = str_replace( 'tax_rate_', '', $key ); |
|
66
|
|
|
$new_key = 'tax_rate' === $new_key ? 'rate' : $new_key; |
|
67
|
|
|
|
|
68
|
|
|
if ( isset( $assoc_args[ $new_key ] ) ) { |
|
69
|
|
|
if ( in_array( $new_key, array( 'compound', 'shipping' ) ) ) { |
|
70
|
|
|
$tax_data[ $key ] = $assoc_args[ $new_key ] ? 1 : 0; |
|
71
|
|
|
} else { |
|
72
|
|
|
$tax_data[ $key ] = $assoc_args[ $new_key ]; |
|
73
|
|
|
} |
|
74
|
|
|
} |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
// Create tax rate. |
|
78
|
|
|
$id = WC_Tax::_insert_tax_rate( $tax_data ); |
|
79
|
|
|
|
|
80
|
|
|
// Add locales. |
|
81
|
|
|
if ( ! empty( $assoc_args['postcode'] ) ) { |
|
82
|
|
|
WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $assoc_args['postcode'] ) ); |
|
|
|
|
|
|
83
|
|
|
} |
|
84
|
|
|
|
|
85
|
|
|
if ( ! empty( $assoc_args['city'] ) ) { |
|
86
|
|
|
WC_Tax::_update_tax_rate_cities( $id, wc_clean( $assoc_args['city'] ) ); |
|
|
|
|
|
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
|
|
do_action( 'woocommerce_cli_create_tax_rate', $id, $tax_data ); |
|
90
|
|
|
|
|
91
|
|
|
if ( $porcelain ) { |
|
92
|
|
|
WP_CLI::line( $id ); |
|
93
|
|
|
} else { |
|
94
|
|
|
WP_CLI::success( "Created tax rate $id." ); |
|
95
|
|
|
} |
|
96
|
|
|
} |
|
97
|
|
|
|
|
98
|
|
|
/** |
|
99
|
|
|
* Create a tax class. |
|
100
|
|
|
* |
|
101
|
|
|
* ## OPTIONS |
|
102
|
|
|
* |
|
103
|
|
|
* [--<field>=<value>] |
|
104
|
|
|
* : Associative args for the new tax class. |
|
105
|
|
|
* |
|
106
|
|
|
* [--porcelain] |
|
107
|
|
|
* : Outputs just the new tax class slug. |
|
108
|
|
|
* |
|
109
|
|
|
* ## AVAILABLE FIELDS |
|
110
|
|
|
* |
|
111
|
|
|
* These fields are available for create command: |
|
112
|
|
|
* |
|
113
|
|
|
* * name |
|
114
|
|
|
* |
|
115
|
|
|
* ## EXAMPLES |
|
116
|
|
|
* |
|
117
|
|
|
* wp wc tax create_class --name="Reduced Rate" |
|
118
|
|
|
* |
|
119
|
|
|
* @since 2.5.0 |
|
120
|
|
|
*/ |
|
121
|
|
|
public function create_class( $__, $assoc_args ) { |
|
122
|
|
|
try { |
|
123
|
|
|
$porcelain = isset( $assoc_args['porcelain'] ); |
|
124
|
|
|
unset( $assoc_args['porcelain'] ); |
|
125
|
|
|
|
|
126
|
|
|
$assoc_args = apply_filters( 'woocommerce_cli_create_tax_class_data', $assoc_args ); |
|
127
|
|
|
|
|
128
|
|
|
// Check if name is specified. |
|
129
|
|
View Code Duplication |
if ( ! isset( $assoc_args['name'] ) ) { |
|
|
|
|
|
|
130
|
|
|
throw new WC_CLI_Exception( 'woocommerce_cli_missing_name', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'name' ) ); |
|
131
|
|
|
} |
|
132
|
|
|
|
|
133
|
|
|
$name = sanitize_text_field( $assoc_args['name'] ); |
|
134
|
|
|
$slug = sanitize_title( $name ); |
|
135
|
|
|
$classes = WC_Tax::get_tax_classes(); |
|
136
|
|
|
$exists = false; |
|
137
|
|
|
|
|
138
|
|
|
// Check if class exists. |
|
139
|
|
|
foreach ( $classes as $key => $class ) { |
|
140
|
|
|
if ( sanitize_title( $class ) === $slug ) { |
|
141
|
|
|
$exists = true; |
|
142
|
|
|
break; |
|
143
|
|
|
} |
|
144
|
|
|
} |
|
145
|
|
|
|
|
146
|
|
|
// Return error if tax class already exists. |
|
147
|
|
|
if ( $exists ) { |
|
148
|
|
|
throw new WC_CLI_Exception( 'woocommerce_cli_cannot_create_tax_class', __( 'Tax class already exists', 'woocommerce' ) ); |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
// Add the new class |
|
152
|
|
|
$classes[] = $name; |
|
153
|
|
|
|
|
154
|
|
|
update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); |
|
155
|
|
|
|
|
156
|
|
|
do_action( 'woocommerce_cli_create_tax_class', $slug, array( 'name' => $name ) ); |
|
157
|
|
|
|
|
158
|
|
|
if ( $porcelain ) { |
|
159
|
|
|
WP_CLI::line( $slug ); |
|
160
|
|
|
} else { |
|
161
|
|
|
WP_CLI::success( "Created tax class $slug." ); |
|
162
|
|
|
} |
|
163
|
|
|
} catch ( WC_CLI_Exception $e ) { |
|
164
|
|
|
WP_CLI::error( $e->getMessage() ); |
|
165
|
|
|
} |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
/** |
|
169
|
|
|
* Delete one or more tax rates. |
|
170
|
|
|
* |
|
171
|
|
|
* ## OPTIONS |
|
172
|
|
|
* |
|
173
|
|
|
* <id>... |
|
174
|
|
|
* : The tax rate ID to delete. |
|
175
|
|
|
* |
|
176
|
|
|
* ## EXAMPLES |
|
177
|
|
|
* |
|
178
|
|
|
* wp wc tax delete 123 |
|
179
|
|
|
* |
|
180
|
|
|
* wp wc tax delete $(wp wc tax list --format=ids) |
|
181
|
|
|
* |
|
182
|
|
|
* @since 2.5.0 |
|
183
|
|
|
*/ |
|
184
|
|
|
public function delete( $args, $assoc_args ) { |
|
185
|
|
|
$exit_code = 0; |
|
186
|
|
|
|
|
187
|
|
|
foreach ( $args as $tax_id ) { |
|
188
|
|
|
$tax_id = absint( $tax_id ); |
|
189
|
|
|
$tax = WC_Tax::_get_tax_rate( $tax_id ); |
|
190
|
|
|
|
|
191
|
|
|
if ( is_null( $tax ) ) { |
|
192
|
|
|
$exit_code += 1; |
|
193
|
|
|
WP_CLI::warning( "Failed deleting tax rate {$tax_id}." ); |
|
194
|
|
|
continue; |
|
195
|
|
|
} |
|
196
|
|
|
|
|
197
|
|
|
do_action( 'woocommerce_cli_delete_tax_rate', $tax_id ); |
|
198
|
|
|
|
|
199
|
|
|
WC_Tax::_delete_tax_rate( $tax_id ); |
|
200
|
|
|
WP_CLI::success( "Deleted tax rate {$tax_id}." ); |
|
201
|
|
|
} |
|
202
|
|
|
exit( $exit_code ? 1 : 0 ); |
|
203
|
|
|
} |
|
204
|
|
|
|
|
205
|
|
|
/** |
|
206
|
|
|
* Delete one or more tax classes. |
|
207
|
|
|
* |
|
208
|
|
|
* ## OPTIONS |
|
209
|
|
|
* |
|
210
|
|
|
* <slug>... |
|
211
|
|
|
* : The tax class slug to delete. |
|
212
|
|
|
* |
|
213
|
|
|
* ## EXAMPLES |
|
214
|
|
|
* |
|
215
|
|
|
* wp wc tax delete_class reduced-rate |
|
216
|
|
|
* |
|
217
|
|
|
* wp wc tax delete_class $(wp wc tax list_class --format=ids) |
|
218
|
|
|
* |
|
219
|
|
|
* @since 2.5.0 |
|
220
|
|
|
*/ |
|
221
|
|
|
public function delete_class( $args, $assoc_args ) { |
|
222
|
|
|
$classes = WC_Tax::get_tax_classes(); |
|
223
|
|
|
$exit_code = 0; |
|
224
|
|
|
|
|
225
|
|
|
foreach ( $args as $slug ) { |
|
226
|
|
|
$slug = sanitize_title( $slug ); |
|
227
|
|
|
$deleted = false; |
|
228
|
|
|
|
|
229
|
|
|
foreach ( $classes as $key => $class ) { |
|
230
|
|
|
if ( sanitize_title( $class ) === $slug ) { |
|
231
|
|
|
unset( $classes[ $key ] ); |
|
232
|
|
|
$deleted = true; |
|
233
|
|
|
break; |
|
234
|
|
|
} |
|
235
|
|
|
} |
|
236
|
|
|
|
|
237
|
|
|
if ( $deleted ) { |
|
238
|
|
|
WP_CLI::success( "Deleted tax class {$slug}." ); |
|
239
|
|
|
} else { |
|
240
|
|
|
$exit_code += 1; |
|
241
|
|
|
WP_CLI::warning( "Failed deleting tax class {$slug}." ); |
|
242
|
|
|
} |
|
243
|
|
|
} |
|
244
|
|
|
|
|
245
|
|
|
update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); |
|
246
|
|
|
|
|
247
|
|
|
exit( $exit_code ? 1 : 0 ); |
|
248
|
|
|
} |
|
249
|
|
|
|
|
250
|
|
|
/** |
|
251
|
|
|
* Get a tax rate. |
|
252
|
|
|
* |
|
253
|
|
|
* ## OPTIONS |
|
254
|
|
|
* |
|
255
|
|
|
* <id> |
|
256
|
|
|
* : Tax rate ID |
|
257
|
|
|
* |
|
258
|
|
|
* [--field=<field>] |
|
259
|
|
|
* : Instead of returning the whole tax rate fields, returns the value of a single fields. |
|
260
|
|
|
* |
|
261
|
|
|
* [--fields=<fields>] |
|
262
|
|
|
* : Get a specific subset of the tax rates fields. |
|
263
|
|
|
* |
|
264
|
|
|
* [--format=<format>] |
|
265
|
|
|
* : Accepted values: table, json, csv. Default: table. |
|
266
|
|
|
* |
|
267
|
|
|
* ## AVAILABLE FIELDS |
|
268
|
|
|
* |
|
269
|
|
|
* These fields are available for get command: |
|
270
|
|
|
* |
|
271
|
|
|
* * id |
|
272
|
|
|
* * country |
|
273
|
|
|
* * state |
|
274
|
|
|
* * postcode |
|
275
|
|
|
* * city |
|
276
|
|
|
* * rate |
|
277
|
|
|
* * name |
|
278
|
|
|
* * priority |
|
279
|
|
|
* * compound |
|
280
|
|
|
* * shipping |
|
281
|
|
|
* * order |
|
282
|
|
|
* * class |
|
283
|
|
|
* |
|
284
|
|
|
* ## EXAMPLES |
|
285
|
|
|
* |
|
286
|
|
|
* wp wc tax get 123 --field=rate |
|
287
|
|
|
* |
|
288
|
|
|
* wp wc tax get 321 --format=json > rate321.json |
|
289
|
|
|
* |
|
290
|
|
|
* @since 2.5.0 |
|
291
|
|
|
*/ |
|
292
|
|
|
public function get( $args, $assoc_args ) { |
|
293
|
|
|
global $wpdb; |
|
294
|
|
|
|
|
295
|
|
|
try { |
|
296
|
|
|
|
|
297
|
|
|
$tax_data = $this->format_taxes_to_items( array( $args[0] ) ); |
|
298
|
|
|
|
|
299
|
|
View Code Duplication |
if ( empty( $tax_data ) ) { |
|
|
|
|
|
|
300
|
|
|
throw new WC_CLI_Exception( 'woocommerce_cli_invalid_tax_rate', sprintf( __( 'Invalid tax rate ID: %s', 'woocommerce' ), $args[0] ) ); |
|
301
|
|
|
} |
|
302
|
|
|
|
|
303
|
|
|
$tax_data = apply_filters( 'woocommerce_cli_get_tax_rate', $tax_data[0] ); |
|
304
|
|
|
|
|
305
|
|
|
if ( empty( $assoc_args['fields'] ) ) { |
|
306
|
|
|
$assoc_args['fields'] = array_keys( $tax_data ); |
|
307
|
|
|
} |
|
308
|
|
|
|
|
309
|
|
|
$formatter = $this->get_formatter( $assoc_args ); |
|
310
|
|
|
$formatter->display_item( $tax_data ); |
|
311
|
|
|
} catch ( WC_CLI_Exception $e ) { |
|
312
|
|
|
WP_CLI::error( $e->getMessage() ); |
|
313
|
|
|
} |
|
314
|
|
|
} |
|
315
|
|
|
|
|
316
|
|
|
/** |
|
317
|
|
|
* List taxes. |
|
318
|
|
|
* |
|
319
|
|
|
* ## OPTIONS |
|
320
|
|
|
* |
|
321
|
|
|
* [--<field>=<value>] |
|
322
|
|
|
* : Filter tax based on tax property. |
|
323
|
|
|
* |
|
324
|
|
|
* [--field=<field>] |
|
325
|
|
|
* : Prints the value of a single field for each tax. |
|
326
|
|
|
* |
|
327
|
|
|
* [--fields=<fields>] |
|
328
|
|
|
* : Limit the output to specific tax fields. |
|
329
|
|
|
* |
|
330
|
|
|
* [--format=<format>] |
|
331
|
|
|
* : Acceptec values: table, csv, json, count, ids. Default: table. |
|
332
|
|
|
* |
|
333
|
|
|
* ## AVAILABLE FIELDS |
|
334
|
|
|
* |
|
335
|
|
|
* These fields will be displayed by default for each tax: |
|
336
|
|
|
* |
|
337
|
|
|
* * id |
|
338
|
|
|
* * country |
|
339
|
|
|
* * state |
|
340
|
|
|
* * postcode |
|
341
|
|
|
* * city |
|
342
|
|
|
* * rate |
|
343
|
|
|
* * name |
|
344
|
|
|
* * priority |
|
345
|
|
|
* * compound |
|
346
|
|
|
* * shipping |
|
347
|
|
|
* * class |
|
348
|
|
|
* |
|
349
|
|
|
* These fields are optionally available: |
|
350
|
|
|
* |
|
351
|
|
|
* * order |
|
352
|
|
|
* |
|
353
|
|
|
* Fields for filtering query result also available: |
|
354
|
|
|
* |
|
355
|
|
|
* * class Sort by tax class. |
|
356
|
|
|
* * page Page number. |
|
357
|
|
|
* |
|
358
|
|
|
* ## EXAMPLES |
|
359
|
|
|
* |
|
360
|
|
|
* wp wc tax list |
|
361
|
|
|
* |
|
362
|
|
|
* wp wc tax list --field=id |
|
363
|
|
|
* |
|
364
|
|
|
* wp wc tax list --fields=id,rate,class --format=json |
|
365
|
|
|
* |
|
366
|
|
|
* @since 2.5.0 |
|
367
|
|
|
* @subcommand list |
|
368
|
|
|
*/ |
|
369
|
|
|
public function list_( $__, $assoc_args ) { |
|
370
|
|
|
$query_args = $this->merge_tax_query_args( array(), $assoc_args ); |
|
371
|
|
|
$formatter = $this->get_formatter( $assoc_args ); |
|
372
|
|
|
|
|
373
|
|
|
$taxes = $this->query_tax_rates( $query_args ); |
|
374
|
|
|
|
|
375
|
|
|
if ( 'ids' === $formatter->format ) { |
|
376
|
|
|
$_taxes = array(); |
|
377
|
|
|
foreach ( $taxes as $tax ) { |
|
378
|
|
|
$_taxes[] = $tax->tax_rate_id; |
|
379
|
|
|
} |
|
380
|
|
|
echo implode( ' ', $_taxes ); |
|
381
|
|
|
} else { |
|
382
|
|
|
$items = $this->format_taxes_to_items( $taxes ); |
|
383
|
|
|
$formatter->display_items( $items ); |
|
384
|
|
|
} |
|
385
|
|
|
} |
|
386
|
|
|
|
|
387
|
|
|
/** |
|
388
|
|
|
* List tax classes. |
|
389
|
|
|
* |
|
390
|
|
|
* ## OPTIONS |
|
391
|
|
|
* |
|
392
|
|
|
* [--<field>=<value>] |
|
393
|
|
|
* : Filter tax class based on tax class property. |
|
394
|
|
|
* |
|
395
|
|
|
* [--field=<field>] |
|
396
|
|
|
* : Prints the value of a single field for each tax class. |
|
397
|
|
|
* |
|
398
|
|
|
* [--fields=<fields>] |
|
399
|
|
|
* : Limit the output to specific tax class fields. |
|
400
|
|
|
* |
|
401
|
|
|
* [--format=<format>] |
|
402
|
|
|
* : Acceptec values: table, csv, json, count, ids. Default: table. |
|
403
|
|
|
* |
|
404
|
|
|
* ## AVAILABLE FIELDS |
|
405
|
|
|
* |
|
406
|
|
|
* These fields will be displayed by default for each tax class: |
|
407
|
|
|
* |
|
408
|
|
|
* * slug |
|
409
|
|
|
* * name |
|
410
|
|
|
* |
|
411
|
|
|
* ## EXAMPLES |
|
412
|
|
|
* |
|
413
|
|
|
* wp wc tax list_class |
|
414
|
|
|
* |
|
415
|
|
|
* wp wc tax list_class --field=slug |
|
416
|
|
|
* |
|
417
|
|
|
* wp wc tax list_class --format=json |
|
418
|
|
|
* |
|
419
|
|
|
* @since 2.5.0 |
|
420
|
|
|
* @subcommand list_class |
|
421
|
|
|
*/ |
|
422
|
|
|
public function list_class( $__, $assoc_args ) { |
|
423
|
|
|
// Set default fields for tax classes |
|
424
|
|
|
if ( empty( $assoc_args['fields'] ) ) { |
|
425
|
|
|
$assoc_args['fields'] = 'slug,name'; |
|
426
|
|
|
} |
|
427
|
|
|
|
|
428
|
|
|
$formatter = $this->get_formatter( $assoc_args ); |
|
429
|
|
|
$items = array(); |
|
430
|
|
|
|
|
431
|
|
|
// Add standard class |
|
432
|
|
|
$items[] = array( |
|
433
|
|
|
'slug' => 'standard', |
|
434
|
|
|
'name' => __( 'Standard Rate', 'woocommerce' ) |
|
435
|
|
|
); |
|
436
|
|
|
|
|
437
|
|
|
$classes = WC_Tax::get_tax_classes(); |
|
438
|
|
|
|
|
439
|
|
|
foreach ( $classes as $class ) { |
|
440
|
|
|
$items[] = apply_filters( 'woocommerce_cli_tax_class_response', array( |
|
441
|
|
|
'slug' => sanitize_title( $class ), |
|
442
|
|
|
'name' => $class |
|
443
|
|
|
), $class, $assoc_args, $this ); |
|
444
|
|
|
} |
|
445
|
|
|
|
|
446
|
|
|
if ( 'ids' === $formatter->format ) { |
|
447
|
|
|
$_slugs = array(); |
|
448
|
|
|
foreach ( $items as $item ) { |
|
449
|
|
|
$_slugs[] = $item['slug']; |
|
450
|
|
|
} |
|
451
|
|
|
echo implode( ' ', $_slugs ); |
|
452
|
|
|
} else { |
|
453
|
|
|
$formatter->display_items( $items ); |
|
454
|
|
|
} |
|
455
|
|
|
} |
|
456
|
|
|
|
|
457
|
|
|
/** |
|
458
|
|
|
* Update a tax rate. |
|
459
|
|
|
* |
|
460
|
|
|
* ## OPTIONS |
|
461
|
|
|
* |
|
462
|
|
|
* <id> |
|
463
|
|
|
* : The ID of the tax rate to update. |
|
464
|
|
|
* |
|
465
|
|
|
* [--<field>=<value>] |
|
466
|
|
|
* : One or more fields to update. |
|
467
|
|
|
* |
|
468
|
|
|
* ## AVAILABLE FIELDS |
|
469
|
|
|
* |
|
470
|
|
|
* These fields are available for update command: |
|
471
|
|
|
* |
|
472
|
|
|
* * country |
|
473
|
|
|
* * state |
|
474
|
|
|
* * postcode |
|
475
|
|
|
* * city |
|
476
|
|
|
* * rate |
|
477
|
|
|
* * name |
|
478
|
|
|
* * priority |
|
479
|
|
|
* * compound |
|
480
|
|
|
* * shipping |
|
481
|
|
|
* * class |
|
482
|
|
|
* |
|
483
|
|
|
* ## EXAMPLES |
|
484
|
|
|
* |
|
485
|
|
|
* wp wc tax update 123 --rate=5 |
|
486
|
|
|
* |
|
487
|
|
|
* @since 2.5.0 |
|
488
|
|
|
*/ |
|
489
|
|
|
public function update( $args, $assoc_args ) { |
|
490
|
|
|
try { |
|
491
|
|
|
// Get current tax rate data |
|
492
|
|
|
$tax_data = $this->format_taxes_to_items( array( $args[0] ) ); |
|
493
|
|
|
|
|
494
|
|
View Code Duplication |
if ( empty( $tax_data ) ) { |
|
|
|
|
|
|
495
|
|
|
throw new WC_CLI_Exception( 'woocommerce_cli_invalid_tax_rate', sprintf( __( 'Invalid tax rate ID: %s', 'woocommerce' ), $args[0] ) ); |
|
496
|
|
|
} |
|
497
|
|
|
|
|
498
|
|
|
$current_data = $tax_data[0]; |
|
499
|
|
|
$id = $current_data['id']; |
|
500
|
|
|
$data = apply_filters( 'woocommerce_cli_update_tax_rate_data', $assoc_args, $id ); |
|
501
|
|
|
$new_data = array(); |
|
502
|
|
|
$default_fields = array( |
|
503
|
|
|
'tax_rate_country', |
|
504
|
|
|
'tax_rate_state', |
|
505
|
|
|
'tax_rate', |
|
506
|
|
|
'tax_rate_name', |
|
507
|
|
|
'tax_rate_priority', |
|
508
|
|
|
'tax_rate_compound', |
|
509
|
|
|
'tax_rate_shipping', |
|
510
|
|
|
'tax_rate_order', |
|
511
|
|
|
'tax_rate_class' |
|
512
|
|
|
); |
|
513
|
|
|
|
|
514
|
|
|
foreach ( $data as $key => $value ) { |
|
515
|
|
|
$new_key = 'rate' === $key ? 'tax_rate' : 'tax_rate_' . $key; |
|
516
|
|
|
|
|
517
|
|
|
// Check if the key is valid |
|
518
|
|
|
if ( ! in_array( $new_key, $default_fields ) ) { |
|
519
|
|
|
continue; |
|
520
|
|
|
} |
|
521
|
|
|
|
|
522
|
|
|
// Test new data against current data |
|
523
|
|
|
if ( $value === $current_data[ $key ] ) { |
|
524
|
|
|
continue; |
|
525
|
|
|
} |
|
526
|
|
|
|
|
527
|
|
|
// Fix compund and shipping values |
|
528
|
|
|
if ( in_array( $key, array( 'compound', 'shipping' ) ) ) { |
|
529
|
|
|
$value = $value ? 1 : 0; |
|
530
|
|
|
} |
|
531
|
|
|
|
|
532
|
|
|
$new_data[ $new_key ] = $value; |
|
533
|
|
|
} |
|
534
|
|
|
|
|
535
|
|
|
// Update tax rate |
|
536
|
|
|
WC_Tax::_update_tax_rate( $id, $new_data ); |
|
537
|
|
|
|
|
538
|
|
|
// Update locales |
|
539
|
|
View Code Duplication |
if ( ! empty( $data['postcode'] ) && $current_data['postcode'] != $data['postcode'] ) { |
|
|
|
|
|
|
540
|
|
|
WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $data['postcode'] ) ); |
|
|
|
|
|
|
541
|
|
|
} |
|
542
|
|
|
|
|
543
|
|
View Code Duplication |
if ( ! empty( $data['city'] ) && $current_data['city'] != $data['city'] ) { |
|
|
|
|
|
|
544
|
|
|
WC_Tax::_update_tax_rate_cities( $id, wc_clean( $data['city'] ) ); |
|
|
|
|
|
|
545
|
|
|
} |
|
546
|
|
|
|
|
547
|
|
|
do_action( 'woocommerce_cli_update_tax_rate', $id, $data ); |
|
548
|
|
|
|
|
549
|
|
|
WP_CLI::success( "Updated tax rate $id." ); |
|
550
|
|
|
} catch ( WC_CLI_Exception $e ) { |
|
551
|
|
|
WP_CLI::error( $e->getMessage() ); |
|
552
|
|
|
} |
|
553
|
|
|
} |
|
554
|
|
|
|
|
555
|
|
|
/** |
|
556
|
|
|
* Add common cli arguments to argument list before $wpdb->get_results() is run. |
|
557
|
|
|
* |
|
558
|
|
|
* @since 2.5.0 |
|
559
|
|
|
* @param array $base_args Required arguments for the query (e.g. `limit`, etc) |
|
560
|
|
|
* @param array $assoc_args Arguments provided in when invoking the command |
|
561
|
|
|
* @return array |
|
562
|
|
|
*/ |
|
563
|
|
|
protected function merge_tax_query_args( $base_args, $assoc_args ) { |
|
564
|
|
|
$args = array(); |
|
565
|
|
|
|
|
566
|
|
|
if ( ! empty( $assoc_args['class'] ) ) { |
|
567
|
|
|
$args['class'] = $assoc_args['class']; |
|
568
|
|
|
} |
|
569
|
|
|
|
|
570
|
|
|
// Number of post to show per page. |
|
571
|
|
|
if ( ! empty( $assoc_args['limit'] ) ) { |
|
572
|
|
|
$args['posts_per_page'] = $assoc_args['limit']; |
|
573
|
|
|
} |
|
574
|
|
|
|
|
575
|
|
|
// posts page. |
|
576
|
|
|
$args['paged'] = ( isset( $assoc_args['page'] ) ) ? absint( $assoc_args['page'] ) : 1; |
|
577
|
|
|
|
|
578
|
|
|
$args = apply_filters( 'woocommerce_cli_tax_query_args', $args, $assoc_args ); |
|
579
|
|
|
|
|
580
|
|
|
return array_merge( $base_args, $args ); |
|
581
|
|
|
} |
|
582
|
|
|
|
|
583
|
|
|
/** |
|
584
|
|
|
* Helper method to get tax rates objects |
|
585
|
|
|
* |
|
586
|
|
|
* @since 2.5.0 |
|
587
|
|
|
* |
|
588
|
|
|
* @param array $args |
|
589
|
|
|
* |
|
590
|
|
|
* @return array |
|
591
|
|
|
*/ |
|
592
|
|
|
protected function query_tax_rates( $args ) { |
|
593
|
|
|
global $wpdb; |
|
594
|
|
|
|
|
595
|
|
|
$query = " |
|
596
|
|
|
SELECT tax_rate_id |
|
597
|
|
|
FROM {$wpdb->prefix}woocommerce_tax_rates |
|
598
|
|
|
WHERE 1 = 1 |
|
599
|
|
|
"; |
|
600
|
|
|
|
|
601
|
|
|
// Filter by tax class |
|
602
|
|
View Code Duplication |
if ( ! empty( $args['class'] ) ) { |
|
|
|
|
|
|
603
|
|
|
$class = 'standard' !== $args['class'] ? sanitize_title( $args['class'] ) : ''; |
|
604
|
|
|
$query .= " AND tax_rate_class = '$class'"; |
|
605
|
|
|
} |
|
606
|
|
|
|
|
607
|
|
|
// Order tax rates |
|
608
|
|
|
$order_by = ' ORDER BY tax_rate_order'; |
|
609
|
|
|
|
|
610
|
|
|
// Pagination |
|
611
|
|
|
$per_page = isset( $args['posts_per_page'] ) ? $args['posts_per_page'] : get_option( 'posts_per_page' ); |
|
612
|
|
|
$offset = 1 < $args['paged'] ? ( $args['paged'] - 1 ) * $per_page : 0; |
|
613
|
|
|
$pagination = sprintf( ' LIMIT %d, %d', $offset, $per_page ); |
|
614
|
|
|
|
|
615
|
|
|
return $wpdb->get_results( $query . $order_by . $pagination ); |
|
616
|
|
|
} |
|
617
|
|
|
|
|
618
|
|
|
/** |
|
619
|
|
|
* Get default format fields that will be used in `list` and `get` subcommands. |
|
620
|
|
|
* |
|
621
|
|
|
* @since 2.5.0 |
|
622
|
|
|
* @return string |
|
623
|
|
|
*/ |
|
624
|
|
|
protected function get_default_format_fields() { |
|
625
|
|
|
return 'id,country,state,postcode,city,rate,name,priority,compound,shipping,class'; |
|
626
|
|
|
} |
|
627
|
|
|
|
|
628
|
|
|
/** |
|
629
|
|
|
* Format taxes from query result to items in which each item contain |
|
630
|
|
|
* common properties of item, for instance `tax_rate_id` will be `id`. |
|
631
|
|
|
* |
|
632
|
|
|
* @since 2.5.0 |
|
633
|
|
|
* @param array $taxes Array of tax rate. |
|
634
|
|
|
* @return array Items |
|
635
|
|
|
*/ |
|
636
|
|
|
protected function format_taxes_to_items( $taxes ) { |
|
637
|
|
|
global $wpdb; |
|
638
|
|
|
|
|
639
|
|
|
$items = array(); |
|
640
|
|
|
|
|
641
|
|
|
foreach ( $taxes as $tax_id ) { |
|
642
|
|
|
$id = is_object( $tax_id ) ? $tax_id->tax_rate_id : $tax_id; |
|
643
|
|
|
$id = absint( $id ); |
|
644
|
|
|
|
|
645
|
|
|
// Get tax rate details |
|
646
|
|
|
$tax = WC_Tax::_get_tax_rate( $id ); |
|
647
|
|
|
|
|
648
|
|
|
if ( is_wp_error( $tax ) || empty( $tax ) ) { |
|
649
|
|
|
continue; |
|
650
|
|
|
} |
|
651
|
|
|
|
|
652
|
|
|
$tax_data = array( |
|
653
|
|
|
'id' => $tax['tax_rate_id'], |
|
654
|
|
|
'country' => $tax['tax_rate_country'], |
|
655
|
|
|
'state' => $tax['tax_rate_state'], |
|
656
|
|
|
'postcode' => '', |
|
657
|
|
|
'city' => '', |
|
658
|
|
|
'rate' => $tax['tax_rate'], |
|
659
|
|
|
'name' => $tax['tax_rate_name'], |
|
660
|
|
|
'priority' => (int) $tax['tax_rate_priority'], |
|
661
|
|
|
'compound' => (bool) $tax['tax_rate_compound'], |
|
662
|
|
|
'shipping' => (bool) $tax['tax_rate_shipping'], |
|
663
|
|
|
'order' => (int) $tax['tax_rate_order'], |
|
664
|
|
|
'class' => $tax['tax_rate_class'] ? $tax['tax_rate_class'] : 'standard' |
|
665
|
|
|
); |
|
666
|
|
|
|
|
667
|
|
|
// Get locales from a tax rate |
|
668
|
|
|
$locales = $wpdb->get_results( $wpdb->prepare( " |
|
669
|
|
|
SELECT location_code, location_type |
|
670
|
|
|
FROM {$wpdb->prefix}woocommerce_tax_rate_locations |
|
671
|
|
|
WHERE tax_rate_id = %d |
|
672
|
|
|
", $id ) ); |
|
673
|
|
|
|
|
674
|
|
View Code Duplication |
if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) { |
|
|
|
|
|
|
675
|
|
|
foreach ( $locales as $locale ) { |
|
676
|
|
|
$tax_data[ $locale->location_type ] = $locale->location_code; |
|
677
|
|
|
} |
|
678
|
|
|
} |
|
679
|
|
|
|
|
680
|
|
|
$items[] = $tax_data; |
|
681
|
|
|
} |
|
682
|
|
|
|
|
683
|
|
|
return $items; |
|
684
|
|
|
} |
|
685
|
|
|
} |
|
686
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.