From 5c04bad4e634fa471a3b9bd344fca56130199739 Mon Sep 17 00:00:00 2001 From: Basil Khan Date: Tue, 14 Feb 2017 23:56:58 -0500 Subject: [PATCH 01/22] First Commit --- manage.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 manage.py diff --git a/manage.py b/manage.py new file mode 100644 index 000000000..621838c79 --- /dev/null +++ b/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) From dedf988dff97584501046aa9718a20dbc42e21ef Mon Sep 17 00:00:00 2001 From: Basil Khan Date: Wed, 15 Feb 2017 21:36:12 -0500 Subject: [PATCH 02/22] refactor(FielStructure): building the file structure --- wave/__init__.py | 0 wave/myapp/__init__.py | 0 wave/myapp/admin.py | 4 ++ wave/myapp/forms.py | 9 +++ wave/myapp/models.py | 20 ++++++ wave/myapp/templates/list.html | 55 ++++++++++++++++ wave/myapp/tests.py | 3 + wave/myapp/urls.py | 7 ++ wave/myapp/views.py | 90 ++++++++++++++++++++++++++ wave/settings.py | 115 +++++++++++++++++++++++++++++++++ wave/urls.py | 13 ++++ wave/wsgi.py | 16 +++++ 12 files changed, 332 insertions(+) create mode 100644 wave/__init__.py create mode 100644 wave/myapp/__init__.py create mode 100644 wave/myapp/admin.py create mode 100644 wave/myapp/forms.py create mode 100644 wave/myapp/models.py create mode 100644 wave/myapp/templates/list.html create mode 100644 wave/myapp/tests.py create mode 100644 wave/myapp/urls.py create mode 100644 wave/myapp/views.py create mode 100644 wave/settings.py create mode 100644 wave/urls.py create mode 100644 wave/wsgi.py diff --git a/wave/__init__.py b/wave/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/wave/myapp/__init__.py b/wave/myapp/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/wave/myapp/admin.py b/wave/myapp/admin.py new file mode 100644 index 000000000..b8853866b --- /dev/null +++ b/wave/myapp/admin.py @@ -0,0 +1,4 @@ +from django.contrib import admin +from myproject.myapp.models import Document +admin.site.register(Document) +# Register your models here. diff --git a/wave/myapp/forms.py b/wave/myapp/forms.py new file mode 100644 index 000000000..e3a3dfd37 --- /dev/null +++ b/wave/myapp/forms.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +from django import forms + + +class DocumentForm(forms.Form): + docfile = forms.FileField( + label='Select a file' + ) diff --git a/wave/myapp/models.py b/wave/myapp/models.py new file mode 100644 index 000000000..5033a4536 --- /dev/null +++ b/wave/myapp/models.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from django.db import models + +class Document(models.Model): + docfile = models.FileField(upload_to='documents/%Y-%m-%d') + created_time = models.DateTimeField() + +class Expense(models.Model): + document = models.ForeignKey( + Document, + on_delete=models.CASCADE, + ) + date = models.DateField() + category = models.CharField(max_length=100) + employee_name = models.CharField(max_length=100) + employee_address = models.CharField(max_length=512) + expense_desc = models.CharField(max_length=100) + pretax_amt = models.DecimalField(max_digits=6, decimal_places=2) + tax_name = models.CharField(max_length=100) + tax_amount = models.DecimalField(max_digits=6, decimal_places=2) \ No newline at end of file diff --git a/wave/myapp/templates/list.html b/wave/myapp/templates/list.html new file mode 100644 index 000000000..6b360e896 --- /dev/null +++ b/wave/myapp/templates/list.html @@ -0,0 +1,55 @@ + + + + + Wave SE Challenge + + + +

Wave SE Challenge

+ + {% if documents %} + + {% else %} +

No documents.

+ {% endif %} + + +
+ {% csrf_token %} +

{{ form.non_field_errors }}

+ +

{{ form.docfile.label_tag }} {{ form.docfile.help_text }}

+ +

+ {{ form.docfile.errors }} + {{ form.docfile }} +

+ +

+
+ + + diff --git a/wave/myapp/tests.py b/wave/myapp/tests.py new file mode 100644 index 000000000..7ce503c2d --- /dev/null +++ b/wave/myapp/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/wave/myapp/urls.py b/wave/myapp/urls.py new file mode 100644 index 000000000..7ed59c8c6 --- /dev/null +++ b/wave/myapp/urls.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +from django.conf.urls import url +from myproject.myapp.views import list + +urlpatterns = [ + url(r'^list/$', list, name='list') +] diff --git a/wave/myapp/views.py b/wave/myapp/views.py new file mode 100644 index 000000000..9e7fff210 --- /dev/null +++ b/wave/myapp/views.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +from django.shortcuts import render +from django.template import RequestContext +from django.http import HttpResponseRedirect +from django.core.urlresolvers import reverse + +from myproject.myapp.models import Document +from myproject.myapp.models import Expense +from myproject.myapp.forms import DocumentForm +from datetime import datetime +import csv + + +def list(request): + # Handle file upload + if request.method == 'POST': + form = DocumentForm(request.POST, request.FILES) + if form.is_valid(): + handle_uploaded_file(request) + + # Redirect to the document list after POST + return HttpResponseRedirect(reverse('list')) + else: + form = DocumentForm() # A empty, unbound form + + # Load documents for the list page + documents = Document.objects.all() + # expenses = Expense.objects.all() + # Render list page with the documents and the form +# expense = {} +# for document in documents: +# for expenses in document.expense_set.all(): +# dt = expenses.date.day.replace(day=0) +# dt +# for monthly in expenses.date + # expense[expenses.date] = expenses.pretax_amt+ expenses.tax_amount + + expenses = Expense.objects.raw('''SELECT id, date, strftime('%m',date) AS month_date, strftime('%Y',date) AS year_date, SUM(tax_amount+pretax_amt) AS total_amount + FROM myapp_expense + WHERE document_id=30 + GROUP BY year_date, month_date + ORDER BY date''') + # print expenses.total_amount + +# for document in documents: +# for expenses in document.expense_set.all(): +# if expense[str(expenses.date.year)+'/'+str(expenses.date.month)]: +# expense[str(expenses.date.year)+'/'+str(expenses.date.month)] += expenses.pretax_amt+ expenses.tax_amount +# else: +# expense[str(expenses.date.year)+'/'+str(expenses.date.month)] = expenses.pretax_amt+ expenses.tax_amount + # expense[document.id] = { document.id: expense.pretax_amt+ expense.tax_amount } + + return render( + request, + 'list.html', + { + 'documents': documents, + 'form': form, + 'expenses': expenses + } + ) + +def handle_uploaded_file(request): + newdoc = Document( + docfile=request.FILES['docfile'], + created_time = datetime.now() + ) + newdoc.save() + + + # handle_uploaded_file(request.FILES['docfile']) + reader = csv.DictReader(request.FILES['docfile']) + # save_to_db(row, newdoc) + for row in reader: + save_to_db(row, newdoc) + +def save_to_db(row, doc): + csv_to_db = Expense( + date = datetime.strptime(row['date'],'%m/%d/%Y' ), + category = row['category'], + employee_name = row['employee name'], + employee_address = row['employee address'], + expense_desc = row['expense description'], + pretax_amt = amount_formatter(row['pre-tax amount']), + tax_name = row['tax name'], + tax_amount = amount_formatter(row['tax amount']), + document = doc + ) + csv_to_db.save() + diff --git a/wave/settings.py b/wave/settings.py new file mode 100644 index 000000000..438402a02 --- /dev/null +++ b/wave/settings.py @@ -0,0 +1,115 @@ +""" +Django settings for myproject project. + +Generated by 'django-admin startproject' using Django 1.8. + +For more information on this file, see +https://docs.djangoproject.com/en/1.8/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.8/ref/settings/ +""" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '-q@x+fbn4vl-+qs!*a=+(u%j1w76z_(7re-1*b+yb&a+rj=-&+' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'myproject.myapp' +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.middleware.security.SecurityMiddleware', +) + +ROOT_URLCONF = 'myproject.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + os.path.join(BASE_DIR, 'myproject', 'myapp', 'templates') + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this + # list if you haven't customized them: + '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', + ], + }, + }, +] + +WSGI_APPLICATION = 'myproject.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.8/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + + +# Internationalization +# https://docs.djangoproject.com/en/1.8/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') +MEDIA_URL = '/media/' + +DATE_INPUT_FORMATS = ('%m-%d-%Y') +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.8/howto/static-files/ +STATIC_URL = '/static/' diff --git a/wave/urls.py b/wave/urls.py new file mode 100644 index 000000000..93518858a --- /dev/null +++ b/wave/urls.py @@ -0,0 +1,13 @@ +from django.conf.urls import include, url +from django.conf import settings +from django.conf.urls.static import static +from django.views.generic import RedirectView +from myproject.myapp.views import list + +from django.contrib import admin + +urlpatterns = [ + url(r'^admin/', include(admin.site.urls)), + url(r'^myapp/', include('myproject.myapp.urls')), + url(r'^$', list, name='list') +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/wave/wsgi.py b/wave/wsgi.py new file mode 100644 index 000000000..4aa8a8163 --- /dev/null +++ b/wave/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for myproject project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") + +application = get_wsgi_application() From 0ced7b5547315cde34d0ebd7a416b3c8d075de03 Mon Sep 17 00:00:00 2001 From: Basil Khan Date: Wed, 15 Feb 2017 22:12:05 -0500 Subject: [PATCH 03/22] feat(Migration): Complete first migration and DB setup --- db.sqlite3 | Bin 0 -> 40960 bytes manage.py | 2 +- wave/__init__.pyc | Bin 0 -> 160 bytes wave/myapp/__init__.pyc | Bin 0 -> 166 bytes wave/myapp/admin.py | 2 +- wave/myapp/admin.pyc | Bin 0 -> 326 bytes wave/myapp/forms.pyc | Bin 0 -> 532 bytes wave/myapp/migrations/0001_initial.py | 40 +++++++++++++++++++++++++ wave/myapp/migrations/0001_initial.pyc | Bin 0 -> 1713 bytes wave/myapp/migrations/__init__.py | 0 wave/myapp/migrations/__init__.pyc | Bin 0 -> 177 bytes wave/myapp/models.pyc | Bin 0 -> 1291 bytes wave/myapp/urls.py | 2 +- wave/myapp/urls.pyc | Bin 0 -> 348 bytes wave/myapp/views.py | 6 ++-- wave/myapp/views.pyc | Bin 0 -> 2625 bytes wave/settings.py | 10 +++---- wave/settings.pyc | Bin 0 -> 3223 bytes wave/urls.py | 4 +-- wave/urls.pyc | Bin 0 -> 790 bytes wave/wsgi.py | 4 +-- wave/wsgi.pyc | Bin 0 -> 611 bytes 22 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 db.sqlite3 create mode 100644 wave/__init__.pyc create mode 100644 wave/myapp/__init__.pyc create mode 100644 wave/myapp/admin.pyc create mode 100644 wave/myapp/forms.pyc create mode 100644 wave/myapp/migrations/0001_initial.py create mode 100644 wave/myapp/migrations/0001_initial.pyc create mode 100644 wave/myapp/migrations/__init__.py create mode 100644 wave/myapp/migrations/__init__.pyc create mode 100644 wave/myapp/models.pyc create mode 100644 wave/myapp/urls.pyc create mode 100644 wave/myapp/views.pyc create mode 100644 wave/settings.pyc create mode 100644 wave/urls.pyc create mode 100644 wave/wsgi.pyc diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..4d0f207f681ea2f2da48e7fa33119f8697628bb5 GIT binary patch literal 40960 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 literal 0 HcmV?d00001 diff --git a/wave/myapp/admin.py b/wave/myapp/admin.py index b8853866b..2af3ce874 100644 --- a/wave/myapp/admin.py +++ b/wave/myapp/admin.py @@ -1,4 +1,4 @@ from django.contrib import admin -from myproject.myapp.models import Document +from wave.myapp.models import Document admin.site.register(Document) # Register your models here. diff --git a/wave/myapp/admin.pyc b/wave/myapp/admin.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee51badc27d8239a3141f04707bb3c95cbe167a4 GIT binary patch literal 326 zcmYLDO-lqZ3{9uIDuS~6FXlA4coY%wC?YGO>_uuPE*<(YG+kxS{uY0sKS0x2#n8Uw zrA^+`Unj?h%g-kZztKp(l*?xVy&MG|AShTXP?a~}8weWK8WbrQW-!cwGl%>GCd801u%s6%- z_2hXqEv*{t3YEGp)5dY3+)54qz&AoM#DW$dm@?y)VdwEro$)TGfox%X6cv1R(fH?a d-@_`5lQ2&1yKy&(or{gFr;BQXtBr+Ps2~0;OX>gs literal 0 HcmV?d00001 diff --git a/wave/myapp/forms.pyc b/wave/myapp/forms.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a9d2edd2ea3a45eb4a174f81e9c0fde8e6ab368 GIT binary patch literal 532 zcmb_ZO;3a{5S;>k?8Z$zd)gxx?H@44Yz!x348*8hNTq{;w1v>FX3y(?@aCWN2k5l; z5$`s1c<&97LEB*?XKyyiC+N6S~jwu*n>!Sd^|@2I`yx8ezT(;A_wVbb`sm-I#q0}t0f88*2$ vWS6#0JYX|+m3rj7COcss`)NWidWS;6??3_l`&7ZO)5)SU|KF|m`7r(j!UlT< literal 0 HcmV?d00001 diff --git a/wave/myapp/migrations/0001_initial.py b/wave/myapp/migrations/0001_initial.py new file mode 100644 index 000000000..1f8e9813d --- /dev/null +++ b/wave/myapp/migrations/0001_initial.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.2 on 2017-02-16 03:08 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Document', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('docfile', models.FileField(upload_to=b'documents/%Y-%m-%d')), + ('created_time', models.DateTimeField()), + ], + ), + migrations.CreateModel( + name='Expense', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('category', models.CharField(max_length=100)), + ('employee_name', models.CharField(max_length=100)), + ('employee_address', models.CharField(max_length=512)), + ('expense_desc', models.CharField(max_length=100)), + ('pretax_amt', models.DecimalField(decimal_places=2, max_digits=6)), + ('tax_name', models.CharField(max_length=100)), + ('tax_amount', models.DecimalField(decimal_places=2, max_digits=6)), + ('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='myapp.Document')), + ], + ), + ] diff --git a/wave/myapp/migrations/0001_initial.pyc b/wave/myapp/migrations/0001_initial.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab1f1683b50fe58902736927d25f31167658b28e GIT binary patch literal 1713 zcmcgs%Z?jG6usST&nxrFWF{dD1Xv7s6Zf!3h{-r3ArwHKAcz;Vdb+MVW%^-tRfm`@ z?D!1C7xDpc?rnRVMUYrwTjhICRo%xqRTcfUxAVt?KYz$*`HArV1%>3kfno3qs30l> zngkSxA5sxg8PO!7vPY9%helNNX|h44M;y^?lcoWgKK(}YE76O|CYgw?2OEfK|Hfw! z!19L}+RA3N;iRyho3wC)P-b>8ls0ctZ|ll=*;is!;lB3Uu%E4_Zp%If`b5h99g&%& zS`MYg95!m|(+tIFJLmw#@FvZ+v|PA-S!_0lx5=Q?Efn3G0@>DOJ7n;?127P9S3z+J zZXUr1*YWp+A@d*O?`x>tWhir?E+QO~xeHL!9lZ^__Xc>pT6yvYc)R_+g8O71ka>s9 zLo)ATeJG8bzHR+`|GxfxojM@%i1?6ZcSYve5zX$A`GCxa%dq*57&*v4rt$UQBM9Sr z7^<}7b_>R+&f1bIuc}Th7sj3GoeD>n;S^4x@2uPmEll<)2NI_XQn!`Y zIdIW2E_bJ{kPpPL*LZa+naV{vpAT2c3{E75Xq9NpB++)01b4747_M;gylL4BQMR%k zil`ihL7L$zv+Txt$wk6TmGhb0;IU?vLM|ZmmB{b=@UC$8JGHJLTZapuBM|-^l5~jd z6J+gOzD%3W6A?!pV;vw&T-6QRy!r}fN2oHhw90Gk+}vn~$^{-7?d0;}`toA*RJ*O` zc#rh?8DJx=2lpe~xU77f#oysDy7)=zY!R>6bMd!LJ>$%~`1|w~$5UI0h8-6FERfP2 zuOGPh{QUgWWXa=jz8K3ZEWNsqF>HkR_O^qK@RQ&qIEgyzKy3Y!nGjsG^@{>z*Q}arS^#h9Xvr?0RjPS&=RQPO2Tq5ye2v001!KEZ+bC literal 0 HcmV?d00001 diff --git a/wave/myapp/models.pyc b/wave/myapp/models.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d89bb2e6dc0c2fd6ff355de8e77438d03783621 GIT binary patch literal 1291 zcmcIk&2AGh5FT%S+J>YpJs`Mo3CgA27eI)%X)dS;B_L=nE3=-Yj`mM$2byzv6<&cC z;{jl1oTfn)$L?ll$KN>P@i(8h@w?Y~dGPZ~3hS#u@3-{05g9{21sOoDV5&fw2vETy zf|&x-fFA(209VrnnC4cXwFxxAv|%#Xp;Yz{T?0j)Z|PcMu6{;Khz#S+I$`D5|Y+P7_Cd_ zfW~ld+$9a;yzp@ve{xv6_)I&S#drI5@rSxxVCr4`S%1TLW(%DqRlwr!4CO0bRdL|# zq*{%c#wI-J783r|6J(#2VOlH$!}+7>!GoEH|C#xe`^o~5zLrHoib0Rku3Xa!;vEK(h1c`b z$@%HXD5;5M5CpSBN4#e@NjCqK&E1InQds z&`H{{O9dE)ErhIGXH}yo4s`CNEcRK=!a)d>%fjD_P`pP_A|E;4rF%xEt@!RnT~cJY wpVRyOfQ2Z`n1wFp<%#(k2xt6~KLjG^G3R>piiNJ%;jq79DaaW*j9xVV0&egl6951J literal 0 HcmV?d00001 diff --git a/wave/myapp/urls.py b/wave/myapp/urls.py index 7ed59c8c6..30e49c8c3 100644 --- a/wave/myapp/urls.py +++ b/wave/myapp/urls.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from django.conf.urls import url -from myproject.myapp.views import list +from wave.myapp.views import list urlpatterns = [ url(r'^list/$', list, name='list') diff --git a/wave/myapp/urls.pyc b/wave/myapp/urls.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f39180e7b8c5e05c51ccf00a50563b800919f31b GIT binary patch literal 348 zcmYLE!Ab)$5S?sV6-8M61`m7M`GF!L-UN|~Sb9*xCM{c%?6Q-#^z66zg?@m(bOl55 z^4`qL%tU`*o?l;mEgJe;Q`~nrG6Ps_MV=@qS}Iam7vu{HnwFZBQ)D$cO?ER08bA#C2CUU0l_u zAalgV%--x=9S)}N>s{;ia(tOCkcO`}DY+p^mF@o^kB}T<;)Y+v4Z`Y@ literal 0 HcmV?d00001 diff --git a/wave/myapp/views.py b/wave/myapp/views.py index 9e7fff210..3c9e3bcb5 100644 --- a/wave/myapp/views.py +++ b/wave/myapp/views.py @@ -4,9 +4,9 @@ from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse -from myproject.myapp.models import Document -from myproject.myapp.models import Expense -from myproject.myapp.forms import DocumentForm +from wave.myapp.models import Document +from wave.myapp.models import Expense +from wave.myapp.forms import DocumentForm from datetime import datetime import csv diff --git a/wave/myapp/views.pyc b/wave/myapp/views.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72801e1bf4ff89424f44587e3d50a2a8588c4b2f GIT binary patch literal 2625 zcmcImOK;mo5FV1UW$Ixmb!*fJQ1D_zMP0E)ft>n`EjI!D!YYny0R_Qu*D+N-6z<9o zAUV1H7rpk>pVXhxAJERs(y@RZd}$=@a%Xn-G4suQqW5>V^;iFopAx7)E)>cJZqei#Qi2L3$ykICtR$+e2B+G2dXKQQrC6zAo2ctb)gMu z<17=jB@0!2DR2yfcczssG|@(_Xi-N+F~DX!y@#VPFHD$(#~Q0Ed=l$43vVk+heuV( zr-di+g$mEo0>PeHU3f_#Hn5zG3sWo;EHZExi_gJ$PM5hbtu0lO3s(=RfOdXf z7fF!jcS6Juc zs73K2(>81%F!(n?LKkONZ)bXTrqB3*kJuq_mRRXeZajE^H?efbrAU};=HaFcH&3~O z62$9OSzRM}V*TYvYAsg#IS*W%*3Tb>zEfpDP2ojR3$z}3r=$J37tadQqEC%V!GC8iNgEhfrq&DJ~q8hhhVy`JFWWL z$7kR1-N6Sq!@{*(3$LQhLt)EWE^S|_0{{^=`NdN!< literal 0 HcmV?d00001 diff --git a/wave/settings.py b/wave/settings.py index 438402a02..1656ad812 100644 --- a/wave/settings.py +++ b/wave/settings.py @@ -1,5 +1,5 @@ """ -Django settings for myproject project. +Django settings for wave project. Generated by 'django-admin startproject' using Django 1.8. @@ -38,7 +38,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'myproject.myapp' + 'wave.myapp' ) MIDDLEWARE_CLASSES = ( @@ -52,13 +52,13 @@ 'django.middleware.security.SecurityMiddleware', ) -ROOT_URLCONF = 'myproject.urls' +ROOT_URLCONF = 'wave.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ - os.path.join(BASE_DIR, 'myproject', 'myapp', 'templates') + os.path.join(BASE_DIR, 'wave', 'myapp', 'templates') ], 'APP_DIRS': True, 'OPTIONS': { @@ -77,7 +77,7 @@ }, ] -WSGI_APPLICATION = 'myproject.wsgi.application' +WSGI_APPLICATION = 'wave.wsgi.application' # Database diff --git a/wave/settings.pyc b/wave/settings.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df9179e6e975b1757a5756fe2c1336f0ab7c1b77 GIT binary patch literal 3223 zcmeHJTXWM!6h5|t4JJ?u3D;6Y+Yl3Di2!4mPGL}NCH3G-CXyS_Lp8E??a1h2v};0m z<+t<~_6M|QS9a_nZb=`Rsb#Ns_nh;c>z-Ba&kM!ntAD)qVDdSK|1a^!9%TRsfQ@4Y zNEU(&*cqT17-nIZJ26=TdImmaCSN-bBnNf@=vlDO!2ofJKpuj99>^xx%RsJxeF6L> zAS*ytp*q362oxo+0=Wj{I(%A!0qVYihz0OSX# zk{_Xp0`@mReggXvAiJLhvIgYdXByVw6B0@&av!Spw?H<)z6_)c_7!RJiX2zvcy;P) zYTN@MYNLG>u&)DA!M*`R1N){3l398rVz-X5E7pf@G>8>OIrpOhQ~GhD9J=qRGD_kh z^|)Fr?$C%PE~iB49VzQX3RGMY`jNu8oA3$ex-w=6p-d1r)n_QXjc{R{P{ofBIdr)n zM+$!VfseZUfIdLgw0OYzi2bZ-B=(q^YMAQx;!vZJhHx5>N503jsjXTH&kv~59|wUF z_>3!Yf98uD5mZF|M0xK9W6J)Eu7vjI6#0MQr_DszD(_x?DEE8OllMWT{Epq-aG#e; zo?8yS|i54~V2?^+- zn^4tE_gcq0?EXw}jt>(V#*tc+e_!TiNnfqu@S9H$=eVEFu#aPjA)7Zy$2Eq^_hhxr z$-elq?8KRWgjf)hX>{jJXkkn+;&ZyIGu`2Fq*O2Py|+Wxdy5B0eZ8HyA?=LB8DVpx zm4%{=dgH|BM;QNfGAAM0qfF#D2^iC6@|=dF0FScTL!C4t)5E5wht`^q884vBmR@^h zwCj9ng2vC_M3x2@3Z__0GSnM;CO?bY`tGhH7Oaem&#PW!N>=g*?%)CUFidg6R96&z zX~sW=Uc^giZ#-b@r(^avpGBty4k_{7`P%(AE3ollfw8sInZZA@$1~1p-5wXtf{09M z{4&a&q|5wtcCALIZL(Elk=Z_E17F3Hi$x_%fBw9a-YnLwKsC1rP0z# zg6k{oh9%+E|1EJrSN$qlVo6-7vYH(SUosqrXK^D=d)LV22Wh4INrWv}&fOl9`y%g- zBQ8i35{oU}G(?Bv;<_}A+MZ!KuZ%ac3tGvT%2QD{wz@m~0&?ihW@q21JHK{J%j6ev zr_nYo+{HcYm8Lx5twz1xH1_p9!>KiO(=<%JjGTL&j^%Xsnzc@QTjCF6Ka$PYGFrP$ z-9o-g$hU9qGz3_)QPV|FkSulG(uJ+2G^44vce?rx;&OXh%ejq0K9|qt^N^W6`K8%h%#b6O%M`MAvV}};DVLc&EBSn0 StO}Xi=MW`*a;q7f<^BfaJIj6m literal 0 HcmV?d00001 diff --git a/wave/urls.py b/wave/urls.py index 93518858a..cf5effc1e 100644 --- a/wave/urls.py +++ b/wave/urls.py @@ -2,12 +2,12 @@ from django.conf import settings from django.conf.urls.static import static from django.views.generic import RedirectView -from myproject.myapp.views import list +from wave.myapp.views import list from django.contrib import admin urlpatterns = [ url(r'^admin/', include(admin.site.urls)), - url(r'^myapp/', include('myproject.myapp.urls')), + url(r'^myapp/', include('wave.myapp.urls')), url(r'^$', list, name='list') ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/wave/urls.pyc b/wave/urls.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b81eccd469c947312ef66334db126f607265575d GIT binary patch literal 790 zcmY*W&2H2%5FRJ{oBipwDwGG{u&4OI6(KbH--{R-~U=a8+&;W)($-pE~CcubIK&M~^ zP!1waK@Y)SgV}D|r*y0kT>-AJGs|C5*C;4!R5} zkGZ+6x{f>2b5mW*Jm4J9caD@@zVx(}t&A*a7r($D+InZC^_#wJ{pa-&@hjq+%5K}d zZtYdrp+F9b;A8f5x(KdMo|0ir9=#RR1%JFRxJGL(-%2ZcRTrcw9QjCdsE8t$`*kSB z_v%+cZ3|YM@-igk(NB^7bawjT-R7eB=(7h@oS%R5BpR!_%6r*cw?+v2;LZ?oV?D3= zg_FJG?<=P?KfUjc<6ru=!CP_s2X>ZUDO>4H7dcMCIZ4R7+i=UTO)GXf&we80CD!Q2Z+TDA%tMnQWZfL(OoU-B{lIRb>-MmX4e67Uo%6NavKb|odAr_2@FsX2fSg^rgCR{4o zOe`{yKqA&hVtp*kkub;NCS_M9Zus6HUYZXFk?R*jel?#=WfgpF8(D{5?(`O9*M~J! zROI=TBz*4z0!mteJY;L<^fw1mqtvnuX5-+wgDp6@)xF(^yl%nB^ff10Y$D)8z>@lvhAj)F4K zxp3WrC$+=Is@(qJH5(?}9z9`bfXWyt?}(wN92k9gH=CT7^YO*SbT*lnpUy{@AIEsY zp*V&Dfynv>hxZ~?gtBBsWl1U90qK;tgSw*PrixhQ3;Pbq;J3C9o^p0Dm4RAs9MJjaY9@Uvf>(nSzo7f|&&xglBb;TN0ZM}Bo?Qm3-y`MtSUDJJL UdVP4FH_^rjgY;o~nm$hd0s`=?hyVZp literal 0 HcmV?d00001 From dfa070bfa6accd32ae53035d4fa0a820e9b508ab Mon Sep 17 00:00:00 2001 From: Basil Khan Date: Wed, 15 Feb 2017 22:34:42 -0500 Subject: [PATCH 04/22] feat(Utilities): Add helper functions to upload file --- db.sqlite3 | Bin 40960 -> 47104 bytes media/documents/2017-02-16/MYFILE.csv | 20 ++++++ media/documents/2017-02-16/MYFILE_1SLuNV5.csv | 20 ++++++ media/documents/2017-02-16/MYFILE_54zRCY5.csv | 20 ++++++ .../templates/{list.html => upload.html} | 6 +- wave/myapp/urls.py | 4 +- wave/myapp/urls.pyc | Bin 348 -> 352 bytes wave/myapp/utils.py | 0 wave/myapp/utils.pyc | Bin 0 -> 163 bytes wave/myapp/views.py | 63 +++--------------- wave/myapp/views.pyc | Bin 2625 -> 1730 bytes wave/urls.py | 5 +- wave/urls.pyc | Bin 790 -> 740 bytes 13 files changed, 78 insertions(+), 60 deletions(-) create mode 100644 media/documents/2017-02-16/MYFILE.csv create mode 100644 media/documents/2017-02-16/MYFILE_1SLuNV5.csv create mode 100644 media/documents/2017-02-16/MYFILE_54zRCY5.csv rename wave/myapp/templates/{list.html => upload.html} (90%) create mode 100644 wave/myapp/utils.py create mode 100644 wave/myapp/utils.pyc diff --git a/db.sqlite3 b/db.sqlite3 index 4d0f207f681ea2f2da48e7fa33119f8697628bb5..a36eda9cb985f73b60200fbc59f518049feedd93 100644 GIT binary patch literal 47104 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 G7yf^6ljE}h delta 75 zcmZqpz|?SnX@WGXCIbV5#zX~sM$L^0OV|Zine!N!Uo!7u&SPHA+|Jy-u`!ByavpaY fqr^l - Wave SE Challenge + Wave Challenge -

Wave SE Challenge

+

Wave Challenge

{% if documents %} - \ No newline at end of file + diff --git a/wave/myapp/templates/components/sidebar.html b/wave/myapp/templates/components/sidebar.html index c48c894c3..88c471af2 100644 --- a/wave/myapp/templates/components/sidebar.html +++ b/wave/myapp/templates/components/sidebar.html @@ -1,12 +1,11 @@ {% load static %} - From ec57a93e4579ae80a19860b3c525c9c66add40b6 Mon Sep 17 00:00:00 2001 From: Lansa Date: Thu, 16 Feb 2017 22:40:42 -0500 Subject: [PATCH 13/22] feat(Upload): Upload button styles and datatables sort default --- wave/myapp/templates/upload.html | 90 ++++++++++++-------------------- 1 file changed, 32 insertions(+), 58 deletions(-) diff --git a/wave/myapp/templates/upload.html b/wave/myapp/templates/upload.html index 3f2769d58..8aff65051 100644 --- a/wave/myapp/templates/upload.html +++ b/wave/myapp/templates/upload.html @@ -1,59 +1,38 @@ -{% load static %} - {% include "components/head.html" %} - -
- - {% include "components/sidebar.html" %} - -
- - {% include "components/navbar.html" %} +{% load static %} {% include "components/head.html" %} + +
+ {% include "components/sidebar.html" %} +
+ {% include "components/navbar.html" %}
- -
-

CSV File Upload

-
- +
+

CSV File Upload

+
- -
-
- -
- {% csrf_token %} -
-
- - {{ form.docfile }} - {{ form.docfile.errors }} - {{ form.docfile.label_tag }} {{ form.docfile.help_text }} - - -
-
- - - UPLOAD - + {% csrf_token %} +
+
+ + {{ form.docfile }} + Change File + + + + + UPLOAD - - Remove - -
- + Remove +
- -
-
@@ -86,10 +65,9 @@

Wave CSV Merger

Actions - {% if documents %} - {% for document in documents %} + {% for document in documents %} {{ document.id }} {{ document.docfile.name }} @@ -101,12 +79,11 @@

Wave CSV Merger

delete - {% endfor %} + {% endfor %} {% else %} -

No documents have been uploaded

+

No documents have been uploaded

{% endif %} -
@@ -119,17 +96,15 @@

Wave CSV Merger

- - {% include "components/footer.html" %} -
+ {% include "components/footer.html" %}
- - - - {% include "components/scripts.html" %} - - From 0796263bf801500121db702b4c2bf44c545544da Mon Sep 17 00:00:00 2001 From: Lansa Date: Thu, 16 Feb 2017 22:58:52 -0500 Subject: [PATCH 14/22] refactor(Template): refactor html template and add font icons --- static/assets/css/material-dashboard.css | 3 +++ wave/myapp/templates/summary.html | 2 +- wave/myapp/templates/upload.html | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/static/assets/css/material-dashboard.css b/static/assets/css/material-dashboard.css index a4176628e..280e25f98 100644 --- a/static/assets/css/material-dashboard.css +++ b/static/assets/css/material-dashboard.css @@ -11574,3 +11574,6 @@ footer .btn { } } +.hide-file-bar{ + display: none; +} \ No newline at end of file diff --git a/wave/myapp/templates/summary.html b/wave/myapp/templates/summary.html index bc37b5eb4..7a066f7b5 100644 --- a/wave/myapp/templates/summary.html +++ b/wave/myapp/templates/summary.html @@ -32,7 +32,7 @@

File: {{ document.docfile.name }}

-

Expense Summary

+

Monthly Expenses Summary

Data uploaded on {{ document.created_time }}

diff --git a/wave/myapp/templates/upload.html b/wave/myapp/templates/upload.html index 8aff65051..ffef3ba38 100644 --- a/wave/myapp/templates/upload.html +++ b/wave/myapp/templates/upload.html @@ -20,8 +20,8 @@

CSV File Upload

- {{ form.docfile }} - Change File + Upload CSV File {{ form.docfile }} + Change File From 9ce266a9e58111c59f5e761eaeedd01560bc1e33 Mon Sep 17 00:00:00 2001 From: Lansa Date: Thu, 16 Feb 2017 23:15:12 -0500 Subject: [PATCH 15/22] feat(Timezone): Add timezone aware time (EST) --- wave/myapp/templates/upload.html | 2 +- wave/myapp/utils.py | 3 ++- wave/myapp/views.py | 11 +---------- wave/settings.py | 2 +- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/wave/myapp/templates/upload.html b/wave/myapp/templates/upload.html index ffef3ba38..cc7ad389a 100644 --- a/wave/myapp/templates/upload.html +++ b/wave/myapp/templates/upload.html @@ -104,7 +104,7 @@

Wave CSV Merger