Source code for shoop.customer_group_pricing.admin_form_part
# -*- coding: utf-8 -*-
# This file is part of Shoop.
#
# Copyright (c) 2012-2016, Shoop Ltd. All rights reserved.
#
# This source code is licensed under the AGPLv3 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 shoop.admin.form_part import FormPart, TemplatedFormDef
from shoop.core.models import ContactGroup, Shop
from shoop.customer_group_pricing.models import CgpPrice
[docs]class CustomerGroupPricingForm(forms.Form):
def __init__(self, **kwargs):
self.product = kwargs.pop("product", None)
super(CustomerGroupPricingForm, self).__init__(**kwargs)
self.shops = []
self.groups = []
if self.product:
self._build_fields()
def _build_fields(self):
self.shops = list(Shop.objects.all())
self.groups = list(ContactGroup.objects.filter(
Q(show_pricing=True) |
Q(
id__in=CgpPrice.objects.filter(product=self.product)
.values_list("group_id", flat=True).distinct()
)
))
prices_by_shop_and_group = dict(
((shop_id or 0, group_id or 0), price)
for (shop_id, group_id, price)
in CgpPrice.objects.filter(product=self.product)
.values_list("shop_id", "group_id", "price_value")
)
for group in self.groups:
for shop in self.shops:
shop_group_id_tuple = self._get_id_tuple(shop, group)
name = self._get_field_name(shop_group_id_tuple)
price = prices_by_shop_and_group.get(shop_group_id_tuple)
price_field = forms.DecimalField(
min_value=0, initial=price,
label=(_("Price (%(shop)s/%(group)s)") %
{"shop": shop, "group": group}),
required=False
)
self.fields[name] = price_field
def _get_id_tuple(self, shop, group):
return (
shop.id if shop else 0,
group.id if group else 0
)
def _get_field_name(self, id_tuple):
return "s_%d_g_%d" % id_tuple
def _process_single_save(self, shop, group):
shop_group_id_tuple = self._get_id_tuple(shop, group)
name = self._get_field_name(shop_group_id_tuple)
value = self.cleaned_data.get(name)
clear = (value is None or value < 0)
if clear:
CgpPrice.objects.filter(product=self.product, group=group, shop=shop).delete()
else:
(spp, created) = CgpPrice.objects.get_or_create(
product=self.product, group=group, shop=shop,
defaults={'price_value': value})
if not created:
spp.price_value = value
spp.save()
[docs] def save(self):
if not self.has_changed(): # No changes, so no need to do anything.
# (This is required because `.full_clean()` would create an empty `.cleaned_data`,
# but short-circuits out if `has_changed()` returns false.
# That, in kind, would cause `self.cleaned_data.get(name)` in `_process_single_save`
# to return Nones, clearing out all prices. Oops.)
return
for group in self.groups:
for shop in self.shops:
self._process_single_save(shop, group)
[docs] def get_shop_group_field(self, shop, group):
shop_group_id_tuple = self._get_id_tuple(shop, group)
name = self._get_field_name(shop_group_id_tuple)
return self[name]
[docs]class CustomerGroupPricingFormPart(FormPart):
priority = 10
[docs] def get_form_defs(self):
yield TemplatedFormDef(
name="customer_group_pricing",
form_class=CustomerGroupPricingForm,
template_name="shoop/admin/customer_group_pricing/form_part.jinja",
required=False,
kwargs={"product": self.object}
)