def test_stacked_tax_taxful_price(): shop = get_shop(prices_include_tax=True, currency='EUR') source = OrderSource(shop) assert source.prices_include_tax source.add_line( type=OrderLineType.OTHER, quantity=1, base_unit_price=source.create_price(20) ) with override_provides("tax_module", TAX_MODULE_SPEC): with override_settings(SHOOP_TAX_MODULE="irvine"): source.shipping_address = MutableAddress( street="16215 Alton Pkwy", postal_code="92602", ) line = source.get_final_lines(with_taxes=True)[0] assert isinstance(line, SourceLine) assert line.taxes assert line.taxful_price == TaxfulPrice(20, 'EUR') assert_almost_equal(line.taxless_price, TaxlessPrice("18.518518", 'EUR')) source.uncache() # Let's move out to a taxless location. source.shipping_address.postal_code = "11111" line = source.get_final_lines(with_taxes=True)[0] assert isinstance(line, SourceLine) assert not line.taxes assert line.taxful_price == TaxfulPrice(20, source.currency) assert line.taxless_price.value == Decimal("20")
def _initialize_source_from_state(self, state, creator, ip_address, save): shop_data = state.pop("shop", None).get("selected", {}) shop = self.safe_get_first(Shop, pk=shop_data.pop("id", None)) if not shop: self.add_error(ValidationError(_("Please choose a valid shop."), code="no_shop")) return None source = OrderSource(shop=shop) customer_data = state.pop("customer", None) billing_address_data = customer_data.pop("billingAddress", {}) shipping_address_data = ( billing_address_data if customer_data.pop("shipToBillingAddress", False) else customer_data.pop("shippingAddress", {})) is_company = customer_data.pop("isCompany", False) save_address = customer_data.pop("saveAddress", False) customer = self.safe_get_first(Contact, pk=customer_data.get("id")) if customer_data else None if not customer: customer = self._create_contact_from_address(billing_address_data, is_company) if not customer: return if save: customer.save() billing_address = MutableAddress.from_data(billing_address_data) shipping_address = MutableAddress.from_data(shipping_address_data) if save: billing_address.save() shipping_address.save() if save and save_address: customer.default_billing_address = billing_address customer.default_shipping_address = shipping_address customer.save() methods_data = state.pop("methods", None) or {} shipping_method = methods_data.pop("shippingMethod") if not shipping_method: self.add_error(ValidationError(_("Please select shipping method."), code="no_shipping_method")) payment_method = methods_data.pop("paymentMethod") if not payment_method: self.add_error(ValidationError(_("Please select payment method."), code="no_payment_method")) if self.errors: return source.update( creator=creator, ip_address=ip_address, customer=customer, billing_address=billing_address, shipping_address=shipping_address, status=OrderStatus.objects.get_default_initial(), shipping_method=self.safe_get_first(ShippingMethod, pk=shipping_method.get("id")), payment_method=self.safe_get_first(PaymentMethod, pk=payment_method.get("id")), ) return source
def _initialize_source_from_state(self, state, creator): shop_data = state.pop("shop", None).get("selected", {}) shop = self.safe_get_first(Shop, pk=shop_data.pop("id", None)) if not shop: self.add_error(ValidationError(_("Please choose a valid shop."), code="no_shop")) return None source = OrderSource(shop=shop) customer_data = state.pop("customer", None) billing_address = customer_data.pop("billingAddress", {}) shipping_address = customer_data.pop("shippingAddress", {}) ship_to_billing_address = customer_data.pop("shipToBillingAddress", False) is_company = customer_data.pop("isCompany", False) save_address = customer_data.pop("saveAddress", False) customer = self.safe_get_first(Contact, pk=customer_data.get("id")) if customer_data else None if not customer: customer = self._create_contact_from_address(billing_address, is_company) if not customer: return billing_address = self._create_address(billing_address) shipping_address = billing_address if ship_to_billing_address else self._create_address(shipping_address) if save_address: customer.default_billing_address = billing_address customer.default_shipping_address = shipping_address customer.save() methods_data = state.pop("methods", None) or {} shipping_method = methods_data.pop("shippingMethod") if not shipping_method: self.add_error(ValidationError(_("Please select shipping method."), code="no_shipping_method")) payment_method = methods_data.pop("paymentMethod") if not payment_method: self.add_error(ValidationError(_("Please select payment method."), code="no_payment_method")) if self.errors: return source.update( creator=creator, customer=customer, billing_address=billing_address, shipping_address=shipping_address, status=OrderStatus.objects.get_default_initial(), shipping_method=self.safe_get_first(ShippingMethod, pk=shipping_method.get("id")), payment_method=self.safe_get_first(PaymentMethod, pk=payment_method.get("id")), ) return source
def test_stacked_tax_taxless_price(): source = OrderSource(get_shop(prices_include_tax=False)) assert source.prices_include_tax is False source.add_line(type=OrderLineType.OTHER, quantity=1, base_unit_price=source.create_price(10)) with override_provides("tax_module", TAX_MODULE_SPEC): with override_settings(SHOOP_TAX_MODULE="irvine"): source.shipping_address = MutableAddress(street="16215 Alton Pkwy", postal_code="92602") line = source.get_final_lines(with_taxes=True)[0] assert isinstance(line, SourceLine) assert line.taxes assert line.taxful_price.value == Decimal("10.800") source.uncache() # Let's move out to a taxless location. source.shipping_address.postal_code = "11111" line = source.get_final_lines(with_taxes=True)[0] assert isinstance(line, SourceLine) assert not line.taxes assert line.taxful_price.value == Decimal("10")
def _initialize_source_from_state(self, state, creator): customer_data = state.pop("customer", None) or {} shop_data = state.pop("shop", None) or {} methods_data = state.pop("methods", None) or {} customer = self.safe_get_first(Contact, pk=customer_data.get("id")) shop = self.safe_get_first(Shop, pk=shop_data.pop("id", None)) if not customer: self.add_error(ValidationError(_("Please choose a valid customer."), code="no_customer")) if not shop: self.add_error(ValidationError(_("Please choose a valid shop."), code="no_shop")) return None source = OrderSource(shop=shop) source.update( creator=creator, customer=customer, status=OrderStatus.objects.get_default_initial(), shipping_method=self.safe_get_first(ShippingMethod, pk=methods_data.pop("shippingMethodId")), payment_method=self.safe_get_first(PaymentMethod, pk=methods_data.pop("paymentMethodId")), ) return source
def test_stacked_tax_taxless_price(): source = OrderSource(get_shop(prices_include_tax=False)) assert source.prices_include_tax is False source.add_line( type=OrderLineType.OTHER, quantity=1, base_unit_price=source.create_price(10) ) with override_provides("tax_module", TAX_MODULE_SPEC): with override_settings(SHOOP_TAX_MODULE="irvine"): source.shipping_address = MutableAddress( street="16215 Alton Pkwy", postal_code="92602", ) line = source.get_final_lines(with_taxes=True)[0] assert isinstance(line, SourceLine) assert line.taxes assert line.taxful_price.value == Decimal("10.800") source.uncache() # Let's move out to a taxless location. source.shipping_address.postal_code = "11111" line = source.get_final_lines(with_taxes=True)[0] assert isinstance(line, SourceLine) assert not line.taxes assert line.taxful_price.value == Decimal("10")
def create_order_source(prices_include_tax, line_data, tax_rates): """ Get order source with some testing data. :rtype: OrderSource """ lines = [Line.from_text(x) for x in line_data] shop = get_shop(prices_include_tax, currency='USD') tax_classes = create_assigned_tax_classes(tax_rates) products = create_products(shop, lines, tax_classes) services = create_services(shop, lines, tax_classes) source = OrderSource(shop) fill_order_source(source, lines, products, services) return source
def create_random_order(customer=None, products=(), completion_probability=0): if not customer: customer = Contact.objects.all().order_by("?").first() if not customer: raise ValueError("No valid contacts") shop = get_default_shop() request = apply_request_middleware(RequestFactory().get("/"), customer=customer) context = PriceTaxContext.from_request(request) source = OrderSource(shop) source.customer = customer source.customer_comment = "Mock Order" if customer.default_billing_address and customer.default_shipping_address: source.billing_address = customer.default_billing_address source.shipping_address = customer.default_shipping_address else: source.billing_address = create_random_address() source.shipping_address = create_random_address() source.order_date = now() - datetime.timedelta(days=random.uniform(0, 400)) source.language = customer.language source.status = get_initial_order_status() if not products: products = list( Product.objects.list_visible(source.shop, customer).order_by("?")[:40]) for i in range(random.randint(3, 10)): product = random.choice(products) quantity = random.randint(1, 5) price_info = product.get_price_info(context, quantity=quantity) shop_product = product.get_shop_instance(source.shop) supplier = shop_product.suppliers.first() line = source.add_line(type=OrderLineType.PRODUCT, product=product, supplier=supplier, quantity=quantity, base_unit_price=price_info.base_unit_price, discount_amount=price_info.discount_amount, sku=product.sku, text=product.safe_translation_getter( "name", any_language=True)) assert line.total_price == price_info.price with atomic(): oc = OrderCreator(request) order = oc.create_order(source) if random.random() < completion_probability: order.create_shipment_of_all_products() # also set complete order.status = OrderStatus.objects.get_default_complete() order.save(update_fields=("status", )) return order
def create_random_order(customer=None, products=(), completion_probability=0): if not customer: customer = Contact.objects.all().order_by("?").first() if not customer: raise ValueError("No valid contacts") shop = get_default_shop() request = apply_request_middleware(RequestFactory().get("/"), customer=customer) context = PriceTaxContext.from_request(request) source = OrderSource() source.customer = customer source.customer_comment = "Mock Order" if customer.default_billing_address and customer.default_shipping_address: source.billing_address = customer.default_billing_address source.shipping_address = customer.default_shipping_address else: source.billing_address = create_random_address() source.shipping_address = create_random_address() source.order_date = now() - datetime.timedelta(days=random.uniform(0, 400)) source.shop = shop source.language = customer.language source.status = get_initial_order_status() if not products: products = list(Product.objects.list_visible(source.shop, customer).order_by("?")[:40]) source.lines = [] for i in range(random.randint(3, 10)): product = random.choice(products) quantity = random.randint(1, 5) price_info = product.get_price_info(context, quantity=quantity) shop_product = product.get_shop_instance(source.shop) supplier = shop_product.suppliers.first() line = SourceLine( type=OrderLineType.PRODUCT, product=product, supplier=supplier, quantity=quantity, unit_price=price_info.unit_base_price, total_discount=price_info.discount_amount, sku=product.sku, text=product.safe_translation_getter("name", any_language=True) ) assert line.total_price == price_info.price source.lines.append(line) with atomic(): oc = OrderCreator(request) order = oc.create_order(source) if random.random() < completion_probability: order.create_shipment_of_all_products() # also set complete order.status = OrderStatus.objects.get_default_complete() order.save(update_fields=("status",)) return order
def _get_source_line(request): source = OrderSource(request.shop) return _create_line(source, Product(sku='6.0745'))
def test_invalid_source_line_updating(): source = OrderSource(Shop()) with pytest.raises(TypeError): # Test forbidden keys SourceLine(source).update({"update": True})
def test_invalid_order_source_updating(): with pytest.raises(ValueError): # Test nonexisting key updating OrderSource(Shop()).update(__totes_not_here__=True)
def test_codes_type_conversion(): source = OrderSource(Shop()) assert source.codes == [] with pytest.raises(AttributeError): source.codes = "test" assert source.codes == [] source.add_code("t") source.add_code("e") source.add_code("s") assert source.codes == ["t", "e", "s"] was_added = source.add_code("t") assert was_added is False assert source.codes == ["t", "e", "s"] was_cleared = source.clear_codes() assert was_cleared assert source.codes == [] was_cleared = source.clear_codes() assert not was_cleared source.add_code("test") source.add_code(1) source.add_code("1") assert source.codes == ["test", "1"]
def _initialize_source_from_state(self, state, creator, ip_address, save, order_to_update=None): shop_data = state.pop("shop", None).get("selected", {}) shop = self.safe_get_first(Shop, pk=shop_data.pop("id", None)) if not shop: self.add_error( ValidationError(_("Please choose a valid shop."), code="no_shop")) return None source = OrderSource(shop=shop) if order_to_update: source.update_from_order(order_to_update) customer_data = state.pop("customer", None) billing_address_data = customer_data.pop("billingAddress", {}) shipping_address_data = (billing_address_data if customer_data.pop( "shipToBillingAddress", False) else customer_data.pop( "shippingAddress", {})) is_company = customer_data.pop("isCompany", False) save_address = customer_data.pop("saveAddress", False) customer = self._get_customer(customer_data, billing_address_data, is_company, save) if not customer: return billing_address = MutableAddress.from_data(billing_address_data) shipping_address = MutableAddress.from_data(shipping_address_data) if save: billing_address.save() shipping_address.save() if save and save_address: customer.default_billing_address = billing_address customer.default_shipping_address = shipping_address customer.save() methods_data = state.pop("methods", None) or {} shipping_method = methods_data.pop("shippingMethod") if not shipping_method: self.add_error( ValidationError(_("Please select shipping method."), code="no_shipping_method")) payment_method = methods_data.pop("paymentMethod") if not payment_method: self.add_error( ValidationError(_("Please select payment method."), code="no_payment_method")) if self.errors: return source.update( creator=creator, ip_address=ip_address, customer=customer, billing_address=billing_address, shipping_address=shipping_address, status=OrderStatus.objects.get_default_initial(), shipping_method=self.safe_get_first(ShippingMethod, pk=shipping_method.get("id")), payment_method=self.safe_get_first(PaymentMethod, pk=payment_method.get("id")), ) return source