def test_encode_address(): contact = create_random_company() address = contact.default_billing_address address.save() assert not address.tax_number encoded = encode_address(address) for field, value in encoded.items(): assert getattr(address, field) == value # If no tax number, use tax_number argument encoded = encode_address(address, tax_number="12345") for field, value in encoded.items(): if field == "tax_number": assert value == "12345" else: assert getattr(address, field) == value address.tax_number = "67890" address.save() # If tax number exists, use existing tax number encoded = encode_address(address, tax_number="12345") for field, value in encoded.items(): if field == "tax_number": assert value == "67890" else: assert getattr(address, field) == value
def test_encode_address(): contact = create_random_company() address = contact.default_billing_address address.save() assert not address.tax_number encoded = encode_address(address) for field, value in encoded.items(): assert getattr(address, field) == value # If no tax number, use tax_number argument encoded = encode_address(address, tax_number="12345") for field, value in encoded.items(): if field == "tax_number": assert value == "12345" else: assert getattr(address, field) == value address.tax_number = "67890" address.save() # If tax number exists, use existing tax number encoded = encode_address(address, tax_number="12345") for field, value in encoded.items(): if field == "tax_number": assert value == "67890" else: assert getattr(address, field) == value
def get_frontend_order_state(contact, valid_lines=True): """ Get a dict structure mirroring what the frontend JavaScript would submit. :type contact: Contact|None """ translation.activate("en") shop = get_default_shop() tax, created = Tax.objects.get_or_create( code="test_code", defaults={"rate": decimal.Decimal("0.20"), "name": "Default"} ) tax_class, created = TaxClass.objects.get_or_create(identifier="test_tax_class", defaults={"name": "Default"}) rule, created = TaxRule.objects.get_or_create(tax=tax) rule.tax_classes.add(tax_class) rule.save() product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop) product.tax_class = tax_class product.save() if valid_lines: lines = [ {"id": "x", "type": "product", "product": {"id": product.id}, "quantity": "32", "baseUnitPrice": 50}, {"id": "y", "type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "unitPrice": "5.5"}, {"id": "z", "type": "text", "text": "This was an order!", "quantity": 0}, ] else: unshopped_product = create_product(sku=printable_gibberish(), supplier=get_default_supplier()) not_visible_product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop) not_visible_shop_product = not_visible_product.get_shop_instance(shop) not_visible_shop_product.visibility = ShopProductVisibility.NOT_VISIBLE not_visible_shop_product.save() lines = [ {"id": "x", "type": "product"}, # no product? {"id": "x", "type": "product", "product": {"id": unshopped_product.id}}, # not in this shop? {"id": "y", "type": "product", "product": {"id": -product.id}}, # invalid product? {"id": "z", "type": "other", "quantity": 1, "unitPrice": "q"}, # what's that price? {"id": "rr", "type": "product", "quantity": 1, "product": {"id": not_visible_product.id}}, # not visible ] state = { "customer": { "id": contact.id if contact else None, "billingAddress": encode_address(contact.default_billing_address) if contact else {}, "shippingAddress": encode_address(contact.default_shipping_address) if contact else {}, }, "lines": lines, "methods": { "shippingMethod": {"id": get_default_shipping_method().id}, "paymentMethod": {"id": get_default_payment_method().id}, }, "shop": { "selected": { "id": shop.id, "name": shop.name, "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax, } }, } return state
def test_company_contact_creation(rf, admin_user): get_initial_order_status() contact = create_random_company() test_tax_number = "1234567-1" contact.tax_number = test_tax_number contact.save() contact.default_billing_address.tax_number = test_tax_number contact.default_billing_address.save() state = get_frontend_order_state(contact=contact) state["customer"] = { "id": None, "name": None, "billingAddress": encode_address(contact.default_billing_address), "shipToBillingAddress": True, "saveAddress": True, "isCompany": True } order = get_order_from_state(state, admin_user) assert order.lines.count() == 5 assert order.customer.id != contact.id assert order.customer.name == contact.name assert order.customer.tax_number == test_tax_number assert order.billing_address.tax_number == contact.default_billing_address.tax_number assert order.billing_address.street == contact.default_billing_address.street assert order.billing_address.street == order.shipping_address.street
def test_company_contact_creation(rf, admin_user): get_initial_order_status() contact = create_random_company() test_tax_number = "1234567-1" contact.tax_number = test_tax_number contact.save() contact.default_billing_address.tax_number = test_tax_number contact.default_billing_address.save() state = get_frontend_order_state(contact=contact) state["customer"] = { "id": None, "name": None, "billingAddress": encode_address(contact.default_billing_address), "shipToBillingAddress": True, "saveAddress": True, "isCompany": True } order = get_order_from_state(state, admin_user) assert order.lines.count() == 5 assert order.customer.id != contact.id assert order.customer.name == contact.name assert order.customer.tax_number == test_tax_number assert order.billing_address.tax_number == contact.default_billing_address.tax_number assert order.billing_address.street == contact.default_billing_address.street assert order.billing_address.street == order.shipping_address.street
def test_person_contact_creation(rf, admin_user): get_initial_order_status() # Needed for the API contact = create_random_person(locale="en_US", minimum_name_comp_len=5) state = get_frontend_order_state(contact=contact) state["customer"] = { "id": None, "name": None, "billingAddress": encode_address(contact.default_billing_address), "shipToBillingAddress": True, "saveAddress": True, "isCompany": False } order = get_order_from_state(state, admin_user) assert order.lines.count() == 5 assert order.customer.id != contact.id assert order.customer.name == contact.name assert order.billing_address.name == contact.default_billing_address.name assert order.billing_address.street == contact.default_billing_address.street assert order.billing_address.street == order.shipping_address.street
def test_person_contact_creation(rf, admin_user): get_initial_order_status() # Needed for the API contact = create_random_person(locale="en_US", minimum_name_comp_len=5) state = get_frontend_order_state(contact=contact) state["customer"] = { "id": None, "name": None, "billingAddress": encode_address(contact.default_billing_address), "shipToBillingAddress": True, "saveAddress": True, "isCompany": False } order = get_order_from_state(state, admin_user) assert order.lines.count() == 5 assert order.customer.id != contact.id assert order.customer.name == contact.name assert order.billing_address.name == contact.default_billing_address.name assert order.billing_address.street == contact.default_billing_address.street assert order.billing_address.street == order.shipping_address.street
def create(self, request, *args, **kwargs): post_data = request.data # Revise. We should not need to mutate the data for the serializer. # Also one problem is that we use text lines later at the create text_lines = set() for idx, line in enumerate(post_data.get("lines", [])): if "product" not in line: line["product"] = None if line.get("type") == "text": line["type"] = "other" text_lines.add(idx) request.data["orderer"] = None request.data["modified_by"] = None request.data["creator"] = request.user.pk for attr in [ "shipping_method", "payment_method", "account_manager", "tax_group" ]: if attr not in post_data: post_data[attr] = None if "customer_groups" not in post_data: post_data["customer_groups"] = [] # Revise. Create should happen in the serializer, but then again # we need to return the errors from JsonOrderCreator in some sane way. serializer = self.get_serializer(data=post_data) serializer.is_valid(raise_exception=True) shop = serializer.validated_data["shop"] customer = serializer.validated_data["customer"] lines = [{ "id": (idx + 1), "quantity": line["quantity"], "product": { "id": getattr(line["product"], "id", None) }, "baseUnitPrice": line.get("base_unit_price_value"), "unitPrice": line.get("base_unit_price_value") if line["type"].label == "other" else None, "discountAmount": line.get("discount_amount_value", 0), "sku": line.get("sku"), "text": line.get("text"), "type": force_text(line["type"].label) if idx not in text_lines else "text" } for idx, line in enumerate(serializer.validated_data["lines"])] data = { "shop": { "selected": { "id": shop.id, "name": shop.name, "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax } }, "methods": { "shippingMethod": { "id": getattr(serializer.validated_data["shipping_method"], "id", None) }, "paymentMethod": { "id": getattr(serializer.validated_data["payment_method"], "id", None) }, }, "lines": lines } if customer: data["customer"] = { "id": serializer.validated_data["customer"].id, "billingAddress": encode_address(customer.default_billing_address), "shippingAddress": encode_address(customer.default_shipping_address), } joc = JsonOrderCreator() order = joc.create_order_from_state(data, creator=request.user) if not order: return JsonResponse( { "status": "error", "errors": [{ "message": err.message, "code": err.code } for err in joc.errors] }, status=400) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def create(self, request, *args, **kwargs): post_data = request.data # Revise. We should not need to mutate the data for the serializer. # Also one problem is that we use text lines later at the create text_lines = set() for idx, line in enumerate(post_data.get("lines", [])): if "product" not in line: line["product"] = None if line.get("type") == "text": line["type"] = "other" text_lines.add(idx) request.data["orderer"] = None request.data["modified_by"] = None request.data["creator"] = request.user.pk for attr in ["shipping_method", "payment_method", "account_manager", "tax_group"]: if attr not in post_data: post_data[attr] = None if "customer_groups" not in post_data: post_data["customer_groups"] = [] # Revise. Create should happen in the serializer, but then again # we need to return the errors from JsonOrderCreator in some sane way. serializer = self.get_serializer(data=post_data) serializer.is_valid(raise_exception=True) shop = serializer.validated_data["shop"] customer = serializer.validated_data["customer"] lines = [{ "id": (idx + 1), "quantity": line["quantity"], "product": { "id": getattr(line["product"], "id", None) }, "baseUnitPrice": line.get("base_unit_price_value"), "unitPrice": line.get("base_unit_price_value") if line["type"].label == "other" else None, "discountAmount": line.get("discount_amount_value", 0), "sku": line.get("sku"), "text": line.get("text"), "type": force_text(line["type"].label) if idx not in text_lines else "text" } for idx, line in enumerate(serializer.validated_data["lines"])] data = { "shop": { "selected": { "id": shop.id, "name": shop.name, "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax } }, "methods": { "shippingMethod": {"id": getattr(serializer.validated_data["shipping_method"], "id", None)}, "paymentMethod": {"id": getattr(serializer.validated_data["payment_method"], "id", None)}, }, "lines": lines } if customer: data["customer"] = { "id": serializer.validated_data["customer"].id, "billingAddress": encode_address(customer.default_billing_address), "shippingAddress": encode_address(customer.default_shipping_address), } joc = JsonOrderCreator() order = joc.create_order_from_state(data, creator=request.user) if not order: return JsonResponse({ "status": "error", "errors": [{ "message": err.message, "code": err.code } for err in joc.errors] }, status=400) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def get_frontend_order_state(contact, valid_lines=True): """ Get a dict structure mirroring what the frontend JavaScript would submit. :type contact: Contact|None """ translation.activate("en") shop = get_default_shop() tax, created = Tax.objects.get_or_create(code="test_code", defaults={ "rate": decimal.Decimal("0.20"), "name": "Default" }) tax_class, created = TaxClass.objects.get_or_create( identifier="test_tax_class", defaults={"name": "Default"}) rule, created = TaxRule.objects.get_or_create(tax=tax) rule.tax_classes.add(tax_class) rule.save() product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop) product.tax_class = tax_class product.save() if valid_lines: lines = [ { "id": "x", "type": "product", "product": { "id": product.id }, "quantity": "32", "baseUnitPrice": 50 }, { "id": "y", "type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "unitPrice": "5.5" }, { "id": "z", "type": "text", "text": "This was an order!", "quantity": 0 }, ] else: unshopped_product = create_product(sku=printable_gibberish(), supplier=get_default_supplier()) not_visible_product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop) not_visible_shop_product = not_visible_product.get_shop_instance(shop) not_visible_shop_product.visibility = ShopProductVisibility.NOT_VISIBLE not_visible_shop_product.save() lines = [ { "id": "x", "type": "product" }, # no product? { "id": "x", "type": "product", "product": { "id": unshopped_product.id } }, # not in this shop? { "id": "y", "type": "product", "product": { "id": -product.id } }, # invalid product? { "id": "z", "type": "other", "quantity": 1, "unitPrice": "q" }, # what's that price? { "id": "rr", "type": "product", "quantity": 1, "product": { "id": not_visible_product.id } } # not visible ] state = { "customer": { "id": contact.id if contact else None, "billingAddress": encode_address(contact.default_billing_address) if contact else {}, "shippingAddress": encode_address(contact.default_shipping_address) if contact else {}, }, "lines": lines, "methods": { "shippingMethod": { "id": get_default_shipping_method().id }, "paymentMethod": { "id": get_default_payment_method().id }, }, "shop": { "selected": { "id": shop.id, "name": shop.name, "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax } } } return state
def create(self, request, *args, **kwargs): text_lines = set() for idx, line in enumerate(request.data.get("lines", [])): if "product" not in line: line["product"] = None if line.get("type") == "text": line["type"] = "other" text_lines.add(idx) request.data["orderer"] = None request.data["modified_by"] = None request.data["creator"] = request.user.pk if 'shipping_method' not in request.data: request.data['shipping_method'] = None if 'payment_method' not in request.data: request.data['payment_method'] = None serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) shop = Shop.objects.get(pk=serializer.data["shop"]) if serializer.data.get('customer'): customer = Contact.objects.get(pk=serializer.data["customer"]) else: customer = None lines = [{ "id": (idx + 1), "quantity": line["quantity"], "product": { "id": line["product"] }, "baseUnitPrice": line.get("base_unit_price_value"), "unitPrice": line.get("base_unit_price_value") if line["type"].label == "other" else None, "discountAmount": line.get("discount_amount_value", 0), "sku": line.get("sku"), "text": line.get("text"), "type": force_text(line["type"].label) if idx not in text_lines else "text" } for idx, line in enumerate(serializer.data["lines"])] data = { "shop": { "selected": { "id": shop.id, "name": shop.name, "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax } }, "methods": { "shippingMethod": {"id": serializer.data["shipping_method"]}, "paymentMethod": {"id": serializer.data["payment_method"]}, }, "lines": lines } if customer: data["customer"] = { "id": serializer.data["customer"], "billingAddress": encode_address(customer.default_billing_address), "shippingAddress": encode_address(customer.default_shipping_address), } joc = JsonOrderCreator() order = joc.create_order_from_state(data, creator=request.user) if not order: return JsonResponse({ "status": "error", "errors": [{ "message": err.message, "code": err.code } for err in joc.errors] }, status=400) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def create(self, request, *args, **kwargs): text_lines = set() for idx, line in enumerate(request.data.get("lines", [])): if "product" not in line: line["product"] = None if line.get("type") == "text": line["type"] = "other" text_lines.add(idx) request.data["orderer"] = None request.data["modified_by"] = None request.data["creator"] = request.user.pk serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) shop = Shop.objects.get(pk=serializer.data["shop"]) customer = Contact.objects.get(pk=serializer.data["customer"]) lines = [{ "id": (idx + 1), "quantity": line["quantity"], "product": { "id": line["product"] }, "baseUnitPrice": line.get("base_unit_price_value"), "unitPrice": line.get("base_unit_price_value") if line["type"].label == "other" else None, "discountAmount": line.get("discount_amount_value", 0), "sku": line.get("sku"), "text": line.get("text"), "type": force_text(line["type"].label) if idx not in text_lines else "text" } for idx, line in enumerate(serializer.data["lines"])] data = { "shop": { "selected": { "id": shop.id, "name": shop.name, "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax } }, "methods": { "shippingMethod": {"id": serializer.data["shipping_method"]}, "paymentMethod": {"id": serializer.data["payment_method"]}, }, "customer": { "id": serializer.data["customer"], "billingAddress": encode_address(customer.default_billing_address), "shippingAddress": encode_address(customer.default_shipping_address), }, "lines": lines } joc = JsonOrderCreator() order = joc.create_order_from_state(data, creator=request.user) if not order: return JsonResponse({ "status": "error", "errors": [{ "message": err.message, "code": err.code } for err in joc.errors] }, status=400) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)