--- /dev/null
+from invoice.models import Client, Invoice, InvoiceLine, VAT
+from django.contrib import admin
+
+admin.site.register(Client)
+admin.site.register(Invoice)
+admin.site.register(InvoiceLine)
+admin.site.register(VAT)
--- /dev/null
+from django.forms import ModelForm
+from invoice.models import Client, Invoice
+from django.views.generic.edit import ModelFormMixin
+
+class ClientForm(ModelFormMixin, ModelForm):
+ class Meta:
+ model = Client
+
+class InvoiceForm(ModelFormMixin, ModelForm):
+ class Meta:
+ model = Invoice
email = models.CharField(max_length=100)
address = models.TextField()
+ def __unicode__(self):
+ return '%s' % self.name
+
INVOICE_STATUS_CHOICES = (
('N', 'New'),
('S', 'Sent'),
decimal_places=2)
class Meta:
- verbose_name = _('tax')
- verbose_name_plural = _('taxes')
+ verbose_name = _('VAT level')
+ verbose_name_plural = _('VAT levels')
def __unicode__(self):
return '%s' % self.name
--- /dev/null
+from django.conf.urls import patterns, include, url
+import django.contrib.auth.views
+from invoice.views import UpdateClient, DeleteClient, CreateClient, DetailClient, \
+ CreateInvoice
+
+import invoice.views
+
+urlpatterns = patterns('invoice.views',
+ url(r'^$', 'index'),
+ url(r'^client/new$', CreateClient.as_view()),
+ url(r'^client/(?P<pk>\d+)$', DetailClient.as_view()),
+ url(r'^client/(?P<pk>\d+)/edit$', UpdateClient.as_view(), name='c_edit'),
+ url(r'^client/(?P<pk>\d+)/delete$', DeleteClient.as_view(), name='c_delete'),
+ url(r'^accounts/login/$', django.contrib.auth.views.login),
+ url(r'^invoice/new$', CreateInvoice.as_view(), name="invoice_new"),
+)
-# Create your views here.
+from django.shortcuts import render_to_response, get_object_or_404
+from django.contrib.auth.decorators import login_required, permission_required
+from django.http import HttpResponse
+from django.forms.models import inlineformset_factory
+from django.template import RequestContext
+from django.views.generic.create_update import get_model_and_form_class, apply_extra_context, redirect, update_object, lookup_object, delete_object
+from django.views.generic import UpdateView, DeleteView, CreateView, DetailView
+from django.utils.decorators import method_decorator
+
+from invoice.models import Client, Invoice
+from invoice.forms import ClientForm, InvoiceForm
+
+@login_required
+def index(request):
+ clients = Client.objects.all()
+ return render_to_response('invoice/index.html', {'clients': clients})
+
+class DetailClient(DetailView):
+ model = Client
+ @method_decorator(login_required)
+ def dispatch(self, *args, **kwargs):
+ return super(DetailView, self).dispatch(*args, **kwargs)
+
+class CreateClient(CreateView):
+ model = Client
+ form_class = ClientForm
+ success_url = '/'
+
+ @method_decorator(login_required)
+ def dispatch(self, *args, **kwargs):
+ return super(CreateClient, self).dispatch(*args, **kwargs)
+
+class UpdateClient(UpdateView):
+ model = Client
+ form_class = ClientForm
+ success_url = '/'
+
+ @method_decorator(login_required)
+ def dispatch(self, *args, **kwargs):
+ return super(UpdateClient, self).dispatch(*args, **kwargs)
+
+class DeleteClient(DeleteView):
+ model = Client
+ form_class = ClientForm
+ success_url = '/'
+
+ @method_decorator(login_required)
+ def dispatch(self, *args, **kwargs):
+ return super(DeleteClient, self).dispatch(*args, **kwargs)
+
+
+# ------------------- INVOICE ---------------
+class CreateInvoice(CreateView):
+ model = Invoice
+ form_class = InvoiceForm
+ success_url = '/'
+
+ @method_decorator(login_required)
+ def dispatch(self, *args, **kwargs):
+ return super(CreateInvoice, self).dispatch(*args, **kwargs)
+
# 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.abspath(os.path.join(os.path.dirname(__file__))) + "/../templates",
)
INSTALLED_APPS = (
from django.conf.urls import patterns, include, url
-# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
- # url(r'^$', 'peojumk.views.home', name='home'),
+ #url(r'^$', 'invoice.views.home', name='home'),
# url(r'^peojumk/', include('peojumk.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
+ url(r'^', include('invoice.urls', namespace='invoice')),
)
--- /dev/null
+{% load admin_static %}{% load url from future %}<!DOCTYPE html>
+<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
+<head>
+<title>{% block title %}{% endblock %}</title>
+<link rel="stylesheet" type="text/css" href="{% block stylesheet %}{% static "admin/css/base.css" %}{% endblock %}" />
+{% block extrastyle %}{% endblock %}
+<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="{% block stylesheet_ie %}{% static "admin/css/ie.css" %}{% endblock %}" /><![endif]-->
+{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% static "admin/css/rtl.css" %}{% endblock %}" />{% endif %}
+<script type="text/javascript">window.__admin_media_prefix__ = "{% filter escapejs %}{% static "admin/" %}{% endfilter %}";</script>
+{% block extrahead %}{% endblock %}
+{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE" />{% endblock %}
+</head>
+{% load i18n %}
+
+<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}">
+
+<!-- Container -->
+<div id="container">
+
+ {% if not is_popup %}
+ <!-- Header -->
+ <div id="header">
+ <div id="branding">
+ {% block branding %}{% endblock %}
+ </div>
+ {% if user.is_active and user.is_staff %}
+ <div id="user-tools">
+ {% trans 'Welcome,' %}
+ <strong>{% filter force_escape %}{% firstof user.first_name user.username %}{% endfilter %}</strong>.
+ {% block userlinks %}
+ {% url 'django-admindocs-docroot' as docsroot %}
+ {% if docsroot %}
+ <a href="{{ docsroot }}">{% trans 'Documentation' %}</a> /
+ {% endif %}
+ <a href="{% url 'admin:password_change' %}">{% trans 'Change password' %}</a> /
+ <a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a>
+ {% endblock %}
+ </div>
+ {% endif %}
+ {% block nav-global %}{% endblock %}
+ </div>
+ <!-- END Header -->
+ {% block breadcrumbs %}
+ <div class="breadcrumbs">
+ <a href="/">{% trans 'Home' %}</a>
+ {% if title %} › {{ title }}{% endif %}
+ </div>
+ {% endblock %}
+ {% endif %}
+
+ {% block messages %}
+ {% if messages %}
+ <ul class="messagelist">{% for message in messages %}
+ <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
+ {% endfor %}</ul>
+ {% endif %}
+ {% endblock messages %}
+
+ <!-- Content -->
+ <div id="content" class="{% block coltype %}colM{% endblock %}">
+ {% block pretitle %}{% endblock %}
+ {% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}
+ {% block content %}
+ {% block object-tools %}{% endblock %}
+ {{ content }}
+ {% endblock %}
+ {% block sidebar %}{% endblock %}
+ <br class="clear" />
+ </div>
+ <!-- END Content -->
+
+ {% block footer %}<div id="footer"></div>{% endblock %}
+</div>
+<!-- END Container -->
+
+</body>
+</html>
--- /dev/null
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}
+
+{% block branding %}
+<h1 id="site-name">{% trans 'Invoices' %}</h1>
+{% endblock %}
+
+{% block nav-global %}{% endblock %}
--- /dev/null
+{% extends "base_site.html" %}
+
+{% block content %}
+
+Are you sure you want to delete the client named {{client.name}} ?
+
+<form method="post">
+{% csrf_token %}
+
+<input type="submit" value="Delete {{client.name}}">
+</form>
+
+{% endblock %}
--- /dev/null
+{% extends "base_site.html" %}
+
+{% block content %}
+
+<ul>
+ <li>Client: {{client.name}}</li>
+ <li>Email: <a href="mailto:{{client.email}}">{{client.email}}</a></li>
+ <li>Address: <pre class="literal-block">{{client.address}}</pre></li>
+</ul>
+
+<a href="{% url invoice:c_edit client.id %}">Edit</a>
+<a href="{% url invoice:c_delete client.id %}">Delete</a>
+
+{% endblock %}
--- /dev/null
+{% extends "base_site.html" %}
+
+{% block content %}
+
+<form id="form" enctype="multipart/form-data" method="post">
+{% csrf_token %}
+<ul>
+ {{ form.as_ul}}
+</ul>
+<input type="submit">
+</form>
+{% endblock %}
--- /dev/null
+{% extends "base_site.html" %}
+
+{% block content %}
+
+<a href="{% url invoice:invoice_new %}">New invoice</a>
+
+<ul>
+{% if clients %}
+ {% for c in clients %}
+ <li><a href="/client/{{ c.id }}">{{ c.name }}</a></li>
+ {% endfor %}
+{% else %}
+ <p>No clients.</p>
+{% endif %}
+ <li><a href="/client/new">New client</a></li>
+</ul>
+
+{% endblock %}
--- /dev/null
+{% extends "base_site.html" %}
+
+{% block content %}
+
+<form id="form" enctype="multipart/form-data" method="post">
+{% csrf_token %}
+<ul>
+ {{ form.as_ul}}
+</ul>
+<input type="submit">
+</form>
+{% endblock %}
--- /dev/null
+{% extends "base_site.html" %}
+{% load i18n admin_static %}
+{% load url from future %}
+
+{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/login.css" %}" />{% endblock %}
+
+{% block bodyclass %}login{% endblock %}
+
+{% block nav-global %}{% endblock %}
+
+{% block content_title %}{% endblock %}
+
+{% block breadcrumbs %}{% endblock %}
+
+{% block content %}
+{% if form.errors and not form.non_field_errors and not form.this_is_the_login_form.errors %}
+<p class="errornote">
+{% blocktrans count counter=form.errors.items|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %}
+</p>
+{% endif %}
+
+{% if form.non_field_errors or form.this_is_the_login_form.errors %}
+{% for error in form.non_field_errors|add:form.this_is_the_login_form.errors %}
+<p class="errornote">
+ {{ error }}
+</p>
+{% endfor %}
+{% endif %}
+
+<div id="content-main">
+<form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
+ <div class="form-row">
+ {% if not form.this_is_the_login_form.errors %}{{ form.username.errors }}{% endif %}
+ <label for="id_username" class="required">{% trans 'Username:' %}</label> {{ form.username }}
+ </div>
+ <div class="form-row">
+ {% if not form.this_is_the_login_form.errors %}{{ form.password.errors }}{% endif %}
+ <label for="id_password" class="required">{% trans 'Password:' %}</label> {{ form.password }}
+ <input type="hidden" name="this_is_the_login_form" value="1" />
+ <input type="hidden" name="next" value="{{ next }}" />
+ </div>
+ {% url 'admin_password_reset' as password_reset_url %}
+ {% if password_reset_url %}
+ <div class="password-reset-link">
+ <a href="{{ password_reset_url }}">{% trans 'Forgotten your password or username?' %}</a>
+ </div>
+ {% endif %}
+ <div class="submit-row">
+ <label> </label><input type="submit" value="{% trans 'Log in' %}" />
+ </div>
+</form>
+
+<script type="text/javascript">
+document.getElementById('id_username').focus()
+</script>
+</div>
+{% endblock %}