Skip to content

Commit

Permalink
Add the pricing to the flight update screen
Browse files Browse the repository at this point in the history
  • Loading branch information
davidfischer committed Aug 24, 2023
1 parent 1579872 commit 910ffdb
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 47 deletions.
15 changes: 14 additions & 1 deletion adserver/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ def __init__(self, *args, **kwargs):
self.fields["exclude_regions"].choices = self.fields["include_regions"].choices
self.fields["include_topics"].choices = [(t.slug, t.name) for t in self.topics]

self.fields["include_regions"].widget.attrs["data-bind"] = "checked: regions"
self.fields["include_topics"].widget.attrs["data-bind"] = "checked: topics"

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

Expand All @@ -197,6 +200,7 @@ def __init__(self, *args, **kwargs):
"budget",
"$",
min=0,
step=100,
data_bind="textInput: budget",
),
),
Expand Down Expand Up @@ -238,6 +242,14 @@ def __init__(self, *args, **kwargs):
Field("priority_multiplier"),
Fieldset(
_("Flight targeting"),
HTML(
"<p class='form-text'>"
+ str(_("Standard CPM: "))
+ "<span id='estimated-cpm' data-bind='text: estimatedCpm()'></span> "
+ "<span data-bind='if: budget() >= 2990 && budget() < 24990'>(10% discount)</span>"
+ "<span data-bind='if: budget() > 24990'>(15% discount)</span>"
+ "</p>"
),
Div("include_regions"),
Div("exclude_regions"),
Div("include_topics"),
Expand Down Expand Up @@ -468,6 +480,7 @@ def create_form_helper(self):
"budget",
"$",
min=0,
step=100,
data_bind="textInput: budget",
),
),
Expand Down Expand Up @@ -678,7 +691,7 @@ def create_form_helper(self):
Fieldset(
_("Flight targeting"),
HTML(
"<p class='form-text'>"
"<p class='form-text mb-0'>"
+ str(_("Estimated CPM: "))
+ "<span id='estimated-cpm' data-bind='text: estimatedCpm()'></span> "
+ "<span data-bind='if: budget() >= 2990 && budget() < 24990'>(10% discount applied)</span>"
Expand Down
9 changes: 9 additions & 0 deletions adserver/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,15 @@ def get_region_from_country_code(cls, country):

return "global"

@staticmethod
def get_pricing():
pricing = {}
for region in Region.objects.filter(selectable=True):
if region.prices:
pricing[region.slug] = region.prices

return pricing


class CountryRegion(TimeStampedModel, models.Model):

Expand Down
1 change: 1 addition & 0 deletions adserver/templates/adserver/advertiser/flight-update.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ <h1>{% block heading %}{% trans 'Flight' %}: {{ flight.name }}{% endblock headin
<div class="row">

<div class="col-md">
{{ pricing|json_script:"data-pricing" }}
{% crispy form form.helper %}
</div>

Expand Down
9 changes: 2 additions & 7 deletions adserver/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def form_valid(self, form):

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({"advertiser": self.advertiser})
context.update({"advertiser": self.advertiser, "pricing": Region.get_pricing()})
return context

def get_object(self, queryset=None):
Expand Down Expand Up @@ -499,11 +499,6 @@ def form_valid(self, form):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)

pricing = {}
for region in Region.objects.filter(selectable=True):
if region.prices:
pricing[region.slug] = region.prices

context.update(
{
"advertiser": self.advertiser,
Expand All @@ -512,7 +507,7 @@ def get_context_data(self, **kwargs):
).order_by("-start_date")[:50],
"old_flight": self.old_flight,
"next": self.request.GET.get("next"),
"pricing": pricing,
"pricing": Region.get_pricing(),
}
)

Expand Down
47 changes: 47 additions & 0 deletions assets/src/libs/flight-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
function getFlightPrice(regions, topics) {
let prices = [];
let pricing = JSON.parse($('#data-pricing').text());
let cpm = 0;

// Add all the price combinations to an array
// We will average this array
regions.forEach(function (region) {
let region_pricing = pricing[region];
if (region_pricing) {

if (topics.length > 0) {
topics.forEach(function (topic) {
if (region_pricing[topic]) {
prices.push(region_pricing[topic]);
} else {
// Unknown price for this topic
}
});
} else if (region_pricing["all-developers"]) {
prices.push(region_pricing["all-developers"]);
}
} else {
// Unknown price for this region
}
});

if (prices.length > 0) {
let total = prices.reduce(function (a, b) { return a + b});
cpm = total / prices.length;
}

return cpm;
};


function getDiscount(budget) {
if (budget >= 24990) {
return 0.15;
} else if (budget >= 2990) {
return 0.1;
}

return 0;
};

export { getFlightPrice, getDiscount };
43 changes: 5 additions & 38 deletions assets/src/views/flight-request.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const ko = require('knockout');
import { getFlightPrice, getDiscount } from "../libs/flight-utils";


function FlightRequestViewModel(method) {
Expand All @@ -10,49 +11,15 @@ function FlightRequestViewModel(method) {

this.estimatedCpm = function () {
let budget = Math.round(this.budget(), 10);
let cpm = 0;
let prices = [];

let regions = this.regions();
let topics = this.topics();
let pricing = this.pricing;

// Add all the price combinations to an array
// We will average this array
regions.forEach(function (region) {
let region_pricing = pricing[region];
if (region_pricing) {

if (topics.length > 0) {
topics.forEach(function (topic) {
if (region_pricing[topic]) {
prices.push(region_pricing[topic]);
} else {
// Unknown price for this topic
}
});
} else if (region_pricing["all-developers"]) {
prices.push(region_pricing["all-developers"]);
}
} else {
// Unknown price for this region
}
});

if (prices.length > 0) {
let total = prices.reduce(function (a, b) { return a + b});
cpm = total / prices.length;
}

// Apply discounts
if (budget >= 24990) {
cpm *= 0.85
} else if (budget >= 2990) {
cpm *= 0.9
}

let rateMultiplier = 1.0 - getDiscount(budget);
let cpm = rateMultiplier * getFlightPrice(regions, topics);

return cpm > 0 ? '$' + cpm.toFixed(2) : "TBD";
}
};
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const ko = require('knockout');
import { getFlightPrice, getDiscount } from "../libs/flight-utils";


function FlightUpdateViewModel(method) {
Expand All @@ -8,6 +9,10 @@ function FlightUpdateViewModel(method) {
this.sold_impressions = ko.observable($("#id_sold_impressions").val());
this.sold_clicks = ko.observable($("#id_sold_clicks").val());

this.regions = ko.observable([...document.querySelectorAll("form [name='include_regions']:checked")].map(function (node) { return node.value }));
this.topics = ko.observable([...document.querySelectorAll("form [name='include_topics']:checked")].map(function (node) { return node.value }));


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

Expand All @@ -23,6 +28,18 @@ function FlightUpdateViewModel(method) {
}
}

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

let regions = this.regions();
let topics = this.topics();

let rateMultiplier = 1.0 - getDiscount(budget);
let cpm = rateMultiplier * getFlightPrice(regions, topics);

return cpm > 0 ? '$' + cpm.toFixed(2) : "TBD";
};

this.budget.subscribe(function () {
this.updateBudget();
}, this);
Expand Down
2 changes: 1 addition & 1 deletion assets/src/views/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from './publisher_settings';
export * from './advertisement-form';
export * from './flight-request';
export * from './flight_update';
export * from './flight-update';
export * from './dashboard-home';
export * from './payout-create';

0 comments on commit 910ffdb

Please sign in to comment.