Skip to content

Commit

Permalink
Merge pull request #752 from readthedocs/davidfischer/flight-update-c…
Browse files Browse the repository at this point in the history
…alculator

Add calculator features to flight update/renew
  • Loading branch information
davidfischer committed Jun 6, 2023
2 parents 2c145ca + c1ab78c commit 4e54d43
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 16 deletions.
75 changes: 67 additions & 8 deletions adserver/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ class FlightForm(FlightMixin, forms.ModelForm):
we would need a way to let folks make adjustments and it automatically changes the price.
"""

# This is just a helper field used in JavaScript to ease flight price computation
# This field is *not* displayed in the Django admin because only fields in Meta.fields are displayed
budget = forms.IntegerField(
required=False,
label=_("Budget"),
)

include_regions = forms.MultipleChoiceField(
required=False,
widget=forms.CheckboxSelectMultiple(),
Expand Down Expand Up @@ -147,6 +154,7 @@ def __init__(self, *args, **kwargs):
self.topics = Topic.objects.all().order_by("slug")

if self.instance.pk:
self.fields["budget"].initial = round(self.instance.projected_total_value())
self.fields["include_regions"].initial = self.instance.included_regions
self.fields["exclude_regions"].initial = self.instance.excluded_regions
self.fields["include_topics"].initial = self.instance.included_topics
Expand All @@ -167,6 +175,7 @@ def __init__(self, *args, **kwargs):
self.fields["include_topics"].choices = [(t.slug, t.name) for t in self.topics]

self.helper = FormHelper()
self.helper.attrs = {"id": "flight-update-form"}

self.helper.layout = Layout(
Fieldset(
Expand All @@ -178,22 +187,44 @@ def __init__(self, *args, **kwargs):
css_class="form-row",
),
"live",
Div(
PrependedText(
"budget",
"$",
min=0,
data_bind="textInput: budget",
),
),
css_class="my-3",
),
Fieldset(
_("Per impression (CPM) flights"),
Div(
Div("cpm", css_class="form-group col-lg-6"),
Div("sold_impressions", css_class="form-group col-lg-6"),
Div(
PrependedText("cpm", "$", min=0, data_bind="textInput: cpm"),
css_class="form-group col-lg-6",
),
Div(
Field(
"sold_impressions", data_bind="textInput: sold_impressions"
),
css_class="form-group col-lg-6",
),
css_class="form-row",
),
css_class="my-3",
),
Fieldset(
_("Per click (CPC) flights"),
Div(
Div("cpc", css_class="form-group col-lg-6"),
Div("sold_clicks", css_class="form-group col-lg-6"),
Div(
PrependedText("cpc", "$", min=0, data_bind="textInput: cpc"),
css_class="form-group col-lg-6",
),
Div(
Field("sold_clicks", data_bind="textInput: sold_clicks"),
css_class="form-group col-lg-6",
),
css_class="form-row",
),
css_class="my-3",
Expand Down Expand Up @@ -380,6 +411,10 @@ class FlightRenewForm(FlightMixin, FlightCreateForm):
required=False,
help_text=_("Renew the flight with the following advertisements"),
)
budget = forms.IntegerField(
required=False,
label=_("Budget"),
)

def __init__(self, *args, **kwargs):
"""Set the flight form helper and initial data for renewing a flight."""
Expand All @@ -389,6 +424,7 @@ def __init__(self, *args, **kwargs):
kwargs["initial"] = {}
kwargs["initial"].update(
{
"budget": round(self.old_flight.projected_total_value()),
"name": self.old_flight.name,
"cpm": self.old_flight.cpm,
"cpc": self.old_flight.cpc,
Expand All @@ -409,6 +445,7 @@ def __init__(self, *args, **kwargs):

def create_form_helper(self):
helper = FormHelper()
helper.attrs = {"id": "flight-renew-form"}
helper.layout = Layout(
Fieldset(
"",
Expand All @@ -420,22 +457,44 @@ def create_form_helper(self):
css_class="form-row",
),
"live",
Div(
PrependedText(
"budget",
"$",
min=0,
data_bind="textInput: budget",
),
),
css_class="my-3",
),
Fieldset(
_("Per impression (CPM) flights"),
Div(
Div("cpm", css_class="form-group col-lg-6"),
Div("sold_impressions", css_class="form-group col-lg-6"),
Div(
PrependedText("cpm", "$", min=0, data_bind="textInput: cpm"),
css_class="form-group col-lg-6",
),
Div(
Field(
"sold_impressions", data_bind="textInput: sold_impressions"
),
css_class="form-group col-lg-6",
),
css_class="form-row",
),
css_class="my-3",
),
Fieldset(
_("Per click (CPC) flights"),
Div(
Div("cpc", css_class="form-group col-lg-6"),
Div("sold_clicks", css_class="form-group col-lg-6"),
Div(
PrependedText("cpc", "$", min=0, data_bind="textInput: cpc"),
css_class="form-group col-lg-6",
),
Div(
Field("sold_clicks", data_bind="textInput: sold_clicks"),
css_class="form-group col-lg-6",
),
css_class="form-row",
),
css_class="my-3",
Expand Down
45 changes: 37 additions & 8 deletions assets/src/views/flight_update.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,40 @@
import * as jquery from 'jquery';
const ko = require('knockout');


if ($('.ea-update-field').length > 0) {
$('.ea-update-field').click(function () {
var target = $(this).attr("data-target-field");
var value = $(this).attr("data-value");
$(target).val(value);
return false;
});
function FlightUpdateViewModel(method) {
this.budget = ko.observable($("#id_budget").val());
this.cpm = ko.observable($("#id_cpm").val());
this.cpc = ko.observable($("#id_cpc").val());
this.sold_impressions = ko.observable($("#id_sold_impressions").val());
this.sold_clicks = ko.observable($("#id_sold_clicks").val());

this.updateBudget = function () {
let budget = Math.round(this.budget(), 10);

if (Number(this.cpm()) > 0) {
this.cpc(0);
this.sold_clicks(0);
this.sold_impressions(parseInt(1000 * budget / Number(this.cpm())));
}
if (Number(this.cpc()) > 0) {
this.cpm(0);
this.sold_impressions(0);
this.sold_clicks(parseInt(budget / Number(this.cpc())));
}
}

this.budget.subscribe(function () {
this.updateBudget();
}, this);
this.cpm.subscribe(function () {
this.updateBudget();
}, this);
this.cpc.subscribe(function () {
this.updateBudget();
}, this);
}


if (document.querySelectorAll("#flight-renew-form").length > 0 || document.querySelectorAll("#flight-update-form").length > 0) {
ko.applyBindings(new FlightUpdateViewModel());
}

0 comments on commit 4e54d43

Please sign in to comment.