update project
This commit is contained in:
parent
0c2e5571d1
commit
531cdfbe5e
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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,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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
14
main.py
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
Binary file not shown.
|
|
@ -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)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
class ModelBridge:
|
||||
model = None
|
||||
|
||||
def __init__(self, model):
|
||||
self.model = model
|
||||
|
||||
def Excecute(self, request):
|
||||
pass
|
||||
|
|
@ -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
|
||||
|
|
@ -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]
|
||||
|
|
@ -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())
|
||||
Loading…
Reference in New Issue