old_contents: from uber.common import *
  
  
  class ReportBase:
      def write_row(self, row, out):
          """This method exists for plugins to monkeypatch and/or override."""
          out.writerow(row)
  
  
  class PersonalizedBadgeReport(ReportBase):
      """
      Generate a CSV file which contains personalized badges with custom printed_names on them
  
      Deferred badges probably should be printed, since in theory a Deferred badge might be checked in.
      For example, a badge might be marked as Deferred if the attendee name matches a name on our watch list,
      but we might find at the event that they're just a different person with the same name.
  
      see discussion: https://github.com/magfest/ubersystem/issues/1648
      """
      def __init__(self, include_badge_nums=True):
          self._include_badge_nums = include_badge_nums
  
      def run(self, out, session, *filters, order_by=None, badge_type_override=None):
          for a in (session.query(sa.Attendee)
                           .filter(sa.Attendee.badge_status != c.INVALID_STATUS, *filters)
                           .order_by(order_by).all()):
              row = [a.badge_num] if self._include_badge_nums else []
              badge_type_label = badge_type_override if badge_type_override else a.badge_type_label
              row += [badge_type_label, a.badge_printed_name or a.full_name]
              self.write_row(row, out)
  
  
  class PrintedBadgeReport(ReportBase):
      """Generate a CSV file of badges which do not have customized information"""
      def __init__(self, badge_type, include_badge_nums=True, range=None):
          self._badge_type = badge_type
          self._include_badge_nums = include_badge_nums
          self._range = range
  
      def run(self, out, session):
          badge_range = c.BADGE_RANGES[self._badge_type]
          min_badge_num = max([badge_range[0]] + ([self._range[0]] if self._range else []))
          max_badge_num = min([badge_range[1]] + ([self._range[1]] if self._range else [])) + 1
  
          empty_customized_name = ''
          empty_badge_type = ''
  
          for badge_num in range(min_badge_num, max_badge_num):
              self.write_row([badge_num, empty_badge_type, empty_customized_name], out)
  
new_contents: from uber.common import *
  
  
  class ReportBase:
      def write_row(self, row, out):
          """This method exists for plugins to monkeypatch and/or override."""
          out.writerow(row)
  
  
  class PersonalizedBadgeReport(ReportBase):
      """
      Generate a CSV file which contains personalized badges with custom printed_names on them
  
      Deferred badges probably should be printed, since in theory a Deferred badge might be checked in.
      For example, a badge might be marked as Deferred if the attendee name matches a name on our watch list,
      but we might find at the event that they're just a different person with the same name.
  
      see discussion: https://github.com/magfest/ubersystem/issues/1648
      """
      def __init__(self, include_badge_nums=True):
          self._include_badge_nums = include_badge_nums
  
      def run(self, out, session, *filters, order_by=None, badge_type_override=None):
          badge_nums_seen = []
  
          for a in (session.query(sa.Attendee)
                           .filter(sa.Attendee.badge_status != c.INVALID_STATUS, *filters)
                           .order_by(order_by).all()):
  
              # sanity check no duplicate badges
              if a.badge_num in badge_nums_seen:
                  raise ValueError("duplicate badge number detected: %s" % a.badge_num)
              badge_nums_seen += [a.badge_num]
  
              # write the actual data
              row = [a.badge_num] if self._include_badge_nums else []
              badge_type_label = badge_type_override if badge_type_override else a.badge_type_label
              row += [badge_type_label, a.badge_printed_name or a.full_name]
              self.write_row(row, out)
  
  
  class PrintedBadgeReport(ReportBase):
      """Generate a CSV file of badges which do not have customized information"""
      def __init__(self, badge_type, include_badge_nums=True, range=None):
          self._badge_type = badge_type
          self._include_badge_nums = include_badge_nums
          self._range = range
  
      def run(self, out, session):
          badge_range = c.BADGE_RANGES[self._badge_type]
          min_badge_num = max([badge_range[0]] + ([self._range[0]] if self._range else []))
          max_badge_num = min([badge_range[1]] + ([self._range[1]] if self._range else [])) + 1
  
          empty_customized_name = ''
          empty_badge_type = ''
  
          for badge_num in range(min_badge_num, max_badge_num):
              self.write_row([badge_num, empty_badge_type, empty_customized_name], out)
  
subject: add crude duplicate badge number check to printed badge exports - this won't catch every weird case but will catch the bulk of the issues we're seeing