From cf1b59b66960f947d62d35b43e90f27b13ddab14 Mon Sep 17 00:00:00 2001 From: Trygve Date: Wed, 1 Jun 2022 23:28:22 +0200 Subject: [PATCH] =?UTF-8?q?Startet=20p=C3=A5=20faktura=20pdf=20metoden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- otime.py | 152 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 137 insertions(+), 15 deletions(-) diff --git a/otime.py b/otime.py index d88fc28..54c7971 100644 --- a/otime.py +++ b/otime.py @@ -14,6 +14,21 @@ class Event: self.id = eventid self.name = name + try: + self.start_time = kwargs['start_time'] + except KeyError: + self.start_time = None + + try: + self.end_time = kwargs['end_time'] + except KeyError: + self.end_time = None + + try: + self.organiser = kwargs['organiser'] + except KeyError: + self.organiser = None + try: self.courses = kwargs['courses'] except KeyError: @@ -59,6 +74,29 @@ class Event: self.add_runners(*runners_from_xml_entries(xml_file)) self.add_fees(*fees_from_xml_entries(xml_file)) + def from_xml_entries(xml_file): + tree = ET.parse(xml_file) + root = tree.getroot() + + event_el = root.find('./{http://www.orienteering.org/datastandard/3.0}Event') + event_id = int(event_el.find('./{http://www.orienteering.org/datastandard/3.0}Id').text) + name = event_el.find('./{http://www.orienteering.org/datastandard/3.0}Name').text + organiser = event_el.find('./{http://www.orienteering.org/datastandard/3.0}Organiser/{http://www.orienteering.org/datastandard/3.0}Name').text + + start_ds = event_el.find('./{http://www.orienteering.org/datastandard/3.0}StartTime/{http://www.orienteering.org/datastandard/3.0}Date').text + start_ts = event_el.find('./{http://www.orienteering.org/datastandard/3.0}StartTime/{http://www.orienteering.org/datastandard/3.0}Time').text[:-1] + start_time = datetime.datetime.fromisoformat(f'{start_ds}T{start_ts}') + + end_ds = event_el.find('./{http://www.orienteering.org/datastandard/3.0}EndTime/{http://www.orienteering.org/datastandard/3.0}Date').text + end_ts = event_el.find('./{http://www.orienteering.org/datastandard/3.0}EndTime/{http://www.orienteering.org/datastandard/3.0}Time').text[:-1] + end_time = datetime.datetime.fromisoformat(f'{end_ds}T{end_ts}') + + runners = runners_from_xml_entries(xml_file) + fees = fees_from_xml_entries(xml_file) + + return Event(event_id, name, organiser=organiser, runners=runners, + fees=fees, start_time=start_time, end_time=end_time) + def import_ttime_cnf(self, ttime_file): self.add_course(*courses_from_ttime_conf(ttime_file)) ttime_file.seek(0) @@ -269,25 +307,109 @@ class Event: pdf.ln(line_height) pdf.output(file_name) - def create_invoices(self, file_name): + def create_club_invoice(self, club, file_name): + # Get only runners in specified club + runners_ic = [x for x in self.runners if x.club == club] + + fee_dict = {} + for fee in self.fees: + fee_dict.update({fee.name: [x for x in runners_ic if x.fee.name == fee.name]}) + pdf = FPDF() pdf.add_page() pdf.add_font("LiberationSans", fname="data/fonts/LiberationSans-Regular.ttf") + pdf.add_font("LiberationSans-Bold", fname="data/fonts/LiberationSans-Bold.ttf") pdf.set_font("LiberationSans", size=10) + line_height = pdf.font_size * 1.5 + + # Topp venstre: + pdf.set_font("LiberationSans-Bold", size=10) + pdf.multi_cell(pdf.epw / 2, line_height, self.name, align='L') + pdf.ln() + pdf.set_font("LiberationSans", size=10) + pdf.multi_cell(pdf.epw / 2, line_height, 'Kristiansand OK', align='L') + pdf.ln(10) + pdf.multi_cell(pdf.epw / 2, line_height, 'CLUB', align='L') + pdf.ln() + + # Topp høyre: + pdf.set_xy(-pdf.epw / 3, 10) + pdf.set_font("LiberationSans-Bold", size=20) + pdf.multi_cell(pdf.epw, line_height, 'Faktura', align='L') + pdf.set_xy(-pdf.epw / 3, 20) + + # Dato + pdf.set_font("LiberationSans-Bold", size=10) + pdf.multi_cell(0, line_height, 'Dato:', align='L') + pdf.set_xy(-pdf.epw / 3, 20) + pdf.set_font("LiberationSans", size=10) + pdf.multi_cell(0, line_height, datetime.date.today().strftime('%d.%m.%Y'), align='R') + + # Nummer + pdf.set_xy(-pdf.epw / 3, 20 + line_height) + pdf.set_font("LiberationSans-Bold", size=10) + pdf.multi_cell(0, line_height, 'Nummer:', align='L') + pdf.set_xy(-pdf.epw / 3, 20 + line_height) + pdf.multi_cell(0, line_height, '1', align='R') + + # Kundeid + pdf.set_xy(-pdf.epw / 3, 20 + line_height*2) + pdf.set_font("LiberationSans-Bold", size=10) + pdf.multi_cell(0, line_height, 'Kundeid:', align='L') + pdf.set_xy(-pdf.epw / 3, 20 + line_height*2) + pdf.set_font("LiberationSans", size=10) + pdf.multi_cell(0, line_height, '123', align='R') + + # Forfall + pdf.set_xy(-pdf.epw / 3, 20 + line_height*3) + pdf.set_font("LiberationSans-Bold", size=10) + pdf.multi_cell(0, line_height, 'Forfall:', align='L') + pdf.set_xy(-pdf.epw / 3, 20 + line_height*3) + pdf.set_font("LiberationSans", size=10) + pdf.multi_cell(0, line_height, datetime.date.today().strftime('%d.08.%Y'), align='R') + + pdf.set_xy(-pdf.epw, 20 + line_height*5) + pdf.set_font("LiberationSans-Bold", size=10) + date = self.start_time.strftime('%d.%m.%Y') + pdf.multi_cell(0, line_height, f'Kontingentliste {self.name} dato: {date}', align='R') + + pdf.ln() + + pdf.set_font("LiberationSans", size=10) + # Tabell line_height = pdf.font_size * 2 - col_width = pdf.epw / 7 # distribute content evenly - for runner in self.runners: - pdf.multi_cell(col_width, line_height, runner.id, border=1, ln=3,max_line_height=pdf.font_size, align='L') - pdf.multi_cell(col_width, line_height, runner.last, border=1, ln=3, max_line_height=pdf.font_size, align='L') - pdf.multi_cell(col_width, line_height, runner.first, border=1, ln=3, max_line_height=pdf.font_size, align='L') - pdf.multi_cell(col_width, line_height, runner.o_class_str, border=1, ln=3, max_line_height=pdf.font_size, align='L') - pdf.multi_cell(col_width, line_height, str(runner.card), border=1, ln=3, max_line_height=pdf.font_size) - if runner.start_time != None: - pdf.multi_cell(col_width, line_height, str(runner.start_time), border=1, ln=3, max_line_height=pdf.font_size) - else: - pdf.multi_cell(col_width, line_height, '', border=1, ln=3, max_line_height=pdf.font_size) - pdf.multi_cell(col_width, line_height, str(runner.rank(self.runners)), border=1, ln=3, max_line_height=pdf.font_size) - pdf.ln(line_height) + col_width = pdf.epw / 9 # distribute content evenly + #Top row + pdf.set_fill_color(191, 191, 191) + pdf.set_draw_color(191, 191, 191) + pdf.set_font("LiberationSans-Bold", size=10) + pdf.multi_cell(col_width, line_height, 'Startnr', border=1, ln=3,max_line_height=pdf.font_size, align='L', fill=True) + pdf.multi_cell(col_width*2, line_height, 'Navn', border=1, ln=3,max_line_height=pdf.font_size, align='L', fill=True) + pdf.multi_cell(col_width, line_height, 'Klasse', border=1, ln=3,max_line_height=pdf.font_size, align='L', fill=True) + pdf.multi_cell(col_width, line_height, 'Brikke', border=1, ln=3,max_line_height=pdf.font_size, align='L', fill=True) + pdf.multi_cell(col_width, line_height, 'Starttid', border=1, ln=3,max_line_height=pdf.font_size, align='L', fill=True) + pdf.multi_cell(col_width, line_height, 'Resultat', border=1, ln=3,max_line_height=pdf.font_size, align='L', fill=True) + pdf.multi_cell(col_width, line_height, 'Plass', border=1, ln=3,max_line_height=pdf.font_size, align='L', fill=True) + pdf.multi_cell(col_width, line_height, 'Kontigent', border=1, ln=3,max_line_height=pdf.font_size, align='L', fill=True) + pdf.ln() + for runners in fee_dict.values(): + pdf.set_font("LiberationSans-Bold", size=12) + pdf.multi_cell(0, line_height, runners[0].fee.name, border='B', align='L') + pdf.ln() + pdf.set_font("LiberationSans", size=10) + for runner in runners: + pdf.multi_cell(col_width, line_height, runner.id, ln=3,max_line_height=pdf.font_size, align='L') + pdf.multi_cell(col_width*2, line_height, f'{runner.last}, {runner.first}', ln=3, max_line_height=pdf.font_size, align='L') + pdf.multi_cell(col_width, line_height, runner.o_class_str, ln=3, max_line_height=pdf.font_size, align='L') + pdf.multi_cell(col_width, line_height, str(runner.card), ln=3, max_line_height=pdf.font_size) + if runner.start_time != None: + pdf.multi_cell(col_width, line_height, str(runner.start_time), ln=3, max_line_height=pdf.font_size) + else: + pdf.multi_cell(col_width, line_height, 'Fristart', ln=3, max_line_height=pdf.font_size) + pdf.multi_cell(col_width, line_height, str(datetime.timedelta(seconds=runner.totaltime())), ln=3, max_line_height=pdf.font_size) + pdf.multi_cell(col_width, line_height, str(runner.rank(self.runners)), ln=3, max_line_height=pdf.font_size) + pdf.multi_cell(col_width, line_height, str(runner.fee.amount), ln=3, max_line_height=pdf.font_size) + pdf.ln(line_height) pdf.output(file_name) # The runner object stores all the data specific to a runner. @@ -738,7 +860,7 @@ def fees_from_xml_entries(xml_file): fee_id = f_id name = fee.find('./{http://www.orienteering.org/datastandard/3.0}Name').text currency = fee.find('./{http://www.orienteering.org/datastandard/3.0}Amount').attrib['currency'] - amount = fee.find('./{http://www.orienteering.org/datastandard/3.0}Amount').text + amount = int(fee.find('./{http://www.orienteering.org/datastandard/3.0}Amount').text) try: from_birth_date = fee.find('./{http://www.orienteering.org/datastandard/3.0}FromDateOfBirth').text except AttributeError: