def contextualize_or_complete(self, request, context, data=None): completed = True customer = self.customer user = customer.user user_form = None if user.pk is None: # No prefixing here, in order to utilize overlapping fields user_form = UserCreationForm(data, instance=user) completed &= data and user_form.is_valid() if completed: user = user_form.save(commit=False) context['user_form'] = user_form # No prefixing here, in order to utilize overlapping fields customer_form = CustomerForm(data, instance=customer) completed &= data and customer_form.is_valid() if completed: customer = customer_form.save(commit=False) context['customer_form'] = customer_form # We are overlapping customer form fields with user form fields. # This will most likely only be the 'email' field. Since additional # validation happens by the user form, we need to copy over # these errors to the customer form. if user_form is not None: for field, error in six.iteritems(user_form.errors.as_data()): if field in customer_form.fields: customer_form.add_error(field, error) addresses = {} for address_type in ADDRESS_TYPES: form = AddressForm( data, prefix=underscore_concat(address_type, 'address'), instance=customer.addresses.get(address_type, None), ) completed &= data and form.is_valid() if completed: address = form.save(commit=False) addresses[address_type] = address context[underscore_concat(address_type, 'address_form')] = form if completed: for address_type in ADDRESS_TYPES: address = addresses[address_type] customer.addresses[address_type] = address customer.user = user return completed
def contextualize_or_complete(self, request, context, data=None): completed = True order = self.order # Contact information form = ContactableForm(data, prefix='contactable', instance=order) completed &= data and form.is_valid() if completed: order = form.save(commit=False) context['contactable_form'] = form # Shipping method shipping_method = None if order.needs_shipping(): initial = {} if order.shipping_method is not None: initial['method'] = order.shipping_method.string form = ShippingMethodForm.factory(get_shippings_methods( self.order))( data, prefix='shipping_method', initial=initial ) completed &= data and form.is_valid() if completed: shipping_method = form.cleaned_data['shipping_method'] context['shipping_method_form'] = form # Addresses addresses = {} for address_type in ADDRESS_TYPES: form = AddressForm( data, prefix=underscore_concat(address_type, 'address'), instance=order.addresses.get(address_type, None) ) completed &= data and form.is_valid() if completed: address = form.save(commit=False) addresses[address_type] = address context[underscore_concat(address_type, 'address_form')] = form if completed: order.invalidate() order.shipping_method = shipping_method for address_type in ADDRESS_TYPES: address = addresses[address_type] order.addresses[address_type] = address return completed
def price_field_names( name, multi_currency=False, currencies=True, components=None, extra_fields=False, components_only=False ): result = [] currencies = resolve_currencies(currencies) components = resolve_components(components) if multi_currency: for currency in currencies: if not components_only: result.append(price_field_name(name, currency=currency)) for component in components: for multiplicity in range(1, component.multiplicity + 1): field_name = price_field_name( name, currency=currency, component=component, multiplicity=multiplicity ) result.append(field_name) if extra_fields: for extra_field_name in component.extra_fields: full_extra_field_name = underscore_concat( field_name, extra_field_name ) result.append(full_extra_field_name) else: if not components_only: result.append(price_field_name(name)) result.append(currency_field_name(name)) for component in components: for multiplicity in range(1, component.multiplicity + 1): field_name = price_field_name( name, component=component, multiplicity=multiplicity ) result.append(field_name) if extra_fields: for extra_field_name in component.extra_fields: full_extra_field_name = underscore_concat( field_name, extra_field_name ) result.append(full_extra_field_name) return result
def get_fields(self): fields = super(PriceIndex, self).get_fields() for prefix in self.price_prefixes: for currency in Currency.get_all(): field_name = price_field_name(prefix, currency=currency) fields[field_name] = indexing.DecimalField( max_digits=DECIMAL_MAX_DIGITS, decimal_places=DECIMAL_PLACES ) for component in Price.COMPONENTS: field_names = price_field_names( prefix, multi_currency=True, currencies=[currency], components=[component], components_only=True ) for field_name in field_names: fields[field_name] = indexing.DecimalField( max_digits=DECIMAL_MAX_DIGITS, decimal_places=DECIMAL_PLACES ) for extra_field_name, extra_field in six.iteritems( component.construct_extra_index_fields() ): full_extra_field_name = underscore_concat( field_name, extra_field_name ) fields[full_extra_field_name] = extra_field return fields
def get_fields(self): fields = super(PriceIndex, self).get_fields() for prefix in self.price_prefixes: for currency in Currency.get_all(): field_name = price_field_name(prefix, currency=currency) fields[field_name] = indexing.DecimalField( max_digits=DECIMAL_MAX_DIGITS, decimal_places=DECIMAL_PLACES) for component in Price.COMPONENTS: field_names = price_field_names(prefix, multi_currency=True, currencies=[currency], components=[component], components_only=True) for field_name in field_names: fields[field_name] = indexing.DecimalField( max_digits=DECIMAL_MAX_DIGITS, decimal_places=DECIMAL_PLACES) for extra_field_name, extra_field in six.iteritems( component.construct_extra_index_fields()): full_extra_field_name = underscore_concat( field_name, extra_field_name) fields[full_extra_field_name] = extra_field return fields
def price_field_name(name, currency=None, component=None, multiplicity=None): parts = [name] if currency is not None: parts.append(currency) if component is not None: if multiplicity is not None and multiplicity > 1: component = '%s%s' % (component, multiplicity) parts.append(component) else: parts.append(AMOUNT_FIELD) return underscore_concat(*parts)
def get_indexed_price(self, document, prefix, currency=None): values = getattr(document, '_index_values', {}) field_name = price_field_name(prefix, currency=currency) if field_name not in values: raise Exception("%s not found in index" % field_name) amount = values.get(field_name) if amount is None: return None price = Price(amount, currency=currency) for component in Price.COMPONENTS: field_names = price_field_names( prefix, multi_currency=True, currencies=[currency], components=[component], components_only=True ) for field_name in field_names: if field_name not in values: raise Exception("%s not found in index" % field_name) amount = values[field_name] if amount is None: # Due to multiplicity, we can have unused fields. # Do not apply these. continue extra_values = {} for extra_field_name in component.extra_fields: full_extra_field_name = underscore_concat( field_name, extra_field_name ) if full_extra_field_name not in values: raise Exception( "%s not found in index" % full_extra_field_name ) extra_values[ extra_field_name ] = values[full_extra_field_name] amount, extra_values = component.prepare_from_index( amount, extra_values ) price = component.apply(price, amount, extra_values) return price
def populate(self, document, values, **variety): values = super(PriceIndex, self).populate(document, values, **variety) kwargs = self.get_price_kwargs(document, **variety) for prefix in self.price_prefixes: for currency in Currency.get_all(): try: price = self.get_price( document, prefix, currency, **kwargs ) except CurrencyNotAvailable: price = None if price is None: continue field_name = price_field_name(prefix, currency=currency) values[field_name] = price.amount for component in Price.COMPONENTS: multiplicity = 0 for ( amount, extra_values ) in component.safe_extract(price): multiplicity += 1 field_name = price_field_name( prefix, currency=currency, component=component, multiplicity=multiplicity ) amount, extra_values = component.prepare_for_index( amount, extra_values ) values[field_name] = amount for extra_field_name in component.extra_fields: full_extra_field_name = underscore_concat( field_name, extra_field_name ) values[full_extra_field_name] = extra_values.get( extra_field_name ) return values
def get_indexed_price(self, document, prefix, currency=None): values = getattr(document, '_index_values', {}) field_name = price_field_name(prefix, currency=currency) if field_name not in values: raise Exception("%s not found in index" % field_name) amount = values.get(field_name) if amount is None: return None price = Price(amount, currency=currency) for component in Price.COMPONENTS: field_names = price_field_names(prefix, multi_currency=True, currencies=[currency], components=[component], components_only=True) for field_name in field_names: if field_name not in values: raise Exception("%s not found in index" % field_name) amount = values[field_name] if amount is None: # Due to multiplicity, we can have unused fields. # Do not apply these. continue extra_values = {} for extra_field_name in component.extra_fields: full_extra_field_name = underscore_concat( field_name, extra_field_name) if full_extra_field_name not in values: raise Exception("%s not found in index" % full_extra_field_name) extra_values[extra_field_name] = values[ full_extra_field_name] amount, extra_values = component.prepare_from_index( amount, extra_values) price = component.apply(price, amount, extra_values) return price
def contruct_component_field(self, name, component, currency=None): fields = {} if self.multi_currency: field_names = price_field_names( name, multi_currency=self.multi_currency, currencies=[currency], components=[component], components_only=True ) else: field_names = price_field_names( name, components=[component], components_only=True ) for field_name in field_names: fargs = {'null': True, 'blank': True} verbose_name = [] if self.verbose_name is not None: verbose_name.append(self.verbose_name) verbose_name.extend([" ", component.verbose_name]) if currency is not None: verbose_name.extend([" (", currency.name, ")"]) fargs['verbose_name'] = string_concat(*verbose_name) for extra_field_name, extra_field in six.iteritems( component.construct_extra_model_fields() ): full_extra_field_name = underscore_concat( field_name, extra_field_name ) fields[full_extra_field_name] = extra_field fields[field_name] = StandardizedDecimalField(**fargs) return fields
def populate(self, document, values, **variety): values = super(PriceIndex, self).populate(document, values, **variety) kwargs = self.get_price_kwargs(document, **variety) for prefix in self.price_prefixes: for currency in Currency.get_all(): try: price = self.get_price(document, prefix, currency, **kwargs) except CurrencyNotAvailable: price = None if price is None: continue field_name = price_field_name(prefix, currency=currency) values[field_name] = price.amount for component in Price.COMPONENTS: multiplicity = 0 for (amount, extra_values) in component.safe_extract(price): multiplicity += 1 field_name = price_field_name( prefix, currency=currency, component=component, multiplicity=multiplicity) amount, extra_values = component.prepare_for_index( amount, extra_values) values[field_name] = amount for extra_field_name in component.extra_fields: full_extra_field_name = underscore_concat( field_name, extra_field_name) values[full_extra_field_name] = extra_values.get( extra_field_name) return values
def differs_field_name(field_name): return underscore_concat(field_name, 'differs')
# specific prior written permission. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from sellmo.apps.customer.constants import ADDRESS_TYPES from sellmo.utils.text import underscore_concat from .price import TaxPriceComponent TAX = TaxPriceComponent() POLICY_CUSTOMER_ADDRESS = 'address' POLICY_CUSTOMER_ADDRESS_TYPES = { underscore_concat(POLICY_CUSTOMER_ADDRESS, address_type): address_type for address_type in ADDRESS_TYPES } DISPLAY_PRICES_INCLUDING_TAX = 'including_tax' DISPLAY_PRICES_EXCLUDING_TAX = 'excluding_tax' DISPLAY_PRICES_INCLUDING_EXCLUDING_TAX = 'including_excluding_tax'
from sellmo.apps.customer.constants import ADDRESS_TYPES from sellmo.utils.text import underscore_concat from sellmo.contrib.settings import settings_manager from sellmo.contrib.settings.signals import setting_changed from .models import Tax, TaxRule, ProductTaxClass from .constants import (TAX, DISPLAY_PRICES_INCLUDING_TAX, DISPLAY_PRICES_EXCLUDING_TAX, DISPLAY_PRICES_INCLUDING_EXCLUDING_TAX, POLICY_CUSTOMER_ADDRESS) group = _("Taxes") POLICY_CHOICES = tuple( (underscore_concat(POLICY_CUSTOMER_ADDRESS, address_type), _("%s address") % address_type) for address_type in ADDRESS_TYPES) POLICY_DEFAULT = POLICY_CHOICES[0][0] if POLICY_CHOICES else None settings_manager.add_setting( 'tax_policy', models.CharField( max_length=80, null=POLICY_DEFAULT is None, blank=POLICY_DEFAULT is None, default=POLICY_DEFAULT, choices=POLICY_CHOICES, verbose_name=_("tax policy"), ), group)
def setting_key(key, prefix=None): if prefix: key = underscore_concat(prefix, key) return key
def __hash__(self): return hash( underscore_concat('attr', self.value.attribute.key, 'value', self.value.value))
def cache_tag_key(self, tag): return self.cache_key(underscore_concat(TAG_PREFIX, tag))
def cache_key(self, key): return underscore_concat(self.prefix, key)
def __hash__(self): return hash( underscore_concat( 'attr', self.value.attribute.key, 'value', self.value.value ) )
def currency_field_name(name): return underscore_concat(name, CURRENCY_FIELD)