PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / trunk
Subscriptions for WooCommerce with Stripe Recurring Payments vtrunk
1.11.2 1.11.1 1.11.0 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.6 1.9.5 trunk 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 All 60 releases
subscription / src / index.js

index.js in Subscriptions for WooCommerce with Stripe Recurring Payments trunk, at src/index.js

193 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { ExperimentalOrderMeta, registerCheckoutFilters, TotalsItem } from "@woocommerce/blocks-checkout";
2 import { FormattedMonetaryAmount } from "@woocommerce/blocks-components";
3 import { __, sprintf } from "@wordpress/i18n";
4 import { registerPlugin } from "@wordpress/plugins";
5
6 import { formatPrice, getCurrencyFromPriceResponse } from "@woocommerce/price-format";
7 // import { useStoreCart } from "@woocommerce/base-context/hooks";
8
9 const modifyCartItemPrice = (defaultValue, extensions, args, validation) => {
10 const { sdevs_subscription } = extensions;
11 const { cartItem } = args;
12 const { totals } = cartItem;
13
14 if (totals === undefined) {
15 return defaultValue;
16 }
17 if (totals.line_total === "0") {
18 return `<price/> ${__("Due Today", "subscription")}`;
19 }
20 if (sdevs_subscription && sdevs_subscription.type) {
21 // Capitalize the first letter to match product page display
22 const capitalizedType = sdevs_subscription.type.charAt(0).toUpperCase() + sdevs_subscription.type.slice(1);
23
24 // Check max_no_payment - handle string, number, null, undefined
25 const maxPayments = parseInt(sdevs_subscription.max_no_payment, 10);
26 const paymentInfo = !isNaN(maxPayments) && maxPayments > 0 ? ` x ${maxPayments}` : "";
27 return `<price/> / ${
28 sdevs_subscription.time && sdevs_subscription.time > 1 ? " " + sdevs_subscription.time + "-" : ""
29 }${capitalizedType}${paymentInfo}`;
30 }
31 return defaultValue;
32 };
33
34 const modifySubtotalPriceFormat = (defaultValue, extensions, args, validation) => {
35 const { sdevs_subscription } = extensions;
36 const { sdevs_subscription: recurrings } = extensions;
37
38 if (sdevs_subscription && sdevs_subscription.type) {
39 // Capitalize the first letter to match product page display
40 const capitalizedType = sdevs_subscription.type.charAt(0).toUpperCase() + sdevs_subscription.type.slice(1);
41
42 // Check max_no_payment - handle string, number, null, undefined
43 const maxPayments = parseInt(sdevs_subscription.max_no_payment, 10);
44 const paymentInfo = !isNaN(maxPayments) && maxPayments > 0 ? ` x ${maxPayments}` : "";
45
46 const timePart = sdevs_subscription.time && sdevs_subscription.time > 1 ? sdevs_subscription.time + "-" : "";
47 const priceText = "<price/>\u00A0" + __("Every", "subscription") + " " + timePart + capitalizedType + paymentInfo;
48
49 return priceText;
50 }
51
52 return defaultValue;
53 };
54
55 registerCheckoutFilters("sdevs-subscription", {
56 cartItemPrice: modifyCartItemPrice,
57 subtotalPriceFormat: modifySubtotalPriceFormat,
58 });
59
60 const RecurringTotals = ({ cart, extensions }) => {
61 if (Object.keys(extensions).length === 0) {
62 return;
63 }
64 const { cartTotals } = cart;
65 const { sdevs_subscription: recurrings } = extensions;
66 if (recurrings.length === 0) {
67 return;
68 }
69
70 const currency = getCurrencyFromPriceResponse(cartTotals);
71 const multiplier = Math.pow(10, currency.minorUnit);
72
73 return (
74 <TotalsItem
75 className="wc-block-components-totals-footer-item"
76 label={__("Recurring totals", "subscription")}
77 description={
78 <div style={{ display: "grid" }}>
79 {recurrings.map((recurring) => {
80 // Capitalize the first letter to match product page display
81 const capitalizedType = recurring.type.charAt(0).toUpperCase() + recurring.type.slice(1);
82
83 const priceFormatArgs = {
84 currency: currency.code,
85 currency_symbol: currency.symbol,
86 decimal_separator: currency.decimalSeparator,
87 thousand_separator: currency.thousandSeparator,
88 precision: currency.minorUnit,
89 price_format: currency.priceFormat,
90 };
91
92 /**
93 * Format an amount the same way the surrounding totals are formatted.
94 *
95 * @param {number} amount Amount in major units.
96 * @return {string} Formatted price.
97 */
98 const format = (amount) => formatPrice(Math.round(amount * multiplier), priceFormatArgs);
99
100 const recurringLimit = parseInt(recurring.recurring_limit, 10) || 0;
101
102 // Billing period as plain text, so notes can quote a price the same way the row does.
103 const periodLabel =
104 recurring.time && recurring.time > 1 ? `${recurring.time}-${capitalizedType}` : capitalizedType;
105
106 return (
107 <div style={{ margin: "20px 0", float: "right" }}>
108 <div style={{ fontSize: "18px" }}>
109 {recurring.has_recurring_discount && (
110 <del aria-hidden="true" style={{ marginRight: "6px", opacity: 0.6 }}>
111 {format(recurring.full_price)}
112 </del>
113 )}
114 <FormattedMonetaryAmount currency={currency} value={Math.round(recurring.price * multiplier)} />
115 <span class="wpsubs-subscription-timing">
116 &nbsp;/&nbsp;
117 {recurring.time && recurring.time > 1
118 ? `${recurring.time + "-" + capitalizedType} `
119 : capitalizedType}
120 </span>
121 </div>
122 <small>{recurring.description}</small>
123 {recurring.has_one_time_discount && (
124 <>
125 <br />
126 <small>
127 {sprintf(
128 // translators: 1: amount paid today, 2: amount charged on each renewal.
129 __("You pay %1$s today. %2$s will be charged from the next renewal.", "subscription"),
130 format(recurring.first_price),
131 format(recurring.price),
132 )}
133 </small>
134 </>
135 )}
136 {recurring.has_recurring_discount && recurringLimit > 1 && (
137 <>
138 <br />
139 <small>
140 {sprintf(
141 // translators: 1: number of discounted payments, 2: full price charged afterwards.
142 __("Discount applies to your first %1$s payments. After that, %2$s.", "subscription"),
143 recurringLimit,
144 `${format(recurring.full_price)} / ${periodLabel}`,
145 )}
146 </small>
147 </>
148 )}
149 {recurring.can_user_cancel === "yes" &&
150 (recurring.max_no_payment === "" || parseInt(recurring.max_no_payment) === 0) && (
151 <>
152 <br />
153 <small>{__("You can cancel subscription at any time!", "subscription")} </small>
154 </>
155 )}
156 {parseInt(recurring.max_no_payment) > 0 && (
157 <>
158 <br />
159 <small>
160 {sprintf(
161 // translators: 1: number of installments, 2: total amount.
162 __(
163 "This subscription will be billed in %1$s installments, for a total of %2$s.",
164 "subscription",
165 ),
166 recurring.max_no_payment,
167 format(recurring.price * parseInt(recurring.max_no_payment)),
168 )}
169 </small>
170 </>
171 )}
172 </div>
173 );
174 })}
175 </div>
176 }
177 ></TotalsItem>
178 );
179 };
180
181 const render = () => {
182 return (
183 <ExperimentalOrderMeta>
184 <RecurringTotals />
185 </ExperimentalOrderMeta>
186 );
187 };
188
189 registerPlugin("sdevs-subscription", {
190 render,
191 scope: "woocommerce-checkout",
192 });
193