Upgrade to django 1.8, ++

This commit is contained in:
nikolark committed 2015-11-17 13:12:37 +01:00
1 parent 8c004276a7
commit b47ee8f832
22 files changed
+767 -1051

No files matched your search

+26 -22
View File
@@ -4,7 +4,6 @@ import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email@example.com'),
@@ -14,12 +13,8 @@ MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'db.sqlite3', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3',
},
}
@@ -90,12 +85,26 @@ STATICFILES_FINDERS = (
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'osv$uy-ea$*%lc)+xiwt5@2b7au%u*c!pa6hmh#vl)*+tp%fss'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
]
},
},
]
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
@@ -107,13 +116,6 @@ MIDDLEWARE_CLASSES = (
ROOT_URLCONF = 'bbssite.urls'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
os.path.join(BASE_DIR, 'templates'),
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
@@ -122,13 +124,15 @@ INSTALLED_APPS = (
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'main',
'widget_tweaks',
'south',
'bootstrapform',
'compressor',
'django_extensions',
)
LOCAL_APPS = (
'main',
)
INSTALLED_APPS += LOCAL_APPS
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
+15 -7
View File
@@ -1,17 +1,25 @@
from django.conf import settings
from django.conf.urls import patterns, include, url
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from main import urls as main_urls
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', 'main.views.register', name='home'),
url(r'', include('main.urls')),
urlpatterns = [
url(r'', include(main_urls)),
url(r'^accounts/login/$', 'django.contrib.auth.views.login', name='login'),
url(r'^logout/$', 'main.views.logout', name='logout'),
url(r'^accounts/logout/$', 'main.views.users.logout', name='logout'),
url(r'^admin/', include(admin.site.urls)),
)
]
if settings.DEBUG:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
urlpatterns += [
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
})
]
+11 -9
View File
@@ -1,18 +1,19 @@
# coding: utf-8
from __future__ import unicode_literals
from django import forms
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from models import *
import utils
from main.models import Order, Transaction, InventoryTransaction, Product
from main.utils import format_username
class OrderForm(forms.ModelForm):
customer_name = forms.CharField(required=False)
def clean(self):
if self.cleaned_data['customer'] is None and self.cleaned_data['customer_name'] != u"Ekstern":
raise forms.ValidationError(_(u"Du har ikke valgt hvem som skal kjøpe."))
if self.cleaned_data['customer'] is None and self.cleaned_data['customer_name'] != "Ekstern":
raise forms.ValidationError(_("Du har ikke valgt hvem som skal kjøpe."))
return self.cleaned_data
@@ -20,8 +21,8 @@ class OrderForm(forms.ModelForm):
if self.cleaned_data['customer'] is None:
return self.cleaned_data['customer']
if self.cleaned_data['customer'].get_profile().balance <= 0:
raise forms.ValidationError(_(u"Du har negativ saldo og kan ikke kjøpe noe."))
if self.cleaned_data['customer'].profile.balance <= 0:
raise forms.ValidationError(_("Du har negativ saldo og kan ikke kjøpe noe."))
return self.cleaned_data['customer']
@@ -41,6 +42,7 @@ class DepositForm(forms.ModelForm):
class Meta:
model = Transaction
fields = ['user', 'amount']
class SimpleCreateUserForm(forms.Form):
@@ -55,12 +57,12 @@ class SimpleCreateUserForm(forms.Form):
return "https://graph.facebook.com/{0}/picture".format(self.cleaned_data['facebook_username'])
def save(self, commit=True):
username = utils.format_username(self.cleaned_data['first_name'], self.cleaned_data['last_name'])
username = format_username(self.cleaned_data['first_name'], self.cleaned_data['last_name'])
user = User.objects.create_user(username, email=self.cleaned_data['email'])
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
profile = user.get_profile()
profile = user.profile
profile.image = self._get_facebook_url()
if commit:
+96 -167
View File
@@ -1,172 +1,101 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
class Migration(SchemaMigration):
class Migration(migrations.Migration):
def forwards(self, orm):
# Adding model 'Product'
db.create_table('main_product', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=64)),
('sale_price_int', self.gf('django.db.models.fields.FloatField')()),
('sale_price_ext', self.gf('django.db.models.fields.FloatField')()),
('description', self.gf('django.db.models.fields.CharField')(max_length=256, blank=True)),
('volume_liter', self.gf('django.db.models.fields.FloatField')(null=True)),
('alcohol_percent', self.gf('django.db.models.fields.FloatField')(null=True)),
('image', self.gf('django.db.models.fields.files.ImageField')(max_length=100, blank=True)),
('customer_support', self.gf('django.db.models.fields.CharField')(max_length=32, blank=True)),
('active', self.gf('django.db.models.fields.BooleanField')(default=True)),
('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('updated', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
))
db.send_create_signal('main', ['Product'])
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
# Adding model 'Order'
db.create_table('main_order', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('customer', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('order_sum', self.gf('django.db.models.fields.FloatField')(db_column='sum')),
('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
))
db.send_create_signal('main', ['Order'])
# Adding model 'OrderLine'
db.create_table('main_orderline', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('order', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['main.Order'])),
('product', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['main.Product'])),
('amount', self.gf('django.db.models.fields.IntegerField')()),
('unit_price', self.gf('django.db.models.fields.FloatField')()),
))
db.send_create_signal('main', ['OrderLine'])
# Adding unique constraint on 'OrderLine', fields ['order', 'product']
db.create_unique('main_orderline', ['order_id', 'product_id'])
# Adding model 'Transaction'
db.create_table('main_transaction', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('amount', self.gf('django.db.models.fields.FloatField')()),
('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
))
db.send_create_signal('main', ['Transaction'])
# Adding model 'UserProfile'
db.create_table('main_userprofile', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True)),
('balance', self.gf('django.db.models.fields.FloatField')(default=0.0)),
('image', self.gf('django.db.models.fields.URLField')(max_length=200, blank=True)),
))
db.send_create_signal('main', ['UserProfile'])
def backwards(self, orm):
# Removing unique constraint on 'OrderLine', fields ['order', 'product']
db.delete_unique('main_orderline', ['order_id', 'product_id'])
# Deleting model 'Product'
db.delete_table('main_product')
# Deleting model 'Order'
db.delete_table('main_order')
# Deleting model 'OrderLine'
db.delete_table('main_orderline')
# Deleting model 'Transaction'
db.delete_table('main_transaction')
# Deleting model 'UserProfile'
db.delete_table('main_userprofile')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'main.order': {
'Meta': {'object_name': 'Order'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'customer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order_sum': ('django.db.models.fields.FloatField', [], {'db_column': "'sum'"})
},
'main.orderline': {
'Meta': {'unique_together': "(('order', 'product'),)", 'object_name': 'OrderLine'},
'amount': ('django.db.models.fields.IntegerField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Order']"}),
'product': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Product']"}),
'unit_price': ('django.db.models.fields.FloatField', [], {})
},
'main.product': {
'Meta': {'object_name': 'Product'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'alcohol_percent': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'customer_support': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
'sale_price_ext': ('django.db.models.fields.FloatField', [], {}),
'sale_price_int': ('django.db.models.fields.FloatField', [], {}),
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'volume_liter': ('django.db.models.fields.FloatField', [], {'null': 'True'})
},
'main.transaction': {
'Meta': {'object_name': 'Transaction'},
'amount': ('django.db.models.fields.FloatField', [], {}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'main.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'balance': ('django.db.models.fields.FloatField', [], {'default': '0.0'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
}
}
complete_apps = ['main']
operations = [
migrations.CreateModel(
name='InventoryTransaction',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('amount', models.FloatField(verbose_name='Antall')),
('unit_price', models.FloatField(verbose_name='Enhetspris')),
('comment', models.TextField(verbose_name='Kommentar', blank=True)),
('created', models.DateTimeField(auto_now_add=True)),
],
),
migrations.CreateModel(
name='Order',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('order_sum', models.FloatField(db_column=b'sum')),
('created', models.DateTimeField(auto_now_add=True)),
('customer', models.ForeignKey(related_name='orders', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
],
),
migrations.CreateModel(
name='OrderLine',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('amount', models.IntegerField()),
('unit_price', models.FloatField(verbose_name='Enhetspris')),
('order', models.ForeignKey(related_name='orderlines', to='main.Order')),
],
),
migrations.CreateModel(
name='Product',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=64)),
('sale_price_int', models.FloatField()),
('sale_price_ext', models.FloatField()),
('description', models.CharField(max_length=256, blank=True)),
('volume_liter', models.FloatField(null=True)),
('alcohol_percent', models.FloatField(null=True)),
('image', models.ImageField(upload_to=b'products', blank=True)),
('customer_support', models.CharField(max_length=32, blank=True)),
('inventory_amount', models.FloatField(default=0)),
('active', models.BooleanField(default=True)),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
],
options={
'ordering': ['name'],
},
),
migrations.CreateModel(
name='Transaction',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('amount', models.FloatField()),
('created', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(related_name='transactions', to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='UserProfile',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('balance', models.FloatField(default=0.0)),
('image', models.URLField(blank=True)),
('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL)),
],
),
migrations.AddField(
model_name='orderline',
name='product',
field=models.ForeignKey(related_name='orderlines', to='main.Product'),
),
migrations.AddField(
model_name='inventorytransaction',
name='product',
field=models.ForeignKey(related_name='transactions', verbose_name='Produkt', to='main.Product'),
),
migrations.AddField(
model_name='inventorytransaction',
name='user',
field=models.ForeignKey(related_name='inventory_transactions', to=settings.AUTH_USER_MODEL),
),
migrations.AlterUniqueTogether(
name='orderline',
unique_together=set([('order', 'product')]),
),
]
@@ -1,131 +0,0 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'InventoryTransaction'
db.create_table(u'main_inventorytransaction', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('product', self.gf('django.db.models.fields.related.ForeignKey')(related_name='transactions', to=orm['main.Product'])),
('amount', self.gf('django.db.models.fields.FloatField')()),
('unit_price', self.gf('django.db.models.fields.FloatField')()),
('comment', self.gf('django.db.models.fields.TextField')(blank=True)),
('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
))
db.send_create_signal(u'main', ['InventoryTransaction'])
# Adding field 'Product.inventory_amount'
db.add_column(u'main_product', 'inventory_amount',
self.gf('django.db.models.fields.FloatField')(default=0),
keep_default=False)
def backwards(self, orm):
# Deleting model 'InventoryTransaction'
db.delete_table(u'main_inventorytransaction')
# Deleting field 'Product.inventory_amount'
db.delete_column(u'main_product', 'inventory_amount')
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'main.inventorytransaction': {
'Meta': {'object_name': 'InventoryTransaction'},
'amount': ('django.db.models.fields.FloatField', [], {}),
'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transactions'", 'to': u"orm['main.Product']"}),
'unit_price': ('django.db.models.fields.FloatField', [], {}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
},
u'main.order': {
'Meta': {'object_name': 'Order'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'customer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order_sum': ('django.db.models.fields.FloatField', [], {'db_column': "'sum'"})
},
u'main.orderline': {
'Meta': {'unique_together': "(('order', 'product'),)", 'object_name': 'OrderLine'},
'amount': ('django.db.models.fields.IntegerField', [], {}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['main.Order']"}),
'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'orderlines'", 'to': u"orm['main.Product']"}),
'unit_price': ('django.db.models.fields.FloatField', [], {})
},
u'main.product': {
'Meta': {'ordering': "['name']", 'object_name': 'Product'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'alcohol_percent': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'customer_support': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'inventory_amount': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
'sale_price_ext': ('django.db.models.fields.FloatField', [], {}),
'sale_price_int': ('django.db.models.fields.FloatField', [], {}),
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'volume_liter': ('django.db.models.fields.FloatField', [], {'null': 'True'})
},
u'main.transaction': {
'Meta': {'object_name': 'Transaction'},
'amount': ('django.db.models.fields.FloatField', [], {}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
},
u'main.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'balance': ('django.db.models.fields.FloatField', [], {'default': '0.0'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'})
}
}
complete_apps = ['main']
@@ -1,118 +0,0 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Order.customer'
db.alter_column(u'main_order', 'customer_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True))
def backwards(self, orm):
# User chose to not deal with backwards NULL issues for 'Order.customer'
raise RuntimeError("Cannot reverse this migration. 'Order.customer' and its values cannot be restored.")
# The following code is provided here to aid in writing a correct migration
# Changing field 'Order.customer'
db.alter_column(u'main_order', 'customer_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User']))
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'main.inventorytransaction': {
'Meta': {'object_name': 'InventoryTransaction'},
'amount': ('django.db.models.fields.FloatField', [], {}),
'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transactions'", 'to': u"orm['main.Product']"}),
'unit_price': ('django.db.models.fields.FloatField', [], {}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
},
u'main.order': {
'Meta': {'object_name': 'Order'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'customer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order_sum': ('django.db.models.fields.FloatField', [], {'db_column': "'sum'"})
},
u'main.orderline': {
'Meta': {'unique_together': "(('order', 'product'),)", 'object_name': 'OrderLine'},
'amount': ('django.db.models.fields.IntegerField', [], {}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['main.Order']"}),
'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'orderlines'", 'to': u"orm['main.Product']"}),
'unit_price': ('django.db.models.fields.FloatField', [], {})
},
u'main.product': {
'Meta': {'ordering': "['name']", 'object_name': 'Product'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'alcohol_percent': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'customer_support': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'inventory_amount': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
'sale_price_ext': ('django.db.models.fields.FloatField', [], {}),
'sale_price_int': ('django.db.models.fields.FloatField', [], {}),
'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'volume_liter': ('django.db.models.fields.FloatField', [], {'null': 'True'})
},
u'main.transaction': {
'Meta': {'object_name': 'Transaction'},
'amount': ('django.db.models.fields.FloatField', [], {}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
},
u'main.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'balance': ('django.db.models.fields.FloatField', [], {'default': '0.0'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'})
}
}
complete_apps = ['main']
+1 -1
View File
@@ -117,7 +117,7 @@ class InventoryTransaction(models.Model):
class UserProfile(models.Model):
user = models.OneToOneField(User)
user = models.OneToOneField(User, related_name='profile')
balance = models.FloatField(default=0.0)
#image = models.ImageField(upload_to='users', blank=True)
image = models.URLField(blank=True)
+31 -22
View File
@@ -1,24 +1,33 @@
from django.conf.urls import patterns, include, url
from django.conf.urls import url
from main.views.stats import stats_list, stats_orders, stats_orders_hourly, stats_products_realtime, stats_products, \
stats_products_per_user, products_json
from main.views.general import register, deposit, log
from main.views.reports import inventory, inventory_add, report
from main.views.users import create_user, profile
urlpatterns = patterns('main.views',
url(r'^register/$', 'register', name='register'),
url(r'^deposit/$', 'deposit', name='deposit'),
url(r'^log/$', 'log', name='log'),
url(r'^log/all$', 'log', kwargs={'limit': None}, name='log-all'),
url(r'^stats/$', 'stats', name='stats'),
url(r'^stats/orders/$', 'stats_orders', name='stats-orders'),
url(r'^stats/orders/hourly$', 'stats_orders_hourly', name='stats-orders-hourly'),
url(r'^stats/orders/products_realtime$', 'stats_products_realtime', name='stats-products-realtime'),
url(r'^stats/products/$', 'stats_products', name='stats-products'),
url(r'^stats/products/(?P<product>[0-9]+)/$', 'stats_products', name='stats-product'),
url(r'^stats/products/by_user/(?P<user_id>[0-9]+)/$', 'stats_products_per_user', name='stats-products-per-user'),
url(r'^products/(?P<product_id>[0-9]+)/$', 'products_json', name='json-product'),
url(r'^products/$', 'products_json', name='json-products'),
url(r'^user/create/$', 'create_user', name='create-user'),
url(r'^profile/$', 'profile', name='profile'),
url(r'^inventory/$', 'inventory', name='inventory'),
url(r'^inventory/add/$', 'inventory_add', name='inventory-add'),
url(r'^report$', 'report', name='report'),
)
urlpatterns = [
url(r'^$', register, name='home'),
url(r'^register/$', register, name='register'),
url(r'^deposit/$', deposit, name='deposit'),
url(r'^log/$', log, name='log'),
url(r'^log/all$', log, kwargs={'limit': None}, name='log-all'),
# Stats
url(r'^stats/$', stats_list, name='stats'),
url(r'^stats/orders/$', stats_orders, name='stats-orders'),
url(r'^stats/orders/hourly$', stats_orders_hourly, name='stats-orders-hourly'),
url(r'^stats/orders/products_realtime$', stats_products_realtime, name='stats-products-realtime'),
url(r'^stats/products/$', stats_products, name='stats-products'),
url(r'^stats/products/(?P<product>[0-9]+)/$', stats_products, name='stats-product'),
url(r'^stats/products/by_user/(?P<user_id>[0-9]+)/$', stats_products_per_user, name='stats-products-per-user'),
# Products
url(r'^products/(?P<product_id>[0-9]+)/$', products_json, name='json-product'),
url(r'^products/$', products_json, name='json-products'),
# Users
url(r'^user/create/$', create_user, name='create-user'),
url(r'^profile/$', profile, name='profile'),
# Reports
url(r'^inventory/$', inventory, name='inventory'),
url(r'^inventory/add/$', inventory_add, name='inventory-add'),
url(r'^report$', report, name='report'),
]
+11
View File
@@ -1,14 +1,25 @@
from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.db.models import Q
def format_username(firstname, lastname):
first = firstname.lower().strip().replace(" ", "")[:6].encode('ascii', 'ignore')
last = lastname.lower().strip().replace(" ", "")[:6].encode('ascii', 'ignore')
return "{0}{1}".format(first, last)
def users_with_perm(perm_name):
return User.objects.filter(
Q(is_superuser=True) |
Q(user_permissions__codename=perm_name) |
Q(groups__permissions__codename=perm_name)).distinct()
def users_format_js(users):
users_js = []
for user in users:
users_js.append('"' + user.first_name + ' ' + user.last_name[:1] + '"')
users_js = "[{0}]".format(u",".join(users_js))
return users_js
-542
View File
@@ -1,542 +0,0 @@
# coding: utf-8
from datetime import timedelta
from itertools import groupby
import json
import time
from django.db import connection
from django.conf import settings
from django.contrib.auth import login, logout as auth_logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AuthenticationForm
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.db.models import Count, Sum, Min
from django.forms.formsets import formset_factory
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response, render, get_object_or_404, redirect
from django.template import RequestContext
from forms import *
from models import *
import utils
def home(request):
if request.method == "POST":
form = AuthenticationForm(data=request.POST)
if form.is_valid():
# Log the user in.
login(request, form.get_user())
else:
if request.user.is_authenticated():
# Redirect to the register
return HttpResponseRedirect(reverse('main.views.register'))
else:
form = AuthenticationForm(request)
return render_to_response('home.html', locals(), context_instance=RequestContext(request))
def register(request):
products = Product.objects.filter(active=True)
cheapest_product_price = products.aggregate(Min('sale_price_int')).values()[0] or 0
half_a_year_ago = datetime.now() - timedelta(days=180)
users = User.objects.filter(userprofile__balance__gt=cheapest_product_price)
# sort users after user's last purchase time
users = sorted(users, key=lambda u: u.get_profile().last_purchase_date(), reverse=True)
users_js = users_format_js(users)
# multiple orderlines (one per product)
OrderLineFormSet = formset_factory(OrderLineForm)
if request.method == "POST":
orderform = OrderForm(request.POST)
formset = OrderLineFormSet(request.POST)
if formset.is_valid() and orderform.is_valid():
order = orderform.save(commit=False)
if order.is_external():
order_sum = sum([ol['amount'] * ol['unit_price_ext'] for ol in formset.cleaned_data])
else:
order_sum = sum([ol['amount'] * ol['unit_price_int'] for ol in formset.cleaned_data])
# empty order?
if order_sum == 0:
messages.error(request, u'Du har ikke valgt hva du skal kjøpe...')
return HttpResponseRedirect(reverse('main.views.register'))
if not order.is_external():
profile = order.customer.get_profile()
# can she afford it?
if order_sum >= profile.balance:
messages.error(request, u'{0} {1} har ikke råd, mangler {2} kr.'.format(
order.customer.first_name,
order.customer.last_name,
int(order_sum - profile.balance)))
return HttpResponseRedirect(reverse('main.views.register'))
# substract order from balance
profile.balance -= order_sum
profile.save()
order.order_sum = order_sum
order.save()
orderlines = []
for ol in formset.cleaned_data:
if ol['amount'] > 0:
product = Product.objects.get(pk=ol['product'])
if order.is_external():
unit_price = ol['unit_price_ext']
else:
unit_price = ol['unit_price_int']
OrderLine.objects.create(
order=order,
product=product,
amount=ol['amount'],
unit_price=unit_price)
product.inventory_amount -= ol['amount']
product.save()
orderlines.append(u"{0} {1}".format(ol['amount'], product))
if order.is_external():
messages.success(request, u'Ekstern kjøpte {0}.'.format(u", ".join(orderlines)))
else:
messages.success(request, u'{0} {1} kjøpte {2}.'.format(
order.customer.first_name,
order.customer.last_name,
u", ".join(orderlines)
))
return HttpResponseRedirect(reverse('main.views.register'))
else:
# TODO specify error(s)
messages.error(request, u'Skjemaet er ikke gyldig.')
orderform = OrderForm(request.POST)
formset = OrderLineFormSet(request.POST)
else:
orderform = OrderForm()
formset = OrderLineFormSet()
return render_to_response('register.html', locals(), context_instance=RequestContext(request))
def deposit(request):
users = User.objects.all().order_by('first_name', 'last_name')
users_js = users_format_js(users)
allowed_users = utils.users_with_perm('add_transaction')
error_message_template = u'{0} {1} kan ikke sette inn {2} kr, det overskrider maks saldo ({3} kr) med {4} kr'
# FIXME: dont need this
try:
limit_deposists = settings.BBS_LIMIT_DEPOSITS
except:
pass
if request.method == "POST":
form = DepositForm(request.POST)
if form.is_valid():
amount = form.cleaned_data['amount']
user = form.cleaned_data['user']
if amount + user.get_profile().balance > settings.BBS_SALDO_MAX and amount + user.get_profile().balance != 1337:
messages.error(request, error_message_template.format(
user.first_name,
user.last_name,
amount,
settings.BBS_SALDO_MAX,
amount + user.get_profile().balance - settings.BBS_SALDO_MAX
))
return HttpResponseRedirect(reverse('main.views.deposit'))
transaction = form.save()
profile = transaction.user.get_profile()
profile.balance += transaction.amount
profile.save()
messages.success(request, u'{0} {1} satte inn {2} kr. Ny saldo er {3}'.format(
transaction.user.first_name,
transaction.user.last_name,
transaction.amount,
profile.balance))
return HttpResponseRedirect(reverse('main.views.deposit'))
else:
messages.error(request, u'Skjemaet er ikke gyldig.')
form = DepositForm(request.POST)
else:
form = DepositForm()
return render_to_response('deposit.html', locals(), context_instance=RequestContext(request))
def log(request, limit=datetime.now()-timedelta(days=2)):
if limit:
# display last two days of orders and transactions
orders = Order.objects.filter(created__gte=limit).order_by('-created')
transactions = Transaction.objects.filter(created__gte=limit).order_by('-created')
# no action in the last two days?
# ...then display the last 5 items
if len(orders) == 0:
orders = Order.objects.all().order_by('-created')[:5]
if len(transactions) == 0:
transactions = Transaction.objects.all().order_by('-created')[:5]
else:
# display everything
orders = Order.objects.all().order_by('-created')
transactions = Transaction.objects.all().order_by('-created')
return render_to_response('log.html', locals(), context_instance=RequestContext(request))
def stats(request):
products = Product.objects.filter(active=True)
return render_to_response('stats.html', locals(), context_instance=RequestContext(request))
def serialize_product(product):
f_product = {}
for attr in Product._meta.get_all_field_names():
if attr == "transactions" or attr == "orderlines":
continue
if hasattr(product, attr) and product.__getattribute__(attr):
if type(product.__getattribute__(attr)) is datetime:
f_product[attr] = str(product.__getattribute__(attr))
else:
f_product[attr] = product.__getattribute__(attr)
return f_product
def products_json(request, product_id=None):
if product_id:
#single
products = get_object_or_404(Product, pk=product_id)
else:
#many
products = Product.objects.filter(active=True)
if product_id:
f_products = serialize_product(products)
else:
f_products = [serialize_product(product) for product in products]
return HttpResponse(json.dumps(f_products), content_type='application/javascript; charset=utf8')
def stats_product(product):
# reverse lookup via order, customer
per_user = OrderLine.objects\
.filter(product=product)\
.values('order__customer__first_name', 'order__customer__last_name')\
.annotate(num=Sum('amount'))\
.order_by('num')\
.reverse()
f_per_user = []
for row in per_user:
if row['order__customer__first_name'] is not None:
who = row['order__customer__first_name'] + " " + row['order__customer__last_name']
else:
who = u"Ekstern"
num = row['num']
f_per_user.append([who, num])
response = {
'product': serialize_product(Product.objects.get(pk=product)) if type(product) is unicode else serialize_product(product),
'counts': f_per_user,
'total_counts': sum([row['num'] for row in per_user]),
}
return response
def stats_products(request, product=None):
if product:
#single
f_products = [stats_product(product)]
sales = OrderLine.objects.filter(product=product)
else:
#all
sales = OrderLine.objects.filter(product__active=True)
f_products = [stats_product(p) for p in Product.objects.filter(active=True)]
totals = float(sum([sale.amount for sale in sales]))
response = {
'request': 'all' if not product else product,
'response': {
'products': f_products,
'total_count': totals,
}
}
return HttpResponse(json.dumps(response), content_type='application/javascript; charset=utf8')
def stats_orders(request):
num_external_orders = Order.objects.filter(customer=None).count()
per_user = Order.objects\
.values('customer__first_name', 'customer__last_name')\
.annotate(num=Count('customer'))\
.order_by('num').reverse()
f_per_user = []
for row in per_user:
if row['customer__first_name'] is not None:
who = row['customer__first_name'] + " " + row['customer__last_name']
num = row['num']
else:
who = u"Ekstern"
num = num_external_orders
f_per_user.append([who, num])
return HttpResponse(json.dumps(f_per_user), content_type='application/javascript; charset=utf8')
def stats_orders_hourly(request):
orders = Order.objects.all()
f_hourly = dict([(key, 0) for key in range(0, 24)]) # init
# group by hour
for key, values in groupby(orders, key=lambda row: row.created.hour):
count = len(list(values))
f_hourly[key] += count
if len(orders) == 0:
return HttpResponse(json.dumps({}), content_type='application/javascript; charset=utf8')
response = {
'start': str(orders[0].created),
'hourly': [[k, v] for k, v in f_hourly.iteritems()],
'total': sum(f_hourly.values()),
}
return HttpResponse(json.dumps(response), content_type='application/javascript; charset=utf8')
def stats_products_realtime(request):
end_time = datetime.now()
start_time = datetime.now() - timedelta(hours=24)
order_lines = OrderLine.objects.filter(order__created__range=(start_time, end_time)).order_by("order__created")
products = {}
for order_line in order_lines:
order_time_in_milliseconds = int(time.mktime(order_line.order.created.timetuple()) * 1000)
if order_line.product not in products:
products[order_line.product] = [[order_time_in_milliseconds, order_line.amount]]
else:
prev_entry = products[order_line.product][-1]
products[order_line.product].append([order_time_in_milliseconds, prev_entry[1] + order_line.amount])
serialized_products = {}
for product, value in products.iteritems():
serialized_products[product.name] = value
response = {
'products': serialized_products
}
return HttpResponse(json.dumps(response), content_type='application/javascript; charset=utf8')
def logout(request):
auth_logout(request)
return render_to_response('registration/logout.html', locals(), context_instance=RequestContext(request))
def users_format_js(users):
users_js = []
for user in users:
users_js.append('"' + user.first_name + ' ' + user.last_name[:1] + '"')
users_js = u"[{0}]".format(u",".join(users_js))
return users_js
def create_user(request):
if request.method == "POST":
form = SimpleCreateUserForm(data=request.POST)
if form.is_valid():
user = form.save()
messages.success(request, u"Hurra! {0} {1} er lagt til".format(user.first_name, user.last_name))
return redirect('create-user')
else:
messages.error(request, u'Feil med skjemaet, se under.')
form = SimpleCreateUserForm(data=request.POST)
else:
form = SimpleCreateUserForm()
return render(request, 'registration/create_user.html', locals())
def inventory(request):
products = Product.objects.all().order_by('-active', 'inventory_amount', 'name')
transactions = InventoryTransaction.objects.all().order_by('-created')
products_active = products.filter(active=True)
wholesale_value = sum([p.wholesale_value for p in products_active])
num_products = sum(products_active.values_list('inventory_amount', flat=True))
return render(request, 'inventory.html', locals())
def inventory_add(request):
if request.method == "POST":
form = InventoryTransactionForm(data=request.POST)
if form.is_valid():
itrans = form.save(commit=False)
# Add amount and user, then save
itrans.product.inventory_amount += itrans.amount
itrans.user = request.user
itrans.product.save()
itrans.save()
messages.success(request, u"Satt inn {0} stk {1}.".format(itrans.amount, itrans.product))
return redirect('inventory-add')
else:
messages.error(request, u'Feil med skjemaet, se under.')
form = InventoryTransactionForm(data=request.POST)
else:
form = InventoryTransactionForm()
return render(request, 'inventory_add.html', locals())
def report(request):
# FIXME: split this up in smaller pieces
datetime_now = datetime.now()
start_time = datetime.now() - timedelta(days=30)
# start of day, 1 month
start_time = start_time.replace(hour=0, minute=0, second=0, microsecond=0)
# end of day
end_time = datetime.now().replace(hour=23, minute=59, second=59, microsecond=999)
if request.GET.get('start_time', False) or request.GET.get('end_time', False):
form = DateRangeForm(request.GET)
if form.is_valid():
start_time = form.cleaned_data['start_time']
# end of day
end_time = form.cleaned_data['end_time'].replace(hour=23, minute=59, second=59, microsecond=999)
else:
form = DateRangeForm(initial={
'start_time': start_time.strftime("%Y-%m-%d"),
'end_time': end_time.strftime("%Y-%m-%d")
})
# Inventory
products = Product.objects\
.filter(transactions__created__range=[start_time, end_time])\
.values('name', 'transactions__unit_price', 'transactions__amount')\
.order_by('name')
# group by name and sum
inventory_products = {}
for k, g in groupby(products, lambda x: x['name']):
group = []
for el in g:
el['transactions__price'] = el['transactions__amount'] * el['transactions__unit_price']
group.append(el)
inventory_products.update({k: {
'name': k,
"transactions": group,
"transactions_sum": sum(map(lambda x: x['transactions__price'], group)),
"transactions_units": sum(map(lambda x: x['transactions__amount'], group))
}})
itrans = InventoryTransaction.objects.filter(created__range=[start_time, end_time])
inv_in = sum(map(lambda x: x[1].get('transactions_sum', 0), inventory_products.items()))
# out
out_products = Product.objects\
.filter(orderlines__order__created__range=[start_time, end_time])\
.values('name', 'orderlines__unit_price', 'orderlines__amount')\
.order_by('name')
# group by name and sum
for k, g in groupby(out_products, lambda x: x['name']):
group = []
for el in g:
el['orderlines__price'] = el['orderlines__amount'] * el['orderlines__unit_price']
group.append(el)
product = {
'name': k,
"orderlines": group,
"orderlines_sum": sum(map(lambda x: x['orderlines__price'], group)),
"orderlines_units": sum(map(lambda x: x['orderlines__amount'], group))
}
if k in inventory_products:
# add diff
inventory_products[k].update(product)
else:
inventory_products.update({k: product})
for p in inventory_products.items():
p[1]['value_diff'] = p[1].get('transactions_sum', 0) - p[1].get('orderlines_sum', 0)
p[1]['units_diff'] = p[1].get('transactions_units', 0) - p[1].get('orderlines_units', 0)
inv_out = sum(map(lambda x: x[1].get('orderlines_sum', 0), inventory_products.items()))
inv_diff = inv_in - inv_out
# Deposits and sales
saldo_profiles = sum(UserProfile.objects.all().values_list('balance', flat=True))
deposits = sum(Transaction.objects.all().values_list('amount', flat=True))
purchases = sum(Order.objects.all().values_list('order_sum', flat=True))
saldo = deposits - purchases
deposits_start = sum(Transaction.objects.filter(created__lt=start_time).values_list('amount', flat=True))
purchases_start = sum(Order.objects.filter(created__lt=start_time).values_list('order_sum', flat=True))
saldo_start = deposits_start - purchases_start
deposits_end = sum(Transaction.objects.filter(created__lt=end_time).values_list('amount', flat=True))
purchases_end = sum(Order.objects.filter(created__lt=end_time).values_list('order_sum', flat=True))
saldo_end = deposits_end - purchases_end
deposits_diff = deposits_end - deposits_start
purchases_diff = purchases_end - purchases_start
saldo_diff = saldo_end - saldo_start
return render(request, 'report.html', locals())
@login_required
def profile(request):
transactions = Transaction.objects.filter(user=request.user.pk)
transaction_totals = {
'sum': sum([t.amount for t in transactions])
}
orders = Order.objects.filter(customer=request.user.pk)
orders_totals = {
'sum': sum([o.order_sum for o in orders])
}
#order_lines = OrderLine.objects.filter(order__customer__pk=1).order_by("order__created")
order_report = _orders_monthly(filter_by={'customer': request.user.pk})
top_months = order_report.order_by('-sum')[:5]
return render(request, 'profile.html', locals())
def stats_products_per_user(request, user_id=None):
if not user_id:
return HttpResponse(
json.dumps({'error': 'Missing param user_id'}),
content_type='application/javascript; charset=utf8')
order_lines = OrderLine.objects.filter(order__customer__pk=user_id).order_by("order__created")
products = {}
for order_line in order_lines:
order_time_in_milliseconds = int(time.mktime(order_line.order.created.timetuple()) * 1000)
if order_line.product not in products:
products[order_line.product] = [[order_time_in_milliseconds, order_line.amount]]
else:
prev_entry = products[order_line.product][-1]
products[order_line.product].append([order_time_in_milliseconds, prev_entry[1] + order_line.amount])
serialized_products = []
for product, value in products.iteritems():
serialized_products.append({
'name': product.name,
'data': value
})
return HttpResponse(json.dumps(serialized_products), content_type='application/javascript; charset=utf8')
def _orders_monthly(filter_by={}, order_by='month'):
truncate_date = connection.ops.date_trunc_sql('month', 'created')
qs = Order.objects.filter(**filter_by).extra({'month': truncate_date})
order_report = qs.values('month').annotate(sum=Sum('order_sum'), num=Count('pk')).order_by(order_by)
return order_report
View File
Whitespace-only changes.
+171
View File
@@ -0,0 +1,171 @@
# coding: utf-8
from __future__ import unicode_literals
from datetime import datetime, timedelta
import settings
from django.contrib import messages
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.db.models import Min
from django.forms import formset_factory
from django.http import HttpResponseRedirect
from django.shortcuts import render, redirect
from main.forms import OrderLineForm, OrderForm, DepositForm
from main.models import Product, OrderLine, Order, Transaction
from main.utils import users_format_js, users_with_perm
def register(request):
products = Product.objects.filter(active=True)
cheapest_product_price = products.aggregate(Min('sale_price_int')).values()[0] or 0
half_a_year_ago = datetime.now() - timedelta(days=180)
users = User.objects.filter(profile__balance__gte=cheapest_product_price)
# sort users after user's last purchase time
users = sorted(users, key=lambda u: u.profile.last_purchase_date(), reverse=True)
users_js = users_format_js(users)
# multiple orderlines (one per product)
OrderLineFormSet = formset_factory(OrderLineForm)
if request.method == "POST":
orderform = OrderForm(request.POST)
formset = OrderLineFormSet(request.POST)
if formset.is_valid() and orderform.is_valid():
order = orderform.save(commit=False)
if order.is_external():
order_sum = sum([ol['amount'] * ol['unit_price_ext'] for ol in formset.cleaned_data])
else:
order_sum = sum([ol['amount'] * ol['unit_price_int'] for ol in formset.cleaned_data])
# empty order?
if order_sum == 0:
messages.error(request, 'Du har ikke valgt hva du skal kjøpe...')
return HttpResponseRedirect(reverse('register'))
if not order.is_external():
profile = order.customer.profile
# can she afford it?
if order_sum >= profile.balance:
messages.error(request, '{0} {1} har ikke råd, mangler {2} kr.'.format(
order.customer.first_name,
order.customer.last_name,
int(order_sum - profile.balance)))
return HttpResponseRedirect(reverse('register'))
# substract order from balance
profile.balance -= order_sum
profile.save()
order.order_sum = order_sum
order.save()
orderlines = []
for ol in formset.cleaned_data:
if ol['amount'] > 0:
product = Product.objects.get(pk=ol['product'])
if order.is_external():
unit_price = ol['unit_price_ext']
else:
unit_price = ol['unit_price_int']
OrderLine.objects.create(
order=order,
product=product,
amount=ol['amount'],
unit_price=unit_price)
product.inventory_amount -= ol['amount']
product.save()
orderlines.append("{0} {1}".format(ol['amount'], product))
if order.is_external():
messages.success(request, 'Ekstern kjøpte {0}.'.format(", ".join(orderlines)))
else:
messages.success(request, '{0} {1} kjøpte {2}.'.format(
order.customer.first_name,
order.customer.last_name,
", ".join(orderlines)
))
return redirect('register')
else:
# TODO specify error(s)
messages.error(request, 'Skjemaet er ikke gyldig.')
orderform = OrderForm(request.POST)
formset = OrderLineFormSet(request.POST)
else:
orderform = OrderForm()
formset = OrderLineFormSet()
return render(request, 'register.html', locals())
def deposit(request):
users = User.objects.all().order_by('first_name', 'last_name')
users_js = users_format_js(users)
allowed_users = users_with_perm('add_transaction')
error_message_template = '{0} {1} kan ikke sette inn {2} kr, det overskrider maks saldo ({3} kr) med {4} kr'
# FIXME: dont need this
try:
limit_deposists = settings.BBS_LIMIT_DEPOSITS
except:
pass
if request.method == "POST":
form = DepositForm(request.POST)
if form.is_valid():
amount = form.cleaned_data['amount']
user = form.cleaned_data['user']
if amount + user.profile.balance > settings.BBS_SALDO_MAX and amount + user.profile.balance != 1337:
messages.error(request, error_message_template.format(
user.first_name,
user.last_name,
amount,
settings.BBS_SALDO_MAX,
amount + user.profile.balance - settings.BBS_SALDO_MAX
))
return HttpResponseRedirect(reverse('deposit'))
transaction = form.save()
profile = transaction.user.profile
profile.balance += transaction.amount
profile.save()
messages.success(request, '{0} {1} satte inn {2} kr. Ny saldo er {3}'.format(
transaction.user.first_name,
transaction.user.last_name,
transaction.amount,
profile.balance))
return HttpResponseRedirect(reverse('deposit'))
else:
messages.error(request, 'Skjemaet er ikke gyldig.')
form = DepositForm(request.POST)
else:
form = DepositForm()
return render(request, 'deposit.html', locals())
def log(request, limit=datetime.now()-timedelta(days=2)):
if limit:
# display last two days of orders and transactions
orders = Order.objects.filter(created__gte=limit).order_by('-created')
transactions = Transaction.objects.filter(created__gte=limit).order_by('-created')
# no action in the last two days?
# ...then display the last 5 items
if len(orders) == 0:
orders = Order.objects.all().order_by('-created')[:5]
if len(transactions) == 0:
transactions = Transaction.objects.all().order_by('-created')[:5]
else:
# display everything
orders = Order.objects.all().order_by('-created')
transactions = Transaction.objects.all().order_by('-created')
return render(request, 'log.html', locals())
+136
View File
@@ -0,0 +1,136 @@
from datetime import datetime, timedelta
from itertools import groupby
from django.contrib import messages
from django.shortcuts import render, redirect
from main.forms import DateRangeForm, InventoryTransactionForm
from main.models import Product, InventoryTransaction, UserProfile, Transaction, Order
def report(request):
# FIXME: split this up in smaller pieces
datetime_now = datetime.now()
start_time = datetime.now() - timedelta(days=30)
# start of day, 1 month
start_time = start_time.replace(hour=0, minute=0, second=0, microsecond=0)
# end of day
end_time = datetime.now().replace(hour=23, minute=59, second=59, microsecond=999)
if request.GET.get('start_time', False) or request.GET.get('end_time', False):
form = DateRangeForm(request.GET)
if form.is_valid():
start_time = form.cleaned_data['start_time']
# end of day
end_time = form.cleaned_data['end_time'].replace(hour=23, minute=59, second=59, microsecond=999)
else:
form = DateRangeForm(initial={
'start_time': start_time.strftime("%Y-%m-%d"),
'end_time': end_time.strftime("%Y-%m-%d")
})
# Inventory
products = Product.objects\
.filter(transactions__created__range=[start_time, end_time])\
.values('name', 'transactions__unit_price', 'transactions__amount')\
.order_by('name')
# group by name and sum
inventory_products = {}
for k, g in groupby(products, lambda x: x['name']):
group = []
for el in g:
el['transactions__price'] = el['transactions__amount'] * el['transactions__unit_price']
group.append(el)
inventory_products.update({k: {
'name': k,
"transactions": group,
"transactions_sum": sum(map(lambda x: x['transactions__price'], group)),
"transactions_units": sum(map(lambda x: x['transactions__amount'], group))
}})
itrans = InventoryTransaction.objects.filter(created__range=[start_time, end_time])
inv_in = sum(map(lambda x: x[1].get('transactions_sum', 0), inventory_products.items()))
# out
out_products = Product.objects\
.filter(orderlines__order__created__range=[start_time, end_time])\
.values('name', 'orderlines__unit_price', 'orderlines__amount')\
.order_by('name')
# group by name and sum
for k, g in groupby(out_products, lambda x: x['name']):
group = []
for el in g:
el['orderlines__price'] = el['orderlines__amount'] * el['orderlines__unit_price']
group.append(el)
product = {
'name': k,
"orderlines": group,
"orderlines_sum": sum(map(lambda x: x['orderlines__price'], group)),
"orderlines_units": sum(map(lambda x: x['orderlines__amount'], group))
}
if k in inventory_products:
# add diff
inventory_products[k].update(product)
else:
inventory_products.update({k: product})
for p in inventory_products.items():
p[1]['value_diff'] = p[1].get('transactions_sum', 0) - p[1].get('orderlines_sum', 0)
p[1]['units_diff'] = p[1].get('transactions_units', 0) - p[1].get('orderlines_units', 0)
inv_out = sum(map(lambda x: x[1].get('orderlines_sum', 0), inventory_products.items()))
inv_diff = inv_in - inv_out
# Deposits and sales
saldo_profiles = sum(UserProfile.objects.all().values_list('balance', flat=True))
deposits = sum(Transaction.objects.all().values_list('amount', flat=True))
purchases = sum(Order.objects.all().values_list('order_sum', flat=True))
saldo = deposits - purchases
deposits_start = sum(Transaction.objects.filter(created__lt=start_time).values_list('amount', flat=True))
purchases_start = sum(Order.objects.filter(created__lt=start_time).values_list('order_sum', flat=True))
saldo_start = deposits_start - purchases_start
deposits_end = sum(Transaction.objects.filter(created__lt=end_time).values_list('amount', flat=True))
purchases_end = sum(Order.objects.filter(created__lt=end_time).values_list('order_sum', flat=True))
saldo_end = deposits_end - purchases_end
deposits_diff = deposits_end - deposits_start
purchases_diff = purchases_end - purchases_start
saldo_diff = saldo_end - saldo_start
return render(request, 'report.html', locals())
def inventory(request):
products = Product.objects.all().order_by('-active', 'inventory_amount', 'name')
transactions = InventoryTransaction.objects.all().order_by('-created')
products_active = products.filter(active=True)
wholesale_value = sum([p.wholesale_value for p in products_active])
num_products = sum(products_active.values_list('inventory_amount', flat=True))
return render(request, 'inventory.html', locals())
def inventory_add(request):
if request.method == "POST":
form = InventoryTransactionForm(data=request.POST)
if form.is_valid():
itrans = form.save(commit=False)
# Add amount and user, then save
itrans.product.inventory_amount += itrans.amount
itrans.user = request.user
itrans.product.save()
itrans.save()
messages.success(request, "Satt inn {0} stk {1}.".format(itrans.amount, itrans.product))
return redirect('inventory-add')
else:
messages.error(request, 'Feil med skjemaet, se under.')
form = InventoryTransactionForm(data=request.POST)
else:
form = InventoryTransactionForm()
return render(request, 'inventory_add.html', locals())
+176
View File
@@ -0,0 +1,176 @@
from __future__ import unicode_literals
from datetime import datetime, timedelta, time
from django.db.models import Sum, Count
from django.http import JsonResponse
from django.shortcuts import render, get_object_or_404
from itertools import groupby
from main.models import Product, OrderLine, Order
def stats_list(request):
products = Product.objects.filter(active=True)
return render(request, 'stats.html', {'products': products})
def serialize_product(product):
f_product = {}
for attr in Product._meta.get_all_field_names():
if attr in ["transactions", "orderlines", "image"]:
continue
if hasattr(product, attr) and product.__getattribute__(attr):
if type(product.__getattribute__(attr)) is datetime:
f_product[attr] = str(product.__getattribute__(attr))
else:
f_product[attr] = product.__getattribute__(attr)
return f_product
def products_json(request, product_id=None):
if product_id:
# single
products = get_object_or_404(Product, pk=product_id)
else:
# many
products = Product.objects.filter(active=True)
if product_id:
f_products = serialize_product(products)
else:
f_products = [serialize_product(product) for product in products]
return JsonResponse(f_products)
def stats_product(product):
# reverse lookup via order, customer
per_user = OrderLine.objects\
.filter(product=product)\
.values('order__customer__first_name', 'order__customer__last_name')\
.annotate(num=Sum('amount'))\
.order_by('-num')
f_per_user = []
for row in per_user:
if row['order__customer__first_name'] is not None:
who = row['order__customer__first_name'] + " " + row['order__customer__last_name']
else:
who = "Ekstern"
num = row['num']
f_per_user.append([who, num])
response = {
'product': serialize_product(Product.objects.get(pk=product)) if type(product) is unicode else serialize_product(product),
'counts': f_per_user,
'total_counts': sum([row['num'] for row in per_user]),
}
return response
def stats_products(request, product=None):
if product:
# single
f_products = [stats_product(product)]
sales = OrderLine.objects.filter(product=product)
else:
# all
sales = OrderLine.objects.filter(product__active=True)
f_products = [stats_product(p) for p in Product.objects.filter(active=True)]
totals = float(sum([sale.amount for sale in sales]))
response = {
'request': 'all' if not product else product,
'response': {
'products': f_products,
'total_count': totals,
}
}
return JsonResponse(response)
def stats_orders(request):
num_external_orders = Order.objects.filter(customer=None).count()
per_user = Order.objects\
.values('customer__first_name', 'customer__last_name')\
.annotate(num=Count('customer'))\
.order_by('num').reverse()
f_per_user = []
for row in per_user:
if row['customer__first_name'] is not None:
who = row['customer__first_name'] + " " + row['customer__last_name']
num = row['num']
else:
who = "Ekstern"
num = num_external_orders
f_per_user.append([who, num])
return JsonResponse(f_per_user, safe=False)
def stats_orders_hourly(request):
orders = Order.objects.all()
f_hourly = dict([(key, 0) for key in range(0, 24)]) # init
# group by hour
for key, values in groupby(orders, key=lambda row: row.created.hour):
count = len(list(values))
f_hourly[key] += count
if len(orders) == 0:
return JsonResponse({})
response = {
'start': str(orders[0].created),
'hourly': [[k, v] for k, v in f_hourly.iteritems()],
'total': sum(f_hourly.values()),
}
return JsonResponse(response)
def stats_products_realtime(request):
end_time = datetime.now()
start_time = datetime.now() - timedelta(hours=24)
order_lines = OrderLine.objects.filter(order__created__range=(start_time, end_time)).order_by("order__created")
products = {}
for order_line in order_lines:
order_time_in_milliseconds = int(time.mktime(order_line.order.created.timetuple()) * 1000)
if order_line.product not in products:
products[order_line.product] = [[order_time_in_milliseconds, order_line.amount]]
else:
prev_entry = products[order_line.product][-1]
products[order_line.product].append([order_time_in_milliseconds, prev_entry[1] + order_line.amount])
serialized_products = {}
for product, value in products.iteritems():
serialized_products[product.name] = value
response = {
'products': serialized_products
}
return JsonResponse(response)
def stats_products_per_user(request, user_id=None):
if not user_id:
return JsonResponse({'error': 'Missing param user_id'})
order_lines = OrderLine.objects.filter(order__customer__pk=user_id).order_by("order__created")
products = {}
for order_line in order_lines:
order_time_in_milliseconds = int(time.mktime(order_line.order.created.timetuple()) * 1000)
if order_line.product not in products:
products[order_line.product] = [[order_time_in_milliseconds, order_line.amount]]
else:
prev_entry = products[order_line.product][-1]
products[order_line.product].append([order_time_in_milliseconds, prev_entry[1] + order_line.amount])
serialized_products = []
for product, value in products.iteritems():
serialized_products.append({
'name': product.name,
'data': value
})
return JsonResponse(serialized_products)
+61
View File
@@ -0,0 +1,61 @@
# coding: utf-8
from __future__ import unicode_literals
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db import connection
from django.db.models import Sum, Count
from django.shortcuts import render, redirect
from django.contrib.auth import logout as auth_logout
from main.forms import SimpleCreateUserForm
from main.models import Order
from main.models import Transaction
def logout(request):
auth_logout(request)
return render(request, 'registration/logout.html')
def create_user(request):
if request.method == "POST":
form = SimpleCreateUserForm(data=request.POST)
if form.is_valid():
user = form.save()
messages.success(request, "Hurra! {0} {1} er lagt til".format(user.first_name, user.last_name))
return redirect('create-user')
else:
messages.error(request, 'Feil med skjemaet, se under.')
form = SimpleCreateUserForm(data=request.POST)
else:
form = SimpleCreateUserForm()
return render(request, 'registration/create_user.html', {'form': form})
@login_required
def profile(request):
transactions = Transaction.objects.filter(user=request.user.pk)
transaction_totals = {
'sum': sum([t.amount for t in transactions])
}
orders = Order.objects.filter(customer=request.user.pk)
orders_totals = {
'sum': sum([o.order_sum for o in orders])
}
# order_lines = OrderLine.objects.filter(order__customer__pk=1).order_by("order__created")
order_report = _orders_monthly(filter_by={'customer': request.user.pk})
top_months = order_report.order_by('-sum')[:5]
return render(request, 'profile.html', locals())
def _orders_monthly(filter_by={}, order_by='month'):
truncate_date = connection.ops.date_trunc_sql('month', 'created')
qs = Order.objects.filter(**filter_by).extra({'month': truncate_date})
order_report = qs.values('month').annotate(sum=Sum('order_sum'), num=Count('pk')).order_by(order_by)
return order_report
+3 -4
View File
@@ -1,9 +1,8 @@
Django>=1.6,<1.7
Django>=1.8,<1.9
django-bootstrap-form==3.1
django-compressor==1.4
django-extensions==1.5.5
django-extensions==1.5.9
django-widget-tweaks==1.3
facebook-sdk==0.4.0
mysqlclient==1.3.6
Pillow==2.5.1
South==1.0
Pillow==3.0.0
+14 -14
View File
@@ -1,13 +1,13 @@
<!doctype html>
{% load compress %}
{% load compress staticfiles %}
<html>
<head>
<title>{%block title%}BBS{%endblock%}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="x-django-static-url" content="{{ STATIC_URL }}">
<meta name="x-django-static-url" content="{% static "" %}">
{% compress css %}
<link rel="stylesheet" href="{{ STATIC_URL }}dist/styles/screen.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="{% static "dist/styles/screen.css" %}" type="text/css" media="screen, projection">
{% endcompress %}
{%block headinc %}{%endblock%}
</head>
@@ -38,7 +38,7 @@
<li><a href="{% url 'login' %}">Logg inn</a></li>
{% else %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><img src="{{ user.get_profile.profile_image_url }}" /><span class="name">{{ user.first_name }}</span> <b class="caret"></b></a>
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><img src="{{ user.profile.profile_image_url }}" /><span class="name">{{ user.first_name }}</span> <b class="caret"></b></a>
<ul class="dropdown-menu">
{% if request.user.is_authenticated %}<li class="{% block active_profile %}{% endblock %}"><a href="{% url 'profile' %}"><i class="glyphicon glyphicon-user"></i> Profil</a></li>{% endif %}
<li class="{% block active_create_user %}{% endblock %}"><a href="{% url 'create-user' %}"><i class="glyphicon glyphicon-plus"></i> Ny bruker</a></li>
@@ -63,7 +63,7 @@
{%block footer %}
<div class="credits">
Laget med <span class="love" title="kærlighed">♥</span> av <a href="http://edb.neuf.no/">EDB-gjengen i KAK</a><br/>
<a href="http://edb.neuf.no/"><img src="{{ STATIC_URL }}dist/images/edb_brick.png" alt="EDB" /></a>
<a href="http://edb.neuf.no/"><img src="{% static "dist/images/edb_brick.png" %}" alt="EDB" /></a>
</div>
{%endblock%}
</div>
@@ -72,15 +72,15 @@
{% compress js %}
<script type="text/javascript" src="{{ STATIC_URL }}app/bower_components/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/collapse.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/dropdown.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/tooltip.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}app/bower_components/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}app/bower_components/bootstrap-datepicker/js/locales/bootstrap-datepicker.nb.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}app/bower_components/highcharts/highcharts.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}app/bower_components/underscore/underscore-min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}dist/js/app.js"></script>
<script type="text/javascript" src="{% static "app/bower_components/jquery/dist/jquery.min.js" %}"></script>
<script type="text/javascript" src="{% static "app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/collapse.js" %}"></script>
<script type="text/javascript" src="{% static "app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/dropdown.js" %}"></script>
<script type="text/javascript" src="{% static "app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/tooltip.js" %}"></script>
<script type="text/javascript" src="{% static "app/bower_components/bootstrap-datepicker/js/bootstrap-datepicker.js" %}"></script>
<script type="text/javascript" src="{% static "app/bower_components/bootstrap-datepicker/js/locales/bootstrap-datepicker.nb.js" %}"></script>
<script type="text/javascript" src="{% static "app/bower_components/highcharts/highcharts.js" %}"></script>
<script type="text/javascript" src="{% static "app/bower_components/underscore/underscore-min.js" %}"></script>
<script type="text/javascript" src="{% static "dist/js/app.js" %}"></script>
{% endcompress %}
{%block tailinc %}{%endblock%}
</body>
+3 -3
View File
@@ -20,7 +20,7 @@
<p>Spør en av disse om de kan hjelpe deg:</p>
<ul>
{% for u in allowed_users %}
<li style="padding-bottom: 8px;"><img src="{{u.get_profile.image }}" />{{u.first_name }} {{u.last_name }}</li>
<li style="padding-bottom: 8px;"><img src="{{u.profile.image }}" />{{u.first_name }} {{u.last_name }}</li>
{% endfor %}
</ul>
</div>
@@ -48,9 +48,9 @@
<ul class="well">
{% for user in users %}
<li class="customer">{% spaceless %}
<img class="profile" src="{{ user.get_profile.profile_image_url }}" alt="Profile picture"/><br />
<img class="profile" src="{{ user.profile.profile_image_url }}" alt="Profile picture"/><br />
<span class="name">{{ user.first_name }} {{ user.last_name|slice:":1"}}</span><br />
<span class="balance">{{ user.get_profile.balance }}</span>
<span class="balance">{{ user.profile.balance }}</span>
<span class="id" style="display:none;">{{ user.id }}</span>
{% endspaceless %}</li>
{% endfor %}
+1 -1
View File
@@ -66,7 +66,7 @@
<td>{{ t.created }}</td>
<td>{{ t.product }}</td>
<td>{{ t.amount }}</td>
<td>{% if t.user.get_profile.image %}<img src="{{ t.user.get_profile.image }}" class="customer" title="{{ t.user.first_name }} {{ t.user.last_name|slice:":1"}}" />{% else %}{{ t.user.first_name }} {{ t.user.last_name|slice:":1"}}{% endif %}</td>
<td>{% if t.user.profile.image %}<img src="{{ t.user.profile.image }}" class="customer" title="{{ t.user.first_name }} {{ t.user.last_name|slice:":1"}}" />{% else %}{{ t.user.first_name }} {{ t.user.last_name|slice:":1"}}{% endif %}</td>
</tr>
{% endfor %}
</tbody>
+2 -2
View File
@@ -36,7 +36,7 @@
{% for order in orders %}
<tr>
<td>{{ order.created }}</td>
<td>{% if order.customer %}{% if order.customer.get_profile.image %}<img src="{{ order.customer.get_profile.image }}" class="customer" title="{{ order.customer.first_name }} {{ order.customer.last_name|slice:":1"}}" />{% else %}{{ order.customer.first_name }} {{ order.customer.last_name|slice:":1"}}{% endif %}{% else %}Ekstern{% endif %}</td>
<td>{% if order.customer %}{% if order.customer.profile.image %}<img src="{{ order.customer.profile.image }}" class="customer" title="{{ order.customer.first_name }} {{ order.customer.last_name|slice:":1"}}" />{% else %}{{ order.customer.first_name }} {{ order.customer.last_name|slice:":1"}}{% endif %}{% else %}Ekstern{% endif %}</td>
<td>{% for line in order.orderlines.all %}
<span class="amount">{{ line.amount}}</span> <a href="#" class="product" title="{{ line.unit_price}} per">{{ line.product }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</td>
<td>{{ order.order_sum }}</td>
@@ -69,7 +69,7 @@
{% for t in transactions %}
<tr>
<td>{{ t.created }}</td>
<td>{% if t.user.get_profile.image %}<img src="{{ t.user.get_profile.image }}" class="customer" title="{{ t.user.first_name }} {{ t.user.last_name|slice:":1"}}" />{% else %}{{ t.user.first_name }} {{ t.user.last_name|slice:":1"}}{% endif %}</td>
<td>{% if t.user.profile.image %}<img src="{{ t.user.profile.image }}" class="customer" title="{{ t.user.first_name }} {{ t.user.last_name|slice:":1"}}" />{% else %}{{ t.user.first_name }} {{ t.user.last_name|slice:":1"}}{% endif %}</td>
<td>{{ t.amount }}</td>
<!--<td>{% include "modal-delete-transaction.html" with t=t %}<a class="btn btn-danger" data-toggle="modal" href="#modal-trans-{{t.id}}"><i class="icon-trash icon-white"></i> Slett</a></td>-->
</tr>
+2 -2
View File
@@ -5,7 +5,7 @@
<section id="user-profile" data-user-id="{{request.user.pk}}">
<div class="row">
<div class="col-md-12">
<h1 class="profile-name"><img src="{{ request.user.get_profile.profile_image_url }}" class="profile-image" /> {{user.first_name}}</h1>
<h1 class="profile-name"><img src="{{ request.user.profile.profile_image_url }}" class="profile-image" /> {{user.first_name}}</h1>
</div>
</div>
<div class="row">
@@ -13,7 +13,7 @@
<div class="panel panel-default">
<div class="panel-heading">Saldo</div>
<div class="panel-body">
<h2>{{request.user.get_profile.balance }} kr</h2>
<h2>{{request.user.profile.balance }} kr</h2>
</div>
</div>
<div class="panel panel-default">
+7 -6
View File
@@ -1,4 +1,5 @@
{% extends "base.html" %}
{% load staticfiles %}
{% block active_register %}active{% endblock %}
{% block content %}
@@ -40,14 +41,14 @@
<div class="col-md-12">
<ul class="well">
<li class="customer">{% spaceless %}
<img class="profile" src="{{ STATIC_URL }}dist/images/unknown_person.png" alt="Profile picture" /><br />
<img class="profile" src="{% static "dist/images/unknown_person.png" %}" alt="Profile picture" /><br />
<span class="name">Ekstern</span><br />
<span class="balance">&nbsp;</span>
{% endspaceless %}</li>
{% for user in users %}<li class="customer{% if user.get_profile.last_purchase_date < half_a_year_ago and not user.get_profile.last_purchase == None %} infrequent hidden{% endif %}">{% spaceless %}
<img class="profile" src="{{ user.get_profile.profile_image_url }}" alt="Profile picture" /><br />
{% for user in users %}<li class="customer{% if user.profile.last_purchase_date < half_a_year_ago and not user.profile.last_purchase == None %} infrequent hidden{% endif %}">{% spaceless %}
<img class="profile" src="{{ user.profile.profile_image_url }}" alt="Profile picture" /><br />
<span class="name">{{ user.first_name }} {{ user.last_name|slice:":1"}}</span><br />
<span class="balance">{{ user.get_profile.balance }}</span>
<span class="balance">{{ user.profile.balance }}</span>
<span class="id" style="display:none;">{{ user.id }}</span>
{% endspaceless %}</li>{% endfor %}
</ul>
@@ -77,9 +78,9 @@
<input type="hidden" name="form-{{ forloop.counter0 }}-unit_price_ext" value="{{product.sale_price_ext }}" />
<span class="qty">0</span>
{% if product.image %}
<img class="product" src="{{ product.image.url }}" /><br />
<img class="product" src="{{ product.image.url }}" /><br />
{% else %}
<img class="product" src="{{ STATIC_URL }}dist/images/product.png" /><br />
<img class="product" src="{% static "dist/images/product.png" %}" /><br />
{% endif %}
<span class="name">{{ product.name }}</span> - <span class="sale_price_ext">{{product.sale_price_ext|floatformat:0}}</span>/<span class="sale_price_int">{{product.sale_price_int|floatformat:0}}</span>
</li>