GetPaid_REST_Report_Sales_Controller::get_items()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 6
rs 10
1
<?php
2
/**
3
 * REST API reports controller
4
 *
5
 * Handles requests to the /reports/sales endpoint.
6
 *
7
 * @package GetPaid
8
 * @subpackage REST API
9
 * @since   2.0.0
10
 */
11
12
defined( 'ABSPATH' ) || exit;
13
14
/**
15
 * GetPaid REST reports controller class.
16
 *
17
 * @package GetPaid
18
 */
19
class GetPaid_REST_Report_Sales_Controller extends GetPaid_REST_Date_Based_Controller {
20
21
	/**
22
	 * Route base.
23
	 *
24
	 * @var string
25
	 */
26
	protected $rest_base = 'reports/sales';
27
28
	/**
29
	 * The report data.
30
	 *
31
	 * @var stdClass
32
	 */
33
	public $report_data;
34
35
	/**
36
	 * The report range.
37
	 *
38
	 * @var array
39
	 */
40
	public $report_range;
41
42
	/**
43
	 * Registers the routes for the objects of the controller.
44
	 *
45
	 * @since 2.0.0
46
	 *
47
	 * @see register_rest_route()
48
	 */
49
	public function register_namespace_routes( $namespace ) {
50
51
		// Get sales report.
52
		register_rest_route(
53
			$namespace,
54
			$this->rest_base,
55
			array(
56
				array(
57
					'methods'             => WP_REST_Server::READABLE,
58
					'callback'            => array( $this, 'get_items' ),
59
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
60
					'args'                => $this->get_collection_params(),
61
				),
62
				'schema' => array( $this, 'get_public_item_schema' ),
63
			)
64
		);
65
66
	}
67
68
	/**
69
	 * Makes sure the current user has access to READ the report APIs.
70
	 *
71
	 * @since  2.0.0
72
	 * @param WP_REST_Request $request Full data about the request.
73
	 * @return WP_Error|boolean
74
	 */
75
	public function get_items_permissions_check( $request ) {
76
77
		if ( ! wpinv_current_user_can_manage_invoicing() ) {
78
			return new WP_Error( 'rest_cannot_view', __( 'Sorry, you cannot list resources.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
79
		}
80
81
		return true;
82
	}
83
84
	/**
85
	 * Get sales reports.
86
	 *
87
	 * @param WP_REST_Request $request
88
	 * @return array|WP_Error
89
	 */
90
	public function get_items( $request ) {
91
		$data   = array();
92
		$item   = $this->prepare_item_for_response( null, $request );
93
		$data[] = $this->prepare_response_for_collection( $item );
94
95
		return rest_ensure_response( $data );
0 ignored issues
show
Bug Best Practice introduced by
The expression return rest_ensure_response($data) returns the type WP_REST_Response which is incompatible with the documented return type WP_Error|array.
Loading history...
96
	}
97
98
	/**
99
	 * Prepare a report sales object for serialization.
100
	 *
101
	 * @param null $_
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $_ is correct as it would always require null to be passed?
Loading history...
102
	 * @param WP_REST_Request $request Request object.
103
	 * @return WP_REST_Response $response Response data.
104
	 */
105
	public function prepare_item_for_response( $_, $request ) {
106
107
		// Set report range.
108
		$this->report_range = $this->get_date_range( $request );
109
110
		$report_data     = $this->get_report_data();
111
		$period_totals   = array();
112
113
		// Setup period totals by ensuring each period in the interval has data.
114
		$start_date      = strtotime( $this->report_range['after'] );
115
116
		if ( 'month' === $this->groupby ) {
117
			$start_date      = strtotime( gmdate( 'Y-m-01', $start_date ) );
118
		}
119
120
		for ( $i = 0; $i < $this->interval; $i++ ) {
121
122
			switch ( $this->groupby ) {
123
				case 'day':
124
					$time = gmdate( 'Y-m-d', strtotime( "+{$i} DAY", $start_date ) );
125
					break;
126
				default:
127
					$time = gmdate( 'Y-m', strtotime( "+{$i} MONTH", $start_date ) );
128
					break;
129
			}
130
131
			// Set the defaults for each period.
132
			$period_totals[ $time ] = array(
133
				'invoices'          => 0,
134
				'items'             => 0,
135
				'refunded_items'    => 0,
136
				'refunded_tax'      => wpinv_round_amount( 0.00 ),
137
				'subtotal'          => wpinv_round_amount( 0.00 ),
138
				'refunded_subtotal' => wpinv_round_amount( 0.00 ),
139
				'refunded_fees'     => wpinv_round_amount( 0.00 ),
140
				'discount'          => wpinv_round_amount( 0.00 ),
141
			);
142
143
			foreach ( array_keys( wpinv_get_report_graphs() ) as $key ) {
144
				if ( ! isset( $period_totals[ $time ][ $key ] ) ) {
145
					$period_totals[ $time ][ $key ] = wpinv_round_amount( 0.00 );
146
				}
147
			}
148
		}
149
150
		// add total sales, total invoice count, total tax for each period
151
		$date_format = ( 'day' === $this->groupby ) ? 'Y-m-d' : 'Y-m';
152
		foreach ( $report_data->invoices as $invoice ) {
153
			$time = gmdate( $date_format, strtotime( $invoice->post_date ) );
154
155
			if ( ! isset( $period_totals[ $time ] ) ) {
156
				continue;
157
			}
158
159
			$period_totals[ $time ]['sales']    = wpinv_round_amount( $invoice->total_sales );
160
			$period_totals[ $time ]['tax']      = wpinv_round_amount( $invoice->total_tax );
161
			$period_totals[ $time ]['subtotal'] = wpinv_round_amount( $invoice->subtotal );
162
			$period_totals[ $time ]['fees']     = wpinv_round_amount( $invoice->total_fees );
163
164
		}
165
166
		foreach ( $report_data->refunds as $invoice ) {
167
			$time = gmdate( $date_format, strtotime( $invoice->post_date ) );
168
169
			if ( ! isset( $period_totals[ $time ] ) ) {
170
				continue;
171
			}
172
173
			$period_totals[ $time ]['refunds']           = wpinv_round_amount( $invoice->total_sales );
174
			$period_totals[ $time ]['refunded_tax']      = wpinv_round_amount( $invoice->total_tax );
175
			$period_totals[ $time ]['refunded_subtotal'] = wpinv_round_amount( $invoice->subtotal );
176
			$period_totals[ $time ]['refunded_fees']     = wpinv_round_amount( $invoice->total_fees );
177
178
		}
179
180
		foreach ( $report_data->invoice_counts as $invoice ) {
181
			$time = gmdate( $date_format, strtotime( $invoice->post_date ) );
182
183
			if ( isset( $period_totals[ $time ] ) ) {
184
				$period_totals[ $time ]['invoices']   = (int) $invoice->count;
185
			}
186
		}
187
188
		// Add total invoice items for each period.
189
		foreach ( $report_data->invoice_items as $invoice_item ) {
190
			$time = ( 'day' === $this->groupby ) ? gmdate( 'Y-m-d', strtotime( $invoice_item->post_date ) ) : gmdate( 'Y-m', strtotime( $invoice_item->post_date ) );
191
192
			if ( isset( $period_totals[ $time ] ) ) {
193
				$period_totals[ $time ]['items'] = (int) $invoice_item->invoice_item_count;
194
			}
195
		}
196
197
		// Add total discount for each period.
198
		foreach ( $report_data->coupons as $discount ) {
199
			$time = ( 'day' === $this->groupby ) ? gmdate( 'Y-m-d', strtotime( $discount->post_date ) ) : gmdate( 'Y-m', strtotime( $discount->post_date ) );
200
201
			if ( isset( $period_totals[ $time ] ) ) {
202
				$period_totals[ $time ]['discount'] = wpinv_round_amount( $discount->discount_amount );
203
			}
204
		}
205
206
		// Extra fields.
207
		foreach ( array_keys( wpinv_get_report_graphs() ) as $key ) {
208
209
			// Abort unprepared.
210
			if ( ! isset( $report_data->$key ) ) {
211
				continue;
212
			} 
213
214
			// Abort defaults.
215
			if ( in_array( $key, array( 'sales', 'refunds', 'tax', 'fees', 'discount', 'invoices', 'items' ) ) ) {
216
				continue;
217
			}
218
219
			// Set values.
220
			foreach ( $report_data->$key as $item ) {
221
				$time = ( 'day' === $this->groupby ) ? gmdate( 'Y-m-d', strtotime( $item->date ) ) : gmdate( 'Y-m', strtotime( $item->date ) );
222
223
				if ( isset( $period_totals[ $time ] ) ) {
224
					$period_totals[ $time ][ $key ] = wpinv_round_amount( $item->val );
225
				}
226
			}
227
228
			unset( $report_data->$key );
229
		}
230
231
		$report_data->totals            = $period_totals;
232
		$report_data->grouped_by        = $this->groupby;
233
		$report_data->interval          = max( $this->interval, 1 );
234
		$report_data->currency          = wpinv_get_currency();
235
		$report_data->currency_symbol   = wpinv_currency_symbol();
236
		$report_data->currency_position = wpinv_currency_position();
237
		$report_data->decimal_places    = wpinv_decimals();
238
		$report_data->thousands_sep     = wpinv_thousands_separator();
239
		$report_data->decimals_sep      = wpinv_decimal_separator();
240
		$report_data->start_date        = gmdate( 'Y-m-d', strtotime( $this->report_range['after'] ) );
241
		$report_data->end_date          = gmdate( 'Y-m-d', strtotime( $this->report_range['before'] ) );
242
		$report_data->start_date_locale = getpaid_format_date( gmdate( 'Y-m-d', strtotime( $this->report_range['after'] ) ) );
243
		$report_data->end_date_locale   = getpaid_format_date( gmdate( 'Y-m-d', strtotime( $this->report_range['before'] ) ) );
244
		$report_data->decimals_sep      = wpinv_decimal_separator();
245
246
		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
247
		$data    = $report_data;
248
		unset( $data->invoice_counts, $data->invoices, $data->coupons, $data->refunds, $data->invoice_items );
249
		$data    = $this->add_additional_fields_to_object( (array) $data, $request );
250
		$data    = $this->filter_response_by_context( $data, $context );
251
252
		// Wrap the data in a response object.
253
		$response = rest_ensure_response( $data );
254
		$response->add_links(
255
            array(
256
				'about' => array(
257
					'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ),
258
				),
259
            )
260
        );
261
262
		return apply_filters( 'getpaid_rest_prepare_report_sales', $response, $report_data, $request );
263
	}
264
265
	/**
266
	 * Get report data.
267
	 *
268
	 * @return stdClass
269
	 */
270
	public function get_report_data() {
271
		if ( empty( $this->report_data ) ) {
272
			$this->query_report_data();
273
		}
274
		return $this->report_data;
275
	}
276
277
	/**
278
	 * Get all data needed for this report and store in the class.
279
	 */
280
	protected function query_report_data() {
281
282
		// Prepare reports.
283
		$this->report_data = (object) array(
284
			'invoice_counts' => $this->query_invoice_counts(), //count, post_date
285
			'coupons'        => $this->query_coupon_counts(), // discount_amount, post_date
286
			'invoice_items'  => $this->query_item_counts(), // invoice_item_count, post_date
287
			'refunded_items' => $this->count_refunded_items(), // invoice_item_count, post_date
288
			'invoices'       => $this->query_invoice_totals(), // total_sales, total_tax, total_discount, total_fees, subtotal, post_date
289
			'refunds'        => $this->query_refunded_totals(), // total_sales, total_tax, total_discount, total_fees, subtotal, post_date
290
			'previous_range' => $this->previous_range,
291
		);
292
293
		// Calculated totals.
294
		$this->report_data->total_tax          = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_tax' ) ) );
295
		$this->report_data->total_sales        = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_sales' ) ) );
296
		$this->report_data->total_discount     = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_discount' ) ) );
297
		$this->report_data->total_fees         = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'total_fees' ) ) );
298
		$this->report_data->subtotal           = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->invoices, 'subtotal' ) ) );
299
		$this->report_data->net_sales          = wpinv_round_amount( $this->report_data->total_sales - max( 0, $this->report_data->total_tax ) );
300
		$this->report_data->total_refunded_tax = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_tax' ) ) );
301
		$this->report_data->total_refunds      = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_sales' ) ) );
302
		$this->report_data->refunded_discount  = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_discount' ) ) );
303
		$this->report_data->refunded_fees      = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'total_fees' ) ) );
304
		$this->report_data->refunded_subtotal  = wpinv_round_amount( array_sum( wp_list_pluck( $this->report_data->refunds, 'subtotal' ) ) );
305
		$this->report_data->net_refunds        = wpinv_round_amount( $this->report_data->total_refunds + max( 0, $this->report_data->total_refunded_tax ) );
306
307
		// Calculate average based on net.
308
		$this->report_data->average_sales       = wpinv_round_amount( $this->report_data->net_sales / max( $this->interval, 1 ), 2 );
309
		$this->report_data->average_total_sales = wpinv_round_amount( $this->report_data->total_sales / max( $this->interval, 1 ), 2 );
310
311
		// Total invoices in this period, even if refunded.
312
		$this->report_data->total_invoices = absint( array_sum( wp_list_pluck( $this->report_data->invoice_counts, 'count' ) ) );
313
314
		// Items invoiced in this period, even if refunded.
315
		$this->report_data->total_items = absint( array_sum( wp_list_pluck( $this->report_data->invoice_items, 'invoice_item_count' ) ) );
316
317
		// 3rd party filtering of report data
318
		$this->report_data = apply_filters( 'getpaid_rest_api_filter_report_data', $this->report_data, $this );
319
	}
320
321
	/**
322
	 * Prepares invoice counts.
323
	 *
324
	 * @return array.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array. at position 0 could not be parsed: Unknown type name 'array.' at position 0 in array..
Loading history...
325
	 */
326
	protected function query_invoice_counts() {
327
328
		return (array) GetPaid_Reports_Helper::get_invoice_report_data(
329
			array(
330
				'data'           => array(
331
					'ID'        => array(
332
						'type'     => 'post_data',
333
						'function' => 'COUNT',
334
						'name'     => 'count',
335
						'distinct' => true,
336
					),
337
					'post_date' => array(
338
						'type'     => 'post_data',
339
						'function' => 'MIN',
340
						'name'     => 'post_date',
341
					),
342
				),
343
				'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
344
				'order_by'       => 'post_date ASC',
345
				'query_type'     => 'get_results',
346
				'filter_range'   => $this->report_range,
347
				'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-refunded', 'wpi-renewal' ),
348
			)
349
		);
350
351
	}
352
353
	/**
354
	 * Prepares coupon counts.
355
	 *
356
	 * @return array.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array. at position 0 could not be parsed: Unknown type name 'array.' at position 0 in array..
Loading history...
357
	 */
358
	protected function query_coupon_counts() {
359
360
		return (array) GetPaid_Reports_Helper::get_invoice_report_data(
361
			array(
362
				'data'           => array(
363
					'discount'  => array(
364
						'type'     => 'invoice_data',
365
						'function' => 'SUM',
366
						'name'     => 'discount_amount',
367
					),
368
					'post_date' => array(
369
						'type'     => 'post_data',
370
						'function' => 'MIN',
371
						'name'     => 'post_date',
372
					),
373
				),
374
				'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
375
				'order_by'       => 'post_date ASC',
376
				'query_type'     => 'get_results',
377
				'filter_range'   => $this->report_range,
378
				'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-refunded', 'wpi-renewal' ),
379
			)
380
		);
381
382
	}
383
384
	/**
385
	 * Prepares item counts.
386
	 *
387
	 * @return array.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array. at position 0 could not be parsed: Unknown type name 'array.' at position 0 in array..
Loading history...
388
	 */
389
	protected function query_item_counts() {
390
391
		return (array) GetPaid_Reports_Helper::get_invoice_report_data(
392
			array(
393
				'data'           => array(
394
					'quantity'  => array(
395
						'type'     => 'invoice_item',
396
						'function' => 'SUM',
397
						'name'     => 'invoice_item_count',
398
					),
399
					'post_date' => array(
400
						'type'     => 'post_data',
401
						'function' => 'MIN',
402
						'name'     => 'post_date',
403
					),
404
				),
405
				'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
406
				'order_by'       => 'post_date ASC',
407
				'query_type'     => 'get_results',
408
				'filter_range'   => $this->report_range,
409
				'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-refunded', 'wpi-renewal' ),
410
			)
411
		);
412
413
	}
414
415
	/**
416
	 * Prepares refunded item counts.
417
	 *
418
	 * @return array.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array. at position 0 could not be parsed: Unknown type name 'array.' at position 0 in array..
Loading history...
419
	 */
420
	protected function count_refunded_items() {
421
422
		return (int) GetPaid_Reports_Helper::get_invoice_report_data(
423
			array(
424
				'data'           => array(
425
					'quantity' => array(
426
						'type'     => 'invoice_item',
427
						'function' => 'SUM',
428
						'name'     => 'invoice_item_count',
429
					),
430
				),
431
				'query_type'     => 'get_var',
432
				'filter_range'   => $this->report_range,
433
				'invoice_status' => array( 'wpi-refunded' ),
434
			)
435
		);
436
437
	}
438
439
	/**
440
	 * Prepares daily invoice totals.
441
	 *
442
	 * @return array.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array. at position 0 could not be parsed: Unknown type name 'array.' at position 0 in array..
Loading history...
443
	 */
444
	protected function query_invoice_totals() {
445
446
		return (array) GetPaid_Reports_Helper::get_invoice_report_data(
447
			array(
448
				'data'           => array(
449
					'total'      => array(
450
						'type'     => 'invoice_data',
451
						'function' => 'SUM',
452
						'name'     => 'total_sales',
453
					),
454
					'tax'        => array(
455
						'type'     => 'invoice_data',
456
						'function' => 'SUM',
457
						'name'     => 'total_tax',
458
					),
459
					'discount'   => array(
460
						'type'     => 'invoice_data',
461
						'function' => 'SUM',
462
						'name'     => 'total_discount',
463
					),
464
					'fees_total' => array(
465
						'type'     => 'invoice_data',
466
						'function' => 'SUM',
467
						'name'     => 'total_fees',
468
					),
469
					'subtotal'   => array(
470
						'type'     => 'invoice_data',
471
						'function' => 'SUM',
472
						'name'     => 'subtotal',
473
					),
474
					'post_date'  => array(
475
						'type'     => 'post_data',
476
						'function' => '',
477
						'name'     => 'post_date',
478
					),
479
				),
480
				'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
481
				'order_by'       => 'post_date ASC',
482
				'query_type'     => 'get_results',
483
				'filter_range'   => $this->report_range,
484
				'invoice_status' => array( 'publish', 'wpi-processing', 'wpi-onhold', 'wpi-renewal' ),
485
			)
486
		);
487
488
	}
489
490
	/**
491
	 * Prepares daily invoice totals.
492
	 *
493
	 * @return array.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array. at position 0 could not be parsed: Unknown type name 'array.' at position 0 in array..
Loading history...
494
	 */
495
	protected function query_refunded_totals() {
496
497
		return (array) GetPaid_Reports_Helper::get_invoice_report_data(
498
			array(
499
				'data'           => array(
500
					'total'      => array(
501
						'type'     => 'invoice_data',
502
						'function' => 'SUM',
503
						'name'     => 'total_sales',
504
					),
505
					'tax'        => array(
506
						'type'     => 'invoice_data',
507
						'function' => 'SUM',
508
						'name'     => 'total_tax',
509
					),
510
					'discount'   => array(
511
						'type'     => 'invoice_data',
512
						'function' => 'SUM',
513
						'name'     => 'total_discount',
514
					),
515
					'fees_total' => array(
516
						'type'     => 'invoice_data',
517
						'function' => 'SUM',
518
						'name'     => 'total_fees',
519
					),
520
					'subtotal'   => array(
521
						'type'     => 'invoice_data',
522
						'function' => 'SUM',
523
						'name'     => 'subtotal',
524
					),
525
					'post_date'  => array(
526
						'type'     => 'post_data',
527
						'function' => '',
528
						'name'     => 'post_date',
529
					),
530
				),
531
				'group_by'       => $this->get_group_by_sql( 'posts.post_date' ),
532
				'order_by'       => 'post_date ASC',
533
				'query_type'     => 'get_results',
534
				'filter_range'   => $this->report_range,
535
				'invoice_status' => array( 'wpi-refunded' ),
536
			)
537
		);
538
539
	}
540
541
	/**
542
	 * Get the Report's schema, conforming to JSON Schema.
543
	 *
544
	 * @return array
545
	 */
546
	public function get_item_schema() {
547
548
		$schema = array(
549
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
550
			'title'      => 'sales_report',
551
			'type'       => 'object',
552
			'properties' => array(
553
				'total_sales'         => array(
554
					'description' => __( 'Gross sales in the period.', 'invoicing' ),
555
					'type'        => 'string',
556
					'context'     => array( 'view' ),
557
					'readonly'    => true,
558
				),
559
				'net_sales'           => array(
560
					'description' => __( 'Net sales in the period.', 'invoicing' ),
561
					'type'        => 'string',
562
					'context'     => array( 'view' ),
563
					'readonly'    => true,
564
				),
565
				'average_sales'       => array(
566
					'description' => __( 'Average net daily sales.', 'invoicing' ),
567
					'type'        => 'string',
568
					'context'     => array( 'view' ),
569
					'readonly'    => true,
570
				),
571
				'average_total_sales' => array(
572
					'description' => __( 'Average gross daily sales.', 'invoicing' ),
573
					'type'        => 'string',
574
					'context'     => array( 'view' ),
575
					'readonly'    => true,
576
				),
577
				'total_invoices'      => array(
578
					'description' => __( 'Number of paid invoices.', 'invoicing' ),
579
					'type'        => 'integer',
580
					'context'     => array( 'view' ),
581
					'readonly'    => true,
582
				),
583
				'total_items'         => array(
584
					'description' => __( 'Number of items purchased.', 'invoicing' ),
585
					'type'        => 'integer',
586
					'context'     => array( 'view' ),
587
					'readonly'    => true,
588
				),
589
				'refunded_items'      => array(
590
					'description' => __( 'Number of items refunded.', 'invoicing' ),
591
					'type'        => 'integer',
592
					'context'     => array( 'view' ),
593
					'readonly'    => true,
594
				),
595
				'total_tax'           => array(
596
					'description' => __( 'Total charged for taxes.', 'invoicing' ),
597
					'type'        => 'string',
598
					'context'     => array( 'view' ),
599
					'readonly'    => true,
600
				),
601
				'total_refunded_tax'  => array(
602
					'description' => __( 'Total refunded for taxes.', 'invoicing' ),
603
					'type'        => 'string',
604
					'context'     => array( 'view' ),
605
					'readonly'    => true,
606
				),
607
				'total_fees'          => array(
608
					'description' => __( 'Total fees charged.', 'invoicing' ),
609
					'type'        => 'string',
610
					'context'     => array( 'view' ),
611
					'readonly'    => true,
612
				),
613
				'total_refunds'       => array(
614
					'description' => __( 'Total of refunded invoices.', 'invoicing' ),
615
					'type'        => 'integer',
616
					'context'     => array( 'view' ),
617
					'readonly'    => true,
618
				),
619
				'net_refunds'         => array(
620
					'description' => __( 'Net of refunded invoices.', 'invoicing' ),
621
					'type'        => 'integer',
622
					'context'     => array( 'view' ),
623
					'readonly'    => true,
624
				),
625
				'total_discount'      => array(
626
					'description' => __( 'Total of discounts used.', 'invoicing' ),
627
					'type'        => 'integer',
628
					'context'     => array( 'view' ),
629
					'readonly'    => true,
630
				),
631
				'totals'              => array(
632
					'description' => __( 'Totals.', 'invoicing' ),
633
					'type'        => 'array',
634
					'items'       => array(
635
						'type' => 'array',
636
					),
637
					'context'     => array( 'view' ),
638
					'readonly'    => true,
639
				),
640
				'interval'            => array(
641
					'description' => __( 'Number of months/days in the report period.', 'invoicing' ),
642
					'type'        => 'integer',
643
					'context'     => array( 'view' ),
644
					'readonly'    => true,
645
				),
646
				'previous_range'      => array(
647
					'description' => __( 'The previous report period.', 'invoicing' ),
648
					'type'        => 'array',
649
					'items'       => array(
650
						'type' => 'string',
651
					),
652
					'context'     => array( 'view' ),
653
					'readonly'    => true,
654
				),
655
				'grouped_by'          => array(
656
					'description' => __( 'The period used to group the totals.', 'invoicing' ),
657
					'type'        => 'string',
658
					'context'     => array( 'view' ),
659
					'enum'        => array( 'day', 'month' ),
660
					'readonly'    => true,
661
				),
662
				'currency'            => array(
663
					'description' => __( 'The default store currency.', 'invoicing' ),
664
					'type'        => 'string',
665
					'context'     => array( 'view' ),
666
					'readonly'    => true,
667
				),
668
				'currency_symbol'     => array(
669
					'description' => __( 'The default store currency symbol.', 'invoicing' ),
670
					'type'        => 'string',
671
					'context'     => array( 'view' ),
672
					'readonly'    => true,
673
				),
674
				'currency_position'   => array(
675
					'description' => __( 'The default store currency position.', 'invoicing' ),
676
					'type'        => 'string',
677
					'context'     => array( 'view' ),
678
					'readonly'    => true,
679
				),
680
				'decimal_places'      => array(
681
					'description' => __( 'The default store decimal places.', 'invoicing' ),
682
					'type'        => 'string',
683
					'context'     => array( 'view' ),
684
					'readonly'    => true,
685
				),
686
				'thousands_sep'       => array(
687
					'description' => __( 'The default store thousands separator.', 'invoicing' ),
688
					'type'        => 'string',
689
					'context'     => array( 'view' ),
690
					'readonly'    => true,
691
				),
692
				'decimals_sep'        => array(
693
					'description' => __( 'The default store decimals separator.', 'invoicing' ),
694
					'type'        => 'string',
695
					'context'     => array( 'view' ),
696
					'readonly'    => true,
697
				),
698
			),
699
		);
700
701
		return $this->add_additional_fields_schema( $schema );
702
703
	}
704
705
}
706