|
5 | 5 | @inject IStringLocalizer<Resgrid.Localization.Areas.User.Subscription.Subscription> localizer |
6 | 6 | @{ |
7 | 7 | ViewBag.Title = "Resgrid | " + @localizer["SubscriptionHeader"]; |
| 8 | + |
| 9 | + var locationName = SystemBehaviorConfig.LocationName ?? "US-West"; |
| 10 | + var location = InfoConfig.Locations.Find(l => l.Name == locationName) ?? InfoConfig.Locations[0]; |
| 11 | + var isEU = locationName.StartsWith("EU", StringComparison.OrdinalIgnoreCase); |
| 12 | + var currencySymbol = isEU ? "\u20AC" : "$"; |
8 | 13 | } |
9 | 14 |
|
10 | 15 | @section Styles |
|
319 | 324 |
|
320 | 325 | @if (Model.Plan == null || Model.Plan.PlanId == 1) |
321 | 326 | { |
322 | | - <p>Move the blue slider below with the arrows to select the number of Entities (Users + Units) you require. You can also type in the Entity count (in increments of 10) in the text box below. Please the "Buy Yearly" or "Buy Monthly" depending on the payment interval you wish. This will then take you to the Stripe checkout page. Please note you cannot buy a 10 entity pack as that is our free plan.</p> |
| 327 | + <p>Select the number of Entities (Users + Units) you require using the slider or text box below. |
| 328 | + @if (!isEU) { <text>Your first 10 entities are included at no charge — each</text> } else { <text>Each</text> } |
| 329 | + additional pack of 10 entities is billed at the rate shown. Select "Buy Yearly" or "Buy Monthly" to proceed to checkout.</p> |
| 330 | + |
| 331 | + @if (isEU) |
| 332 | + { |
| 333 | + <div class="alert alert-info" style="font-size:13px;"> |
| 334 | + <strong>European Region</strong> — Pricing includes GDPR-compliant data hosting. All prices shown in EUR (@currencySymbol) with a regional adjustment. No free tier is available. |
| 335 | + </div> |
| 336 | + } |
| 337 | + |
323 | 338 | <div class="price-box"> |
324 | 339 |
|
325 | 340 | <form class="form-horizontal form-pricing" role="form"> |
|
345 | 360 | </div> |
346 | 361 | </div> |
347 | 362 | <div class="form-group"> |
348 | | - <label for="amount" class="col-sm-6 control-label">Monthly ($): </label> |
| 363 | + <label for="amount" class="col-sm-6 control-label">Monthly (@currencySymbol): </label> |
349 | 364 | <span class="help-text">Monthly billing amount</span> |
350 | 365 | <div class="col-sm-6"> |
351 | 366 | <input type="hidden" id="amount" class="form-control"> |
352 | | - <p class="price lead" id="monthly-label"></p> |
353 | | - <span class="price">.00</span> |
| 367 | + <p class="price lead" id="monthly-label">0.00</p> |
354 | 368 | </div> |
355 | 369 | </div> |
356 | 370 | <div class="form-group"> |
357 | | - <label for="duration" class="col-sm-6 control-label">Yearly ($): </label> |
| 371 | + <label for="duration" class="col-sm-6 control-label">Yearly (@currencySymbol): </label> |
358 | 372 | <span class="help-text">Yearly (annual) billing amount</span> |
359 | 373 | <div class="col-sm-6"> |
360 | 374 | <input type="hidden" id="duration" class="form-control"> |
361 | | - <p class="price lead" id="yearly-label"></p> |
362 | | - <span class="price">.00</span> |
| 375 | + <p class="price lead" id="yearly-label">0.00</p> |
363 | 376 | </div> |
364 | 377 | </div> |
365 | 378 | <hr class="style"> |
|
627 | 640 |
|
628 | 641 |
|
629 | 642 |
|
| 643 | + var IS_EU = @(isEU ? "true" : "false"); |
| 644 | + var EU_MULTIPLIER = 1.25; |
| 645 | +
|
630 | 646 | $(document).ready(function () { |
631 | 647 | $("#slider").slider({ |
632 | 648 | animate: true, |
|
639 | 655 | handle.text($(this).slider("value")); |
640 | 656 | }, |
641 | 657 | slide: function (event, ui) { |
642 | | - update(1, ui.value); //changed |
| 658 | + update(1, ui.value); |
643 | 659 | } |
644 | 660 | }); |
645 | 661 |
|
|
663 | 679 | } |
664 | 680 | }); |
665 | 681 |
|
666 | | - //Added, set initial value. |
667 | 682 | $("#amount").val(10); |
668 | | - //$("#duration").val(0); |
669 | | - //$("#amount-label").text(0); |
670 | | - $("#amount-input").val(0); |
671 | | - $("#monthly-label").text(0); |
672 | | - $("#yearly-label").text(0); |
673 | | -
|
674 | | - //$("#duration-label").text(0); |
| 683 | + $("#amount-input").val(10); |
| 684 | + $("#monthly-label").text('0.00'); |
| 685 | + $("#yearly-label").text('0.00'); |
675 | 686 |
|
676 | 687 | update(); |
677 | 688 | }); |
678 | 689 |
|
679 | | - //changed. now with parameter |
680 | | - function update(slider, val) { |
| 690 | + function update(sliderFlag, sliderVal) { |
681 | 691 | let handle = $("#handle-text"); |
682 | | -
|
683 | | - //changed. Now, directly take value from ui.value. if not set (initial, will use current value.) |
684 | | - var $amount = slider == 1 ? val : $("#amount").val(); |
685 | | - var $duration = slider == 2 ? val : $("#duration").val(); |
686 | | -
|
687 | | - /* commented |
688 | | - $amount = $( "#slider" ).slider( "value" ); |
689 | | - $duration = $( "#slider2" ).slider( "value" ); |
690 | | - */ |
| 692 | + var $amount = sliderFlag == 1 ? sliderVal : $("#amount").val(); |
| 693 | + var showButtons = IS_EU ? ($amount >= 10) : ($amount > 10); |
691 | 694 |
|
692 | 695 | handle.text($amount); |
693 | | - //$total = "$" + ($amount * $duration); |
694 | 696 | $("#amount").val($amount); |
695 | | - //$("#amount-label").text($amount); |
696 | 697 | $("#amount-input").val($amount); |
697 | 698 |
|
698 | | - if ($amount > 10) { |
699 | | - const totalCostMonthly = calculateCostFromUsers($amount, true); |
700 | | - const totalCostYearly = calculateCostFromUsers($amount, false); |
| 699 | + if (showButtons) { |
| 700 | + var totalCostMonthly = calculateCostFromUsers($amount, true); |
| 701 | + var totalCostYearly = calculateCostFromUsers($amount, false); |
701 | 702 |
|
702 | | - $("#monthly-label").text(totalCostMonthly); |
703 | | - $("#yearly-label").text(totalCostYearly); |
| 703 | + $("#monthly-label").text(totalCostMonthly.toFixed(2)); |
| 704 | + $("#yearly-label").text(totalCostYearly.toFixed(2)); |
704 | 705 |
|
705 | 706 | $("#buyYearlyButton").show(); |
706 | 707 | $("#buyMonthlyButton").show(); |
707 | 708 | } else { |
708 | | - $("#monthly-label").text(0); |
709 | | - $("#yearly-label").text(0); |
| 709 | + $("#monthly-label").text('0.00'); |
| 710 | + $("#yearly-label").text('0.00'); |
710 | 711 |
|
711 | 712 | $("#buyYearlyButton").hide(); |
712 | 713 | $("#buyMonthlyButton").hide(); |
713 | 714 | } |
714 | 715 | } |
715 | 716 |
|
716 | | -
|
717 | 717 | const calculateCostFromUsers = (totalNumUsers, isMonthly) => { |
718 | | - let marginalBreakdownStrs = []; |
719 | | -
|
720 | 718 | const pricingTiersMonthly = [ |
721 | | - //{ tier: 0, marginalUserSlots: 1, costPerUser: 0.0 }, |
722 | | - { tier: 0, marginalUserSlots: 5, costPerUser: 20.0 }, |
723 | | - { tier: 1, marginalUserSlots: 100, costPerUser: 2.0 }, |
724 | | - { tier: 2, marginalUserSlots: 1000, costPerUser: 1.5 }, |
725 | | - { tier: 3, marginalUserSlots: 5000, costPerUser: 1.0 }, |
726 | | - { tier: 4, marginalUserSlots: 999999999, costPerUser: 0.5 }, |
| 719 | + { marginalUserSlots: 1, costPerUser: 0.0 }, |
| 720 | + { marginalUserSlots: 5, costPerUser: 20.0 }, |
| 721 | + { marginalUserSlots: 100, costPerUser: 2.0 }, |
| 722 | + { marginalUserSlots: 1000, costPerUser: 1.5 }, |
| 723 | + { marginalUserSlots: 5000, costPerUser: 1.0 }, |
| 724 | + { marginalUserSlots: 999999999, costPerUser: 0.5 }, |
727 | 725 | ]; |
728 | 726 |
|
729 | 727 | const pricingTiersYearly = [ |
730 | | - //{ tier: 0, marginalUserSlots: 1, costPerUser: 0.0 }, |
731 | | - { tier: 0, marginalUserSlots: 5, costPerUser: 200.0 }, |
732 | | - { tier: 1, marginalUserSlots: 100, costPerUser: 20.0 }, |
733 | | - { tier: 2, marginalUserSlots: 1000, costPerUser: 15.0 }, |
734 | | - { tier: 3, marginalUserSlots: 5000, costPerUser: 10.0 }, |
735 | | - { tier: 4, marginalUserSlots: 999999999, costPerUser: 5.0 }, |
| 728 | + { marginalUserSlots: 1, costPerUser: 0.0 }, |
| 729 | + { marginalUserSlots: 5, costPerUser: 200.0 }, |
| 730 | + { marginalUserSlots: 100, costPerUser: 20.0 }, |
| 731 | + { marginalUserSlots: 1000, costPerUser: 15.0 }, |
| 732 | + { marginalUserSlots: 5000, costPerUser: 10.0 }, |
| 733 | + { marginalUserSlots: 999999999, costPerUser: 5.0 }, |
736 | 734 | ]; |
737 | 735 |
|
738 | 736 | let finalCost = 0.0; |
739 | | - let remainingUsers = (totalNumUsers / 10) - 1; // First 10 users are free. |
740 | | - let pricingTiers = isMonthly ? pricingTiersMonthly : pricingTiersYearly; |
| 737 | + let remainingUsers = totalNumUsers / 10; |
| 738 | + const baseTiers = isMonthly ? pricingTiersMonthly : pricingTiersYearly; |
| 739 | +
|
| 740 | + let tiers; |
| 741 | + if (IS_EU) { |
| 742 | + tiers = [{ |
| 743 | + marginalUserSlots: baseTiers[0].marginalUserSlots + baseTiers[1].marginalUserSlots, |
| 744 | + costPerUser: baseTiers[1].costPerUser |
| 745 | + }].concat(baseTiers.slice(2)); |
| 746 | + } else { |
| 747 | + tiers = baseTiers; |
| 748 | + } |
741 | 749 |
|
742 | | - for (let i = 0; i < pricingTiers.length; i++) { |
743 | | - let tier = pricingTiers[i]; |
| 750 | + for (let i = 0; i < tiers.length; i++) { |
| 751 | + let tier = tiers[i]; |
744 | 752 | if (tier.marginalUserSlots < remainingUsers) { |
745 | | - // calculate cost |
746 | 753 | finalCost += tier.marginalUserSlots * tier.costPerUser; |
747 | | - marginalBreakdownStrs.push(`${tier.marginalUserSlots} @@ $${tier.costPerUser}`); |
748 | | - // remove the users |
749 | 754 | remainingUsers -= tier.marginalUserSlots; |
750 | 755 | } else { |
751 | | - // only need the partial group of the marginal user slots/ potentially all of them |
752 | 756 | finalCost += tier.costPerUser * remainingUsers; |
753 | | - marginalBreakdownStrs.push(`${remainingUsers} @@ $${tier.costPerUser}`); |
754 | 757 | remainingUsers = 0; |
755 | 758 | } |
756 | | - //console.log("RemainingUsers: ", remainingUsers); |
| 759 | + } |
| 760 | +
|
| 761 | + if (IS_EU) { |
| 762 | + finalCost = Math.round(finalCost * EU_MULTIPLIER); |
757 | 763 | } |
758 | 764 |
|
759 | 765 | return finalCost; |
|
0 commit comments