PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / trunk
GiveWP – Donation Plugin and Fundraising Platform vtrunk
4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / Subscriptions / Actions / CalculateProjectedAnnualRevenue.php
give / src / Subscriptions / Actions Last commit date
CalculateProjectedAnnualRevenue.php 9 months ago GenerateNextRenewalForSubscription.php 3 years ago LoadSubscriptionAdminOptions.php 9 months ago LoadSubscriptionDetailsAssets.php 9 months ago LoadSubscriptionsListTableAssets.php 8 months ago
CalculateProjectedAnnualRevenue.php
104 lines
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Give\Subscriptions\Actions;
6
7 use DateTime;
8 use Exception;
9 use Give\DonationForms\DonationQuery;
10 use Give\Donations\ValueObjects\DonationStatus;
11 use Give\Donations\ValueObjects\DonationMetaKeys;
12 use Give\Framework\QueryBuilder\QueryBuilder;
13 use Give\Framework\Support\ValueObjects\Money;
14 use Give\Subscriptions\Models\Subscription;
15 use Give\Subscriptions\ValueObjects\SubscriptionPeriod;
16
17 /**
18 * Calculates the projected annual revenue for a subscription based on completed donations
19 * from the current year and estimated remaining donations until the end of the year.
20 *
21 * @since 4.8.0
22 */
23 class CalculateProjectedAnnualRevenue
24 {
25 /**
26 * Calculate the projected annual revenue for a subscription.
27 *
28 * @param Subscription $subscription
29 * @return Money
30 */
31 public function __invoke(Subscription $subscription): Money
32 {
33 try {
34 $currentYear = (int) date('Y');
35 $yearStart = new DateTime("January 1st, {$currentYear}");
36 $yearEnd = new DateTime("December 31st, {$currentYear} 23:59:59");
37
38 // Get completed donations from January 1st of current year to now
39 $completedAmount = (new DonationQuery())
40 ->whereIn("post_status", [
41 DonationStatus::COMPLETE,
42 DonationStatus::RENEWAL
43 ])
44 ->whereIn("ID", function (QueryBuilder $builder) use ($subscription) {
45 $builder
46 ->select("donation_id")
47 ->from("give_donationmeta")
48 ->where("meta_key", DonationMetaKeys::SUBSCRIPTION_ID)
49 ->where("meta_value", $subscription->id);
50 })
51 ->between(
52 $yearStart->format("Y-m-d H:i:s"),
53 $yearEnd->format("Y-m-d H:i:s")
54 )
55 ->sumIntendedAmount();
56
57 $completedAmount = Money::fromDecimal($completedAmount, $subscription->amount->getCurrency()->getCode());
58
59 // Calculate projected amount based on remaining donations this year
60 $remainingInstallments = $this->calculateRemainingInstallmentsUntilEndOfYear($subscription);
61
62 $projectedAmount = $subscription->intendedAmount()->multiply($remainingInstallments);
63
64 return $completedAmount->add($projectedAmount);
65 } catch (Exception $e) {
66 // Return zero Money object on error
67 return new Money(0, $subscription->amount->getCurrency()->getCode());
68 }
69 }
70
71 /**
72 * Calculate the remaining installments until the end of the current year.
73 *
74 * @since 4.8.0
75 */
76 private function calculateRemainingInstallmentsUntilEndOfYear(Subscription $subscription): int
77 {
78 $nextRenewal = clone $subscription->renewsAt;
79 $currentYear = (new DateTime())->format('Y');
80 $yearEnd = new DateTime('last day of December ' . $currentYear . ' 23:59:59');
81 $modifier = $subscription->period->isQuarter()
82 ? ($subscription->frequency * 3) . ' ' . SubscriptionPeriod::MONTH
83 : $subscription->frequency . ' ' . $subscription->period->getValue();
84
85 $installments = 0;
86
87 while ($nextRenewal <= $yearEnd) {
88 if ($nextRenewal->format('Y') === $currentYear) {
89 $installments++;
90 }
91
92 $nextRenewal->modify($modifier);
93 }
94
95 if ($subscription->installments > 0) {
96 $paidInstallments = $subscription->donations()->count();
97 $remainingInstallments = max(0, $subscription->installments - $paidInstallments);
98 $installments = min($installments, $remainingInstallments);
99 }
100
101 return $installments;
102 }
103 }
104