Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Project-wide PEP8ification.

  • Loading branch information...
commit 25f7d447623422a413a7731c5f5d34bda396f8dd 1 parent 40c2668
@chmarr authored
Showing with 1,963 additions and 1,833 deletions.
  1. +57 −59 artshow-utils/overgrid.py
  2. +4 −1 artshow/__init__.py
  3. +20 −16 artshow/admin.py
  4. +96 −80 artshow/bidderreg.py
  5. +24 −25 artshow/bidsheets.py
  6. +1 −1  artshow/cashier.py
  7. +98 −92 artshow/cheques.py
  8. +1 −0  artshow/context_processors.py
  9. +168 −160 artshow/csvreports.py
  10. +102 −95 artshow/manage.py
  11. +8 −8 artshow/manage_urls.py
  12. +22 −22 artshow/management/commands/artshowctl.py
  13. +90 −80 artshow/management/commands/artshowtestdata.py
  14. +15 −14 artshow/management/commands/printinvoice.py
  15. +40 −38 artshow/management/commands/scannerreader.py
  16. +95 −86 artshow/mod11codes.py
  17. +6 −4 artshow/models.py
  18. +127 −119 artshow/pdfreports.py
  19. +10 −8 artshow/preprint_dummy.py
  20. +282 −276 artshow/processbatchscan.py
  21. +194 −175 artshow/reports.py
  22. +1 −0  artshow/tests.py
  23. +37 −37 artshow/urls.py
  24. +51 −48 artshow/utils.py
  25. +23 −20 artshow/views.py
  26. +117 −120 artshow/voice_auction.py
  27. +14 −14 artshowjockey/common_settings.py
  28. +8 −9 artshowjockey/urls.py
  29. +9 −6 peeps/admin.py
  30. +33 −30 peeps/lookups.py
  31. +100 −93 peeps/management/commands/importpeeps.py
  32. +7 −6 peeps/urls.py
  33. +43 −40 tinyreg/captcha.py
  34. +7 −5 tinyreg/context_processors.py
  35. +28 −29 tinyreg/forms.py
  36. +25 −17 tinyreg/urls.py
View
116 artshow-utils/overgrid.py
@@ -6,76 +6,74 @@
"""
cli_defaults = {
- 'lpi': 10,
- }
+ 'lpi': 10,
+}
cli_usage = "%prog infile"
cli_description = """\
Read in a PDF file and overlay a 0.1" grid on top of it. Writes to stdout.
"""
+import optparse
+import sys
+
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.units import inch
-from reportlab.lib.styles import getSampleStyleSheet, TA_CENTER, ParagraphStyle
-from reportlab.platypus import Paragraph, Frame
from reportlab.lib.pagesizes import letter
-
from pdfrw import PdfReader
from pdfrw.buildxobj import pagexobj
from pdfrw.toreportlab import makerl
-import optparse
-import sys
-def grid_overlay ( infile, outfile=sys.stdout, pagesize=letter, lpi=10 ):
-
- """Read PDF file 'infile'. Generates a new PDF file to 'outfile'
- containing the first page (only) of infile, with a 'lpi' grid
- overlaid.
- """
-
- c = Canvas ( outfile, pagesize=pagesize )
-
- pdf = PdfReader ( infile )
- xobj = pagexobj ( pdf.pages[0] )
- rlobj = makerl ( c, xobj )
-
- c.doForm ( rlobj )
-
- xmax = 9
- ymax = 12
-
- thickline = 0.5
- thinline = 0.1
-
- for x in range( 0, xmax ):
- c.setLineWidth ( thickline )
- for xx in range ( 0, lpi ):
- x0 = (x+(float(xx)/lpi))*inch
- c.line ( x0, 0, x0, ymax*inch )
- c.setLineWidth ( thinline )
-
- for y in range( 0, ymax ):
- c.setLineWidth ( thickline )
- for yy in range ( 0, lpi ):
- y0 = (y+(float(yy)/lpi))*inch
- c.line ( 0, y0, xmax*inch, y0 )
- c.setLineWidth ( thinline )
-
- c.showPage ()
- c.save ()
-
-
-def get_options ():
- parser = optparse.OptionParser ( usage=cli_usage, description=cli_description )
- parser.set_defaults ( **cli_defaults )
- parser.add_option ( "--lpi", type="int", help="lines per inch [%default]")
- opts, args = parser.parse_args ()
- try:
- opts.file = args[0]
- except IndexError:
- raise parser.error ( "Missing argument" )
- return opts
-
+def grid_overlay(infile, outfile=sys.stdout, pagesize=letter, lpi=10):
+ """Read PDF file 'infile'. Generates a new PDF file to 'outfile'
+ containing the first page (only) of infile, with a 'lpi' grid
+ overlaid.
+ """
+
+ c = Canvas(outfile, pagesize=pagesize)
+
+ pdf = PdfReader(infile)
+ xobj = pagexobj(pdf.pages[0])
+ rlobj = makerl(c, xobj)
+
+ c.doForm(rlobj)
+
+ xmax = 9
+ ymax = 12
+
+ thickline = 0.5
+ thinline = 0.1
+
+ for x in range(0, xmax):
+ c.setLineWidth(thickline)
+ for xx in range(0, lpi):
+ x0 = (x + (float(xx) / lpi)) * inch
+ c.line(x0, 0, x0, ymax * inch)
+ c.setLineWidth(thinline)
+
+ for y in range(0, ymax):
+ c.setLineWidth(thickline)
+ for yy in range(0, lpi):
+ y0 = (y + (float(yy) / lpi)) * inch
+ c.line(0, y0, xmax * inch, y0)
+ c.setLineWidth(thinline)
+
+ c.showPage()
+ c.save()
+
+
+def get_options():
+ parser = optparse.OptionParser(usage=cli_usage, description=cli_description)
+ parser.set_defaults(**cli_defaults)
+ parser.add_option("--lpi", type="int", help="lines per inch [%default]")
+ opts, args = parser.parse_args()
+ try:
+ opts.file = args[0]
+ except IndexError:
+ raise parser.error("Missing argument")
+ return opts
+
+
if __name__ == "__main__":
- opts = get_options ()
- grid_overlay ( opts.file, lpi=opts.lpi )
+ opts = get_options()
+ grid_overlay(opts.file, lpi=opts.lpi)
View
5 artshow/__init__.py
@@ -1,6 +1,8 @@
from south.signals import post_migrate
-def update_permissions_after_migration(app,**kwargs):
+
+# noinspection PyUnusedLocal
+def update_permissions_after_migration(app, **kwargs):
"""
Update app permission just after every migration.
This is based on app django_extensions update_permissions management command.
@@ -11,4 +13,5 @@ def update_permissions_after_migration(app,**kwargs):
create_permissions(get_app(app), get_models(), 2 if settings.DEBUG else 0)
+
post_migrate.connect(update_permissions_after_migration)
View
36 artshow/admin.py
@@ -12,7 +12,9 @@
import email1
import processbatchscan
from django.core.mail import send_mail
-import smtplib, datetime, decimal
+import smtplib
+import datetime
+import decimal
from django.http import HttpResponse
from ajax_select import make_ajax_form
from ajax_select.admin import AjaxSelectAdmin
@@ -20,11 +22,10 @@
from django.db.models import Max
-
class ArtistAccessInline(admin.TabularInline):
model = ArtistAccess
extra = 0
- raw_id_fields = ( 'user', )
+ raw_id_fields = ('user', )
class AllocationInlineForm(forms.ModelForm):
@@ -45,7 +46,7 @@ class AllocationInline(admin.TabularInline):
class PieceInlineForm(forms.ModelForm):
class Meta:
model = Piece
- fields = ( "pieceid", "name", "media", "adult", "not_for_sale", "min_bid", "buy_now", "location",
+ fields = ("pieceid", "name", "media", "adult", "not_for_sale", "min_bid", "buy_now", "location",
"voice_auction", "status")
widgets = {
'pieceid': forms.TextInput(attrs={'size': 3}),
@@ -60,7 +61,7 @@ class Meta:
class PieceInline(admin.TabularInline):
form = PieceInlineForm
fields = ("pieceid", "name", "media", "adult", "not_for_sale", "min_bid", "buy_now", "location", "voice_auction",
- "status")
+ "status")
model = Piece
extra = 5
ordering = ('pieceid',)
@@ -118,10 +119,10 @@ class ArtistAdmin(AjaxSelectAdmin):
def requested_spaces(self, artist):
return ", ".join("%s:%s" % (al.space.shortname, al.requested) for al in artist.allocation_set.all())
- def allocated_spaces( self, artist ):
+ def allocated_spaces(self, artist):
return ", ".join("%s:%s" % (al.space.shortname, al.allocated) for al in artist.allocation_set.all())
- def person_name( self, artist ):
+ def person_name(self, artist):
return artist.person.name
person_name.short_description = "name"
@@ -138,7 +139,7 @@ def person_mailing_label(self, artist):
person_mailing_label.short_description = "mailing address"
person_mailing_label.allow_tags = True
- def send_email( self, request, queryset ):
+ def send_email(self, request, queryset):
opts = self.model._meta
app_label = opts.app_label
emails = []
@@ -193,8 +194,7 @@ def print_bidsheets(self, request, queryset):
import bidsheets
response = HttpResponse(mimetype="application/pdf")
- bidsheets.generate_bidsheets_for_artists(template_pdf=settings.ARTSHOW_BLANK_BID_SHEET, output=response,
- artists=queryset)
+ bidsheets.generate_bidsheets_for_artists(output=response, artists=queryset)
self.message_user(request, "Bid sheets printed.")
return response
@@ -214,8 +214,7 @@ def print_control_forms( self, request, artists ):
import bidsheets
response = HttpResponse(mimetype="application/pdf")
- bidsheets.generate_control_forms(template_pdf=settings.ARTSHOW_BLANK_CONTROL_FORM, output=response,
- artists=artists)
+ bidsheets.generate_control_forms(output=response, artists=artists)
self.message_user(request, "Control Forms printed.")
return response
@@ -274,7 +273,8 @@ def apply_winnings_and_commission(self, request, artists):
date=datetime.datetime.now())
payment.save()
- def create_cheques( self, request, artists):
+ # noinspection PyUnusedLocal
+ def create_cheques(self, request, artists):
pt_paymentsent = PaymentType.objects.get(pk=settings.ARTSHOW_PAYMENT_SENT_PK)
for a in artists:
balance = a.payment_set.aggregate(balance=Sum('amount'))['balance']
@@ -284,6 +284,7 @@ def create_cheques( self, request, artists):
chq.clean()
chq.save()
+ # noinspection PyUnusedLocal
def allocate_spaces(self, request, artists):
artists = artists.order_by('reservationdate', 'artistid')
spaces_remaining = {}
@@ -400,14 +401,15 @@ def set_scanned_flag(self, request, pieces):
pieces.exclude(status=Piece.StatusNotInShow).update(bidsheet_scanned=True)
self.message_user(request, "Bidsheet_scanned flags have been set if the piece is or was in show.")
- def clear_won_status( self, request, pieces ):
+ def clear_won_status(self, request, pieces):
pieces.filter(status=Piece.StatusWon).update(status=Piece.StatusInShow)
self.message_user(request, "Pieces marked as 'Won' have been returned to 'In Show'.")
- def apply_won_status( self, request, pieces ):
+ def apply_won_status(self, request, pieces):
# This code is duplicated in the management code
for p in pieces.filter(status=Piece.StatusInShow, voice_auction=False):
try:
+ # noinspection PyUnusedLocal
top_bid = p.top_bid()
except Bid.DoesNotExist:
pass
@@ -420,6 +422,7 @@ def apply_won_status( self, request, pieces ):
def apply_won_status_incl_voice_auction(self, request, pieces):
for p in pieces.filter(status=Piece.StatusInShow):
try:
+ # noinspection PyUnusedLocal
top_bid = p.top_bid()
except Bid.DoesNotExist:
pass
@@ -436,7 +439,7 @@ def print_bidsheets(self, request, queryset):
import bidsheets
response = HttpResponse(mimetype="application/pdf")
- bidsheets.generate_bidsheets(template_pdf=settings.ARTSHOW_BLANK_BID_SHEET, output=response, pieces=queryset)
+ bidsheets.generate_bidsheets(output=response, pieces=queryset)
self.message_user(request, "Bid sheets printed.")
return response
@@ -648,6 +651,7 @@ class ChequePaymentAdmin(admin.ModelAdmin):
def cheque_amount(self, obj):
return -obj.amount
+ # noinspection PyUnusedLocal
def print_cheques(self, request, cheqs):
import cheques
View
176 artshow/bidderreg.py
@@ -4,84 +4,100 @@
from django.conf import settings
from artshow.models import Person, Bidder, BidderId
-class BidderRegistrationForm0 ( forms.Form ):
- pass
-
-class BidderRegistrationForm1 ( forms.Form ):
- name = forms.CharField ( max_length=100, help_text = "Your real, first and last name. This should match your identification." )
- reg_id = forms.CharField ( max_length=20, help_text = "The number on the front of your convention badge. It looks like 123-456, and may have fewer or more digits. Enter the dash, too." )
- cell_contact = forms.CharField ( max_length=40, required=False,
- help_text = "If you have one, provide your cell number or that of a friend." )
- other_contact = forms.CharField ( max_length=100, required=False,
- help_text = "Optionally, another way to contact you during the convention, such as your hotel and room number." )
- details_changed = forms.BooleanField ( initial=False, required=False,
- help_text = "When you registered at the convention, you provided your address and e-mail. Have these changed since then?" )
-
- def clean ( self ):
- cleaned_data = super(BidderRegistrationForm1, self).clean ()
- cell_contact = cleaned_data.get("cell_contact")
- other_contact = cleaned_data.get("other_contact")
- if cell_contact == "" and other_contact == "":
- raise forms.ValidationError ( "Please enter at least one way to contact you at the show." )
- reg_id = cleaned_data.get("reg_id")
- if not settings.ARTSHOW_REGID_NONUNIQUE:
- matched_people = Person.objects.filter ( reg_id=reg_id )
- if BidderId.objects.filter ( bidder__person__in = matched_people ).exists ():
- raise forms.ValidationError ( "We think you have already been issued a Bidder ID. If this is unexpected, please see Staff immediately" )
- return cleaned_data
-
-class BidderRegistrationForm2 ( forms.Form ):
- address1 = forms.CharField ( max_length = 100, required=False )
- address2 = forms.CharField ( max_length = 100, required=False )
- city = forms.CharField ( max_length = 100, required=False )
- state = forms.CharField ( max_length = 40, required=False )
- postcode = forms.CharField ( max_length = 20, required=False )
- country = forms.CharField ( max_length = 40, required=False )
- phone = forms.CharField ( max_length = 40, required=False )
- email = forms.CharField ( max_length = 100, required=False )
-
+
+class BidderRegistrationForm0(forms.Form):
+ pass
+
+
+class BidderRegistrationForm1(forms.Form):
+ name = forms.CharField(max_length=100,
+ help_text="Your real, first and last name. This should match your identification.")
+ reg_id = forms.CharField(max_length=20,
+ help_text="The number on the front of your convention badge. It looks like 123-456, and may have fewer or more digits. Enter the dash, too.")
+ cell_contact = forms.CharField(max_length=40, required=False,
+ help_text="If you have one, provide your cell number or that of a friend.")
+ other_contact = forms.CharField(max_length=100, required=False,
+ help_text="Optionally, another way to contact you during the convention, such as your hotel and room number.")
+ details_changed = forms.BooleanField(initial=False, required=False,
+ help_text="When you registered at the convention, you provided your address and e-mail. Have these changed since then?")
+
+ def clean(self):
+ cleaned_data = super(BidderRegistrationForm1, self).clean()
+ cell_contact = cleaned_data.get("cell_contact")
+ other_contact = cleaned_data.get("other_contact")
+ if cell_contact == "" and other_contact == "":
+ raise forms.ValidationError("Please enter at least one way to contact you at the show.")
+ reg_id = cleaned_data.get("reg_id")
+ if not settings.ARTSHOW_REGID_NONUNIQUE:
+ matched_people = Person.objects.filter(reg_id=reg_id)
+ if BidderId.objects.filter(bidder__person__in=matched_people).exists():
+ raise forms.ValidationError(
+ "We think you have already been issued a Bidder ID. If this is unexpected, please see Staff immediately")
+ return cleaned_data
+
+
+class BidderRegistrationForm2(forms.Form):
+ address1 = forms.CharField(max_length=100, required=False)
+ address2 = forms.CharField(max_length=100, required=False)
+ city = forms.CharField(max_length=100, required=False)
+ state = forms.CharField(max_length=40, required=False)
+ postcode = forms.CharField(max_length=20, required=False)
+ country = forms.CharField(max_length=40, required=False)
+ phone = forms.CharField(max_length=40, required=False)
+ email = forms.CharField(max_length=100, required=False)
+
+
+# noinspection PyUnusedLocal
def do_print_bidder_registration_form(person):
- pass
-
-class BidderRegistrationWizard ( CookieWizardView ):
- template_name = "artshow/bidderreg_wizard.html"
-
- def done ( self, form_list, **kwargs ):
-
- p = None
- for form in form_list:
- cleaned_data = form.cleaned_data
- if isinstance( form, BidderRegistrationForm1 ):
- p = Person (
- name = cleaned_data['name'],
- reg_id = cleaned_data['reg_id'],
- )
- cell_contact = cleaned_data.get('cell_contact','')
- other_contact = cleaned_data.get('other_contact','')
- at_con_contact = "\n".join ( ( x for x in [cell_contact,other_contact] if x ) )
- b = Bidder ( at_con_contact=at_con_contact )
- elif isinstance ( form, BidderRegistrationForm2 ):
- p.address1 = cleaned_data.get('address1','')
- p.address2 = cleaned_data.get('address2','')
- p.city = cleaned_data.get('city','')
- p.state = cleaned_data.get('state','')
- p.postcode = cleaned_data.get('postcode','')
- p.country = cleaned_data.get('country','')
- p.phone = cleaned_data.get('phone','')
- p.email = cleaned_data.get('email','')
- p.save()
- b.person = p
- b.save()
- do_print_bidder_registration_form ( p )
- return redirect ( final )
-
-def final ( request ):
- return render ( request, "artshow/bidderreg_final.html" )
-
-def process_step_2 ( wizard ):
- cleaned_data = wizard.get_cleaned_data_for_step('1') or {}
- return cleaned_data.get('details_changed',False)
-
-bidderreg_wizard_view = BidderRegistrationWizard.as_view ( [BidderRegistrationForm0,BidderRegistrationForm1,BidderRegistrationForm2],
- condition_dict={'2':process_step_2} )
-
+ pass
+
+
+class BidderRegistrationWizard(CookieWizardView):
+ template_name = "artshow/bidderreg_wizard.html"
+
+ def done(self, form_list, **kwargs):
+
+ p = b = None
+ for form in form_list:
+ cleaned_data = form.cleaned_data
+ if isinstance(form, BidderRegistrationForm1):
+ p = Person(
+ name=cleaned_data['name'],
+ reg_id=cleaned_data['reg_id'],
+ )
+ cell_contact = cleaned_data.get('cell_contact', '')
+ other_contact = cleaned_data.get('other_contact', '')
+ at_con_contact = "\n".join((x for x in [cell_contact, other_contact] if x))
+ b = Bidder(at_con_contact=at_con_contact)
+ elif isinstance(form, BidderRegistrationForm2):
+ p.address1 = cleaned_data.get('address1', '')
+ p.address2 = cleaned_data.get('address2', '')
+ p.city = cleaned_data.get('city', '')
+ p.state = cleaned_data.get('state', '')
+ p.postcode = cleaned_data.get('postcode', '')
+ p.country = cleaned_data.get('country', '')
+ p.phone = cleaned_data.get('phone', '')
+ p.email = cleaned_data.get('email', '')
+ if b is None:
+ raise forms.ValidationError("End of wizard without creating bidder.")
+ if p is None:
+ raise forms.ValidationError("End of wizard without creating person.")
+ p.save()
+ b.person = p
+ b.save()
+ do_print_bidder_registration_form(p)
+ return redirect(final)
+
+
+def final(request):
+ return render(request, "artshow/bidderreg_final.html")
+
+
+def process_step_2(wizard):
+ cleaned_data = wizard.get_cleaned_data_for_step('1') or {}
+ return cleaned_data.get('details_changed', False)
+
+
+bidderreg_wizard_view = BidderRegistrationWizard.as_view(
+ [BidderRegistrationForm0, BidderRegistrationForm1, BidderRegistrationForm2],
+ condition_dict={'2': process_step_2})
View
49 artshow/bidsheets.py
@@ -3,28 +3,27 @@
from django.conf import settings
from models import Piece
-preprint = __import__ ( settings.ARTSHOW_PREPRINT_MODULE, globals(), locals(), ['bid_sheets','control_forms','piece_stickers','mailing_labels'] )
-
-def generate_bidsheets_for_artists ( template_pdf, output, artists ):
- pieces = Piece.objects.filter ( artist__in=artists ).order_by ( 'artist__artistid', 'pieceid' )
- preprint.bid_sheets ( pieces, output )
-
-
-def generate_bidsheets ( template_pdf, output, pieces ):
- preprint.bid_sheets ( pieces, output )
-
-
-def generate_mailing_labels ( output, artists ):
- preprint.mailing_labels ( artists, output )
-
-
-def generate_control_forms ( template_pdf, output, artists ):
- """Write a pdf file to 'output' using 'template_pdf' as a template,
- and generate control forms (one or more pages each) for 'artists'.
- """
- pieces = Piece.objects.filter ( artist__in=artists ).order_by ( 'artist__artistid','pieceid' )
- preprint.control_forms ( pieces, output )
-
-
-def generate_piece_stickers ( output, pieces ):
- preprint.piece_stickers ( pieces, output )
+preprint = __import__(settings.ARTSHOW_PREPRINT_MODULE, globals(), locals(),
+ ['bid_sheets', 'control_forms', 'piece_stickers', 'mailing_labels'])
+
+
+def generate_bidsheets_for_artists(output, artists):
+ pieces = Piece.objects.filter(artist__in=artists).order_by('artist__artistid', 'pieceid')
+ preprint.bid_sheets(pieces, output)
+
+
+def generate_bidsheets(output, pieces):
+ preprint.bid_sheets(pieces, output)
+
+
+def generate_mailing_labels(output, artists):
+ preprint.mailing_labels(artists, output)
+
+
+def generate_control_forms(output, artists):
+ pieces = Piece.objects.filter(artist__in=artists).order_by('artist__artistid', 'pieceid')
+ preprint.control_forms(pieces, output)
+
+
+def generate_piece_stickers(output, pieces):
+ preprint.piece_stickers(pieces, output)
View
2  artshow/cashier.py
@@ -61,8 +61,8 @@ def clean_amount(self):
class PaymentFormSet (BaseModelFormSet):
def clean(self):
-# super(PaymentFormSet,self).clean()
total = sum([form.cleaned_data['amount'] for form in self.forms], Decimal(0))
+ # self.items_total is set from the cashier_bidder function.
if total != self.items_total:
raise ValidationError("payments (%s) must equal invoice total (%s)" % (total, self.items_total))
View
190 artshow/cheques.py
@@ -3,114 +3,120 @@
# Copyright (C) 2009-2012 Chris Cogdon
# See file COPYING for licence details
-import sys, os, re, num2word, time, optparse
from decimal import Decimal
-from artshow.models import Artist
-from email1 import wrap
+
from django.conf import settings
+import num2word
+from email1 import wrap
+
+
class PRINT_GRID:
- x_size = 87
- y_size = 66
- def __init__ ( self ):
- self.data = [ " "*self.x_size for i in range(self.y_size) ]
- def print_at ( self, x, y, msg ):
- if x + len(msg) - 1 > self.x_size:
- raise Exception ( "line too long" )
- msg_len = len(msg)
- s = self.data[y-1]
- s = s[:x-1] + msg + s[x-1+msg_len:]
- self.data[y-1] = s
- self.last_line_printed = y
- def print_on_next_line ( self, msg ):
- self.print_at ( 1, self.last_line_printed+1, msg )
- def save ( self, f ):
- for line in self.data:
- print >>f, line
-
-def dotpad ( s, max ):
- l = len(s)
- if l >= max:
- return s
- s += " " * (( max-l ) % 4)
- s += " .." * ((max-l) / 4 )
- return s
-
-
-def cheque_to_text ( cheque, f ):
-
- date_str = cheque.date.strftime ( "%d %b %Y" ).upper()
-
- cheque_amount = -cheque.amount
+ x_size = 87
+ y_size = 66
- cheque_dollars = int(cheque_amount)
- cheque_cents = int ((cheque_amount - cheque_dollars) * 100 + Decimal("0.5") )
+ def __init__(self):
+ # noinspection PyUnusedLocal
+ self.data = [" " * self.x_size for i in range(self.y_size)]
- cheque_words = "** " + num2word.n2w.to_cardinal ( cheque_dollars ) + " dollars and %d cents" % cheque_cents + " **"
- cheque_words = cheque_words.upper ()
-
- person = cheque.artist.person
+ def print_at(self, x, y, msg):
+ if x + len(msg) - 1 > self.x_size:
+ raise Exception("line too long")
+ msg_len = len(msg)
+ s = self.data[y - 1]
+ s = s[:x - 1] + msg + s[x - 1 + msg_len:]
+ self.data[y - 1] = s
+ self.last_line_printed = y
- grid = PRINT_GRID ()
+ def print_on_next_line(self, msg):
+ self.print_at(1, self.last_line_printed + 1, msg)
- grid.print_at ( 77, 3, date_str )
+ def save(self, f):
+ for line in self.data:
+ print >> f, line
- grid.print_at ( 8, 7, cheque.payee.upper() )
- grid.print_at ( 77, 7, "$%-8.2f" % cheque_amount )
- grid.print_at ( 1, 9, cheque_words )
+def dotpad(s, max):
+ l = len(s)
+ if l >= max:
+ return s
+ s += " " * ((max - l) % 4)
+ s += " .." * ((max - l) / 4)
+ return s
- mailing_label_lines = [ cheque.payee, person.address1 ]
- if person.address2:
- mailing_label_lines.append ( person.address2 )
- mailing_label_lines.append ( "%s %s %s" % ( person.city, person.state, person.postcode ) )
- if person.country and person.country != "USA":
- mailing_label_lines.append ( person.country )
- mailing_label_lines = [ x.upper() for x in mailing_label_lines ]
-
- for i in range(len(mailing_label_lines)):
- grid.print_at ( 9, 14+i, mailing_label_lines[i] )
-
- print_items ( cheque, grid, 23, True )
- print_items ( cheque, grid, 46, False )
- grid.save ( f )
+def cheque_to_text(cheque, f):
+ date_str = cheque.date.strftime("%d %b %Y").upper()
+ cheque_amount = -cheque.amount
-def print_items ( cheque, grid, offset, payee_side ):
+ cheque_dollars = int(cheque_amount)
+ cheque_cents = int((cheque_amount - cheque_dollars) * 100 + Decimal("0.5"))
- date_str = cheque.date.strftime ( "%d %b %Y" ).upper()
-
- s = "(%d) %s" % ( cheque.artist.artistid, cheque.artist.person.name )
- if cheque.artist.publicname:
- s += " (%s)" % cheque.artist.publicname
+ cheque_words = "** " + num2word.n2w.to_cardinal(cheque_dollars) + " dollars and %d cents" % cheque_cents + " **"
+ cheque_words = cheque_words.upper()
- grid.print_at ( 1, offset, s )
- grid.print_at ( 77, offset, date_str )
+ person = cheque.artist.person
- grid.last_line_printed = offset+1
-
- item_no = 0
- for item in cheque.artist.payment_set.all().order_by ( 'date', 'id' ):
- item_no += 1
- if item.id == cheque.id:
- name = dotpad ( "This cheque", 71 )
- else:
- name = dotpad ( "%s: %s" % ( item.payment_type.name, item.description), 71 )[:71]
- grid.print_on_next_line ( " %2d. %-71s $%8.2f" % ( item_no, name, item.amount ) )
-
- grid.print_on_next_line ( " %71s $%8.2f" % ( "Balance:", cheque.artist.balance() ) )
-
- if payee_side:
- grid.print_on_next_line ( "" )
- message = wrap ( settings.ARTSHOW_CHEQUE_THANK_YOU, cols=78, always_wrap=True )
- message_lines = message.split ( "\n" )
- for l in message_lines:
- grid.print_on_next_line ( l )
-
- else:
- grid.print_on_next_line ( "" )
- grid.print_on_next_line ( "Signature: _____________________________________________ Date: __________" )
- grid.print_on_next_line ( "I have received this cheque and agree to return any amount paid in error." )
+ grid = PRINT_GRID()
+
+ grid.print_at(77, 3, date_str)
+
+ grid.print_at(8, 7, cheque.payee.upper())
+ grid.print_at(77, 7, "$%-8.2f" % cheque_amount)
+
+ grid.print_at(1, 9, cheque_words)
+
+ mailing_label_lines = [cheque.payee, person.address1]
+ if person.address2:
+ mailing_label_lines.append(person.address2)
+ mailing_label_lines.append("%s %s %s" % (person.city, person.state, person.postcode))
+ if person.country and person.country != "USA":
+ mailing_label_lines.append(person.country)
+ mailing_label_lines = [x.upper() for x in mailing_label_lines]
+
+ for i in range(len(mailing_label_lines)):
+ grid.print_at(9, 14 + i, mailing_label_lines[i])
+
+ print_items(cheque, grid, 23, True)
+ print_items(cheque, grid, 46, False)
+
+ grid.save(f)
+
+
+def print_items( cheque, grid, offset, payee_side ):
+ date_str = cheque.date.strftime("%d %b %Y").upper()
+
+ s = "(%d) %s" % ( cheque.artist.artistid, cheque.artist.person.name )
+ if cheque.artist.publicname:
+ s += " (%s)" % cheque.artist.publicname
+
+ grid.print_at(1, offset, s)
+ grid.print_at(77, offset, date_str)
+
+ grid.last_line_printed = offset + 1
+
+ item_no = 0
+ for item in cheque.artist.payment_set.all().order_by('date', 'id'):
+ item_no += 1
+ if item.id == cheque.id:
+ name = dotpad("This cheque", 71)
+ else:
+ name = dotpad("%s: %s" % ( item.payment_type.name, item.description), 71)[:71]
+ grid.print_on_next_line(" %2d. %-71s $%8.2f" % ( item_no, name, item.amount ))
+
+ grid.print_on_next_line(" %71s $%8.2f" % ( "Balance:", cheque.artist.balance() ))
+
+ if payee_side:
+ grid.print_on_next_line("")
+ message = wrap(settings.ARTSHOW_CHEQUE_THANK_YOU, cols=78, always_wrap=True)
+ message_lines = message.split("\n")
+ for l in message_lines:
+ grid.print_on_next_line(l)
+
+ else:
+ grid.print_on_next_line("")
+ grid.print_on_next_line("Signature: _____________________________________________ Date: __________")
+ grid.print_on_next_line("I have received this cheque and agree to return any amount paid in error.")
View
1  artshow/context_processors.py
@@ -1,4 +1,5 @@
from artshow.utils import artshow_settings
+# noinspection PyUnusedLocal
def artshow_settings ( request ):
return { 'artshow_settings':artshow_settings }
View
328 artshow/csvreports.py
@@ -2,166 +2,174 @@
# Copyright (C) 2009-2012 Chris Cogdon
# See file COPYING for licence details
-from artshow.models import *
-from django.http import HttpResponse
import csv
+from django.http import HttpResponse
from django.contrib.auth.decorators import permission_required
+from artshow.models import *
+
-@permission_required ( 'artshow.view_artist' )
-def artists ( request ):
-
- ## TODO - This depends on the Person structure, which we want to move out into the model itself.
-
- artists = Artist.objects.all ().order_by('artistid')
- spaces = Space.objects.all ()
- checkoffs = Checkoff.objects.all()
-
- field_names = [ 'artistid', 'name', 'address1', 'address2', 'city', 'state', 'postcode',
- 'country', 'phone', 'email', 'regid', 'artistname', 'website', 'mailin', 'agent', 'reservationdate',
- 'nameforcheque' ]
-
- for space in spaces:
- field_names += [ 'req-'+space.shortname, 'alloc-'+space.shortname ]
-
- for checkoff in checkoffs:
- field_names += [ 'chk-'+checkoff.shortname ]
-
- field_names_d = {}
- for n in field_names:
- field_names_d[n] = n
-
- response = HttpResponse ( mimetype="text/csv" )
- response['Content-Disposition'] = "attachment; filename=artists.csv"
- c = csv.DictWriter ( response, field_names )
- c.writerow ( field_names_d )
-
- for a in artists:
- d = dict ( artistid=a.artistid, name=a.person.name, address1=a.person.address1, address2=a.person.address2, city=a.person.city, state=a.person.state,
- postcode=a.person.postcode, country=a.person.country, phone=a.person.phone, email=a.person.email, regid=a.person.reg_id, artistname=a.artistname(),
- website=a.website, mailin= a.mailin and "Yes" or "No", agent=", ".join ( [ p.name for p in a.agents.all() ] ),
- reservationdate=str(a.reservationdate) )
- for alloc in a.allocation_set.all():
- d['req-'+alloc.space.shortname] = str(alloc.requested)
- d['alloc-'+alloc.space.shortname] = str(alloc.allocated)
- for checkoff in a.checkoffs.all():
- d['chk-'+checkoff.shortname] = checkoff.shortname
- c.writerow ( d )
-
- return response
-
-
-@permission_required ( 'artshow.view_piece' )
-def pieces ( request ):
-
- pieces = Piece.objects.all ().order_by ( 'artist__artistid', 'pieceid' )
-
- field_names = [ 'artistid', 'pieceid', 'code', 'artistname', 'title', 'media', 'min_bid', 'buy_now', 'adult', 'not_for_sale', 'status', 'top_bid', 'bought_now', 'voice_auction', 'bidder_name', 'bidder_ids' ]
-
- field_names_d = {}
- for n in field_names:
- field_names_d[n] = n
-
- response = HttpResponse ( mimetype="text/csv" )
- response['Content-Disposition'] = "attachment; filename=pieces.csv"
- c = csv.DictWriter ( response, field_names )
- c.writerow ( field_names_d )
-
- for p in pieces:
- try:
- top_bid = p.top_bid()
- except Bid.DoesNotExist:
- top_bid = None
- d = dict ( artistid=p.artist.artistid, pieceid=p.pieceid, code=p.code, artistname=p.artist.artistname(),
- title=p.name, media=p.media, min_bid=p.min_bid, buy_now=p.buy_now, adult=p.adult and "Yes" or "No", not_for_sale=p.not_for_sale and "Yes" or "No",
- status = p.get_status_display(), top_bid=top_bid and top_bid.amount or "",
- bought_now = top_bid and ( top_bid.buy_now_bid and "Yes" or "No" ) or "",
- voice_auction = p.voice_auction and "Yes" or "No",
- bidder_name=top_bid and top_bid.bidder.name or "", bidder_ids = top_bid and (", ".join(top_bid.bidder.bidder_ids()) or "" ),
- )
- c.writerow ( d )
-
- return response
-
-
-@permission_required ( 'artshow.view_bidder' )
-def bidders ( request ):
-
- ## TODO - This depends on the Person structure, which we want to move out into the model itself.
-
- bidders = Bidder.objects.all ()
-
- field_names = [ 'primary_bidder_id', 'bidder_ids', 'name', 'address1', 'address2', 'city', 'state', 'postcode',
- 'country', 'phone', 'email', 'regid' ]
-
- field_names_d = {}
- for n in field_names:
- field_names_d[n] = n
-
- response = HttpResponse ( mimetype="text/csv" )
- response['Content-Disposition'] = "attachment; filename=bidders.csv"
- c = csv.DictWriter ( response, field_names )
- c.writerow ( field_names_d )
-
- for b in bidders:
- bidder_ids = b.bidder_ids()
- if bidder_ids:
- primary_bidder_id = bidder_ids[0]
- else:
- primary_bidder_id = ""
- d = dict ( primary_bidder_id=primary_bidder_id,
- bidder_ids = ", ".join ( bidder_ids ),
- name=b.person.name, address1=b.person.address1, address2=b.person.address2, city=b.person.city, state=b.person.state,
- postcode=b.person.postcode, country=b.person.country, phone=b.person.phone, email=b.person.email, regid=b.person.reg_id )
- c.writerow ( d )
-
- return response
-
-
-@permission_required ( 'artshow.view_payment' )
-def payments ( request ):
-
- payments = Payment.objects.all ().order_by ( 'artist__artistid', 'date' )
-
- field_names = [ 'artistid', 'name', 'artistname', 'date', 'type', 'description', 'amount' ]
-
- field_names_d = {}
- for n in field_names:
- field_names_d[n] = n
-
- response = HttpResponse ( mimetype="text/csv" )
- response['Content-Disposition'] = "attachment; filename=payments.csv"
- c = csv.DictWriter ( response, field_names )
- c.writerow ( field_names_d )
-
- for p in payments:
- d = dict (
- artistid=p.artist.artistid, name=p.artist.name, artistname=p.artist.artistname(),
- date=p.date, type=p.payment_type.name, description=p.description, amount=p.amount )
- c.writerow ( d )
-
- return response
-
-
-@permission_required ( 'artshow.view_cheque' )
-def cheques ( request ):
-
- cheques = ChequePayment.objects.all ().order_by ( 'date', 'number', 'id' )
-
- field_names = [ 'artistid', 'name', 'artistname', 'payee', 'date', 'number', 'amount' ]
-
- field_names_d = {}
- for n in field_names:
- field_names_d[n] = n
-
- response = HttpResponse ( mimetype="text/csv" )
- response['Content-Disposition'] = "attachment; filename=cheques.csv"
- c = csv.DictWriter ( response, field_names )
- c.writerow ( field_names_d )
-
- for q in cheques:
- d = dict (
- artistid=q.artist.artistid, name=q.artist.name(), artistname=q.artist.artistname(),
- payee=q.payee, date=q.date, number=q.number, amount=-q.amount )
- c.writerow ( d )
-
- return response
+@permission_required('artshow.view_artist')
+def artists(request):
+ ## TODO - This depends on the Person structure, which we want to move out into the model itself.
+
+ artists = Artist.objects.all().order_by('artistid')
+ spaces = Space.objects.all()
+ checkoffs = Checkoff.objects.all()
+
+ field_names = ['artistid', 'name', 'address1', 'address2', 'city', 'state', 'postcode',
+ 'country', 'phone', 'email', 'regid', 'artistname', 'website', 'mailin', 'agent', 'reservationdate',
+ 'nameforcheque']
+
+ for space in spaces:
+ field_names += ['req-' + space.shortname, 'alloc-' + space.shortname]
+
+ for checkoff in checkoffs:
+ field_names += ['chk-' + checkoff.shortname]
+
+ field_names_d = {}
+ for n in field_names:
+ field_names_d[n] = n
+
+ response = HttpResponse(mimetype="text/csv")
+ response['Content-Disposition'] = "attachment; filename=artists.csv"
+ c = csv.DictWriter(response, field_names)
+ c.writerow(field_names_d)
+
+ for a in artists:
+ d = dict(artistid=a.artistid, name=a.person.name, address1=a.person.address1, address2=a.person.address2,
+ city=a.person.city, state=a.person.state,
+ postcode=a.person.postcode, country=a.person.country, phone=a.person.phone, email=a.person.email,
+ regid=a.person.reg_id, artistname=a.artistname(),
+ website=a.website, mailin=a.mailin and "Yes" or "No",
+ agent=", ".join([p.name for p in a.agents.all()]),
+ reservationdate=str(a.reservationdate))
+ for alloc in a.allocation_set.all():
+ d['req-' + alloc.space.shortname] = str(alloc.requested)
+ d['alloc-' + alloc.space.shortname] = str(alloc.allocated)
+ for checkoff in a.checkoffs.all():
+ d['chk-' + checkoff.shortname] = checkoff.shortname
+ c.writerow(d)
+
+ return response
+
+
+# noinspection PyUnusedLocal
+@permission_required('artshow.view_piece')
+def pieces(request):
+ pieces = Piece.objects.all().order_by('artist__artistid', 'pieceid')
+
+ field_names = ['artistid', 'pieceid', 'code', 'artistname', 'title', 'media', 'min_bid', 'buy_now', 'adult',
+ 'not_for_sale', 'status', 'top_bid', 'bought_now', 'voice_auction', 'bidder_name', 'bidder_ids']
+
+ field_names_d = {}
+ for n in field_names:
+ field_names_d[n] = n
+
+ response = HttpResponse(mimetype="text/csv")
+ response['Content-Disposition'] = "attachment; filename=pieces.csv"
+ c = csv.DictWriter(response, field_names)
+ c.writerow(field_names_d)
+
+ for p in pieces:
+ try:
+ top_bid = p.top_bid()
+ except Bid.DoesNotExist:
+ top_bid = None
+ d = dict(artistid=p.artist.artistid, pieceid=p.pieceid, code=p.code, artistname=p.artist.artistname(),
+ title=p.name, media=p.media, min_bid=p.min_bid, buy_now=p.buy_now, adult=p.adult and "Yes" or "No",
+ not_for_sale=p.not_for_sale and "Yes" or "No",
+ status=p.get_status_display(), top_bid=top_bid and top_bid.amount or "",
+ bought_now=top_bid and (top_bid.buy_now_bid and "Yes" or "No") or "",
+ voice_auction=p.voice_auction and "Yes" or "No",
+ bidder_name=top_bid and top_bid.bidder.name or "",
+ bidder_ids=top_bid and (", ".join(top_bid.bidder.bidder_ids()) or ""),
+ )
+ c.writerow(d)
+
+ return response
+
+
+# noinspection PyUnusedLocal
+@permission_required('artshow.view_bidder')
+def bidders(request):
+ ## TODO - This depends on the Person structure, which we want to move out into the model itself.
+
+ bidders = Bidder.objects.all()
+
+ field_names = ['primary_bidder_id', 'bidder_ids', 'name', 'address1', 'address2', 'city', 'state', 'postcode',
+ 'country', 'phone', 'email', 'regid']
+
+ field_names_d = {}
+ for n in field_names:
+ field_names_d[n] = n
+
+ response = HttpResponse(mimetype="text/csv")
+ response['Content-Disposition'] = "attachment; filename=bidders.csv"
+ c = csv.DictWriter(response, field_names)
+ c.writerow(field_names_d)
+
+ for b in bidders:
+ bidder_ids = b.bidder_ids()
+ if bidder_ids:
+ primary_bidder_id = bidder_ids[0]
+ else:
+ primary_bidder_id = ""
+ d = dict(primary_bidder_id=primary_bidder_id,
+ bidder_ids=", ".join(bidder_ids),
+ name=b.person.name, address1=b.person.address1, address2=b.person.address2, city=b.person.city,
+ state=b.person.state,
+ postcode=b.person.postcode, country=b.person.country, phone=b.person.phone, email=b.person.email,
+ regid=b.person.reg_id)
+ c.writerow(d)
+
+ return response
+
+
+# noinspection PyUnusedLocal
+@permission_required('artshow.view_payment')
+def payments(request):
+ payments = Payment.objects.all().order_by('artist__artistid', 'date')
+
+ field_names = ['artistid', 'name', 'artistname', 'date', 'type', 'description', 'amount']
+
+ field_names_d = {}
+ for n in field_names:
+ field_names_d[n] = n
+
+ response = HttpResponse(mimetype="text/csv")
+ response['Content-Disposition'] = "attachment; filename=payments.csv"
+ c = csv.DictWriter(response, field_names)
+ c.writerow(field_names_d)
+
+ for p in payments:
+ d = dict(
+ artistid=p.artist.artistid, name=p.artist.name, artistname=p.artist.artistname(),
+ date=p.date, type=p.payment_type.name, description=p.description, amount=p.amount)
+ c.writerow(d)
+
+ return response
+
+
+# noinspection PyUnusedLocal
+@permission_required('artshow.view_cheque')
+def cheques(request):
+ cheques = ChequePayment.objects.all().order_by('date', 'number', 'id')
+
+ field_names = ['artistid', 'name', 'artistname', 'payee', 'date', 'number', 'amount']
+
+ field_names_d = {}
+ for n in field_names:
+ field_names_d[n] = n
+
+ response = HttpResponse(mimetype="text/csv")
+ response['Content-Disposition'] = "attachment; filename=cheques.csv"
+ c = csv.DictWriter(response, field_names)
+ c.writerow(field_names_d)
+
+ for q in cheques:
+ d = dict(
+ artistid=q.artist.artistid, name=q.artist.name(), artistname=q.artist.artistname(),
+ payee=q.payee, date=q.date, number=q.number, amount=-q.amount)
+ c.writerow(d)
+
+ return response
View
197 artshow/manage.py
@@ -2,122 +2,129 @@
from artshow.models import *
from django import forms
from django.contrib.auth.decorators import login_required
-from django.forms.models import modelformset_factory, inlineformset_factory
+from django.forms.models import inlineformset_factory
from django.http import HttpResponse
from django.core.urlresolvers import reverse
from django.contrib import messages
from artshow.utils import artshow_settings
import utils
-import csv
import re
import bidsheets
EXTRA_PIECES = 5
+
@login_required
-def index ( request ):
- artists = Artist.objects.viewable_by ( request.user )
- return render ( request, "artshow/manage_index.html", {'artists':artists,'artshow_settings':artshow_settings} )
-
-
-@login_required
-def artist ( request, artist_id ):
- artist = get_object_or_404 ( Artist.objects.viewable_by(request.user), pk=artist_id )
- pieces = artist.piece_set.order_by ( "pieceid" )
- can_edit = artist.editable_by(request.user)
- return render ( request, "artshow/manage_artist.html", {'artist':artist,'pieces':pieces,'can_edit':can_edit,'artshow_settings':artshow_settings} )
-
-class PieceForm ( forms.ModelForm ):
- class Meta:
- model = Piece
- fields=('pieceid','name','media','not_for_sale','adult','min_bid','buy_now')
- widgets={
- 'pieceid': forms.TextInput ( attrs={'size':4} ),
- 'name': forms.TextInput ( attrs={'size':40} ),
- 'media': forms.TextInput ( attrs={'size':40} ),
- 'min_bid': forms.TextInput ( attrs={'size':5} ),
- 'buy_now': forms.TextInput ( attrs={'size':5} ),
- }
-
-PieceFormSet = inlineformset_factory ( Artist, Piece, form=PieceForm,
- extra=EXTRA_PIECES,
- can_delete=True,
- )
-
-class DeleteConfirmForm ( forms.Form ):
- confirm_delete = forms.BooleanField ( required=False, help_text = "You are about to delete pieces. The information is not recoverable. Please confirm." )
+def index(request):
+ artists = Artist.objects.viewable_by(request.user)
+ return render(request, "artshow/manage_index.html", {'artists': artists, 'artshow_settings': artshow_settings})
@login_required
-def pieces ( request, artist_id ):
-
- artist = get_object_or_404 ( Artist.objects.viewable_by(request.user), pk=artist_id )
-
- if artshow_settings.ARTSHOW_SHUT_USER_EDITS:
- return render ( request, "artshow/manage_pieces_shut.html", {'artist':artist} )
-
- if not artist.editable_by ( request.user ):
- return render ( request, "artshow/manage_pieces_noedit.html", {'artist':artist} )
-
- pieces = artist.piece_set.order_by ( "pieceid" )
-
- if request.method == "POST":
- formset = PieceFormSet ( request.POST, queryset=pieces, instance=artist )
- delete_confirm_form = DeleteConfirmForm ( request.POST )
- if formset.is_valid () and delete_confirm_form.is_valid():
- if not formset.deleted_forms or delete_confirm_form.cleaned_data['confirm_delete']:
- formset.save ()
- messages.info ( request, "Changes to piece details have been saved" )
- if request.POST.get('saveandcontinue'):
- return redirect ( '.' )
- else:
- return redirect ( reverse('artshow.manage.artist', args=(artist_id,)) )
- else:
- formset = PieceFormSet ( queryset=pieces, instance=artist )
- delete_confirm_form = DeleteConfirmForm ()
-
- return render ( request, "artshow/manage_pieces.html", {'artist':artist,'formset':formset,'delete_confirm_form':delete_confirm_form,'artshow_settings':artshow_settings} )
-
-def yesno ( b ):
- return "yes" if b else "no"
-
+def artist(request, artist_id):
+ artist = get_object_or_404(Artist.objects.viewable_by(request.user), pk=artist_id)
+ pieces = artist.piece_set.order_by("pieceid")
+ can_edit = artist.editable_by(request.user)
+ return render(request, "artshow/manage_artist.html",
+ {'artist': artist, 'pieces': pieces, 'can_edit': can_edit, 'artshow_settings': artshow_settings})
+
+
+class PieceForm(forms.ModelForm):
+ class Meta:
+ model = Piece
+ fields = ('pieceid', 'name', 'media', 'not_for_sale', 'adult', 'min_bid', 'buy_now')
+ widgets = {
+ 'pieceid': forms.TextInput(attrs={'size': 4}),
+ 'name': forms.TextInput(attrs={'size': 40}),
+ 'media': forms.TextInput(attrs={'size': 40}),
+ 'min_bid': forms.TextInput(attrs={'size': 5}),
+ 'buy_now': forms.TextInput(attrs={'size': 5}),
+ }
+
+
+PieceFormSet = inlineformset_factory(Artist, Piece, form=PieceForm,
+ extra=EXTRA_PIECES,
+ can_delete=True,
+ )
+
+
+class DeleteConfirmForm(forms.Form):
+ confirm_delete = forms.BooleanField(
+ required=False,
+ help_text="You are about to delete pieces. The information is not recoverable. Please confirm."
+ )
+
+
@login_required
-def downloadcsv ( request, artist_id ):
-
- artist = get_object_or_404 ( Artist.objects.viewable_by(request.user), pk=artist_id )
-
- reduced_artist_name = re.sub ( '[^A-Za-z0-9]+', '', artist.artistname() ).lower()
- filename = "pieces-" + reduced_artist_name + ".csv"
-
- field_names = [ 'pieceid', 'code', 'title', 'media', 'min_bid', 'buy_now', 'adult', 'not_for_sale' ]
-
- response = HttpResponse ( mimetype="text/csv" )
- response['Content-Disposition'] = "attachment; filename=" + filename
-
- c = utils.UnicodeCSVWriter ( response )
- c.writerow ( field_names )
-
- for p in artist.piece_set.all():
- c.writerow ( ( p.pieceid, p.code, p.name, p.media, p.min_bid, p.buy_now, yesno(p.adult), yesno(p.not_for_sale) ) )
-
- return response
-
+def pieces(request, artist_id):
+ artist = get_object_or_404(Artist.objects.viewable_by(request.user), pk=artist_id)
+
+ if artshow_settings.ARTSHOW_SHUT_USER_EDITS:
+ return render(request, "artshow/manage_pieces_shut.html", {'artist': artist})
+
+ if not artist.editable_by(request.user):
+ return render(request, "artshow/manage_pieces_noedit.html", {'artist': artist})
+
+ pieces = artist.piece_set.order_by("pieceid")
+
+ if request.method == "POST":
+ formset = PieceFormSet(request.POST, queryset=pieces, instance=artist)
+ delete_confirm_form = DeleteConfirmForm(request.POST)
+ if formset.is_valid() and delete_confirm_form.is_valid():
+ if not formset.deleted_forms or delete_confirm_form.cleaned_data['confirm_delete']:
+ formset.save()
+ messages.info(request, "Changes to piece details have been saved")
+ if request.POST.get('saveandcontinue'):
+ return redirect('.')
+ else:
+ return redirect(reverse('artshow.manage.artist', args=(artist_id,)))
+ else:
+ formset = PieceFormSet(queryset=pieces, instance=artist)
+ delete_confirm_form = DeleteConfirmForm()
+
+ return render(request, "artshow/manage_pieces.html",
+ {'artist': artist, 'formset': formset, 'delete_confirm_form': delete_confirm_form,
+ 'artshow_settings': artshow_settings})
+
+
+def yesno(b):
+ return "yes" if b else "no"
+
@login_required
-def bid_sheets ( request, artist_id ):
+def downloadcsv(request, artist_id):
+ artist = get_object_or_404(Artist.objects.viewable_by(request.user), pk=artist_id)
+
+ reduced_artist_name = re.sub('[^A-Za-z0-9]+', '', artist.artistname()).lower()
+ filename = "pieces-" + reduced_artist_name + ".csv"
- artist = get_object_or_404 ( Artist.objects.viewable_by(request.user), pk=artist_id )
+ field_names = ['pieceid', 'code', 'title', 'media', 'min_bid', 'buy_now', 'adult', 'not_for_sale']
- response = HttpResponse ( mimetype="application/pdf" )
- bidsheets.generate_bidsheets_for_artists ( template_pdf=settings.ARTSHOW_BLANK_BID_SHEET, output=response, artists=[artist] )
- return response
+ response = HttpResponse(mimetype="text/csv")
+ response['Content-Disposition'] = "attachment; filename=" + filename
+
+ c = utils.UnicodeCSVWriter(response)
+ c.writerow(field_names)
+
+ for p in artist.piece_set.all():
+ c.writerow((p.pieceid, p.code, p.name, p.media, p.min_bid, p.buy_now, yesno(p.adult), yesno(p.not_for_sale)))
+
+ return response
@login_required
-def control_forms ( request, artist_id ):
+def bid_sheets(request, artist_id):
+ artist = get_object_or_404(Artist.objects.viewable_by(request.user), pk=artist_id)
- artist = get_object_or_404 ( Artist.objects.viewable_by(request.user), pk=artist_id )
+ response = HttpResponse(mimetype="application/pdf")
+ bidsheets.generate_bidsheets_for_artists(output=response, artists=[artist])
+ return response
+
+
+@login_required
+def control_forms(request, artist_id):
+ artist = get_object_or_404(Artist.objects.viewable_by(request.user), pk=artist_id)
- response = HttpResponse ( mimetype="application/pdf" )
- bidsheets.generate_control_forms ( template_pdf=settings.ARTSHOW_BLANK_CONTROL_FORM, output=response, artists=[artist] )
- return response
+ response = HttpResponse(mimetype="application/pdf")
+ bidsheets.generate_control_forms(output=response, artists=[artist])
+ return response
View
16 artshow/manage_urls.py
@@ -2,13 +2,13 @@
# Copyright (C) 2009, 2010 Chris Cogdon
# See file COPYING for licence details
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns
urlpatterns = patterns('artshow',
- (r'^$', 'manage.index' ),
- (r'^artist/(?P<artist_id>\d+)/$', 'manage.artist' ),
- (r'^artist/(?P<artist_id>\d+)/pieces/$', 'manage.pieces' ),
- (r'^artist/(?P<artist_id>\d+)/downloadcsv/$', 'manage.downloadcsv' ),
- (r'^artist/(?P<artist_id>\d+)/bidsheets/$', 'manage.bid_sheets' ),
- (r'^artist/(?P<artist_id>\d+)/controlforms/$', 'manage.control_forms' ),
-)
+ (r'^$', 'manage.index' ),
+ (r'^artist/(?P<artist_id>\d+)/$', 'manage.artist'),
+ (r'^artist/(?P<artist_id>\d+)/pieces/$', 'manage.pieces'),
+ (r'^artist/(?P<artist_id>\d+)/downloadcsv/$', 'manage.downloadcsv'),
+ (r'^artist/(?P<artist_id>\d+)/bidsheets/$', 'manage.bid_sheets'),
+ (r'^artist/(?P<artist_id>\d+)/controlforms/$', 'manage.control_forms'),
+ )
View
44 artshow/management/commands/artshowctl.py
@@ -1,25 +1,25 @@
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import BaseCommand
from artshow.models import *
-class Command ( BaseCommand ):
- args = 'command [options ...]'
- help = "Apply a command (applywonstatus)"
-
- def handle ( self, *args, **options ):
-
- command = args[0]
- method = getattr ( self, "command_"+command )
- return method ( *args[1:], **options )
-
- def command_applywonstatus ( self, *args, **options ):
-
- for p in Piece.objects.filter(status=Piece.StatusInShow,voice_auction=False):
- try:
- top_bid = p.top_bid()
- except Bid.DoesNotExist:
- pass
- else:
- p.status = Piece.StatusWon
- p.save ()
-
+class Command(BaseCommand):
+ args = 'command [options ...]'
+ help = "Apply a command (applywonstatus)"
+
+ def handle(self, *args, **options):
+
+ command = args[0]
+ method = getattr(self, "command_" + command)
+ return method(*args[1:], **options)
+
+ # noinspection PyUnusedLocal
+ def command_applywonstatus(self, *args, **options):
+
+ for p in Piece.objects.filter(status=Piece.StatusInShow, voice_auction=False):
+ try:
+ top_bid = p.top_bid()
+ except Bid.DoesNotExist:
+ pass
+ else:
+ p.status = Piece.StatusWon
+ p.save()
View
170 artshow/management/commands/artshowtestdata.py
@@ -1,89 +1,99 @@
from django.core.management.base import BaseCommand, CommandError
-from artshow.models import *
from django.db.models.loading import get_model
from django.conf import settings
-Person = get_model ( *settings.ARTSHOW_PERSON_CLASS.split('.',1) )
+from artshow.models import *
+
+
+Person = get_model(*settings.ARTSHOW_PERSON_CLASS.split('.', 1))
+
+
+class Command(BaseCommand):
+ args = '<stage ...>'
+ help = "Load up the artshow database with test data. Stages are start, bids, auctions"
+
+ def handle(self, *args, **options):
+
+ for stage in args:
+ method = "stage_" + stage
+ try:
+ attr = getattr(self, method)
+ except AttributeError:
+ raise CommandError("unknown stage %s" % stage)
+ attr()
+
+ def stage_start(self):
+ ps = Person(name="Bill Baggins")
+ ps.save()
+ a = Artist(artistid=1, person=ps)
+ a.save()
+ p = Piece(artist=a, pieceid=1, name="Bill's First Piece", not_for_sale=False, adult=False, min_bid=10,
+ buy_now=20, status=Piece.StatusInShow)
+ p.clean()
+ p.save()
+ p = Piece(artist=a, pieceid=2, name="Bill's Second Piece", not_for_sale=False, adult=False, min_bid=10,
+ buy_now=20, status=Piece.StatusInShow)
+ p.clean()
+ p.save()
+ p = Piece(artist=a, pieceid=3, name="Bill's Third Piece", not_for_sale=False, adult=False, min_bid=10,
+ buy_now=20, status=Piece.StatusInShow)
+ p.clean()
+ p.save()
+
+ ps = Person(name="Freddy Frodo")
+ ps.save()
+ a = Artist(artistid=2, person=ps)
+ a.save()
+ p = Piece(artist=a, pieceid=1, name="Freddy's First Piece", not_for_sale=False, adult=False, min_bid=10,
+ buy_now=20, status=Piece.StatusInShow)
+ p.clean()
+ p.save()
+ p = Piece(artist=a, pieceid=2, name="Freddy's Second Piece", not_for_sale=False, adult=False, min_bid=10,
+ buy_now=20, status=Piece.StatusInShow)
+ p.clean()
+ p.save()
+ p = Piece(artist=a, pieceid=3, name="Freddy's Third Piece", not_for_sale=False, adult=False, min_bid=10,
+ buy_now=20, status=Piece.StatusInShow)
+ p.clean()
+ p.save()
-class Command ( BaseCommand ):
+ ps = Person(name="Jenny Johnson")
+ ps.save()
+ a = Artist(artistid=3, person=ps)
+ a.save()
+ p = Piece(artist=a, pieceid=2, name="Jenny's First Piece", not_for_sale=False, adult=False, min_bid=10,
+ buy_now=20, status=Piece.StatusInShow)
+ p.clean()
+ p.save()
+ p = Piece(artist=a, pieceid=2, name="Jenny's Second Piece", not_for_sale=False, adult=False, min_bid=10,
+ buy_now=20, status=Piece.StatusInShow)
+ p.clean()
+ p.save()
+ p = Piece(artist=a, pieceid=3, name="Jenny's Third Piece", not_for_sale=False, adult=False, min_bid=10,
+ buy_now=20, status=Piece.StatusInShow)
+ p.clean()
+ p.save()
- args = '<stage ...>'
- help = "Load up the artshow database with test data. Stages are start, bids, auctions"
-
- def handle ( self, *args, **options ):
-
- for stage in args:
- method = "stage_"+stage
- try:
- attr = getattr ( self, method )
- except AttributeError:
- raise CommandError ( "unknown stage %s" % stage )
- attr ()
-
- def stage_start ( self ):
- ps = Person ( name="Bill Baggins" )
- ps.save ()
- a = Artist ( artistid=1, person=ps )
- a.save()
- p = Piece ( artist=a, pieceid=1, name="Bill's First Piece", not_for_sale=False, adult=False, min_bid=10, buy_now=20, status=Piece.StatusInShow )
- p.clean ()
- p.save ()
- p = Piece ( artist=a, pieceid=2, name="Bill's Second Piece", not_for_sale=False, adult=False, min_bid=10, buy_now=20, status=Piece.StatusInShow )
- p.clean ()
- p.save ()
- p = Piece ( artist=a, pieceid=3, name="Bill's Third Piece", not_for_sale=False, adult=False, min_bid=10, buy_now=20, status=Piece.StatusInShow )
- p.clean ()
- p.save ()
+ ps = Person(name="Chris Wilkie")
+ ps.save()
+ b = Bidder(person=ps)
+ b.save()
+ bi = BidderId("1001", bidder=b)
+ bi.save()
- ps = Person ( name="Freddy Frodo" )
- ps.save ()
- a = Artist ( artistid=2, person=ps )
- a.save()
- p = Piece ( artist=a, pieceid=1, name="Freddy's First Piece", not_for_sale=False, adult=False, min_bid=10, buy_now=20, status=Piece.StatusInShow )
- p.clean ()
- p.save ()
- p = Piece ( artist=a, pieceid=2, name="Freddy's Second Piece", not_for_sale=False, adult=False, min_bid=10, buy_now=20, status=Piece.StatusInShow )
- p.clean ()
- p.save ()
- p = Piece ( artist=a, pieceid=3, name="Freddy's Third Piece", not_for_sale=False, adult=False, min_bid=10, buy_now=20, status=Piece.StatusInShow )
- p.clean ()
- p.save ()
+ ps = Person(name="Eric Gordon")
+ ps.save()
+ b = Bidder(person=ps)
+ b.save()
+ bi = BidderId("1021", bidder=b)
+ bi.save()
- ps = Person ( name="Jenny Johnson" )
- ps.save ()
- a = Artist ( artistid=3, person=ps )
- a.save()
- p = Piece ( artist=a, pieceid=2, name="Jenny's First Piece", not_for_sale=False, adult=False, min_bid=10, buy_now=20, status=Piece.StatusInShow )
- p.clean ()
- p.save ()
- p = Piece ( artist=a, pieceid=2, name="Jenny's Second Piece", not_for_sale=False, adult=False, min_bid=10, buy_now=20, status=Piece.StatusInShow )
- p.clean ()
- p.save ()
- p = Piece ( artist=a, pieceid=3, name="Jenny's Third Piece", not_for_sale=False, adult=False, min_bid=10, buy_now=20, status=Piece.StatusInShow )
- p.clean ()
- p.save ()
-
- ps = Person ( name="Chris Wilkie" )
- ps.save ()
- b = Bidder ( person=ps )
- b.save ()
- bi = BidderId ( "1001", bidder=b )
- bi.save ()
-
- ps = Person ( name="Eric Gordon" )
- ps.save ()
- b = Bidder ( person=ps )
- b.save ()
- bi = BidderId ( "1021", bidder=b )
- bi.save ()
+ def stage_bids(self):
+ bidder = Bidder.objects.get(person__name="Chris Wilkie")
+ b = Bid(bidder=bidder, amount=15, piece=Piece.objects.get(code="1-1"))
+ b.save()
+ b = Bid(bidder=bidder, amount=20, buy_now_bid=True, piece=Piece.objects.get(code="2-2"))
+ b.save()
-
- def stage_bids ( self ):
- bidder = Bidder.objects.get ( person__name="Chris Wilkie" )
- b = Bid ( bidder=bidder, amount=15, piece=Piece.objects.get(code="1-1") )
- b.save ()
- b = Bid ( bidder=bidder, amount=20, buy_now_bid=True, piece=Piece.objects.get(code="2-2") )
- b.save ()
-
- def stage_auctions ( self ):
- pass
+ def stage_auctions(self):
+ pass
View
29 artshow/management/commands/printinvoice.py
@@ -1,18 +1,19 @@
-from django.core.management.base import BaseCommand, CommandError
-from artshow.models import *
from optparse import make_option
+
+from django.core.management.base import BaseCommand
+
from artshow.invoicegen import print_invoices
-class Command ( BaseCommand ):
- args = 'invoiceid ... '
- help = "Print invoices to console or printer"
-
- option_list = BaseCommand.option_list + (
- make_option ( "--copy-name", type="string", action="append", default=[], help="copy name"),
- make_option ( "--printer", action="store_true", default=False, help="send to configured printer" ),
- )
-
- def handle ( self, *args, **options ):
- invoice_ids = [ int(x) for x in args ]
- print_invoices ( invoice_ids, copy_names=options['copy_name'], to_printer=options['printer'] )
+class Command(BaseCommand):
+ args = 'invoiceid ... '
+ help = "Print invoices to console or printer"
+
+ option_list = BaseCommand.option_list + (
+ make_option("--copy-name", type="string", action="append", default=[], help="copy name"),
+ make_option("--printer", action="store_true", default=False, help="send to configured printer"),
+ )
+
+ def handle(self, *args, **options):
+ invoice_ids = [int(x) for x in args]
+ print_invoices(invoice_ids, copy_names=options['copy_name'], to_printer=options['printer'])
View
78 artshow/management/commands/scannerreader.py
@@ -1,43 +1,45 @@
-from django.core.management.base import BaseCommand, CommandError
-from django.conf import settings
-from artshow.models import BatchScan
from optparse import make_option
import datetime
import select
-
-class Command ( BaseCommand ):
+from django.core.management.base import BaseCommand
+from django.conf import settings
+
+from artshow.models import BatchScan
+
+
+class Command(BaseCommand):
+ args = ''
+ help = "Monitor connected scanner"
+
+ option_list = BaseCommand.option_list + (
+ make_option("--device", type="string", action="append", default=settings.ARTSHOW_SCANNER_DEVICE,
+ help="scanner device name [%default]"),
+ )
+
+ def handle(self, *args, **options):
+ device = options['device']
+ f = open(device)
- args = ''
- help = "Monitor connected scanner"
-
- option_list = BaseCommand.option_list + (
- make_option ( "--device", type="string", action="append", default=settings.ARTSHOW_SCANNER_DEVICE, help="scanner device name [%default]"),
- )
-
- def handle ( self, *args, **options ):
- device = options['device']
- f = open ( device )
-
- while True:
- data = []
- print "waiting for new data"
- l = f.readline ()
- print "\a"
- while True:
- if not l:
- print "oops. no data to read. wtf?"
- l = l.strip()
- if l:
- data.append ( l )
- print l
- rlist, wlist, xlist = select.select ( [f], [], [f], 5.0 )
- if not rlist and not xlist:
- break
- l = f.readline ()
- print "timed out"
- print "\a"
- data_str = "\n".join ( data ) + "\n"
- batchscan = BatchScan ( data=data, date_scanned=datetime.datetime.now() )
- batchscan.save ()
- print str(batchscan), "saved"
+ while True:
+ data = []
+ print "waiting for new data"
+ l = f.readline()
+ print "\a"
+ while True:
+ if not l:
+ print "oops. no data to read. wtf?"
+ l = l.strip()
+ if l:
+ data.append(l)
+ print l
+ rlist, wlist, xlist = select.select([f], [], [f], 5.0)
+ if not rlist and not xlist:
+ break
+ l = f.readline()
+ print "timed out"
+ print "\a"
+ data_str = "\n".join(data) + "\n"
+ batchscan = BatchScan(data=data_str, date_scanned=datetime.datetime.now())
+ batchscan.save()
+ print str(batchscan), "saved"
View
181 artshow/mod11codes.py
@@ -3,92 +3,101 @@
# Copyright (C) 2009, 2010 Chris Cogdon
# See file COPYING for licence details
-import optparse, sys
-
-default_factors = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
-
-class CheckDigitError ( ValueError ):
- pass
-
-
-def make_check ( s, check10="X", factors=default_factors ):
- tally = 0
- for i in range(len(s)):
- tally += int(s[-1-i]) * factors[ (1+i) % len(factors) ]
- check = (-tally) % 11
- if check == 10:
- return check10
- else:
- return str(check)
-
-
-def check ( s, check10="X", start=0, end=None, factors=default_factors ):
- s2 = s[start:end]
- tally = 0
- for i in range(len(s2)):
- c = s2[-1-i]
- c = (c==check10) and 10 or int(c)
- tally += c * factors [ i % len(factors) ]
- if tally % 11 != 0: raise CheckDigitError ( "check digit failed for " + s )
-
-
-def make_codes ( num, first=0, count=1, min_digits=3, check10=False, factors=default_factors ):
- i = 0
- bare_code = first
- while i < num:
- bare_code_str = "%0*d" % ( min_digits, bare_code )
- bare_code += 1
- check = make_check ( bare_code_str, factors=factors )
- if check == "X":
- if not check10: continue
- check = check10
- for c in range(count):
- yield bare_code_str + check
- i += 1
-
-def _get_options ():
-
- def factors_callback ( option, opt, value, parser ):
- try:
- factors = value.split(",")
- factors = [ int(x) for x in factors ]
- parser.values.factors = factors
- except ValueError, x:
- raise optparse.OptionValueError ( str(x) )
-
- parser = optparse.OptionParser ( )
- parser.add_option ( "-c", "--count", type="int", default=1 )
- parser.add_option ( "--min_digits", type="int", default=3 )
- parser.add_option ( "--check10", type="str", default="" )
- parser.add_option ( "--prefix", type="str", default="" )
- parser.add_option ( "--suffix", type="str", default="" )
- parser.add_option ( "--factors", type="str", action="callback", callback=factors_callback, default=default_factors )
- parser.add_option ( "--check", action="store_true", default=False )
- opts, args = parser.parse_args ()
-
- if opts.check:
- opts.sample = args[0]
- else:
- opts.num = int(args[0])
- try: opts.first = int(args[1])
- except IndexError: opts.first=0
-
- return opts
-
-
-def _main ():
- opts = _get_options ()
- if opts.check:
- try:
- check ( opts.sample, check10=opts.check10, start=len(opts.prefix), end=len(opts.suffix) or None, factors=opts.factors )
- except ValueError, x:
- print >>sys.stderr, x
- raise SystemExit(1)
- else:
- for c in make_codes ( opts.num, opts.first, opts.count, min_digits=opts.min_digits, check10=opts.check10, factors=opts.factors ):
- print opts.prefix+c+opts.suffix
-
+import optparse
+import sys
+
+default_factors = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+
+
+class CheckDigitError(ValueError):
+ pass
+
+
+def make_check(s, check10="X", factors=default_factors):
+ tally = 0
+ for i in range(len(s)):
+ tally += int(s[-1 - i]) * factors[(1 + i) % len(factors)]
+ check = (-tally) % 11
+ if check == 10:
+ return check10
+ else:
+ return str(check)
+
+
+def check(s, check10="X", start=0, end=None, factors=default_factors):
+ s2 = s[start:end]
+ tally = 0
+ for i in range(len(s2)):
+ c = s2[-1 - i]
+ c = (c == check10) and 10 or int(c)
+ tally += c * factors[i % len(factors)]
+ if tally % 11 != 0:
+ raise CheckDigitError("check digit failed for " + s)
+
+
+def make_codes(num, first=0, count=1, min_digits=3, check10=False, factors=default_factors):
+ i = 0
+ bare_code = first
+ while i < num:
+ bare_code_str = "%0*d" % (min_digits, bare_code)
+ bare_code += 1
+ check = make_check(bare_code_str, factors=factors)
+ if check == "X":
+ if not check10:
+ continue
+ check = check10
+ for c in range(count):
+ yield bare_code_str + check
+ i += 1
+
+
+def _get_options():
+ # noinspection PyUnusedLocal
+ def factors_callback(option, opt, value, parser):
+ try:
+ factors = value.split(",")
+ factors = [int(x) for x in factors]
+ parser.values.factors = factors
+ except ValueError, x:
+ raise optparse.OptionValueError(str(x))
+
+ parser = optparse.OptionParser()
+ parser.add_option("-c", "--count", type="int", default=1)
+ parser.add_option("--min_digits", type="int", default=3)
+ parser.add_option("--check10", type="str", default="")
+ parser.add_option("--prefix", type="str", default="")
+ parser.add_option("--suffix", type="str", default="")
+ parser.add_option("--factors", type="str", action="callback", callback=factors_callback, default=default_factors)
+ parser.add_option("--check", action="store_true", default=False)
+ opts, args = parser.parse_args()
+
+ if opts.check:
+ opts.sample = args[0]
+ else:
+ opts.num = int(args[0])
+ try:
+ opts.first = int(args[1])
+ except IndexError:
+ opts.first = 0
+
+ return opts
+
+
+def _main():
+ opts = _get_options()
+ if opts.check:
+ try:
+ check(opts.sample, check10=opts.check10, start=len(opts.prefix), end=len(opts.suffix) or None,
+ factors=opts.factors)
+ except ValueError, x:
+ print >> sys.stderr, x
+ raise SystemExit(1)
+ else:
+ for c in make_codes(opts.num, opts.first, opts.count, min_digits=opts.min_digits, check10=opts.check10,
+ factors=opts.factors):
+ print opts.prefix + c + opts.suffix
+
if __name__ == "__main__":
- _main ()
+ _main()
View
10 artshow/models.py
@@ -42,7 +42,7 @@ def __unicode__(self):
return self.name
-class Checkoff ( models.Model ):
+class Checkoff (models.Model):
name = models.CharField(max_length=100)
shortname = models.CharField(max_length=100)
@@ -81,6 +81,7 @@ def name(self):
checkoffs = models.ManyToManyField(Checkoff, blank=True)
payment_to = models.ForeignKey(settings.ARTSHOW_PERSON_CLASS, null=True,
blank=True, related_name="receiving_payment_for")
+
def artistname(self):
return self.publicname or self.person.name
@@ -106,9 +107,9 @@ def chequename(self):
return self.person.name
def editable_by(self, user):
- return self.artistaccess_set.filter(user=user,can_edit=True).exists()
+ return self.artistaccess_set.filter(user=user, can_edit=True).exists()
- def viewable_by ( self, user ):
+ def viewable_by(self, user):
return self.artistaccess_set.filter(user=user).exists()
class Meta:
@@ -333,6 +334,7 @@ def __unicode__(self):
class PaymentType (models.Model):
name = models.CharField(max_length=40)
+
def __unicode__(self):
return self.name
@@ -363,7 +365,7 @@ def clean(self):
if self.amount >= 0:
raise ValidationError("Cheque amounts are a payment outbound and must be negative")
self.payment_type = PaymentType.objects.get(pk=settings.ARTSHOW_PAYMENT_SENT_PK)
- self.description = "Cheque %s Payee %s" % (self.number and "#"+self.number or "pending number", self.payee)
+ self.description = "Cheque %s Payee %s" % (self.number and "#" + self.number or "pending number", self.payee)
class Meta:
permissions = (
View
246 artshow/pdfreports.py
@@ -7,134 +7,142 @@
from django.http import HttpResponse
from django.contrib.auth.decorators import permission_required
-from reportlab.platypus import SimpleDocTemplate, Paragraph, Table, TableStyle
+from reportlab.platypus import SimpleDocTemplate, Paragraph, Table
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
-from reportlab.lib.units import inch
+from reportlab.lib.units import inch
from reportlab.lib import colors
from cgi import escape
MAX_PIECES_PER_PAGE = 30
-@permission_required ( 'artshow.is_artshow_staff' )
-def winning_bidders ( request ):
-
- bidders = Bidder.objects.all().annotate(first_bidderid=Min('bidderid')).order_by('first_bidderid')
- response = HttpResponse ( mimetype="application/pdf" )
-
- styles = getSampleStyleSheet()
- normal_style = styles["Normal"]
- heading_style = styles["Heading3"]
- heading_style_white = ParagraphStyle ( "heading_style_white", parent=heading_style, textColor=colors.white )
- doc = SimpleDocTemplate ( response, leftMargin=0.5*inch, rightMargin=0.5*inch, topMargin=0.5*inch, bottomMargin=0.5*inch )
-
- data = [ ( "Bidder", Table ( [("ID", "Piece", "Bid", "Notes")], colWidths=[ 0.5*inch, 4.5*inch, 0.5*inch, 1.2*inch] ) ) ]
-
- for bidder in bidders:
- top_bids = bidder.top_bids()
- if top_bids:
- for i in range(0,len(top_bids),MAX_PIECES_PER_PAGE):
- bidder_data = []
- if i != 0:
- bidder_data.append ( ( Paragraph ( "... continued from previous page", normal_style ), "", "" ) )
- for bid in top_bids[i:i+MAX_PIECES_PER_PAGE]:
- bidder_data.append ( (
- bid.piece.code,
- Paragraph ("<i>%s</i> by %s" % ( escape(bid.piece.name),
- escape(bid.piece.artist.artistname()) ), normal_style ),
- str(bid.amount),
- bid.piece.voice_auction and "Voice Auction" or "" ) )
- if i + MAX_PIECES_PER_PAGE <= len(top_bids):
- bidder_data.append ( ( Paragraph ( "continued on next page...", normal_style ), "", "" ) )
- right_part = Table ( bidder_data, colWidths=[ 0.5*inch, 4.5*inch, 0.5*inch, 1.2*inch],
- style = [
- ( "ROWBACKGROUNDS", (0,0), (-1,-1), ( colors.lightgrey, colors.white ) ),
- ( "SIZE", (0,0), (0,-1), 8 ),
- ( "ALIGN", (2,0), (2,-1), "DECIMAL" ),
- ] )
- data.append ( (
- Paragraph ( ", ".join(["B"+str(x) for x in bidder.bidder_ids()]), heading_style_white ),
- right_part,
- ) )
- else:
- right_part = Table ( [[Paragraph ( "No winning bids", normal_style )]] )
- data.append ( (
- Paragraph ( ", ".join(["B"+str(x) for x in bidder.bidder_ids()]), heading_style_white ),
- right_part,
- ) )
-
- table_style = [
- ( "LEFTPADDING", (1,0), (1,-1), 0 ),
- ( "RIGHTPADDING", (1,0), (1,-1), 0 ),
- ( "TOPPADDING", (1,0), (1,-1), 0 ),
- ( "BOTTOMPADDING", (1,0), (1,-1), 0 ),
- ( "VALIGN", (0,0), (0,-1), "MIDDLE" ),
- ( "BACKGROUND", (0,1), (0,-1), colors.black ),
- ( "LINEABOVE", (0,1), (0,1), 2, colors.black ),
- ( "LINEABOVE", (1,1), (0,-1), 2, colors.white ),
- ( "LINEBELOW", (0,1), (0,-2), 2, colors.white ),
- ( "LINEBELOW", (0,-1), (0,-1), 2, colors.black ),
- ( "LINEABOVE", (1,1), (1,-1), 2, colors.black ),
- ( "LINEBELOW", (1,1), (1,-1), 2, colors.black ),
- ( "LINEABOVE", (0,'splitfirst'), (0,'splitfirst'), 2, colors.black ),
- ( "LINEBELOW", (0,'splitlast'), (0,'splitlast'), 2, colors.black ),
-
- ]
- table = Table ( data, colWidths=[ 0.8*inch, 6.7*inch], repeatRows=1, style=table_style )
- story = [ table ]
- doc.build ( story )
-
- return response
-
-@permission_required ( 'artshow.is_artshow_staff' )
-def bid_entry_by_artist ( request ):
+
+@permission_required('artshow.is_artshow_staff')
+def winning_bidders(request):
+ bidders = Bidder.objects.all().annotate(first_bidderid=Min('bidderid')).order_by('first_bidderid')
+ response = HttpResponse(mimetype="application/pdf")
+
+ styles = getSampleStyleSheet()
+ normal_style = styles["Normal"]
+ heading_style = styles["Heading3"]
+ heading_style_white = ParagraphStyle("heading_style_white", parent=heading_style, textColor=colors.white)
+ doc = SimpleDocTemplate(response, leftMargin=0.5 * inch, rightMargin=0.5 * inch, topMargin=0.5 * inch,
+ bottomMargin=0.5 * inch)
+
+ data = [("Bidder",
+ Table([("ID", "Piece", "Bid", "Notes")], colWidths=[0.5 * inch, 4.5 * inch, 0.5 * inch, 1.2 * inch]))]
+
+ for bidder in bidders:
+ top_bids = bidder.top_bids()
+ if top_bids:
+ for i in range(0, len(top_bids), MAX_PIECES_PER_PAGE):
+ bidder_data = []
+ if i != 0:
+ bidder_data.append((Paragraph("... continued from previous page", normal_style), "<