return int(self.progress_percent)
def update_progress(self):
- # Total of new payments during the action.
- # This definition will need to change for longer timespans.
if not self.since or not self.until or not self.target:
return
Schedule = apps.get_model('club', 'Schedule')
- self.progress = Schedule.objects.filter(
- payed_at__gte=self.since,
- payed_at__lte=self.until,
- ).aggregate(c=models.Sum('amount'))['c']
+ PayUOrder = apps.get_model('club', 'PayUOrder')
+ progress = PayUOrder.objects.filter(
+ completed_at__gte=self.since,
+ completed_at__lte=self.until,
+ ).aggregate(c=models.Sum('schedule__amount'))['c']
+
+ for schedule in Schedule.objects.filter(
+ method='paypal',
+ expires_at__gt=self.since
+ ):
+ progress += schedule.n_paypal_payments(self.since, self.until) * schedule.amount
+ self.progress = progress
self.save(update_fields=['progress'])
@classmethod
def update_all_progress(cls):
- for obj in cls.objects.exclude(target=None):
+ for obj in cls.objects.exclude(target=None).exclude(until__lt=now()):
obj.update_progress()
('quiet', 'Spokojny'),
('loud', 'Ostry'),
)),
+ ('seasonal', 'Sezonowa', False),
]
PLACE_CHOICES = [p[:2] for p in PLACE_DEFINITIONS]
--- /dev/null
+{% load l10n %}
+{% load time_tags %}
+
+{% if banner %}
+<div class="l-container">
+ <div class="
+ annoy-banner
+ annoy-banner_{{ banner.place }}
+ annoy-banner-style_{{ banner.style }}
+ {% if banner.get_image %}with-image{% endif %}
+ {% if banner.smallfont %}banner-smallfont{% endif %}
+ annoy-banner-clickable
+ "
+ id="annoy-banner-{{ banner.id }}"
+ style="
+ {% if banner.text_color %}color: {{ banner.text_color }};{% endif %}
+ {% if banner.background_color %}background-color: {{ banner.background_color }};{% endif %}
+ ">
+ {% if not banner.action_label %}
+ <a
+ {% if banner.is_external %}target="_blank"{% endif %}
+ href="{{ banner.url }}">
+ {% endif %}
+ <div class="annoy-banner-inner">
+
+ {% if banner.get_image %}
+ <div>
+ <img src="{{ banner.get_image.url }}">
+ </div>
+ {% endif %}
+ <div class="text">
+ {{ banner.get_text|safe|linebreaks }}
+ </div>
+
+
+
+
+ {% if banner.action_label %}
+ <a class="action"
+ {% if banner.is_external %}target="_blank"{% endif %}
+ href="{{ banner.url }}">
+ {{ banner.action_label }}
+ </a>
+ {% endif %}
+ </div>
+ {% if not banner.action_label %}
+ </a>
+ {% endif %}
+
+ <div class="state-box">
+ <div class="progress-box">
+ <div>
+ <div class="l-checkout__support__bar">
+ <span class="{% if banner.progress_percent < 15 %}little-progress{% endif %}" data-label="{{ banner.progress_percent_pretty }}%" style="width: {{ banner.progress_percent|stringformat:".3f" }}%;"></span>
+ </div>
+ </div>
+ </div>
+ <div class="bar-status-box">
+ <div class="time-box">
+ <strong class="countdown inline" data-until='{{ banner.until|date_to_utc:True|utc_for_js }}'> </strong>
+ </div>
+ {% if banner.target %}
+ <strong>{{ banner.target }} zł</strong>
+ {% endif %}
+ </div>
+ </div>
+
+
+ </div>
+</div>
+{% endif %}
'banner': banners.first(),
'closable': True,
}
+
+@register.inclusion_tag('annoy/banner_seasonal.html', takes_context=True)
+def annoy_banner_seasonal(context):
+ banners = Banner.choice('seasonal', request=context['request'], exemptions=False)
+ return {
+ 'banner': banners.first(),
+ 'closable': False,
+ }
model = models.Schedule
fields = [
'first_name', 'last_name',
- 'email', 'phone',
- 'postal',
- 'postal_code', 'postal_town', 'postal_country',
+ 'email',
]
widgets = {
'amount': forms.HiddenInput,
def __init__(self, **kwargs):
super().__init__(**kwargs)
- self.fields['first_name'].required = True
- self.fields['last_name'].required = True
-
self.consent = []
for c in models.Consent.objects.filter(active=True).order_by('order'):
key = f'consent{c.id}'
- self.fields[key] = forms.BooleanField(
- label=c.text,
- required=c.required
- )
+ if not c.required:
+ self.fields[key] = forms.BooleanField(
+ label=c.text,
+ required=c.required
+ )
self.consent.append((
c, key, (lambda k: lambda: self[k])(key)
))
def is_recurring(self):
return self.monthly or self.yearly
+ def n_paypal_payments(self, since, until):
+ # TODO: pull BA payments.
+ t = self.payed_at
+ if t is None: return 0
+ c = 0
+ until = min(until, now())
+ t += timedelta(days=1)
+ while t < until:
+ if t >= since:
+ c += 1
+ m = datetime(t.year, t.month, 1)
+ t += ((m + timedelta(days=31)).replace(day=1)) - m
+ return c
+
def set_payed(self):
since = self.expires_at
n = now()
{% extends 'club/donation_step_base.html' %}
+{% load chunks %}
{% block donation-step-content %}
{% include "club/donation_step1_form.html" %}
{% endblock %}
+
+{% block donate-bottom %}
+<a name="wiecej"></a>
+<div class="donation-more">
+ {% chunk "donate-bottom" %}
+</div>
+{% endblock %}
{% csrf_token %}
{{ form.errors }}
<div class="l-checkout__form">
- <div class="l-checkout__form__row">
- <div class="l-checkout__input">
- <label for="id_first_name"><span>*</span> {% trans "Imię" %}</label>
- {{ form.first_name }}
- {{ form.first_name.errors }}
- </div>
- <div class="l-checkout__input">
- <label for="id_last_name"><span>*</span> {% trans "Nazwisko" %}</label>
- {{ form.last_name }}
- {{ form.last_name.errors }}
- </div>
- </div>
- <div class="l-checkout__form__row">
- <div class="l-checkout__input">
+ <div class="l-checkout__form__row full">
+ <div class="l-checkout__input" lang="pl">
<label for="id_email"><span>*</span> {% trans "E-mail" %}</label>
{{ form.email }}
{{ form.email.errors }}
</div>
- <div class="l-checkout__input">
- <label for="id_phone">{% trans "Telefon" %}</label>
- {{ form.phone }}
- {{ form.phone.errors }}
- </div>
- </div>
- <div class="l-checkout__form__row full">
- <div class="l-checkout__input">
- <label for="id_postal">{% trans "Adres pocztowy" %}</label>
- {{ form.postal }}
- {{ form.postal.errors }}
- </div>
</div>
<div class="l-checkout__form__row">
<div class="l-checkout__input">
- <label for="id_postal_code">{% trans "Kod pocztowy" %}</label>
- {{ form.postal_code }}
- {{ form.postal_code.errors }}
- </div>
- <div class="l-checkout__input">
- <label for="id_postal_town">{% trans "Miejscowość" %}</label>
- {{ form.postal_town }}
- {{ form.postal_town.errors }}
+ <label for="id_first_name">{% trans "Imię / pseudonim (opcjonalnie)" %}</label>
+ {{ form.first_name }}
+ {{ form.first_name.errors }}
</div>
- </div>
- <div class="l-checkout__form__row full">
<div class="l-checkout__input">
- <label for="id_postal_country">{% trans "Kraj" %}</label>
- {{ form.postal_country }}
- {{ form.postal_country.errors }}
+ <label for="id_last_name">{% trans "Nazwisko (opcjonalnie)" %}</label>
+ {{ form.last_name }}
+ {{ form.last_name.errors }}
</div>
</div>
+
<div class="l-checkout__form__row full">
{% for consent, key, field in form.consent %}
- {{ field.errors }}
+ {% if not consent.required %}
+ {{ field.errors }}
+ {% endif %}
<div class="c-checkbox">
+ {% if consent.required %}
+ <label><p class="scroll">{{ consent.text|safe }}</p></label>
+ {% else %}
{{ field }}
<label for="id_{{ key }}">
- <p>{% if field.field.required %}<span>*</span> {% endif %}{{ field.label }}</p>
+ <p>{% if field.field.required %}<span>*</span> {% endif %}{{ field.label|safe }}</p>
</label>
+ {% endif %}
</div>
{% endfor %}
<div class="c-checkbox">
{{ form.agree_newsletter }}
<label for="id_agree_newsletter">
- <p>{% trans "Zapisuję się na newsletter." %}</p>
+ <p>{% trans "Chcę dostawać newsletter o działalności Wolnych Lektur" %}</p>
</label>
</div>
</div>
<div class="l-checkout__footer">
<div class="l-checkout__footer__content">
- {% chunk 'donate-bottom' %}
+ {% block donate-bottom %}{% endblock %}
+ <a name="informacje"></a>
<div class="l-checkout__footer__content__item">
<h3>{% trans "Transparentność jest dla nas bardzo ważna." %}</h3>
<div>
}
}
+
.annoy-banner_book-page-center {
background: white;
margin-top: 50px;
}
}
}
+
+
+
+
+
+.annoy-banner_seasonal {
+ background-color: #ffd430;
+ color: #083F4D;
+ border-radius: 10px;
+ padding: 15px 20px;
+ margin-top: 20px;
+ cursor: pointer;
+
+ .annoy-banner-inner {
+ display: flex;
+ flex-direction: row;
+ gap: 20px;
+ align-items: flex-start;
+ justify-content: space-between;
+
+ p {
+ margin: 0;
+ }
+ a {
+ line-height: 1.35;
+ color: #c32721;
+ white-space: nowrap;
+ border: solid #c32721;
+ border-width: 0 0 1px;
+
+ &:hover {
+ text-decoration: none;
+ border-bottom-width: 2px;
+ }
+ }
+ a.action {
+ color: #fff;
+ background: #c92834;
+ padding: 9px 20px;
+ font-weight: 600;
+ border-radius: 15px;
+ border-width: 0;
+ &:hover {
+ border-bottom-width: 0;
+ }
+ }
+
+ }
+ .state-box {
+ margin-top: 15px;
+ }
+ .bar-status-box {
+ display: flex;
+ justify-content: space-between;
+ }
+}
flex-direction: row;
}
- &:nth-child(4) {
- .l-checkout__input {
- &:nth-child(1) { width: 172px; }
- &:nth-child(2) { width: calc(100% - 172px); }
- }
- }
-
&.full {
flex-direction: column;
@include rwd($break-flow) {
border: 1px solid #edc016;
background: #edc016;
}
+
+
+.donation-more {
+ margin-bottom:40px;
+}
history.pushState({}, '', anchor);
},
});
+ return true;
}
}
}
scrollToAnchor(window.location.hash)
- $('#toc, #themes, #book-text, #annotation').on('click', 'a', function(event) {
- event.preventDefault();
- scrollToAnchor($(this).attr('href'));
+ $('#toc, #themes, #book-text, #annotation, .scroll').on('click', 'a', function(event) {
+ if (scrollToAnchor($(this).attr('href'))) {
+ event.preventDefault();
+ }
});
-
})})(jQuery);
$(".c-media__settings").toggleClass('active');
});
- const crisis = document.querySelector(".annoy-banner_crisis-container");
- const crisisLink = document.querySelector('.annoy-banner_crisis-container a.action');
- if (crisis) {
- crisis.addEventListener("click", function() {
- crisisLink.click();
- });
- }
+ $(".annoy-banner-clickable").each(function() {
+ $(this).click(() => {
+ $("a.action", this).click();
+ });
+ });
})();
{% load funding_tags %}
{% load piwik_tags %}
{% load title %}
+{% load annoy %}
{% block settings %}
{% endblock %}
-<html class="no-js">
+<html class="no-js" lang="{{ LANGUAGE_CODE }}">
<head>
<meta charset="utf-8">
<meta name="description" content="">
</div>
{% endif %}
+ {% annoy_banner_seasonal %}
+
{% block global-content %}
<div class="l-container l-breadcrumb-container">
<div class="l-breadcrumb">