diff --git a/port/admin.py b/port/admin.py index 469cd5b..452653c 100644 --- a/port/admin.py +++ b/port/admin.py @@ -7,6 +7,8 @@ admin.site.register(Person) admin.site.register(Company) admin.site.register(Employee) admin.site.register(Boat) +admin.site.register(BoatInsurance) +admin.site.register(Insurance) admin.site.register(Port) admin.site.register(Dock) admin.site.register(Plug) @@ -15,4 +17,5 @@ admin.site.register(Payment) admin.site.register(Service) admin.site.register(Bill) admin.site.register(Stay) +admin.site.register(SailsOn) admin.site.register(Mooring) diff --git a/port/forms.py b/port/forms.py index ed0a685..b362b3d 100644 --- a/port/forms.py +++ b/port/forms.py @@ -7,6 +7,17 @@ from phonenumber_field.formfields import PhoneNumberField from .models import * +class AddressForm(ModelForm): + class Meta: + model = Address + + fields = [ + 'address', + 'zip_code', + 'city', + 'country' + ] + class PersonForm(ModelForm): class Meta: model = Person @@ -26,18 +37,56 @@ class PersonForm(ModelForm): phone = PhoneNumberField(label='Phone Number') """ -class AddressForm(ModelForm): +class CompanyForm(ModelForm): class Meta: - model = Address + model = Company + + fields = [ + 'name', + 'email', + 'phone', + 'registration_num'] + +class InsuranceForm(CompanyForm): + class Meta: + model = Insurance 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', - 'zip_code', - 'city', - 'country' - ] - + 'company'] + """ + 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 Meta: model = Dock @@ -71,25 +120,10 @@ class DockForm(ModelForm): 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 Meta: model = Plug - + fields = [ 'name', 'amperage', @@ -125,45 +159,28 @@ class TapForm(ModelForm): 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 Meta: model = Stay + fields = ['arrival', 'departure', 'coming_from', 'going_to', 'no_mooring'] widgets = { - #Use localization and bootstrap 3 - 'datetime': DateTimeWidget( - attrs={'id':"yourdatetimeid"}, - usel10n = True) } class MooringForm(ModelForm): - class Meta: model = Mooring + fields = ['date', 'dock', 'tap', 'plug'] - + MooringFormSet = formset_factory(MooringForm) diff --git a/port/models.py b/port/models.py index 76f5967..0431921 100644 --- a/port/models.py +++ b/port/models.py @@ -1,237 +1,331 @@ -from django.db import models -from django.db.models import Model, CharField, EmailField, \ - DateTimeField, DecimalField, ForeignKey, ManyToManyField, \ - IntegerField, ImageField, BooleanField, \ - CASCADE, SET_NULL, PROTECT -from django_countries.fields import CountryField -from phonenumber_field.modelfields import PhoneNumberField -from django.core.exceptions import ValidationError -from django.utils.translation import gettext_lazy as _ - -def validate_positive(value): - if value < 0: - raise ValidationError( - _('%(value)s is not a positive number'), - params={'value': value}, - ) - -class Address(Model): - address = CharField(max_length=200) - zip_code = CharField(max_length=10) - city = CharField(max_length=200) - country = CountryField() - - def __str__(self): - return '{}, {} - {}, {}'.format(self.address, self.zip_code, - self.city, self.country) - -class Person(Model): - name = CharField(max_length=50,blank=True,null=True) - surname = CharField(max_length=50,blank=True,null=True) - nationality = CountryField(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) - def __str__(self): - return '{} {}'.format(self.name, self.surname) - - -class Company(Model): - name = CharField(max_length=50) - email = EmailField(max_length=200,blank=True,null=True) - phone = PhoneNumberField(blank=True,null=True) - registration_num = CharField(max_length=50,blank=True,null=True) - - # Foreign keys - address = ForeignKey(Address,on_delete=SET_NULL,blank=True,null=True) - def __str__(self): - return '{}'.format(self.name) - -class Insurance(Company): - pass - -class Boat(Model): - name = CharField(max_length=50) - registration_num = CharField('Registration number', max_length=20,blank=True,null=True) - length = DecimalField('Length', max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) - 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]) - tonnage = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) - water_tank = DecimalField('Water tank capacity', max_digits=7, decimal_places=2, - blank=True,null=True, validators=[validate_positive]) - model = CharField(max_length=50,blank=True,null=True) - heating = CharField(max_length=50,blank=True,null=True) - passenger_capacity = IntegerField(blank=True,null=True) - picture = ImageField(upload_to='uploads/', height_field=None, - width_field=None, max_length=100, blank=True,null=True) - - # Foreign keys - company = ForeignKey(Company,on_delete=SET_NULL,blank=True,null=True,related_name='+') - - boat_insurance = ManyToManyField( - Insurance, - through='BoatInsurance', - through_fields=('boat', 'insurance') - ) - persons = ManyToManyField( - Person, - through='SailsOn', - through_fields=('boat', 'person') - ) - def __str__(self): - return '{}'.format(self.name) - -class SailsOn(Model): - boat = ForeignKey(Boat,on_delete=PROTECT) - person = ForeignKey(Person,on_delete=PROTECT) - - is_captain = BooleanField() - is_crew = BooleanField() - is_owner = BooleanField() - is_guest = BooleanField() - is_pet = BooleanField() - -class BoatInsurance(Model): - contract = IntegerField(blank=True,null=True) - date = DateTimeField(auto_now_add=True) - - # Foreign keys - insurance = ForeignKey(Insurance,on_delete=PROTECT) - boat = ForeignKey(Boat,on_delete=PROTECT) - -class Port(Model): - name = CharField(max_length=50) - - # Foreign keys - address = ForeignKey(Address,on_delete=PROTECT) - company = ForeignKey(Company,on_delete=PROTECT) - employees = ManyToManyField( - Person, - through='Employee', - through_fields=('port', 'person') - ) - def __str__(self): - return '{}'.format(self.name) - - -class Employee(Model): - position = CharField('Job', max_length=20, blank=True,null=True) - - # Foreign keys - port = ForeignKey(Port,on_delete=PROTECT) - person = ForeignKey(Person,on_delete=PROTECT) - def __str__(self): - return '{}, {} at {}'.format(str(self.person), self.position, - str(self.port)) - -class Dock(Model): - name = CharField(max_length=10) - length = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) - width = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) - depth_min = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) - depth_max = DecimalField(max_digits=7, decimal_places=2, blank=True,null=True, validators=[validate_positive]) - - # Foreign keys - port = ForeignKey(Port,on_delete=PROTECT) - def __str__(self): - return '{} : {}'.format(str(self.port), self.num) - -class Plug(Model): - name = CharField(max_length=10) - amperage = DecimalField(max_digits=7, decimal_places=2, validators=[validate_positive]) - voltage = DecimalField(max_digits=7, decimal_places=2, validators=[validate_positive]) - - # Foreign keys - port = ForeignKey(Port,on_delete=PROTECT) - def __str__(self): - return '{} : {}'.format(str(self.port), self.num) - -class Tap(Model): - name = CharField(max_length=10) - - # Foreign keys - port = ForeignKey(Port,on_delete=PROTECT) - def __str__(self): - 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' - ) - def __str__(self): - return '{} at {}'.format(self.num, str(self.date)) - -class Service(Model): - name = CharField(max_length=50) - 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') - ) - 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) - 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) - 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)) +from django.db import models +from django.db.models import Model, CharField, EmailField, \ + DateTimeField, DecimalField, ForeignKey, ManyToManyField, \ + IntegerField, ImageField, BooleanField, \ + CASCADE, SET_NULL, PROTECT +from django_countries.fields import CountryField +from phonenumber_field.modelfields import PhoneNumberField +from django.core.exceptions import ValidationError +from django.utils.translation import gettext_lazy as _ + +def validate_positive(value): + if value < 0: + raise ValidationError( + _('%(value)s is not a positive number'), + params={'value': value}, + ) + +class Address(Model): + address = CharField(max_length=200) + zip_code = CharField(max_length=10) + city = CharField(max_length=200) + country = CountryField() + + # Methods + def __str__(self): + return '{}, {} - {}, {}'.format(self.address, self.zip_code, + self.city, self.country) + +class Person(Model): + name = CharField(max_length=50,blank=True,null=True) + surname = CharField(max_length=50,blank=True,null=True) + nationality = CountryField(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) + + # Methods + def __str__(self): + return '{} {}'.format(self.name, self.surname) + + +class Company(Model): + name = CharField(max_length=50,blank=True) + email = EmailField(max_length=200,blank=True,null=True) + phone = PhoneNumberField(blank=True,null=True) + registration_num = CharField(max_length=50,blank=True,null=True) + + # Foreign keys + address = ForeignKey(Address,on_delete=SET_NULL,blank=True,null=True) + + # Methods + def __str__(self): + return '{}'.format(self.name) + +class Insurance(Company): + pass + +class Boat(Model): + name = CharField(max_length=50) + registration_num = CharField('Registration number', + max_length=20, + blank=True, + null=True) + + length = DecimalField('Length', + max_digits=7, + decimal_places=2, + blank=True,null=True, + validators=[validate_positive]) + + 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]) + + tonnage = DecimalField(max_digits=7, + decimal_places=2, + blank=True, + null=True, + validators=[validate_positive]) + + water_tank = DecimalField('Water tank capacity', + max_digits=7, + decimal_places=2, + blank=True, + null=True, + validators=[validate_positive]) + + model = CharField(max_length=50,blank=True,null=True) + + heating = CharField(max_length=50,blank=True,null=True) + + passenger_capacity = IntegerField(blank=True,null=True) + + picture = ImageField(upload_to='uploads/', + height_field=None, + width_field=None, + max_length=100, + blank=True, + null=True) + + # Foreign keys + company = ForeignKey(Company, + on_delete=SET_NULL, + blank=True, + null=True, + related_name='+') + + boat_insurance = ManyToManyField( + Insurance, + through='BoatInsurance', + through_fields=('boat', 'insurance'), + blank=True + ) + + persons = ManyToManyField( + Person, + through='SailsOn', + through_fields=('boat', 'person') + ) + + # Methods + def __str__(self): + return '{}'.format(self.name) + +class SailsOn(Model): + boat = ForeignKey(Boat,on_delete=PROTECT) + person = ForeignKey(Person,on_delete=PROTECT) + + is_captain = BooleanField() + is_crew = BooleanField() + is_owner = BooleanField() + is_guest = BooleanField() + is_pet = BooleanField() + +class BoatInsurance(Model): + contract = IntegerField(blank=True,null=True) + date = DateTimeField(auto_now_add=True) + + # Foreign keys + insurance = ForeignKey(Insurance,on_delete=PROTECT) + boat = ForeignKey(Boat,on_delete=PROTECT) + +class Port(Model): + name = CharField(max_length=50) + + # Foreign keys + address = ForeignKey(Address,on_delete=PROTECT) + company = ForeignKey(Company,on_delete=PROTECT) + employees = ManyToManyField( + Person, + through='Employee', + through_fields=('port', 'person')) + + # Methods + def __str__(self): + return '{}'.format(self.name) + + +class Employee(Model): + position = CharField('Job', max_length=20, blank=True,null=True) + + # Foreign keys + port = ForeignKey(Port,on_delete=PROTECT) + person = ForeignKey(Person,on_delete=PROTECT) + + # Methods + def __str__(self): + return '{}, {} at {}'.format(str(self.person), self.position, + str(self.port)) + +class Dock(Model): + name = CharField(max_length=10) + + length = DecimalField(max_digits=7, + decimal_places=2, + blank=True, + null=True, + validators=[validate_positive]) + + width = DecimalField(max_digits=7, + decimal_places=2, + blank=True, + null=True, + validators=[validate_positive]) + + depth_min = DecimalField(max_digits=7, + decimal_places=2, + blank=True, + null=True, + validators=[validate_positive]) + + depth_max = DecimalField(max_digits=7, + decimal_places=2, + blank=True, + null=True, + validators=[validate_positive]) + + # Foreign keys + port = ForeignKey(Port,on_delete=PROTECT) + + # Methods + def __str__(self): + return '{} : {}'.format(str(self.port), self.num) + +class Plug(Model): + name = CharField(max_length=10) + amperage = DecimalField(max_digits=7, decimal_places=2, + validators=[validate_positive]) + voltage = DecimalField(max_digits=7, decimal_places=2, + validators=[validate_positive]) + + # Foreign keys + port = ForeignKey(Port,on_delete=PROTECT) + + # Methods + def __str__(self): + return '{} : {}'.format(str(self.port), self.num) + +class Tap(Model): + name = CharField(max_length=10) + + # Foreign keys + port = ForeignKey(Port,on_delete=PROTECT) + + # Methods + def __str__(self): + 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)) diff --git a/port/templates/boat/form.html b/port/templates/boat/form.html index 87e2889..f14fccf 100644 --- a/port/templates/boat/form.html +++ b/port/templates/boat/form.html @@ -6,9 +6,18 @@ {{ boat_form }} +
+