示例#1
0
def ignore_payment(transaction, log_user, reason):
    try:
        payment = Payment.objects.get(transaction_id=transaction)
        if not payment.ignore and not payment.billingcycle:
            payment.ignore = True
            payment.save()
            log_change(payment, log_user, change_message="Ignored by manual_matches: %s" % reason)
    except Payment.DoesNotExist:
        pass
示例#2
0
def ignore_payment(transaction, log_user, reason):
    try:
        payment = Payment.objects.get(transaction_id=transaction)
        if not payment.ignore and not payment.billingcycle:
            payment.ignore = True
            payment.save()
            log_change(payment, log_user, change_message="Ignored by manual_matches: %s" % reason)
    except Payment.DoesNotExist:
        pass
示例#3
0
def process_csv(filename):
    """Actual CSV file processing logic
    """
    num_attached = num_notattached = 0
    sum_attached = sum_notattached = 0
    num_nomember = num_nopayment = num_nocycle = num_old = 0
    log_user = User.objects.get(id=1)
    with open(filename, 'r') as f:
        reader = csv.reader(f)
        for row in reader:
            (mid, year, date, reference, transaction) = row
            try:
                membership = Membership.objects.get(id=int(mid))
                cycle = find_cycle(membership, year)
                payment = Payment.objects.get(transaction_id=transaction)

                if payment.billingcycle:  # Already assigned, mark cycle as paid
                    if payment.billingcycle != cycle:
                        mark_cycle_paid(
                            cycle, log_user,
                            "One payment for several billing cycles")
                    num_old += 1
                    continue
                payment.attach_to_cycle(cycle)
                log_change(payment,
                           log_user,
                           change_message="Attached by manual_matches")
                num_attached += 1
                sum_attached += payment.amount
                continue
            except Membership.DoesNotExist:
                logger.warning("Membership %s not found. transaction id: %s" %
                               (mid, transaction))
                # Payment references a billing cycle for a removed member - ignore
                ignore_payment(transaction, log_user, "no member")
                num_nomember += 1
            except BillingCycle.DoesNotExist:
                # Payment references a legacy billing cycle - ignore payment
                ignore_payment(transaction, log_user, "legacy payment")
                num_nocycle += 1
            except Payment.DoesNotExist:
                if not cycle.is_paid:
                    logger.warning(
                        "No transaction found for id: %s, member: %s year: %s. Marking as paid anyway"
                        % (transaction, mid, year))
                    mark_cycle_paid(cycle, log_user,
                                    "Paid by a legacy payment (before 2010)")
                num_nopayment += 1
            num_notattached = num_notattached + 1

    logger.info(
        "Processed %s payments, attached %s payments, total %.2f EUR. Unidentified payments: %s"
        % (num_attached + num_notattached, num_attached, sum_attached,
           num_notattached))
    logger.info(
        "No members: %s, no cycle: %s, no payment in db: %s, already attached to a cycle: %s"
        % (num_nomember, num_nocycle, num_nopayment, num_old))
示例#4
0
文件: views.py 项目: ptMuta/sikteeri
def alias_edit(request, id, template_name='membership/entity_edit.html'):
    alias = get_object_or_404(Alias, id=id)

    class Form(ModelForm):
        class Meta:
            model = Alias
            fields = '__all__'

        owner = ModelChoiceField(
            queryset=Membership.objects.filter(pk=alias.owner.id),
            empty_label=None)

        @staticmethod
        def clean_name():
            return alias.name

        @staticmethod
        def clean_owner():
            return alias.owner

        def disable_fields(self):
            self.fields['name'].required = False
            self.fields['name'].widget.attrs['readonly'] = 'readonly'
            self.fields['owner'].required = False
            self.fields['owner'].widget.attrs['readonly'] = 'readonly'

    if request.method == 'POST':
        form = Form(request.POST, instance=alias)
        before = model_to_dict(alias)
        form.disable_fields()
        if form.is_valid():
            form.save()
            after = model_to_dict(alias)
            log_change(alias, request.user, before, after)
            return redirect(
                'alias_edit',
                id)  # form stays as POST otherwise if someone refreshes
    else:
        form = Form(instance=alias)
        form.disable_fields()
    logentries = bake_log_entries(alias.logs.all())
    return render_to_response(template_name, {
        'form': form,
        'alias': alias,
        'logentries': logentries
    },
                              context_instance=RequestContext(request))
示例#5
0
def process_csv(filename):
    """Actual CSV file processing logic
    """
    num_attached = num_notattached = 0
    sum_attached = sum_notattached = 0
    num_nomember = num_nopayment = num_nocycle = num_old = 0
    log_user = User.objects.get(id=1)
    with open(filename, 'r') as f:
        reader = csv.reader(f)
        for row in reader:
            (mid, year, date, reference, transaction) = row
            try:
                membership = Membership.objects.get(id=int(mid))
                cycle = find_cycle(membership, year)
                payment = Payment.objects.get(transaction_id=transaction)

                if payment.billingcycle: # Already assigned, mark cycle as paid
                    if payment.billingcycle != cycle:
                        mark_cycle_paid(cycle, log_user, "One payment for several billing cycles")
                    num_old += 1
                    continue
                payment.attach_to_cycle(cycle)
                log_change(payment, log_user, change_message="Attached by manual_matches")
                num_attached += 1
                sum_attached += payment.amount
                continue
            except Membership.DoesNotExist:
                logger.warning("Membership %s not found. transaction id: %s" % (mid, transaction))
                # Payment references a billing cycle for a removed member - ignore
                ignore_payment(transaction, log_user, "no member")
                num_nomember += 1
            except BillingCycle.DoesNotExist:
                # Payment references a legacy billing cycle - ignore payment
                ignore_payment(transaction, log_user, "legacy payment")
                num_nocycle += 1
            except Payment.DoesNotExist:
                if not cycle.is_paid:
                    logger.warning("No transaction found for id: %s, member: %s year: %s. Marking as paid anyway" % (transaction, mid, year))
                    mark_cycle_paid(cycle, log_user, "Paid by a legacy payment (before 2010)")
                num_nopayment += 1
            num_notattached = num_notattached + 1

    logger.info("Processed %s payments, attached %s payments, total %.2f EUR. Unidentified payments: %s" %
                (num_attached + num_notattached, num_attached, sum_attached, num_notattached))
    logger.info("No members: %s, no cycle: %s, no payment in db: %s, already attached to a cycle: %s" %
                (num_nomember, num_nocycle, num_nopayment, num_old))
示例#6
0
def attach_payment_to_cycle(payment):
    """
    Outside of this module, this function is mainly used by
    generate_test_data.py.
    """
    if payment.ignore == True or payment.billingcycle != None:
        raise Exception("Unexpected function call. This shouldn't happen.")
    reference = payment.reference_number
    cycle = BillingCycle.objects.get(reference_number=reference)
    if cycle.is_paid == False or cycle.amount_paid() < cycle.sum:
        payment.attach_to_cycle(cycle)
    else:
        # Don't attach a payment to a cycle with enough payments
        payment.comment = _('duplicate payment')
        log_user = User.objects.get(id=1)
        log_change(payment, log_user, change_message="Payment not attached due to duplicate payment")
        payment.save()
        return None
    return cycle
示例#7
0
def alias_edit(request, id, template_name='membership/entity_edit.html'):
    alias = get_object_or_404(Alias, id=id)

    class Form(ModelForm):
        class Meta:
            model = Alias
            fields = '__all__'

        owner = ModelChoiceField(queryset=Membership.objects.filter(pk=alias.owner.id),
                                 empty_label=None)

        @staticmethod
        def clean_name():
            return alias.name

        @staticmethod
        def clean_owner():
            return alias.owner

        def disable_fields(self):
            self.fields['name'].required = False
            self.fields['name'].widget.attrs['readonly'] = 'readonly'
            self.fields['owner'].required = False
            self.fields['owner'].widget.attrs['readonly'] = 'readonly'

    if request.method == 'POST':
        form = Form(request.POST, instance=alias)
        before = model_to_dict(alias)
        form.disable_fields()
        if form.is_valid():
            form.save()
            after = model_to_dict(alias)
            log_change(alias, request.user, before, after)
            return redirect('alias_edit', id) # form stays as POST otherwise if someone refreshes
    else:
        form = Form(instance=alias)
        form.disable_fields()
    logentries = bake_log_entries(alias.logs.all())
    return render_to_response(template_name, {'form': form,
        'alias': alias, 'logentries': logentries},
        context_instance=RequestContext(request))
示例#8
0
def mark_cycle_paid(cycle, log_user, reason):
    if not cycle.is_paid:
        cycle.is_paid = True
        cycle.save()
        log_change(cycle, log_user, change_message=reason)
示例#9
0
def mark_cycle_paid(cycle, log_user, reason):
    if not cycle.is_paid:
        cycle.is_paid = True
        cycle.save()
        log_change(cycle, log_user, change_message=reason)
示例#10
0
def create_member(mdata, logins):
    # legacy fields
    # ['application_id', 'sendinfo', 'memberclass', 'applicationtime', 'sms',
    # 'id', 'email', 'website', 'publicwebsite', 'lastname', 'phone',
    # 'firstnames', 'address', 'nationality', 'post', 'removed', 'publicname',
    # 'name', 'mobile', 'residence', 'time', 'publicemail', 'period_start',
    # 'period_end']
    # TODO: latest billing period start date?
    post_index = mdata['post'].find(' ')
    postcode = mdata['post'][:post_index]
    postoffice = mdata['post'][post_index+1:]
    d = {
        'street_address' : mdata['address'],
        'postal_code' : postcode,
        'post_office' : postoffice,
        'country' : mdata['nationality'],
        'phone' : mdata['phone'].replace(" ", "").replace("-", ""),
        'sms' : mdata['sms'].replace(" ", "").replace("-", ""),
        'email' : mdata['email'].strip(" "),
        'homepage' : mdata['website'].strip(" "),
        'first_name' : mdata['name'].strip(" "),
        'given_names' : mdata['firstnames'].strip(" "),
        'last_name' : mdata['lastname'].strip(" "),
        # mdata['application_id'],
        # mdata['sendinfo'],
    }

    # Hide non-public websites
    if not mdata['publicwebsite']:
        d['homepage'] = ""

    if not mdata['memberclass']:
        mtype = 'P'
        print >> sys.stderr, "# Member type missing for member %d" % mdata['id']
    elif mdata['memberclass'] == 'member':
        mtype = 'P'
    elif mdata['memberclass'] == 'supporting':
        mtype = 'S'
    elif mdata['memberclass'] == 'organization':
        mtype = 'O'
    elif mdata['memberclass'] == 'honorary':
        mtype = 'H'
    else:
        print >> sys.stderr, "! Not importing, member class unknown for member %d" % mdata['id']
        return False

    contact = Contact(**d)
    contact.save()
    if mtype == 'O':
        membership = Membership(id=mdata['id'], type=mtype, status='A',
                                created=datetime.utcfromtimestamp(mdata['time']),
                                approved=datetime.utcfromtimestamp(mdata['time']),
                                organization=contact,
                                nationality=mdata['nationality'],
                                municipality=mdata['residence'],
                                extra_info='Imported from legacy',
                                public_memberlist=bool(mdata['publicname']))
    else:
        membership = Membership(id=mdata['id'], type=mtype, status='A',
                                created=datetime.utcfromtimestamp(mdata['time']),
                                approved=datetime.utcfromtimestamp(mdata['time']),
                                person=contact,
                                nationality=mdata['nationality'],
                                municipality=mdata['residence'],
                                extra_info='Imported from legacy',
                                public_memberlist=bool(mdata['publicname']))
    logger.info("Member %s imported from legacy database." % (unicode(contact)))
    membership.save()

    # Create a period only if there already is one previously. Else let
    # makebills create one.
    if mdata.has_key('period_start'):
        billing_cycle = BillingCycle(membership=membership, is_paid=False,
                                     start=datetime.strptime(mdata['period_start'], "%Y-%m-%d %H:%M:%S"),
                                     end=datetime.strptime(mdata['period_end'], "%Y-%m-%d %H:%M:%S")+timedelta(days=1))
        billing_cycle.save()
        bill = Bill(billingcycle=billing_cycle)
        bill.save()
        # Due to auto_now_add, need to save first before changing
        bill.created=datetime.strptime(mdata['bill_creation'], "%Y-%m-%d %H:%M:%S")
        bill.due_date=datetime.strptime(mdata['bill_dueday'], "%Y-%m-%d %H:%M:%S")
        bill.save()
    for alias in mdata['aliases']:
        if alias in logins:
            a = Alias(owner=membership, name=alias, account=True,
                      created=membership.created)
        else:
            a = Alias(owner=membership, name=alias, account=False,
                      created=membership.created)
        a.save()

        account_alias_count = Alias.objects.filter(owner=a.owner, account=True).count()
        if account_alias_count > 1:
            logger.warning("%i account aliases for %s" % (account_alias_count, a.owner))

    log_change(membership, user, change_message="Imported into system")
    return True