Skip to content

Instantly share code, notes, and snippets.

@Vasiliy566
Created January 28, 2021 15:38
Show Gist options
  • Save Vasiliy566/bbe44b094c5cd9559c18fcbc4c67f0df to your computer and use it in GitHub Desktop.
Save Vasiliy566/bbe44b094c5cd9559c18fcbc4c67f0df to your computer and use it in GitHub Desktop.
BusinessAnalytics
from django import forms
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.models import User
from .models import Deal
class AuthUserForm(AuthenticationForm, forms.ModelForm):
class Meta:
model = User
fields = ['username', 'password']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs['class'] = 'form-control'
self.fields[field].help_text = None;
self.fields[field].label = ""
self.fields['username'].widget.attrs['placeholder'] = 'Логин'
self.fields['password'].widget.attrs['placeholder'] = 'Пароль'
self.fields['username'].widget.attrs['class'] = 'form-control mb-3'
class RegisterUserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'password']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs['class'] = 'form-control'
self.fields[field].help_text = None;
self.fields[field].label = ""
self.fields['username'].widget.attrs['placeholder'] = 'Логин'
self.fields['password'].widget.attrs['placeholder'] = 'Пароль'
self.fields['username'].widget.attrs['class'] = 'form-control mb-3'
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password"])
if commit:
user.save()
return user
from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.db.models import JSONField
class Customer(models.Model):
"""
таблица организаций делающих заказы
"""
name_of_organisation = models.CharField('organisation`s name', max_length=200, unique=True)
def __str__(self):
return self.name_of_organisation
class Manager(models.Model):
"""
таблица менеджеров продающих товар
"""
manager_name = models.CharField('manager`s name', max_length=100, unique=True)
def __str__(self):
return self.manager_name
class Deal(models.Model):
"""
таблица сделок совершонных менеджером manager для покупателя customer
"""
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
manager = models.ForeignKey(Manager, on_delete=models.CASCADE)
date = models.DateField('date of drop off Shipping_date')
profit = models.FloatField()
payment_format = models.TextField('Формат оплаты', blank=True)
name_of_money_recipient = models.TextField('Фамилия получившего деньги по наличной сделке', blank=True)
date_of_receipt_of_money_cache = models.TextField('Дата получания денег по наличной сделке', blank=True)
payment_order_material = models.TextField('Материал заказа по платёжке', blank=True)
adress = models.TextField('АДРЕС', blank=True)
payment_amount = models.TextField('Объём заказа по платёжке заказчика', blank=True)
order_unit = models.TextField('Единица измерения заказа', blank=True)
unit_price_for_customer = models.TextField('Цена за единицу измерения для заказчика', blank=True)
actual_volume_received_by_the_customer = models.TextField('Фактически полученный объём заказчиком', blank=True)
Deal_balance_surplus_missed = models.TextField('Сальдо по сделке ++ излишки —— недовезли', blank=True)
payable_by_customer = models.FloatField('к оплате заказчиком')
the_date_of_payment = models.TextField('дата оплаты', blank=True)
Name_of_supplier_organization = models.TextField('Наименование организации поставщика', blank=True)
Form_No = models.TextField('№ по форме', blank=True)
Shipping_date = models.TextField('дата отгрузки', blank=True)
Amount_of_order_by_invoice_from_supplier = models.TextField('Объём заказа по счету от поставщика', blank=True)
Unit_price_from_supplier = models.TextField('Цена за единицу измерения от поставщика', blank=True)
Transportation_cost = models.TextField('Стоимость перевозки', blank=True)
Actual_shipped_volume_by_supplier = models.TextField('Фактически отгруженный объём поставщиком', blank=True)
The_balance_of_the_suppliers_deal_surplus_not_delivered = models.TextField('Сальдо по сделке у поставщика ++ излишки — недовезли', blank=True)
Payable_to_supplier = models.TextField('К оплате поставщику', blank=True)
Invoice_number_from_carrier = models.TextField('№ счета от перевозчика', blank=True)
Carrier = models.TextField('Перевозчик', blank=True)
Logist = models.TextField('Логист', blank=True)
def __str__(self):
return str(self.customer) + "_" + str(self.manager) + "_" + \
str(self.date) + "_" + str(self.profit)
# objects = models.Manager()
class ApiStats(models.Model):
"""
таблица с данными по api ( вывод апи для этого поля - [A, B, C])
"""
name_of_api = models.CharField('api name', max_length=200, unique=True)
conversation = ArrayField(
models.FloatField(), size=3,
)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class ApiStatsJson(models.Model):
"""
таблица с данными по api ( вывод апи для этого поля - [[strings], [floats]]
"""
name_of_api = models.CharField('api name', max_length=200, unique=True)
conversation = ArrayField(
JSONField(), size=3,
)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
import datetime
import logging
from apscheduler.schedulers.background import BackgroundScheduler
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.contrib.auth.views import LoginView, LogoutView
from django.shortcuts import render, redirect
from django.http import HttpResponseRedirect, HttpResponseForbidden
from django.http import HttpResponseNotFound
from django.urls import reverse_lazy
from django.views import View
from django.views.generic import CreateView
from .businesslogic.apis import get_apis_stats, recreate_googlesheet
from .forms import AuthUserForm, RegisterUserForm
from .models import Customer, Manager, Deal
from .businesslogic.metrics_calculator import profit_last_days, proceeds_last_days, \
get_average_check_last_days, get_profitability_last_days, get_amount_new_customers_last_days, \
get_managers_info_last_days, get_profit_from_new_customers_last_n_days, set_all_data_into_BD_from_exel, \
get_managers_bounty
from .businesslogic.common.utils import get_config
logger = logging.getLogger(__name__)
config = get_config()
class DealView(LoginRequiredMixin, View):
"""
отдает таблицу сделок авторизированного пользователя
"""
def get(self, request):
manager, created1 = Manager.objects.get_or_create(
manager_name=request.user
)
deal = Deal.objects.filter(manager=manager)
return render(request, "singlepage/table.html", {"deal": deal})
class SalaryView(LoginRequiredMixin, View):
"""
отдает таблицу сделок авторизированного пользователя
"""
def get(self, request):
manager, created1 = Manager.objects.get_or_create(
manager_name=request.user
)
bounty = get_managers_bounty()[str(manager.manager_name)]
api_stats = get_apis_stats()
if manager in api_stats["ncalls_for_managers"]["7days"]:
ncalls = api_stats["ncalls_for_managers"]["7days"][manager]
else:
ncalls = 0
return render(request, "singlepage/salary.html",
{"bounty": bounty,
"ncalls": ncalls})
class SummaryView(LoginRequiredMixin, View):
"""
отдает сводку только для ADMIN
"""
target_dates = ["1days", "3days", "7days"]
def get(self, request):
def generate_dates_results(calculate_function):
return {date: calculate_function(i) for date, i in zip(self.target_dates, [1, 3, 7])}
if str(request.user) != config["admin"]:
return HttpResponseForbidden()
api_stats = get_apis_stats()
set_all_data_into_BD_from_exel()
profit = generate_dates_results(profit_last_days)
proceeds_arr = [proceeds_last_days(n) for n in [1, 3, 7]]
proceeds = {date: proceeds_arr[i] for date, i in zip(self.target_dates, [0, 1, 2])}
avg_check = generate_dates_results(get_average_check_last_days)
profitability = generate_dates_results(get_profitability_last_days)
new_customers = generate_dates_results(get_amount_new_customers_last_days)
sales_plan_percent = {date: round(proceeds_arr[i] / config["sales_plan"] * 100, 1)
for date, i in zip(self.target_dates, [0, 1, 2])}
managers_ncalls = api_stats["ncalls_for_managers"]
managers = {"1days": get_managers_info_last_days(1, managers_ncalls["1days"]),
"3days": get_managers_info_last_days(3, managers_ncalls["3days"]),
"7days": get_managers_info_last_days(7, managers_ncalls["7days"]),
"updated": managers_ncalls["updated"]}
inc_applications = api_stats["inc_application"]
income_application = {date: inc_applications[date] for date in self.target_dates}
income_application.update({"updated":inc_applications["updated"]})
income_application.update({"updated": income_application["updated"]})
spending = api_stats["spendings"]
spending_on_advertising = api_stats["spendings"]
incoming_request_cost = {date: round(spending[date] / (inc_applications[date] + 0.0001), 1) for date in
self.target_dates}
incoming_request_cost.update({"updated": spending["updated"]})
profit_from_new_customers = [get_profit_from_new_customers_last_n_days(n) for n in [1, 3, 7]]
effectiveness_of_investment = {
"1days": round(profit_from_new_customers[0] / (spending["1days"] + 0.00001) * 100, 1),
"3days": round(profit_from_new_customers[1] / (spending["3days"] + 0.00001) * 100, 1),
"7days": round(profit_from_new_customers[2] / (spending["7days"] + 0.00001) * 100, 1),
"updated": spending["updated"]}
# TODO : pass JSON to html @markpristup !!!
diagram = {date: [list(api_stats["sources_stat"][date].keys()),
list(api_stats["sources_stat"][date].values())] for date in self.target_dates}
diagram.update({"updated": api_stats["sources_stat"]["updated"]})
return render(request, "singlepage/summary.html",
{"profit": profit, "proceeds": proceeds, "managers": managers,
"avg_check": avg_check, "profitability": profitability, "new_customers": new_customers,
"income_application": income_application, "spending_on_advertising": spending_on_advertising,
"incoming_request_cost": incoming_request_cost, "sales_plan_percent": sales_plan_percent,
"effectiveness_of_investment": effectiveness_of_investment,
"unique_visitors": api_stats["unique_visitors"],
"diagram": diagram, "outgoing_calls": api_stats["outgoing_calls"], })
class WholeTableView(LoginRequiredMixin, View):
"""
отдаёт таблицу всех сделок только для ADMIN
"""
def get(self, request):
if str(request.user) != config["admin"]:
return HttpResponseForbidden()
deal = Deal.objects.all()
return render(request, "singlepage/table.html", {"deal": deal})
class DealCreateView(LoginRequiredMixin, View):
def post(self, request):
manager, created1 = Manager.objects.get_or_create(
manager_name=request.user
)
customer, created2 = Customer.objects.get_or_create(
name_of_organisation=request.POST.get("name_of_organisation")
)
def validate(date_text):
try:
datetime.datetime.strptime(date_text, '%Y-%m-%d')
except ValueError:
raise ValueError("Incorrect data format, should be YYYY-MM-DD")
date = request.POST.get("data")
validate(date)
Deal.objects.create(customer=customer, manager=manager,
profit=request.POST.get("profit"),
date=date,
payment_format=request.POST.get("payment_format"),
payable_by_customer=request.POST.get("payable_by_customer"),
name_of_money_recipient=request.POST.get("name_of_money_recipient"),
date_of_receipt_of_money_cache=request.POST.get("date_of_receipt_of_money_cache"),
payment_order_material=request.POST.get("payment_order_material"),
adress=request.POST.get("adress"),
payment_amount=request.POST.get("payment_amount"),
order_unit=request.POST.get("order_unit"),
unit_price_for_customer=request.POST.get("unit_price_for_customer"),
actual_volume_received_by_the_customer=request.POST.get(
"actual_volume_received_by_the_customer"),
Deal_balance_surplus_missed=request.POST.get("Deal_balance_surplus_missed"),
the_date_of_payment=request.POST.get("the_date_of_payment"),
Name_of_supplier_organization=request.POST.get("Name_of_supplier_organization"),
Form_No=max([int(x["Form_No"]) for x in list(Deal.objects.all().values("Form_No"))]) + 1,
Shipping_date=request.POST.get("Shipping_date"),
Amount_of_order_by_invoice_from_supplier=request.POST.get(
"Amount_of_order_by_invoice_from_supplier"),
Unit_price_from_supplier=request.POST.get("Unit_price_from_supplier"),
Transportation_cost=request.POST.get("Transportation_cost"),
Actual_shipped_volume_by_supplier=request.POST.get("Actual_shipped_volume_by_supplier"),
The_balance_of_the_suppliers_deal_surplus_not_delivered=request.POST.get(
"The_balance_of_the_suppliers_deal_surplus_not_delivered"),
Payable_to_supplier=request.POST.get("Payable_to_supplier"),
Invoice_number_from_carrier=request.POST.get("Invoice_number_from_carrier"),
Carrier=request.POST.get("Carrier"),
Logist=request.POST.get("Logist")
)
return HttpResponseRedirect("/singlepage/")
def get(self, request):
customers = Customer.objects.all()
return render(request, "singlepage/create.html", {"customers": customers})
# формирование excele
def excele(request):
if str(request.user) == config["admin"]:
scheduler = BackgroundScheduler()
scheduler.add_job(recreate_googlesheet,
'date',
run_date=datetime.datetime.now()
)
scheduler.start()
return redirect(
"https://docs.google.com/spreadsheets/d/180_nue-UMtotdZJmQFLXIyP0k9OArCHMWge0kldUreY/edit#gid=0")
else:
return HttpResponseForbidden()
# удаление данных из бд
def delete(request, id):
try:
deal = Deal.objects.get(id=id)
manager_name = deal.manager
if str(manager_name) == str(request.user) or str(request.user) == config["admin"]:
name_of_organisation = deal.customer
deal.delete()
if not Deal.objects.filter(manager=manager_name).exists():
try:
manager = Manager.objects.get(manager_name=manager_name)
manager.delete()
except Manager.DoesNotExist:
pass
if not Deal.objects.filter(customer=name_of_organisation).exists():
try:
customer = Customer.objects.get(name_of_organisation=name_of_organisation)
customer.delete()
except Customer.DoesNotExist:
pass
return HttpResponseRedirect("/singlepage/")
else:
return HttpResponseForbidden()
except Deal.DoesNotExist:
return HttpResponseNotFound("<h2>Person not found</h2>")
# изменение данных в бд
def edit(request, id):
try:
deal = Deal.objects.get(id=id)
if str(deal.manager) == str(request.user) or str(request.user) == config["admin"]:
if request.method == "POST":
'''
сначала создаем нового покупателя если надо;
если покупатель которого меняем(обязательно) присутствует только в одно сделке,
то получаем меняемое поле в Customer, записываем в строку нового покупателя,
а потом удаляем меняемое поле.
'''
customer, created1 = Customer.objects.get_or_create(
name_of_organisation=request.POST.get("name_of_organisation")
)
if Deal.objects.filter(customer=deal.customer).count() == 1 and \
str(deal.customer) != str(request.POST.get("name_of_organisation")):
customer_to_delete = Customer.objects.get(name_of_organisation=deal.customer)
deal.customer = customer
customer_to_delete.delete()
else:
deal.customer = customer
deal.date = request.POST.get("data")
deal.profit = request.POST.get("profit")
deal.payment_format = request.POST.get("payment_format")
deal.payable_by_customer = request.POST.get("payable_by_customer")
deal.name_of_money_recipient = request.POST.get("name_of_money_recipient")
deal.date_of_receipt_of_money_cache = request.POST.get("date_of_receipt_of_money_cache")
deal.payment_order_material = request.POST.get("payment_order_material")
deal.adress = request.POST.get("adress")
deal.payment_amount = request.POST.get("payment_amount")
deal.order_unit = request.POST.get("order_unit")
deal.unit_price_for_customer = request.POST.get("unit_price_for_customer")
deal.actual_volume_received_by_the_customer = request.POST.get("actual_volume_received_by_the_customer")
deal.Deal_balance_surplus_missed = request.POST.get("Deal_balance_surplus_missed")
deal.the_date_of_payment = request.POST.get("the_date_of_payment")
deal.Name_of_supplier_organization = request.POST.get("Name_of_supplier_organization")
deal.Shipping_date = request.POST.get("Shipping_date")
deal.Amount_of_order_by_invoice_from_supplier = request.POST.get(
"Amount_of_order_by_invoice_from_supplier")
deal.Unit_price_from_supplier = request.POST.get("Unit_price_from_supplier")
deal.Transportation_cost = request.POST.get("Transportation_cost")
deal.Actual_shipped_volume_by_supplier = request.POST.get("Actual_shipped_volume_by_supplier")
deal.The_balance_of_the_suppliers_deal_surplus_not_delivered = request.POST.get(
"The_balance_of_the_suppliers_deal_surplus_not_delivered")
deal.Payable_to_supplier = request.POST.get("Payable_to_supplier")
deal.Invoice_number_from_carrier = request.POST.get("Invoice_number_from_carrier")
deal.Carrier = request.POST.get("Carrier")
deal.Logist = request.POST.get("Logist")
deal.save()
return HttpResponseRedirect("/singlepage/")
else:
return render(request, "singlepage/edit.html", {"deal": deal})
else:
return HttpResponseForbidden()
except Deal.DoesNotExist:
return HttpResponseNotFound("<h2>Deal not found</h2>")
class MyLoginView(LoginView):
template_name = 'singlepage/login.html'
success_url = reverse_lazy('main')
form_class = AuthUserForm
def get_success_url(self):
return self.success_url
class MyLogoutView(LogoutView):
next_page = reverse_lazy('login_page')
class RegisterUserView(CreateView):
model = User
template_name = 'singlepage/register_page.html'
success_url = reverse_lazy('main')
form_class = RegisterUserForm
success_msg = "Пользователь успешно создан"
def get(self, request, *args, **kwargs):
if str(request.user) != config["admin"]:
return HttpResponseForbidden()
else:
return super().get(self, request, *args, **kwargs)
def post(self, request, *args, **kwargs):
if str(request.user) != config["admin"]:
return HttpResponseForbidden()
else:
return super().post(self, request, *args, **kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment