Skip to content

Commit

Permalink
CRM: 3433 - Additional HPOS tweaks (#36003)
Browse files Browse the repository at this point in the history
* Don't set up Woo Admin hooks if Woo isn't active

* Gather screens where we want to add metaboxes

* Don't set up local Woo hooks if Woo isn't active

* Add backslash to class lookup

* Coding standards

* Remove legacy condition

* Coding standards

* Simplify Woo subs code using wc_get_orders()

* Further simplify code

* Use proper date functions

* Add changelog

* Fix segment listview escape issue

* Update changelog

* Search all subscription statuses

* Ensure each email alias adds to the array
  • Loading branch information
tbradsha committed Feb 28, 2024
1 parent 69c0650 commit 1036cfc
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 175 deletions.
6 changes: 6 additions & 0 deletions projects/plugins/crm/changelog/fix-crm-3433-hpos-tweaks
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Significance: patch
Type: fixed

WooSync: No longer shows today as renewal date if subscription has no renewal date set.
WooSync: Modernize code.
Segments: Fix output if segment has an error.
6 changes: 3 additions & 3 deletions projects/plugins/crm/js/ZeroBSCRM.admin.listview.js
Original file line number Diff line number Diff line change
Expand Up @@ -2799,15 +2799,15 @@ function zeroBSCRMJS_listView_segment_added( dataLine ) {
* @param dataLine
*/
function zeroBSCRMJS_listView_segment_name( dataLine ) {
var name_str = dataLine.name;
var name_str = jpcrm.esc_html(dataLine.name);

// if any errors, attach an exclaimation mark
if ( typeof dataLine.error !== 'undefined' ) {
name_str += ' <i class="red exclamation triangle icon" title="' + dataLine.error + '"></i>';
name_str += ' <i class="red exclamation triangle icon" title="' + jpcrm.esc_attr(dataLine.error) + '"></i>';
}

var td =
'<td><a href="' + zeroBSCRMJS_listView_editURL( dataLine.id ) + '">' + jpcrm.esc_html(name_str) + '</a></td>';
'<td><a href="' + zeroBSCRMJS_listView_editURL( dataLine.id ) + '">' + name_str + '</a></td>';

return td;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,25 @@ private function debug( $str ){
/**
* Initialise Hooks
*/
private function init_hooks( ) {
private function init_hooks() {

// cron
add_action( 'jpcrm_woosync_sync', array( $this, 'cron_job' ) );

// Syncing based on WooCommerce hooks:
// add our cron task to the core crm cron monitor list
add_filter( 'jpcrm_cron_to_monitor', array( $this, 'add_cron_monitor' ) );

global $zbs;

// Abort if Woo isn't active.
if ( ! $zbs->woocommerce_is_active() ) {
return;
}

// Order changes:
add_action( 'woocommerce_order_status_changed', array( $this, 'add_update_from_woo_order' ), 1, 1 );
add_action( 'woocommerce_order_status_changed', array( $this, 'add_update_from_woo_order' ), 1, 1 );
add_action( 'woocommerce_process_shop_order_meta', array( $this, 'add_update_from_woo_order' ), 100, 1 );
add_action( 'woocommerce_deposits_create_order', array( $this, 'add_update_from_woo_order' ), 100, 1 );
add_action( 'woocommerce_deposits_create_order', array( $this, 'add_update_from_woo_order' ), 100, 1 );
if ( jpcrm_woosync_is_hpos_enabled() ) {
// These hooks are available as of Woo 7.1.0 and are required for HPOS.
add_action( 'woocommerce_before_trash_order', array( $this, 'woocommerce_order_trashed' ), 10, 1 );
Expand All @@ -152,14 +160,9 @@ private function init_hooks( ) {
}

// Catch WooCommerce customer address changes and update contact:
add_action( 'woocommerce_customer_save_address', array( $this, 'update_contact_address_from_wp_user' ), 10, 3 );

// add our cron task to the core crm cron monitor list
add_filter( 'jpcrm_cron_to_monitor', array( $this, 'add_cron_monitor' ) );

add_action( 'woocommerce_customer_save_address', array( $this, 'update_contact_address_from_wp_user' ), 10, 3 );
}


/**
* Setup cron schedule
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ public static function instance() {
* Initialise Hooks
*/
private function init_hooks() {
global $zbs;

// Abort if Woo isn't active.
if ( ! $zbs->woocommerce_is_active() ) {
return;
}

// Hook into Woo orders listview.
if ( jpcrm_woosync_is_hpos_enabled() ) {
Expand Down Expand Up @@ -137,20 +143,28 @@ public function render_orders_column_content( $column, $order_or_post_id ) {
* Add CRM meta boxes to Woo pages
*/
public function add_meta_boxes() {
if ( jpcrm_woosync_is_hpos_enabled() ) {
$screen = wc_get_page_screen_id( 'shop-order' );
} else {
$screen = array( 'shop_order', 'shop_subscription' );

// Gather Woo screens where we'll want to add metaboxes.
$screens_to_use = array();
$woo_screens = array( 'shop_order', 'shop_subscription' );
foreach ( $woo_screens as $woo_screen ) {
$potential_screen = wc_get_page_screen_id( $woo_screen );
if ( ! empty( $potential_screen ) ) {
$screens_to_use[] = $potential_screen;
}
}

add_meta_box(
'zbs_crm_contact',
__( 'CRM Contact', 'zero-bs-crm' ),
array( $this, 'render_woo_order_page_contact_box' ),
$screen,
'side',
'core'
);
// Currently if Woo is active we should at least have the orders page, but that could change.
if ( ! empty( $screens_to_use ) ) {
add_meta_box(
'zbs_crm_contact',
__( 'CRM Contact', 'zero-bs-crm' ),
array( $this, 'render_woo_order_page_contact_box' ),
$screens_to_use,
'side',
'core'
);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,12 @@ private function generate_bookings_tab_html( $object_id = -1 ){
*/
private function generate_subscriptions_tab_html( $object_id = -1 ) {

$contact_has_subscriptions = false;
$subscriptions = array();
if ( zeroBSCRM_getClientPortalUserID( $object_id ) > 0 ) {
// Retrieve any subs against the main email or aliases.
$subscriptions = $this->get_contact_subscriptions( $object_id );
$contact_has_subscriptions = ( 'success' === $subscriptions['message'] && count( $subscriptions['data'] ) > 0 );
$subscriptions = $this->get_contact_subscriptions( $object_id );
}
if ( ! $contact_has_subscriptions ) {
if ( count( $subscriptions ) === 0 ) {
return '<div class="ui message info blue"><i class="ui icon info circle"></i>' . __( 'This contact does not have any WooCommerce Subscriptions yet.', 'zero-bs-crm' ) . '</div>';
}

Expand All @@ -203,20 +202,19 @@ private function generate_subscriptions_tab_html( $object_id = -1 ) {
$html .= '</tr></thead>';
$html .= '<tbody>';

foreach ( $subscriptions['data'] as $k => $v ) {

$order = wc_get_order( $k );
foreach ( $subscriptions as $order_id ) {
$order = wc_get_order( $order_id );
$status = $order->get_status();
$date_created = $order->get_date_created();
$date_renew = $order->get_date( 'next_payment_date' );
$price = $order->get_formatted_order_total();
$name = '';
$sub_link = admin_url( "post.php?post={$k}&action=edit" );
$created = zeroBSCRM_date_i18n( zeroBSCRM_getDateFormat(), strtotime( $date_created ), true, false );
$next = zeroBSCRM_date_i18n( zeroBSCRM_getDateFormat(), strtotime( $date_renew ), true, false );
$sub_link = admin_url( "post.php?post={$order_id}&action=edit" );
$created = jpcrm_uts_to_date_str( strtotime( $date_created ) );
$next = jpcrm_uts_to_date_str( strtotime( $date_renew ) );

$html .= '<tr>';
$html .= '<td><a href="' . esc_url( $sub_link ) . '">' . $name . __( ' Subscription #', 'zero-bs-crm' ) . $k . '</a></td>';
$html .= '<td><a href="' . esc_url( $sub_link ) . '">' . $name . __( ' Subscription #', 'zero-bs-crm' ) . $order_id . '</a></td>';
$html .= '<td><span class="ui label ' . $status . '">' . $status . '</span></td>';
$html .= '<td>' . $price . '</td>';
$html .= '<td>' . $created . '</td>';
Expand Down Expand Up @@ -264,20 +262,20 @@ private function generate_memberships_tab_html( $object_id = -1 ) {
foreach ( $memberships as $membership ) {

// populate fields
$member_id = $membership->id;
$status = $this->display_membership_status( $membership->get_status() );
$name = $membership->plan->name;
$date_expires = $membership->get_end_date( 'Y-m-d H:i:s' );
$date_created = $membership->get_start_date();
$created = zeroBSCRM_date_i18n( zeroBSCRM_getDateFormat(), strtotime( $date_created ), true, false );
$member_id = $membership->id;
$status = $this->display_membership_status( $membership->get_status() );
$name = $membership->plan->name;
$date_expires = $membership->get_end_date( 'Y-m-d H:i:s' );
$date_created = $membership->get_start_date();
$created = jpcrm_uts_to_date_str( strtotime( $date_created ) );

if ( empty( $date_expires ) ) {

$expires = __( 'Never', 'zero-bs-crm' );

} else {

$expires = zeroBSCRM_date_i18n( zeroBSCRM_getDateFormat(), strtotime( $date_expires ), true, false );
$expires = jpcrm_uts_to_date_str( strtotime( $date_expires ) );

}

Expand Down Expand Up @@ -354,142 +352,56 @@ private function get_contact_memberships( $object_id = -1 ){
}
}

/**
* Retrieves any Woo Subscriptions against a contact
*
* @param int $object_id Contact ID.
*/
private function get_contact_subscriptions( $object_id = -1 ) {
$all_sub_statuses = array_keys( wcs_get_subscription_statuses() );

/**
* Retrieves any Woo Subscriptions against a contact
*
* @var int contactID
*/
private function get_contact_subscriptions( $object_id = -1 ){

$return = array();

if ( $object_id > 0 ){

$subscription_user_ids = array();
$subscription_email_ids = array();

// 1 - get the subscription IDs for the attached wp user (array_1)
$user_id = zeroBS_getCustomerWPID($object_id);
if ($user_id > 0){

$subscription_user_ids = \WCS_Customer_Store::instance()->get_users_subscription_ids( $user_id );

}

// 2 - find subs for all emails (inc aliases) #3.0.12+ of core
if ( function_exists( 'zeroBS_customerEmails' ) ){

// multi, inc aliases
$emails = zeroBS_customerEmails( $object_id );
if ( is_array( $emails ) ){

foreach ( $emails as $email ){

$subscription_ids = $this->get_subscriptions_by_email( $email );

// add any to the stack
if ( is_array( $subscription_ids ) ){

foreach ( $subscription_ids as $id ){

$subscription_email_ids[] = $id;

}

}

}

}


} else {

// subscription IDs for the main EMAIL (array_2)
$contact_email = zeroBS_customerEmail($object_id);
$subscription_email_ids = $this->get_subscriptions_by_email($contact_email);

}

// 3 - remove any duplicate IDs between array_1 and array_2
$subscription_ids = array_unique( array_merge( $subscription_user_ids, $subscription_email_ids ), SORT_REGULAR );

// 4 - get the subscriptions from the combined IDs
$return = array(
'data' => $this->get_subscriptions_by_id_array( $subscription_ids )
);

// 5 - return the new array of subscriptions
if ( count( $return['data'] ) > 0){

$return['message'] = 'success';

} else {

$return['message'] = 'notfound';

}

}

return $return;

}


/**
* Turns out that wcs_get_users_subscriptions runs from userIDs and we need a variant from email
*/
private function get_subscriptions_by_id_array( $subscription_ids ){

$subscriptions = array();
foreach ( $subscription_ids as $subscription_id ) {
$subscription = wcs_get_subscription( $subscription_id );

if ( $subscription ) {
$subscriptions[ $subscription_id ] = $subscription;
}
}

return $subscriptions;
$subscription_ids = array();

}
if ( $object_id > 0 ) {

// 1 - get the subscription IDs for the attached wp user
$user_id = zeroBS_getCustomerWPID( $object_id );
if ( $user_id > 0 ) {
$args = array(
'customer_id' => $user_id,
'status' => $all_sub_statuses,
'type' => 'shop_subscription',
'return' => 'ids',
);

/**
* Get subs by email
*/
private function get_subscriptions_by_email($email = ''){

if ( empty( $email ) ) {

return array();
$subscription_ids = wc_get_orders( $args );
}

}
// 2 - find subs for all emails (inc aliases)
$emails = zeroBS_customerEmails( $object_id );
if ( is_array( $emails ) ) {

foreach ( $emails as $email ) {
if ( empty( $email ) ) {
continue;
}

$args = array(
'billing_email' => $email,
'status' => $all_sub_statuses,
'type' => 'shop_subscription',
'return' => 'ids',
);

$subscription_ids_by_email = wc_get_orders( $args );
$subscription_ids = array_merge( $subscription_ids, $subscription_ids_by_email );
}
}

$query = new \WP_Query();

return $query->query( array(

'post_type' => 'shop_subscription',
'posts_per_page' => -1,
'post_status' => 'any',
'orderby' => array(
'date' => 'DESC',
'ID' => 'DESC',
),
'fields' => 'ids',
'no_found_rows' => true,
'ignore_sticky_posts' => true,
'meta_query' => array(
array(
'key' => '_billing_email',
'value' => $email,
),
),

));
// 3 - remove any duplicate IDs between array_1 and array_2
$subscription_ids = array_unique( $subscription_ids, SORT_REGULAR );
}

}
return $subscription_ids;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ function jpcrm_add_woo_jobs_to_system_assistant( $job_list ) {
* @return bool Defaults to false.
*/
function jpcrm_woosync_is_hpos_enabled() {
if ( class_exists( 'Automattic\WooCommerce\Utilities\OrderUtil' ) ) {
if ( class_exists( '\Automattic\WooCommerce\Utilities\OrderUtil' ) ) {
return \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();
}
return false;
Expand Down

0 comments on commit 1036cfc

Please sign in to comment.