working boat form

This commit is contained in:
maxime 2019-06-09 22:12:49 +02:00
parent 7e6fb59f71
commit 7a1335a423
5 changed files with 507 additions and 308 deletions

View File

@ -7,6 +7,8 @@ admin.site.register(Person)
admin.site.register(Company) admin.site.register(Company)
admin.site.register(Employee) admin.site.register(Employee)
admin.site.register(Boat) admin.site.register(Boat)
admin.site.register(BoatInsurance)
admin.site.register(Insurance)
admin.site.register(Port) admin.site.register(Port)
admin.site.register(Dock) admin.site.register(Dock)
admin.site.register(Plug) admin.site.register(Plug)
@ -15,4 +17,5 @@ admin.site.register(Payment)
admin.site.register(Service) admin.site.register(Service)
admin.site.register(Bill) admin.site.register(Bill)
admin.site.register(Stay) admin.site.register(Stay)
admin.site.register(SailsOn)
admin.site.register(Mooring) admin.site.register(Mooring)

View File

@ -7,6 +7,17 @@ from phonenumber_field.formfields import PhoneNumberField
from .models import * from .models import *
class AddressForm(ModelForm):
class Meta:
model = Address
fields = [
'address',
'zip_code',
'city',
'country'
]
class PersonForm(ModelForm): class PersonForm(ModelForm):
class Meta: class Meta:
model = Person model = Person
@ -26,18 +37,56 @@ class PersonForm(ModelForm):
phone = PhoneNumberField(label='Phone Number') phone = PhoneNumberField(label='Phone Number')
""" """
class AddressForm(ModelForm): class CompanyForm(ModelForm):
class Meta: class Meta:
model = Address model = Company
fields = [
'name',
'email',
'phone',
'registration_num']
class InsuranceForm(CompanyForm):
class Meta:
model = Insurance
fields = [ fields = [
'name']
class BoatForm(ModelForm):
class Meta:
model = Boat
fields = ['name',
'registration_num',
'length',
'beam',
'water_draught',
'tonnage',
'water_tank',
'model',
'heating',
'passenger_capacity',
'company',
'picture']
class PortForm(ModelForm):
class Meta:
model = Port
fields = [
'name',
'address', 'address',
'zip_code', 'company']
'city',
'country'
]
"""
name = CharField(label='Name', max_length=50)
address = CharField(label='Address', max_length=50)
company = CharField(label='Company', max_length=50)
"""
class DockForm(ModelForm): class DockForm(ModelForm):
class Meta: class Meta:
model = Dock model = Dock
@ -71,25 +120,10 @@ class DockForm(ModelForm):
DockFormSet = formset_factory(DockForm) DockFormSet = formset_factory(DockForm)
class PortForm(ModelForm):
class Meta:
model = Port
fields = [
'name',
'address',
'company']
"""
name = CharField(label='Name', max_length=50)
address = CharField(label='Address', max_length=50)
company = CharField(label='Company', max_length=50)
"""
class PlugForm(ModelForm): class PlugForm(ModelForm):
class Meta: class Meta:
model = Plug model = Plug
fields = [ fields = [
'name', 'name',
'amperage', 'amperage',
@ -125,45 +159,28 @@ class TapForm(ModelForm):
TapFormSet = formset_factory(TapForm) TapFormSet = formset_factory(TapForm)
class BoatForm(ModelForm):
class Meta:
model = Boat
fields = ['name',
'registration_num',
'length',
'beam',
'water_draught',
'tonnage',
'water_tank',
'model',
'heating',
'passenger_capacity',
'picture']
class StayForm(ModelForm): class StayForm(ModelForm):
class Meta: class Meta:
model = Stay model = Stay
fields = ['arrival', fields = ['arrival',
'departure', 'departure',
'coming_from', 'coming_from',
'going_to', 'going_to',
'no_mooring'] 'no_mooring']
widgets = { widgets = {
#Use localization and bootstrap 3
'datetime': DateTimeWidget(
attrs={'id':"yourdatetimeid"},
usel10n = True)
} }
class MooringForm(ModelForm): class MooringForm(ModelForm):
class Meta: class Meta:
model = Mooring model = Mooring
fields = ['date', fields = ['date',
'dock', 'dock',
'tap', 'tap',
'plug'] 'plug']
MooringFormSet = formset_factory(MooringForm) MooringFormSet = formset_factory(MooringForm)

View File

@ -1,237 +1,331 @@
from django.db import models from django.db import models
from django.db.models import Model, CharField, EmailField, \ from django.db.models import Model, CharField, EmailField, \
DateTimeField, DecimalField, ForeignKey, ManyToManyField, \ DateTimeField, DecimalField, ForeignKey, ManyToManyField, \
IntegerField, ImageField, BooleanField, \ IntegerField, ImageField, BooleanField, \
CASCADE, SET_NULL, PROTECT CASCADE, SET_NULL, PROTECT
from django_countries.fields import CountryField from django_countries.fields import CountryField
from phonenumber_field.modelfields import PhoneNumberField from phonenumber_field.modelfields import PhoneNumberField
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
def validate_positive(value): def validate_positive(value):
if value < 0: if value < 0:
raise ValidationError( raise ValidationError(
_('%(value)s is not a positive number'), _('%(value)s is not a positive number'),
params={'value': value}, params={'value': value},
) )
class Address(Model): class Address(Model):
address = CharField(max_length=200) address = CharField(max_length=200)
zip_code = CharField(max_length=10) zip_code = CharField(max_length=10)
city = CharField(max_length=200) city = CharField(max_length=200)
country = CountryField() country = CountryField()
def __str__(self): # Methods
return '{}, {} - {}, {}'.format(self.address, self.zip_code, def __str__(self):
self.city, self.country) return '{}, {} - {}, {}'.format(self.address, self.zip_code,
self.city, self.country)
class Person(Model):
name = CharField(max_length=50,blank=True,null=True) class Person(Model):
surname = CharField(max_length=50,blank=True,null=True) name = CharField(max_length=50,blank=True,null=True)
nationality = CountryField(blank=True,null=True) surname = CharField(max_length=50,blank=True,null=True)
email = EmailField(max_length=254,blank=True,null=True) nationality = CountryField(blank=True,null=True)
phone = PhoneNumberField(blank=True,null=True) email = EmailField(max_length=254,blank=True,null=True)
phone = PhoneNumberField(blank=True,null=True)
# Foreign keys
address = ForeignKey(Address,on_delete=SET_NULL,blank=True,null=True) # Foreign keys
def __str__(self): address = ForeignKey(Address,on_delete=SET_NULL,blank=True,null=True)
return '{} {}'.format(self.name, self.surname)
# Methods
def __str__(self):
class Company(Model): return '{} {}'.format(self.name, self.surname)
name = CharField(max_length=50)
email = EmailField(max_length=200,blank=True,null=True)
phone = PhoneNumberField(blank=True,null=True) class Company(Model):
registration_num = CharField(max_length=50,blank=True,null=True) name = CharField(max_length=50,blank=True)
email = EmailField(max_length=200,blank=True,null=True)
# Foreign keys phone = PhoneNumberField(blank=True,null=True)
address = ForeignKey(Address,on_delete=SET_NULL,blank=True,null=True) registration_num = CharField(max_length=50,blank=True,null=True)
def __str__(self):
return '{}'.format(self.name) # Foreign keys
address = ForeignKey(Address,on_delete=SET_NULL,blank=True,null=True)
class Insurance(Company):
pass # Methods
def __str__(self):
class Boat(Model): return '{}'.format(self.name)
name = CharField(max_length=50)
registration_num = CharField('Registration number', max_length=20,blank=True,null=True) class Insurance(Company):
length = DecimalField('Length', max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) pass
beam = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive])
water_draught = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) class Boat(Model):
tonnage = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) name = CharField(max_length=50)
water_tank = DecimalField('Water tank capacity', max_digits=7, decimal_places=2, registration_num = CharField('Registration number',
blank=True,null=True, validators=[validate_positive]) max_length=20,
model = CharField(max_length=50,blank=True,null=True) blank=True,
heating = CharField(max_length=50,blank=True,null=True) null=True)
passenger_capacity = IntegerField(blank=True,null=True)
picture = ImageField(upload_to='uploads/', height_field=None, length = DecimalField('Length',
width_field=None, max_length=100, blank=True,null=True) max_digits=7,
decimal_places=2,
# Foreign keys blank=True,null=True,
company = ForeignKey(Company,on_delete=SET_NULL,blank=True,null=True,related_name='+') validators=[validate_positive])
boat_insurance = ManyToManyField( beam = DecimalField(max_digits=7,
Insurance, decimal_places=2,
through='BoatInsurance', blank=True,
through_fields=('boat', 'insurance') null=True,
) validators=[validate_positive])
persons = ManyToManyField(
Person, water_draught = DecimalField(max_digits=7,
through='SailsOn', decimal_places=2,
through_fields=('boat', 'person') blank=True,
) null=True,
def __str__(self): validators=[validate_positive])
return '{}'.format(self.name)
tonnage = DecimalField(max_digits=7,
class SailsOn(Model): decimal_places=2,
boat = ForeignKey(Boat,on_delete=PROTECT) blank=True,
person = ForeignKey(Person,on_delete=PROTECT) null=True,
validators=[validate_positive])
is_captain = BooleanField()
is_crew = BooleanField() water_tank = DecimalField('Water tank capacity',
is_owner = BooleanField() max_digits=7,
is_guest = BooleanField() decimal_places=2,
is_pet = BooleanField() blank=True,
null=True,
class BoatInsurance(Model): validators=[validate_positive])
contract = IntegerField(blank=True,null=True)
date = DateTimeField(auto_now_add=True) model = CharField(max_length=50,blank=True,null=True)
# Foreign keys heating = CharField(max_length=50,blank=True,null=True)
insurance = ForeignKey(Insurance,on_delete=PROTECT)
boat = ForeignKey(Boat,on_delete=PROTECT) passenger_capacity = IntegerField(blank=True,null=True)
class Port(Model): picture = ImageField(upload_to='uploads/',
name = CharField(max_length=50) height_field=None,
width_field=None,
# Foreign keys max_length=100,
address = ForeignKey(Address,on_delete=PROTECT) blank=True,
company = ForeignKey(Company,on_delete=PROTECT) null=True)
employees = ManyToManyField(
Person, # Foreign keys
through='Employee', company = ForeignKey(Company,
through_fields=('port', 'person') on_delete=SET_NULL,
) blank=True,
def __str__(self): null=True,
return '{}'.format(self.name) related_name='+')
boat_insurance = ManyToManyField(
class Employee(Model): Insurance,
position = CharField('Job', max_length=20, blank=True,null=True) through='BoatInsurance',
through_fields=('boat', 'insurance'),
# Foreign keys blank=True
port = ForeignKey(Port,on_delete=PROTECT) )
person = ForeignKey(Person,on_delete=PROTECT)
def __str__(self): persons = ManyToManyField(
return '{}, {} at {}'.format(str(self.person), self.position, Person,
str(self.port)) through='SailsOn',
through_fields=('boat', 'person')
class Dock(Model): )
name = CharField(max_length=10)
length = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) # Methods
width = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) def __str__(self):
depth_min = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) return '{}'.format(self.name)
depth_max = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive])
class SailsOn(Model):
# Foreign keys boat = ForeignKey(Boat,on_delete=PROTECT)
port = ForeignKey(Port,on_delete=PROTECT) person = ForeignKey(Person,on_delete=PROTECT)
def __str__(self):
return '{} : {}'.format(str(self.port), self.num) is_captain = BooleanField()
is_crew = BooleanField()
class Plug(Model): is_owner = BooleanField()
name = CharField(max_length=10) is_guest = BooleanField()
amperage = DecimalField(max_digits=7, decimal_places=2, validators=[validate_positive]) is_pet = BooleanField()
voltage = DecimalField(max_digits=7, decimal_places=2, validators=[validate_positive])
class BoatInsurance(Model):
# Foreign keys contract = IntegerField(blank=True,null=True)
port = ForeignKey(Port,on_delete=PROTECT) date = DateTimeField(auto_now_add=True)
def __str__(self):
return '{} : {}'.format(str(self.port), self.num) # Foreign keys
insurance = ForeignKey(Insurance,on_delete=PROTECT)
class Tap(Model): boat = ForeignKey(Boat,on_delete=PROTECT)
name = CharField(max_length=10)
class Port(Model):
# Foreign keys name = CharField(max_length=50)
port = ForeignKey(Port,on_delete=PROTECT)
def __str__(self): # Foreign keys
return '{} : {}'.format(str(self.port), self.num) address = ForeignKey(Address,on_delete=PROTECT)
company = ForeignKey(Company,on_delete=PROTECT)
class Payment(Model): employees = ManyToManyField(
num = CharField(max_length=40) Person,
date = DateTimeField() through='Employee',
amount = DecimalField(max_digits=7, decimal_places=2) through_fields=('port', 'person'))
pay_type = CharField(
max_length=3, # Methods
choices=[ def __str__(self):
('CSH', 'Cash'), return '{}'.format(self.name)
('CHK', 'Check'),
('TSF', 'Transfer'),
('CRD', 'Credit Card') class Employee(Model):
], position = CharField('Job', max_length=20, blank=True,null=True)
default='CSH'
) # Foreign keys
def __str__(self): port = ForeignKey(Port,on_delete=PROTECT)
return '{} at {}'.format(self.num, str(self.date)) person = ForeignKey(Person,on_delete=PROTECT)
class Service(Model): # Methods
name = CharField(max_length=50) def __str__(self):
def __str__(self): return '{}, {} at {}'.format(str(self.person), self.position,
return '{}'.format(self.name) str(self.port))
class Bill(Model): class Dock(Model):
num = IntegerField() name = CharField(max_length=10)
date = DateTimeField()
total = DecimalField(max_digits=7, decimal_places=2) length = DecimalField(max_digits=7,
decimal_places=2,
# Foreign keys blank=True,
payments = ManyToManyField( null=True,
Payment, validators=[validate_positive])
through='BillPayment',
through_fields=('bill', 'payment') width = DecimalField(max_digits=7,
) decimal_places=2,
def __str__(self): blank=True,
return '{} at {}'.format(self.num, str(self.date)) null=True,
validators=[validate_positive])
class BillLine(Model):
quantity = DecimalField(max_digits=7, decimal_places=2) depth_min = DecimalField(max_digits=7,
value = DecimalField(max_digits=7, decimal_places=2, default=0.) decimal_places=2,
blank=True,
# Foreign keyks null=True,
service = ForeignKey(Service,on_delete=PROTECT) validators=[validate_positive])
bill = ForeignKey(Bill,on_delete=PROTECT)
def __str__(self): depth_max = DecimalField(max_digits=7,
return '{}x {} - {}'.format(self.quantity, str(self.service), decimal_places=2,
str(self.value)) blank=True,
null=True,
class BillPayment(Model): validators=[validate_positive])
amount = DecimalField(max_digits=7, decimal_places=2)
# Foreign keys
# Foreign keys port = ForeignKey(Port,on_delete=PROTECT)
bill = ForeignKey(Bill,on_delete=PROTECT)
payment = ForeignKey(Payment,on_delete=PROTECT) # Methods
def __str__(self):
class Stay(Model): return '{} : {}'.format(str(self.port), self.num)
arrival = DateTimeField()
departure = DateTimeField(blank=True,null=True) class Plug(Model):
coming_from = CharField(max_length=200,blank=True,null=True) name = CharField(max_length=10)
going_to = CharField(max_length=200,blank=True,null=True) amperage = DecimalField(max_digits=7, decimal_places=2,
no_mooring = BooleanField('Set moorings later',default=False,blank=True) validators=[validate_positive])
voltage = DecimalField(max_digits=7, decimal_places=2,
# Foreign keys validators=[validate_positive])
boat = ForeignKey(Boat,on_delete=PROTECT)
bill = ForeignKey(Bill,on_delete=PROTECT,blank=True,null=True) # Foreign keys
def __str__(self): port = ForeignKey(Port,on_delete=PROTECT)
return '{} - {} : {}'.format(self.arrival, self.departure, str(self.boat))
# Methods
class Mooring(Model): def __str__(self):
date = DateTimeField() return '{} : {}'.format(str(self.port), self.num)
# Foreign keys class Tap(Model):
stay = ForeignKey(Stay,on_delete=CASCADE) name = CharField(max_length=10)
dock = ForeignKey(Dock,on_delete=PROTECT)
tap = ForeignKey(Tap,on_delete=PROTECT,blank=True,null=True) # Foreign keys
plug = ForeignKey(Plug,on_delete=PROTECT,blank=True,null=True) port = ForeignKey(Port,on_delete=PROTECT)
# Methods # Methods
def __str__(self): def __str__(self):
return '{} - {} at {}'.format(str(self.date), str(self.stay.boat), str(self.dock)) return '{} : {}'.format(str(self.port), self.num)
class Payment(Model):
num = CharField(max_length=40)
date = DateTimeField()
amount = DecimalField(max_digits=7, decimal_places=2)
pay_type = CharField(
max_length=3,
choices=[
('CSH', 'Cash'),
('CHK', 'Check'),
('TSF', 'Transfer'),
('CRD', 'Credit Card')
],
default='CSH'
)
# Methods
def __str__(self):
return '{} at {}'.format(self.num, str(self.date))
class Service(Model):
name = CharField(max_length=50)
# Methods
def __str__(self):
return '{}'.format(self.name)
class Bill(Model):
num = IntegerField()
date = DateTimeField()
total = DecimalField(max_digits=7, decimal_places=2)
# Foreign keys
payments = ManyToManyField(
Payment,
through='BillPayment',
through_fields=('bill', 'payment')
)
# Methods
def __str__(self):
return '{} at {}'.format(self.num, str(self.date))
class BillLine(Model):
quantity = DecimalField(max_digits=7, decimal_places=2)
value = DecimalField(max_digits=7, decimal_places=2, default=0.)
# Foreign keyks
service = ForeignKey(Service,on_delete=PROTECT)
bill = ForeignKey(Bill,on_delete=PROTECT)
# Methods
def __str__(self):
return '{}x {} - {}'.format(self.quantity, str(self.service),
str(self.value))
class BillPayment(Model):
amount = DecimalField(max_digits=7, decimal_places=2)
# Foreign keys
bill = ForeignKey(Bill,on_delete=PROTECT)
payment = ForeignKey(Payment,on_delete=PROTECT)
class Stay(Model):
arrival = DateTimeField()
departure = DateTimeField(blank=True,null=True)
coming_from = CharField(max_length=200,blank=True,null=True)
going_to = CharField(max_length=200,blank=True,null=True)
no_mooring = BooleanField('Set moorings later',default=False,blank=True)
# Foreign keys
boat = ForeignKey(Boat,on_delete=PROTECT)
bill = ForeignKey(Bill,on_delete=PROTECT,blank=True,null=True)
# Methods
def __str__(self):
return '{} - {} : {}'.format(self.arrival,
self.departure,
str(self.boat))
class Mooring(Model):
date = DateTimeField()
# Foreign keys
stay = ForeignKey(Stay,on_delete=CASCADE)
dock = ForeignKey(Dock,on_delete=PROTECT)
tap = ForeignKey(Tap,on_delete=PROTECT,blank=True,null=True)
plug = ForeignKey(Plug,on_delete=PROTECT,blank=True,null=True)
# Methods
def __str__(self):
return '{} - {} at {}'.format(str(self.date),
str(self.stay.boat),
str(self.dock))

View File

@ -6,9 +6,18 @@
<legend>Boat</legend> <legend>Boat</legend>
{{ boat_form }} {{ boat_form }}
</fieldset> </fieldset>
<fieldset>
<legend>Insurance</legend>
{{ insurance_form }}
</fieldset>
<fieldset>
<legend>Company</legend>
{{ company_form }}
</fieldset>
<fieldset> <fieldset>
<legend>Person</legend> <legend>Person</legend>
{{ person_form }} {{ person_form }}
{{ address_form }}
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>Stay</legend> <legend>Stay</legend>

View File

@ -1,5 +1,6 @@
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse from django.http import HttpResponse
from django.core.exceptions import ValidationError
from pprint import pprint from pprint import pprint
@ -12,38 +13,113 @@ def index(request):
def list_boats(request): def list_boats(request):
return render(request, 'boat/list.html', return render(request, 'boat/list.html',
{'boats': boat.objects.all}) {'boats': Boat.objects.all})
def form(request): def form(request):
boat_form = BoatForm() boat_form = BoatForm(prefix='boa')
person_form = PersonForm() company_form = CompanyForm(prefix='com')
stay_form = StayForm() insurance_form = InsuranceForm(prefix='ins')
mooring_forms = MooringFormSet() person_form = PersonForm(prefix='per')
address_form = AddressForm(prefix='add')
return render(request, 'boat/form.html', stay_form = StayForm(prefix='sta')
mooring_forms = MooringFormSet(prefix='moo')
return render(request, 'boat/form.html',
{'boat_form': boat_form, {'boat_form': boat_form,
'company_form': company_form,
'insurance_form': insurance_form,
'person_form': person_form, 'person_form': person_form,
'address_form': address_form,
'stay_form': stay_form, 'stay_form': stay_form,
'mooring_forms': mooring_forms}) 'mooring_forms': mooring_forms})
def add_boat(request): def add_boat(request):
if request.method == 'POST': if request.method != 'POST':
boat_form = BoatForm(request.POST) return form(request.POST)
if not boat_form.is_valid():
return form(request)
person_form = PersonForm(request.POST)
if not person_form.is_valid():
return form(request)
stay_form = StayForm(request.POST)
if not stay_form.is_valid():
return form(request)
if stay_form.no_mooring is not True:
mooring_forms = MooringFormSet(request.POST)
mooring_forms_data = mooring_forms.save(commit=False)
for mooring_data in mooring_forms_data:
pass
return form(request) try:
new_boat_form = BoatForm(request.POST, prefix='boa')
new_boat = new_boat_form.save(commit=False)
pprint(new_boat)
# TODO : Handle case where insurance is already existing
# if not new_boat.boat_insurance:
# When the boat's insurance is not specified, it means we need to
# create a new insurance
# new_insurance = InsuranceForm(request.POST).save(commit=False)
#else:
# new_insurance = None
new_insurance = InsuranceForm(request.POST, prefix='ins').save(commit=False)
if not new_boat.company:
# When the boat's company is not specified, it means we need to
# create a new company
try:
new_company = CompanyForm(request.POST, prefix='com').save(commit=False)
except:
return form(request)
else:
new_company = None
new_person = PersonForm(request.POST, prefix='per').save(commit=False)
new_address = AddressForm(request.POST, prefix='add').save(commit=False)
new_stay = StayForm(request.POST, prefix='sta').save(commit=False)
if new_stay.no_mooring is not True:
new_moorings = MooringFormSet(request.POST, prefix='moo').save(commit=False)
for mooring in new_moorings:
# Check if mooring is between the date of stay
if new_stay.arrival > mooring.date:
mooring = False
elif new_stay.departure is not None and\
new_stay.departure < mooring.date:
mooring = False
# Check if dock is available
else:
# Set the moorings later
new_moorings = []
if new_company is not None:
new_boat.company = new_company.save()
new_boat.save()
if new_insurance is not None:
new_insurance.save()
# Set insurance for boat since current date
BoatInsurance.objects.create(
insurance = new_insurance,
boat = new_boat
)
new_person.address = new_address.save()
new_person.save()
# Say that person is sailing on boat
SailsOn.objects.create(
boat = new_boat,
person = new_person,
is_captain = False,
is_crew = False,
is_owner = False,
is_guest = False,
is_pet = True)
new_stay.boat = new_boat
new_stay.save()
for mooring in new_moorings:
morring.stay = new_stay
mooring.save()
new_boat_form.save_m2m()
except ValidationError as err:
pprint(err)
return form(request)
return list_boats(request)