Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
80.00% covered (warning)
80.00%
32 / 40
87.50% covered (warning)
87.50%
7 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
Booking_Status_Breakdown_Controller
79.49% covered (warning)
79.49%
31 / 39
87.50% covered (warning)
87.50%
7 / 8
8.55
0.00% covered (danger)
0.00%
0 / 1
 get_report_key
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_report_label
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_data_endpoint
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_column_headers
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 format_row_for_csv
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 get_default_values
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 get_fields
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 calculate_pending_count
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * REST API Reports Booking Status Breakdown controller class.
4 *
5 * @package Automattic\Jetpack\PremiumAnalytics\Reports\Export\Exports
6 */
7
8declare( strict_types=1 );
9
10namespace Automattic\Jetpack\PremiumAnalytics\Reports\Export\Exports;
11
12defined( 'ABSPATH' ) || exit;
13
14use Automattic\Jetpack\PremiumAnalytics\Reports\Export\Abstract_Csv_Report_Controller;
15
16/**
17 * Booking Status Breakdown CSV Export Controller.
18 *
19 * Handles CSV exports for the Booking Status Breakdown report, supporting both
20 * single interval and comparison interval data.
21 *
22 * @since $$next-version$$
23 */
24class Booking_Status_Breakdown_Controller extends Abstract_Csv_Report_Controller {
25
26    /**
27     * Get the report key for this controller.
28     *
29     * @return string The report key.
30     */
31    public function get_report_key(): string {
32        return 'bookingstatusbreakdown';
33    }
34
35    /**
36     * Get the report label for this controller.
37     *
38     * @return string The report label.
39     */
40    public function get_report_label(): string {
41        return __( 'Booking Status Breakdown', 'jetpack-premium-analytics' );
42    }
43
44    /**
45     * Get the data endpoint for this controller.
46     *
47     * @return string The data endpoint.
48     */
49    public function get_data_endpoint(): string {
50        return 'reports/bookings/by-date';
51    }
52
53    /**
54     * Get the column headers for this controller.
55     *
56     * @param string|null $interval Optional time interval for dynamic headers.
57     * @return array The column headers.
58     */
59    public function get_column_headers( ?string $interval = null ): array {
60        return array(
61            'time_interval' => $this->get_interval_label( $interval ),
62            'completed'     => __( 'Completed', 'jetpack-premium-analytics' ),
63            'pending'       => __( 'Pending', 'jetpack-premium-analytics' ),
64            'cancelled'     => __( 'Cancelled', 'jetpack-premium-analytics' ),
65        );
66    }
67
68    /**
69     * Format a row for CSV export.
70     *
71     * @param array       $item     The row data.
72     * @param string|null $interval Optional time interval for formatting.
73     * @return array The formatted row.
74     */
75    public function format_row_for_csv( array $item, ?string $interval = null ): array {
76        $defaults = $this->get_default_values();
77
78        return array(
79            'time_interval' => $this->format_time_interval( $item, $interval ),
80            'completed'     => (int) ( $item['status_complete'] ?? $defaults['status_complete'] ),
81            'pending'       => $this->calculate_pending_count( $item ),
82            'cancelled'     => (int) ( $item['status_cancelled'] ?? $defaults['status_cancelled'] ),
83        );
84    }
85
86    /**
87     * Get default values for missing data fields.
88     *
89     * @return array Array of field_name => default_value pairs.
90     */
91    public function get_default_values(): array {
92        return array(
93            'status_complete'             => 0,
94            'status_pending_confirmation' => 0,
95            'status_confirmed'            => 0,
96            'status_paid'                 => 0,
97            'status_unpaid'               => 0,
98            'status_cancelled'            => 0,
99        );
100    }
101
102    /**
103     * Get the list of API fields needed for this report.
104     *
105     * @return array
106     */
107    public function get_fields(): array {
108        // time_interval, date_start, and date_end are always returned by the
109        // API for time-series endpoints and do not need to be requested.
110        return array(
111            'status_complete',
112            'status_pending_confirmation',
113            'status_confirmed',
114            'status_paid',
115            'status_unpaid',
116            'status_cancelled',
117        );
118    }
119
120    /**
121     * Calculate the total pending count from various pending statuses.
122     *
123     * @param array $item The item data.
124     * @return int The total pending count.
125     */
126    private function calculate_pending_count( array $item ): int {
127        $defaults = $this->get_default_values();
128
129        $pending_count  = 0;
130        $pending_count += (int) ( $item['status_pending_confirmation'] ?? $defaults['status_pending_confirmation'] );
131        $pending_count += (int) ( $item['status_confirmed'] ?? $defaults['status_confirmed'] );
132        $pending_count += (int) ( $item['status_paid'] ?? $defaults['status_paid'] );
133        $pending_count += (int) ( $item['status_unpaid'] ?? $defaults['status_unpaid'] );
134
135        return $pending_count;
136    }
137}