PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / trunk
LatePoint – Calendar Booking Plugin for Appointments and Events vtrunk
5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / controllers / transactions_controller.php
latepoint / lib / controllers Last commit date
activities_controller.php 1 month ago auth_controller.php 3 months ago booking_form_settings_controller.php 3 months ago bookings_controller.php 10 hours ago calendars_controller.php 3 months ago carts_controller.php 10 hours ago controller.php 3 months ago customer_cabinet_controller.php 2 months ago customers_controller.php 10 hours ago dashboard_controller.php 2 months ago default_agent_controller.php 3 months ago events_controller.php 3 months ago form_fields_controller.php 1 week ago integrations_controller.php 3 months ago invoices_controller.php 10 hours ago manage_booking_by_key_controller.php 3 months ago manage_order_by_key_controller.php 3 months ago notifications_controller.php 3 months ago orders_controller.php 10 hours ago pro_controller.php 2 weeks ago process_jobs_controller.php 3 months ago processes_controller.php 1 month ago razorpay_connect_controller.php 1 week ago search_controller.php 3 months ago services_controller.php 3 months ago settings_controller.php 2 months ago steps_controller.php 2 weeks ago stripe_connect_controller.php 1 week ago support_topics_controller.php 3 months ago todos_controller.php 3 months ago transactions_controller.php 10 hours ago wizard_controller.php 1 week ago
transactions_controller.php
347 lines
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly.
4 }
5
6
7 if ( ! class_exists( 'OsTransactionsController' ) ) :
8
9
10 class OsTransactionsController extends OsController {
11
12 function __construct() {
13 parent::__construct();
14
15 $this->views_folder = LATEPOINT_VIEWS_ABSPATH . 'transactions/';
16 $this->vars['page_header'] = OsMenuHelper::get_menu_items_by_id( 'payments' );
17 $this->vars['breadcrumbs'][] = array(
18 'label' => __( 'Transactions', 'latepoint' ),
19 'link' => OsRouterHelper::build_link( OsRouterHelper::build_route_name( 'transactions', 'index' ) ),
20 );
21
22 $this->action_access['public'] = array_merge( $this->action_access['public'], [ 'view_receipt_by_key' ] );
23 }
24
25 public function edit_form() {
26 if ( filter_var( $this->params['id'], FILTER_VALIDATE_INT ) ) {
27 // existing
28 $transaction = new OsTransactionModel( $this->params['id'] );
29 if ( ! $transaction->is_new_record() && ! empty( $transaction->order_id ) ) {
30 $allowed_order = ( new OsOrderModel() )->where( [ LATEPOINT_TABLE_ORDERS . '.id' => absint( $transaction->order_id ) ] )->filter_allowed_records()->set_limit( 1 )->get_results_as_models();
31 if ( ! $allowed_order ) {
32 $this->send_json(
33 array(
34 'status' => LATEPOINT_STATUS_ERROR,
35 'message' => __( 'Not Allowed', 'latepoint' ),
36 )
37 );
38 }
39 }
40 } else {
41 // new
42 $transaction = new OsTransactionModel();
43 if ( filter_var( $this->params['order_id'], FILTER_VALIDATE_INT ) ) {
44 $transaction->order_id = $this->params['order_id'];
45 }
46 }
47 $this->vars['real_or_rand_id'] = ( $transaction->is_new_record() ) ? 'new_transaction_' . OsUtilHelper::random_text( 'alnum', 5 ) : $transaction->id;
48 $this->vars['transaction'] = $transaction;
49
50 $this->format_render( __FUNCTION__ );
51 }
52
53 public function view_receipt_by_key() {
54 $receipt_access_key = sanitize_text_field( $this->params['key'] );
55
56 if ( empty( $receipt_access_key ) ) {
57 echo __( 'Invalid Receipt Key', 'latepoint' );
58 exit;
59 }
60
61
62 $transaction = new OsTransactionModel();
63 $transaction = $transaction->where( [ 'access_key' => $receipt_access_key ] )->set_limit( 1 )->get_results_as_models();
64
65 if ( empty( $transaction ) ) {
66 echo __( 'Receipt not found', 'latepoint' );
67 exit;
68 }
69
70 if ( empty( $transaction->receipt_number ) ) {
71 $transaction->update_attributes( [ 'receipt_number' => $transaction->generate_receipt_number() ] );
72 }
73
74 $invoice = new OsInvoiceModel( $transaction->invoice_id );
75
76 $this->vars['invoice'] = $invoice;
77 $this->vars['transaction'] = $transaction;
78
79 $this->set_layout( 'clean' );
80 $this->format_render( __FUNCTION__ );
81 }
82
83 public function destroy() {
84 if ( filter_var( $this->params['id'], FILTER_VALIDATE_INT ) ) {
85 $this->check_nonce( 'destroy_transaction_' . $this->params['id'] );
86 $transaction = new OsTransactionModel( $this->params['id'] );
87 if ( ! $transaction->is_new_record() && ! empty( $transaction->order_id ) ) {
88 $allowed_order = ( new OsOrderModel() )->where( [ LATEPOINT_TABLE_ORDERS . '.id' => absint( $transaction->order_id ) ] )->filter_allowed_records()->set_limit( 1 )->get_results_as_models();
89 if ( ! $allowed_order ) {
90 $this->send_json(
91 array(
92 'status' => LATEPOINT_STATUS_ERROR,
93 'message' => __( 'Not Allowed', 'latepoint' ),
94 )
95 );
96 }
97 }
98 if ( $transaction->delete() ) {
99 $status = LATEPOINT_STATUS_SUCCESS;
100 $response_html = __( 'Transaction Removed', 'latepoint' );
101 } else {
102 $status = LATEPOINT_STATUS_ERROR;
103 $response_html = __( 'Error Removing Transaction', 'latepoint' );
104 }
105 } else {
106 $status = LATEPOINT_STATUS_ERROR;
107 $response_html = __( 'Error Removing Transaction', 'latepoint' );
108 }
109 if ( $this->get_return_format() == 'json' ) {
110 $this->send_json(
111 array(
112 'status' => $status,
113 'message' => $response_html,
114 )
115 );
116 }
117 }
118
119 /*
120 Index of transactions
121 */
122
123 public function index() {
124
125 $per_page = OsSettingsHelper::get_number_of_records_per_page();
126 $page_number = isset( $this->params['page_number'] ) ? $this->params['page_number'] : 1;
127
128 $this->vars['page_header'] = false;
129
130 $transactions = new OsTransactionModel();
131
132
133 // TABLE SEARCH FILTERS
134 $filter = $this->params['filter'] ?? false;
135 $query_args = [];
136 if ( $filter ) {
137 if ( ! empty( $filter['id'] ) ) {
138 $query_args['id'] = $filter['id'];
139 }
140 if ( ! empty( $filter['token'] ) ) {
141 $query_args['token'] = $filter['token'];
142 }
143 if ( ! empty( $filter['booking_id'] ) ) {
144 $query_args['booking_id'] = $filter['booking_id'];
145 }
146 if ( ! empty( $filter['processor'] ) ) {
147 $query_args['processor'] = $filter['processor'];
148 }
149 if ( ! empty( $filter['payment_method'] ) ) {
150 $query_args['payment_method'] = $filter['payment_method'];
151 }
152 if ( ! empty( $filter['amount'] ) ) {
153 $query_args['amount'] = $filter['amount'];
154 }
155 if ( ! empty( $filter['status'] ) ) {
156 $query_args['status'] = $filter['status'];
157 }
158 if ( ! empty( $filter['kind'] ) ) {
159 $query_args['kind'] = $filter['kind'];
160 }
161
162 if ( ! empty( $filter['customer']['full_name'] ) ) {
163 $transactions->select( LATEPOINT_TABLE_TRANSACTIONS . '.*, ' . LATEPOINT_TABLE_CUSTOMERS . '.first_name, ' . LATEPOINT_TABLE_CUSTOMERS . '.last_name' );
164 $transactions->join( LATEPOINT_TABLE_CUSTOMERS, [ 'id' => LATEPOINT_TABLE_TRANSACTIONS . '.customer_id' ] );
165
166 $query_args[ 'concat_ws(" ", ' . LATEPOINT_TABLE_CUSTOMERS . '.first_name,' . LATEPOINT_TABLE_CUSTOMERS . '.last_name) LIKE' ] = '%' . $filter['customer']['full_name'] . '%';
167 $this->vars['customer_name_query'] = $filter['customer']['full_name'];
168
169 }
170
171 if ( ! empty( $filter['created_at_from'] ) && ! empty( $filter['created_at_to'] ) ) {
172 $query_args['created_at >='] = $filter['created_at_from'] . ' 00:00:00';
173 $query_args['created_at <='] = $filter['created_at_to'] . ' 23:59:59';
174 }
175 }
176
177
178 // OUTPUT CSV IF REQUESTED
179 if ( isset( $this->params['download'] ) && $this->params['download'] == 'csv' ) {
180 $csv_filename = 'payments_' . OsUtilHelper::random_text() . '.csv';
181
182 header( 'Content-Type: text/csv' );
183 header( "Content-Disposition: attachment; filename={$csv_filename}" );
184
185 $labels_row = [
186 __( 'ID', 'latepoint' ),
187 __( 'Token', 'latepoint' ),
188 __( 'Order ID', 'latepoint' ),
189 __( 'Customer', 'latepoint' ),
190 __( 'Processor', 'latepoint' ),
191 __( 'Method', 'latepoint' ),
192 __( 'Amount', 'latepoint' ),
193 __( 'Status', 'latepoint' ),
194 __( 'Type', 'latepoint' ),
195 __( 'Date', 'latepoint' ),
196 ];
197
198
199 $transactions_data = [];
200 $transactions_data[] = $labels_row;
201
202
203 $transactions_arr = $transactions->where( $query_args )->filter_allowed_records()->get_results_as_models();
204
205 if ( $transactions_arr ) {
206 foreach ( $transactions_arr as $transaction ) {
207 $values_row = [
208 $transaction->id,
209 $transaction->token,
210 $transaction->order_id,
211 ( $transaction->customer_id ? $transaction->customer->full_name : 'n/a' ),
212 $transaction->processor,
213 $transaction->payment_method,
214 OsMoneyHelper::format_price( $transaction->amount, true, false ),
215 $transaction->status,
216 $transaction->kind,
217 $transaction->created_at,
218 ];
219 $values_row = apply_filters( 'latepoint_transaction_row_for_csv_export', $values_row, $transaction, $this->params );
220 $transactions_data[] = $values_row;
221 }
222 }
223
224 $transactions_data = apply_filters( 'latepoint_transactions_data_for_csv_export', $transactions_data, $this->params );
225 OsCSVHelper::array_to_csv( $transactions_data );
226 return;
227 }
228
229 if ( $query_args ) {
230 $transactions->where( $query_args );
231 }
232 $transactions->filter_allowed_records();
233
234
235 $count_transactions = clone $transactions;
236 $total_transactions = $count_transactions->count();
237
238 $transactions = $transactions->order_by( LATEPOINT_TABLE_TRANSACTIONS . '.created_at desc' )->set_limit( $per_page );
239 if ( $page_number > 1 ) {
240 $transactions = $transactions->set_offset( ( $page_number - 1 ) * $per_page );
241 }
242
243 $this->vars['transactions'] = $transactions->get_results_as_models();
244
245 $this->vars['total_transactions'] = $total_transactions;
246 $this->vars['current_page_number'] = $page_number;
247 $this->vars['per_page'] = $per_page;
248 $total_pages = ceil( $total_transactions / $per_page );
249 $this->vars['total_pages'] = $total_pages;
250
251 $this->vars['showing_from'] = ( ( $page_number - 1 ) * $per_page ) ? ( ( $page_number - 1 ) * $per_page ) : 1;
252 $this->vars['showing_to'] = min( $page_number * $per_page, $total_transactions );
253
254 $this->format_render(
255 [
256 'json_view_name' => '_table_body',
257 'html_view_name' => __FUNCTION__,
258 ],
259 [],
260 [
261 'total_pages' => $total_pages,
262 'showing_from' => $this->vars['showing_from'],
263 'showing_to' => $this->vars['showing_to'],
264 'total_records' => $total_transactions,
265 ]
266 );
267 }
268
269
270 public function refund_transaction() {
271 // Validate transaction ID.
272 if ( ! filter_var( $this->params['transaction_refund']['transaction_id'], FILTER_VALIDATE_INT ) ) {
273 $this->send_json(
274 array(
275 'status' => LATEPOINT_STATUS_ERROR,
276 'message' => esc_html__( 'Invalid Transaction', 'latepoint' ),
277 )
278 );
279 return;
280 }
281
282 // Verify nonce for refunding transaction.
283 $this->check_nonce( 'refund_transaction_' . $this->params['transaction_refund']['transaction_id'] );
284
285 $transaction = new OsTransactionModel( absint( $this->params['transaction_refund']['transaction_id'] ) );
286 if ( ! $transaction->is_new_record() && ! empty( $transaction->order_id ) ) {
287 $allowed_order = ( new OsOrderModel() )->where( [ LATEPOINT_TABLE_ORDERS . '.id' => absint( $transaction->order_id ) ] )->filter_allowed_records()->set_limit( 1 )->get_results_as_models();
288 if ( ! $allowed_order ) {
289 $this->send_json(
290 array(
291 'status' => LATEPOINT_STATUS_ERROR,
292 'message' => __( 'Not Allowed', 'latepoint' ),
293 )
294 );
295 }
296 }
297
298 try {
299 if ( empty( $transaction ) || ! $transaction->can_refund() ) {
300 throw new Exception( esc_html__( 'Invalid Transaction', 'latepoint' ) );
301 }
302
303 $refund_amount = ( $this->params['transaction_refund']['portion'] == 'custom' ) ? $this->params['transaction_refund']['custom_amount'] : ( $transaction->amount - $transaction->get_total_refunded_amount() );
304 $refund_amount = OsParamsHelper::sanitize_param( $refund_amount, 'money' );
305
306 if ( empty( $refund_amount ) || $refund_amount > $transaction->amount - $transaction->get_total_refunded_amount() ) {
307 throw new Exception( __( 'Invalid Refund Amount', 'latepoint' ) );
308 }
309
310 /**
311 * Process refund for different payment gateways
312 *
313 * @param {bool | OsTransactionRefundModel} $transaction_refund
314 * @param {OsTransactionModel} $transaction
315 * @param {array} $refund_amount
316 *
317 * @returns {OsTransactionRefundModel}
318 * @since 5.1.8
319 * @hook latepoint_process_refund
320 *
321 */
322 $transaction_refund = apply_filters( 'latepoint_process_refund', false, $transaction, $refund_amount );
323
324 if ( $transaction_refund ) {
325 $this->vars['transaction'] = new OsTransactionModel( $transaction->id ); # reload to get new refund info
326 $message = $this->render( LATEPOINT_VIEWS_ABSPATH . 'orders/_transaction_box', 'none' );
327 $this->send_json(
328 array(
329 'status' => LATEPOINT_STATUS_SUCCESS,
330 'message' => $message,
331 )
332 );
333 }
334 } catch ( Exception $e ) {
335 $this->send_json(
336 array(
337 'status' => LATEPOINT_STATUS_ERROR,
338 'message' => $e->getMessage(),
339 )
340 );
341 }
342 }
343 }
344
345
346 endif;
347