Exemple #1
0
def payment_ok(sender, **kwargs):
    log.debug("Payment OK")
    payment = gooN(Payment, code=sender.invoice)
    if not payment:
        log.error("Coudnt find payment for invoice %s" % sender.invoice)
        return
    else:
        log.info('Payment: user=%s price=%s invoice=%s' %
                 (payment.user, payment.price, payment.code))

    user_profile = UserProfile.objects.get_or_create(user=payment.user)[0]
    user_profile.credits += payment.credits
    user_profile.save()

    payment.set_paid()
    payment.save()

    if payment.coupon:
        log.info("Coupon code %s has been used by user %s" %
                 (payment.coupon.code, payment.user))
        if payment.coupon.used:
            log.error("It was already used by someone else. Fraud warning!")
        coupon = payment.coupon
        coupon.set_used()
        coupon.save()

    log.info("User %s has paid at price %s" % (payment.user, payment.price))
Exemple #2
0
def payments(req):
    coupon = None
    if req.GET.get('coupon', None):
        coupon = Coupon.objects.filter(used=False,
                                       code=req.GET.get('coupon', None))[:1]
        if coupon:
            coupon = coupon[0]
            log.debug('User %s (pk:%s) passed valid cupon: %s' %
                      (req.user, req.user.pk, req.GET['coupon']))
        else:
            messages.error(req, _('Invalid coupon code!'))
            log.debug('User %s (pk:%s) passed invalid coupon %s' %
                      (req.user, req.user.pk, req.GET['coupon']))
            coupon = None

            url = furl.furl(req.get_full_path())
            del url.args['coupon']
            return redirect(str(url))

    if 'plan' in req.POST:
        # find plan selected by the user
        plan = gooN(CreditsPricingPlan, pk=req.POST["plan"])

        if not plan:
            messages.error(req, _('Error during payments processing. Sorry.'))
            log.warning(
                'User %s (pk:%s) wanted to buy pricing plan which not exists (pk:%s) (1337?)'
                % (req.user, req.user.pk, req.POST['plan']))
            return redirect('/')
        if not plan.is_active:
            messages.error(req, _('Error during payments processing. Sorry.'))
            log.warning(
                'User %s (pk:%s) wanted to buy pricing plan which is not allowed (pk:%s) (1337?)'
                % (req.user, req.user.pk, req.POST['plan']))
            return redirect('/')

        log.debug("pricing plan selected: %s (pk:%s)" % (plan, plan.pk))
        log.debug("coupon used: %s" % coupon)

        # create transaction for user
        payment = Payment.make_from_pricing_plan(req.user, plan, coupon)
        # WARNING: coupon waits for paypal signal
        payment.save()

        # safety check for free coupons
        if payment.price < Decimal("0.01"):  # minimal paypal amount is 0.01
            log.info('user %s (pk:%s) just bought plan pk=%s for 0.0$' %
                     (req.user, req.user.pk, plan.pk))

            payment.price = Decimal("0")
            payment.set_paid()
            payment.save()

            coupon.set_used()
            coupon.save()

            profile = req.user.userprofile
            profile.credits += plan.credits
            profile.save()

            #TODO: pluralize gettext
            messages.info(req,
                          _("You just got %d free credits!") % plan.credits)
            return redirect(req.path)

        log.info("Build form for plan %s and build paypal form" % plan)
        return {
            'TEMPLATE': 'payments/paypal_redirection.html',
            'paypal_form': payment.render_paypal_form(req),
        }
    pricing_plans = list(
        CreditsPricingPlan.objects.filter(is_active=True).order_by('credits'))
    if coupon:
        for plan in pricing_plans:
            plan.new_price = coupon.discount_price(plan.price)

    return dict(
        # current coupon
        coupon=coupon,
        payments=req.user.payment_set.filter(
            is_paid=True).order_by('-date_created'),
        pricing_plans=pricing_plans,
    )
    def update_applicant(self, which, app_blob):
        '''

        **** THIS ONE WORKS:
        if no new social AND the name is the same as current one:
            use the current one because I'm not changing the social and the name stayed the same.
        else if there is a match:
            use it instead of the current one.  It already exists.
        else If the current one has a person_id and is locked:
            make a new one, because I can't reuse the current one (it is locked with a social).
        else (there isn't one, and the current one has no person_id):
            use the current one, because it isn't locked and can be altered.

        '''

        new_social = app_blob.get('social') or None  # blank is None.
        new_social_type = app_blob.get('social_type', 'US')

        current = getattr(self.agreement, which)
        name_same = False
        cap = lambda n: (n or '').upper()

        # Determine if the name is the same.
        if current:
            current_name = (cap(current.first_name), cap(current.last_name))
        else:
            current_name = ('', '')

        new_name = (cap(app_blob.get('first_name')),
                    cap(app_blob.get('last_name')))

        name_same = current_name == new_name

        # If the social is provided, look up an exact match.
        exact_match = None
        if new_social:
            new_person_id = Applicant.generate_person_id(
                app_blob.get('first_name'), app_blob.get('last_name'),
                new_social)
            if new_person_id:
                exact_match = gooN(Applicant, person_id=new_person_id)

        new_applicant = None
        if exact_match:
            print "Reusing exact match."
            # Reuse the found exact match.
            # It might even BE the current one if nothing changed.
            new_applicant = exact_match
        elif current and not new_social and name_same:
            print "Reusing because name is same."
            # Reuse the current one because I didn't provide a new_social and the name is the same.
            new_applicant = current
        elif current and current.person_id:
            print "Making new because current has a person_id"
            # Make a new one, because the current isn't an exact match or even a soft match because no social was given
            new_applicant = Applicant(agreement=self.agreement)
        elif not current:
            print "Making new because no current."
            # Make a new one, because there isn't an exact match or a current to use.
            new_applicant = Applicant(agreement=self.agreement)
        else:
            print "Using current because."
            # Reuse the current one, because it exists and isn't locked.
            new_applicant = current

        new_applicant.update_from_blob(app_blob, updater=self)
        print "After update with %r, applicant %r has person_id %r" % (
            app_blob, new_applicant, new_applicant.person_id)
        #if not new_applicant.pk:
        new_applicant.save()
        print "Setting agreement's %s to %r" % (which, new_applicant)
        setattr(self.agreement, which, new_applicant)
        if not current or current.pk != new_applicant.pk:
            self.agreement.save()
Exemple #4
0
    def get_credit_status(self):
        if not self.person_id:
            return None

        # Social is None, or a dictionary with keys 'social' and 'social_type'

        # Do I have a credit file for me?
        from credit_file import CreditFile, CreditRequest
        cfs = CreditFile.objects.filter(applicant=self)
        print "Found cfs: ", list(cfs)
        if cfs:
            status_strings = [cf.status_string for cf in cfs]
            print "status strings: ", status_strings
            for status in ('APPROVED', 'REVIEW', 'NO HIT', 'DCS'):
                if status in status_strings:
                    return status
            return 'ERROR'  # It's not possible for a credit file to not be one of those four.



        # I don't have a credit file for me,
        # so see if I can find and copy one.
        earliest_reusable = datetime.now() - settings.CREDIT_REUSABLE_SPAN
        reusable = list(CreditFile.objects.filter(person_id=self.person_id, generated_date__gte=earliest_reusable))

        if reusable:
            reusable.sort(key=lambda cf: cf.generated_date, reversed=True)
            reuse = reusable[0]
            cf = reuse.clone(applicant=self)

            # I found one and cloned it, now return its status_string.
            return cf.status_string

        # I don't have one, and I couldn't clone one, so I need to run.

        # but if I already made a request, I'm pending.
        credit_request = gooN(CreditRequest, applicant=self, processed=0, error=0)

        if credit_request:
            if getattr(settings, 'MOCK_CREDIT', None):
                self.run_mock_credit(credit_request)
                return self.get_credit_status()

            return 'PENDING'

        # If I don't have a social, I can't start it.
        if not self.social_data:
            #if list(CreditRequest.objects.filter(applicant=self, error=1)):
            #    return 'ERROR'

            return None

        system_address = self.agreement.system_address
        if not system_address or not all([getattr(system_address, k, None) for k in ('street1', 'city', 'state', 'zip')]):
            return None



        # This will fail because system_address will be null, but this list will keep getting constructed and raise an error.
        # things_to_check =   [   self.agreement.system_address,
        #                         self.agreement.system_address.street1,
        #                         self.agreement.system_address.city,
        #                         self.agreement.system_address.state,
        #                         self.agreement.system_address.zip,
        #                     ]
        # # anyone home?
        # try:
        #     first_not_falsy = next((thing for thing in things_to_check if thing))
        # except StopIteration:
        #     return None


        # Is the social I got passed in actually what's on this
        # agreement?  This should never not be true.
        # sanity_check = self.person_id == Applicant.generate_person_id(self.first_name, self.last_name, social['social'], social['social_type'])
        # if not sanity_check:
        #     # XXX this should probably be handled smarter.
        #     # I'd use an assert but I don't want to 500 here.
        #     print "SANITY CHECK FAILED"
        #     print social
        #     return 'ERROR'



        rq = CreditRequest.create_request(applicant=self)
        self.social_data = None
        self.save()

        # Mock credit run.
        if getattr(settings, 'MOCK_CREDIT', None):
            self.run_mock_credit(rq)
            return self.get_credit_status()

        return 'PENDING'
PGMembership(pricegroup=inside_group, pricetable=inside_pt).save()

#inside_group.pricetables.add(inside_pt)

csp_group = PriceGroup(name='csp')
csp_group.save()
#csp_group.pricetables.add(csp_pt)
PGMembership(pricegroup=csp_group, pricetable=csp_pt).save()

organizations = {}


for camp in camps:
    org_code = camp['org_code']
    if org_code not in organizations:
        o = gooN(Organization, org_code=org_code)
        if not o:
            print "Creating org ", org_code
            o = Organization(org_code=org_code, name=camp['org_name'], distribution_email=camp['distribution_email'])
            if org_code == 'protectamerica':
                o.pricegroup = inside_group
            else:
                o.pricegroup = csp_group
            o.save()
        else:
            print "Found org ", org_code
        organizations[org_code] = o
    else:
        o = organizations[org_code]

    campaign_id = camp['campaign_id']
    def update_applicant(self, which, app_blob):
        '''

        **** THIS ONE WORKS:
        if no new social AND the name is the same as current one:
            use the current one because I'm not changing the social and the name stayed the same.
        else if there is a match:
            use it instead of the current one.  It already exists.
        else If the current one has a person_id and is locked:
            make a new one, because I can't reuse the current one (it is locked with a social).
        else (there isn't one, and the current one has no person_id):
            use the current one, because it isn't locked and can be altered.

        '''

        new_social = app_blob.get('social') or None # blank is None.
        new_social_type = app_blob.get('social_type', 'US')

        current = getattr(self.agreement, which)
        name_same = False
        cap = lambda n: (n or '').upper()

        # Determine if the name is the same.
        if current:
            current_name = (cap(current.first_name), cap(current.last_name))
        else:
            current_name = ('', '')

        new_name = (cap(app_blob.get('first_name')), cap(app_blob.get('last_name')))

        name_same = current_name == new_name

        # If the social is provided, look up an exact match.
        exact_match = None
        if new_social:
            new_person_id = Applicant.generate_person_id(app_blob.get('first_name'), app_blob.get('last_name'), new_social)
            if new_person_id:
                exact_match = gooN(Applicant, person_id=new_person_id)

        new_applicant = None
        if exact_match:
            print "Reusing exact match."
            # Reuse the found exact match.
            # It might even BE the current one if nothing changed.
            new_applicant = exact_match
        elif current and not new_social and name_same:
            print "Reusing because name is same."
            # Reuse the current one because I didn't provide a new_social and the name is the same.
            new_applicant = current
        elif current and current.person_id:
            print "Making new because current has a person_id"
            # Make a new one, because the current isn't an exact match or even a soft match because no social was given
            new_applicant = Applicant(agreement=self.agreement)
        elif not current:
            print "Making new because no current."
            # Make a new one, because there isn't an exact match or a current to use.
            new_applicant = Applicant(agreement=self.agreement)
        else:
            print "Using current because."
            # Reuse the current one, because it exists and isn't locked.
            new_applicant = current


        new_applicant.update_from_blob(app_blob, updater=self)
        print "After update with %r, applicant %r has person_id %r" % (app_blob, new_applicant, new_applicant.person_id)
        #if not new_applicant.pk:
        new_applicant.save()
        print "Setting agreement's %s to %r" % (which, new_applicant)
        setattr(self.agreement, which, new_applicant)
        if not current or current.pk != new_applicant.pk:
            self.agreement.save()
inside_group.save()
PGMembership(pricegroup=inside_group, pricetable=inside_pt).save()

#inside_group.pricetables.add(inside_pt)

csp_group = PriceGroup(name='csp')
csp_group.save()
#csp_group.pricetables.add(csp_pt)
PGMembership(pricegroup=csp_group, pricetable=csp_pt).save()

organizations = {}

for camp in camps:
    org_code = camp['org_code']
    if org_code not in organizations:
        o = gooN(Organization, org_code=org_code)
        if not o:
            print "Creating org ", org_code
            o = Organization(org_code=org_code,
                             name=camp['org_name'],
                             distribution_email=camp['distribution_email'])
            if org_code == 'protectamerica':
                o.pricegroup = inside_group
            else:
                o.pricegroup = csp_group
            o.save()
        else:
            print "Found org ", org_code
        organizations[org_code] = o
    else:
        o = organizations[org_code]