# -*- 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.
import datetime
import itertools
from django.conf import settings
from django.core.management.base import BaseCommand
from django.utils.translation import activate
from shuup.admin.forms.fields import WeekdayField
from shuup.campaigns.models import CatalogCampaign
from shuup.campaigns.models.catalog_filters import CategoryFilter, ProductFilter
from shuup.campaigns.models.context_conditions import ContactCondition, ContactGroupCondition, HourCondition
from shuup.campaigns.models.product_effects import ProductDiscountAmount, ProductDiscountPercentage
from shuup.core.models import Category, CompanyContact, ContactGroup, PersonContact, Product
from shuup.discounts.models import Discount, HappyHour, TimeRange
[docs]class Command(BaseCommand):
[docs] def handle(self, *args, **options):
activate(settings.PARLER_DEFAULT_LANGUAGE_CODE)
Discount.objects.all().delete()
HappyHour.objects.all().delete()
for campaign in CatalogCampaign.objects.all():
data, categories, contact_groups, contacts, products, happy_hours = _get_data_from_campaign(campaign)
new_happy_hours = []
for happy_hour_name, time_ranges in happy_hours:
happy_hour = HappyHour.objects.create(name=happy_hour_name)
happy_hour.shops.set([campaign.shop])
happy_hour.time_ranges.all().delete()
possible_parent = None
for valid_hour in time_ranges:
valid_hour.update({"happy_hour": happy_hour})
if possible_parent and valid_hour.get("continuation", False):
valid_hour.pop("continuation")
valid_hour.update({"parent": possible_parent})
possible_parent = TimeRange.objects.create(**valid_hour)
new_happy_hours.append(happy_hour)
conditions = [categories, contact_groups, products, contacts]
conditions_trimmed = [condition_list for condition_list in conditions if len(condition_list)]
for condition_items in itertools.product(*conditions_trimmed):
product, category, contact, contact_group = _open_condition_items(condition_items)
identifier = "catalog_campaign-%s-%s-%s-%s-%s" % (
campaign.pk,
product.pk if product else 0,
category.pk if category else 0,
contact.pk if contact else 0,
contact_group.pk if contact_group else 0,
)
data.update(
{"product": product, "category": category, "contact": contact, "contact_group": contact_group}
)
discount, created = Discount.objects.get_or_create(identifier=identifier, defaults=data)
discount.shops.set([campaign.shop])
discount.happy_hours.set(new_happy_hours)
def _get_data_from_campaign(campaign): # noqa
data = {
"created_by": campaign.created_by,
"active": campaign.active,
"start_datetime": campaign.start_datetime,
"end_datetime": campaign.end_datetime,
}
categories = []
contact_groups = []
contacts = []
products = []
happy_hours = []
for condition in campaign.conditions.all():
if isinstance(condition, ContactCondition):
contacts = condition.contacts.all()
elif isinstance(condition, ContactGroupCondition):
contact_groups = condition.contact_groups.all()
elif isinstance(condition, HourCondition):
time_ranges = []
for valid_day in condition.days.split(","):
if condition.hour_end < condition.hour_start:
time_ranges.append(
{
"from_hour": condition.hour_start,
"to_hour": datetime.time(hour=23, minute=59),
"weekday": int(valid_day),
}
)
time_ranges.append(
{
"continuation": True,
"from_hour": datetime.time(hour=0),
"to_hour": condition.hour_end,
"weekday": (int(valid_day) + 1 if int(valid_day) < 6 else 0),
}
)
else:
time_ranges.append(
{"from_hour": condition.hour_start, "to_hour": condition.hour_end, "weekday": int(valid_day)}
)
happy_hours.append(
(
"%s %s-%s" % (_get_weekdays_in_labels(condition.days), condition.hour_start, condition.hour_end),
time_ranges,
)
)
for filter in campaign.filters.all():
if isinstance(filter, ProductFilter):
products = filter.products.all()
elif isinstance(filter, CategoryFilter):
categories = filter.categories.all()
for effect in campaign.effects.all():
if isinstance(effect, ProductDiscountAmount):
data.update({"discount_amount_value": effect.discount_amount})
elif isinstance(effect, ProductDiscountPercentage):
data.update({"discount_percentage": effect.discount_percentage})
return data, categories, contact_groups, contacts, products, happy_hours
def _get_weekdays_in_labels(weekdays):
return ", ".join(["%s" % label for value, label in WeekdayField.DAYS_OF_THE_WEEK if "%s" % value in weekdays])
def _open_condition_items(condition_items):
product = None
category = None
contact = None
contact_group = None
for condition in condition_items:
if isinstance(condition, Product):
product = condition
if isinstance(condition, Category):
category = condition
if isinstance(condition, PersonContact) or isinstance(condition, CompanyContact):
contact = condition
if isinstance(condition, ContactGroup):
contact_group = condition
return product, category, contact, contact_group