Merge pull request #133 from levivm/feature/new_digitalglarus

Feature/new digitalglarus
This commit is contained in:
Levi Velázquez 2016-10-18 23:31:55 -05:00 committed by GitHub
commit 8b75ddd64f
14 changed files with 201 additions and 87 deletions

View File

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2016-10-17 19:58
from __future__ import unicode_literals
import datetime
from django.db import migrations, models
from django.utils.timezone import utc
class Migration(migrations.Migration):
dependencies = [
('digitalglarus', '0020_auto_20161013_0253'),
]
operations = [
migrations.AddField(
model_name='membership',
name='end_date',
field=models.DateField(default=datetime.datetime(2016, 10, 17, 19, 58, 0, 209303, tzinfo=utc)),
preserve_default=False,
),
migrations.AddField(
model_name='membership',
name='start_date',
field=models.DateField(default=datetime.datetime(2016, 10, 17, 19, 58, 7, 361473, tzinfo=utc)),
preserve_default=False,
),
migrations.AddField(
model_name='membershiporder',
name='end_date',
field=models.DateField(default=datetime.datetime(2016, 10, 17, 19, 58, 15, 657240, tzinfo=utc)),
preserve_default=False,
),
migrations.AddField(
model_name='membershiporder',
name='start_date',
field=models.DateField(default=datetime.datetime(2016, 10, 17, 19, 58, 16, 897120, tzinfo=utc)),
preserve_default=False,
),
]

View File

@ -62,6 +62,13 @@ class MembershipType(models.Model):
class Membership(models.Model):
type = models.ForeignKey(MembershipType)
active = models.BooleanField(default=True)
start_date = models.DateField()
end_date = models.DateField()
@classmethod
def get_by_user(cls, user):
return cls.objects.\
filter(membershiporder__customer__user=user).last()
@classmethod
def create(cls, data):
@ -79,6 +86,11 @@ class Membership(models.Model):
return cls.objects.filter(has_order_past_month | has_order_current_month).\
filter(active_membership).exists()
def update_dates(self, start_date, end_date):
self.start_date = start_date
self.end_date = end_date
self.save()
def deactivate(self):
self.active = False
self.save()
@ -86,17 +98,19 @@ class Membership(models.Model):
class MembershipOrder(Ordereable, models.Model):
membership = models.ForeignKey(Membership)
start_date = models.DateField()
end_date = models.DateField()
@classmethod
def current_membership(cls, user):
last_payment = cls.objects.\
last_membership_payment = cls.objects.\
filter(customer__user=user).last()
start_date = last_payment.created_at
_, days_in_month = calendar.monthrange(start_date.year,
start_date.month)
start_date.replace(day=1)
end_date = start_date + timedelta(days=days_in_month)
return start_date, end_date
# start_date = last_payment.created_at
# _, days_in_month = calendar.monthrange(start_date.year,
# start_date.month)
# start_date.replace(day=1)
# end_date = start_date + timedelta(days=days_in_month)
return last_membership_payment.start_date, last_membership_payment.end_date
def first_membership_range_date(self):
start_date = self.created_at

View File

@ -1172,11 +1172,11 @@ footer {
}
.map-caption{
text-transform: none;
text-transform:uppercase;
font-size: 13px;
font-family:"Montserrat","Helvetica Neue",Helvetica, Arial,sans-serif;
font-weight: 400;
color: #ffffff;
font-size: 14px;
letter-spacing: 1px;
text-align:center;
}

View File

@ -18,4 +18,6 @@ $( document ).ready(function() {
});
});

View File

@ -55,8 +55,13 @@
<hr class="greyline-long">
<h2 class="col-xs-6 payment-total text-left"> Total</h2>
<h2 class="order-result">{{final_price|floatformat}}CHF</h2>
<br>
<br>
<p class="order-bottom-text">
View my bookings <a href="{% url 'digitalglarus:booking_orders_list' %}">Go to my page</a>
</p>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-lg-4 wow fadeInDown hidden-print">

View File

@ -24,6 +24,7 @@
<th>#</th>
<th>Booking dates</th>
<th>Days</th>
<th>Membership Required Months</th>
<th>Invoice</th>
</tr>
</thead>
@ -33,6 +34,7 @@
<th scope="row">{{order.id}}</th>
<td>{{order.booking.start_date}}-{{order.booking.end_date}}</td>
<td>{{order.booking_days}}</td>
<td>{{order.membership_required_months}}</td>
<td><a class="btn btn-xs btn-primary btn-darkgrey" href="{% url 'digitalglarus:booking_orders_detail' order.id %}">View</a></td>
</tr>
{% endfor %}

View File

@ -18,6 +18,10 @@
padding: .5em;
padding-right: 1.5em
}
.order-bottom-text a{
margin-left: 0px;
}
</style>
<section id="price">
@ -140,9 +144,10 @@
<h2 class="order-name">Booking Summary</h2>
</div>
<div class="order-box">
<h3 class="col-xs-6 order-item">Dates {{start_date}} - {{end_date}}</h3>
<br/>
<h3 class="col-xs-6 order-item">Dates {{start_date}} - {{end_date}}</h3>
<p class="order-bottom-text">
<a href="{{request.META.HTTP_REFERER}}">Change dates</a>
</p>
<hr class="greyline">
<h2 class="col-xs-6 payment-total">Total days: {{booking_days}} </h2>
<h2 class="order-sum">{{original_price|floatformat}}CHF</h2>
@ -168,7 +173,7 @@
<div class="button-box">
<div class="row">
<div class="col-xs-12">
<button id="payment_button" class="btn btn-primary btn-lg btn-blck " type="submit">Book</button>
<button id="payment_button" class="btn btn-primary btn-md btn-blck " type="submit">Book</button>
</div>
</div>
</div>

View File

@ -3,6 +3,15 @@
{% block title %}crowdfunding{% endblock %}
{% block content %}
<style type="text/css">
#cancel-subscription-modal{
margin-top:10%;
}
</style>
<section id="price">
<div class="signup-container">
<div class="col-xs-12 col-sm-3 col-lg-4 text-center wow fadeInDown"> </div>
@ -25,6 +34,7 @@
<button type="button" class="btn btn-primary btn-blue" data-toggle="modal" data-target="#cancel-subscription-modal">Cancel my Membership</button>
<div class="modal fade bs-example-modal-sm" id="cancel-subscription-modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
@ -36,7 +46,7 @@
<p>Do you want to cancel your subscription?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
<button type="button" class="btn btn-primary btn-grey" data-dismiss="modal">No</button>
<button type="submit" class="btn btn-primary">Yes</button>
</div>
</div><!-- /.modal-content -->
@ -49,7 +59,7 @@
</div>
<div class="notice-box text-left">
<p class="order-bottom-text">
Your membership wouldn't be automatically renewed each month.
Your membership wouldn't be automatically renewed each month. <a href="{{request.META.HTTP_REFERER}}">Go back</a>
</p>
</div>
</div>

View File

@ -17,7 +17,7 @@
<div class="signup-container">
<div class="col-xs-12 col-sm-6 col-lg-8 text-center wow fadeInDown">
<div class="payment-box">
<h2 class="section-heading payment-head">Your membership invoice for {{order.created_at|date:"F"}}</h2>
<h2 class="section-heading payment-head">Your membership invoice for {{order.created_at|date:"Y-m"}}</h2>
<hr class="greyline-long">
<h2 class="billing-head">Invoice<btn class="btn btn-primary btn-grey btn-edit print hidden-print" data-print="price">Get PDF</btn></h2>

View File

@ -14,7 +14,7 @@
<h2 class="order-head">Member Name</h2>
<h2 class="member-name">{{request.user.name}}</h2>
<hr class="greyline-long">
<h2 class="order-head">Active Membership</h2>
<h2 class="order-head">Current Membership</h2>
<h2 class="member-name">{{membership_start_date|date}}-{{membership_end_date|date}}</h2>
<hr class="greyline-long">
<h2 class="order-head">Orders history</h2>

View File

@ -91,6 +91,13 @@
</div>
</div>
<div class="row">
<label class="custom-control custom-checkbox">
<br/>
<input type="checkbox" class="custom-control-input">
<span class="custom-control-indicator"></span>
<span class="custom-control-description">I accept the Digital Glarus <a href=#>Terms and Conditions</a>, <a href=#>Community Guidelines</a> and <a href=#>Privacy Policy</a></span>
</label>
<div class="col-xs-12">
<button class="btn btn-primary btn-md btn-blck " type="submit">Purchase membership</button>
</div>
@ -132,12 +139,6 @@
<h2 class="col-xs-6 payment-total">Total</h2>
<h2 class="order-result">{{membership_type.first_month_price|floatformat}}CHF</h2>
<div class="text-center">
<label class="custom-control custom-checkbox">
<br/>
<input type="checkbox" class="custom-control-input">
<span class="custom-control-indicator"></span>
<span class="custom-control-description">I accept the Digital Glarus <a href=#>Terms and Conditions</a>, <a href=#>Community Guidelines</a> and <a href=#>Privacy Policy</a></span>
</label>
<div class="button-box">
</div>

View File

@ -5,8 +5,8 @@
{% block content %}
<section id="price">
<div class="container">
<div class="row col-md-3 text-center wow fadeInDown"></div>
<div class="row col-md-6 text-center wow fadeInDown">
<div class="row col-md-2 text-center wow fadeInDown"></div>
<div class="row col-md-8 text-center wow fadeInDown">
<div class="price-box">
<span class="glyphicon glyphicon-star"></span>
<h2 class="section-heading">Digital Glarus Membership</h2>
@ -39,7 +39,7 @@
</div>
</div>
<div class="row col-md-3 text-center wow fadeInDown"></div>
<div class="row col-md-2 text-center wow fadeInDown"></div>
</div>
</section>
<!--membership includes-->

View File

@ -24,7 +24,7 @@
<div class="signup-container">
<div class="col-xs-12 col-sm-6 col-lg-8 text-center wow fadeInDown">
<div class="payment-box">
<h2 class="section-heading payment-head">Billing Address Info</h2>
<h2 class="section-heading payment-head">Billing Address</h2>
<!-- <h2 class="membership-amount">35CHF</h2> -->
<hr class="greyline-long">
<h2 class="billing-head">Billing Adress</h2>
@ -35,6 +35,7 @@
{% bootstrap_field field show_label=False type='fields'%}
{% endfor %}
{% bootstrap_form_errors form type='non_fields'%}
<input type="hidden" name="next" value="{{request.META.HTTP_REFERER}}">
<br>
<div class="row">
@ -44,7 +45,7 @@
<h2 class="signup-lead text-center">{{ message }}</h2>
{% endfor %}
{% endif %}
<button id="payment_button" class="btn btn-primary btn-lg btn-blck " type="submit">Save</button>
<button id="payment_button" class="btn btn-primary btn-md btn-blck " type="submit">Save</button>
</div>
</div>
</form>

View File

@ -209,63 +209,83 @@ class BookingPaymentView(LoginRequiredMixin, MembershipRequiredMixin, FormView):
form.add_error("__all__", "Invalid credit card")
return self.render_to_response(self.get_context_data(form=form))
if is_free:
billing_address = form.save()
# if is_free:
# billing_address = form.save()
# Create Billing Address for User if he does not have one
if not customer.user.billing_addresses.count():
data.update({
'user': customer.user.id
# # Create Billing Address for User if he does not have one
# if not customer.user.billing_addresses.count():
# data.update({
# 'user': customer.user.id
# })
# billing_address_user_form = UserBillingAddressForm(data)
# billing_address_user_form.is_valid()
# billing_address_user_form.save()
# # Create membership plan
# booking_data = {
# 'start_date': start_date,
# 'end_date': end_date,
# 'start_date': start_date,
# 'free_days': free_days,
# 'price': normal_price,
# 'final_price': final_price,
# }
# booking = Booking.create(booking_data)
# # Create membership order
# order_data = {
# 'booking': booking,
# 'customer': customer,
# 'billing_address': billing_address,
# 'amount': final_price,
# 'original_price': normal_price,
# 'special_month_price': BookingPrice.objects.last().special_month_price,
# 'membership_required_months': membership_required_months,
# 'membership_required_months_price': membership_required_months_price,
# }
# order = BookingOrder.create(order_data)
# return HttpResponseRedirect(self.get_success_url(order.id))
# If booking is not free, make the stripe charge
if not is_free:
# Make stripe charge to a customer
stripe_utils = StripeUtils()
charge_response = stripe_utils.make_charge(amount=final_price,
customer=customer.stripe_id)
charge = charge_response.get('response_object')
# Check if the payment was approved
if not charge:
context.update({
'paymentError': charge_response.get('error'),
'form': form
})
billing_address_user_form = UserBillingAddressForm(data)
billing_address_user_form.is_valid()
billing_address_user_form.save()
return render(self.request, self.template_name, context)
# Create membership plan
booking_data = {
'start_date': start_date,
'end_date': end_date,
'start_date': start_date,
'free_days': free_days,
'price': normal_price,
'final_price': final_price,
}
booking = Booking.create(booking_data)
# Create membership order
order_data = {
'booking': booking,
'customer': customer,
'billing_address': billing_address,
'amount': final_price,
'original_price': normal_price,
'special_month_price': BookingPrice.objects.last().special_month_price,
'membership_required_months': membership_required_months,
'membership_required_months_price': membership_required_months_price,
}
order = BookingOrder.create(order_data)
return HttpResponseRedirect(self.get_success_url(order.id))
# Make stripe charge to a customer
stripe_utils = StripeUtils()
charge_response = stripe_utils.make_charge(amount=final_price,
customer=customer.stripe_id)
charge = charge_response.get('response_object')
# Check if the payment was approved
if not charge:
context.update({
'paymentError': charge_response.get('error'),
'form': form
})
return render(self.request, self.template_name, context)
charge = charge_response.get('response_object')
charge = charge_response.get('response_object')
# Create Billing Address for Membership Order
billing_address = form.save()
# Check if user had to pay membership months in advaced
# if membership_required_months:
# # Get current user membership
# membership = Membership.get_by_user(self.request.user)
# # Create membership order
# order_data = {
# 'membership': membership,
# 'customer': customer,
# 'billing_address': billing_address,
# 'amount': membership_required_months_price,
# 'start_date': start_date,
# 'end_date': end_date
# }
# MembershipOrder.create(order_data)
# Create Billing Address for User if he does not have one
if not customer.user.billing_addresses.count():
data.update({
@ -275,7 +295,7 @@ class BookingPaymentView(LoginRequiredMixin, MembershipRequiredMixin, FormView):
billing_address_user_form.is_valid()
billing_address_user_form.save()
# Create membership plan
# Create Booking
booking_data = {
'start_date': start_date,
'end_date': end_date,
@ -286,7 +306,7 @@ class BookingPaymentView(LoginRequiredMixin, MembershipRequiredMixin, FormView):
}
booking = Booking.create(booking_data)
# Create membership order
# Create Booking order
order_data = {
'booking': booking,
'customer': customer,
@ -383,8 +403,15 @@ class MembershipPaymentView(LoginRequiredMixin, IsNotMemberMixin, FormView):
billing_address_user_form.is_valid()
billing_address_user_form.save()
# Get membership dates
membership_start_date, membership_end_date = membership_type.first_month_range
# Create membership plan
membership_data = {'type': membership_type}
membership_data = {
'type': membership_type,
'start_date': membership_start_date,
'end_date': membership_end_date
}
membership = Membership.create(membership_data)
# Create membership order
@ -393,7 +420,9 @@ class MembershipPaymentView(LoginRequiredMixin, IsNotMemberMixin, FormView):
'customer': customer,
'billing_address': billing_address,
'stripe_charge': charge,
'amount': membership_type.first_month_price
'amount': membership_type.first_month_price,
'start_date': membership_start_date,
'end_date': membership_end_date
}
membership_order = MembershipOrder.create(order_data)
@ -403,13 +432,11 @@ class MembershipPaymentView(LoginRequiredMixin, IsNotMemberMixin, FormView):
'membership_dates': membership.type.first_month_formated_range
})
start_m_date, end_m_date = membership_order.first_membership_range_date()
context = {
'membership': membership,
'order': membership_order,
'membership_start_date': start_m_date,
'membership_end_date': end_m_date,
'membership_start_date': membership_start_date,
'membership_end_date': membership_end_date,
'base_url': "{0}://{1}".format(request.scheme, request.get_host())
}
@ -475,6 +502,12 @@ class UserBillingAddressView(LoginRequiredMixin, UpdateView):
success_url = reverse_lazy('digitalglarus:user_billing_address')
success_message = "Billing Address Updated"
def get_success_url(self):
next_url = self.request.POST.get('next') if self.request.POST.get('next')\
else self.success_url
return next_url
def form_valid(self, form):
"""
If the form is valid, save the associated model.