from BaseModels.mailSender import techSendMail
from django.db.models import Sum, FloatField, F, Value as V, Count, OuterRef, Subquery, Q, Max, Exists
from django.db.models.functions import Concat, Length
from operator import itemgetter
from datetime import datetime
import copy
from .models import User
from datetime import datetime, date, timedelta
from collections import OrderedDict
def managers_sales_by_period_n_regions(period_from=None, period_to=None, region_ids=None, kwargs=None, sum_w_prev_data=None):
from CompaniesApp.models import Company
log_begin_DT = datetime.now()
msg = 'managers_sales_by_period_n_regions start - {0}
---------------
'.format(str(log_begin_DT))
print(msg)
stat_kwargs = {}
queryset_kwargs = {}
all_managers = False
separate_managers_sales_by_link_in_order = False
if kwargs:
if 'stat_kwargs' in kwargs:
stat_kwargs.update(kwargs['stat_kwargs'])
if 'all_managers' in kwargs:
all_managers = kwargs['all_managers']
if 'queryset_kwargs' in kwargs:
queryset_kwargs.update(kwargs['queryset_kwargs'])
if 'separate_managers_sales_by_link_in_order' in kwargs:
separate_managers_sales_by_link_in_order = kwargs['separate_managers_sales_by_link_in_order']
from B2BApp.stat_funcs import get_sales_by_period_n_regions
orders, receipts, pays = get_sales_by_period_n_regions(period_from=period_from, period_to=period_to, region_ids=region_ids, kwargs=kwargs)
ids = []
if not all_managers:
ord_manager_ids = set(item['manager_obj__id'] for item in orders)
receipt_manager_ids = set(item['manager_obj__id'] for item in receipts)
pay_manager_ids = set(item['manager__id'] for item in pays)
ids = set.union(ord_manager_ids, receipt_manager_ids, pay_manager_ids)
queryset_kwargs.update({'id__in': ids})
if not sum_w_prev_data:
managers = User.objects.filter(
**queryset_kwargs
).annotate(
full_name=Concat(F('last_name'), V(' '), F('first_name')),
).order_by('full_name').values(
'id', 'full_name'
)
objs = list(managers)
objs.sort(key=itemgetter('full_name'), reverse=False)
if None in ids:
objs.append({'id': None, 'full_name': 'не назначен менеджер'})
else:
objs = copy.deepcopy(sum_w_prev_data)
from_date = None
to_date = None
if orders:
orders.sort(key=itemgetter('delivery_DT'), reverse=False)
from_date = orders[0]['delivery_DT'].date()
to_date = orders[-1]['delivery_DT'].date()
if from_date:
from_DT = from_date
else:
from_DT = date(year=2000, month=1, day=1)
if to_date:
to_DT = to_date + timedelta(days=1)
else:
to_DT = datetime.now().date() + timedelta(days=1)
chart_data_Dict = OrderedDict({
str(from_DT + timedelta(n)): {
'sales_count': 0,
'sales_sum': 0,
'paid_sum': 0,
'paid_cash': 0,
'paid_invoice': 0
} for n in range(int((to_DT - from_DT).days) + 1)
})
objs_i = 0
while objs_i < len(objs):
obj_i = objs[objs_i]
# if separate_managers_sales_by_link_in_order:
if not 'sales_count' in obj_i:
obj_i['sales_count'] = 0
if not 'sales_sum' in obj_i:
obj_i['sales_sum'] = 0
if not 'paid_sum' in obj_i:
obj_i['paid_sum'] = 0
if not 'receipts_sum' in obj_i:
obj_i['receipts_sum'] = 0
if not 'receipts_count' in obj_i:
obj_i['receipts_count'] = 0
# # if not 'top_sales_80' in obj_i:
# # обнуляем все при каждой итерации
# obj_i['top_sales_80'] = ''
# obj_i['manager_top_sales_80'] = ''
# if obj_i['id'] == 657:
# print('!')
obj_orders = list(filter(lambda item: item['manager_obj__id'] == obj_i['id'], orders))
cash_orders = list(filter(lambda item: item['pay_type'] == 'cash', obj_orders))
obj_pays = list(filter(lambda item: item['manager__id'] == obj_i['id'], pays))
obj_receipts = list(filter(lambda item: item['manager_obj__id'] == obj_i['id'], receipts))
cash_receipts = list(filter(lambda item: item['pay_type'] == 'cash' and item['receipts_sum'], obj_receipts))
if obj_orders:
obj_i['sales_sum'] += round(sum(item['sales_sum'] for item in obj_orders if item['sales_sum']), 2)
obj_i['sales_count'] += round(sum(item['sales_count'] for item in obj_orders if item['sales_count']), 2)
if cash_orders:
# добавляем в оплаты кэшевые операции потому как они отсутствуют в платежах
obj_i['paid_sum'] += round(sum(item['paid_sum'] for item in cash_orders if item['paid_sum']), 2)
# if obj_i['id'] == 1199:
# print('!')
if obj_receipts:
obj_i['receipts_sum'] += round(
sum(item['receipts_sum'] for item in obj_receipts if item['receipts_sum']), 2)
obj_i['receipts_count'] += round(
sum(item['receipts_count'] for item in obj_receipts if item['receipts_count']), 2)
obj_i['sales_sum'] -= obj_i['receipts_sum']
obj_i['sales_count'] -= obj_i['receipts_count']
if cash_receipts:
# минусуем из оплат кэшевые операции потому как возвраты
obj_i['paid_sum'] -= round(sum(item['receipts_sum'] for item in cash_receipts if item['receipts_sum']), 2)
if obj_pays:
obj_i['paid_sum'] += round(sum(item['sum_pay_byn'] for item in obj_pays if item['sum_pay_byn']), 2)
obj_i['indicative_sales'] = round(( obj_i['sales_sum'] + obj_i['paid_sum']) / 2, 2)
required_del_client = False
if stat_kwargs:
if stat_kwargs and 'sales_count__gte' in stat_kwargs and stat_kwargs['sales_count__gte'] and \
objs[objs_i][
'sales_count'] < float(stat_kwargs['sales_count__gte']):
required_del_client = True
elif stat_kwargs and 'sales_count__lte' in stat_kwargs and stat_kwargs['sales_count__lte'] and \
objs[objs_i][
'sales_count'] > float(stat_kwargs['sales_count__lte']):
required_del_client = True
elif stat_kwargs and 'sales_sum__gte' in stat_kwargs and stat_kwargs['sales_sum__gte'] and objs[objs_i][
'sales_sum'] < float(stat_kwargs['sales_sum__gte']):
required_del_client = True
elif stat_kwargs and 'sales_sum__lte' in stat_kwargs and stat_kwargs['sales_sum__lte'] and objs[objs_i][
'sales_sum'] > float(stat_kwargs['sales_sum__lte']):
required_del_client = True
# if 'months_count' in kwargs:
# obj_i['middle_sum_for_month'] = round( obj_i['indicative_sales'] / kwargs['months_count'], 2)
# # else:
# # print('!')
if required_del_client:
del objs[objs_i]
else:
objs_i += 1
msg = 'managers_sales_by_period_n_regions finish - {0} (processing time = {1}
---------------
'.format(
str(datetime.now()),
str(datetime.now() - log_begin_DT)
)
print(msg)
return objs, chart_data_Dict