| @@ -39,8 +39,9 @@ | ||
| 39 | 39 | 'pending' => 'pending', |
| 40 | 40 | 'pe_cancelled' => 'pending-cancel', |
| 41 | 41 | 'cancelled' => 'cancelled', |
| 42 | 42 | 'expired' => 'expired', |
| 43 | + 'completed' => 'completed', | |
| 43 | 44 | 'draft' => 'draft', |
| 44 | 45 | 'trash' => 'trash', |
| 45 | 46 | ); |
| 46 | 47 | $badge_mod = $badge_mod_map[ $subscrpt_status ] ?? 'expired'; |
| @@ -102,14 +103,26 @@ | ||
| 102 | 103 | $timing_per = (int) ( $subscription_data['schedule']['timing_per'] ?? 1 ); |
| 103 | 104 | $timing_option = $subscription_data['schedule']['timing_option'] ?? ''; |
| 104 | 105 | $period_label = ''; |
| 105 | 106 | if ( $timing_option ) { |
| 107 | + $timing_unit = ucfirst( Helper::get_typos( $timing_per, $timing_option ) ); | |
| 106 | 108 | $period_label = $timing_per > 1 |
| 107 | - ? $timing_per . ' ' . ucfirst( $timing_option ) . 's' | |
| 108 | - : ucfirst( $timing_option ); | |
| 109 | + ? $timing_per . ' ' . $timing_unit | |
| 110 | + : $timing_unit; | |
| 109 | 111 | } |
| 110 | 112 | |
| 111 | - $recurring_value = wc_price( (float) $subscription_data['price'], array( 'currency' => $order->get_currency() ) ); | |
| 113 | + // Net of any discount that carries into renewals, with the original struck through. | |
| 114 | + $recurring_totals = Helper::get_subscription_display_totals( $subscription_id, $order_item ); | |
| 115 | + $recurring_full = $recurring_totals['full_excl'] + $recurring_totals['tax'] + $recurring_totals['discount_tax']; | |
| 116 | + | |
| 117 | + $recurring_value = wc_price( (float) $recurring_totals['total'], array( 'currency' => $order->get_currency() ) ); | |
| 118 | + | |
| 119 | + if ( $recurring_totals['has_discount'] ) { | |
| 120 | + $recurring_value = '<del aria-hidden="true" class="subscrpt-summary__was">' | |
| 121 | + . wc_price( $recurring_full, array( 'currency' => $order->get_currency() ) ) | |
| 122 | + . '</del> ' . $recurring_value; | |
| 123 | + } | |
| 124 | + | |
| 112 | 125 | if ( $period_label ) { |
| 113 | 126 | $recurring_value .= '<span class="subscrpt-summary__unit"> / ' . esc_html( $period_label ) . '</span>'; |
| 114 | 127 | } |
| 115 | 128 | |
| @@ -123,14 +136,15 @@ | ||
| 123 | 136 | 'label' => __( 'Started', 'subscription' ), |
| 124 | 137 | 'value' => esc_html( wp_date( get_option( 'date_format' ), strtotime( $subscription_data['start_date'] ) ) ), |
| 125 | 138 | ); |
| 126 | 139 | } |
| 127 | -if ( ! empty( $subscription_data['next_date'] ) ) { | |
| 128 | - $summary_tiles[] = array( | |
| 129 | - 'label' => __( 'Next Payment', 'subscription' ), | |
| 130 | - 'value' => esc_html( wp_date( get_option( 'date_format' ), strtotime( $subscription_data['next_date'] ) ) ), | |
| 131 | - ); | |
| 132 | -} | |
| 140 | +// Always show the Next Payment tile; dash when there is no next date. | |
| 141 | +$summary_tiles[] = array( | |
| 142 | + 'label' => __( 'Next Payment', 'subscription' ), | |
| 143 | + 'value' => ! empty( $subscription_data['next_date'] ) | |
| 144 | + ? esc_html( wp_date( get_option( 'date_format' ), strtotime( $subscription_data['next_date'] ) ) ) | |
| 145 | + : '-', | |
| 146 | +); | |
| 133 | 147 | // Total payments is not part of $subscription_data; pull it from the info rows. |
| 134 | 148 | if ( isset( $rows['total_payments'] ) ) { |
| 135 | 149 | $summary_tiles[] = array( |
| 136 | 150 | 'label' => __( 'Total Payments', 'subscription' ), |
| @@ -151,8 +165,9 @@ | ||
| 151 | 165 | |
| 152 | 166 | // Plan card: product + qty render side by side; trial/signup fee as extra rows. |
| 153 | 167 | $plan_product = isset( $rows['product'] ) ? $rows['product']['value'] : ''; |
| 154 | 168 | $plan_qty = isset( $rows['quantity'] ) ? $rows['quantity']['value'] : ''; |
| 169 | +$plan_label = function_exists( 'subscrpt_get_subscription_plan_label' ) ? subscrpt_get_subscription_plan_label( $subscription_id ) : ''; | |
| 155 | 170 | $plan_extra = array(); |
| 156 | 171 | foreach ( array( 'product', 'quantity', 'signup_fee', 'trial', 'trial_period' ) as $plan_key ) { |
| 157 | 172 | $used_keys[ $plan_key ] = true; |
| 158 | 173 | if ( in_array( $plan_key, array( 'signup_fee', 'trial', 'trial_period' ), true ) && isset( $rows[ $plan_key ] ) ) { |
| @@ -254,8 +269,18 @@ | ||
| 254 | 269 | 'label' => ucfirst( str_replace( '-', ' ', (string) $history->type ) ), |
| 255 | 270 | ); |
| 256 | 271 | } |
| 257 | 272 | |
| 273 | +/* | |
| 274 | + * Sequence number within this subscription: 1 = first (parent) order, then each | |
| 275 | + * renewal in order. Helper::get_related_orders() returns newest-first, so the | |
| 276 | + * sequence counts down across the rendered rows. | |
| 277 | + */ | |
| 278 | +$related_count = count( $related_rows ); | |
| 279 | +foreach ( array_keys( $related_rows ) as $related_index ) { | |
| 280 | + $related_rows[ $related_index ]['seq'] = $related_count - $related_index; | |
| 281 | +} | |
| 282 | + | |
| 258 | 283 | // Reusable per-page + date toolbar for the paginated tables. Uses the admin |
| 259 | 284 | // advanced-select component; the date options are injected client-side from the |
| 260 | 285 | // table's date column. |
| 261 | 286 | $subscrpt_render_table_tools = function () { |
| @@ -276,32 +301,13 @@ | ||
| 276 | 301 | ), |
| 277 | 302 | ), |
| 278 | 303 | ) |
| 279 | 304 | ); |
| 280 | - wpsubs_render_adv_select( | |
| 305 | + wpsubs_render_per_page_select( | |
| 281 | 306 | array( |
| 282 | - 'name' => 'subscrpt_per_page', | |
| 283 | - 'value' => '10', | |
| 284 | - 'align' => 'right', | |
| 285 | - 'class' => 'subscrpt-filter-perpage', | |
| 286 | - 'options' => array( | |
| 287 | - array( | |
| 288 | - 'value' => '10', | |
| 289 | - 'label' => __( '10 / page', 'subscription' ), | |
| 290 | - ), | |
| 291 | - array( | |
| 292 | - 'value' => '20', | |
| 293 | - 'label' => __( '20 / page', 'subscription' ), | |
| 294 | - ), | |
| 295 | - array( | |
| 296 | - 'value' => '50', | |
| 297 | - 'label' => __( '50 / page', 'subscription' ), | |
| 298 | - ), | |
| 299 | - array( | |
| 300 | - 'value' => '100', | |
| 301 | - 'label' => __( '100 / page', 'subscription' ), | |
| 302 | - ), | |
| 303 | - ), | |
| 307 | + 'name' => 'subscrpt_per_page', | |
| 308 | + 'align' => 'right', | |
| 309 | + 'class' => 'subscrpt-filter-perpage', | |
| 304 | 310 | ) |
| 305 | 311 | ); |
| 306 | 312 | ?> |
| 307 | 313 | </div> |
| @@ -408,8 +414,16 @@ | ||
| 408 | 414 | <?php endif; ?> |
| 409 | 415 | </div> |
| 410 | 416 | <div class="subscrpt-plan-meta"> |
| 411 | 417 | <span class="subscrpt-plan-name"><?php echo $plan_product ? wp_kses_post( $plan_product ) : '—'; ?></span> |
| 418 | + <?php if ( $plan_label ) : ?> | |
| 419 | + <span class="subscrpt-plan-term"> | |
| 420 | + <?php | |
| 421 | + /* translators: %s: plan name */ | |
| 422 | + printf( esc_html__( 'Plan: %s', 'subscription' ), esc_html( $plan_label ) ); | |
| 423 | + ?> | |
| 424 | + </span> | |
| 425 | + <?php endif; ?> | |
| 412 | 426 | <span class="subscrpt-plan-qty"> |
| 413 | 427 | <?php |
| 414 | 428 | /* translators: %s: quantity */ |
| 415 | 429 | printf( esc_html__( 'Quantity: %s', 'subscription' ), $plan_qty ? wp_kses_post( $plan_qty ) : '1' ); |
| @@ -491,9 +505,9 @@ | ||
| 491 | 505 | </div> |
| 492 | 506 | <?php endif; ?> |
| 493 | 507 | |
| 494 | 508 | <!-- Related orders card --> |
| 495 | - <div class="subscrpt-card" data-subscrpt-paginate data-per-page="10" data-date-col="2"> | |
| 509 | + <div class="subscrpt-card" data-subscrpt-paginate data-per-page="10" data-date-col="3"> | |
| 496 | 510 | <div class="subscrpt-card__head subscrpt-card__head--toolbar"> |
| 497 | 511 | <span class="subscrpt-card__title"><?php esc_html_e( 'Related Orders', 'subscription' ); ?></span> |
| 498 | 512 | <?php if ( ! empty( $related_rows ) ) : ?> |
| 499 | 513 | <?php $subscrpt_render_table_tools(); ?> |
| @@ -502,13 +516,13 @@ | ||
| 502 | 516 | <?php if ( ! empty( $related_rows ) ) : ?> |
| 503 | 517 | <table class="wpsubs-table subscrpt-table--compact"> |
| 504 | 518 | <thead> |
| 505 | 519 | <tr> |
| 520 | + <th><?php esc_html_e( '#', 'subscription' ); ?></th> | |
| 506 | 521 | <th><?php esc_html_e( 'Order', 'subscription' ); ?></th> |
| 507 | 522 | <th><?php esc_html_e( 'Type', 'subscription' ); ?></th> |
| 508 | 523 | <th><?php esc_html_e( 'Date', 'subscription' ); ?></th> |
| 509 | 524 | <th><?php esc_html_e( 'Status', 'subscription' ); ?></th> |
| 510 | - <th><?php esc_html_e( 'Items', 'subscription' ); ?></th> | |
| 511 | 525 | <th><?php esc_html_e( 'Payment', 'subscription' ); ?></th> |
| 512 | 526 | <th><?php esc_html_e( 'Total', 'subscription' ); ?></th> |
| 513 | 527 | </tr> |
| 514 | 528 | </thead> |
| @@ -531,17 +545,19 @@ | ||
| 531 | 545 | $related_status = $related_order->get_status(); |
| 532 | 546 | $badge_class = $order_badge_map[ $related_status ] ?? 'draft'; |
| 533 | 547 | ?> |
| 534 | 548 | <tr> |
| 549 | + <td><span class="wpsubs-cell-title"><?php echo esc_html( number_format_i18n( $related['seq'] ) ); ?></span></td> | |
| 535 | 550 | <td> |
| 536 | - <a href="<?php echo esc_url( $related_order->get_edit_order_url() ); ?>" target="_blank" class="wpsubs-cell-title"> | |
| 537 | - #<?php echo esc_html( $related_order->get_order_number() ); ?> | |
| 538 | - </a> | |
| 551 | + <?php | |
| 552 | + // translators: %s: WooCommerce order number. | |
| 553 | + $order_id_label = sprintf( __( 'Order ID: #%s', 'subscription' ), $related_order->get_order_number() ); | |
| 554 | + ?> | |
| 555 | + <a href="<?php echo esc_url( $related_order->get_edit_order_url() ); ?>" target="_blank" class="wpsubs-cell-title" title="<?php echo esc_attr( $order_id_label ); ?>">#<?php echo esc_html( $related_order->get_order_number() ); ?></a> | |
| 539 | 556 | </td> |
| 540 | 557 | <td><?php echo esc_html( $related['label'] ); ?></td> |
| 541 | 558 | <td><?php echo esc_html( $related_order->get_date_created()->date( get_option( 'date_format' ) . ' - ' . get_option( 'time_format' ) ) ); ?></td> |
| 542 | 559 | <td><span class="wpsubs-badge wpsubs-badge--<?php echo esc_attr( $badge_class ); ?>"><?php echo esc_html( wc_get_order_status_name( $related_status ) ); ?></span></td> |
| 543 | - <td><?php echo esc_html( number_format_i18n( $related_order->get_item_count() ) ); ?></td> | |
| 544 | 560 | <td><?php echo $related_order->get_payment_method_title() ? esc_html( $related_order->get_payment_method_title() ) : '—'; ?></td> |
| 545 | 561 | <td><?php echo wp_kses_post( $related_order->get_formatted_order_total() ); ?></td> |
| 546 | 562 | </tr> |
| 547 | 563 | <?php endforeach; ?> |
| @@ -616,9 +632,9 @@ | ||
| 616 | 632 | <div> |
| 617 | 633 | <strong><?php esc_html_e( 'Upgrade to WPSubscription Pro', 'subscription' ); ?></strong> |
| 618 | 634 | <p><?php esc_html_e( 'Track subscription activity history, automation, and more.', 'subscription' ); ?></p> |
| 619 | 635 | </div> |
| 620 | - <a href="https://wpsubscription.co/" target="_blank" class="wpsubs-btn wpsubs-btn--primary wpsubs-btn--sm" rel="noreferrer noopener"> | |
| 636 | + <a href="https://wpsubscription.co/?utm_source=plugin&utm_medium=admin&utm_campaign=upgrade_pro" target="_blank" class="wpsubs-btn wpsubs-btn--primary wpsubs-btn--sm" rel="noreferrer noopener"> | |
| 621 | 637 | <?php esc_html_e( 'Upgrade to Pro', 'subscription' ); ?> |
| 622 | 638 | </a> |
| 623 | 639 | </div> |
| 624 | 640 | </div> |
| @@ -750,12 +766,13 @@ | ||
| 750 | 766 | |
| 751 | 767 | </div> |
| 752 | 768 | |
| 753 | 769 | <style> |
| 754 | -/* Page sits on WP admin gray; the cards are the white surfaces (matches list/health pages). */ | |
| 770 | +/* Page sits on WP admin gray; the cards are the white surfaces (matches list/health pages). | |
| 771 | + No `padding: 0` here — that overrode `.list-page`'s own `0 24px` and ran the | |
| 772 | + whole page flush into the admin menu and the right edge of the window. */ | |
| 755 | 773 | .wp-subscription-admin-content.list-page.subscrpt-subs-details { |
| 756 | 774 | background: transparent; |
| 757 | - padding: 0; | |
| 758 | 775 | border-radius: 0; |
| 759 | 776 | margin-top: 24px; |
| 760 | 777 | margin-bottom: 32px; |
| 761 | 778 | } |
| @@ -813,8 +830,14 @@ | ||
| 813 | 830 | font-size: 13px; |
| 814 | 831 | font-weight: 500; |
| 815 | 832 | color: var(--wpsubs-text-muted); |
| 816 | 833 | } |
| 834 | +.subscrpt-summary__value .subscrpt-summary__was { | |
| 835 | + font-size: 14px; | |
| 836 | + font-weight: 500; | |
| 837 | + color: var(--wpsubs-text-muted); | |
| 838 | + margin-right: 4px; | |
| 839 | +} | |
| 817 | 840 | |
| 818 | 841 | .subscrpt-detail-grid { |
| 819 | 842 | display: grid; |
| 820 | 843 | grid-template-columns: minmax(0, 1fr) 340px; |
| @@ -981,8 +1004,9 @@ | ||
| 981 | 1004 | .subscrpt-plan-name { font-size: 14px; font-weight: 600; color: var(--wpsubs-text); line-height: 1.3; } |
| 982 | 1005 | .subscrpt-plan-name a { color: var(--wpsubs-text); text-decoration: none; } |
| 983 | 1006 | .subscrpt-plan-name a:hover { color: var(--wpsubs-brand); } |
| 984 | 1007 | .subscrpt-plan-qty { font-size: 13px; color: var(--wpsubs-text-muted); } |
| 1008 | +.subscrpt-plan-term { font-size: 13px; color: var(--wpsubs-text-muted); } | |
| 985 | 1009 | .subscrpt-plan-col { display: flex; flex-direction: column; gap: 4px; min-width: 0; } |
| 986 | 1010 | .subscrpt-plan-label { |
| 987 | 1011 | font-size: 11px; |
| 988 | 1012 | font-weight: 600; |