Beispiel #1
0
def handleDonationProductCreated(product, event):
    # don't accidentaly acquire the parent's sf_object_id when checking this
    if getattr(aq_base(product), 'sf_object_id', None) is None:
        sfconn = getUtility(ISalesforceUtility).get_connection()

        data = {
            'ProductCode': product.id,
            'Description': product.description,
            'Name': product.title,
            'Donation_Only__c': product.donation_only,
        }
        container = product.get_container()
        if container:
            campaign_id = container.get_parent_sfid()
            product.campaign_sf_id = campaign_id
            data['Campaign__c'] = campaign_id

        res = sfconn.Product2.create(data)
        if not res['success']:
            raise Exception(res['errors'][0])
        product.sf_object_id = res['id']
        product.reindexObject(idxs=['sf_object_id'])
        # set up a pricebook entry for this object
        pricebook_id = get_standard_pricebook_id(sfconn)
        pedata = {
            'Pricebook2Id': pricebook_id,
            'Product2Id': product.sf_object_id,
            'IsActive': True,
            'UnitPrice': product.price
        }
        pe_res = sfconn.PricebookEntry.create(pedata)
        if not pe_res['success']:
            req = product.REQUEST
            msg = u'Unable to set price for this product in salesforce'
            IStatusMessage(req).add(msg, type=u'warning')

        # Record the pricebook entry id
        product.pricebook_entry_sf_id = pe_res['id']
    return
def handleDonationProductCreated(product, event):
    # don't accidentaly acquire the parent's sf_object_id when checking this
    if getattr(aq_base(product), 'sf_object_id', None) is None:
        sfconn = getUtility(ISalesforceUtility).get_connection()

        data = {
            'ProductCode': product.id,
            'Description': product.description,
            'Name': product.title,
            'Donation_Only__c': product.donation_only,
        }
        container = product.get_container()
        if container:
            campaign_id = container.get_parent_sfid()
            product.campaign_sf_id = campaign_id
            data['Campaign__c'] = campaign_id

        res = sfconn.Product2.create(data)
        if not res['success']:
            raise Exception(res['errors'][0])
        product.sf_object_id = res['id']
        product.reindexObject(idxs=['sf_object_id'])
        # set up a pricebook entry for this object
        pricebook_id = get_standard_pricebook_id(sfconn)
        pedata = {'Pricebook2Id': pricebook_id,
                  'Product2Id': product.sf_object_id,
                  'IsActive': True,
                  'UnitPrice': product.price}
        pe_res = sfconn.PricebookEntry.create(pedata)
        if not pe_res['success']:
            req = product.REQUEST
            msg = u'Unable to set price for this product in salesforce'
            IStatusMessage(req).add(msg, type=u'warning')

        # Record the pricebook entry id
        product.pricebook_entry_sf_id = pe_res['id']
    return
    def render(self):
        charge_id = self.request.form.get("charge_id")
        page = self.context.get_fundraising_campaign_page()

        if not charge_id:
            logger.warning(
                "collective.salesforce.fundraising: Record Stripe Donation " "Error: no charge_id passed in request"
            )
            url = page.absolute_url() + "/@@post_donation_error"
            return self.request.response.redirect(url)

        # Check to make sure a donation does not already exist for this
        # transaction.  If it does, redirect to it.
        pc = getToolByName(self.context, "portal_catalog")
        res = pc.searchResults(
            portal_type="collective.salesforce.fundraising.donation", transaction_id=charge_id, sort_limit=1
        )
        if len(res) == 1:
            # Redirect to the donation or the honorary-memorial form if needed
            donation = res[0].getObject()

            # If this is an honorary or memorial donation, redirect to the
            # form to provide details
            is_honorary = self.request.form.get("is_honorary", None)
            if is_honorary == "true" and donation.honorary_type is None:
                redirect_url = "%s/honorary-memorial-donation?key=%s" % (donation.absolute_url(), donation.secret_key)
            else:
                redirect_url = "%s?key=%s" % (donation.absolute_url(), donation.secret_key)

            return self.request.response.redirect(redirect_url)

        stripe_util = getUtility(IStripeUtility)
        stripe_api = stripe_util.get_stripe_api(page)

        charge = stripe_api.Charge.retrieve(charge_id, expand=["customer.subscriptions", "invoice"])
        # What happens if there is no charge_id passed or no charge was found?
        if not charge:
            logger.warning(
                "collective.salesforce.fundraising: Record Stripe Donation "
                "Error: charge_id %s was not found" % charge_id
            )
            url = page.absolute_url() + "/@@post_donation_error"
            return self.request.response.redirect(url)

        pc = getToolByName(self.context, "portal_catalog")

        # Handle Donation Product forms
        product = None
        product_id = self.request.form.get("c_product_id", None)
        c_products = self.request.form.get("c_products", None)
        quantity = self.request.form.get("c_quantity", None)
        pricebook_id = None
        type_name = "collective.salesforce.fundraising.donationproduct"
        msg = "collective.salesforce.fundraising: Stripe Post Payment Error: " "Product with ID %s not found"
        if product_id:
            res = pc.searchResults(sf_object_id=product_id, portal_type=type_name)
            if not res:
                raise ValueError(msg % product_id)
            product = res[0].getObject()

        if product_id or c_products:
            sfbc = getToolByName(self.context, "portal_salesforcebaseconnector")
            pricebook_id = get_standard_pricebook_id(sfbc)

        # Handle Product Forms with multiple products, each with their own
        # quantity
        products = []
        if c_products:
            for item in c_products.split(","):
                item_id, item_quantity = item.split(":")
                product_res = pc.searchResults(sf_object_id=item_id, portal_type=type_name)
                if not product_res:
                    raise ValueError(msg % item_id)
                products.append({"id": item_id, "quantity": item_quantity, "product": product_res[0].getObject()})

        # lowercase all email addresses to avoid lookup errors if typed with
        # different caps
        email = self.request.form.get("email", None)
        if email:
            email = email.lower()

        first_name = uencode(self.request.form.get("first_name", None))
        last_name = uencode(self.request.form.get("last_name", None))
        email_opt_in = self.request.form.get("email_signup", None) == "YES"
        phone = uencode(self.request.form.get("phone", None))
        address = uencode(self.request.form.get("address", None))
        city = uencode(self.request.form.get("city", None))
        state = uencode(self.request.form.get("state", None))
        zipcode = uencode(self.request.form.get("zip", None))
        country = uencode(self.request.form.get("country", None))
        amount = int(float(self.request.form.get("x_amount", None)))
        source_url = self.request.form.get("source_url", "")

        data = {
            "first_name": first_name,
            "last_name": last_name,
            "email": email,
            "email_opt_in": email_opt_in,
            "phone": phone,
            "address_street": address,
            "address_city": city,
            "address_state": state,
            "address_zip": zipcode,
            "address_country": country,
            "secret_key": build_secret_key(),
            "amount": amount,
            "stage": "Posted",
            "products": [],
            "campaign_sf_id": page.sf_object_id,
            "source_campaign_sf_id": page.get_source_campaign(),
            "source_url": source_url,
            "payment_method": "Stripe",
        }

        # Stripe invoices are only used for recurring so if there is an
        # invoice.
        if charge["invoice"]:
            invoice = charge["invoice"]
            customer = charge["customer"]
            subscriptions = customer["subscriptions"]
            plan = invoice["lines"]["data"][0]["plan"]
            period = invoice["lines"]["data"][0]["period"]

            data["stripe_customer_id"] = customer["id"]
            data["stripe_plan_id"] = plan["id"]
            data["transaction_id"] = charge["id"]
            data["is_test"] = charge["livemode"] == False
            data["title"] = "%s %s - $%i per %s" % (first_name, last_name, amount, plan["interval"])
            data["payment_date"] = stripe_timestamp_to_date(charge["created"])
            data["next_payment_date"] = stripe_timestamp_to_date(period["end"])
        else:
            # One time donation
            data["payment_date"] = stripe_timestamp_to_date(charge["created"])
            data["transaction_id"] = charge["id"]
            data["is_test"] = charge["livemode"] == False
            data["title"] = "%s %s - $%i One Time Donation" % (first_name, last_name, amount)

        if product_id and product is not None:
            # Set a custom name with the product info and quantity
            data["title"] = "%s %s - %s (Qty %s)" % (first_name, last_name, product.title, quantity)

        elif products:
            # Set a custom name with the product info and quantity
            parent_form = products[0]["product"].get_parent_product_form()
            title = "Donation"
            if parent_form:
                title = parent_form.title
            data["title"] = "%s %s - %s" % (first_name, last_name, title)

        if product_id and product is not None:
            data["products"].append("%s|%s|%s" % product.price, quantity, IUUID(product))

        if products:
            for item in products:
                data["products"].append("%s|%s|%s" % (item["product"].price, item["quantity"], IUUID(item["product"])))

        # title must be unicode for dexterity
        if data.get("title", None) and not isinstance(data["title"], unicode):
            data["title"] = unicode(data["title"])

        donation = createContentInContainer(
            page, "collective.salesforce.fundraising.donation", checkConstraints=False, **data
        )

        # If this is an honorary or memorial donation, redirect to the form to provide details
        is_honorary = self.request.form.get("is_honorary", None)
        if is_honorary == "true":
            redirect_url = "%s/honorary-memorial-donation?key=%s" % (donation.absolute_url(), donation.secret_key)
        else:
            redirect_url = "%s?key=%s" % (donation.absolute_url(), donation.secret_key)

        return self.request.response.redirect(redirect_url)
    def render(self):
        charge_id = self.request.form.get('charge_id')
        page = self.context.get_fundraising_campaign_page()

        if not charge_id:
            logger.warning('collective.salesforce.fundraising: Record Stripe Donation Error: no charge_id passed in request')
            return self.request.response.redirect(page.absolute_url() + '/@@post_donation_error')

        # Check to make sure a donation does not already exist for this transaction.  If it does, redirect to it.
        pc = getToolByName(self.context, 'portal_catalog')
        res = pc.searchResults(
            portal_type='collective.salesforce.fundraising.donation', 
            transaction_id=charge_id, 
            sort_limit=1
        )
        if len(res) == 1:
            # Redirect to the donation or the honorary-memorial form if needed
            donation = res[0].getObject()

            # If this is an honorary or memorial donation, redirect to the form to provide details
            is_honorary = self.request.form.get('is_honorary', None)
            if is_honorary == 'true' and donation.honorary_type is None:
                redirect_url = '%s/honorary-memorial-donation?key=%s' % (donation.absolute_url(), donation.secret_key)
            else:
                redirect_url = '%s?key=%s' % (donation.absolute_url(), donation.secret_key)
    
            return self.request.response.redirect(redirect_url)

        stripe_util = getUtility(IStripeUtility)
        stripe_api = stripe_util.get_stripe_api(page)

        charge = stripe_api.Charge.retrieve(charge_id, expand=['customer.subscription','invoice'])
        # What happens if there is no charge_id passed or no charge was found?
        if not charge:
            logger.warning('collective.salesforce.fundraising: Record Stripe Donation Error: charge_id %s was not found' % charge_id)
            return self.request.response.redirect(page.absolute_url() + '/@@post_donation_error')


        pc = getToolByName(self.context, 'portal_catalog')

        # Handle Donation Product forms
        product = None
        product_id = self.request.form.get('c_product_id', None)
        c_products = self.request.form.get('c_products', None)
        quantity = self.request.form.get('c_quantity', None)
        pricebook_id = None
        if product_id:
            res = pc.searchResults(sf_object_id=product_id, portal_type='collective.salesforce.fundraising.donationproduct')
            if not res:
                raise ValueError('collective.salesforce.fundraising: Stripe Post Payment Error: Product with ID %s not found' % product_id)
            product = res[0].getObject()

        if product_id or c_products:
            sfbc = getToolByName(self.context, 'portal_salesforcebaseconnector')
            pricebook_id = get_standard_pricebook_id(sfbc)

        # Handle Product Forms with multiple products, each with their own quantity
        products = []
        if c_products:
            for item in c_products.split(','):
                item_id, item_quantity = item.split(':')
                product_res = pc.searchResults(sf_object_id = item_id, portal_type='collective.salesforce.fundraising.donationproduct')
                if not product_res:
                    raise ValueError('collective.salesforce.fundraising: Stripe Post Payment Error: Product with ID %s not found' % item_id)
                products.append({'id': item_id, 'quantity': item_quantity, 'product': product_res[0].getObject()})

        settings = get_settings()

        # lowercase all email addresses to avoid lookup errors if typed with different caps
        email = self.request.form.get('email', None)
        if email:
            email = email.lower()

        first_name = self.request.form.get('first_name', None)
        last_name = self.request.form.get('last_name', None)
        email_opt_in = self.request.form.get('email_signup', None) == 'YES'
        phone = self.request.form.get('phone', None)
        address = self.request.form.get('address', None)
        city = self.request.form.get('city', None)
        state = self.request.form.get('state', None)
        zipcode = self.request.form.get('zip', None)
        country = self.request.form.get('country', None)
        amount = int(float(self.request.form.get('x_amount', None)))

        data = {
            'first_name': first_name,
            'last_name': last_name,
            'email': email,
            'email_opt_in': email_opt_in,
            'phone': phone,
            'address_street': address,
            'address_city': city,
            'address_state': state,
            'address_zip': zipcode,
            'address_country': zipcode,
            'secret_key': build_secret_key(),
            'amount': amount,
            'stage': 'Posted',
            'products': [],
            'campaign_sf_id': page.sf_object_id,
            'source_campaign_sf_id': page.get_source_campaign(),
            'source_url': page.get_source_url(),
            'payment_method': 'Stripe',
        }
      
        # Stripe invoices are only used for recurring so if there is an invoice.
        if charge['invoice']:
            invoice = charge['invoice']
            customer = charge['customer']
            subscription = customer['subscription']
            plan = invoice['lines']['data'][0]['plan']
                
            data['stripe_customer_id'] = customer['id']
            data['stripe_plan_id'] = plan['id']
            data['transaction_id'] = charge['id']
            data['is_test'] = charge['livemode'] == False
            data['title'] = '%s %s - $%i per %s' % (first_name, last_name, amount, plan['interval'])
            data['payment_date'] = stripe_timestamp_to_date(subscription['current_period_start'])
            data['next_payment_date'] = stripe_timestamp_to_date(subscription['current_period_end'])
        else:
            # One time donation
            data['payment_date'] = stripe_timestamp_to_date(charge['created'])
            data['transaction_id'] = charge['id']
            data['is_test'] = charge['livemode'] == False
            data['title'] = '%s %s - $%i One Time Donation' % (first_name, last_name, amount)

        if product_id and product is not None:
            # Set a custom name with the product info and quantity
            data['title'] = '%s %s - %s (Qty %s)' % (first_name, last_name, product.title, quantity)

        elif products:
            # Set a custom name with the product info and quantity
            parent_form = products[0]['product'].get_parent_product_form()
            title = 'Donation'
            if parent_form:
                title = parent_form.title
            data['title'] = '%s %s - %s' % (first_name, last_name, title)
            
        if product_id and product is not None:
            data['products'].append('%s|%s|%s' % product.price, quantity, IUUID(product))

        if products:
            for item in products:
                data['products'].append('%s|%s|%s' % (item['product'].price, item['quantity'], IUUID(item['product'])))

        donation = createContentInContainer(
            page,
            'collective.salesforce.fundraising.donation',
            checkConstraints=False,
            **data
        )

        # If this is an honorary or memorial donation, redirect to the form to provide details
        is_honorary = self.request.form.get('is_honorary', None)
        if is_honorary == 'true':
            redirect_url = '%s/honorary-memorial-donation?key=%s' % (donation.absolute_url(), donation.secret_key)
        else:
            redirect_url = '%s?key=%s' % (donation.absolute_url(), donation.secret_key)

        return self.request.response.redirect(redirect_url)
    def render(self):
        charge_id = self.request.form.get('charge_id')
        page = self.context.get_fundraising_campaign_page()

        if not charge_id:
            logger.warning(
                'collective.salesforce.fundraising: Record Stripe Donation '
                'Error: no charge_id passed in request')
            url = page.absolute_url() + '/@@post_donation_error'
            return self.request.response.redirect(url)

        # Check to make sure a donation does not already exist for this
        # transaction.  If it does, redirect to it.
        pc = getToolByName(self.context, 'portal_catalog')
        res = pc.searchResults(
            portal_type='collective.salesforce.fundraising.donation',
            transaction_id=charge_id,
            sort_limit=1)
        if len(res) == 1:
            # Redirect to the donation or the honorary-memorial form if needed
            donation = res[0].getObject()

            # If this is an honorary or memorial donation, redirect to the
            # form to provide details
            is_honorary = self.request.form.get('is_honorary', None)
            if is_honorary == 'true' and donation.honorary_type is None:
                redirect_url = '%s/honorary-memorial-donation?key=%s' % (
                    donation.absolute_url(), donation.secret_key)
            else:
                redirect_url = '%s?key=%s' % (donation.absolute_url(),
                                              donation.secret_key)

            return self.request.response.redirect(redirect_url)

        stripe_util = getUtility(IStripeUtility)
        stripe_api = stripe_util.get_stripe_api(page)

        charge = stripe_api.Charge.retrieve(
            charge_id, expand=['customer.subscriptions', 'invoice'])
        # What happens if there is no charge_id passed or no charge was found?
        if not charge:
            logger.warning(
                'collective.salesforce.fundraising: Record Stripe Donation '
                'Error: charge_id %s was not found' % charge_id)
            url = page.absolute_url() + '/@@post_donation_error'
            return self.request.response.redirect(url)

        pc = getToolByName(self.context, 'portal_catalog')

        # Handle Donation Product forms
        product = None
        product_id = self.request.form.get('c_product_id', None)
        c_products = self.request.form.get('c_products', None)
        quantity = self.request.form.get('c_quantity', None)
        pricebook_id = None
        type_name = 'collective.salesforce.fundraising.donationproduct'
        msg = ('collective.salesforce.fundraising: Stripe Post Payment Error: '
               'Product with ID %s not found')
        if product_id:
            res = pc.searchResults(sf_object_id=product_id,
                                   portal_type=type_name)
            if not res:
                raise ValueError(msg % product_id)
            product = res[0].getObject()

        if product_id or c_products:
            sfbc = getToolByName(self.context,
                                 'portal_salesforcebaseconnector')
            pricebook_id = get_standard_pricebook_id(sfbc)

        # Handle Product Forms with multiple products, each with their own
        # quantity
        products = []
        if c_products:
            for item in c_products.split(','):
                item_id, item_quantity = item.split(':')
                product_res = pc.searchResults(sf_object_id=item_id,
                                               portal_type=type_name)
                if not product_res:
                    raise ValueError(msg % item_id)
                products.append({
                    'id': item_id,
                    'quantity': item_quantity,
                    'product': product_res[0].getObject()
                })

        # lowercase all email addresses to avoid lookup errors if typed with
        # different caps
        email = self.request.form.get('email', None)
        if email:
            email = email.lower()

        first_name = uencode(self.request.form.get('first_name', None))
        last_name = uencode(self.request.form.get('last_name', None))
        email_opt_in = self.request.form.get('email_signup', None) == 'YES'
        phone = uencode(self.request.form.get('phone', None))
        address = uencode(self.request.form.get('address', None))
        city = uencode(self.request.form.get('city', None))
        state = uencode(self.request.form.get('state', None))
        zipcode = uencode(self.request.form.get('zip', None))
        country = uencode(self.request.form.get('country', None))
        amount = int(float(self.request.form.get('x_amount', None)))
        source_url = self.request.form.get('source_url', '')

        data = {
            'first_name': first_name,
            'last_name': last_name,
            'email': email,
            'email_opt_in': email_opt_in,
            'phone': phone,
            'address_street': address,
            'address_city': city,
            'address_state': state,
            'address_zip': zipcode,
            'address_country': country,
            'secret_key': build_secret_key(),
            'amount': amount,
            'stage': 'Posted',
            'products': [],
            'campaign_sf_id': page.sf_object_id,
            'source_campaign_sf_id': page.get_source_campaign(),
            'source_url': source_url,
            'payment_method': 'Stripe',
        }

        # Stripe invoices are only used for recurring so if there is an
        # invoice.
        if charge['invoice']:
            invoice = charge['invoice']
            customer = charge['customer']
            subscriptions = customer['subscriptions']
            plan = invoice['lines']['data'][0]['plan']
            period = invoice['lines']['data'][0]['period']

            data['stripe_customer_id'] = customer['id']
            data['stripe_plan_id'] = plan['id']
            data['transaction_id'] = charge['id']
            data['is_test'] = charge['livemode'] == False
            data['title'] = '%s %s - $%i per %s' % (first_name, last_name,
                                                    amount, plan['interval'])
            data['payment_date'] = stripe_timestamp_to_date(charge['created'])
            data['next_payment_date'] = stripe_timestamp_to_date(period['end'])
        else:
            # One time donation
            data['payment_date'] = stripe_timestamp_to_date(charge['created'])
            data['transaction_id'] = charge['id']
            data['is_test'] = charge['livemode'] == False
            data['title'] = '%s %s - $%i One Time Donation' % (
                first_name, last_name, amount)

        if product_id and product is not None:
            # Set a custom name with the product info and quantity
            data['title'] = '%s %s - %s (Qty %s)' % (first_name, last_name,
                                                     product.title, quantity)

        elif products:
            # Set a custom name with the product info and quantity
            parent_form = products[0]['product'].get_parent_product_form()
            title = 'Donation'
            if parent_form:
                title = parent_form.title
            data['title'] = '%s %s - %s' % (first_name, last_name, title)

        if product_id and product is not None:
            data['products'].append('%s|%s|%s' % product.price, quantity,
                                    IUUID(product))

        if products:
            for item in products:
                data['products'].append(
                    '%s|%s|%s' % (item['product'].price, item['quantity'],
                                  IUUID(item['product'])))

        # title must be unicode for dexterity
        if data.get('title', None) and not isinstance(data['title'], unicode):
            data['title'] = unicode(data['title'])

        donation = createContentInContainer(
            page,
            'collective.salesforce.fundraising.donation',
            checkConstraints=False,
            **data)

        # If this is an honorary or memorial donation, redirect to the form to provide details
        is_honorary = self.request.form.get('is_honorary', None)
        if is_honorary == 'true':
            redirect_url = '%s/honorary-memorial-donation?key=%s' % (
                donation.absolute_url(), donation.secret_key)
        else:
            redirect_url = '%s?key=%s' % (donation.absolute_url(),
                                          donation.secret_key)

        return self.request.response.redirect(redirect_url)