update project

This commit is contained in:
Yousef 2023-08-16 21:04:00 +03:30
parent 0c2e5571d1
commit 531cdfbe5e
16 changed files with 445 additions and 10 deletions

View File

@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.9 (badmin)" jdkType="Python SDK" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (badmin)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (badmin)" project-jdk-type="Python SDK" />
</project>

0
admin/models.py Normal file
View File

152
admin/repository.py Normal file
View File

@ -0,0 +1,152 @@
import datetime
import os
import smtplib
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from os.path import basename
from sqlalchemy.orm import joinedload
from badmin.models.model import SubscriptionContract, SubscriptionPlan
from core.te import NewTableEngine
from database import get_db
from utility.DatabaseU import DatabaseU, Setting
ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
class SubscriptionRep:
def __init__(self):
pass
@staticmethod
def get_(_id: int):
db = next(get_db())
row = db.query(SubscriptionContract).filter(SubscriptionContract.id == _id).first()
if not row:
return None
for item in ['plan', 'owner']:
getattr(row, item)
return row
@staticmethod
def update_(_id: int, _input: dict):
db = next(get_db())
_input['updated_at'] = datetime.datetime.now()
db.query(SubscriptionContract).filter(SubscriptionContract.id == _id).update(_input)
db.commit()
return True
@staticmethod
async def sub_list(body: dict):
db = next(get_db())
return await NewTableEngine.mssql(
query_class=db,
model=SubscriptionContract,
extra_filter=[],
search_cols=[],
options=[
joinedload(SubscriptionContract.plan),
joinedload(SubscriptionContract.owner)
],
inputs=body.get('te', {})).to_dict()
@staticmethod
async def plan_list(body: dict):
db = next(get_db())
return await NewTableEngine.mssql(
query_class=db,
model=SubscriptionPlan,
extra_filter=[],
search_cols=[],
options=[],
inputs=body.get('te', {})).to_dict()
# @staticmethod
# async def send_invoice(body: dict, contract_id: int):
# db = next(get_db())
# contract = db.query(SubscriptionContract).filter(SubscriptionContract.id == contract_id).first()
# SubscriptionRep.invoice_pdf(contract)
# return "ok"
@staticmethod
def invoice_html(contract: SubscriptionContract):
invoice_template = os.path.join(ROOT_DIR, "admin/template/checkout.html")
invoice_html = open(invoice_template, "r", encoding="utf-8").read()
collection = DatabaseU.GetMongoDBDatabase()[Setting.FIRM_SETTING_COLLECTION_NAME]
settings = collection.find_one({"main_lawyer_user": contract.owner_id})
account_settings = settings['setting']['accounts']
template_settings = settings['setting']['templates']
invoice_html = invoice_html.format(
company_address=account_settings['street'] + " ," + account_settings['state'] + " ," + account_settings[
'city'],
plan_name=contract.plan.title,
per_user_price=contract.payable_amount / contract.user_limit,
user_limit=contract.user_limit,
storage_limit=contract.storage_limit,
to_date=contract.to_date.strftime("%d/%m/%Y") if contract.to_date else '-',
created_at=contract.created_at.strftime("%d/%m/%Y") if contract.created_at else '-',
from_date=contract.from_date.strftime("%d/%m/%Y") if contract.from_date else '-',
company_tel=account_settings['phone'],
company_fax=account_settings['fax'],
payable_amount=contract.payable_amount,
discounted_amount=contract.discounted_price,
owner_name=contract.owner.first_name + ' ' + contract.owner.last_name,
company_mail=account_settings['contact_email'],
company_name=account_settings['firm_name'],
company_site=account_settings['contact_website'],
company_country=account_settings['country'],
company_city=account_settings['city'],
avatar=template_settings['avatar'],
company_state=account_settings['state'] + " " + account_settings['street'] + " " + account_settings[
'city'],
)
return invoice_html
@staticmethod
def invoice_pdf(contract: SubscriptionContract):
code = f"receipt-{contract.id}"
path = os.path.join(ROOT_DIR, f"storage/temp/{code}.pdf")
html = os.path.join(ROOT_DIR, f"storage/temp/{code}.html")
if not os.path.exists(os.path.dirname(path)):
try:
os.makedirs(os.path.dirname(path))
except Exception as e:
raise e
from weasyprint import HTML
with open(html, mode="w", encoding="utf-8") as f:
f.write(SubscriptionRep.invoice_html(contract))
HTML(html).write_pdf(path)
return path
@staticmethod
def send_invoice(request, _id):
db = next(get_db())
contract = db.query(SubscriptionContract).filter(SubscriptionContract.id == _id).first()
to_emails = request.get("to_emails", [])
if len(to_emails) == 0:
return "at least enter one mail."
pdf_file = SubscriptionRep.invoice_pdf(contract)
html_tmp = SubscriptionRep.invoice_html(contract)
with smtplib.SMTP("smtp.gmail.com", 465) as server:
server.login("info@ira-lex.com", "Iralex2022")
message = MIMEMultipart("alternative")
message["subject"] = "Invoice"
message["from"] = "info@ira-lex.com"
message["to"] = ", ".join(to_emails)
with open(pdf_file, "rb") as fil:
part = MIMEApplication(
fil.read(),
Name=basename(pdf_file)
)
message_body = MIMEText(html_tmp, "html")
message.attach(message_body)
message.attach(part)
server.sendmail(
"info@ira-lex.com", to_emails, message.as_string()
)
return True

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>checkout</title>
</head>
<body>
<span>plan name : {plan_name}</span>
<br>
<span>user limit : {user_limit}</span>
<br>
<span>to time : {to_date}</span>
<br>
<span>from time {from_date}</span>
<br>
<span>craeted_at: {created_at}</span>
<br>
<span>storage limit : {storage_limit}</span>
<br>
<span>per user price: {per_user_price}</span>
<br>
<span>payable amount: {payable_amount}</span>
<br>
<span>discount amount: {discounted_amount}</span>
<br>
<span>owner name : {owner_name}</span>
<br>
<span>owner address : {owner_name}</span>
<br>
<span>company address : {company_name}</span>
<br>
<span>company fax : {company_fax}</span>
<br>
<span>company tel : {company_tel}</span>
<br>
<span>company email : {company_mail}</span>
</body>
</html>

34
admin/urls.py Normal file
View File

@ -0,0 +1,34 @@
import app
from config import conf
from utils import generateRouter
router = generateRouter("admin", auth_dependencies=False)
from admin.repository import SubscriptionRep
@router.get(f'{conf.PREFIX_API_URL}/contract' + '/{_id}')
def get(_id: int):
return SubscriptionRep.get_(_id)
@router.put(f'{conf.PREFIX_API_URL}/contract' + '/{_id}')
def update(_id: int, _input: dict):
return SubscriptionRep.update_(_id=_id, _input=_input)
@router.post(f'{conf.PREFIX_API_URL}/contract' + '/')
async def _list(body: dict):
return await SubscriptionRep.sub_list(body)
@router.post(f'{conf.PREFIX_API_URL}/plan' + '/')
async def plan_list(body: dict):
return await SubscriptionRep.plan_list(body)
@router.post(f'{conf.PREFIX_API_URL}/send-invoice' + '/{_id}')
async def send_invoice(body: dict, _id: int):
return SubscriptionRep.send_invoice(body, _id)
app.app.include_router(router)

14
main.py
View File

@ -1,22 +1,22 @@
import uvicorn
from fastapi import Depends
from fastapi.middleware.cors import CORSMiddleware
from app import app
from fastapi.middleware.cors import CORSMiddleware
from config import conf
import badmin.urls
from database import get_db
from badmin.models.model import AccountAdmin
from config import conf
from core.auth.auth import PasswordMaker
from database import get_db
import admin.urls
import badmin.urls
@app.get('/ping')
def ping():
return {"message": "pong", "production": conf.IS_PROD}
@app.get('/create')
def create_user(db=Depends(get_db)):
def create_user():
db = next(get_db())
new_admin = AccountAdmin(
first_name='Admin',
last_name='Supper',

View File

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>checkout</title>
</head>
<body>
<span>plan name : 3 months</span>
<br>
<span>user limit : 10</span>
<br>
<span>to time : 01/07/2029</span>
<br>
<span>from time 05/10/2022</span>
<br>
<span>craeted_at: 05/10/2022</span>
<br>
<span>storage limit : 1000000000.0</span>
<br>
<span>per user price: 0.1</span>
<br>
<span>payable amount: 1.0</span>
<br>
<span>discount amount: 1.0</span>
<br>
<span>owner name : Alireza KARARI</span>
<br>
<span>owner address : Alireza KARARI</span>
<br>
<span>company address : asas</span>
<br>
<span>company fax : 88888</span>
<br>
<span>company tel : 123745263</span>
<br>
<span>company email : 2hhhh2@gmail.com</span>
</body>
</html>

BIN
storage/temp/receipt-5.pdf Normal file

Binary file not shown.

54
utility/DatabaseU.py Normal file
View File

@ -0,0 +1,54 @@
import datetime
import json
import traceback
import pymongo
class Setting:
LAWYER_USER_SETTING_COLLECTION_NAME = "lawyer_user_setting"
FIRM_SETTING_COLLECTION_NAME = "lawyer_user_setting"
class DatabaseU:
LOG_COLLECTION_NAME = "log"
mongoDBClient = None
@staticmethod
def GetMongoDBDatabase():
if DatabaseU.mongoDBClient is None:
DatabaseU.mongoDBClient = pymongo.MongoClient(
"mongodb+srv://iralex:iralexpasswordofcluster@iralex.3sg8g.mongodb.net")
return DatabaseU.mongoDBClient["iralex"]
@staticmethod
def GetLogCollection():
return DatabaseU.GetMongoDBDatabase()[DatabaseU.LOG_COLLECTION_NAME]
class LogLevel:
INFO = "info"
DEBUG = "debug"
WARNING = "warning"
ERROR = "error"
@staticmethod
def InsertLog(level: str, lawyerUser=None, exception: Exception = None, debugMessage=None):
DatabaseU.GetLogCollection().insert_one({
"created_at": datetime.datetime.utcnow(),
"level": level,
"lawyer_user": json.loads(json.dumps(lawyerUser.ToDict(), default=str)),
"exception_message": str(exception),
"traceback": "".join(traceback.TracebackException.from_exception(exception).format()) if exception else None
})
@staticmethod
def ToSneakCase(_str):
result = [_str[0].lower()]
for c in _str[1:]:
if c in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
result.append('_')
result.append(c.lower())
else:
result.append(c)
return ''.join(result)

8
utility/ModelBridge.py Normal file
View File

@ -0,0 +1,8 @@
class ModelBridge:
model = None
def __init__(self, model):
self.model = model
def Excecute(self, request):
pass

73
utility/Response.py Normal file
View File

@ -0,0 +1,73 @@
import json
from django.core.handlers.wsgi import WSGIRequest
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models import Model, query
from django.forms import model_to_dict
from django.http import JsonResponse, HttpResponse
class Response(HttpResponse):
data = None
def __init__(self, content=None, encoder=DjangoJSONEncoder, jsonDumpsParams=None, **kwargs):
self.data = content
if isinstance(self.data, Model) or isinstance(self.data, query.QuerySet):
self.ConvertDataToDict()
if isinstance(self.data, dict) or isinstance(self.data, list):
kwargs.setdefault('content_type', 'application/json')
if jsonDumpsParams is None:
jsonDumpsParams = {}
self.data = json.dumps(self.data, cls=encoder, **jsonDumpsParams)
super().__init__(content=self.data, **kwargs)
else:
super().__init__(content=self.data)
def Correct(self):
self.status_code = 200
return self
def NotFound(self):
self.status_code = 404
return self
def Unauthorized(self):
self.status_code = 401
return self
def Conflict(self):
self.status_code = 409
return self
def TooLarge(self):
self.status_code = 413
return self
def Unsuspected(self):
self.status_code = 422
return self
def ConvertDataToDict(self):
if hasattr(self.data, "ToDict"):
self.data = self.data.ToDict()
elif isinstance(self.data, Model):
self.data = model_to_dict(self.data)
elif isinstance(self.data, query.QuerySet):
self.data = [m.ToDict() if hasattr(m, "ToDict") else model_to_dict(m) for m in self.data]
def Forbidden(self):
self.status_code = 403
return self
def NotAllowed(self):
self.status_code = 405
return self
def NotAcceptable(self):
self.status_code = 406
return self

8
utility/functions.py Normal file
View File

@ -0,0 +1,8 @@
from uuid import uuid4, UUID
import shortuuid
def get_v_id(_len) -> str:
short_id = shortuuid.encode(uuid4())
return short_id[:_len]

View File

@ -0,0 +1,31 @@
from datetime import datetime
from django.db import models
from django.db.models import Count, Aggregate
class ReportEngine:
def __init__(
self,
model,
values,
aggr
):
self.model = model
self.values = values
self.aggr = aggr
model: models.Model
aggr_fn: Aggregate
aggr_col: str
values: list
def filter(self, **kwargs):
self.filters = kwargs
def exec(self):
return (self.model.objects
.filter(**self.filters)
.values(*self.values)
.annotate(*self.aggr)
.order_by())

View File

@ -6,7 +6,6 @@ from pydantic import ValidationError
from starlette.requests import Request
from starlette.responses import Response
from starlette.routing import BaseRoute
import app
import schema
from badmin.models.model import AccountAdmin