Source code for shuup.admin.modules.services.forms

# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2021, Shuup Commerce Inc. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.

from __future__ import unicode_literals

from django import forms
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from django_countries import Countries

from shuup.admin.forms import ShuupAdminForm
from shuup.admin.forms.widgets import QuickAddLabelMultiSelect, TextEditorWidget
from shuup.admin.shop_provider import get_shop
from shuup.admin.supplier_provider import get_supplier
from shuup.core.models import (
    Carrier,
    CountryLimitBehaviorComponent,
    FixedCostBehaviorComponent,
    GroupAvailabilityBehaviorComponent,
    OrderTotalLimitBehaviorComponent,
    PaymentMethod,
    PaymentProcessor,
    ServiceProvider,
    ShippingMethod,
    StaffOnlyBehaviorComponent,
    WaivingCostBehaviorComponent,
    WeightLimitsBehaviorComponent,
)


[docs]def get_service_providers_filters(request, payment_method=None): shop_filter = Q(Q(shops__isnull=True) | Q(shops=get_shop(request))) if payment_method and payment_method.pk and payment_method.supplier: return shop_filter & Q( Q(supplier__isnull=True) | Q(supplier=get_supplier(request)) | Q(supplier=payment_method.supplier) ) return shop_filter & Q(Q(supplier__isnull=True) | Q(supplier=get_supplier(request)))
[docs]class BaseMethodForm(ShuupAdminForm):
[docs] class Meta: model = None exclude = ["identifier", "behavior_components", "old_module_identifier", "old_module_data", "shop"] base_fields = ["choice_identifier", "name", "description", "enabled", "logo", "tax_class", "labels", "supplier"] widgets = { "description": TextEditorWidget(), "labels": QuickAddLabelMultiSelect(), }
def __init__(self, **kwargs): self.request = kwargs.pop("request") self.instance = kwargs.get("instance") selected_provider = self.get_service_provider(self.request.GET.get("provider")) if selected_provider: self.service_provider = selected_provider super(BaseMethodForm, self).__init__(**kwargs) self.fields["choice_identifier"] = forms.ChoiceField( choices=_get_service_choices(self.service_provider), required=bool(self.service_provider), label=_("Service"), help_text=_("Select a service to use for this service provider."), ) self.fields[self.service_provider_attr].required = True
[docs] def get_service_provider(self, id): if not id: return return ( ServiceProvider.objects.filter(get_service_providers_filters(self.request, self.instance)) .filter(pk=id) .first() )
@property def service_provider(self): return getattr(self.instance, self.service_provider_attr) if self.instance else None @service_provider.setter def service_provider(self, value): setattr(self.instance, self.service_provider_attr, value) def _save_master(self, commit=True): self.cleaned_data["shop"] = self.request.shop if self.instance.pk: return super(BaseMethodForm, self)._save_master(commit) # New services are always created with provider.create_service method service_data = self._get_cleaned_data_without_translations() provider = service_data.pop(self.service_provider_attr) choice_identifier = service_data.pop("choice_identifier") return provider.create_service(choice_identifier, **service_data)
def _get_service_choices(service_provider): if not service_provider: return [] service_choices = service_provider.get_service_choices() return [(sc.identifier, sc.name) for sc in service_choices]
[docs]class AlwaysChangedModelForm(forms.ModelForm): """ ModelForm that can be saved if it is empty or has unchanged lines on creation """
[docs] def has_changed(self, *args, **kwargs): if self.instance.pk is None: return True return super(AlwaysChangedModelForm, self).has_changed(*args, **kwargs)
[docs]class ShippingMethodForm(BaseMethodForm): service_provider_attr = "carrier"
[docs] class Meta(BaseMethodForm.Meta): model = ShippingMethod fields = ["carrier"] + BaseMethodForm.Meta.base_fields help_texts = { "carrier": _( "The carrier to use for this shipping method. " "Select a carrier before filling other fields." ) }
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["carrier"].queryset = Carrier.objects.filter( get_service_providers_filters(self.request, self.instance) ).distinct()
[docs]class PaymentMethodForm(BaseMethodForm): service_provider_attr = "payment_processor"
[docs] class Meta(BaseMethodForm.Meta): model = PaymentMethod fields = ["payment_processor"] + BaseMethodForm.Meta.base_fields help_texts = { "payment_processor": _( "The payment processor to use for this payment method. " "Select a payment processor before filling out the other fields." ) }
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["payment_processor"].queryset = PaymentProcessor.objects.filter( get_service_providers_filters(self.request, self.instance) ).distinct()
[docs]class FixedCostBehaviorComponentForm(ShuupAdminForm):
[docs] class Meta: model = FixedCostBehaviorComponent exclude = ["identifier"] labels = { "price_value": _("Price"), }
[docs]class WaivingCostBehaviorComponentForm(ShuupAdminForm):
[docs] class Meta: model = WaivingCostBehaviorComponent exclude = ["identifier"] labels = {"price_value": _("Price"), "waive_limit_value": _("Waive limit")}
[docs]class WeightLimitsBehaviorComponentForm(forms.ModelForm):
[docs] class Meta: model = WeightLimitsBehaviorComponent exclude = ["identifier"]
[docs]class GroupAvailabilityBehaviorComponentForm(forms.ModelForm):
[docs] class Meta: model = GroupAvailabilityBehaviorComponent exclude = ["identifier"]
[docs]class StaffOnlyBehaviorComponentForm(AlwaysChangedModelForm):
[docs] class Meta: model = StaffOnlyBehaviorComponent exclude = ["identifier"]
[docs]class OrderTotalLimitBehaviorComponentForm(forms.ModelForm):
[docs] class Meta: model = OrderTotalLimitBehaviorComponent exclude = ["identifier"]
[docs]class CountryLimitBehaviorComponentForm(forms.ModelForm): available_in_countries = forms.MultipleChoiceField( choices=Countries, label=_("Available in countries"), required=False ) unavailable_in_countries = forms.MultipleChoiceField( choices=Countries, label=_("Unavailable in countries"), required=False )
[docs] class Meta: model = CountryLimitBehaviorComponent exclude = ["identifier"] help_texts = { "available_in_countries": _("Select accepted countries for this service."), "available_in_european_countries": _("Select this to accept all countries in EU."), "unavailable_in_countries": _("Select restricted countries for this service."), "unavailable_in_european_countries": _("Select this to restrict this service for countries in EU"), }
def __init__(self, **kwargs): super(CountryLimitBehaviorComponentForm, self).__init__(**kwargs) if self.instance and self.instance.pk: self.initial["available_in_countries"] = self.instance.available_in_countries self.initial["unavailable_in_countries"] = self.instance.unavailable_in_countries