mirror of https://github.com/zulip/zulip.git
parent
bf53c70dd9
commit
395cafcf46
|
@ -0,0 +1,27 @@
|
|||
# Generated by Django 4.2.6 on 2023-11-11 14:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("corporate", "0018_customer_cloud_xor_self_hosted"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="zulipsponsorshiprequest",
|
||||
name="expected_total_users",
|
||||
field=models.TextField(default=""),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="zulipsponsorshiprequest",
|
||||
name="paid_users_count",
|
||||
field=models.TextField(default=""),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="zulipsponsorshiprequest",
|
||||
name="paid_users_description",
|
||||
field=models.TextField(default=""),
|
||||
),
|
||||
]
|
|
@ -360,3 +360,6 @@ class ZulipSponsorshipRequest(models.Model):
|
|||
org_website = models.URLField(max_length=MAX_ORG_URL_LENGTH, blank=True, null=True)
|
||||
|
||||
org_description = models.TextField(default="")
|
||||
expected_total_users = models.TextField(default="")
|
||||
paid_users_count = models.TextField(default="")
|
||||
paid_users_description = models.TextField(default="")
|
||||
|
|
|
@ -2159,6 +2159,9 @@ class StripeTest(StripeTestCase):
|
|||
"organization-type": Realm.ORG_TYPES["opensource"]["id"],
|
||||
"website": "invalid-url",
|
||||
"description": "Infinispan is a distributed in-memory key/value data store with optional schema.",
|
||||
"expected_total_users": "10 users",
|
||||
"paid_users_count": "1 user",
|
||||
"paid_users_description": "We have 1 paid user.",
|
||||
}
|
||||
|
||||
response = self.client_post("/json/billing/sponsorship", data)
|
||||
|
@ -2172,6 +2175,9 @@ class StripeTest(StripeTestCase):
|
|||
"organization-type": Realm.ORG_TYPES["opensource"]["id"],
|
||||
"website": "",
|
||||
"description": "Infinispan is a distributed in-memory key/value data store with optional schema.",
|
||||
"expected_total_users": "10 users",
|
||||
"paid_users_count": "1 user",
|
||||
"paid_users_description": "We have 1 paid user.",
|
||||
}
|
||||
|
||||
response = self.client_post("/json/billing/sponsorship", data)
|
||||
|
@ -2223,6 +2229,9 @@ class StripeTest(StripeTestCase):
|
|||
"organization-type": Realm.ORG_TYPES["opensource"]["id"],
|
||||
"website": "https://infinispan.org/",
|
||||
"description": "Infinispan is a distributed in-memory key/value data store with optional schema.",
|
||||
"expected_total_users": "10 users",
|
||||
"paid_users_count": "1 user",
|
||||
"paid_users_description": "We have 1 paid user.",
|
||||
}
|
||||
response = self.client_post("/json/billing/sponsorship", data)
|
||||
self.assert_json_success(response)
|
||||
|
|
|
@ -233,6 +233,9 @@ class SponsorshipRequestForm(forms.Form):
|
|||
website = forms.URLField(max_length=ZulipSponsorshipRequest.MAX_ORG_URL_LENGTH, required=False)
|
||||
organization_type = forms.IntegerField()
|
||||
description = forms.CharField(widget=forms.Textarea)
|
||||
expected_total_users = forms.CharField(widget=forms.Textarea)
|
||||
paid_users_count = forms.CharField(widget=forms.Textarea)
|
||||
paid_users_description = forms.CharField(widget=forms.Textarea, required=False)
|
||||
|
||||
|
||||
@require_organization_member
|
||||
|
@ -243,6 +246,9 @@ def sponsorship(
|
|||
organization_type: str = REQ("organization-type"),
|
||||
website: str = REQ(),
|
||||
description: str = REQ(),
|
||||
expected_total_users: str = REQ(),
|
||||
paid_users_count: str = REQ(),
|
||||
paid_users_description: str = REQ(),
|
||||
) -> HttpResponse:
|
||||
realm = user.realm
|
||||
billing_session = RealmBillingSession(user)
|
||||
|
@ -266,6 +272,9 @@ def sponsorship(
|
|||
org_website=form.cleaned_data["website"],
|
||||
org_description=form.cleaned_data["description"],
|
||||
org_type=form.cleaned_data["organization_type"],
|
||||
expected_total_users=form.cleaned_data["expected_total_users"],
|
||||
paid_users_count=form.cleaned_data["paid_users_count"],
|
||||
paid_users_description=form.cleaned_data["paid_users_description"],
|
||||
)
|
||||
sponsorship_request.save()
|
||||
|
||||
|
@ -287,6 +296,9 @@ def sponsorship(
|
|||
"organization_type": org_type_display_name,
|
||||
"website": website,
|
||||
"description": description,
|
||||
"expected_total_users": expected_total_users,
|
||||
"paid_users_count": paid_users_count,
|
||||
"paid_users_description": paid_users_description,
|
||||
}
|
||||
send_email(
|
||||
"zerver/emails/sponsorship_request",
|
||||
|
|
|
@ -66,17 +66,35 @@
|
|||
</div>
|
||||
<label for="organization-type" class="inline-block label-title">Organization type</label>
|
||||
</div>
|
||||
<p id="sponsorship-discount-details"></p>
|
||||
<div class="input-box sponsorship-form-field no-validation">
|
||||
<label for="org-website" class="inline-block label-title">Organization website</label>
|
||||
<input id="org-website" name="website" type="text" placeholder="Leave blank if this organization does not have a website."/>
|
||||
<label for="org-website" class="inline-block
|
||||
label-title">Organization website (if any)</label>
|
||||
<input id="org-website" name="website" type="text"/>
|
||||
<div id="sponsorship-org-website-error" class="alert alert-danger sponsorship-field-error"></div>
|
||||
</div>
|
||||
<div class="input-box sponsorship-form-field">
|
||||
<label for="description" class="inline-block label-title">Describe this organization</label>
|
||||
<label for="description" class="inline-block
|
||||
label-title">Description of your organization</label>
|
||||
<textarea id="description" name="description" cols="100" rows="5"></textarea>
|
||||
<div id="sponsorship-description-error" class="alert alert-danger sponsorship-field-error"></div>
|
||||
</div>
|
||||
<p id="sponsorship-discount-details"></p>
|
||||
<div class="input-box sponsorship-form-field">
|
||||
<label for="expected-total-users" class="inline-block label-title">Expected number of users (approximate range)</label>
|
||||
<input id="expected-total-users" name="expected_total_users" type="text" />
|
||||
<div id="sponsorship-expected-total-users-error" class="alert alert-danger sponsorship-field-error"></div>
|
||||
</div>
|
||||
<div class="input-box sponsorship-form-field no-validation">
|
||||
<label for="paid-users-count" class="inline-block label-title">How many paid staff does your organization have?</label>
|
||||
<input id="paid-users-count" name="paid_users_count" type="text"/>
|
||||
<div id="sponsorship-paid-users-count-error" class="alert alert-danger sponsorship-field-error"></div>
|
||||
</div>
|
||||
<div class="input-box sponsorship-form-field">
|
||||
<label for="paid-users-description" class="inline-block
|
||||
label-title">Description of paid staff (if any)</label>
|
||||
<textarea id="paid-users-description" name="paid_users_description" cols="100" rows="2"></textarea>
|
||||
<div id="sponsorship-paid-users-description-error" class="alert alert-danger sponsorship-field-error"></div>
|
||||
</div>
|
||||
<!-- Disabled buttons do not fire any events, so we need a container div that isn't disabled for tippyjs to work -->
|
||||
<div class="upgrade-button-container" {% if is_demo_organization %}data-tippy-content="Convert demo organization before upgrading."{% endif %}>
|
||||
<button type="submit" id="sponsorship-button" class="stripe-button-el invoice-button" {% if is_demo_organization %}disabled{% endif %}>
|
||||
|
|
|
@ -14,6 +14,30 @@ function hide_submit_loading_indicator(): void {
|
|||
$("#sponsorship-button .sponsorship-button-text").show();
|
||||
}
|
||||
|
||||
function validate_data(data: helpers.FormDataObject): boolean {
|
||||
let found_error = false;
|
||||
if (data.description.trim() === "") {
|
||||
$("#sponsorship-description-error").text("Organization description cannot be blank.");
|
||||
hide_submit_loading_indicator();
|
||||
found_error = true;
|
||||
}
|
||||
|
||||
if (data.paid_users_count.trim() === "") {
|
||||
$("#sponsorship-paid-users-count-error").text("Number of paid staff cannot be blank.");
|
||||
hide_submit_loading_indicator();
|
||||
found_error = true;
|
||||
}
|
||||
|
||||
if (data.expected_total_users.trim() === "") {
|
||||
$("#sponsorship-expected-total-users-error").text(
|
||||
"Expected number of users cannot be blank.",
|
||||
);
|
||||
hide_submit_loading_indicator();
|
||||
found_error = true;
|
||||
}
|
||||
return !found_error;
|
||||
}
|
||||
|
||||
function create_ajax_request(): void {
|
||||
show_submit_loading_indicator();
|
||||
const $form = $("#sponsorship-form");
|
||||
|
@ -25,10 +49,7 @@ function create_ajax_request(): void {
|
|||
|
||||
// Clear any previous error messages.
|
||||
$(".sponsorship-field-error").text("");
|
||||
|
||||
if (data.description.trim() === "") {
|
||||
$("#sponsorship-description-error").text("Organization description cannot be blank.");
|
||||
hide_submit_loading_indicator();
|
||||
if (!validate_data(data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -62,7 +83,10 @@ export function initialize(): void {
|
|||
});
|
||||
|
||||
function update_discount_details(): void {
|
||||
const selected_org_type = $<HTMLSelectElement>("#organization-type").find(":selected").attr("data-string-value") ?? "";
|
||||
const selected_org_type =
|
||||
$<HTMLSelectElement>("#organization-type")
|
||||
.find(":selected")
|
||||
.attr("data-string-value") ?? "";
|
||||
helpers.update_discount_details(selected_org_type);
|
||||
}
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ input[name="licenses"] {
|
|||
#sponsorship-discount-details {
|
||||
font-weight: normal;
|
||||
margin: 2px;
|
||||
padding-top: 25px;
|
||||
padding-top: 0;
|
||||
text-align: left;
|
||||
overflow-wrap: break-word;
|
||||
width: 450px;
|
||||
|
|
Loading…
Reference in New Issue