Lots of fixes and improvements, killed email reminders for now due to security problems.
parent
98bc74d874
commit
416ae2afa6
|
@ -161,11 +161,14 @@ def api_months_due(membername):
|
|||
raise APIError("No such member.", 404)
|
||||
year, month = member.get_last_paid()
|
||||
if not year:
|
||||
raise APIError("Member never paid", 402)
|
||||
now = datetime.datetime.now()
|
||||
then_timestamp = year * 12 + (month-1)
|
||||
now_timestamp = now.year * 12 + (now.month-1)
|
||||
return now_timestamp - then_timestamp
|
||||
raise APIError("Member never paid.", 402)
|
||||
if year and member.active == False:
|
||||
raise APIError("No longer a member.", 410)
|
||||
due = member.months_due()
|
||||
#now = datetime.datetime.now()
|
||||
#then_timestamp = year * 12 + (month-1)
|
||||
#now_timestamp = now.year * 12 + (now.month-1)
|
||||
return due
|
||||
|
||||
@_public_api_method("cashflow/<int:year>/<int:month>")
|
||||
def api_cashflow(year, month):
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import datetime
|
||||
import re
|
||||
|
||||
from webapp import db
|
||||
from webapp import app,db
|
||||
|
||||
|
||||
class APIKey(db.Model):
|
||||
|
@ -34,13 +34,17 @@ class Member(db.Model):
|
|||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String(64), unique=True)
|
||||
type = db.Column(db.Enum("starving", "fatty", name="member_types"))
|
||||
transfers = db.relationship("MemberTransfer")
|
||||
transfers = db.relationship("MemberTransfer",order_by=[db.asc(MemberTransfer.year), db.asc(MemberTransfer.month)])
|
||||
active = db.Column(db.Boolean)
|
||||
api_keys = db.relationship("APIKey")
|
||||
join_year = db.Column(db.Integer)
|
||||
join_month = db.Column(db.Integer)
|
||||
|
||||
def get_last_paid(self):
|
||||
year, month, oldest = 0, 0, 0
|
||||
for mt in self.transfers:
|
||||
if mt.transfer.uid == app.config["DUMMY_TRANSFER_UID"]:
|
||||
continue
|
||||
age = mt.year * 12 + (mt.month - 1)
|
||||
if age > oldest:
|
||||
oldest = age
|
||||
|
@ -52,13 +56,28 @@ class Member(db.Model):
|
|||
return year, month
|
||||
|
||||
def get_next_unpaid(self):
|
||||
now_date = datetime.datetime.now()
|
||||
now = now_date.year * 12 + (now_date.month -1)
|
||||
del now_date
|
||||
|
||||
if self.join_year is not None and self.join_month is not None:
|
||||
joined = self.join_year * 12 + (self.join_month - 1)
|
||||
else:
|
||||
joined = None
|
||||
|
||||
year, month, oldest = 0, 0, 0
|
||||
|
||||
|
||||
for mt in self.transfers:
|
||||
age = mt.year * 12 + (mt.month - 1)
|
||||
if age > oldest:
|
||||
oldest = age
|
||||
year = mt.year
|
||||
month = mt.month
|
||||
if mt.transfer.uid == app.config["DUMMY_TRANSFER_UID"]:
|
||||
year = 0
|
||||
month = 0
|
||||
else:
|
||||
year = mt.year
|
||||
month = mt.month
|
||||
if year == 0:
|
||||
# TODO: should be a member's join date rather than now
|
||||
now = datetime.datetime.now()
|
||||
|
@ -72,21 +91,67 @@ class Member(db.Model):
|
|||
|
||||
|
||||
def months_due(self):
|
||||
# TODO: fix if member hasn't paid yet...
|
||||
now = datetime.datetime.now()
|
||||
oldest = 0
|
||||
now_date = datetime.datetime.now()
|
||||
now = now_date.year * 12 + (now_date.month -1)
|
||||
del now_date
|
||||
|
||||
if self.join_year is not None and self.join_month is not None:
|
||||
joined = self.join_year * 12 + (self.join_month - 1)
|
||||
else:
|
||||
joined = None
|
||||
|
||||
unpaid_months = 0
|
||||
last_age = 0
|
||||
last_uid = None
|
||||
|
||||
for mt in self.transfers:
|
||||
age = mt.year * 12 + (mt.month - 1)
|
||||
if age > oldest:
|
||||
oldest = age
|
||||
return (now.year * 12 + (now.month - 1)) - oldest
|
||||
|
||||
# First transfer, join date known
|
||||
if last_uid == None and joined is not None:
|
||||
unpaid_months = unpaid_months + (joined - age)
|
||||
|
||||
# First transfer, join date not known, nothing to do here
|
||||
elif last_uid == None:
|
||||
pass
|
||||
|
||||
# First transfer after a gap in membership
|
||||
elif last_uid == app.config["DUMMY_TRANSFER_UID"]:
|
||||
pass
|
||||
|
||||
# Unpaid months between transfers
|
||||
elif age - last_age > 1:
|
||||
unpaid_months = unpaid_months + (age - last_age) - 1
|
||||
|
||||
last_age = age
|
||||
last_uid = mt.transfer.uid
|
||||
|
||||
# Not a member anymore
|
||||
if last_uid == app.config["DUMMY_TRANSFER_UID"]:
|
||||
pass
|
||||
|
||||
# Never paid, known join date
|
||||
elif last_uid is None and joined is not None:
|
||||
unpaid_months = unpaid_months + (now - joined)
|
||||
|
||||
# Never paid, unknown join date, WTF
|
||||
elif last_uid is None:
|
||||
pass
|
||||
|
||||
# Is a member, has not paid recently
|
||||
else:
|
||||
unpaid_months = unpaid_months + (now - last_age)
|
||||
|
||||
return unpaid_months
|
||||
|
||||
def __init__(self, _id, _username, _type, _active):
|
||||
self.id = _id
|
||||
self.username = _username
|
||||
self.type = _type
|
||||
self.active = _active
|
||||
|
||||
now_date = datetime.datetime.now()
|
||||
self.join_year = now_date.year
|
||||
self.join_month = now_date.month
|
||||
|
||||
class Transfer(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
@ -126,7 +191,10 @@ class Transfer(db.Model):
|
|||
if not member:
|
||||
return self.MATCH_NO_USER, member_name
|
||||
|
||||
if (title[1] == 'starving' and self.amount > 50) or (title[1] == 'fatty' and self.amount > 100):
|
||||
return self.MATCH_WRONG_TYPE, member
|
||||
|
||||
if title[2]:
|
||||
return self.MATCH_WRONG_TYPE, member
|
||||
|
||||
return self.MATCH_OK, member
|
||||
return self.MATCH_OK, member
|
||||
|
|
|
@ -4,23 +4,25 @@
|
|||
<h2>Operations:</h2>
|
||||
<a href="/fetch">fetch transfers from bre</a><br />
|
||||
<a href="/spam">send monthly report to members</a>
|
||||
<h2>Active members:</h2>
|
||||
<ul>
|
||||
{% for member in active_members %}
|
||||
{% for group in active_members|groupby("type") %}
|
||||
<h2>Active members, {{ group.grouper }}:</h2>
|
||||
<ol>
|
||||
{% for member in group.list %}
|
||||
<li>
|
||||
<a style="color: #{{ member.color }};" href="/member/{{ member.username }}">{{ member.username }}</a> ({{ member.months_due() }} months due)
|
||||
| <a href="/member/{{ member.username }}/edit">edit</a>
|
||||
| <a href="/member/{{ member.username }}/deactivate">deactivate</a>
|
||||
{% if member.months_due() > 2 %}
|
||||
{% if member.months_due() > 2 %}
|
||||
| <a href="/member/{{ member.username }}/warn">warn</a>
|
||||
{% else %}
|
||||
{% else %}
|
||||
| <a href="/member/{{ member.username }}/remind">remind</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
{% endfor %}
|
||||
<h2>Inactive members:</h2>
|
||||
<ul>
|
||||
<ol>
|
||||
{% for member in inactive_members %}
|
||||
<li>
|
||||
<a style="color: #{{ member.color }};" href="/member/{{ member.username }}">{{ member.username }}</a> ({{ member.months_due() }} months due)
|
||||
|
@ -28,5 +30,5 @@
|
|||
| <a href="/member/{{ member.username }}/activate">activate</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</ol>
|
||||
{% endblock %}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<h3>Transfers...</h3>
|
||||
<ul>
|
||||
{% for member_transfer in member.transfers %}
|
||||
<li>{{member_transfer.year}}/{{member_transfer.month}} - <b>{{ member_transfer.transfer.amount/100 }}PLN</b> (transfer „ {{member_transfer.transfer.title}}” at {{member_transfer.transfer.date}} from {{member_transfer.transfer.from_account}})</li>
|
||||
<li>{{member_transfer.year}}/{{member_transfer.month}} - <b>{{ member_transfer.transfer.amount/100 }}PLN</b> (transfer „ {{member_transfer.transfer.title}}” at {{member_transfer.transfer.date}} from {{member_transfer.transfer.name_from}})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
|
|
@ -251,6 +251,7 @@ Hackerspace'owy Kasownik
|
|||
#f = open("/tmp/spamspamspam", "a")
|
||||
#f.write(msg.as_string())
|
||||
#f.close()
|
||||
p = Popen(["/usr/sbin/sendmail", "-t"], stdin=PIPE)
|
||||
p.communicate(msg.as_string())
|
||||
#p = Popen(["/usr/sbin/sendmail", "-t"], stdin=PIPE)
|
||||
#p.communicate(msg.as_string())
|
||||
pass
|
||||
return "done!"
|
||||
|
|
Loading…
Reference in New Issue