194 lines
7.4 KiB
Python
194 lines
7.4 KiB
Python
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}<br>---------------<br><br>'.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}<br>---------------<br><br>'.format(
|
|
str(datetime.now()),
|
|
str(datetime.now() - log_begin_DT)
|
|
)
|
|
print(msg)
|
|
|
|
return objs, chart_data_Dict |