mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 22:13:26 +00:00
billing: Move all price computations into billing.js.
This commit is contained in:
@@ -11,6 +11,7 @@ from django.urls import reverse
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from zerver.decorator import zulip_login_required, require_billing_access
|
from zerver.decorator import zulip_login_required, require_billing_access
|
||||||
|
from zerver.lib.json_encoder_for_html import JSONEncoderForHTML
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_error, json_success
|
from zerver.lib.response import json_error, json_success
|
||||||
from zerver.lib.validator import check_string
|
from zerver.lib.validator import check_string
|
||||||
@@ -119,9 +120,13 @@ def initial_upgrade(request: HttpRequest) -> HttpResponse:
|
|||||||
'nickname_monthly': Plan.CLOUD_MONTHLY,
|
'nickname_monthly': Plan.CLOUD_MONTHLY,
|
||||||
'nickname_annual': Plan.CLOUD_ANNUAL,
|
'nickname_annual': Plan.CLOUD_ANNUAL,
|
||||||
'error_message': error_message,
|
'error_message': error_message,
|
||||||
'cloud_monthly_price': 8,
|
'page_params': JSONEncoderForHTML().encode({
|
||||||
'cloud_annual_price': 80,
|
'seat_count': seat_count,
|
||||||
'cloud_annual_price_per_month': 6.67,
|
'nickname_annual': Plan.CLOUD_ANNUAL,
|
||||||
|
'nickname_monthly': Plan.CLOUD_MONTHLY,
|
||||||
|
'annual_price': 8000,
|
||||||
|
'monthly_price': 800,
|
||||||
|
}),
|
||||||
} # type: Dict[str, Any]
|
} # type: Dict[str, Any]
|
||||||
response = render(request, 'corporate/upgrade.html', context=context)
|
response = render(request, 'corporate/upgrade.html', context=context)
|
||||||
response['error_description'] = error_description
|
response['error_description'] = error_description
|
||||||
|
|||||||
@@ -62,16 +62,41 @@ $(function () {
|
|||||||
$('html,body').scrollTop(0);
|
$('html,body').scrollTop(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function format_money(cents) {
|
||||||
|
// allow for small floating point errors
|
||||||
|
cents = Math.ceil(cents - 0.001);
|
||||||
|
var precision;
|
||||||
|
if (cents % 100 === 0) {
|
||||||
|
precision = 0;
|
||||||
|
} else {
|
||||||
|
precision = 2;
|
||||||
|
}
|
||||||
|
// TODO: Add commas for thousands, millions, etc.
|
||||||
|
return (cents / 100).toFixed(precision);
|
||||||
|
}
|
||||||
|
|
||||||
if (window.location.pathname === '/upgrade/') {
|
if (window.location.pathname === '/upgrade/') {
|
||||||
const seat_count = parseInt($('input[name=seat_count]').val());
|
var prices = {};
|
||||||
function update_charged_amount(per_seat_cost) {
|
prices[page_params.nickname_annual] =
|
||||||
$("#charged_amount").html(seat_count * per_seat_cost);
|
page_params.annual_price
|
||||||
|
prices[page_params.nickname_monthly] =
|
||||||
|
page_params.monthly_price
|
||||||
|
|
||||||
|
function update_charged_amount(plan_nickname) {
|
||||||
|
$("#charged_amount").text(
|
||||||
|
format_money(page_params.seat_count * prices[plan_nickname])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$('input[type=radio][name=plan]').change(function () {
|
$('input[type=radio][name=plan]').change(function () {
|
||||||
update_charged_amount($(this).data('amount'));
|
update_charged_amount($(this).val());
|
||||||
});
|
});
|
||||||
|
|
||||||
update_charged_amount($('input[type=radio][name=plan]:checked').data('amount'));
|
$("#autopay_annual_price").text(format_money(prices[page_params.nickname_annual]));
|
||||||
|
$("#autopay_annual_price_per_month").text(format_money(prices[page_params.nickname_annual] / 12));
|
||||||
|
$("#autopay_monthly_price").text(format_money(prices[page_params.nickname_monthly]));
|
||||||
|
$("#invoice_annual_price").text(format_money(prices[page_params.nickname_annual]));
|
||||||
|
$("#invoice_annual_price_per_month").text(format_money(prices[page_params.nickname_annual] / 12));
|
||||||
|
update_charged_amount($('input[type=radio][name=plan]:checked').val());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
{% extends "zerver/portico.html" %}
|
{% extends "zerver/portico.html" %}
|
||||||
|
|
||||||
|
{% block page_params %}
|
||||||
|
{# Insert parameters, which have been encoded with JSONEncoderForHTML. #}
|
||||||
|
<script>
|
||||||
|
{% autoescape off %}
|
||||||
|
var page_params = {{ page_params }};
|
||||||
|
{% endautoescape %}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block customhead %}
|
{% block customhead %}
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
{{ render_bundle('landing-page') }}
|
{{ render_bundle('landing-page') }}
|
||||||
@@ -7,6 +16,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="app portico-page">
|
<div class="app portico-page">
|
||||||
|
|
||||||
{% include 'zerver/billing_nav.html' %}
|
{% include 'zerver/billing_nav.html' %}
|
||||||
@@ -41,22 +51,22 @@
|
|||||||
<div class="payment-schedule">
|
<div class="payment-schedule">
|
||||||
<h3>{{ _("Payment schedule") }}</h3>
|
<h3>{{ _("Payment schedule") }}</h3>
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" name="plan" value="{{ nickname_annual }}" data-amount="{{ cloud_annual_price }}" checked />
|
<input type="radio" name="plan" value="{{ nickname_annual }}" checked />
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="schedule-time annually">{{ _("Pay annually") }}</div>
|
<div class="schedule-time annually">{{ _("Pay annually") }}</div>
|
||||||
<div class="schedule-amount">
|
<div class="schedule-amount">
|
||||||
${{ cloud_annual_price_per_month }}/user/month
|
$<span id="autopay_annual_price_per_month"></span>/user/month
|
||||||
<div class="schedule-amount-2">
|
<div class="schedule-amount-2">
|
||||||
(${{ cloud_annual_price }}/user/year)
|
($<span id="autopay_annual_price"></span>/user/year)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" name="plan" value="{{ nickname_monthly }}" data-amount="{{ cloud_monthly_price }}" />
|
<input type="radio" name="plan" value="{{ nickname_monthly }}" />
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="schedule-time">{{ _("Pay monthly") }}</div>
|
<div class="schedule-time">{{ _("Pay monthly") }}</div>
|
||||||
<div class="schedule-amount">${{ cloud_monthly_price }}/user/month</div>
|
<div class="schedule-amount">$<span id="autopay_monthly_price"></span>/user/month</div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,13 +101,13 @@
|
|||||||
<div class="payment-schedule">
|
<div class="payment-schedule">
|
||||||
<h3>{{ _("Payment schedule") }}</h3>
|
<h3>{{ _("Payment schedule") }}</h3>
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" name="plan" value="{{ nickname_annual }}" data-amount="{{ cloud_annual_price }}" checked />
|
<input type="radio" name="plan" value="{{ nickname_annual }}" checked />
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="schedule-time annually">{{ _("Pay annually") }}</div>
|
<div class="schedule-time annually">{{ _("Pay annually") }}</div>
|
||||||
<div class="schedule-amount">
|
<div class="schedule-amount">
|
||||||
${{ cloud_annual_price_per_month }}/user/month
|
$<span id="invoice_annual_price_per_month"></span>/user/month
|
||||||
<div class="schedule-amount-2">
|
<div class="schedule-amount-2">
|
||||||
(${{ cloud_annual_price }}/user/year)
|
($<span id="invoice_annual_price"></span>/user/year)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user