Skip to content
This repository has been archived by the owner on Jan 10, 2020. It is now read-only.

Added initial migration for the old old system. #5

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions stregsystem/stregsystem/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

dependencies = [
]

operations = [
migrations.CreateModel(
name='Member',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
('active', models.BooleanField(default=True)),
('username', models.CharField(max_length=16)),
('year', models.CharField(max_length=4)),
('firstname', models.CharField(max_length=20)),
('lastname', models.CharField(max_length=30)),
('gender', models.CharField(choices=[('U', 'Unknown'), ('M', 'Male'), ('F', 'Female')], max_length=1)),
('email', models.EmailField(blank=True, max_length=75)),
('want_spam', models.BooleanField(default=True)),
('balance', models.IntegerField(default=0)),
('undo_count', models.IntegerField(default=0)),
('phone_number', models.CharField(blank=True, max_length=16)),
('notes', models.TextField(blank=True)),
],
options={
},
bases=(models.Model,),
),
migrations.CreateModel(
name='News',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
('title', models.CharField(max_length=40)),
('text', models.TextField()),
('pub_date', models.DateTimeField()),
('stop_date', models.DateTimeField()),
],
options={
},
bases=(models.Model,),
),
migrations.CreateModel(
name='OldPrice',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
('price', models.IntegerField()),
('changed_on', models.DateTimeField(auto_now_add=True)),
],
options={
},
bases=(models.Model,),
),
migrations.CreateModel(
name='Payment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
('timestamp', models.DateTimeField(auto_now_add=True)),
('amount', models.IntegerField()),
('member', models.ForeignKey(to='stregsystem.Member')),
],
options={
},
bases=(models.Model,),
),
migrations.CreateModel(
name='Product',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
('name', models.CharField(max_length=32)),
('price', models.IntegerField()),
('active', models.BooleanField(default=True)),
('deactivate_date', models.DateTimeField(null=True, blank=True)),
],
options={
},
bases=(models.Model,),
),
migrations.CreateModel(
name='Room',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
('name', models.CharField(max_length=20)),
('description', models.CharField(max_length=20)),
],
options={
},
bases=(models.Model,),
),
migrations.CreateModel(
name='Sale',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
('timestamp', models.DateTimeField(auto_now_add=True)),
('price', models.IntegerField()),
('member', models.ForeignKey(to='stregsystem.Member')),
('product', models.ForeignKey(to='stregsystem.Product')),
('room', models.ForeignKey(to='stregsystem.Room', null=True)),
],
options={
},
bases=(models.Model,),
),
migrations.AddField(
model_name='oldprice',
name='product',
field=models.ForeignKey(related_name='old_prices', to='stregsystem.Product'),
preserve_default=True,
),
]
Empty file.
82 changes: 82 additions & 0 deletions stregsystem/stregsystem/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from django.db import models
from django.contrib.auth import hashers
from django.core.exceptions import ValidationError
import re

from stregsystem import utils


# TODO these validators might belong to Member?
def validate_pin(value):
msg = "Invalid pin"
if re.match('\d{4}$', value) is None:
raise ValidationError(msg)


def validate_phone_number(number):
msg = "{} is an invalid phone number"
if re.match('\d{1,16}$', number) is None:
raise ValidationError(msg.format(number))


class Member(models.Model):
username = models.CharField(max_length=64)
name = models.CharField(max_length=64, default='')
# gender
# weight
join_date = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)
_pin = models.CharField(verbose_name="pin",
max_length=128,
blank=True,
null=True)
note = models.TextField(blank=True)
email = models.EmailField()
_phone_number = models.CharField(verbose_name="phone number",
max_length=16,
blank=True,
validators=[validate_phone_number])

def phone_number_format(self):
if len(self.phone_number) % 2:
n = self.phone_number[1:]
res = self.phone_number[0] + ' '
else:
n = self.phone_number
res = ''
res += ' '.join([a+b for a, b in utils.grouper(2, n)])
return res

@property
def phone_number(self):
return self._phone_number

@phone_number.setter
def phone_number(self, new_phone_number):
sep = [' ', '-', '_', '+']

# wait, they moved reduce and said it is unreadable!? :(
for s in sep:
new_phone_number = new_phone_number.replace(s, '')

new_phone_number = utils.phone_letter_converter(new_phone_number)
self._phone_number = new_phone_number

@property
def pin(self):
return self._pin

@pin.setter
def pin(self, new_pin):
validate_pin(new_pin)
self._pin = hashers.make_password(new_pin)

def check_pin(self, pin):
return hashers.check_password(pin, self._pin)

def change_pin(self, old_pin, new_pin):
if self.check_pin(old_pin):
self.pin = new_pin
return True
else:
return False
4 changes: 3 additions & 1 deletion stregsystem/stregsystem/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@

THIRD_PARTY_APPS = ()

PROJECT_APPS = ()
PROJECT_APPS = (
'stregsystem',
)

INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + PROJECT_APPS

Expand Down
Empty file.
82 changes: 82 additions & 0 deletions stregsystem/stregsystem/test/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from django.test import TestCase
from stregsystem import models
from django.core.exceptions import ValidationError


class MemberPhoneNumberTestCase(TestCase):
def test_phone_number_set_success_space(self):
m = models.Member(phone_number='12 34')
self.assertEqual(m.phone_number, '1234')

def test_phone_number_set_success_dash(self):
m = models.Member(phone_number='12-34')
self.assertEqual(m.phone_number, '1234')

def test_phone_number_set_success_underscore(self):
m = models.Member(phone_number='12_34')
self.assertEqual(m.phone_number, '1234')

def test_phone_number_format_even(self):
m = models.Member(phone_number='1234')
self.assertEqual(m.phone_number_format(), '12 34')

def test_phone_number_format_odd(self):
m = models.Member(phone_number='123')
self.assertEqual(m.phone_number_format(), '1 23')

def test_phone_number_validator_fail_nothing(self):
with self.assertRaises(ValidationError):
models.validate_phone_number('')

def test_phone_number_validator_fail_long(self):
with self.assertRaises(ValidationError):
models.validate_phone_number('12345678901234567')

def test_phone_number_validator_fail_letters(self):
# Recall that this is not a likely thing to happen.
with self.assertRaises(ValidationError):
models.validate_phone_number('1234567a')

def test_phone_number_validator_success_short(self):
self.assertEqual(models.validate_phone_number('1'), None)

def test_phone_number_validator_success_middle(self):
self.assertEqual(models.validate_phone_number('12345678'), None)

def test_phone_number_validator_success_long(self):
self.assertEqual(models.validate_phone_number('1234567890123456'),
None)


class MemberPinTestCase(TestCase):
def setUp(self):
self.member = models.Member(pin='1234')

def test_check_pin_fail(self):
self.assertFalse(self.member.check_pin('4321'))

def test_check_pin_success(self):
self.assertTrue(self.member.check_pin('1234'))

def test_change_pin_fail(self):
self.assertFalse(self.member.change_pin('2234', '4321'))
self.assertFalse(self.member.check_pin('4321'))

def test_change_pin_success(self):
self.assertTrue(self.member.change_pin('1234', '4321'))
self.assertTrue(self.member.check_pin('4321'))

def test_pin_validator_fail_short(self):
with self.assertRaises(ValidationError):
models.validate_pin('123')

def test_pin_validator_fail_long(self):
with self.assertRaises(ValidationError):
models.validate_pin('12345')

def test_pin_validator_fail_letters(self):
with self.assertRaises(ValidationError):
models.validate_pin('abcd')

def test_pin_validator_success(self):
self.assertEqual(models.validate_pin('1234'), None)
14 changes: 14 additions & 0 deletions stregsystem/stregsystem/test/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from django.test import TestCase
from stregsystem import utils


class TestGrouper(TestCase):
pass


class TestPhoneLetterConverter(TestCase):
def test_phone_letter_converter_lower(self):
self.assertEqual(utils.phone_letter_converter('5052treo'), '50527625')

def test_phone_letter_converter_upper(self):
self.assertEqual(utils.phone_letter_converter('5052TREO'), '50527625')
16 changes: 16 additions & 0 deletions stregsystem/stregsystem/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from itertools import zip_longest


def grouper(n, iterable, filler='x'):
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=filler)


def phone_letter_converter(phone_number):
from string import ascii_lowercase, digits
phone_number = phone_number.lower()
for letters, digit in zip(grouper(3, ascii_lowercase),
digits[1:]):
for l in letters:
phone_number = phone_number.replace(l, digit)
return phone_number