예제 #1
0
def update_ach_charges():

    lock = Lock(key='update-ach-charges-lock')
    lock.acquire()

    log = Log()

    log.it('---Starting batch ach job...')
    log.it('---Checking for status changes on ACH charges...')

    three_days_ago = (datetime.now(tz=zone) -
                      timedelta(days=3)).strftime("%Y-%m-%d")
    today = datetime.now(tz=zone).strftime("%Y-%m-%d")

    opportunities = Opportunity.list(begin=three_days_ago,
                                     end=today,
                                     stage_name="ACH Pending")

    for opportunity in opportunities:
        if not opportunity.stripe_customer_id:
            continue
        amount = amount_to_charge(opportunity)
        log.it(
            f"---- ACH Charging ${amount} to {opportunity.stripe_customer_id} ({opportunity.name})"
        )
        try:
            charge(opportunity)
        except ChargeException as e:
            logging.info("ACH batch charge error")
            e.send_slack_notification()

    log.send()

    lock.release()
예제 #2
0
def charge_cards():

    lock = Lock(key="charge-cards-lock")
    lock.acquire()

    log = Log()

    log.it("---Starting batch card job...")

    three_days_ago = (datetime.now(tz=zone) -
                      timedelta(days=14)).strftime("%Y-%m-%d")
    today = datetime.now(tz=zone).strftime("%Y-%m-%d")

    opportunities = Opportunity.list(begin=three_days_ago, end=today)

    log.it("---Processing charges...")

    log.it(f"Found {len(opportunities)} opportunities available to process.")

    for opportunity in opportunities:
        if not opportunity.stripe_customer_id:
            continue
        amount = amount_to_charge(opportunity)
        log.it(
            f"---- Charging ${amount} to {opportunity.stripe_customer_id} ({opportunity.name})"
        )
        try:
            charge(opportunity)
        except ChargeException as e:
            logging.info("Batch charge error")
            e.send_slack_notification()

    log.send()

    lock.release()
예제 #3
0
def charge_cards():

    lock = Lock(key="charge-cards-lock")
    lock.acquire()

    log = Log()

    log.it("---Starting batch job...")

    three_days_ago = (datetime.now(tz=zone) - timedelta(days=3)).strftime("%Y-%m-%d")
    today = datetime.now(tz=zone).strftime("%Y-%m-%d")

    opportunities = Opportunity.list(begin=three_days_ago, end=today)

    log.it("---Processing charges...")

    log.it(f"Found {len(opportunities)} opportunities available to process.")

    for opportunity in opportunities:
        if not opportunity.stripe_customer:
            continue
        amount = amount_to_charge(opportunity)
        log.it(
            f"---- Charging ${amount} to {opportunity.stripe_customer} ({opportunity.name})"
        )
        charge(opportunity)

    log.send()

    lock.release()
예제 #4
0
def charge_cards():

    lock = Lock(key="charge-cards-lock")
    lock.acquire()

    log = Log()

    log.it("---Starting batch job...")

    three_days_ago = (datetime.now(tz=zone) - timedelta(days=14)).strftime("%Y-%m-%d")
    today = datetime.now(tz=zone).strftime("%Y-%m-%d")

    opportunities = Opportunity.list(begin=three_days_ago, end=today)

    log.it("---Processing charges...")

    processing_msg = f"Found {len(opportunities)} opportunities available to process."
    log.it(processing_msg)
    send_slack_message(
        {
            "channel": "#stripe",
            "text": processing_msg,
            "icon_emoji": ":moneybag:",
        }
    )

    for opportunity in opportunities:
        if not opportunity.stripe_customer:
            continue
        amount = amount_to_charge(opportunity)
        try:
            entry_name = opportunity.name
            # replaces non-ascii characters with "?" - See PR #851
            encoded_name = entry_name.encode("ascii", "replace")
            decoded_name = encoded_name.decode("ascii")
            log.it(
                f"---- Charging ${amount} to {opportunity.stripe_customer} ({decoded_name})"
            )
        except:
            log.it(
                f"---- Charging ${amount} to {opportunity.stripe_customer} ({opportunity.name})"
            )
            logging.warn(f"Could not encode {opportunity.name}")
        try:
            charge(opportunity)
        except ChargeException as e:
            logging.info("Batch charge error")
            e.send_slack_notification()
        except QuarantinedException:
            logging.info(
                "Failed to charge because Opportunity %s is quarantined", opportunity
            )

    log.send()

    lock.release()
예제 #5
0
def customer_source_updated(event):

    card_details = dict()

    # TODO update this with Opportunity fields when npsp is merged

    # we update all of these fields if any of them have changed because
    # we don't have these fields already populated; after some time that won't be
    # important

    if any([
            "last4" in event["data"]["previous_attributes"],
            "brand" in event["data"]["previous_attributes"],
            "exp_year" in event["data"]["previous_attributes"],
    ]):
        year = event["data"]["object"]["exp_year"]
        month = event["data"]["object"]["exp_month"]
        day = calendar.monthrange(year, month)[1]
        expiration = f"{year}-{month:02d}-{day:02d}"
        card_details["Stripe_Card_Expiration__c"] = expiration
        card_details["Stripe_Card_Brand__c"] = event["data"]["object"]["brand"]
        card_details["Stripe_Card_Last_4__c"] = event["data"]["object"][
            "last4"]
    else:
        logging.info("Event not relevant; discarding.")
        return

    opps = Opportunity.list(
        stage_name="Pledged",
        stripe_customer_id=event["data"]["object"]["customer"])

    if not opps:
        return

    response = Opportunity.update_card(opps, card_details)
    logging.info(response)
    logging.info("card details updated")