def test_serialize_basket_product_version_program(mock_context): """Test ProductVersion serialization for a Program""" program = ProgramFactory.create() courses = CourseFactory.create_batch(3, program=program) product_version = ProductVersionFactory.create( product=ProductFactory(content_object=program) ) data = FullProductVersionSerializer( instance=product_version, context=mock_context ).data assert data == { "id": product_version.id, "description": product_version.description, "content_title": product_version.product.content_object.title, "price": str(round_half_up(product_version.price)), "type": product_version.product.content_type.model, "courses": [ CourseSerializer(instance=course, context=mock_context).data for course in courses ], "thumbnail_url": program.catalog_image_url, "object_id": product_version.product.object_id, "product_id": product_version.product.id, "readable_id": get_readable_id(product_version.product.content_object), "run_tag": None, "created_on": product_version.created_on.strftime(datetime_millis_format), "start_date": product_version.product.content_object.next_run_date.isoformat() if product_version.product.content_object.next_run_date else None, }
def send_b2b_receipt_email(order): """ Send an email summarizing the enrollment codes purchased by a user Args: order (b2b_ecommerce.models.B2BOrder): An order """ from ecommerce.api import get_readable_id course_run_or_program = order.product_version.product.content_object title = course_run_or_program.title if ( isinstance(course_run_or_program, CourseRun) and course_run_or_program.start_date is not None and course_run_or_program.end_date is not None ): run = course_run_or_program date_range = f"{run.start_date.strftime(EMAIL_DATE_FORMAT)} - {run.end_date.strftime(EMAIL_DATE_FORMAT)}" else: date_range = "" download_url = ( f'{urljoin(settings.SITE_BASE_URL, reverse("bulk-enrollment-code-receipt"))}?' f'{urlencode({"hash": str(order.unique_id)})}' ) try: api.send_message( api.message_for_recipient( order.email, api.context_for_user( user=None, extra_context={ "purchase_date": order.updated_on.strftime(EMAIL_DATE_FORMAT), "total_price": format_price(order.total_price), "item_price": format_price(order.per_item_price), "discount": format_price(order.discount) if order.discount is not None else None, "contract_number": order.contract_number, "num_seats": str(order.num_seats), "readable_id": get_readable_id( order.product_version.product.content_object ), "run_date_range": date_range, "title": title, "download_url": download_url, "email": order.email, "order_reference_id": order.reference_number, "receipt_data": get_b2b_receipt_data(order), }, ), EMAIL_B2B_RECEIPT, ) ) except: # pylint: disable=bare-except log.exception("Error sending receipt email")
def test_send_b2b_receipt_email(mocker, settings, has_discount): """send_b2b_receipt_email should send a receipt email""" patched_mail_api = mocker.patch("ecommerce.mail_api.api") order = B2BOrderFactory.create() if has_discount: discount = order.total_price / 3 order.discount = discount order.total_price -= discount order.save() send_b2b_receipt_email(order) run = order.product_version.product.content_object download_url = f'{urljoin(settings.SITE_BASE_URL, reverse("bulk-enrollment-code-receipt"))}?hash={str(order.unique_id)}' patched_mail_api.context_for_user.assert_called_once_with( user=None, extra_context={ "purchase_date": order.updated_on.strftime(EMAIL_DATE_FORMAT), "total_price": format_price(order.total_price), "item_price": format_price(order.per_item_price), "discount": format_price(order.discount) if has_discount else None, "num_seats": str(order.num_seats), "contract_number": order.contract_number, "readable_id": get_readable_id(run), "run_date_range": f"{run.start_date.strftime(EMAIL_DATE_FORMAT)} - {run.end_date.strftime(EMAIL_DATE_FORMAT)}", "title": run.title, "download_url": download_url, "email": order.email, "order_reference_id": order.reference_number, "receipt_data": {}, }, ) patched_mail_api.message_for_recipient.assert_called_once_with( order.email, patched_mail_api.context_for_user.return_value, EMAIL_B2B_RECEIPT) patched_mail_api.send_message.assert_called_once_with( patched_mail_api.message_for_recipient.return_value)
def test_send_ecommerce_order_receipt(mocker, receipt_data): """send_ecommerce_order_receipt should send a receipt email""" patched_mail_api = mocker.patch("ecommerce.mail_api.api") date = datetime.datetime(2010, 1, 1, 0, tzinfo=UTC) user = UserFactory.create( name="test", email="*****@*****.**", legal_address__first_name="Test", legal_address__last_name="User", legal_address__street_address_1="11 Main Street", legal_address__country="US", legal_address__state_or_territory="US-CO", legal_address__city="Boulder", legal_address__postal_code="80309", ) line = LineFactory.create( order__status=Order.CREATED, order__id=1, order__created_on=date, order__total_price_paid=0, order__purchaser=user, product_version__price=100, quantity=1, product_version__product__content_object=CourseRunFactory.create( title="test_run_title"), product_version__product__content_object__course__readable_id= "course:/v7/choose-agency", ) # pylint: disable=expression-not-assigned (ReceiptFactory.create(order=line.order, data=receipt_data) if receipt_data else None) send_ecommerce_order_receipt(line.order) patched_mail_api.context_for_user.assert_called_once_with( user=None, extra_context={ "coupon": None, "content_title": "test_run_title", "lines": [{ "quantity": 1, "total_paid": "100.00", "discount": "0.0", "price": "100.00", "readable_id": get_readable_id(line.product_version.product.content_object), "start_date": None, "end_date": None, "content_title": "test_run_title", "CEUs": line.product_version.product.content_object.course.page. certificate_page.CEUs, }], "order_total": "100.00", "order": { "id": 1, "created_on": line.order.created_on, "reference_number": "xpro-b2c-dev-1", }, "receipt": { "card_number": "1234", "card_type": "Visa", "name": "MIT Doof", "payment_method": "card", "bill_to_email": "*****@*****.**", }, "purchaser": { "name": " ".join(["Test", "User"]), "email": "*****@*****.**", "street_address": ["11 Main Street"], "state_code": "CO", "postal_code": "80309", "city": "Boulder", "country": "United States", "company": user.profile.company, }, }, ) patched_mail_api.messages_for_recipients.assert_called_once_with( [("*****@*****.**", patched_mail_api.context_for_user.return_value)], EMAIL_PRODUCT_ORDER_RECEIPT, )
def test_serialize_order_receipt(receipt_data): """ Test that the OrderReceiptSerializer has correct data """ line = LineFactory.create(order__status=Order.FULFILLED) product_version = line.product_version order = line.order purchaser = order.purchaser.legal_address receipt = ( ReceiptFactory.create(order=order, data=receipt_data) if receipt_data else None ) serialized_data = OrderReceiptSerializer(instance=order).data assert serialized_data == { "coupon": None, "lines": [ { "readable_id": get_readable_id(product_version.product.content_object), "content_title": product_version.product.content_object.title, "discount": "0.0", "start_date": None, "end_date": None, "price": str(product_version.price), "total_paid": str(line.quantity * product_version.price), "quantity": line.quantity, "CEUs": product_version.product.content_object.course.page.certificate_page.CEUs, } ], "order": { "id": order.id, "created_on": order.created_on, "reference_number": order.reference_number, }, "purchaser": { "first_name": purchaser.first_name, "last_name": purchaser.last_name, "email": order.purchaser.email, "country": purchaser.country, "state_or_territory": purchaser.state_or_territory, "city": purchaser.city, "postal_code": purchaser.postal_code, "company": order.purchaser.profile.company, "street_address": [ line for line in [ purchaser.street_address_1, purchaser.street_address_2, purchaser.street_address_3, purchaser.street_address_4, purchaser.street_address_5, ] if line ], }, "receipt": { "card_number": receipt_data["req_card_number"] if "req_card_number" in receipt_data else None, "card_type": CYBERSOURCE_CARD_TYPES[receipt_data["req_card_type"]] if "req_card_type" in receipt_data else None, "payment_method": receipt.data["req_payment_method"] if "req_payment_method" in receipt.data else None, "bill_to_email": receipt.data["req_bill_to_email"] if "req_bill_to_email" in receipt.data else None, "name": f"{receipt.data.get('req_bill_to_forename')} {receipt.data.get('req_bill_to_surname')}" if "req_bill_to_forename" in receipt.data or "req_bill_to_surname" in receipt.data else None, } if receipt else None, }