Initial commit.
authorgniibe <gniibe@atom.fsij.org>
Thu, 30 Jul 2009 06:57:46 +0000 (15:57 +0900)
committergniibe <gniibe@atom.fsij.org>
Thu, 30 Jul 2009 06:57:46 +0000 (15:57 +0900)
65 files changed:
.hgignore [new file with mode: 0644]
TODO [new file with mode: 0644]
__init__.py [new file with mode: 0644]
accounting/__init__.py [new file with mode: 0644]
accounting/__setup__.py [new file with mode: 0644]
accounting/admin.py [new file with mode: 0644]
accounting/models.py [new file with mode: 0644]
accounting/urls.py [new file with mode: 0644]
accounting/views.py [new file with mode: 0644]
files/__init__.py [new file with mode: 0644]
files/models.py [new file with mode: 0644]
files/urls.py [new file with mode: 0644]
files/views.py [new file with mode: 0644]
locale/ja/LC_MESSAGES/django.po [new file with mode: 0644]
manage.py [new file with mode: 0755]
meeting_attendance/__init__.py [new file with mode: 0644]
meeting_attendance/admin.py [new file with mode: 0644]
meeting_attendance/models.py [new file with mode: 0644]
meeting_attendance/urls.py [new file with mode: 0644]
meeting_attendance/views.py [new file with mode: 0644]
membership/__init__.py [new file with mode: 0644]
membership/__setup__.py [new file with mode: 0644]
membership/admin.py [new file with mode: 0644]
membership/models.py [new file with mode: 0644]
membership/urls.py [new file with mode: 0644]
membership/views.py [new file with mode: 0644]
settings.py [new file with mode: 0644]
templates/accounting/account_list.html [new file with mode: 0644]
templates/accounting/bs_pl_cf.html [new file with mode: 0644]
templates/accounting/show_entry.html [new file with mode: 0644]
templates/accounting/show_entry_1.html [new file with mode: 0644]
templates/accounting/transaction.html [new file with mode: 0644]
templates/accounting/transaction_list.html [new file with mode: 0644]
templates/admin/base.html [new file with mode: 0644]
templates/admin/base_site.html [new file with mode: 0644]
templates/admin/index.html [new file with mode: 0644]
templates/meeting_attendance/attendance_list.html [new file with mode: 0644]
templates/meeting_attendance/meeting_detail.html [new file with mode: 0644]
templates/meeting_attendance/meeting_list.html [new file with mode: 0644]
templates/meeting_attendance/registration_list.html [new file with mode: 0644]
templates/membership/member_address.html [new file with mode: 0644]
templates/membership/member_address_old.html [new file with mode: 0644]
templates/membership/member_edit.html [new file with mode: 0644]
templates/membership/member_email.html [new file with mode: 0644]
templates/membership/member_index.html [new file with mode: 0644]
templates/membership/member_list.html [new file with mode: 0644]
templates/membership/member_list_top.html [new file with mode: 0644]
templates/membership/member_payment.html [new file with mode: 0644]
templates/membership/payment_list.html [new file with mode: 0644]
templates/membership/valid_member_list.html [new file with mode: 0644]
templates/registration/logged_out.html [new file with mode: 0644]
templates/registration/login.html [new file with mode: 0644]
templates/registration/password_change_done.html [new file with mode: 0644]
templates/registration/password_change_form.html [new file with mode: 0644]
templates/registration/password_reset_complete.html [new file with mode: 0644]
templates/registration/password_reset_confirm.html [new file with mode: 0644]
templates/registration/password_reset_done.html [new file with mode: 0644]
templates/registration/password_reset_email.html [new file with mode: 0644]
templates/registration/password_reset_form.html [new file with mode: 0644]
templates/top_page.html [new file with mode: 0644]
trac_placeholder/__init__.py [new file with mode: 0644]
trac_placeholder/models.py [new file with mode: 0644]
trac_placeholder/views.py [new file with mode: 0644]
urls.py [new file with mode: 0644]
views.py [new file with mode: 0644]

diff --git a/.hgignore b/.hgignore
new file mode 100644 (file)
index 0000000..532c2d4
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,6 @@
+syntax: glob
+*.db
+*.mo
+*.pyc
+*~
+attic
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..760071d
--- /dev/null
+++ b/TODO
@@ -0,0 +1,39 @@
+* old data for accounting
+* old data for members (historical)
+  * quit date
+* membership management
+* member user interface
+  * password change
+  * name change
+  * e-mail address
+  * data into LDAP
+\f
+* User Interface
+
+* Secretariat Interface
+  * List registration/result
+    * Content of registration_list
+  * Edit result
+  * Access control
+
+* Put users / members data into SQLite
+
+* Access control by LDAP
+
+* Let it run on Hikaru
+
+* membership management
+  * Corporatemember management
+  * Newly create a member
+    * generate a member ID
+  * payment list
+  * create member fee (yearly)
+  * connect payment to ledger entry
+
+* accounting
+  * transaction entry
+  * account entry
+  * transactions by ..., order by ...
+  * B/S
+  * P/L
+  * cash flow
diff --git a/__init__.py b/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/accounting/__init__.py b/accounting/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/accounting/__setup__.py b/accounting/__setup__.py
new file mode 100644 (file)
index 0000000..703667a
--- /dev/null
@@ -0,0 +1,68 @@
+# -*- coding: utf-8-*-
+from fsij.accounting.models import *
+a_eq = AccountType(name='資本', value=0)
+a_eq.save()
+a_as = AccountType(name='資産', value=1)
+a_as.save()
+a_li = AccountType(name='負債', value=2)
+a_li.save()
+a_in = AccountType(name='収益', value=3)
+a_in.save()
+a_ex = AccountType(name='費用', value=4)
+a_ex.save()
+b = Business(name='一般')
+b.save()
+a = Account(type=a_eq,name='元入金',is_cash=False)
+a.save()
+a = Account(type=a_li,name='預り金',is_cash=False)
+a.save()
+a = Account(type=a_li,name='短期借入金',is_cash=False)
+a.save()
+a = Account(type=a_li,name='買掛金',is_cash=False)
+a.save()
+a = Account(type=a_li,name='前受金',is_cash=False)
+a.save()
+a = Account(type=a_li,name='未払金',is_cash=False)
+a.save()
+a = Account(type=a_as,name='未収金',is_cash=False)
+a.save()
+a = Account(type=a_as,name='現金',is_cash=True)
+a.save()
+a = Account(type=a_as,name='商品',is_cash=False)
+a.save()
+a = Account(type=a_as,name='売掛金',is_cash=False)
+a.save()
+a = Account(type=a_as,name='預金',is_cash=True)
+a.save()
+a = Account(type=a_in,name='会費収入',is_cash=False)
+a.save()
+a = Account(type=a_in,name='寄付金収入',is_cash=False)
+a.save()
+a = Account(type=a_in,name='入会金',is_cash=False)
+a.save()
+a = Account(type=a_in,name='売上',is_cash=False)
+a.save()
+a = Account(type=a_in,name='雑収入',is_cash=False)
+a.save()
+a = Account(type=a_in,name='受取利息',is_cash=False)
+a.save()
+a = Account(type=a_ex,name='振込手数料',is_cash=False)
+a.save()
+a = Account(type=a_ex,name='支払報酬',is_cash=False)
+a.save()
+a = Account(type=a_ex,name='仕入',is_cash=False)
+a.save()
+a = Account(type=a_ex,name='消耗品費',is_cash=False)
+a.save()
+a = Account(type=a_ex,name='租税公課',is_cash=False)
+a.save()
+a = Account(type=a_ex,name='会議費',is_cash=False)
+a.save()
+a = Account(type=a_ex,name='通信費',is_cash=False)
+a.save()
+a = Account(type=a_ex,name='商品評価損',is_cash=False)
+a.save()
+a = Account(type=a_ex,name='旅費交通費',is_cash=False)
+a.save()
+a = Account(type=a_ex,name='雑費',is_cash=False)
+a.save()
diff --git a/accounting/admin.py b/accounting/admin.py
new file mode 100644 (file)
index 0000000..9f96320
--- /dev/null
@@ -0,0 +1,8 @@
+from django.contrib import admin
+from fsij.accounting.models import Business, AccountType, Account, Transaction, LedgerEntry
+
+admin.site.register(Business)
+admin.site.register(AccountType)
+admin.site.register(Account)
+admin.site.register(Transaction)
+admin.site.register(LedgerEntry)
diff --git a/accounting/models.py b/accounting/models.py
new file mode 100644 (file)
index 0000000..318f7f6
--- /dev/null
@@ -0,0 +1,242 @@
+# -*- coding: utf-8-*-
+from django.db import models
+import datetime
+#
+# Business: FSIJ has(had) three kinds of business:
+#           general, seminar, goods-selling
+#
+class Business(models.Model):
+    name = models.CharField(max_length=30)
+    def __unicode__(self):
+        return self.name
+
+# 0: Equity 
+# 1: Asset
+# 2: Liability
+# 3: Income
+# 4: Expense
+class AccountType(models.Model):
+    name = models.CharField(max_length=30)
+    value = models.IntegerField()
+    def __unicode__(self):
+        return self.name
+    def is_credit(self):
+        if self.value == 0 or self.value == 2 or self.value == 3:
+            return True
+        else:
+            return False
+
+# Account -- "Kanjo-Kamoku" in Japanese
+class Account(models.Model):
+    type = models.ForeignKey(AccountType)
+    name = models.CharField(max_length=30)
+    is_cash = models.BooleanField()
+    def __unicode__(self):
+        return self.name
+
+class Transaction(models.Model):
+    date = models.DateField()
+    business = models.ForeignKey(Business)
+    memo = models.CharField(max_length=50, blank=True)
+    memo_detail = models.CharField(max_length=100, blank=True)
+    class Meta:
+        permissions = (("can_manage", "Can manage accounting"),)
+    def __unicode__(self):
+        return self.business.__unicode__() + "/" + self.date.__str__()
+    n = 0
+    credit = None
+    debit = None
+    def num_line(self):
+        self.credit = self.ledgerentry_set.filter(is_credit=True)
+        self.debit = self.ledgerentry_set.filter(is_credit=False)
+        self.n = 0
+        return range(0,max(self.credit.count(), self.debit.count()))
+    def get_credit(self):
+        try:
+            return self.credit[self.n]
+        except:
+            return None
+    def get_debit(self):
+        try:
+            return self.debit[self.n]
+        except:
+            return None
+    def next(self):
+        self.n += 1
+        return "%d" % self.n
+    def credit_total(self):
+        ct = 0
+        for i in range(0,self.credit.count()):
+            ct += self.credit[i].amount
+        return ct
+    def debit_total(self):
+        dt = 0
+        for i in range(0,self.debit.count()):
+            dt += self.debit[i].amount
+        return dt
+
+class LedgerEntry(models.Model):
+    t = models.ForeignKey(Transaction)
+    is_credit = models.BooleanField() # Debit or Credit, True if Credit 
+    account = models.ForeignKey(Account)
+    amount  = models.IntegerField()
+    class Meta:
+        permissions = (("can_view_sheets", "Can view sheets"),)
+    def __unicode__(self):
+        return self.t.__unicode__() + "/" + self.account.name
+
+class FinancialYear(object):
+    date_beginning = None
+    date_ending = None
+
+    def __init__(self, year):
+        self.date_beginning = datetime.date(year, 6, 1)
+        self.date_ending = datetime.date(year+1, 5, 31)
+
+    def begin(self):
+        return self.date_beginning
+
+    def end(self):
+        return self.date_ending
+
+class GeneralLedgerEntry(object):
+    fy = None
+    gles = None
+    transactions_over_terms = None
+    def __init__(self, year):
+        self.fy = FinancialYear(year)
+        le_list = LedgerEntry.objects.filter(t__date__range=(self.fy.begin(),self.fy.end())).order_by('account')
+        ac_dict = {}
+        self.transactions_over_terms = set()
+        for le in le_list:
+            if le.account.name == "繰越":
+                self.transactions_over_terms.add(le.t)
+                continue
+            if le.account.type.is_credit():
+                is_total_credit = True
+            else:
+                is_total_credit = False
+            if (le.is_credit and is_total_credit) or ((not le.is_credit) and (not is_total_credit)):
+                total = le.amount
+            else:
+                total = -le.amount
+            try:
+                le.t.ledgerentry_set.get(account__is_cash=True)
+                if le.account.is_cash:
+                    cash_total = 0
+                else:
+                    cash_total = total
+            except:
+                cash_total = 0
+            try:
+                a = ac_dict[le.account.name]
+                a['cash_total'] = a['cash_total'] + cash_total
+                a['ledgerentries'].append((le.is_credit,le.amount,le.t))
+                a['total'] = a['total'] + total
+            except:
+                ac_dict[le.account.name] = {'name': le.account.name,
+                               'type': le.account.type,
+                               'is_cash': le.account.is_cash,
+                               'cash_total': cash_total, 
+                               'ledgerentries':
+                               [(le.is_credit,le.amount,le.t)],
+                               'total': total, }
+        self.gles = ac_dict.values()
+        self.gles.sort(cmp = lambda a,b: a['type'].value - b['type'].value)
+
+    def get_gles(self):
+        return self.gles
+
+    def get_pl_total(self):
+        pl = 0
+        for e in self.gles:
+            if e['type'].value == 3:
+                pl += e['total']
+            if e['type'].value == 4:
+                pl -= e['total']
+        return pl
+
+    def get_cash_total(self):
+        cash = 0
+        for e in self.gles:
+            if e['cash_total'] > 0:
+                if e['type'].is_credit():
+                    cash += e['cash_total']
+                else:
+                    cash -= e['cash_total']
+        return cash
+
+    def get_initial_value(self,account):
+        for t in self.transactions_over_terms:
+            if t.date != self.fy.begin():
+                continue
+            try:
+                le = t.ledgerentry_set.get(account=account)
+                return le
+            except:
+                continue
+        return None
+#
+# Transactions, example
+#
+# In 2007, a member send 14000 (by misunderstanding) by wire
+# transfer, but ask to use the remainder 4000 for next year.
+#
+# In 2008, the member payed 10000 (by misunderstanding again)
+# in cache, asking to use another 7000 as next year members fee.
+#
+# Advance Payment Received
+#
+# -----------------------------------------------------------
+#   Date             Debit                    Credit
+#             Account        Amount    Account         Amount
+# -----------------------------------------------------------
+# 2007-01-03  Deposit        14000     Admission         3000
+#                                      Fee2006           7000
+#                                      Advance Payment   4000
+#
+# 2008-05-04  Cache          10000     Fee2007           7000
+#                                      Advance Payment   3000
+#
+# 2008-06-01  Advance Payment 7000     Fee2008           7000
+# -----------------------------------------------------------
+#
+#
+#
+# -----------------------------------------------------------
+#   Date             Debit                    Credit
+#             Account        Amount    Account         Amount
+# -----------------------------------------------------------
+# 2007-06-03  Deposit          9750    Admission         3000
+#             Transfer fee      250    Fee2007           7000
+# -----------------------------------------------------------
+#
+# A member tried to send 10000 to FSIJ, and FSIJ received 9750
+# because bank took 250 for a fee of wire transfer.
+# FSIJ secretariat decided to treat this 250 as FSIJ's expense.
+#
+#
+# This could be handled by three transactions:
+#
+# -----------------------------------------------------------
+#   Date             Debit                    Credit
+#             Account        Amount    Account         Amount
+# -----------------------------------------------------------
+# 2007-06-03  Deposit          9750    Admission         3000
+#                                      Advance Payment   6750
+# -----------------------------------------------------------
+#
+# -----------------------------------------------------------
+#   Date             Debit                    Credit
+#             Account        Amount    Account         Amount
+# -----------------------------------------------------------
+# 2007-06-03  Transfer fee      250    Advance Payment    250
+# -----------------------------------------------------------
+#
+# -----------------------------------------------------------
+#   Date             Debit                    Credit
+#             Account        Amount    Account         Amount
+# -----------------------------------------------------------
+# 2007-06-03  Advance Payment  7000    Fee2007           7000
+# -----------------------------------------------------------
+#
diff --git a/accounting/urls.py b/accounting/urls.py
new file mode 100644 (file)
index 0000000..c9a6bd3
--- /dev/null
@@ -0,0 +1,18 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+#    (r'^$', 'fsij.accounting.views.index'),
+#    (r'^(?P<year>\d+)/$', 'fsij.accounting.views.index'),
+    (r'^(?P<year>\d+)/transaction/$', 'fsij.accounting.views.transaction_list'),
+    # soukanjoumotocho : general ledger entries
+    (r'^(?P<year>\d+)/gles/$', 'fsij.accounting.views.account_list'),
+    (r'^(?P<year>\d+)/bs_pl_cf/$', 'fsij.accounting.views.bs_pl_cf'),
+    #
+    (r'^transaction/$', 'fsij.accounting.views.transaction_list'),
+    (r'^transaction/new/$', 'fsij.accounting.views.transaction_new'),
+    (r'^transaction/(?P<id>\d+)/$', 'fsij.accounting.views.transaction'),
+    (r'^transaction/(?P<id>\d+)/delete/$', 'fsij.accounting.views.transaction_delete'),
+#    (r'^transaction/(?P<id>\d+)/pdf/$', 'fsij.accounting.views.transaction_pdf'),
+#    (r'^(?P<object_id>\d+)/$', 'fsij.accounting.views.detail'),
+#    (r'^(?P<object_id>\d+)/register/$', 'fsij.accounting.views.register'),
+)
diff --git a/accounting/views.py b/accounting/views.py
new file mode 100644 (file)
index 0000000..adb0d74
--- /dev/null
@@ -0,0 +1,106 @@
+# -*- coding: utf-8-*-
+from django.shortcuts import render_to_response, get_object_or_404
+from django.contrib.auth.decorators import login_required, user_passes_test
+from django.http import HttpResponse, HttpResponseRedirect
+from fsij.accounting.models import Transaction, Account, Business, LedgerEntry, FinancialYear, GeneralLedgerEntry
+from fsij.settings import LOGIN_URL
+import datetime, time
+
+@user_passes_test(lambda u: u.has_perm('accounting.can_manage'), LOGIN_URL)
+def transaction(request,id):
+    t = Transaction.objects.get(pk=id)
+    return render_to_response('accounting/transaction.html',
+                              {'t': t,
+                               })
+
+@user_passes_test(lambda u: u.has_perm('accounting.can_manage'), LOGIN_URL)
+def transaction_new(request):
+    date = datetime.date(*time.strptime(request.POST['date'], '%Y-%m-%d')[:3])
+    business = Business.objects.get(pk=request.POST['business'])
+    memo = request.POST['memo']
+    memo_detail = request.POST['memo_detail']
+    t = Transaction(date=date, business=business, memo=memo, memo_detail=memo_detail)
+    t.save()
+    d_account = Account.objects.get(pk=request.POST['debit'])
+    d_amount  = request.POST['debit_amount']
+    l = LedgerEntry(t=t, is_credit=False, account=d_account, amount=d_amount)
+    l.save()
+    c_account = Account.objects.get(pk=request.POST['credit'])
+    c_amount = request.POST['credit_amount']
+    l = LedgerEntry(t=t, is_credit=True, account=c_account, amount=c_amount)
+    l.save()
+    if request.POST['debit2']:
+        d_account = Account.objects.get(pk=request.POST['debit2'])
+        d_amount  = request.POST['debit_amount2']
+        l = LedgerEntry(t=t, is_credit=False, account=d_account, amount=d_amount)
+        l.save()
+    if request.POST['credit2']:
+        c_account = Account.objects.get(pk=request.POST['credit2'])
+        c_amount = request.POST['credit_amount2']
+        l = LedgerEntry(t=t, is_credit=True, account=c_account, amount=c_amount)
+        l.save()
+    if request.POST['debit3']:
+        d_account = Account.objects.get(pk=request.POST['debit3'])
+        d_amount  = request.POST['debit_amount3']
+        l = LedgerEntry(t=t, is_credit=False, account=d_account, amount=d_amount)
+        l.save()
+    if request.POST['credit3']:
+        c_account = Account.objects.get(pk=request.POST['credit3'])
+        c_amount = request.POST['credit_amount3']
+        l = LedgerEntry(t=t, is_credit=True, account=c_account, amount=c_amount)
+        l.save()
+    if request.POST['debit4']:
+        d_account = Account.objects.get(pk=request.POST['debit4'])
+        d_amount  = request.POST['debit_amount4']
+        l = LedgerEntry(t=t, is_credit=False, account=d_account, amount=d_amount)
+        l.save()
+    if request.POST['credit4']:
+        c_account = Account.objects.get(pk=request.POST['credit4'])
+        c_amount = request.POST['credit_amount4']
+        l = LedgerEntry(t=t, is_credit=True, account=c_account, amount=c_amount)
+        l.save()
+    return HttpResponseRedirect(request.POST['original_path'])
+
+@user_passes_test(lambda u: u.has_perm('accounting.can_manage'), LOGIN_URL)
+def transaction_delete(request,id):
+    t = Transaction.objects.get(pk=id)
+    t.delete()
+    return HttpResponseRedirect(request.POST['original_path'])
+
+
+@user_passes_test(lambda u: u.has_perm('accounting.can_manage'), LOGIN_URL)
+def transaction_list(request,year=None):
+    if year:
+        fy = FinancialYear(int(year))
+        tr_list = Transaction.objects.filter(date__range=(fy.begin(),fy.end())).order_by('date')
+    else:
+        tr_list = Transaction.objects.all().order_by('date')
+    return render_to_response('accounting/transaction_list.html',
+                              {'year' : year,
+                               'tr_list': tr_list,
+                               'b_list': Business.objects.all(),
+                               'a_list': Account.objects.all(),
+                               'original_path': request.path,
+                               })
+
+@user_passes_test(lambda u: u.has_perm('accounting.can_manage'), LOGIN_URL)
+def account_list(request,year):
+    gles = GeneralLedgerEntry(int(year))
+    return render_to_response('accounting/account_list.html',
+                              {'year' : year,
+                               'ac_list': gles.get_gles(),
+                               })
+
+@user_passes_test(lambda u: u.has_perm('accounting.can_view_sheets'), LOGIN_URL)
+def bs_pl_cf(request,year):
+    gles = GeneralLedgerEntry(int(year))
+    cash_accounts = Account.objects.filter(is_cash=True)
+    cash_initial_list = map(lambda x: gles.get_initial_value(x), cash_accounts)
+    return render_to_response('accounting/bs_pl_cf.html',
+                              {'year' : year,
+                               'ac_list': gles.get_gles(),
+                               'fy': gles.fy,
+                               'pl_total': gles.get_pl_total(),
+                               'cash_total': gles.get_cash_total(),
+                               'cash_initial_list': cash_initial_list,
+                               })
diff --git a/files/__init__.py b/files/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/files/models.py b/files/models.py
new file mode 100644 (file)
index 0000000..d171b09
--- /dev/null
@@ -0,0 +1,6 @@
+from django.db import models
+
+class File(models.Model):
+    file = models.FileField(upload_to='/home/fsij/django/files/')
+    class Meta:
+        permissions = (("can_access_files", "Can access files"),)
diff --git a/files/urls.py b/files/urls.py
new file mode 100644 (file)
index 0000000..b2c7324
--- /dev/null
@@ -0,0 +1,5 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+    (r'^(?P<path>.*)$', 'fsij.files.views.file_access'),
+)
diff --git a/files/views.py b/files/views.py
new file mode 100644 (file)
index 0000000..9c77fbd
--- /dev/null
@@ -0,0 +1,7 @@
+from django.views.static import serve
+from fsij.settings import LOGIN_URL
+from django.contrib.auth.decorators import login_required, user_passes_test
+
+@user_passes_test(lambda u: u.has_perm('files.can_access_files'), LOGIN_URL)
+def file_access(request,path):
+    return serve(request, path, document_root='/home/fsij/django/files/', show_indexes=True)
diff --git a/locale/ja/LC_MESSAGES/django.po b/locale/ja/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..87c0e0c
--- /dev/null
@@ -0,0 +1,104 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-05-01 16:51+0900\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: templates/admin/base_site.html:4
+msgid "Django site admin"
+msgstr ""
+
+#: templates/admin/base_site.html:7
+msgid "Django administration"
+msgstr ""
+
+#: templates/admin/index.html:18
+#, python-format
+msgid "Models available in the %(name)s application."
+msgstr ""
+
+#: templates/admin/index.html:19
+#, python-format
+msgid "%(name)s"
+msgstr ""
+
+#: templates/admin/index.html:29
+msgid "Add"
+msgstr ""
+
+#: templates/admin/index.html:35
+msgid "Change"
+msgstr ""
+
+#: templates/admin/index.html:45
+msgid "You don't have permission to edit anything."
+msgstr ""
+
+#: templates/admin/index.html:53
+msgid "Recent Actions"
+msgstr ""
+
+#: templates/admin/index.html:54
+msgid "My Actions"
+msgstr ""
+
+#: templates/admin/index.html:58
+msgid "None available"
+msgstr ""
+
+#: templates/meeting_attendance/meeting_detail.html:8
+msgid "Date"
+msgstr "日時"
+
+#: templates/meeting_attendance/meeting_detail.html:9
+msgid "Place"
+msgstr "場所"
+
+#: templates/meeting_attendance/meeting_detail.html:10
+msgid "Agenda"
+msgstr "議題"
+
+#: templates/meeting_attendance/meeting_detail.html:18
+#, python-format
+msgid "Registered on %(date)s."
+msgstr "%(date)sに登録されました。"
+
+#: templates/meeting_attendance/meeting_detail.html:20
+msgid "Not registered yet."
+msgstr "まだ登録がありません。"
+
+#: templates/meeting_attendance/meeting_detail.html:30
+msgid "Register"
+msgstr "登録"
+
+#: templates/meeting_attendance/meeting_detail.html:35
+msgid "logout"
+msgstr "ログアウト"
+
+#: templates/meeting_attendance/meeting_detail.html:37
+msgid "Please login and register for the meeting"
+msgstr "ログインして会議の出欠を登録してください"
+
+#: templates/meeting_attendance/meeting_detail.html:50
+msgid "login"
+msgstr "ログイン"
+
+#: templates/meeting_attendance/meeting_list.html:2
+msgid "Meetings"
+msgstr "会議"
+
+#: templates/meeting_attendance/meeting_list.html:10
+msgid "No meetings are available."
+msgstr "会議がありません。"
diff --git a/manage.py b/manage.py
new file mode 100755 (executable)
index 0000000..bcdd55e
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,11 @@
+#!/usr/bin/python
+from django.core.management import execute_manager
+try:
+    import settings # Assumed to be in the same directory.
+except ImportError:
+    import sys
+    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+    sys.exit(1)
+
+if __name__ == "__main__":
+    execute_manager(settings)
diff --git a/meeting_attendance/__init__.py b/meeting_attendance/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/meeting_attendance/admin.py b/meeting_attendance/admin.py
new file mode 100644 (file)
index 0000000..7ac2762
--- /dev/null
@@ -0,0 +1,34 @@
+from fsij.meeting_attendance.models import *
+from django.contrib import admin
+
+class ChoiceInline(admin.TabularInline):
+    model = Attendance
+    extra = 3
+
+class MeetingAdmin(admin.ModelAdmin):
+    list_display = ('name', 'date_time')
+    list_filter = ['pub_date']
+    search_fields = ['name']
+    date_hierarchy = 'pub_date'
+    fieldsets = [
+        (None,               {'fields': ['name']}),
+        (None,               {'fields': ['place']}),
+        ('Publised Date', {'fields': ['pub_date'] }),
+        ('Date & Time Information', {'fields': ['date_time']}),
+        ('Agenda', {'fields': ['agenda']}),
+    ]
+    inlines = [ChoiceInline]
+
+class RegistrationAdmin(admin.ModelAdmin):
+    list_display = ( 'meeting', 'member', 'submit_date', 'choice')
+    list_filter =  [ 'meeting', 'submit_date' ]
+    fieldsets = [ (None, {'fields':['submit_date']}), (None, {'fields':['choice']}), (None, {'fields':['member']}), (None, {'fields':['meeting']}) ]
+
+class ResultAdmin(admin.ModelAdmin):
+    list_display = [ 'meeting', 'member' ]
+    list_filter = [ 'meeting' ]
+    fields = [ 'meeting', 'member', 'attended', 'registration' ]
+
+admin.site.register(Meeting, MeetingAdmin)
+admin.site.register(Registration, RegistrationAdmin)
+admin.site.register(Result, ResultAdmin)
diff --git a/meeting_attendance/models.py b/meeting_attendance/models.py
new file mode 100644 (file)
index 0000000..93448df
--- /dev/null
@@ -0,0 +1,40 @@
+from django.db import models
+import datetime
+from django.contrib.auth.models import User
+from fsij.membership.models import Member
+
+class Meeting(models.Model):
+    name = models.CharField(max_length=80)
+    date_time = models.DateTimeField('meeting date&time')
+    place = models.CharField(max_length=40)
+    pub_date = models.DateField('date published')
+    agenda = models.TextField()
+    def __unicode__(self):
+        return self.name
+
+class Attendance(models.Model):
+    meeting = models.ForeignKey(Meeting)
+    choice = models.CharField(max_length=200)
+    def __unicode__(self):
+        return self.choice
+
+class Registration(models.Model):
+    member = models.ForeignKey(Member)
+    choice = models.ForeignKey(Attendance)
+    meeting = models.ForeignKey(Meeting)
+    submit_date = models.DateField('date submitted')
+    class Meta:
+        permissions = (("can_list_registration", "Can list all registrations"),)
+    def __unicode__(self):
+        return self.member.__unicode__()
+
+class Result(models.Model):
+    member = models.ForeignKey(Member)
+    meeting = models.ForeignKey(Meeting)
+    registration = models.ForeignKey(Registration,blank=True,null=True)
+    attended = models.BooleanField()
+    class Meta:
+        permissions = (("can_list_result", "Can list all results"),
+                       ("can_change_results", "Can change all results"),)
+    def __unicode__(self):
+        return self.member.__unicode__()
diff --git a/meeting_attendance/urls.py b/meeting_attendance/urls.py
new file mode 100644 (file)
index 0000000..7851d81
--- /dev/null
@@ -0,0 +1,15 @@
+from django.conf.urls.defaults import *
+from fsij.meeting_attendance.models import Meeting
+
+info_dict = {
+    'queryset': Meeting.objects.all(),
+}
+
+urlpatterns = patterns('',
+    (r'^$', 'django.views.generic.list_detail.object_list', info_dict),
+    (r'^(?P<object_id>\d+)/$', 'fsij.meeting_attendance.views.detail'),
+    (r'^(?P<object_id>\d+)/register/$', 'fsij.meeting_attendance.views.register'),
+    (r'^(?P<object_id>\d+)/registrations/$', 'fsij.meeting_attendance.views.registration_list'),
+    (r'^(?P<object_id>\d+)/attendances/$', 'fsij.meeting_attendance.views.attendance_list'),
+    (r'^(?P<object_id>\d+)/attendance_submit/$', 'fsij.meeting_attendance.views.attendance_submit'),
+)
diff --git a/meeting_attendance/views.py b/meeting_attendance/views.py
new file mode 100644 (file)
index 0000000..ebb1ad6
--- /dev/null
@@ -0,0 +1,103 @@
+from django.shortcuts import render_to_response, get_object_or_404
+from fsij.meeting_attendance.models import Meeting, Attendance, Registration, Result
+from fsij.membership.models import Member
+from fsij.settings import LOGIN_URL
+from django.contrib.auth.forms import AuthenticationForm
+from django.contrib.auth.decorators import login_required, user_passes_test
+from django.http import HttpResponseRedirect
+from django.core.urlresolvers import reverse
+import datetime
+
+def detail(request, object_id):
+    m = get_object_or_404(Meeting, pk=object_id)
+    finished = (m.date_time < datetime.datetime.now())
+    if request.user.is_authenticated():
+        member = request.user.get_profile()
+    else:
+        member = None
+    r = None
+    try:
+        if (member):
+            r = m.registration_set.get(member=member)
+    except (KeyError, Registration.DoesNotExist):
+        pass
+    result = None
+    if (finished):
+        try:
+            if (member):
+                result = m.result_set.get(member=member)
+        except (KeyError, Result.DoesNotExist):
+            pass
+    request.session.set_test_cookie()
+    return render_to_response('meeting_attendance/meeting_detail.html',
+                              {'object': m,
+                               'form': AuthenticationForm(request),
+                               'next' : request.path,
+                               'user' : request.user,
+                               'meeting_finished' : finished,
+                               'attended' : result,
+                               'registration' : r })
+
+@login_required
+def register(request, object_id):
+    m = get_object_or_404(Meeting, pk=object_id)
+    try:
+        r = m.registration_set.get(member=request.user.get_profile())
+    except (KeyError, Registration.DoesNotExist):
+        c = m.attendance_set.get(pk=request.POST['choice'])
+        r = Registration(member=request.user.get_profile(), choice=c, meeting=m,
+                         submit_date=datetime.date.today())
+        r.save()
+    else:
+        try:
+            r.choice = m.attendance_set.get(pk=request.POST['choice'])
+        except (KeyError, Attendance.DoesNotExist):
+            r.delete()
+        else:
+            r.submit_date = datetime.date.today()
+            r.save()
+    return HttpResponseRedirect(reverse('fsij.meeting_attendance.views.detail', args=(m.id,)))
+
+# @permission_required('meeting_attendance.can_list_registration')
+@user_passes_test(lambda u: u.has_perm('meeting_attendance.can_list_registration'), LOGIN_URL)
+def registration_list(request, object_id):
+    m = get_object_or_404(Meeting, pk=object_id)
+    l = m.registration_set.all()
+    return render_to_response('meeting_attendance/registration_list.html',
+                              {'object': m,
+                               'list' : l,
+                               })
+
+# @permission_required('meeting_attendance.can_list_result')
+@user_passes_test(lambda u: u.has_perm('meeting_attendance.can_list_result'), LOGIN_URL)
+def attendance_list(request, object_id):
+    m = get_object_or_404(Meeting, pk=object_id)
+    l = m.result_set.all()
+    all_members = Member.objects.all()
+    return render_to_response('meeting_attendance/attendance_list.html',
+                              {'object': m,
+                               'list' : l,
+                               'members' : all_members,
+                               })
+
+# @permission_required('meeting_attendance.can_change_result')
+@user_passes_test(lambda u: u.has_perm('meeting_attendance.can_change_results'), LOGIN_URL)
+def attendance_submit(request, object_id):
+    m = get_object_or_404(Meeting, pk=object_id)
+    member = Member.objects.get(member_id=request.POST['member_id'])
+    attendance = (request.POST['attendance'] == "True")
+    try:
+        reg = m.registration_set.get(member=member)
+    except (KeyError, Registration.DoesNotExist):
+        reg = None
+    try:
+        r = m.result_set.get(member=member)
+    except (KeyError, Result.DoesNotExist):
+        r = Result(member=member, meeting=m,
+                   registration=reg,attended=attendance)
+        r.save()
+    else:
+        r.attended=attendance
+        r.registration=reg
+        r.save()
+    return HttpResponseRedirect(reverse('fsij.meeting_attendance.views.attendance_list', args=(m.id,)))
diff --git a/membership/__init__.py b/membership/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/membership/__setup__.py b/membership/__setup__.py
new file mode 100644 (file)
index 0000000..fbd18be
--- /dev/null
@@ -0,0 +1,11 @@
+# -*- coding: utf-8-*-
+from fsij.membership.models import MemberType
+a1 = MemberType(name='正会員')
+a1.save()
+a2 = MemberType(name='学生会員')
+a2.save()
+a3 = MemberType(name='賛助会員')
+a3.save()
+print "id=%d\n" % a1.id
+print "id=%d\n" % a2.id
+print "id=%d\n" % a3.id
diff --git a/membership/admin.py b/membership/admin.py
new file mode 100644 (file)
index 0000000..0d969a0
--- /dev/null
@@ -0,0 +1,9 @@
+from django.contrib import admin
+from fsij.membership.models import Member, CorporateMember, MemberType, MemberAddress, MemberPayment, MemberFee
+
+admin.site.register(MemberType)
+admin.site.register(Member)
+admin.site.register(CorporateMember)
+admin.site.register(MemberAddress)
+admin.site.register(MemberPayment)
+admin.site.register(MemberFee)
diff --git a/membership/models.py b/membership/models.py
new file mode 100644 (file)
index 0000000..9745a4b
--- /dev/null
@@ -0,0 +1,98 @@
+from django.db import models
+from django.contrib.auth.models import User
+from fsij.accounting.models import LedgerEntry
+
+# member_type
+# 1: member
+# 2: student member
+# 3: associate member (corporate member)
+class MemberType(models.Model):
+    name = models.CharField(max_length=10)
+    def __unicode__(self):
+        return self.name
+
+class Member(models.Model):
+    user = models.ForeignKey(User, unique=True, blank=True, null=True)
+    member_id = models.CharField(max_length=10)
+    member_type = models.ForeignKey(MemberType)
+    name_in_alphabet = models.CharField(max_length=50, blank=True)
+    date_join = models.DateField('date joined', blank=True, null=True)
+    date_quit = models.DateField('date quit', blank=True, null=True)
+    advance_payment = models.IntegerField()
+    def __unicode__(self):
+        return self.member_id + "/" + self.name()
+    class Meta:
+        permissions = (("can_manage", "Can manage members"),)
+    def name(self):
+        if self.member_type.id == 3:
+            try:
+                corp = self.corporatemember
+            except (Corporatemember.DoesNotExist):
+                corp = None
+            if corp:
+                return corp.corporate_name
+        elif self.user:
+            return self.user.last_name + " " + self.user.first_name
+        return self.name_in_alphabet
+
+class CorporateMember(models.Model):
+    member = models.OneToOneField(Member)
+    corporate_name = models.CharField(max_length=50)
+    contact_person = models.CharField(max_length=50)
+    contribution = models.IntegerField() # Kuchi-Suu in Japanese
+    def __unicode__(self):
+        return self.corporate_name
+
+class MemberAddress(models.Model):
+    member = models.ForeignKey(Member, unique=True)
+    contact_is_home = models.BooleanField()
+    zip_code = models.CharField(max_length=12)
+    address_line1 = models.CharField(max_length=30)
+    address_line2 = models.CharField(max_length=30, blank=True)
+    address_line3 = models.CharField(max_length=30, blank=True)
+    affiliation = models.CharField(max_length=80, blank=True)
+    date_updated = models.DateField()
+    def __unicode__(self):
+        return self.zip_code
+
+# MemberFee -- Object which stands for member's fee
+# Instance example: admission_fee, 2002 member's fee, ...
+# Secretariat creates one for each year
+class MemberFee(models.Model):
+    year = models.IntegerField()
+    def __unicode__(self):
+        if self.year == 9999:
+            return "Admission"
+        else:
+            return "%04d" % self.year
+
+class MemberPayment(models.Model):
+    member = models.ForeignKey(Member)
+    date = models.DateField()
+    fee = models.ForeignKey(MemberFee)
+    # member type as of payment time
+    member_type = models.ForeignKey(MemberType)
+    # contribution as of payment time, valid if member_type.id == 3
+    contribution = models.IntegerField() # Kuchi-Suu in Japanese
+    t_i = models.ForeignKey(LedgerEntry, unique=True, blank=True, null=True)
+    def __unicode__(self):
+        return self.member.__unicode__() + "/" + self.fee.__unicode__()
+
+def get_valid_member(year):
+    list_2 = MemberPayment.objects.filter(date__year = (year - 2)).order_by('member').values('member').distinct()
+    list_1 = MemberPayment.objects.filter(date__year = (year - 1)).order_by('member').values('member').distinct()
+    list_0 = MemberPayment.objects.filter(date__year = year).order_by('member').values('member').distinct()
+    members = []
+    for m in list_0:
+        members.append(m['member'])
+    for m in list_1:
+        if not m['member'] in members:
+            members.append(m['member'])
+    for m in list_2:
+        if not m['member'] in members:
+            members.append(m['member'])
+    member_list = []
+    for m in Member.objects.filter(id__in=members):
+        if (not m.date_quit) or m.date_quit.year >= year:
+            member_list.append(m)
+    return member_list
diff --git a/membership/urls.py b/membership/urls.py
new file mode 100644 (file)
index 0000000..17e900c
--- /dev/null
@@ -0,0 +1,30 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+# Views by Individual
+    (r'^$', 'fsij.membership.views.index'),
+    (r'^email/$', 'fsij.membership.views.email'),
+    (r'^email/register/$', 'fsij.membership.views.register_email'),
+    (r'^address/$', 'fsij.membership.views.address'),
+    (r'^address/register/$', 'fsij.membership.views.register_address'),
+    (r'^payment/$', 'fsij.membership.views.payment'),
+# Views by Secretariat (index)
+    (r'^list_top/$', 'fsij.membership.views.member_list_top'),
+    (r'^list/$', 'fsij.membership.views.member_list'),
+    (r'^payments/$', 'fsij.membership.views.payment_list'),
+# Views by Secretariat
+    (r'^valid_members/(?P<year>\d+)/$', 'fsij.membership.views.valid_member_list'),
+###XXX
+#    (r'^memberfee/$', 'fsij.membership.views.memberfee_list'),
+# Views by Secretariat (item)
+    (r'^(?P<member_id>\w+)/email/$', 'fsij.membership.views.manage_member_email'),
+    (r'^(?P<member_id>\w+)/email/register/$', 'fsij.membership.views.manage_register_member_email'),
+    (r'^(?P<member_id>\w+)/address/$', 'fsij.membership.views.manage_member_address'),
+    (r'^(?P<member_id>\w+)/address/register/$', 'fsij.membership.views.manage_register_member_address'),
+    (r'^(?P<member_id>\w+)/payment/$', 'fsij.membership.views.manage_member_payment'),
+    (r'^(?P<member_id>\w+)/payment/add/$', 'fsij.membership.views.manage_add_member_payment'),
+    (r'^(?P<member_id>\w+)/payment/delete/(?P<payment_id>\d+)/$', 'fsij.membership.views.manage_delete_member_payment'),
+#
+    (r'^(?P<member_id>\w+)/(?P<new>(new/)?)$', 'fsij.membership.views.manage_member'),
+    (r'^(?P<member_id>\w+)/register/$', 'fsij.membership.views.manage_register_member'),
+)
diff --git a/membership/views.py b/membership/views.py
new file mode 100644 (file)
index 0000000..d9afb4a
--- /dev/null
@@ -0,0 +1,326 @@
+from django.shortcuts import render_to_response, get_object_or_404
+from django.contrib.auth.decorators import login_required, user_passes_test
+from fsij.membership.models import *
+from django.http import HttpResponseRedirect
+from django.core.urlresolvers import reverse
+from fsij.settings import LOGIN_URL
+import datetime, time, re
+
+def member_index(request, member):
+    return render_to_response('membership/member_index.html',
+                              {'member': member,
+                               })
+
+def member_email(request, member, manage=False):
+    errors = None
+    try:
+        email = request.session['member_email_data']
+        del request.session['member_email_data']
+        errors = addr['errors']
+    except (KeyError):
+        email = member.user.email
+    try: referrer = request.META['HTTP_REFERER']
+    except: referrer = None
+    if referrer:
+       parent_is_list = (not re.match(".*/list/$", referrer))
+    else: parent_is_list = None
+    return render_to_response('membership/member_email.html',
+                              {'member': member,
+                               'email': email,
+                               'errors': errors,
+                               'original_path': request.path,
+                               'reload_parent': parent_is_list and manage,
+                               })
+
+def register_member_email(request, member):
+    email = request.POST['email']
+    errors = []
+    if not email:
+        errors.append('email')
+    if errors:
+        request.session['member_email_data'] = {
+            'email': email,
+            'errors': errors,}
+        return HttpResponseRedirect(request.POST['original_path'])
+    member.user.email = email
+    member.user.save()
+    return HttpResponseRedirect(request.POST['original_path'])
+
+def member_address(request, member, manage=False):
+    errors = None
+    try:
+        addr = request.session['member_address_data']
+        del request.session['member_address_data']
+        errors = addr['errors']
+    except (KeyError):
+        try:
+            addr = MemberAddress.objects.get(member=member)
+        except (MemberAddress.DoesNotExist):
+            addr = None
+    try: referrer = request.META['HTTP_REFERER']
+    except: referrer = None
+    if referrer:
+       parent_is_list = (not re.match(".*/list/$", referrer))
+    else: parent_is_list = None
+    return render_to_response('membership/member_address.html',
+                              {'member': member,
+                               'addr': addr,
+                               'errors': errors,
+                               'original_path': request.path,
+                               'reload_parent': parent_is_list and manage,
+                               })
+
+def register_member_address(request, member):
+    try: request.POST['contact_is_home']
+    except: contact_is_home = False
+    else:   contact_is_home = True
+    zip_code = request.POST['zip_code']
+    address_line1 = request.POST['address_line1']
+    address_line2 = request.POST['address_line2']
+    address_line3 = request.POST['address_line3']
+    affiliation = request.POST['affiliation']
+    errors = []
+    if not contact_is_home and not affiliation:
+        errors.append('affiliation')
+    if not zip_code:
+        errors.append('zip_code')
+    if not address_line1:
+        errors.append('address_line1')
+    if errors:
+        request.session['member_address_data'] = {
+            'contact_is_home': contact_is_home,
+            'zip_code': zip_code,
+            'address_line1': address_line1,
+            'address_line2': address_line2,
+            'address_line3': address_line3,
+            'affiliation': affiliation,
+            'errors': errors,}
+        return HttpResponseRedirect(request.POST['original_path'])
+    date_updated = datetime.date.today()
+    try:
+        addr = MemberAddress.objects.get(member=member)
+        addr.contact_is_home = contact_is_home
+        addr.zip_code = zip_code
+        addr.address_line1 = address_line1
+        addr.address_line2 = address_line2
+        addr.address_line3 = address_line3
+        addr.affiliation = affiliation
+        addr.date_updated = date_updated
+    except (MemberAddress.DoesNotExist):
+        addr = MemberAddress(member = member,
+                             contact_is_home = contact_is_home,
+                             zip_code = zip_code,
+                             address_line1 = address_line1,
+                             address_line2 = address_line2,
+                             address_line3 = address_line3,
+                             affiliation = affiliation,
+                             date_updated = date_updated)
+    addr.save()
+    return HttpResponseRedirect(request.POST['original_path'])
+
+def member_payment(request, member, manage=False):
+    try:
+        payments = member.memberpayment_set.order_by('-fee', '-date')
+    except (MemberPayment.DoesNotExist):
+        payments = None
+    if manage:
+        fee_list = MemberFee.objects.filter(year__gte = (member.date_join.year - 1))
+        if member.member_type.id == 3:
+            fee_list = fee_list.exclude(year = 9999)
+        fee_list_in_payments = map(lambda (p): p.fee, member.memberpayment_set.all())
+        fee_list = filter(lambda (f): not f in fee_list_in_payments, fee_list)
+    else:
+        fee_list = None
+    member_type_list = MemberType.objects.all().exclude(id=3)
+    try: referrer = request.META['HTTP_REFERER']
+    except: referrer = None
+    if referrer:
+       parent_is_list = (not re.match(".*/list/$", referrer))
+    else: parent_is_list = None
+    return render_to_response('membership/member_payment.html',
+                              {'member': member,
+                               'payments': payments,
+                               'reload_parent': parent_is_list and manage,
+                               'manage' : manage,
+                               'fee_list' : fee_list,
+                               'member_type_list': member_type_list })
+
+def add_member_payment(request, member):
+    p = MemberPayment(member = member,
+                      date = datetime.date(*time.strptime(request.POST['date'], '%Y-%m-%d')[:3]),
+                      member_type = MemberType.objects.get(id=request.POST['member_type']),
+                      fee = MemberFee.objects.get(year = request.POST['fee']),
+                      contribution = request.POST['contribution'])
+    p.save()
+    return HttpResponseRedirect(reverse('fsij.membership.views.manage_member_payment', args=(member.member_id,)))
+
+def delete_member_payment(request, member, payment_id):
+    p = MemberPayment.objects.get(pk = payment_id)
+    p.delete()
+    return HttpResponseRedirect(reverse('fsij.membership.views.manage_member_payment', args=(member.member_id,)))
+
+@login_required
+def index(request):
+    member = request.user.get_profile()
+    return member_index(request, member)
+
+@login_required
+def email(request):
+    member = request.user.get_profile()
+    return member_email(request, member)
+
+@login_required
+def register_email(request):
+    member = request.user.get_profile()
+    return register_member_email(request, member)
+
+@login_required
+def address(request):
+    member = request.user.get_profile()
+    return member_address(request, member)
+
+@login_required
+def register_address(request):
+    member = request.user.get_profile()
+    return register_member_address(request, member)
+
+@login_required
+def payment(request):
+    member = request.user.get_profile()
+    return member_payment(request, member)
+
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def manage_member(request, member_id, new):
+### XXX New member!!
+### XXX CorporateMember!!
+    errors = None
+    try:
+        member_data = request.session['member_data']
+        del request.session['member_data']
+        errors = member_data['errors']
+        member = member_data
+    except (KeyError):
+        member = Member.objects.get(member_id=member_id)
+    try: referrer = request.META['HTTP_REFERER']
+    except: referrer = None
+    if referrer:
+       parent_is_list = (not re.match(".*/list/$", referrer))
+    else: parent_is_list = None
+    return render_to_response('membership/member_edit.html',
+                              {'member': member,
+                               'member_type_list': MemberType.objects.all(),
+                               'original_path': request.path,
+                               'reload_parent': parent_is_list,
+                               'errors': errors,
+                               })
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def manage_register_member(request, member_id):
+    member = Member.objects.get(member_id=member_id)
+    errors = []
+    member_type = MemberType.objects.get(id=request.POST['member_type'])
+    name_in_alphabet = request.POST['name_in_alphabet']
+    date_join = request.POST['date_join']
+    date_quit = request.POST['date_quit']
+    advance_payment = request.POST['advance_payment']
+    if not name_in_alphabet:
+        errors.append('name_in_alphabet')
+    if errors:
+        request.session['member_data'] = {
+            'member_id': member.member_id,
+            'member_type' : member_type,
+            'name_in_alphabet': name_in_alphabet,
+            'date_join': date_join,
+            'date_quit': date_quit,
+            'advance_payment': advance_payment,
+            'errors': errors,
+            }
+        return HttpResponseRedirect(request.POST['original_path'])
+    member.member_type = member_type
+    member.name_in_alphabet = name_in_alphabet
+    if date_join and date_join != "None":
+        member.date_join = datetime.date(*time.strptime(date_join, '%Y-%m-%d')[:3])
+        
+    if date_quit and date_quit != "None":
+        member.date_quit = datetime.date(*time.strptime(date_quit, '%Y-%m-%d')[:3])
+    member.advance_payment = advance_payment
+    member.save()
+    return HttpResponseRedirect(request.POST['original_path'])
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def manage_member_email(request, member_id):
+    member = get_object_or_404(Member, member_id=member_id)
+    return member_email(request, member, manage=True)
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def manage_register_member_email(request, member_id):
+    member = get_object_or_404(Member, member_id=member_id)
+    return register_member_email(request, member)
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def manage_member_address(request, member_id):
+    member = get_object_or_404(Member, member_id=member_id)
+    return member_address(request, member, manage=True)
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def manage_register_member_address(request, member_id):
+    member = get_object_or_404(Member, member_id=member_id)
+    return register_member_address(request, member)
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def manage_member_payment(request, member_id):
+    member = get_object_or_404(Member, member_id=member_id)
+    return member_payment(request, member, manage=True)
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def manage_add_member_payment(request, member_id):
+    member = get_object_or_404(Member, member_id=member_id)
+    return add_member_payment(request, member)
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def manage_delete_member_payment(request, member_id, payment_id):
+    member = get_object_or_404(Member, member_id=member_id)
+    return delete_member_payment(request, member, payment_id)
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def member_list_top(request):
+    return render_to_response('membership/member_list_top.html',
+                              { })
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def member_list(request):
+    member_list = Member.objects.filter(date_quit__isnull=True).order_by('member_id')
+    return render_to_response('membership/member_list.html',
+                              {'members': member_list,
+                               })
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def payment_list(request):
+    payments = MemberPayment.objects.all().order_by('date_payment')
+    return render_to_response('membership/payment_list.html',
+                              {'payments': payments,
+                               })
+
+@user_passes_test(lambda u: u.has_perm('membership.can_manage'), LOGIN_URL)
+def valid_member_list(request,year):
+    year_value = int(year)
+    member_list = get_valid_member(year_value)
+    member_list_old = get_valid_member(year_value-1)
+    added = []
+    stable = []
+    deleted = []
+    for m in member_list:
+        if not m in member_list_old:
+            added.append(m)
+        else:
+            stable.append(m)
+    for m in member_list_old:
+        if not m in member_list:
+            deleted.append(m)
+    return render_to_response('membership/valid_member_list.html',
+                              {'stable': stable,
+                               'added': added,
+                               'deleted': deleted,
+                               'year': year,
+                               })
diff --git a/settings.py b/settings.py
new file mode 100644 (file)
index 0000000..ea8d3e1
--- /dev/null
@@ -0,0 +1,100 @@
+# Django settings for fsij project.
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+DEFAULT_FROM_EMAIL = 'webmaster@fsij.org'
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+    ('Niibe Yutaka', 'gniibe@fsij.org'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'sqlite3'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = '/home/fsij/django/fsij/fsij.db'             # Or path to database file if using sqlite3.
+DATABASE_USER = ''             # Not used with sqlite3.
+DATABASE_PASSWORD = ''         # Not used with sqlite3.
+DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
+DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'Asia/Tokyo'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+#LANGUAGE_CODE = 'en-us'
+LANGUAGE_CODE = 'ja'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = ''
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = 'el6y09xy$cbsee0p4y13h_)@6*pxh8(*r8+hg!_qpy(q%pxfnb'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.load_template_source',
+    'django.template.loaders.app_directories.load_template_source',
+#     'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+)
+
+ROOT_URLCONF = 'fsij.urls'
+
+TEMPLATE_DIRS = (
+    "/home/fsij/django/fsij/templates/",
+    # Don't forget to use absolute paths, not relative paths.
+)
+
+INSTALLED_APPS = (
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.admin',
+    'django.contrib.markup',
+#
+    'fsij.membership',
+    'fsij.accounting',
+    'fsij.meeting_attendance',
+    'fsij.files',
+    'fsij.trac_placeholder',
+)
+
+LOGIN_URL = '/fsij/login/'
+LOGOUT_URL = '/fsij/logout/'
+LOGIN_REDIRECT_URL = '/fsij/'
+
+AUTH_PROFILE_MODULE = "membership.Member"
+
+# AUTHENTICATION_BACKENDS = (,)
+
+SESSION_ENGINE = "django.contrib.sessions.backends.file"
+# SESSION_FILE_PATH = "/tmp/django-fsij"
diff --git a/templates/accounting/account_list.html b/templates/accounting/account_list.html
new file mode 100644 (file)
index 0000000..4307450
--- /dev/null
@@ -0,0 +1,22 @@
+<h1>総勘定元帳 {{ year }}年度 </h1>
+
+{% for a in ac_list %}
+{% ifnotequal a.name "繰越" %}
+<!--
+-->
+<h2>{{ a.name }}</h2>
+<table frame=border>
+{% for le in a.ledgerentries %}
+<tr bgcolor={% cycle lightcyan,white %}>
+<td align=right width=100>{% if not le.0 %}<a href="../../transaction/{{ le.2.id }}/">{{ le.1 }}</a>{% endif %}</td>
+<td align=right width=100>{% if le.0 %}<a href="../../transaction/{{ le.2.id }}/">{{ le.1 }}</a>{% endif %}</td>
+</tr>
+{% endfor %}
+<tr><td colspan=2><hr></td></tr>
+<tr>
+<td align=right width=100>{% if not a.type.is_credit %}{{ a.total }}{% endif %}</td>
+<td align=right width=100>{% if a.type.is_credit %}{{ a.total }}{% endif %}</td>
+</tr>
+</table>
+{% endifnotequal %}
+{% endfor %}
diff --git a/templates/accounting/bs_pl_cf.html b/templates/accounting/bs_pl_cf.html
new file mode 100644 (file)
index 0000000..5d94d3e
--- /dev/null
@@ -0,0 +1,185 @@
+<h1>財務諸表 {{ year }}年度 </h1>
+
+<!--
+-->
+<table frame=border rules=cols>
+<caption>貸借対照表<br>{{ fy.end }}</caption>
+<tr>
+<td valign=top>
+<table frame=void cellspacing=4>
+{% for a in ac_list %}
+{% ifnotequal a.name "元入金" %}
+{% if not a.type.is_credit %}
+{% ifequal a.type.value 0 %}
+{% include "accounting/show_entry_1.html" %}
+{% endifequal %}
+{% ifequal a.type.value 1 %}
+{% include "accounting/show_entry_1.html" %}
+{% endifequal %}
+{% ifequal a.type.value 2 %}
+{% include "accounting/show_entry_1.html" %}
+{% endifequal %}
+{% endif %}
+{% endifnotequal %}
+{% endfor %}
+</table>
+</td>
+<td valign=top>
+<table frame=void cellspacing=4>
+{% for a in ac_list %}
+{% ifnotequal a.name "元入金" %}
+{% if a.type.is_credit %}
+{% ifequal a.type.value 0 %}
+{% include "accounting/show_entry_1.html" %}
+{% endifequal %}
+{% ifequal a.type.value 1 %}
+{% include "accounting/show_entry_1.html" %}
+{% endifequal %}
+{% ifequal a.type.value 2 %}
+{% include "accounting/show_entry_1.html" %}
+{% endifequal %}
+{% endif %}
+{% endifnotequal %}
+{% endfor %}
+</table>
+</td>
+</tr>
+<tr><td><hr></td><td><hr></td></tr>
+<tr>
+<td>&nbsp</td>
+<td>
+<table frame=void cellspacing=4>
+{% for a in ac_list %}
+{% ifequal a.name "元入金" %}
+{% include "accounting/show_entry_1.html" %}
+{% endifequal %}
+{% endfor %}
+</table>
+</td>
+</tr>
+<tr>
+<td>&nbsp</td>
+<td>
+<table frame=void cellspacing=4>
+<tr>
+<td aligh=left width=80>当期損益</td>
+<td align=right width=80>{{pl_total}}</td>
+</tr>
+</table>
+</td>
+</tr>
+</table>
+
+
+<br><br><br>
+
+<table frame=border rules=cols>
+<caption>損益計算書<br>{{ fy.begin }} −  {{ fy.end }}</caption
+<tr>
+<td valign=top>
+<table frame=void cellspacing=4>
+{% for a in ac_list %}
+{% ifequal a.type.value 4 %}
+{% include "accounting/show_entry_1.html" %}
+{% endifequal %}
+{% endfor %}
+</table>
+</td>
+<td valign=top>
+<table frame=void cellspacing=4>
+{% for a in ac_list %}
+{% ifequal a.type.value 3 %}
+{% include "accounting/show_entry_1.html" %}
+{% endifequal %}
+{% endfor %}
+</table>
+</td>
+<tr><td><hr></td><td><hr></td></tr>
+<tr>
+<td>
+<table frame=void cellspacing=4>
+<tr>
+<td aligh=left width=80>当期損益</td>
+<td align=right width=80>{{pl_total}}</td>
+</tr>
+</table>
+</td>
+<td>&nbsp</td>
+</tr>
+</table>
+<br><br><br>
+
+<table frame=border rules=cols>
+<caption>収支計算書<br>{{ fy.begin }} −  {{ fy.end }}</caption>
+<tr>
+<td valign=top>
+<table frame=void cellspacing=4>
+{% for a in ac_list %}
+{% ifnotequal a.cash_total 0 %}
+{% if not a.type.is_credit %}
+<tr><td aligh=left width=80>{{a.name}}</td>
+<td align=right width=80>{{ a.cash_total }}</td></tr>
+{% endif %}
+{% endifnotequal %}
+{% endfor %}
+</table>
+</td>
+<td valign=top>
+<table frame=void cellspacing=4>
+{% for a in ac_list %}
+{% ifnotequal a.cash_total 0 %}
+{% if a.type.is_credit %}
+<tr><td aligh=left width=80>{{a.name}}</td>
+<td align=right width=80>{{ a.cash_total }}</td></tr>
+{% endif %}
+{% endifnotequal %}
+{% endfor %}
+</table>
+</td>
+</tr>
+<tr><td><hr></td><td><hr></td></tr>
+<tr>
+<td>
+<table frame=void cellspacing=4>
+<tr>
+<td aligh=left width=80>当期収支</td>
+<td align=right width=80>{{cash_total}}</td>
+</tr>
+</table>
+</td>
+<td>&nbsp</td>
+</tr>
+</table>
+
+<br><br><br>
+
+<table frame=border rules=cols>
+<tr>
+<td valign=top>
+<table frame=void cellspacing=4>
+{% for a in ac_list %}
+{% if a.is_cash %}
+<tr>
+<td aligh=left width=80>期末{{ a.name }}</td>
+<td align=right width=80>{{ a.total }}</td>
+</tr>
+{% endif %}
+{% endfor %}
+</table>
+</td>
+<td valign=top>
+<table frame=void cellspacing=4>
+{% for le in cash_initial_list %}
+<tr>
+<td aligh=left width=80>期初{{le.account.name}}</td>
+<td align=right width=80>{{le.amount }}</td>
+</tr>
+{% endfor %}
+<tr>
+<td aligh=left width=80>当期収支</td>
+<td align=right width=80>{{cash_total}}</td>
+</tr>
+</table>
+</td>
+</tr>
+</table>
\ No newline at end of file
diff --git a/templates/accounting/show_entry.html b/templates/accounting/show_entry.html
new file mode 100644 (file)
index 0000000..b129882
--- /dev/null
@@ -0,0 +1,6 @@
+<tr>
+<td aligh=left width=100>{% if not a.type.is_credit %}{{a.name}}{% endif %}</td>
+<td align=right width=100>{% if not a.type.is_credit %}{{ a.total }}{% endif %}</td>
+<td aligh=left width=100>{% if a.type.is_credit %}{{a.name}}{% endif %}</td>
+<td align=right width=100>{% if a.type.is_credit %}{{ a.total }}{% endif %}</td>
+</tr>
diff --git a/templates/accounting/show_entry_1.html b/templates/accounting/show_entry_1.html
new file mode 100644 (file)
index 0000000..1e77629
--- /dev/null
@@ -0,0 +1,4 @@
+<tr>
+<td aligh=left width=80>{{a.name}}</td>
+<td align=right width=80>{{a.total }}</td>
+</tr>
diff --git a/templates/accounting/transaction.html b/templates/accounting/transaction.html
new file mode 100644 (file)
index 0000000..79cbf27
--- /dev/null
@@ -0,0 +1,44 @@
+<h1>振替伝票</h1>
+
+<h2>{{ t.business.name }}</h2>
+
+<h3>{{ t.date }}</h3>
+<table border="1">
+<caption>ID: {{ t.id|stringformat:"06d" }}</caption>
+<col width=120></col>
+<col width=80></col>
+<col width=250></col>
+<col width=80></col>
+<col width=120></col>
+
+<tr>
+  <th>金額</th>
+  <th>借方科目</th>
+  <th>摘要 / メモ</th>
+  <th>貸方科目</th>
+  <th>金額</th>
+</tr>
+
+{% for i in t.num_line %}
+<tr>
+  <td align=right>{% if t.get_debit.amount %}{{ t.get_debit.amount }}{% else %}&nbsp{% endif %}</td>
+  <td align=right>{% if t.get_debit.account %}{{ t.get_debit.account.name }}{% else %}&nbsp{% endif %}</td>
+  <td>{% ifequal 0 forloop.counter0 %}{% if t.memo %}{{ t.memo }}{% else %}&nbsp{% endif %}{% else %} &nbsp {% endifequal %} 
+  {% ifequal 0 forloop.counter0 %}{% if t.memo_detail %}({{ t.memo_detail }}){% endif %}{% else %}&nbsp{% endifequal %}</td>
+  <td align=right>{% if t.get_credit.account %}{{ t.get_credit.account.name }}{% else %}&nbsp{% endif %}</td>
+  <td align=right>{% if t.get_credit.amount %}{{ t.get_credit.amount }}{% else %}&nbsp{% endif %}</td>
+</tr>
+<!--
+{{ t.next }}
+-->
+{% endfor %}
+<tr>
+<td align=right>{{ t.debit_total }}</td>
+<td colspan=3 align=center>合計</td>
+<td align=right>{{ t.credit_total }}</td>
+</tr>
+</table>
+
+<!--
+<p>Download <a href="pdf/">PDF</a>.</p>
+-->
diff --git a/templates/accounting/transaction_list.html b/templates/accounting/transaction_list.html
new file mode 100644 (file)
index 0000000..8b7e1b7
--- /dev/null
@@ -0,0 +1,140 @@
+{% load i18n %}
+
+<h1>仕訳帳 {% if year %}{{year}}年度{% endif %}</h1>
+
+<table cellpadding=3 rules=rows frame=hsides>
+<tr>
+  <th>年月日</th>
+  <th>事業</th>
+  <th>借方</th>
+  <th>金額</th>
+  <th>貸方</th>
+  <th>金額</th>
+  <th>摘要</th>
+  <th>メモ</th>
+  <th></th>
+</tr>
+
+{% if not year %}
+<form action="new/" method="POST">
+<tr>
+<td><input type="text" name="date" value=""  size=10 maxlength=10 /></td>
+<td><select name="business">
+{% for b in b_list %}
+<option value="{{ b.id }}" />{{ b.name }}</option>
+{% endfor %}
+</select></td>
+<td align=right><select name="debit">
+<option value="" /></option>
+{% for a in a_list %}
+<option value="{{ a.id }}" />{{ a.name }}</option>
+{% endfor %}
+</select></td>
+<td align=right><input type="text" name="debit_amount" size=10 maxlength=10 /></td>
+<td align=right><select name="credit">
+<option value="" /></option>
+{% for a in a_list %}
+<option value="{{ a.id }}" />{{ a.name }}</option>
+{% endfor %}
+</select></td>
+<td align=right><input type="text" name="credit_amount" size=10 maxlength=10 /></td>
+<td><input type="text" name="memo" size=20 /></td>
+<td colspan=2><input type="text" name="memo_detail" size=15 /></td>
+</tr>
+<tr>
+<td></td>
+<td></td>
+<td align=right><select name="debit2">
+<option value="" /></option>
+{% for a in a_list %}
+<option value="{{ a.id }}" />{{ a.name }}</option>
+{% endfor %}
+</select></td>
+<td align=right><input type="text" name="debit_amount2" size=10 maxlength=10 /></td>
+<td align=right><select name="credit2">
+<option value="" /></option>
+{% for a in a_list %}
+<option value="{{ a.id }}" />{{ a.name }}</option>
+{% endfor %}
+</select></td>
+<td align=right><input type="text" name="credit_amount2" size=10 maxlength=10 /></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td></td>
+<td></td>
+<td align=right><select name="debit3">
+<option value="" /></option>
+{% for a in a_list %}
+<option value="{{ a.id }}" />{{ a.name }}</option>
+{% endfor %}
+</select></td>
+<td align=right><input type="text" name="debit_amount3" size=10 maxlength=10 /></td>
+<td align=right><select name="credit3">
+<option value="" /></option>
+{% for a in a_list %}
+<option value="{{ a.id }}" />{{ a.name }}</option>
+{% endfor %}
+</select></td>
+<td align=right><input type="text" name="credit_amount3" size=10 maxlength=10 /></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td></td>
+<td></td>
+<td align=right><select name="debit4">
+<option value="" /></option>
+{% for a in a_list %}
+<option value="{{ a.id }}" />{{ a.name }}</option>
+{% endfor %}
+</select></td>
+<td align=right><input type="text" name="debit_amount4" size=10 maxlength=10 /></td>
+<td align=right><select name="credit4">
+<option value="" /></option>
+{% for a in a_list %}
+<option value="{{ a.id }}" />{{ a.name }}</option>
+{% endfor %}
+</select></td>
+<td align=right><input type="text" name="credit_amount4" size=10 maxlength=10 /></td>
+<td></td>
+<td></td>
+<td><input type="submit" value="登録" /></td>
+</tr>
+<input type="hidden" value="{{ original_path }}" name="original_path" />
+</form>
+{% endif %}
+
+{% for t in tr_list %}
+  {% for i in t.num_line %}
+  {% if not year %}
+<form action="{{ t.id }}/delete/" method="POST">
+  {% endif %}
+<tr bgcolor={% cycle lightcyan,white as rowcolors %}>
+  <td>{% ifequal 0 forloop.counter0 %}<a href="{% if year %}../{% endif %}../transaction/{{ t.id }}/">{{ t.date }}</a>{% endifequal %}</td>
+  <td>{% ifequal 0 forloop.counter0 %}{{ t.business.name }}{% endifequal %}</a></td>
+  <td align=left>{{ t.get_debit.account.name }}</td>
+  <td align=right>{{ t.get_debit.amount }}</td>
+  <td align=left>{{ t.get_credit.account.name }}</td>
+  <td align=right>{{ t.get_credit.amount }}</td>
+  <td align=left>{% ifequal 0 forloop.counter0 %}{{ t.memo }}{% endifequal %}</td>
+  <td align=left>{% ifequal 0 forloop.counter0 %}{{ t.memo_detail }}{% endifequal %}</td>
+  <td>{% if not year %}{% ifequal 0 forloop.revcounter0 %}<input type="submit" name="delete" value="{% trans 'Delete' %}"/>{% endifequal %}{% endif %}</td>
+</tr>
+  {% if not year %}
+<input type="hidden" value="{{ original_path }}" name="original_path" />
+</form>
+  {% endif %}
+<!--
+{{ t.next }}
+{% cycle rowcolors %}
+-->
+  {% endfor %}
+<!--
+{% cycle rowcolors %}
+-->
+{% endfor %}
+</table>
diff --git a/templates/admin/base.html b/templates/admin/base.html
new file mode 100644 (file)
index 0000000..fdf0f28
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE }}" xml:lang="{{ LANGUAGE_CODE }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
+<head>
+<title>{% block title %}{% endblock %}</title>
+<link rel="stylesheet" type="text/css" href="{% block stylesheet %}{% load adminmedia %}{% admin_media_prefix %}css/base.css{% endblock %}" />
+{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% admin_media_prefix %}css/rtl.css{% endblock %}" />{% endif %}
+{% block extrastyle %}{% endblock %}
+{% 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_authenticated and user.is_staff %}
+        <div id="user-tools">{% trans 'Welcome,' %} <strong>{% firstof user.first_name user.username %}</strong>. {% block userlinks %}{% url django-admindocs-docroot as docsroot %}{% if docsroot %}<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> / {% endif %}<a href="{{ root_path }}password_change/">{% trans 'Change password' %}</a> / <a href="{{ root_path }}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 %} &rsaquo; {{ title }}{% endif %}</div>{% endblock %}
+    {% endif %}
+
+        {% if messages %}
+        <ul class="messagelist">{% for message in messages %}<li>{{ message }}</li>{% endfor %}</ul>
+        {% endif %}
+
+    <!-- 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>
diff --git a/templates/admin/base_site.html b/templates/admin/base_site.html
new file mode 100644 (file)
index 0000000..cab3abf
--- /dev/null
@@ -0,0 +1,10 @@
+{% extends "admin/base.html" %}
+{% load i18n %}
+
+{% block title %}{{ title }} | FSIJメンバーズサイト管理 {% endblock %}
+
+{% block branding %}
+<h1 id="site-name">FSIJメンバーズサイト管理</h1>
+{% endblock %}
+
+{% block nav-global %}{% endblock %}
diff --git a/templates/admin/index.html b/templates/admin/index.html
new file mode 100644 (file)
index 0000000..9eb60b8
--- /dev/null
@@ -0,0 +1,68 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+
+{% block stylesheet %}{% load adminmedia %}{% admin_media_prefix %}css/dashboard.css{% endblock %}
+
+{% block coltype %}colMS{% endblock %}
+
+{% block bodyclass %}dashboard{% endblock %}
+
+{% block breadcrumbs %}{% endblock %}
+
+{% block content %}
+<div id="content-main">
+
+{% if app_list %}
+    {% for app in app_list %}
+        <div class="module">
+        <table summary="{% blocktrans with app.name as name %}Models available in the {{ name }} application.{% endblocktrans %}">
+        <caption><a href="{{ app.app_url }}" class="section">{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}</a></caption>
+        {% for model in app.models %}
+            <tr>
+            {% if model.perms.change %}
+                <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
+            {% else %}
+                <th scope="row">{{ model.name }}</th>
+            {% endif %}
+
+            {% if model.perms.add %}
+                <td><a href="{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
+            {% else %}
+                <td>&nbsp;</td>
+            {% endif %}
+
+            {% if model.perms.change %}
+                <td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
+            {% else %}
+                <td>&nbsp;</td>
+            {% endif %}
+            </tr>
+        {% endfor %}
+        </table>
+        </div>
+    {% endfor %}
+{% else %}
+    <p>{% trans "You don't have permission to edit anything." %}</p>
+{% endif %}
+</div>
+{% endblock %}
+
+{% block sidebar %}
+<div id="content-related">
+    <div class="module" id="recent-actions-module">
+        <h2>{% trans 'Recent Actions' %}</h2>
+        <h3>{% trans 'My Actions' %}</h3>
+            {% load log %}
+            {% get_admin_log 10 as admin_log for_user user %}
+            {% if not admin_log %}
+            <p>{% trans 'None available' %}</p>
+            {% else %}
+            <ul class="actionlist">
+            {% for entry in admin_log %}
+            <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">{% if not entry.is_deletion %}<a href="{{ entry.get_admin_url }}">{% endif %}{{ entry.object_repr }}{% if not entry.is_deletion %}</a>{% endif %}<br /><span class="mini quiet">{% filter capfirst %}{% trans entry.content_type.name %}{% endfilter %}</span></li>
+            {% endfor %}
+            </ul>
+            {% endif %}
+    </div>
+</div>
+{% endblock %}
diff --git a/templates/meeting_attendance/attendance_list.html b/templates/meeting_attendance/attendance_list.html
new file mode 100644 (file)
index 0000000..bf1e767
--- /dev/null
@@ -0,0 +1,50 @@
+{% load i18n %}
+{% load markup %}
+
+<h1>{% trans "Attendance list" %} : {{ object.name }}</h1>
+
+<hr/>
+
+<dl><dt><b>{% trans "Date" %}</b></dt><dd>{{ object.date_time }}</dd>
+    <dt><b>{% trans "Place" %}</b></dt><dd>{{ object.place }}</dd>
+    <dt><b>{% trans "Agenda" %}</b></dt><dd>{{ object.agenda|markdown }}</dd>
+</dl>
+
+<hr/>
+<form method="post" action="../attendance_submit/">
+<table>
+<tr>
+<td>会員番号</td>
+<td>名前</td>
+<td>出欠 (登録)</td>
+</tr>
+{% for r in list %}
+<tr>
+<td>{{ r.member.member_id }}</td>
+<td>{{ r.member.user.last_name }} {{ r.member.user.first_name }}</td>
+<td>{% if r.attended %}○{% else %}×{% endif %}
+    ({% if not r.registration.choice %}-{% else %}{{ r.registration.choice.choice }}{% endif %})</td>
+</tr>
+{% endfor %}
+<tr>
+<td>
+  <select name="member_id">
+  {% for person in members %}
+    <option value="{{ person.member_id }}">
+{{ person.member_id }}
+{{ person.user.last_name }} {{ person.user.first_name }}</option>
+  {% endfor %}
+  </select>
+</td>
+<td>
+  <select name="attendance">
+    <option value="True">○</option>
+    <option value="False">×</option>
+  </select>
+</td>
+</tr>
+</table>
+<input type="submit" value="{% trans "Register" %}" />
+</form>
+
+<hr/>
diff --git a/templates/meeting_attendance/meeting_detail.html b/templates/meeting_attendance/meeting_detail.html
new file mode 100644 (file)
index 0000000..9e45a8a
--- /dev/null
@@ -0,0 +1,63 @@
+{% load i18n %}
+{% load markup %}
+
+<h1>{{ object.name }}</h1>
+
+<hr/>
+
+<dl><dt><b>{% trans "Date" %}</b></dt><dd>{{ object.date_time }}</dd>
+    <dt><b>{% trans "Place" %}</b></dt><dd>{{ object.place }}</dd>
+    <dt><b>{% trans "Agenda" %}</b></dt><dd>{{ object.agenda|markdown }}</dd>
+</dl>
+
+<hr/>
+{% if user.is_authenticated %}
+{%   if meeting_finished %}
+<h2>あなたの出欠: {% if attended.attended %}○{% else %}×{% endif %}</h2>
+{%   else %}
+{%     if registration %}
+<h2>現在のあなたの選択: {{ registration.choice.choice }}</h2>
+<p>{% blocktrans with registration.submit_date as date %}Registered on {{ date }}.{% endblocktrans %}</p>
+{%     else %}
+<h2>{% trans "Not registered yet." %}</h2>
+{%     endif %}
+
+<div>
+<form action="register/" method="post">
+<select name="choice">
+{% for choice in object.attendance_set.all %}
+    <option value="{{ choice.id }}"
+{% ifequal choice.choice registration.choice.choice %}selected{% endifequal %}>{{ choice.choice }}</option>
+{% endfor %}
+</select>
+<input type="submit" value="{% trans "Register" %}" />
+</form>
+</div>
+<hr/>
+{%   endif %}
+user: {{ user.username }} <a href="/fsij/logout/">{% trans "logout" %}</a>
+{% else %}
+<div>
+{%   if meeting_finished %}
+{% trans "Please login to see your attendance of the meeting" %}<p>
+{%   else %}
+{% trans "Please login and register for the meeting" %}<p>
+{%   endif %}
+<form method="post" action="/fsij/login/" id="login-form">
+<table>
+<tr>
+    <td><label>{% trans "username" %}</label></td>
+    <td>{{ form.username }}</td>
+</tr>
+<tr>
+    <td><label>{% trans "password" %}</label></td>
+    <td>{{ form.password }}</td>
+</tr>
+</table>
+
+<input type="submit" value="{% trans 'login' %}" />
+<input type="hidden" name="next" value="{{ next }}" />
+</form>
+<a href=/password_reset/>Forgot your password?</a>
+</div>
+{% endif %}
diff --git a/templates/meeting_attendance/meeting_list.html b/templates/meeting_attendance/meeting_list.html
new file mode 100644 (file)
index 0000000..e4f8bab
--- /dev/null
@@ -0,0 +1,11 @@
+{% load i18n %}
+<h1>{% trans "Meetings" %}</h1>
+{% if object_list %}
+    <ul>
+    {% for meeting in object_list %}
+        <li><a href="{{meeting.id}}/">{{ meeting.name }}</a></li>
+    {% endfor %}
+    </ul>
+{% else %}
+    <p>{% trans "No meetings are available." %}</p>
+{% endif %}
diff --git a/templates/meeting_attendance/registration_list.html b/templates/meeting_attendance/registration_list.html
new file mode 100644 (file)
index 0000000..71ddf09
--- /dev/null
@@ -0,0 +1,32 @@
+{% load i18n %}
+{% load markup %}
+
+<h1>{% trans "Registration list" %} : {{ object.name }}</h1>
+
+<hr/>
+
+<dl><dt><b>{% trans "Date" %}</b></dt><dd>{{ object.date_time }}</dd>
+    <dt><b>{% trans "Place" %}</b></dt><dd>{{ object.place }}</dd>
+    <dt><b>{% trans "Agenda" %}</b></dt><dd>{{ object.agenda|markdown }}</dd>
+</dl>
+
+<hr/>
+
+<table>
+<tr>
+<td>会員番号</td>
+<td>名前</td>
+<td>出欠</td>
+<td>登録日</td>
+</tr>
+{% for r in list %}
+<tr>
+<td>{{ r.member.member_id }}</td>
+<td>{{ r.member.user.last_name }} {{ r.member.user.first_name }}</td>
+<td>{{ r.choice.choice }}</td>
+<td>{{ r.submit_date }}</td>
+</tr>
+{% endfor %}
+</table>
+
+<hr/>
diff --git a/templates/membership/member_address.html b/templates/membership/member_address.html
new file mode 100644 (file)
index 0000000..9e3a924
--- /dev/null
@@ -0,0 +1,28 @@
+{% load i18n %}
+
+{% if reload_parent %}
+<script type="text/javascript">
+parent.list.location.reload()
+</script>
+{% endif %}
+
+<h1>会員情報(住所)</h1>
+
+<h2>会員番号: {{ member.member_id }}</h2>
+
+{% if errors %}
+{{ errors }}
+{% endif %}
+
+<form action="register/" method="POST">
+<ul>
+<li>連絡先は自宅<input type=checkbox name=contact_is_home {% if addr.contact_is_home%}checked{% endif %}/> (会社の場合は外してください)</li>
+<li>郵便番号<input type=text name=zip_code value="{{addr.zip_code}}" /> (必須)</li>
+<li>住所一行目<input type=text name=address_line1 value="{{addr.address_line1}}" />(必須)</li>
+<li>住所二行目<input type=text name=address_line2 value="{{addr.address_line2}}" /> </li>
+<li>住所三行目<input type=text name=address_line3 value="{{addr.address_line3}}" /> </li>
+<li>所属<input type=text name=affiliation value="{{addr.affiliation}}" /> (連絡先が会社の場合入力してください)</li>
+</ul>
+<input type="submit" value="登録" />
+<input type="hidden" value="{{ original_path }}" name="original_path" />
+</form>
diff --git a/templates/membership/member_address_old.html b/templates/membership/member_address_old.html
new file mode 100644 (file)
index 0000000..85b4c8f
--- /dev/null
@@ -0,0 +1,16 @@
+{% load i18n %}
+<h1>会員情報(住所)</h1>
+
+<form action="register/" method="post">
+<table>
+<tr><td>会員番号</td><td>{{ member.member_id }}</td></tr>
+<tr><td>連絡先は自宅</td><td><input type="checkbox" value="home" name="contact" {% if address.contact_is_home %}checked{% endif %}></td></tr>
+<tr><td>郵便番号</td><td><input type="text" value="{{ address.zip_code }}" name="zip"/></td></tr>
+<tr><td>住所(1行目)</td><td><input type="text" maxlength="30" value="{{ address.address_line1 }}" name="addr1"/></td></tr>
+<tr><td>住所(2行目)</td><td><input type="text" maxlength="30" value="{{ address.address_line2 }}" name="addr2"/></td></tr>
+<tr><td>住所(3行目)</td><td><input type="text" maxlength="30" value="{{ address.address_line3 }}" name="addr3"/></td></tr>
+<tr><td>所属</td><td><input type="text" value="{{ address.affiliation }}" name="aff"/></td></tr>
+</table>
+<input type="submit" value="{% trans "Register" %}" />
+<input type="hidden" value="{{ original_path }}" name="original_path" />
+</form>
diff --git a/templates/membership/member_edit.html b/templates/membership/member_edit.html
new file mode 100644 (file)
index 0000000..74ddafb
--- /dev/null
@@ -0,0 +1,32 @@
+{% load i18n %}
+
+{% if reload_parent %}
+<script type="text/javascript">
+parent.list.location.reload()
+</script>
+{% endif %}
+
+<h1>会員情報</h1>
+
+{% if errors %}
+{{ errors }}
+{% endif %}
+
+<h2>会員番号: {{ member.member_id }}</h2>
+
+<form action="register/" method="POST">
+<ul>
+<li>会員種別: <select name=member_type>
+{% for mt in member_type_list %}
+<option value="{{mt.id}}" {% ifequal mt member.member_type %}selected{% endifequal %}>{{ mt.name }}</option>
+{% endfor %}
+</select>
+</li>
+<li>名前(in ASCII): <input type=text name=name_in_alphabet value="{{ member.name_in_alphabet }}" /></li>
+<li>入会年月日: <input type=text name=date_join value="{{ member.date_join }}" /></li>
+<li>退会年月日: <input type=text name=date_quit value="{{ member.date_quit }}" /></li>
+<li>前受金: <input type=text name=advance_payment value="{{ member.advance_payment }}" /></li>
+</ul>
+<input type="submit" value="Submit" />
+<input type="hidden" value="{{ original_path }}" name="original_path" />
+</form>
diff --git a/templates/membership/member_email.html b/templates/membership/member_email.html
new file mode 100644 (file)
index 0000000..23ca162
--- /dev/null
@@ -0,0 +1,23 @@
+{% load i18n %}
+
+{% if reload_parent %}
+<script type="text/javascript">
+parent.list.location.reload()
+</script>
+{% endif %}
+
+<h1>会員情報(メールアドレス)</h1>
+
+<h2>会員番号: {{ member.member_id }}</h2>
+
+{% if errors %}
+{{ errors }}
+{% endif %}
+
+<form action="register/" method="POST">
+<ul>
+<li>メールアドレス<input type=text name=email value="{{email}}" /> (@fsij.org はダメです) </li>
+</ul>
+<input type="submit" value="登録" />
+<input type="hidden" value="{{ original_path }}" name="original_path" />
+</form>
diff --git a/templates/membership/member_index.html b/templates/membership/member_index.html
new file mode 100644 (file)
index 0000000..32b3867
--- /dev/null
@@ -0,0 +1,12 @@
+<h1>会員情報</h1>
+
+<ul>
+<li>{{ member.member_id }}</li>
+<li>{{ member.member_type.name }}</li>
+<!--
+<li>{{ member.date_join }}</li>
+-->
+<li><a href="email/">メールアドレス</a><li>
+<li><a href="address/">住所</a></li>
+<li><a href="payment/">会費支払い状況</a></li>
+</ul>
diff --git a/templates/membership/member_list.html b/templates/membership/member_list.html
new file mode 100644 (file)
index 0000000..5e013fd
--- /dev/null
@@ -0,0 +1,26 @@
+<h1>会員情報リスト</h1>
+
+{# adding new member #}
+{# editing member's type, etc #}
+<table>
+<tr>
+  <td>名前</td>
+  <td>会員種別</td>
+  <td>入会年月日</td>
+  <td>住所</td>
+  <td>会費支払い</td>
+  <td>メールアドレス</td>
+</tr>
+{% for m in members %}
+<tr>
+  <td><a href="../{{ m.member_id }}/" target="edit" title="{{ m.member_id }}">
+  {{ m.name }}</a></td>
+  <td>{{ m.member_type.name }}</td>
+  <td>{{ m.date_join }}</td>
+  <td><a href="../{{ m.member_id }}/address/" target="edit">
+{% if m.memberaddress_set.get %}{{ m.memberaddress_set.get.zip_code }}{% else %}新規作成{% endif %}</a></td>
+  <td><a href="../{{ m.member_id }}/payment/" target="edit">{{ m.memberpayment_set.count }}</a></td>
+  <td><a href="../{{ m.member_id }}/email/" target="edit">{{ m.user.email }}</a></td>
+</tr>
+{% endfor %}
+</table>
diff --git a/templates/membership/member_list_top.html b/templates/membership/member_list_top.html
new file mode 100644 (file)
index 0000000..3507e55
--- /dev/null
@@ -0,0 +1,4 @@
+<frameset rows="25%,*">
+<frame name="list" src="/fsij/membership/list/">
+<frame name="edit" src="">
+</frameset>
diff --git a/templates/membership/member_payment.html b/templates/membership/member_payment.html
new file mode 100644 (file)
index 0000000..dab95d7
--- /dev/null
@@ -0,0 +1,78 @@
+{% load i18n %}
+
+{% if reload_parent %}
+<script type="text/javascript">
+parent.list.location.reload()
+</script>
+{% endif %}
+
+<h1>会員情報(会費支払い状況) </h1>
+
+<table>
+<tr><td>会員番号</td><td>{{ member.member_id }}</td></tr>
+<tr><td>会員種別</td><td>{{ member.member_type.name }}</td></tr>
+{% ifnotequal member.advance_payment 0 %}
+<tr><td>前受金</td><td>{{ member.advance_payment }}</td></tr>
+{% endifnotequal %}
+</table>
+
+{% if manage %}
+<table>
+<tr><th>日付</th><th>内容</th><th>編集</th></tr>
+{% for p in payments %}
+<tr bgcolor={% cycle lightcyan,white %}>
+<form action="delete/{{ p.id }}/" method="post">
+<td>{{ p.date }}</td>
+<td>{% ifequal p.fee.year 9999 %}入会金{% else %}{{ p.fee.year }}年度{% endifequal%}
+{% ifnotequal p.member_type member.member_type %}
+[ {{ p.member_type.name }} ]
+{% endifnotequal %}
+{% ifequal p.member_type.id 3 %}
+( {{ p.contribution }} )
+{% endifequal %}
+</td>
+<td><input type="submit" name="delete" value="{% trans 'Delete' %}"/></td>
+</tr>
+</form>
+{% endfor %}
+<form action="add/" method="post">
+<tr>
+<td><input type="text" name="date" value=""/></td>
+<td>
+<select name="fee">
+{% for fee in fee_list%}
+<option value="{{ fee.year }}">{% ifequal fee.year 9999 %}入会金{% else %}{{ fee.year }}年度{% endifequal %}</option>
+{% endfor %}
+</select>
+{% ifequal member.member_type.id 3 %}
+( <input type="text" name="contribution" value="{{ member.corporatemember.contribution }}" /> )
+<input type="hidden" name="member_type" value="{{member.member_type.id}}" />
+{% else %}
+<select name="member_type">
+{% for mt in member_type_list %}
+<option value="{{mt.id}}" {% ifequal mt member.member_type %}selected{% endifequal %}>{{mt.name}}</option>
+{% endfor %}
+</select>
+<input type="hidden" name="contribution" value="1" />
+{% endifequal %}
+</td>
+<td><input type="submit" name="add" value="{% trans 'Add' %}" /></td>
+</tr>
+</form>
+</table>
+{% else %}
+<table>
+<tr><th>日付</th><th>内容</th></tr>
+{% for p in payments %}
+<tr bgcolor={% cycle lightcyan,white %}><td>{{ p.date }}</td>
+<td>{% ifequal p.fee.year 9999 %}入会金{% else %}{{ p.fee.year }}年度{% endifequal %}
+{% ifnotequal p.member_type member.member_type %}
+[ {{ p.member_type.name }} ]
+{% endifnotequal %}
+{% ifequal p.member_type.id 3 %}
+( {{ p.contribution }} )
+{% endifequal %}
+</td></tr>
+{% endfor %}
+</table>
+{% endif %}
diff --git a/templates/membership/payment_list.html b/templates/membership/payment_list.html
new file mode 100644 (file)
index 0000000..bd38b14
--- /dev/null
@@ -0,0 +1,35 @@
+<h1>会費入金リスト</h1>
+
+{# adding new payment #}
+
+<table>
+<tr>
+  <td>年月日</td>
+  <td>会員番号</td>
+  <td>金額</td>
+  <td>支払い区分(貸方)</td>
+  <td></td>
+</tr>
+{% for p in payments %}
+<form action="/{{ p.id }}/" method="POST">
+<tr>
+  <td>{{ p.date_payment }}</td>
+  <td><a href="../{{ p.member.member_id }}/" title="{{ p.member.user.last_name }} {{ p.member.user.first_name }}" target="edit">{{ p.member.member_id }}</a></td>
+  <td>{{ p.amount }}</td>
+  <td>{{ p.payment_for }}</td>
+<td>
+<input type="submit" value="Submit" />
+<input type="hidden" value="{{ original_path }}" name="original_path" />
+</td>
+</tr>
+</form>
+{% endfor %}
+<tr>
+<td>
+<form action="/{{ p.id }}/new/" method="POST">
+<input type="submit" value="Submit" />
+<input type="hidden" value="{{ original_path }}" name="original_path" />
+</form>
+</td>
+</tr>
+</table>
diff --git a/templates/membership/valid_member_list.html b/templates/membership/valid_member_list.html
new file mode 100644 (file)
index 0000000..fcf4ba7
--- /dev/null
@@ -0,0 +1,30 @@
+<h1>会費支払い会員情報リスト ({{year}}年度)</h1>
+
+<table>
+<tr>
+  <td>名前</td>
+  <td>会員種別</td>
+  <td>入会年月日</td>
+</tr>
+{% for m in added %}
+<tr bgcolor=cyan>
+  <td>{{ m.name }}</td>
+  <td>{{ m.member_type.name }}</td>
+  <td>{{ m.date_join }}</td>
+</tr>
+{% endfor %}
+{% for m in deleted %}
+<tr bgcolor=violet>
+  <td>{{ m.name }}</td>
+  <td>{{ m.member_type.name }}</td>
+  <td>{{ m.date_join }}</td>
+</tr>
+{% endfor %}
+{% for m in stable %}
+<tr>
+  <td>{{ m.name }}</td>
+  <td>{{ m.member_type.name }}</td>
+  <td>{{ m.date_join }}</td>
+</tr>
+{% endfor %}
+</table>
diff --git a/templates/registration/logged_out.html b/templates/registration/logged_out.html
new file mode 100644 (file)
index 0000000..28277ed
--- /dev/null
@@ -0,0 +1,7 @@
+{% load i18n %}
+<h1>FSIJメンバーズサイト</h1>
+<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a></div>
+
+<p>{% trans "Thanks for spending some quality time with the Web site today." %}</p>
+
+<p><a href="../">{% trans 'Log in again' %}</a></p>
diff --git a/templates/registration/login.html b/templates/registration/login.html
new file mode 100644 (file)
index 0000000..d49c6a2
--- /dev/null
@@ -0,0 +1,28 @@
+{% load i18n %}
+
+{% if error_message %}
+<p class="errornote">{{ error_message }}</p>
+{% endif %}
+{% if form.error_dict %}
+Failed.
+{% endif %}
+{% if user.is_authenticated %}
+Access denined.<p>
+You don't have permission.<p>
+{% else %}
+Login required.<p>
+
+<form method="post" action="/fsij/login/">
+  <div class="form-row">
+    <label for="id_username">{% trans 'Username:' %}</label> <input type="text" name="username" id="id_username" />
+  </div>
+  <div class="form-row">
+    <label for="id_password">{% trans 'Password:' %}</label> <input type="password" name="password" id="id_password" />
+  </div>
+  <div class="submit-row">
+    <label>&nbsp;</label><input type="submit" value="{% trans 'login' %}" />
+  </div>
+  <input type="hidden" name="next" value="{{ next }}" />
+</form>
+<a href="/fsij/password_reset/">Forgot your password?</a>
+{% endif %}
diff --git a/templates/registration/password_change_done.html b/templates/registration/password_change_done.html
new file mode 100644 (file)
index 0000000..f7c2ceb
--- /dev/null
@@ -0,0 +1,14 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+{% block userlinks %}{% url django-admindocs-docroot as docsroot %}{% if docsroot %}<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> / {% endif %}{% trans 'Change password' %} / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password change' %}</div>{% endblock %}
+
+{% block title %}{% trans 'Password change successful' %}{% endblock %}
+
+{% block content %}
+
+<h1>{% trans 'Password change successful' %}</h1>
+
+<p>{% trans 'Your password was changed.' %}</p>
+
+{% endblock %}
diff --git a/templates/registration/password_change_form.html b/templates/registration/password_change_form.html
new file mode 100644 (file)
index 0000000..c13c7f7
--- /dev/null
@@ -0,0 +1,26 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+{% block userlinks %}{% url django-admindocs-docroot as docsroot %}{% if docsroot %}<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> / {% endif %} {% trans 'Change password' %} / <a href="../logout/">{% trans 'Log out' %}</a>{% endblock %}
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password change' %}</div>{% endblock %}
+
+{% block title %}{% trans 'Password change' %}{% endblock %}
+
+{% block content %}
+
+<h1>{% trans 'Password change' %}</h1>
+
+<p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p>
+
+<form action="" method="post">
+
+{{ form.old_password.errors }}
+<p class="aligned wide"><label for="id_old_password">{% trans 'Old password:' %}</label>{{ form.old_password }}</p>
+{{ form.new_password1.errors }}
+<p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p>
+{{ form.new_password2.errors }}
+<p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p>
+
+<p><input type="submit" value="{% trans 'Change my password' %}" /></p>
+</form>
+
+{% endblock %}
diff --git a/templates/registration/password_reset_complete.html b/templates/registration/password_reset_complete.html
new file mode 100644 (file)
index 0000000..fceb167
--- /dev/null
@@ -0,0 +1,16 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
+
+{% block title %}{% trans 'Password reset complete' %}{% endblock %}
+
+{% block content %}
+
+<h1>{% trans 'Password reset complete' %}</h1>
+
+<p>{% trans "Your password has been set.  You may go ahead and log in now." %}</p>
+
+<p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p>
+
+{% endblock %}
diff --git a/templates/registration/password_reset_confirm.html b/templates/registration/password_reset_confirm.html
new file mode 100644 (file)
index 0000000..0d3eb38
--- /dev/null
@@ -0,0 +1,32 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset confirmation' %}</div>{% endblock %}
+
+{% block title %}{% trans 'Password reset' %}{% endblock %}
+
+{% block content %}
+
+{% if validlink %}
+
+<h1>{% trans 'Enter new password' %}</h1>
+
+<p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
+
+<form action="" method="post">
+{{ form.new_password1.errors }}
+<p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p>
+{{ form.new_password2.errors }}
+<p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p>
+<p><input type="submit" value="{% trans 'Change my password' %}" /></p>
+</form>
+
+{% else %}
+
+<h1>{% trans 'Password reset unsuccessful' %}</h1>
+
+<p>{% trans "The password reset link was invalid, possibly because it has already been used.  Please request a new password reset." %}
+
+{% endif %}
+
+{% endblock %}
diff --git a/templates/registration/password_reset_done.html b/templates/registration/password_reset_done.html
new file mode 100644 (file)
index 0000000..e223bdb
--- /dev/null
@@ -0,0 +1,14 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
+
+{% block title %}{% trans 'Password reset successful' %}{% endblock %}
+
+{% block content %}
+
+<h1>{% trans 'Password reset successful' %}</h1>
+
+<p>{% trans "We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly." %}</p>
+
+{% endblock %}
diff --git a/templates/registration/password_reset_email.html b/templates/registration/password_reset_email.html
new file mode 100644 (file)
index 0000000..4e4bd6d
--- /dev/null
@@ -0,0 +1,15 @@
+{% load i18n %}{% autoescape off %}
+{% trans "You're receiving this e-mail because you requested a password reset" %}
+{% blocktrans %}for your user account at {{ site_name }}{% endblocktrans %}.
+
+{% trans "Please go to the following page and choose a new password:" %}
+{% block reset_link %}
+{{ protocol }}://{{ domain }}{% url django.contrib.auth.views.password_reset_confirm uidb36=uid, token=token %}
+{% endblock %}
+{% trans "Your username, in case you've forgotten:" %} {{ user.username }}
+
+{% trans "Thanks for using our site!" %}
+
+{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
+
+{% endautoescape %}
diff --git a/templates/registration/password_reset_form.html b/templates/registration/password_reset_form.html
new file mode 100644 (file)
index 0000000..704066c
--- /dev/null
@@ -0,0 +1,19 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
+
+{% block title %}{% trans "Password reset" %}{% endblock %}
+
+{% block content %}
+
+<h1>{% trans "Password reset" %}</h1>
+
+<p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p>
+
+<form action="" method="post">
+{{ form.email.errors }}
+<p><label for="id_email">{% trans 'E-mail address:' %}</label> {{ form.email }} <input type="submit" value="{% trans 'Reset my password' %}" /></p>
+</form>
+
+{% endblock %}
diff --git a/templates/top_page.html b/templates/top_page.html
new file mode 100644 (file)
index 0000000..52f759e
--- /dev/null
@@ -0,0 +1,57 @@
+{% load i18n %}
+<h1>FSIJメンバーズサイト</h1>
+<h2>FSIJメンバーズサイト移行のお知らせ (2009-07-09)</h2>
+<p>新しいマシンを用意し、メンバーズサイトは移行しました</p>
+
+<h2>2009年度通常総会のお知らせ</h2>
+<p>
+2009年6月13日(土)に、産総研秋葉原事業所で2009年度通常総会を開催します。
+</p>
+<p>詳しくは<a href="meetings/1/">こちら</a>を参照ください。</p>
+<p>事前の出欠登録をおねがいします。登録は前日まで変更できますので、まずは早めに登録してくださいますよう、おねがいします。</p>
+
+<p>場所は駅前の秋葉原ダイビル 11Fです(大会議室1)。
+Google mapでは<a href=http://maps.google.com/maps/ms?msa=0&msid=114694549899339534298.00043980edf09d46b14cf>ここ</a>。</p>
+
+<br>
+<h2>2008年度財務諸表の閲覧</h2>
+{% if user.is_authenticated %}
+<p>
+2008年度財務諸表は<a href="accounting/2008/bs_pl_cf/">こちら</a>。
+</p>
+{% else %}
+<p>ログインして、閲覧ください。</p>
+{% endif %}
+
+<br>
+<h2>会費支払い、登録住所の確認のお願い</h2>
+{% if user.is_authenticated %}
+<p>
+<a href="membership/">こちら</a>で、登録住所、会費支払い状況を確認ください。
+</p>
+{% else %}
+<p>ログインして、確認ください。</p>
+{% endif %}
+
+<br>
+<hr>
+{% if user.is_authenticated %}
+<p>ユーザ: {{ user.username }} <a href="/fsij/logout/">{% trans "logout" %}</a></p>
+{% else %}
+<h2>ログイン</h2>
+<form method="post" action="/fsij/login/">
+  <div class="form-row">
+    <label for="id_username">{% trans 'Username:' %}</label> <input type="text" name="username" id="id_username" />
+  </div>
+  <div class="form-row">
+    <label for="id_password">{% trans 'Password:' %}</label> <input type="password" name="password" id="id_password" />
+  </div>
+  <div class="submit-row">
+    <label>&nbsp;</label><input type="submit" value="{% trans 'login' %}" />
+  </div>
+  <input type="hidden" name="next" value="/fsij/" />
+</form>
+
+<p><a href=password_reset/>パスワードを忘れちゃった?</a></p>
+<p>{% trans 'Username' %} も忘れてしまった場合は membership at fsij.org まで連絡ください。</p>
+{% endif %}
diff --git a/trac_placeholder/__init__.py b/trac_placeholder/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/trac_placeholder/models.py b/trac_placeholder/models.py
new file mode 100644 (file)
index 0000000..ac6dd81
--- /dev/null
@@ -0,0 +1,6 @@
+from django.db import models
+
+class TracAuthorization(models.Model):
+    class Meta:
+        permissions = (("can_access_members_trac", "Can access members trac"),
+                       ("can_access_staff_trac", "Can access staff trac"))
diff --git a/trac_placeholder/views.py b/trac_placeholder/views.py
new file mode 100644 (file)
index 0000000..60f00ef
--- /dev/null
@@ -0,0 +1 @@
+# Create your views here.
diff --git a/urls.py b/urls.py
new file mode 100644 (file)
index 0000000..5c3beda
--- /dev/null
+++ b/urls.py
@@ -0,0 +1,21 @@
+from django.conf.urls.defaults import *
+
+from django.contrib import admin
+admin.autodiscover()
+
+urlpatterns = patterns('',
+    (r'^fsij/$','fsij.views.index'),
+    (r'^fsij/login/','django.contrib.auth.views.login'),
+    (r'^fsij/logout/','django.contrib.auth.views.logout'),
+    (r'^fsij/password_change/', 'django.contrib.auth.views.password_change'),
+    (r'^fsij/password_change_done/', 'django.contrib.auth.views.password_change_done'),
+    (r'^fsij/password_reset/$', 'django.contrib.auth.views.password_reset'),
+    (r'^fsij/password_reset/done/$', 'django.contrib.auth.views.password_reset_done'),
+    (r'^fsij/password_reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'),
+    (r'^fsij/password_reset/complete/$', 'django.contrib.auth.views.password_reset_complete'),
+    (r'^fsij/meetings/', include('fsij.meeting_attendance.urls')),
+    (r'^fsij/membership/', include('fsij.membership.urls')),
+    (r'^fsij/accounting/', include('fsij.accounting.urls')),
+    (r'^fsij/files/', include('fsij.files.urls')),
+    (r'^fsij/admin/(.*)', admin.site.root),
+)
diff --git a/views.py b/views.py
new file mode 100644 (file)
index 0000000..818c549
--- /dev/null
+++ b/views.py
@@ -0,0 +1,7 @@
+from django.shortcuts import render_to_response
+
+def index(request):
+    request.session.set_test_cookie()
+    return render_to_response('top_page.html',
+                              {'user': request.user,
+                               })