Browse Source

Add bike app with base model.

feature/bike-tracking
Drew Larson 8 years ago
parent
commit
77f4117821
  1. 0
      bikeshop_project/bike/__init__.py
  2. 3
      bikeshop_project/bike/admin.py
  3. 5
      bikeshop_project/bike/apps.py
  4. 44
      bikeshop_project/bike/migrations/0001_bike_with_fsm.py
  5. 27
      bikeshop_project/bike/migrations/0002_auto_20170105_0238.py
  6. 0
      bikeshop_project/bike/migrations/__init__.py
  7. 123
      bikeshop_project/bike/models.py
  8. 3
      bikeshop_project/bike/tests.py
  9. 3
      bikeshop_project/bike/views.py
  10. 1
      bikeshop_project/bikeshop/settings/base.py

0
bikeshop_project/bike/__init__.py

3
bikeshop_project/bike/admin.py

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
bikeshop_project/bike/apps.py

@ -0,0 +1,5 @@
from django.apps import AppConfig
class BikeConfig(AppConfig):
name = 'bike'

44
bikeshop_project/bike/migrations/0001_bike_with_fsm.py

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2017-01-05 02:27
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import django_fsm
class Migration(migrations.Migration):
initial = True
dependencies = [
('registration', '0002_auto_20161130_0157'),
]
operations = [
migrations.CreateModel(
name='Bike',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('colour', models.TextField()),
('make', models.TextField()),
('size', models.TextField(choices=[('C', 'child'), ('M', 'medium'), ('L', 'large'), ('XL', 'extra large')], max_length=2)),
('serial_number', models.TextField()),
('source', models.TextField(choices=[('COS_BIKE_DIVERSION_PILOT', 'City of Saskatoon Bike Diversion Pilot'), ('UOFS', 'University of Saskatchewan'), ('DROP_OFF', 'Drop Off')])),
('stripped', models.NullBooleanField()),
('price', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True)),
('state', django_fsm.FSMField(choices=[('RECEIVED', 'Received'), ('ASSESSED', 'Assessed'), ('AVAILABLE', 'CPIC Searched'), ('CLAIMED', 'Claimed'), ('SCRAPPED', 'Scrapped'), ('PURCHASED', 'Purchased'), ('TRANSFERRED_TO_POLICE', 'Transferred to police')], default='RECEIVED', max_length=50, protected=True)),
('stolen', models.NullBooleanField()),
('donated_by', models.TextField()),
('donated_at', models.DateField()),
('created_at', models.DateTimeField(default=django.utils.timezone.now)),
('modified_at', models.DateTimeField(auto_now=True)),
('cpic_searched_at', models.DateTimeField(blank=True, null=True)),
('claimed_at', models.DateTimeField(blank=True, null=True)),
('last_worked_on', models.DateTimeField(blank=True, null=True)),
('purchased_at', models.DateTimeField(blank=True, null=True)),
('claimed_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='registration.Member')),
],
),
]

27
bikeshop_project/bike/migrations/0002_auto_20170105_0238.py

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2017-01-05 02:38
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('registration', '0002_auto_20161130_0157'),
('bike', '0001_bike_with_fsm'),
]
operations = [
migrations.AddField(
model_name='bike',
name='purchased_by',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='purchased_bike', to='registration.Member'),
),
migrations.AlterField(
model_name='bike',
name='claimed_by',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='claimed_bike', to='registration.Member'),
),
]

0
bikeshop_project/bike/migrations/__init__.py

123
bikeshop_project/bike/models.py

@ -0,0 +1,123 @@
from datetime import timedelta
from django.db import models
from django.utils import timezone
from django_fsm import FSMField, transition
from registration.models import Member
class BikeState(object):
RECEIVED = 'RECEIVED'
ASSESSED = 'ASSESSED'
AVAILABLE = 'AVAILABLE'
CLAIMED = 'CLAIMED'
PURCHASED = 'PURCHASED'
SCRAPPED = 'SCRAPPED'
TRANSFERRED_TO_POLICE = 'TRANSFERRED_TO_POLICE'
CHOICES = (
(RECEIVED, 'Received'),
(ASSESSED, 'Assessed'),
(AVAILABLE, 'CPIC Searched'),
(CLAIMED, 'Claimed'),
(SCRAPPED, 'Scrapped'),
(PURCHASED, 'Purchased'),
(TRANSFERRED_TO_POLICE, 'Transferred to police')
)
class Bike(models.Model):
CHILD = 'C'
SMALL = 'S'
MEDIUM = 'M'
LARGE = 'L'
EXTRA_LARGE = 'XL'
size_choices = (
(CHILD, 'child'),
(MEDIUM, 'medium'),
(LARGE, 'large'),
(EXTRA_LARGE, 'extra large'),
)
COS_BIKE_DIVERSION_PILOT = 'COS_BIKE_DIVERSION_PILOT'
UOFS = 'UOFS'
DROP_OFF = 'DROP_OFF'
source_choices = (
(COS_BIKE_DIVERSION_PILOT, 'City of Saskatoon Bike Diversion Pilot'),
(UOFS, 'University of Saskatchewan'),
(DROP_OFF, 'Drop Off'),
)
colour = models.TextField(blank=False, null=False)
make = models.TextField(blank=False, null=False)
size = models.TextField(choices=size_choices, max_length=2)
serial_number = models.TextField(blank=False, null=False)
source = models.TextField(blank=False, null=False, choices=source_choices)
stripped = models.NullBooleanField()
price = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
state = FSMField(default=BikeState.RECEIVED, choices=BikeState.CHOICES, protected=True)
claimed_by = models.ForeignKey(Member, on_delete=models.SET_NULL, null=True, related_name='claimed_bike')
stolen = models.NullBooleanField()
purchased_by = models.ForeignKey(Member, on_delete=models.SET_NULL, null=True, related_name='purchased_bike')
donated_by = models.TextField()
donated_at = models.DateField(blank=False, null=False)
created_at = models.DateTimeField(default=timezone.now)
modified_at = models.DateTimeField(auto_now=True)
cpic_searched_at = models.DateTimeField(blank=True, null=True)
claimed_at = models.DateTimeField(blank=True, null=True)
last_worked_on = models.DateTimeField(blank=True, null=True)
purchased_at = models.DateTimeField(blank=True, null=True)
def can_assessed(self):
return self.colour is not None and self.make is not None and self.size is not None and self.source is not None \
and self.price is not None
def can_available(self):
return self.stolen is not None and self.cpic_searched_at is not None and self.serial_number is not None
def can_claim(self):
return self.claimed_by is None or self.last_worked_on > timezone.now() + timedelta(weeks=4)
def can_purchase(self):
if self.claimed_by:
return self.can_claim()
return self.purchased_by is None
def can_scrap(self):
return self.stripped is not None
def can_transfer_to_police(self):
return self.stolen
@transition(field=state, source=[BikeState.RECEIVED], target=BikeState.ASSESSED, conditions=[can_assessed])
def assessed(self):
pass
@transition(field=state, source=[BikeState.ASSESSED, BikeState.RECEIVED], target=BikeState.AVAILABLE,
conditions=[can_available])
def available(self):
pass
@transition(field=state, source=[BikeState.AVAILABLE], target=BikeState.CLAIMED, conditions=[can_claim])
def claim(self, member):
self.claimed_by = member
self.claimed_at = timezone.now()
self.last_worked_on = timezone.now()
@transition(field=state, source=[BikeState.AVAILABLE, BikeState.CLAIMED], target=BikeState.PURCHASED,
conditions=[can_purchase])
def purchase(self, member):
self.purchased_at = timezone.now()
self.purchased_by = member
@transition(field=state, source=[BikeState.ASSESSED, BikeState.AVAILABLE, BikeState.CLAIMED],
target=BikeState.SCRAPPED, conditions=[can_scrap])
def scrap(self):
pass
@transition(field=state, source=[BikeState.ASSESSED, BikeState.RECEIVED], conditions=[can_transfer_to_police])
def transfer_to_police(self):
pass

3
bikeshop_project/bike/tests.py

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
bikeshop_project/bike/views.py

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

1
bikeshop_project/bikeshop/settings/base.py

@ -36,6 +36,7 @@ INSTALLED_APPS = [
'registration',
'core',
'bike',
]
MIDDLEWARE_CLASSES = [

Loading…
Cancel
Save