Example #1
0
    def create_payment(cls, user, entrant, amount, project, payment_instrument):
        """
        Create a payment based on a configured payment_instrument.

        :user: a User making the payment
        :entrant: a User entering the payment. if user==entrant then organic payment.
        :amount: float amount in USD
        :project: Project associated with payment
        :payment_instrument: a PaymentInstrument object (see PayPalCreditCardInstrument)
        :return: revolv.payments.models.PaymentTransaction
        """
        if not cls.check_valid_payment_instrument(payment_instrument.type):
            raise PaymentServiceException('Not a valid payment instrument.')
        if not cls.check_valid_amount(amount):
            raise PaymentServiceException('Not a valid dollar amount.')
        if not cls.check_valid_user_entrant(user, entrant, payment_instrument.type):
            raise PaymentServiceException('Improper Payment structure. Invalid entrant or user.')

        amount = floor(amount * 100) / 100.0  # floor amount to 2 decimal places

        if settings.ENABLE_PAYMENT_CHARGING:
            payment_instrument.charge(amount)
        payment = Payment(
            user=user,
            entrant=entrant,
            amount=amount,
            project=project,
            payment_type=payment_instrument.type
        )
        payment.save()
        return payment
Example #2
0
def distribute_reinvestment_fund():
    """
    This task is for Automatic reinvestment

    This is how this script do:
    1. Get all project that is eligible for reinvestment:
        (project with monthly_reinvestment_cap >0 and not fully funded)
    2. For each project determine how we'll reinvest
    3. Add AdminReinvestment object with above value
    4. Reinvestment every user's reinvestment amount in project funding proportion.
    """

    time.sleep(60)
    ADMIN_PAYMENT_USERNAME = settings.ADMIN_PAYMENT_USERNAME

    try:
        admin = RevolvUserProfile.objects.get(
            user__username=ADMIN_PAYMENT_USERNAME)
    except RevolvUserProfile.DoesNotExist:
        logger.error("Can't find admin user: {0}. System exiting!".format(
            ADMIN_PAYMENT_USERNAME))
        sys.exit()

    total_funding_goal = Project.objects.get_active().aggregate(
        total=Sum('funding_goal'))['total']
    pending_reinvestors = []

    users = RevolvUserProfile.objects.filter(reinvest_pool__gt=0.0)
    for user in users:
        reinvest_pool = user.reinvest_pool
        pending_reinvestors.append((user, reinvest_pool))
    for project in Project.objects.get_active():
        reinvest_amount_praportion = float(
            project.funding_goal) / float(total_funding_goal)

        for (user, reinvest_pool) in pending_reinvestors:
            amount = reinvest_pool * float(
                "{0:.2f}".format(reinvest_amount_praportion))
            logger.info('Trying to reinvest %s in %s project!',
                        format(round(amount, 2)), project.title)

            adminReinvestment = AdminReinvestment.objects.create(
                amount=format(round(amount, 2)), admin=admin, project=project)
            reinvestment = Payment(
                user=user,
                project=project,
                entrant=admin,
                payment_type=PaymentType.objects.get_reinvestment_fragment(),
                admin_reinvestment=adminReinvestment,
                amount=format(round(amount, 2)))

            if project.amount_donated >= project.funding_goal:
                project.project_status = project.COMPLETED
                project.save()
            reinvestment.save()

    for user in users:
        if user.reinvest_pool <= 0.01:
            user.reinvest_pool = 0
            user.save()
Example #3
0
    def create_payment(cls, user, entrant, amount, project,
                       payment_instrument):
        """
        Create a payment based on a configured payment_instrument.

        :user: a User making the payment
        :entrant: a User entering the payment. if user==entrant then organic payment.
        :amount: float amount in USD
        :project: Project associated with payment
        :payment_instrument: a PaymentInstrument object (see PayPalCreditCardInstrument)
        :return: revolv.payments.models.PaymentTransaction
        """
        if not cls.check_valid_payment_instrument(payment_instrument.type):
            raise PaymentServiceException('Not a valid payment instrument.')
        if not cls.check_valid_amount(amount):
            raise PaymentServiceException('Not a valid dollar amount.')
        if not cls.check_valid_user_entrant(user, entrant,
                                            payment_instrument.type):
            raise PaymentServiceException(
                'Improper Payment structure. Invalid entrant or user.')

        amount = floor(
            amount * 100) / 100.0  # floor amount to 2 decimal places

        if settings.ENABLE_PAYMENT_CHARGING:
            payment_instrument.charge(amount)
        payment = Payment(user=user,
                          entrant=entrant,
                          amount=amount,
                          project=project,
                          payment_type=payment_instrument.type)
        payment.save()
        return payment
Example #4
0
 def create_check(cls, user, entrant, amount, project):
     check = Payment(user=user,
                     entrant=entrant,
                     amount=float(amount),
                     project=project,
                     payment_type=PaymentType.objects.get_check())
     check.save()
     return check
Example #5
0
 def create_check(cls, user, entrant, amount, project):
     check = Payment(
         user=user,
         entrant=entrant,
         amount=float(amount),
         project=project,
         payment_type=PaymentType.objects.get_check()
     )
     check.save()
     return check
Example #6
0
 def create_repayment(cls, entrant, amount, project):
     donations = Payment.objects.all_donations().filter(project=project)
     total = project.amount_donated
     for donation in donations:
         repayment = Payment(
             user=donation.user,
             entrant=entrant,
             amount=float(amount) * (donation.amount / total),
             project=project,
             payment_type=PaymentType.objects.get_repayment())
         repayment.save()
     return
Example #7
0
 def create_repayment(cls, entrant, amount, project):
     donations = Payment.objects.all_donations().filter(project=project)
     total = project.amount_donated
     for donation in donations:
         repayment = Payment(
             user=donation.user,
             entrant=entrant,
             amount=float(amount) * (donation.amount / total),
             project=project,
             payment_type=PaymentType.objects.get_repayment()
         )
         repayment.save()
     return
Example #8
0
def post_save_admin_reinvestment(**kwargs):
    """
    When an AdminReinvestment is saved, we pool as many donors as we need to
    fund the reinvestment, prioritizing users that have a preference for the
    Category of the project begin invested into and the by order them by thier
    last name. We only consider users that have a non-zero pool of investable money.

    """
    if not kwargs.get('created'):
        return
    instance = kwargs.get('instance')
    total_left = instance.amount
    pending_reinvestors = []

    project = instance.project
    # the list of users with at least one preferred category that matches any of the
    # categories that the project is tagged with
    users_with_preferences = RevolvUserProfile.objects.filter(
        preferred_categories__in=project.category_set.all()).filter(
            reinvest_pool__gt=0.0)
    # iterates through users with preferred categories first
    for user in users_with_preferences:
        total_left -= user.reinvest_pool
        reinvest_amount = user.reinvest_pool + min(0.0, total_left)
        pending_reinvestors.append((user, reinvest_amount))
        if total_left <= 0.0:
            break

    # if we still have money we want to reinvest, loop through users without preferences
    if total_left > 0.0:
        users_without_preferences = RevolvUserProfile.objects.filter(reinvest_pool__gt=0.0)\
            .exclude(pk__in=users_with_preferences).order_by('user__last_name')
        for user in users_without_preferences:
            total_left -= user.reinvest_pool
            reinvest_amount = user.reinvest_pool + min(0.0, total_left)
            pending_reinvestors.append((user, reinvest_amount))
            if total_left <= 0.0:
                break
    for (user, amount) in pending_reinvestors:
        reinvestment = Payment(
            user=user,
            project=instance.project,
            entrant=instance.admin,
            payment_type=PaymentType.objects.get_reinvestment_fragment(),
            admin_reinvestment=instance,
            amount=amount)
        # user's reinvest_pool will be decremented on this Payment's save
        reinvestment.save()
Example #9
0
def post_save_admin_reinvestment(**kwargs):
    """
    When an AdminReinvestment is saved, we pool as many donors as we need to
    fund the reinvestment, prioritizing users that have a preference for the
    Category of the project begin invested into and the by order them by thier
    last name. We only consider users that have a non-zero pool of investable money.

    """
    if not kwargs.get('created'):
        return
    instance = kwargs.get('instance')
    total_left = instance.amount
    pending_reinvestors = []

    project = instance.project
    # the list of users with at least one preferred category that matches any of the
    # categories that the project is tagged with
    users_with_preferences = RevolvUserProfile.objects.filter(preferred_categories__in=project.category_set.all()).filter(reinvest_pool__gt=0.0)
    # iterates through users with preferred categories first
    for user in users_with_preferences:
        total_left -= user.reinvest_pool
        reinvest_amount = user.reinvest_pool + min(0.0, total_left)
        pending_reinvestors.append((user, reinvest_amount))
        if total_left <= 0.0:
            break

    # if we still have money we want to reinvest, loop through users without preferences
    if total_left > 0.0:
        users_without_preferences = RevolvUserProfile.objects.filter(reinvest_pool__gt=0.0)\
            .exclude(pk__in=users_with_preferences).order_by('user__last_name')
        for user in users_without_preferences:
            total_left -= user.reinvest_pool
            reinvest_amount = user.reinvest_pool + min(0.0, total_left)
            pending_reinvestors.append((user, reinvest_amount))
            if total_left <= 0.0:
                break
    for (user, amount) in pending_reinvestors:
        reinvestment = Payment(user=user,
                               project=instance.project,
                               entrant=instance.admin,
                               payment_type=PaymentType.objects.get_reinvestment_fragment(),
                               admin_reinvestment=instance,
                               amount=amount
                               )
        # user's reinvest_pool will be decremented on this Payment's save
        reinvestment.save()
Example #10
0
def post_save_user_reinvestment(**kwargs):
    """
    When an AdminReinvestment is saved, we pool as many donors as we need to
    fund the reinvestment, prioritizing users that have a preference for the
    Category of the project begin invested into. We only consider users that
    have a non-zero pool of investable money.

    """
    if not kwargs.get('created'):
        return
    instance = kwargs.get('instance')
    reinvestment = Payment(
        user=instance.user,
        project=instance.project,
        entrant=instance.user,
        payment_type=PaymentType.objects.get_reinvestment_fragment(),
        user_reinvestment=instance,
        amount=instance.amount)
    # user's reinvest_pool will be decremented on this Payment's save
    reinvestment.save()
Example #11
0
def post_save_user_reinvestment(**kwargs):
    """
    When an AdminReinvestment is saved, we pool as many donors as we need to
    fund the reinvestment, prioritizing users that have a preference for the
    Category of the project begin invested into. We only consider users that
    have a non-zero pool of investable money.

    """
    if not kwargs.get('created'):
        return
    instance = kwargs.get('instance')
    reinvestment = Payment(user=instance.user,
                           project=instance.project,
                           entrant=instance.user,
                           payment_type=PaymentType.objects.get_reinvestment_fragment(),
                           user_reinvestment=instance,
                           amount=instance.amount
                           )
        # user's reinvest_pool will be decremented on this Payment's save
    reinvestment.save()
Example #12
0
 def _create_payment(self,
                     user=None,
                     amount=10.00,
                     project=None,
                     payment_type=None,
                     entrant=None):
     if project is None:
         project = Project.factories.base.create()
     if payment_type is None:
         payment_type = PaymentType.objects.get_paypal()
     if entrant is None:
         entrant = user
     return Payment(amount=amount,
                    user=user,
                    entrant=entrant,
                    payment_type=payment_type,
                    project=project)
def distribute_reinvestment_fund():
    """
    This task is for Automatic reinvestment

    This is how this script do:
    1. Get all project that is eligible for reinvestment:
        (project with monthly_reinvestment_cap >0 and not fully funded)
    2. For each project determine how we'll reinvest
    3. Add AdminReinvestment object with above value
    4. Reinvestment every user's reinvestment amount in project funding proportion.
    """

    time.sleep(60)
    ADMIN_PAYMENT_USERNAME = settings.ADMIN_PAYMENT_USERNAME

    try:
        admin = RevolvUserProfile.objects.get(user__username=ADMIN_PAYMENT_USERNAME)
    except RevolvUserProfile.DoesNotExist:
        logger.error("Can't find admin user: {0}. System exiting!".format(ADMIN_PAYMENT_USERNAME))
        sys.exit()

    total_funding_goal = Project.objects.get_active().aggregate(total=Sum('funding_goal'))['total']
    pending_reinvestors = []

    users = RevolvUserProfile.objects.filter(Q(reinvest_pool__gt=0.0) | Q(solar_seed_fund_pool__gt=0.0))
    for user in users:
        reinvest_pool=user.reinvest_pool
        solar_seed_fund_pool = user.solar_seed_fund_pool
        pending_reinvestors.append((user, reinvest_pool, solar_seed_fund_pool))

    for project in Project.objects.get_active():
        reinvest_amount_praportion = float(project.funding_goal)/float(total_funding_goal)

        for (user, reinvest_pool, solar_seed_fund_pool) in pending_reinvestors:
            if solar_seed_fund_pool > 0.0:
                amount = solar_seed_fund_pool * float("{0:.2f}".format(reinvest_amount_praportion))
                solar_seed_monthly = SolarSeedFund.objects.create(
                    amount=amount,
                    user=user,
                    project=project
                )
                logger.info('Trying to donate %s in %s project!', format(round(amount, 2)), project.title)
                monthly_seed_fund = Payment(user=user,
                                            project=project,
                                            entrant=user,
                                            payment_type=PaymentType.objects.get_stripe(),
                                            solar_seed_monthly=solar_seed_monthly,
                                            amount=format(round(amount, 2))
                                            )
                monthly_seed_fund.save()
                #send_donation_info(user.get_full_name(), round(amount, 2), user.user.email, project.title,
                #                   address='')
                user.solar_seed_fund_pool = user.solar_seed_fund_pool - amount
                user.save()

            if reinvest_pool > 0.0:
                amount = reinvest_pool * float("{0:.2f}".format(reinvest_amount_praportion))
                adminReinvestment = AdminReinvestment.objects.create(
                    amount=amount,
                    admin=admin,
                    project=project
                )
                logger.info('Trying to reinvest %s in %s project!',format(round(amount,2)),project.title)
                reinvestment = Payment(user=user,
                                       project=project,
                                       entrant=admin,
                                       payment_type=PaymentType.objects.get_reinvestment_fragment(),
                                       admin_reinvestment=adminReinvestment,
                                       amount=format(round(amount,2))
                                       )

                reinvestment.save()

                project_matching_donors = ProjectMatchingDonors.objects.filter(project=project, amount__gt=0)

                if project_matching_donors:
                    for donor in project_matching_donors:
                        if donor.amount > float(amount):
                            matching_donation = amount
                            donor.amount = donor.amount - amount
                            donor.save()
                        else:
                            matching_donation = donor.amount
                            donor.amount = 0
                            donor.save()

                        tip = None

                        Payment.objects.create(
                            user=donor.matching_donor,
                            entrant=donor.matching_donor,
                            amount=matching_donation,
                            project=project,
                            tip=tip,
                            payment_type=PaymentType.objects.get_stripe(),
                        )

            if project.amount_donated >= project.funding_goal:
                project.project_status = project.COMPLETED
                project.save()


    for user in users:
        if user.solar_seed_fund_pool <= 0.01:
            user.solar_seed_fund_pool = 0

        if user.reinvest_pool <= 0.01:
            user.reinvest_pool = 0

        user.save()