def get_attr(obj, spec): # extract data for attr spec from populated database object # e.g. get_attr(member, 'address.line_1') # or get_attr(member, 'address.country_for_mail()') - invoke a method if not spec: return '' if '=' == first_or_default(spec, ' '): return eval(spec[1:]) attr, tail = pop_next(spec, '.') if '()' in attr: # function call res = getattr(obj, attr.replace('()', ''))() elif tail and '()' in tail: # function call res = getattr(obj, attr) elif '[]' in attr: # list - get first res = first_or_default(getattr(obj, attr.replace('[]', '')), None) elif 'actions[' in attr: # list - get specific (name, type) = attr.split('[') res = first_or_default([a for a in getattr(obj, name) if a.action.name == type[:-1]], None) elif 'payments[' in attr: # list - get specific (name, type) = attr.split('[') res = first_or_default([a for a in getattr(obj, name) if a.type.name == type[:-1]], None) elif '{' in attr: # literal - return as value res = attr.replace('{', '').replace('}', '') else: # property res = getattr(obj, attr) if res and tail: res = get_attr(res, tail) if res and 'date' in spec and isinstance(res, datetime.date): res = fmt_date(res) return res if res is not None else ''
def update_member_payments(member, details): payments = [] for payment in details['payments']: if payment['amount'] is None: continue item = first_or_default([p for p in member.payments if p.date == payment['date']], None) if item: item.date = payment['date'] item.type = PaymentType(payment['pay_type']) item.amount = payment['amount'] item.method = PaymentMethod(payment['method']) if payment['method'] > 0 else None item.comment = payment['comment'] else: item = Payment( member_id=member.id, date=payment['date'], type=PaymentType(payment['pay_type']), amount=payment['amount'], method=PaymentMethod(payment['method']) if payment['method'] > 0 else None, comment=payment['comment'] ) payments.append(item) if not member.last_payment_method: last = first_or_default(sorted(payments, key=lambda x: x.date, reverse=True), None) if last: member.last_payment_method = last.method else: last = PaymentMethod.from_value(details['payment_method']) if member.last_payment_method != last: member.last_payment_method = last member.payments = payments
def get_next_event(date=datetime.date.today()): start = date + datetime.timedelta(days=1) end = datetime.date(date.year, 12, 31) next = first_or_default(get_events_in((start, end)), None) if not next: end = datetime.date(date.year + 1, 12, 31) next = first_or_default(get_events_in((start, end)), None) return next
def save_event_details(event_id, details): event_type = details['event_type'] if event_id > 0: event = get_event(event_id) else: event = Event(type=event_type) db_session.add(event) event.venue_id = details['venue_id'] event.date = details['date'] event.trophy_id = details['trophy_id'] event.course_id = details['course_id'] event.organiser_id = details['organiser_id'] event.member_price = details['member_price'] event.guest_price = details['guest_price'] event.booking_start = details['start_booking'] event.booking_end = details['end_booking'] event.max = details['max'] event.note = details['note'] if event_type == EventType.wags_vl_event: schedule = [] for row in details['schedule']: if row['time'] is None: continue item = first_or_default([s for s in event.schedule if s.time == row['time']], None) if item: item.time = row['time'] item.text = row['text'] else: item = Schedule(event_id=event_id, time=row['time'], text=row['text']) schedule.append(item) event.schedule = sorted(schedule) if event_type in [EventType.wags_tour, EventType.minotaur]: tour_events = [] all_courses = get_all_courses() for row in details['tour_schedule']: date = row['date'] course_id = row['course'] if course_id > 0: venue_id = all_courses[course_id].venue_id else: venue_id = event.venue_id item = first_or_default([s for s in event.tour_events if s.date == date], None) if item: item.course_id = course_id item.venue_id = venue_id # else: item = get_event_for_course_and_date(date, course_id) item.type = EventType.wags_vl_event item.tour_event_id = event_id item.venue_id = venue_id tour_events.append(item) event.tour_events = tour_events db_session.commit() return event.id
def save_event_result(event_id, result): event = get_event(event_id) scores = [] delete = {s.id: True for s in event.scores} for row in result.rows(): score = first_or_default([s for s in event.scores if s.player_id == int(row['player_id'])], None) if score: score.position = row['position'] score.shots = row['shots'] score.points = row['points'] if 'card' in row: score.card = row['card'] if score.id in delete: delete[score.id] = False else: score = Score(event_id=event_id, player_id=row['player_id'], position=row['position'], shots=row['shots'], points=row['points'], card=row.get('card', None) ) scores.append(score) for score in event.scores: if delete.get(score.id, False): db_session.delete(score) if len(result.data) > 0: update_event_winner(event, result) else: event.winner_id = event.average_score = None event.scores = scores if event.tour_event: if event.tour_event.trophy and event in event.tour_event.tour_events: update_tour_winner(event.tour_event) db_session.commit()
def book_event(self, event_id, member_id): errors = self.errors if len(errors) > 0: return False booking = get_booking(event_id, member_id) with suspend_flush(): booking.date = datetime.date.today() booking.playing = self.attend.data booking.comment = self.comment.data if len( self.comment.data) > 0 else None guests = [] if booking.playing: for guest in self.guests: name = string.capwords(guest.guest_name.data) if len(name) > 0: obj = first_or_default( [g for g in booking.guests if g.name == name], Guest(name=name, booking=booking)) hcap = parse_float(guest.handicap.data, 28.0) known_player = get_player_by_name(name) if known_player: state = known_player.state_as_of(booking.date) if state.status == PlayerStatus.member: hcap = state.handicap obj.handicap = hcap guests.append(obj) booking.guests = guests app.logger.info(booking.debug_info()) save_booking(booking) return self.confirm_booking(event_id, member_id)
def select_fields_to_update(select_fields, default_table): updates = {} for field in select_fields: if field.data: field_name = field.db_map if field.type == 'MySelectField': if field.data in [ c[0].value for c in field.choices if not isinstance(c[0], int) ]: value = field.data else: value = [ c[1] for c in field.choices if c[0] == field.data ][0] if '(' in value: value = value[:value.find('(') - 1] value = first_or_default( [v[0] for v in field.choices if v[1] == value], None) else: value = field.data func = None # if isinstance(value, (int, float)) or len(value) > 0: # if '.' in field_name: # a = field_name.split('.') # if len(a) == 2: # table, column = a # if len(a) == 3: # table, column, func = a # else: # table, column = default_table, field_name updates[field_name] = value return updates
def select_fields_to_query(select_fields, default_table): query_clauses = [] for field in select_fields: if field.data: if field.type == 'MySelectField': if field.data in [ c[0].value for c in field.choices if not isinstance(c[0], int) ]: condition, value = '=', field.data else: v = [c[1] for c in field.choices if c[0] == field.data][0] condition, value = split_condition_and_value(v) value = first_or_default( [v[0] for v in field.choices if v[1] == value], None) else: condition, value = split_condition_and_value(field.data) func = None if isinstance(value, (int, float)) or len(value) > 0: field_name = field.db_map if '.' in field_name: a = field_name.split('.') if len(a) == 2: table, column = a if len(a) == 3: table, column, func = a if '()' not in func: table, column, func = column, func, None else: table, column = default_table, field_name query_clauses.append( (table, column, value, condition, func, field.name)) query_clauses = limit_status_and_lapsed_date_by_access(query_clauses) return query_clauses
def _test_etl_bookings(self): year = '2018' event = 'event14.csv' event_id = 381 booking_file = os.path.join(TestData.data_location, year, event) old = Table(*get_all_records(booking_file)) for old_booking in old.rows(): member_name = old_booking['name'] member = get_member_by_name(member_name) booking = get_booking(event_id, member.id) booking.date = parse_date(old_booking['date'], reverse=True) booking.playing = old_booking['playing'] == '1' booking.comment = old_booking['comment'] number = int(old_booking['number']) guests = [] for count in range(1, number): name = old_booking['guest{}'.format(count)] hcap = parse_float(old_booking['guest{}_hcap'.format(count)]) guest = first_or_default([g for g in booking.guests if g.name == name], Guest(name=name, booking=booking)) known_player = get_player_by_name(name) if known_player: state = known_player.state_as_of(booking.date) if state.status == PlayerStatus.member: hcap = state.handicap guest.handicap = hcap guests.append(guest) booking.guests = guests save_booking(booking, True) self.assertEqual(1, 1)
def renew_recent_resumers(): resume_date = fmt_date(datetime.date(current_year_end().year, 4, 1)) end_date = fmt_date(datetime.date(current_year_end().year, 8, 1)) query_clauses = [ ('Payment', 'date', resume_date, '>=', None), ('Payment', 'type', PaymentType.dues, '=', None), ('Member', 'end_date', end_date, '=', None), ] members = get_members_for_query(query_clauses) count = 0 message = [] for member in members: if member.is_recent_resume(): member.end_date = new_end_date item = first_or_default([ a for a in member.actions if a.action == MemberAction.card and a.status == ActionStatus.open ], None) if not item: item = Action(member_id=member.id, date=datetime.date.today(), action=MemberAction.card, comment='auto renew recent resumer', status=ActionStatus.open) member.actions.append(item) message += [member.dt_number()] save_member(member) count += 1 return '\n'.join(['{} members updated'.format(count)] + message)
def populate_trophy(self, trophy_id): trophy = get_trophy(trophy_id) self.trophy_name.data = trophy.name self.image_url.data = url_for_html('pictures', 'trophies', trophy.name.lower() + '.jpg') extra_file = 'user/extra/' + trophy.name.lower() + '.htm' if template_exists(extra_file): self.extra.data = extra_file hist = trophy.events for event in hist: tour = first_or_default([ e for e in hist if e.date.year == event.date.year and e.type == EventType.wags_tour ], None) if event.date < datetime.date.today() \ and ((event.type == EventType.wags_vl_event and not tour) \ or (event.type == EventType.wags_tour and tour)): item_form = TrophyItemForm() item_form.venue = event.venue.name item_form.date = fmt_date(event.date) if event.winner: item_form.winner = event.winner.full_name() if event.type == EventType.wags_vl_event: item_form.score = event.winner.score_for( event.id).points item_form.average = event.average_score else: item_form.score = item_form.average = '' else: item_form.winner = item_form.score = item_form.average = '' self.winners.append_entry(item_form)
def get_answer(member, question, single=True, other=False): if other: ret = [q.other for q in member.qandas if q.question_id == question] else: ret = [q.answer for q in member.qandas if q.question_id == question] if single: return first_or_default(ret, None) else: return ret
def member_status_at_renewal(self): status = self.status if status not in [MemberStatus.life, MemberStatus.plus]: upgrade = first_or_default([ a for a in self.actions if a.action == MemberAction.upgrade and a.status == ActionStatus.open and a.comment == 'Upgrade to DT plus' ], None) if upgrade: status = MemberStatus.plus return status
def competition_scratch_score(event): position = 2 while position != 0: candidates = [s for s in event.scores if s.position == position] if any([ c for c in candidates if c.player.state_as_of( event.date).status == PlayerStatus.member ]): scratch = first_or_default([c.points for c in candidates], 0) - 1 position = 0 else: position += 1 return scratch
def update_member_comments(member, details): comments = [] for comment in details['comments']: if comment['comment'] in [None, '']: continue item = first_or_default([c for c in member.comments if c.date == comment['date']], None) if item: item.comment = comment['comment'] else: item = Comment( member_id=member.id, date=comment['date'], comment=comment['comment'] ) comments.append(item) member.comments = comments
def save_event_score(event_id, player_id, position, card, shots, points): event = get_event(event_id) score = first_or_default([s for s in event.scores if s.player_id == player_id], None) if score: score.position = position score.card = card score.shots = shots score.points = points else: score = Score(event_id=event_id, player_id=player_id, position=position, shots=shots, points=points, card=card) event.scores.append(score) db_session.commit()
def save_handicaps(new_table): if len(new_table.data) == 0: return players = set(new_table.get_columns('player_id')) dates = set(new_table.get_columns('date')) current = db_session.query(Handicap).filter(Handicap.date.in_(dates), Handicap.player_id.in_(players)).all() for new in new_table.rows(): hcap = first_or_default([h for h in current if h.player_id == new['player_id'] and h.date == new['date']], None) if hcap: if (hcap.handicap == new['handicap'] and hcap.status == new['status']): continue hcap.handicap = new['handicap'] hcap.status = new['status'] else: hcap = Handicap(player_id=new['player_id'], date=new['date'], handicap=new['handicap'], status=new['status']) db_session.add(hcap) db_session.commit()
def update_member_actions(member, details): actions = [] for action in details['actions']: if action['action'] == 0: continue item = first_or_default([a for a in member.actions if a.date == action['date']], None) if item: item.date = action['date'] item.action = MemberAction(action['action']) item.comment = action['comment'] item.status = ActionStatus(action['status']) else: item = Action( member_id=member.id, date=action['date'], action=MemberAction(action['action']), comment=action['comment'], status=ActionStatus(action['status']) ) actions.append(item) member.actions = actions
def query_fields_action(query_clauses): action = first_or_default([q for q in query_clauses if q[1] == 'action'], None) if action: action = MemberAction.from_value(action[2]).name return action
def is_upgrade(self): return self.is_adult() and \ first_or_default(self.actions, MemberAction.other) == MemberAction
def update_member_renewal(member, details): #handle action item = first_or_default( [a for a in member.actions if a.action == MemberAction.upgrade and a.status == ActionStatus.open], None) if details['upgrade']: date = datetime.date.today() comment = 'Upgrade to DT plus' if item: item.date = date item.action = MemberAction.upgrade item.comment = comment item.status = ActionStatus.open else: item = Action( member_id=member.id, date=date, action=MemberAction.upgrade, comment=comment, status=ActionStatus.open ) member.actions.append(item) elif item: member.actions.remove(item) #handle payment if member.status == MemberStatus.plus: dues = member.plus_dues() else: dues = member.base_dues() + (member.upgrade_dues() if details['upgrade'] else 0) date = datetime.date.today() item = first_or_default([p for p in member.payments if p.type == PaymentType.pending], None) if member.status != MemberStatus.life: payment_method = PaymentMethod.from_value(details['payment_method']) if details['payment_method'] else None if details['upgrade'] and (member.is_recent_new() or member.is_recent_resume()): item = None dues = member.upgrade_dues() payment_comment = 'upgrade only' else: payment_comment = 'renewal payment due' if item: item.date = date item.type = PaymentType.pending item.amount = dues item.method = payment_method item.comment = payment_comment elif dues > 0: item = Payment( member_id=member.id, date=date, type=PaymentType.pending, amount=dues, method=payment_method, comment=payment_comment ) member.payments.append(item) if not details['comment'] in [None, '']: date = datetime.date.today() item = first_or_default([c for c in member.comments if c.date == date], None) if item: item.comment = details['comment'] else: item = Comment( member_id=member.id, date=date, comment=details['comment'] ) member.comments.append(item)
def update_member_payment(rec, payment_method, save=True): # rec is line of payments file with keys id, date, amount and note message = [] number = int(rec['id'][4:]) date = parse_date(rec['date'], sep='/', reverse=True) amount = float(rec['amount']) member = get_member(number) pending = first_or_default([ p for p in member.payments if p.type == PaymentType.pending and p.method == payment_method ], None) payment_comment = 'from payments file' if pending: comment = [''] if pending.amount != amount: comment = [ "Expected amount {}, got {}".format(pending.amount, amount) ] message += comment pending.type = PaymentType.dues pending.date = date pending.amount = amount pending.comment = payment_comment + ' ' + comment[0] else: dues = first_or_default([ p for p in member.payments if p.type == PaymentType.dues and p.method == payment_method ], None) if dues and dues.amount == amount and dues.date == date and dues.comment.startswith( payment_comment): message += ['Payment already processed'] return message else: message += ["no pending payment: adding one"] pending = Payment(member_id=member.id, date=date, amount=amount, type=PaymentType.dues, method=payment_method, comment=payment_comment) member.payments.append(pending) action = first_or_default([ a for a in member.actions if a.action == MemberAction.card and a.status == ActionStatus.open ], None) if not action: action = Action(member_id=member.id, date=datetime.date.today(), action=MemberAction.card, status=ActionStatus.open, comment=payment_comment) member.actions.append(action) upgrade = amount in [20.0, 30.0, 45.0 ] and member.status != MemberStatus.plus action = first_or_default([ a for a in member.actions if a.action == MemberAction.upgrade and a.status == ActionStatus.open ], None) if action: if upgrade: member.status = MemberStatus.plus action.status = ActionStatus.closed # else: # message += ['expected an upgrade payment, upgrade action removed'] # member.actions.remove(action) else: if upgrade: action = Action(member_id=member.id, date=date, action=MemberAction.upgrade, status=ActionStatus.closed, comment=payment_comment) member.actions.append(action) member.end_date = new_end_date member.last_payment_method = payment_method if save: save_member(member) return message
def save_member(member_id, data): new_member = member_id == 0 name = data['first_name'] + ' ' + data['last_name'] orig_name = data['orig_name'] handicap = data['handicap'] status = data['status'] player_id = get_player_id(name if new_member else orig_name) date = data['as_of'] or data['accepted'] access = data['access'] # set player status and handicap if status in [MemberStatus.full_member, MemberStatus.overseas_member]: player_status = PlayerStatus.member else: player_status = PlayerStatus.ex_member if player_id == 0: player = add_player(name, handicap, player_status, date, commit=False) else: player = get_player(player_id) if name != orig_name: player.first_name = data['first_name'] player.last_name = data['last_name'] if handicap != data['orig_handicap'] or status.value != data['orig_status']: state = first_or_default([s for s in player.handicaps if s.date == date], None) if state: state.handicap = handicap state.status = player_status else: state = Handicap(date=date, status=player_status, handicap=handicap) player.handicaps.append(state) # create/update member if new_member: contact = Contact( email=data['email'], address=data['address'], post_code=data['post_code'], phone=data['phone'] ) member = Member( player=player, contact=contact, status=status, proposer_id=data['proposer_id'], accepted=data['accepted'] ) else: member = get_member(member_id) member.contact.email = data['email'] member.contact.address = data['address'] member.contact.post_code = data['post_code'] member.contact.phone = data['phone'] member.player = player member.status = status member.proposer_id = data['proposer_id'] if status.value != data['orig_status']: if status == MemberStatus.full_member: member.accepted = date elif status in (MemberStatus.ex_member, MemberStatus.rip): member.resigned = date else: member.accepted = data['accepted'] if member.user: if not access in [r.role for r in member.user.roles]: member.user.roles.append(Role(user_id=member.user.id, role=access)) db_session.commit()
def choice_name(choices, find_number): return first_or_default([name for (number, name) in choices if number == find_number], None)
def choice_number(choices, find_name): l = len(find_name) find_name = find_name.lower() return first_or_default([number for (number, name) in choices if name.lower()[:l] == find_name], None)