[Back] <?php
/*
* Copyright (c) 2023 LatePoint LLC. All rights reserved.
*/
class OsOrdersHelper {
/**
* @param $order_item_id
* @param $service_id
*
* @return OsBookingModel[]
*/
public static function get_bookings_for_order_item( $order_item_id, $service_id = false, array $only_statuses = [] ): array {
$bookings = new OsBookingModel();
if ( $service_id ) {
$bookings = $bookings->where( [ 'service_id' => $service_id ] );
}
if ( ! empty( $only_statuses ) ) {
$bookings = $bookings->where( [ 'status' => $only_statuses ] );
}
$bookings = $bookings->where( [ 'order_item_id' => $order_item_id ] )->order_by( 'start_datetime_utc asc' )->get_results_as_models();
return $bookings;
}
public static function quick_order_btn_html( $order_id = false, $params = array() ) {
$html = '';
if ( $order_id ) {
$params['id'] = $order_id;
}
$route = OsRouterHelper::build_route_name( 'orders', 'quick_edit' );
$params_str = http_build_query( $params );
$html = 'data-os-params="' . esc_attr( $params_str ) . '"
data-os-action="' . esc_attr( $route ) . '"
data-os-output-target="side-panel"
data-os-after-call="latepoint_init_quick_order_form"';
return $html;
}
public static function get_order_statuses_list() {
$statuses = [
LATEPOINT_ORDER_STATUS_OPEN => __( 'Open', 'latepoint' ),
LATEPOINT_ORDER_STATUS_CANCELLED => __( 'Cancelled', 'latepoint' ),
LATEPOINT_ORDER_STATUS_COMPLETED => __( 'Completed', 'latepoint' )
];
/**
* Get list of statuses for orders
*
* @param {array} $statuses array of order status codes
* @returns {array} The filtered array of status codes
*
* @since 5.0.0
* @hook latepoint_order_statuses
*
*/
return apply_filters( 'latepoint_order_statuses', $statuses );
}
public static function bundle_services_and_booked_count_for_order_item_id( int $order_item_id ): array {
$order_item = new OsOrderItemModel( $order_item_id );
$bundle_services = [];
if ( $order_item->is_bundle() ) {
$bundle = $order_item->build_original_object_from_item_data();
$bundle_services = $bundle->get_services( $order_item_id );
}
return $bundle_services;
}
public static function get_items_for_order_id( $order_id ) {
$order_items = new OsOrderItemModel();
return $order_items->where( [ 'order_id' => $order_id ] )->get_results_as_models();
}
public static function create_order_item_from_cart_item( OsCartItemModel $cart_item ): OsOrderItemModel {
$order_item = new OsOrderItemModel();
$order_item->variant = $cart_item->variant;
$order_item->item_data = $cart_item->item_data;
$order_item->total = $cart_item->get_total();
$order_item->subtotal = $cart_item->get_subtotal();
$order_item->coupon_code = $cart_item->get_coupon_code();
$order_item->coupon_discount = $cart_item->get_coupon_discount();
$order_item->tax_total = $cart_item->get_tax_total();
return $order_item;
}
public static function get_fulfillment_statuses_list(): array {
$statuses = [
LATEPOINT_ORDER_FULFILLMENT_STATUS_NOT_FULFILLED => __( 'Not Fulfilled', 'latepoint' ),
LATEPOINT_ORDER_FULFILLMENT_STATUS_FULFILLED => __( 'Fulfilled', 'latepoint' ),
LATEPOINT_ORDER_FULFILLMENT_STATUS_PARTIALLY_FULFILLED => __( 'Partially Fulfilled', 'latepoint' )
];
/**
* Get list of fulfillment statuses for orders
*
* @param {array} $statuses array of order fulfillment status codes
* @returns {array} The filtered array of fulfillment status codes
*
* @since 5.0.0
* @hook latepoint_order_fulfillment_statuses
*
*/
return apply_filters( 'latepoint_order_fulfillment_statuses', $statuses );
}
public static function get_order_payment_statuses_list(): array {
$statuses = [
LATEPOINT_ORDER_PAYMENT_STATUS_NOT_PAID => __( 'Not Paid', 'latepoint' ),
LATEPOINT_ORDER_PAYMENT_STATUS_PARTIALLY_PAID => __( 'Partially Paid', 'latepoint' ),
LATEPOINT_ORDER_PAYMENT_STATUS_FULLY_PAID => __( 'Fully Paid', 'latepoint' ),
LATEPOINT_ORDER_PAYMENT_STATUS_PROCESSING => __( 'Processing', 'latepoint' ),
];
/**
* Get list of fulfillment statuses for orders
*
* @param {array} $statuses array of order payment status codes
* @returns {array} The filtered array of payment status codes
*
* @since 5.0.0
* @hook latepoint_order_payment_statuses
*
*/
return apply_filters( 'latepoint_order_payment_statuses', $statuses );
}
public static function get_default_order_status(): string {
$status = LATEPOINT_ORDER_STATUS_OPEN;
/**
* Get default order status
*
* @param {string} $status a default order status
* @returns {string} filtered status
*
* @since 5.0.0
* @hook latepoint_get_default_order_status
*
*/
return apply_filters( 'latepoint_get_default_order_status', $status );
}
public static function get_nice_order_payment_status_name( $status ) {
$statuses_list = OsOrdersHelper::get_order_payment_statuses_list();
if ( $status && isset( $statuses_list[ $status ] ) ) {
return $statuses_list[ $status ];
} else {
return __( 'Undefined Status', 'latepoint' );
}
}
public static function get_nice_order_status_name( $status ) {
$statuses_list = OsOrdersHelper::get_order_statuses_list();
if ( $status && isset( $statuses_list[ $status ] ) ) {
return $statuses_list[ $status ];
} else {
return __( 'Undefined Status', 'latepoint' );
}
}
public static function get_nice_order_fulfillment_status_name( $status ) {
$statuses_list = OsOrdersHelper::get_fulfillment_statuses_list();
if ( $status && isset( $statuses_list[ $status ] ) ) {
return $statuses_list[ $status ];
} else {
return __( 'Undefined Status', 'latepoint' );
}
}
public static function unfold_price_breakdown_row( $rows ) {
$readable_price_breakdown = [];
foreach ( $rows as $row ) {
if ( empty( $row ) ) {
continue;
}
if ( ! empty( $row['heading'] ) && ! empty( $row['items'] ) ) {
$readable_price_breakdown = array_merge( $readable_price_breakdown, self::unfold_price_breakdown_row( $row['items'] ) );
} elseif ( ! empty( $row['label'] ) ) {
$label = $row['label'];
if ( ! empty( $row['note'] ) ) {
$label .= ' ' . $row['note'];
}
if ( ! empty( $row['badge'] ) ) {
$label .= ' (' . $row['badge'] . ')';
}
$readable_price_breakdown[ $label ] = $row['raw_value'] * 1;
} else {
$readable_price_breakdown = array_merge( $readable_price_breakdown, self::unfold_price_breakdown_row( $row ) );
}
}
return $readable_price_breakdown;
}
public static function generate_confirmation_message( OsOrderModel $order ): string {
$html = '<div class="summary-status-wrapper summary-status-style-' . esc_attr( OsStepsHelper::get_step_setting_value( 'confirmation', 'order_confirmation_message_style', 'green' ) ) . '">
<div class="summary-status-inner">
<div class="ss-icon"></div>
<div class="ss-title">' . OsStepsHelper::get_step_setting_value( 'confirmation', 'order_confirmation_message_title', esc_html__( 'Appointment Confirmed', 'latepoint' ) ) . '</div>
<div class="ss-description">' . OsStepsHelper::get_step_setting_value( 'confirmation', 'order_confirmation_message_content', esc_html__( 'We look forward to seeing you.', 'latepoint' ) ) . '</div>
<div class="ss-confirmation-number"><span>' . esc_html__( 'Order #', 'latepoint' ) . '</span><strong>' . esc_html( $order->confirmation_code ) . '</strong></div>
</div>
</div>';
return $html;
}
public static function generate_direct_manage_order_url( OsOrderModel $order, string $for, string $action = 'show' ): string {
if ( ! in_array( $for, [ 'agent', 'customer' ] ) ) {
return '';
}
$actions = [ 'show', 'list_payments', 'print' ];
if ( ! in_array( $action, $actions ) ) {
$action = $actions[0];
}
$key = $order->get_key_to_manage_for( $for );
$url = OsRouterHelper::build_admin_post_link( [ 'manage_order_by_key', $action ], [ 'key' => $key ] );
return $url;
}
public static function get_order_id_and_manage_ability_by_key( string $key ) {
$order_id = OsMetaHelper::get_order_id_by_meta_value( "key_to_manage_for_agent", $key );
if ( $order_id ) {
return [ 'order_id' => $order_id, 'for' => 'agent' ];
}
$order_id = OsMetaHelper::get_order_id_by_meta_value( "key_to_manage_for_customer", $key );
if ( $order_id ) {
return [ 'order_id' => $order_id, 'for' => 'customer' ];
}
return false;
}
public static function create_booking_object_from_booking_data_form( array $params ): OsBookingModel {
$booking = new OsBookingModel();
if ( ! empty( $params['item_data'] ) ) {
$item_data = json_decode( base64_decode( $params['item_data'] ), true );
$booking->set_data( $item_data );
} else {
$filtered_params = $params;
// input fields are formatted in customer preferred format, we need to convert that to database format Y-m-d
$filtered_params['start_date'] = OsTimeHelper::reformat_date_string( $params['start_date_formatted'], OsSettingsHelper::get_date_format(), 'Y-m-d' );
if ( isset( $params['start_time']['formatted_value'] ) ) {
$start_ampm = isset( $params['start_time']['ampm'] ) ? $params['start_time']['ampm'] : false;
$filtered_params['start_time'] = OsTimeHelper::convert_time_to_minutes( $params['start_time']['formatted_value'], $start_ampm );
}
// set custom end time/date if it was passed in params
if ( isset( $params['end_time']['formatted_value'] ) ) {
$end_ampm = isset( $params['end_time']['ampm'] ) ? $params['end_time']['ampm'] : false;
$filtered_params['end_time'] = OsTimeHelper::convert_time_to_minutes( $params['end_time']['formatted_value'], $end_ampm );
if ( $filtered_params['end_time'] <= $filtered_params['start_time'] ) {
// it's next day
$date_obj = new OsWpDateTime( $filtered_params['start_date'] );
$filtered_params['end_date'] = $date_obj->modify( '+1 day' )->format( 'Y-m-d' );
} else {
$filtered_params['end_date'] = $filtered_params['start_date'];
}
}
$booking->set_data( $filtered_params );
$booking->set_utc_datetimes();
}
return $booking;
}
public static function loading_tile_for_order_item( string $order_item_id ) {
return '<div class="order-item-temp-holder" data-order-item-id="' . $order_item_id . '"><div class="oit-avatar"></div><div class="oit-main-info"><div class="oit-title"></div><div class="oit-sub-title"></div></div></div>';
}
public static function booking_data_form_for_order_item_id( string $order_item_id, OsBookingModel $booking, string $order_item_variant = LATEPOINT_ITEM_VARIANT_BOOKING, bool $is_folded = true ): string {
$services = OsServiceHelper::get_allowed_active_services();
$agents = OsAgentHelper::get_allowed_active_agents();
$order_item_id = empty( $order_item_id ) ? OsUtilHelper::generate_form_id() : $order_item_id;
$extra_css_class = $is_folded ? 'is-folded' : 'is-unfolded';
$html = '';
$html = '<div class="order-item-booking-data-form-wrapper order-item-booking-data-variant-' . $order_item_variant . ' ' . $extra_css_class . '"
data-order-item-variant="' . $order_item_variant . '"
data-order-item-id="' . $order_item_id . '"
data-booking-id="' . $booking->get_form_id() . '">';
$html .= self::loading_tile_for_order_item( $order_item_id );
switch ( $order_item_variant ) {
case LATEPOINT_ITEM_VARIANT_BOOKING:
$html .= OsOrdersHelper::generate_order_item_pill_for_booking( $booking, $order_item_id );
break;
case LATEPOINT_ITEM_VARIANT_BUNDLE:
$html .= OsOrdersHelper::generate_order_item_pill_for_bundle_booking( $booking, $order_item_id );
break;
}
$html .= '<div class="order-booking-data-heading">
<div class="fold-order-item-wrapper fold-order-item-booking-data-form-btn">
<div class="fold-order-item-icon">
<i class="latepoint-icon latepoint-icon-chevron-up"></i>
</div>
<div class="ob-label">' . ( $booking->is_new_record() ? __( 'New Booking', 'latepoint' ) : __( 'Edit Booking', 'latepoint' ) ) . '</div>
</div>
<div class="remove-order-item-new-booking-btn remove-order-item-btn" data-os-prompt="' . __( 'Are you sure you want to remove this booking from the order?', 'latepoint' ) . '">
<i class="latepoint-icon latepoint-icon-trash1"></i>
</div>
</div>';
$html .= '<div class="order-item-booking-data-form-inner">';
$html .= OsFormHelper::hidden_field( 'order_items[' . $order_item_id . '][variant]', $order_item_variant );
ob_start();
include( LATEPOINT_VIEWS_ABSPATH . 'bookings/_booking_data.php' );
$html .= ob_get_clean();
$html .= '</div>';
$html .= '</div>';
return $html;
}
public static function get_orders_for_select() : array {
$order = new OsOrderModel();
$order = $order->order_by( 'id desc' )->set_limit( 100 )->get_results_as_models();
$order_options = [];
foreach ( $order as $order ) {
$name = $order->customer->full_name . ' [' . $order->confirmation_code . ' : ' . $order->id . ']';
$order_options[] = [ 'value' => $order->id, 'label' => esc_html( $name ) ];
}
return $order_options;
}
public static function generate_order_item_pill_for_bundle( OsBundleModel $bundle, $order_item_id = false, $preselected_booking_id = false ): string {
$html = '';
$order_item_form_id = $order_item_id ? $order_item_id : OsUtilHelper::generate_form_id();
$html .= '<div class="order-item-pill order-item-pill-variant-bundle" data-order-item-id="' . $order_item_form_id . '">';
$html .= '<input name="order_items[' . $order_item_form_id . '][id]" class="order_item_id" value="' . $order_item_form_id . '" type="hidden"/>';
$html .= '<input name="order_items[' . $order_item_form_id . '][variant]" value="' . LATEPOINT_ITEM_VARIANT_BUNDLE . '" type="hidden"/>';
$html .= '<input name="order_items[' . $order_item_form_id . '][item_data]" class="order_item_item_data" value="' . base64_encode( wp_json_encode( $bundle->generate_params_for_booking_form() ) ) . '" type="hidden"/>';
$html .= '<div class="order-item-pill-inner">';
$html .= '<div class="order-item-remove-btn remove-order-item-btn"
data-os-prompt="' . __( 'Are you sure you want to remove this item from the order? All associated appointments will be removed as well.', 'latepoint' ) . '"></div>';
$html .= OsBundlesHelper::generate_order_summary_for_bundle( $bundle, $order_item_form_id, $preselected_booking_id );
$html .= '<div class="bundle-icon"><i class="latepoint-icon latepoint-icon-chevron-down"></i></div>';
$html .= '</div>';
$html .= '<div class="order-item-shadow"></div><div class="order-item-shadow"></div>';
$html .= '</div>';
return $html;
}
public static function generate_order_item_pill_for_booking( OsBookingModel $booking, $order_item_id = false ): string {
$html = '';
$order_item_form_id = $order_item_id ? $order_item_id : OsUtilHelper::generate_form_id();
$is_past = ( ! $booking->is_upcoming() ) ? 'is-past' : '';
$html .= '<div class="order-item-pill order-item-pill-variant-' . LATEPOINT_ITEM_VARIANT_BOOKING . ' ' . $is_past . ' status-' . $booking->status . '" data-order-item-id="' . $order_item_form_id . '">';
$html .= '<input name="order_items[' . $order_item_form_id . '][id]" class="order_item_id" value="' . $order_item_form_id . '" type="hidden"/>';
$html .= '<input name="order_items[' . $order_item_form_id . '][variant]" value="' . LATEPOINT_ITEM_VARIANT_BOOKING . '" type="hidden"/>';
$html .= '<div class="order-item-pill-inner">';
if($booking->recurrence_id){
$html.= '<div class="order-item-pill-recurring-mark"><div class="popover-message">'.esc_html__('Part of recurring sequence', 'latepoint').'</div><i class="latepoint-icon latepoint-icon-refresh"></i></div>';
}
$html .= '<div class="order-item-remove-btn remove-order-item-btn"
data-os-prompt="' . __( 'Are you sure you want to remove this item from the order?', 'latepoint' ) . '"></div>';
$html .= '<div class="booking-item-status-pill"></div>';
$html .= OsBookingHelper::generate_summary_for_booking( $booking, false, 'agent' );
$html .= '<div class="os-avatar-w" style="background-image: url(' . ( ( $booking->agent->avatar_image_id ) ? $booking->agent->get_avatar_url() : '' ) . ')">';
if ( ! $booking->agent->avatar_image_id ) {
$html .= '<div class="os-avatar"><span>' . $booking->agent->get_initials() . '</span></div>';
}
$html .= '</div>';
$html .= '</div>';
$html .= '</div>';
return $html;
}
public static function generate_order_item_pill_for_bundle_booking( OsBookingModel $booking, $order_item_id ): string {
$is_past = ( ! $booking->is_upcoming() ) ? 'is-past' : '';
$html = '<div class="bundle-booking-item-pill ' . $is_past . ' status-' . $booking->status . '">';
$html .= '<div class="bundle-booking-item-pill-inner">';
$html .= '<div class="booking-item-status-pill"></div>';
$html .= '<div class="bib-datetime">' . $booking->get_nice_start_datetime() . '</div>';
$html .= '</div>';
$html .= '</div>';
return $html;
}
public static function generate_booking_block_for_bundle_order_item( OsBookingModel $booking, $order_item_id, bool $is_booked = true, $is_preselected = false ): string {
$html = '';
$is_booked_css = $is_booked ? 'is-booked' : '';
$is_preselected_css = ( $is_preselected ? 'is-preselected' : '' );
$html .= '<div class="order-item-variant-bundle-booking ' . $is_booked_css . ' ' . $is_preselected_css . '"
data-order-item-variant="' . LATEPOINT_ITEM_VARIANT_BUNDLE . '"
data-order-item-id="' . $order_item_id . '"
data-booking-id="' . $booking->get_form_id() . '">';
$html .= '<div class="scheduled-bundle-booking">';
$html .= self::loading_tile_for_order_item( $order_item_id );
if ( $is_booked ) {
$html .= OsOrdersHelper::booking_data_form_for_order_item_id( $order_item_id, $booking, LATEPOINT_ITEM_VARIANT_BUNDLE, ! $is_preselected );
}
$html .= '</div>';
$html .= '<div class="unscheduled-bundle-booking">
<div class="booking-item-status-pill"></div>
<div class="bib-label">' . __( 'Schedule now', 'latepoint' ) . '</div>
<input name="order_items[' . $order_item_id . '][unscheduled_bookings][' . $booking->get_form_id() . '][item_data]" class="unscheduled_booking_item_data" value="' . base64_encode( wp_json_encode( $booking->generate_params_for_booking_form() ) ) . '" type="hidden"/>
</div>';
$html .= '</div>';
return $html;
}
public static function generate_price_breakdown_from_params( array $price_breakdown_params ): array {
$price_breakdown_rows = [];
$allowed_keys = [ 'before_subtotal', 'after_subtotal' ];
foreach ( $allowed_keys as $key ) {
if ( ! empty( $price_breakdown_params[ $key ] ) ) {
foreach ( $price_breakdown_params[ $key ] as $row ) {
if ( ! empty( $row['items'] ) ) {
$group = [ 'heading' => '', 'items' => [], 'sub_items' => [] ];
if ( ! empty( $row['heading'] ) ) {
$group['heading'] = $row['heading'];
}
foreach ( $row['items'] as $item ) {
if ( isset( $item['value'] ) ) {
$item['raw_value'] = OsMoneyHelper::convert_amount_from_money_input_to_db_format( $item['value'] );
}
$group['items'][] = $item;
}
if ( ! empty( $row['sub_items'] ) ) {
foreach ( $row['sub_items'] as $sub_item ) {
if ( isset( $sub_item['value'] ) ) {
$sub_item['raw_value'] = OsMoneyHelper::convert_amount_from_money_input_to_db_format( $sub_item['value'] );
}
$group['sub_items'][] = $sub_item;
}
}
$price_breakdown_rows[ $key ][] = $group;
} else {
if ( isset( $row['value'] ) ) {
$row['raw_value'] = OsMoneyHelper::convert_amount_from_money_input_to_db_format( $row['value'] );
}
$price_breakdown_rows[ $key ][] = $row;
}
}
}
}
return $price_breakdown_rows;
}
public static function create_order_item_object( array $order_items_param ): OsOrderItemModel {
$order_item_model = new OsOrderItemModel();
$order_item_model->variant = $order_items_param['variant'];
if ( $order_item_model->is_bundle() ) {
$order_item_model->item_data = base64_decode( $order_items_param['item_data'] );
} else {
// it's a booking variant - so there is only one booking in the array, but still loop for ease of use
foreach ( $order_items_param['bookings'] as $booking_params ) {
$booking = OsOrdersHelper::create_booking_object_from_booking_data_form( $booking_params );
$order_item_model->item_data = $booking->generate_item_data();
}
}
return $order_item_model;
}
public static function generate_transactions_breakdown_html( OsOrderModel $order ): string {
$html = '';
$transactions = $order->get_transactions();
if ( $transactions ) {
$html .= '<div style="margin: 20px 0;">';
foreach ( $transactions as $transaction ) {
$html .= '<div style="margin-bottom: 10px;">';
$html .= '<div>' . esc_html__( 'Payment Portion: ', 'latepoint' ) . '<strong>' . $transaction->get_payment_portion_nice_name() . '</strong></div>';
$html .= '<div>' . esc_html__( 'Payment Amount: ', 'latepoint' ) . '<strong>' . OsMoneyHelper::format_price( $transaction->amount, true, false ) . '</strong></div>';
$html .= '</div>';
}
$html .= '</div>';
} else {
$html .= esc_html__( 'No transactions found.', 'latepoint' );
}
return $html;
}
public static function generate_summary_breakdown_html( OsOrderModel $order ): string {
ob_start();
OsPriceBreakdownHelper::output_price_breakdown( $order->generate_price_breakdown_rows(), true );
$html = ob_get_clean();
return $html;
}
public static function generate_order_items_html( OsOrderModel $order ) {
$html = '';
$order_items = $order->get_items();
$html .= '<table style="width: 100%;">';
$total_items = count( $order_items );
$i = 0;
foreach ( $order_items as $order_item ) {
$i ++;
$html .= '<tr>';
$data_style = ( $i < $total_items ) ? 'border-bottom: 1px solid #eee;' : '';
$html .= '<td style="' . $data_style . ' padding: 10px 0;">';
if ( $order_item->is_bundle() ) {
$bundle = $order_item->build_original_object_from_item_data();
$html .= '<div>' . $bundle->name . '</div>';
$bundle_services = $bundle->get_services();
foreach ( $bundle_services as $service ) {
$qty = $service->join_attributes['quantity'];
$qty_html = $qty > 1 ? ' [' . $qty . ']' : '';
$html .= '<div style="color: #999; font-size: 14px;">' . esc_html( $service->name . $qty_html ) . '</div>';
}
} else {
$booking = $order_item->build_original_object_from_item_data();
$html .= '<div style="font-weight: bold;">' . $booking->service->name . '</div>';
$html .= '<div>' . $booking->get_nice_start_datetime() . '</div>';
$html .= '<div>' . $booking->agent->get_full_name() . '</div>';
}
$html .= '</td>';
$html .= '</tr>';
}
$html .= '</table>';
return $html;
}
public static function extract_agent_emails( OsOrderModel $order ): string {
$to_emails = [];
$order_items = $order->get_items();
foreach ( $order_items as $order_item ) {
if ( $order_item->is_bundle() ) {
$bundle_bookings = OsOrdersHelper::get_bookings_for_order_item( $order_item->id );
foreach ( $bundle_bookings as $booking ) {
$to_emails[] = $booking->agent->get_full_name() . ' <' . $booking->agent->email . '>';
}
} else {
// booking
$booking = $order_item->build_original_object_from_item_data();
$to_emails[] = $booking->agent->get_full_name() . ' <' . $booking->agent->email . '>';
}
}
$to_emails = array_unique( $to_emails );
return implode( ', ', $to_emails );
}
public static function extract_agent_full_names( OsOrderModel $order ): string {
$full_names = [];
$order_items = $order->get_items();
foreach ( $order_items as $order_item ) {
if ( $order_item->is_bundle() ) {
$bundle_bookings = OsOrdersHelper::get_bookings_for_order_item( $order_item->id );
foreach ( $bundle_bookings as $booking ) {
$full_names[] = $booking->agent->get_full_name();
}
} else {
// booking
$booking = $order_item->build_original_object_from_item_data();
$full_names[] = $booking->agent->get_full_name();
}
}
$full_names = array_unique( $full_names );
return implode( ', ', $full_names );
}
/**
* Extract property by name from order. For example, location_id, agent_id...
* @param OsOrderModel $order
* @param string $property
*
* @return string
*/
public static function extract_property_by_name( OsOrderModel $order, string $property ): string {
$property_values = [];
$order_items = $order->get_items();
$property_map = [
'service_ids' => 'service_id',
'location_ids' => 'location_id',
'agent_ids' => 'agent_id',
'bundle_ids' => 'bundle_id'
];
if(empty($property_map[$property])){
return '';
}
$mapped_property = $property_map[$property];
foreach ( $order_items as $order_item ) {
if ( $order_item->is_bundle() ) {
if ($mapped_property == 'bundle_id') {
$property_values[] = $order_item->get_item_data_value_by_key( 'bundle_id' );
} else {
$bundle_bookings = OsOrdersHelper::get_bookings_for_order_item( $order_item->id );
$property_values = array_merge( $property_values, array_column( $bundle_bookings, $mapped_property ) );
}
} else {
$booking = $order_item->build_original_object_from_item_data();
if ( ! empty( $booking->$mapped_property ) ) {
$property_values[] = $booking->$mapped_property;
}
}
}
return implode( ',', array_unique( $property_values ) );
}
public static function check_if_order_invoices_paid_full_balance( $order_id ) {
$order = new OsOrderModel( $order_id );
$invoices = new OsInvoiceModel();
$paid_invoices = $invoices->where(['status' => LATEPOINT_INVOICE_STATUS_PAID, 'order_id' => $order_id])->get_results_as_models();
$total_paid = 0;
$updated = false;
foreach ( $paid_invoices as $invoice ) {
$total_paid += $invoice->charge_amount;
}
if($total_paid > 0){
$old_order = clone $order;
if($total_paid < $order->get_total()){
if($order->payment_status != LATEPOINT_ORDER_PAYMENT_STATUS_PARTIALLY_PAID){
$updated = $order->update_attributes(['payment_status' => LATEPOINT_ORDER_PAYMENT_STATUS_PARTIALLY_PAID]);
}
}else{
if($order->get_total() > 0 && $order->payment_status != LATEPOINT_ORDER_PAYMENT_STATUS_FULLY_PAID){
$updated = $order->update_attributes(['payment_status' => LATEPOINT_ORDER_PAYMENT_STATUS_FULLY_PAID]);
}
}
if($updated){
/**
* Order was updated
*
* @param {OsOrderModel} $order instance of order model after it was updated
* @param {OsOrderModel} $old_order instance of order model before it was updated
*
* @since 5.0.0
* @hook latepoint_order_updated
*
*/
do_action( 'latepoint_order_updated', $order, $old_order );
}
}
}
}