From 28d7ed5dd5b68cf64118fe7b5bb17bc21d8f822f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=C3=BCel=20van=20der=20Steege?= Date: Wed, 5 Jun 2024 14:23:17 +0200 Subject: [PATCH 1/4] Allow partial periods in subscription phase period creation. --- src/Subscriptions/SubscriptionPhase.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Subscriptions/SubscriptionPhase.php b/src/Subscriptions/SubscriptionPhase.php index f963fbbe..def9a306 100644 --- a/src/Subscriptions/SubscriptionPhase.php +++ b/src/Subscriptions/SubscriptionPhase.php @@ -474,6 +474,7 @@ private function add_interval( $date, $times = 1 ) { * * @param DateTimeImmutable $start_date Start date. * @return SubscriptionPeriod|null + * @throws \Exception Throws exception on invalid date period. */ public function get_period( DateTimeImmutable $start_date = null ) { if ( null === $start_date ) { @@ -487,7 +488,11 @@ public function get_period( DateTimeImmutable $start_date = null ) { $end_date = $this->add_interval( $start_date ); if ( null !== $this->end_date && $end_date > $this->end_date ) { - return null; + $end_date = $this->end_date; + + if ( $start_date > $end_date ) { + throw new \Exception( 'The start date of a subscription period cannot be later than the end date.' ); + } } $period = new SubscriptionPeriod( $this, $start_date, $end_date, $this->get_amount() ); From 799d690751351584d12f7faa3826b4cb25f099bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=C3=BCel=20van=20der=20Steege?= Date: Wed, 5 Jun 2024 15:37:10 +0200 Subject: [PATCH 2/4] No longer use total periods in subscription alignment. --- src/Subscriptions/SubscriptionPhase.php | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Subscriptions/SubscriptionPhase.php b/src/Subscriptions/SubscriptionPhase.php index def9a306..0632c7ae 100644 --- a/src/Subscriptions/SubscriptionPhase.php +++ b/src/Subscriptions/SubscriptionPhase.php @@ -680,24 +680,23 @@ public static function align( self $phase, \DateTimeInterface $align_date ) { $alignment_phase = new self( $phase->get_subscription(), $start_date, $alignment_interval, $phase->get_amount() ); - $alignment_phase->set_total_periods( 1 ); - $alignment_phase->set_alignment_rate( $alignment_difference->days / $regular_difference->days ); - - // Remove one period from regular phase. - $total_periods = $phase->get_total_periods(); - - if ( null !== $total_periods ) { - $phase->set_total_periods( $total_periods - 1 ); - } + $alignment_end_date = $start_date->add( $alignment_interval ); - $alignment_end_date = $alignment_phase->get_end_date(); + $alignment_phase->set_end_date( $alignment_end_date ); + $alignment_phase->set_alignment_rate( $alignment_difference->days / $regular_difference->days ); - if ( null === $alignment_end_date ) { + if ( null === $alignment_phase->get_end_date() ) { throw new \Exception( 'The align phase should always end because this phase exists for one period.' ); } $phase->set_start_date( $alignment_end_date ); + if ( null !== $phase->end_date ) { + $end_date = $phase->end_date->add( $alignment_interval ); + + $phase->set_end_date( $end_date ); + } + return $alignment_phase; } } From 7d647a6b7a5ff51acd53bc4ee800ec2dd26fc9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=C3=BCel=20van=20der=20Steege?= Date: Wed, 5 Jun 2024 16:07:57 +0200 Subject: [PATCH 3/4] No longer use `$phase->set_total_periods()` for test payment subscription. --- src/Admin/AdminModule.php | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Admin/AdminModule.php b/src/Admin/AdminModule.php index e5f7f0f2..b1c13e11 100644 --- a/src/Admin/AdminModule.php +++ b/src/Admin/AdminModule.php @@ -533,28 +533,32 @@ public function maybe_test_payment() { $subscription->set_description( $description ); $subscription->set_lines( $payment->get_lines() ); + // Phase. + $phase = new SubscriptionPhase( + $subscription, + new DateTimeImmutable(), + new SubscriptionInterval( 'P' . $interval . Util::to_period( $interval_period ) ), + $price + ); + // Ends on. $total_periods = null; if ( \array_key_exists( 'pronamic_pay_ends_on', $_POST ) ) { + $total_periods = null; + switch ( $_POST['pronamic_pay_ends_on'] ) { case 'count': - $count = \filter_input( \INPUT_POST, 'pronamic_pay_ends_on_count', \FILTER_VALIDATE_INT ); - - if ( ! empty( $count ) ) { - $total_periods = $count; - } + $total_periods = (int) \filter_input( \INPUT_POST, 'pronamic_pay_ends_on_count', \FILTER_VALIDATE_INT ); break; case 'date': $end_date = \array_key_exists( 'pronamic_pay_ends_on_date', $_POST ) ? \sanitize_text_field( \wp_unslash( $_POST['pronamic_pay_ends_on_date'] ) ) : ''; if ( ! empty( $end_date ) ) { - $interval_spec = 'P' . $interval . Util::to_period( $interval_period ); - $period = new \DatePeriod( - new \DateTime(), - new \DateInterval( $interval_spec ), + $phase->get_start_date(), + $phase->get_interval(), new \DateTime( $end_date ) ); @@ -563,17 +567,13 @@ public function maybe_test_payment() { break; } - } - // Phase. - $phase = new SubscriptionPhase( - $subscription, - new DateTimeImmutable(), - new SubscriptionInterval( 'P' . $interval . Util::to_period( $interval_period ) ), - $price - ); + if ( null !== $total_periods ) { + $end_date = $phase->get_start_date()->add( $phase->get_interval()->multiply( $total_periods ) ); - $phase->set_total_periods( $total_periods ); + $phase->set_end_date( $end_date ); + } + } $subscription->add_phase( $phase ); From f9d41f14feb717496546b59b6d11f92a2835c079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=C3=BCel=20van=20der=20Steege?= Date: Wed, 5 Jun 2024 16:24:24 +0200 Subject: [PATCH 4/4] Remove unnecessary end date check. --- src/Subscriptions/SubscriptionPhase.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Subscriptions/SubscriptionPhase.php b/src/Subscriptions/SubscriptionPhase.php index 0632c7ae..b66eed7b 100644 --- a/src/Subscriptions/SubscriptionPhase.php +++ b/src/Subscriptions/SubscriptionPhase.php @@ -685,10 +685,6 @@ public static function align( self $phase, \DateTimeInterface $align_date ) { $alignment_phase->set_end_date( $alignment_end_date ); $alignment_phase->set_alignment_rate( $alignment_difference->days / $regular_difference->days ); - if ( null === $alignment_phase->get_end_date() ) { - throw new \Exception( 'The align phase should always end because this phase exists for one period.' ); - } - $phase->set_start_date( $alignment_end_date ); if ( null !== $phase->end_date ) {