Added session support, but right now it is defaulting to 2 week long session

Reports working:
 Ledger
 Balance Sheet
 Profit & Loss
 Closing Stock
This commit is contained in:
tanshu 2020-05-12 02:57:48 +05:30
parent 6dbab6442f
commit 85d05392b8
8 changed files with 181 additions and 108 deletions

@ -1,5 +1,6 @@
import uvicorn
from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware
from .routers import (
account,
@ -17,15 +18,17 @@ from .routers import (
login,
)
from .routers.auth import client, user, role
from .routers.reports import ledger, balance_sheet, profit_loss, closing_stock
from .db.base_class import Base
from .config import Settings as settings
from .db.session import SessionLocal, engine
from .db.session import engine
Base.metadata.create_all(bind=engine)
app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="c982367648")
# app.include_router(brewman.routers, prefix="/api/db-image", tags=["db-image"])
app.include_router(login.router, tags=["login"])
app.include_router(account.router, prefix="/api/accounts", tags=["accounts"])
@ -57,6 +60,10 @@ app.include_router(recipe.router, prefix="/api/recipes", tags=["products"])
app.include_router(client.router, prefix="/api/clients", tags=["clients"])
app.include_router(role.router, prefix="/api/roles", tags=["users"])
app.include_router(user.router, prefix="/api/users", tags=["users"])
app.include_router(ledger.router, prefix="/api/ledger", tags=["reports"])
app.include_router(balance_sheet.router, prefix="/api/balance-sheet", tags=["reports"])
app.include_router(profit_loss.router, prefix="/api/profit-loss", tags=["reports"])
app.include_router(closing_stock.router, prefix="/api/closing-stock", tags=["reports"])
def init():

@ -1,8 +1,13 @@
import datetime
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func, desc
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from brewman.models.master import AccountType, AccountBase
from brewman.models.voucher import Voucher, Journal, VoucherType
from brewman.routers.reports.closing_stock import get_closing_stock
from brewman.routers.reports.profit_loss import get_accumulated_profit
@ -12,33 +17,47 @@ from brewman.routers.services.session import (
session_period_finish,
)
from fastapi import APIRouter
router = APIRouter()
@router.get("/api/balance-sheet") # "Balance Sheet"
def report_blank(request):
return {"date": session_period_finish(request), "body": [], "footer": []}
# Dependency
def get_db() -> Session:
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.get("/api/balance-sheet/{date}") # "Balance Sheet"
def report_data(request):
date = request.matchdict.get("date", None)
body, footer = build_balance_sheet(date, request.dbsession)
session_period_set(session_period_start(request), date, request)
@router.get("")
def report_blank(
request: Request,
user: UserToken = Security(get_user, scopes=["balance-sheet"]),
):
return {"date": session_period_finish(request.session), "body": [], "footer": []}
@router.get("/{date}")
def report_data(
date: str,
request: Request,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["balance-sheet"]),
):
body, footer = build_balance_sheet(date, db)
session_period_set(session_period_start(request.session), date, request.session)
return {"date": date, "body": body, "footer": footer}
def build_balance_sheet(finish_date, dbsession):
def build_balance_sheet(finish_date, db):
if not isinstance(finish_date, datetime.datetime):
finish_date = datetime.datetime.strptime(finish_date, "%d-%b-%Y")
type_list = [i.id for i in AccountType.list() if i.balance_sheet == True]
report = []
groups = dict()
# Add Net Profit / Loss
closing_stock = get_closing_stock(finish_date, dbsession)
net_profit = get_accumulated_profit(finish_date, dbsession) - closing_stock
closing_stock = get_closing_stock(finish_date, db)
net_profit = get_accumulated_profit(finish_date, db) - closing_stock
total_amount = net_profit
report.append(
{
@ -69,7 +88,7 @@ def build_balance_sheet(finish_date, dbsession):
amount_sum = func.sum(Journal.amount * Journal.debit)
query = (
dbsession.query(AccountBase, amount_sum)
db.query(AccountBase, amount_sum)
.join(Journal.voucher)
.join(Journal.account)
.filter(Voucher.date <= finish_date)

@ -1,7 +1,12 @@
import datetime
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from brewman.models.master import Product, CostCentre
from brewman.models.voucher import Voucher, Journal, Inventory
from brewman.routers.services.session import (
@ -10,31 +15,45 @@ from brewman.routers.services.session import (
session_period_finish,
)
from fastapi import APIRouter
router = APIRouter()
@router.get("/api/closing-stock") # "Closing Stock"
def report_blank(request):
return {"date": session_period_finish(request), "body": []}
# Dependency
def get_db() -> Session:
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.get("/api/closing-stock/{date}") # "Closing Stock"
def report_data(request):
date = request.matchdict.get("date", None)
session_period_set(session_period_start(request), date, request)
return {"date": date, "body": build_report(date, request.dbsession)}
@router.get("") # "Closing Stock"
def report_blank(
request: Request,
user: UserToken = Security(get_user, scopes=["closing-stock"]),
):
return {"date": session_period_finish(request.session), "body": []}
def build_report(date, dbsession):
@router.get("/{date}")
def report_data(
date: str,
request: Request,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["closing-stock"]),
):
session_period_set(session_period_start(request.session), date, request.session)
return {"date": date, "body": build_report(date, db)}
def build_report(date, db):
date = datetime.datetime.strptime(date, "%d-%b-%Y")
amount_sum = func.sum(
Journal.debit * Inventory.quantity * Inventory.rate * (1 + Inventory.tax)
).label("amount")
quantity_sum = func.sum(Journal.debit * Inventory.quantity).label("quantity")
query = (
dbsession.query(Product, quantity_sum, amount_sum)
db.query(Product, quantity_sum, amount_sum)
.join(Product.inventories)
.join(Inventory.voucher)
.join(Voucher.journals)
@ -59,9 +78,9 @@ def build_report(date, dbsession):
return body
def get_opening_stock(start_date, dbsession):
def get_opening_stock(start_date, db):
opening_stock = (
dbsession.query(
db.query(
func.sum(
Inventory.quantity
* Inventory.rate
@ -79,9 +98,9 @@ def get_opening_stock(start_date, dbsession):
return 0 if opening_stock is None else opening_stock
def get_closing_stock(finish_date, dbsession):
def get_closing_stock(finish_date, db):
closing_stock = (
dbsession.query(
db.query(
func.sum(
Inventory.quantity
* Inventory.rate

@ -1,9 +1,13 @@
import datetime
import uuid
from sqlalchemy.orm import joinedload_all
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import joinedload_all, Session
from sqlalchemy.sql.expression import func
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from brewman.models.master import AccountBase
from brewman.models.voucher import Voucher, Journal, VoucherType
from brewman.routers.services.session import (
@ -11,34 +15,47 @@ from brewman.routers.services.session import (
session_period_start,
session_period_finish,
)
from brewman.routers.services.voucher import get_edit_url
from fastapi import APIRouter
router = APIRouter()
@router.get("/api/ledger") # "Ledger"
def show_blank(request):
# Dependency
def get_db() -> Session:
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.get("")
def show_blank(
request: Request,
user: UserToken = Security(get_user, scopes=["ledger"]),
):
return {
"startDate": session_period_start(request),
"finishDate": session_period_finish(request),
"startDate": session_period_start(request.session),
"finishDate": session_period_finish(request.session),
"account": None,
"body": [],
}
@router.get("/api/ledger/{id}") # "Ledger"
def show_data(request):
account = (
request.dbsession.query(AccountBase)
.filter(AccountBase.id == uuid.UUID(request.matchdict["id"]))
.first()
)
start_date = request.GET.get("s", session_period_start(request))
finish_date = request.GET.get("f", session_period_finish(request))
body = build_report(account.id, start_date, finish_date, request)
session_period_set(start_date, finish_date, request)
@router.get("/{id_}")
def show_data(
id_: uuid.UUID,
request: Request,
s: str = None,
f: str = None,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["ledger"]),
):
account = db.query(AccountBase).filter(AccountBase.id == id_).first()
start_date = s if s is not None else session_period_start(request.session)
finish_date = f if f is not None else session_period_finish(request.session)
body = build_report(account.id, start_date, finish_date, db)
session_period_set(start_date, finish_date, request.session)
return {
"startDate": start_date,
"finishDate": finish_date,
@ -47,13 +64,13 @@ def show_data(request):
}
def build_report(account_id, start_date, finish_date, request):
def build_report(account_id, start_date, finish_date, db):
body = []
opening = opening_balance(account_id, start_date, request.dbsession)
opening = opening_balance(account_id, start_date, db)
body.append(opening)
query = (
request.dbsession.query(Voucher)
db.query(Voucher)
.options(joinedload_all(Voucher.journals, Journal.account, innerjoin=True))
.filter(Voucher.journals.any(Journal.account_id == account_id))
.filter(Voucher.date >= datetime.datetime.strptime(start_date, "%d-%b-%Y"))
@ -87,7 +104,7 @@ def build_report(account_id, start_date, finish_date, request):
"id": voucher.id,
"date": voucher.date.strftime("%d-%b-%Y"),
"name": name,
"url": get_edit_url(voucher, request),
"url": "", # get_edit_url(voucher, request),
"type": VoucherType.by_id(voucher.type).name,
"narration": voucher.narration,
"debit": debit,
@ -98,9 +115,9 @@ def build_report(account_id, start_date, finish_date, request):
return body
def opening_balance(account_id, start_date, dbsession):
def opening_balance(account_id, start_date, db):
opening = (
dbsession.query(func.sum(Journal.amount * Journal.debit))
db.query(func.sum(Journal.amount * Journal.debit))
.join(Journal.voucher)
.filter(Voucher.date < datetime.datetime.strptime(start_date, "%d-%b-%Y"))
.filter(Voucher.type != VoucherType.by_name("Issue").id)

@ -1,7 +1,13 @@
import datetime
from fastapi import APIRouter, Depends, Security, Request
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func, desc
from ...schemas.auth import UserToken
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from brewman.models.master import AccountType, AccountBase
from brewman.models.voucher import Voucher, Journal, VoucherType
from brewman.routers.reports.closing_stock import get_opening_stock, get_closing_stock
@ -11,36 +17,50 @@ from brewman.routers.services.session import (
session_period_finish,
)
from fastapi import APIRouter
router = APIRouter()
@router.get("/api/profit-loss", permission="Profit & Loss")
def report_blank(request):
# Dependency
def get_db() -> Session:
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.get("")
def report_blank(
request: Request,
user: UserToken = Security(get_user, scopes=["profit-&-loss"]),
):
return {
"startDate": session_period_start(request),
"finishDate": session_period_finish(request),
"startDate": session_period_start(request.session),
"finishDate": session_period_finish(request.session),
"body": [],
"footer": {},
}
@router.get("/api/profit-loss", request_param=["s", "f"], permission="Profit & Loss")
def report_data(request):
start_date = request.GET["s"]
finish_date = request.GET["f"]
body, footer = build_profit_loss(start_date, finish_date, request.dbsession)
session_period_set(start_date, finish_date, request)
@router.get("/{start}/{finish}")
def report_data(
start: str,
finish: str,
request: Request,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["profit-&-loss"]),
):
body, footer = build_profit_loss(start, finish, db)
session_period_set(start, finish, request.session)
return {
"startDate": start_date,
"finishDate": finish_date,
"startDate": start,
"finishDate": finish,
"body": body,
"footer": footer,
}
def build_profit_loss(start_date, finish_date, dbsession):
def build_profit_loss(start_date, finish_date, db):
start_date = datetime.datetime.strptime(start_date, "%d-%b-%Y")
finish_date = datetime.datetime.strptime(finish_date, "%d-%b-%Y")
profit_type_list = [i.id for i in AccountType.list() if i.balance_sheet == False]
@ -49,7 +69,7 @@ def build_profit_loss(start_date, finish_date, dbsession):
amount_sum = func.sum(Journal.amount * Journal.debit)
query = (
dbsession.query(AccountBase, amount_sum)
db.query(AccountBase, amount_sum)
.join(Journal.voucher)
.join(Journal.account)
.filter(Voucher.date >= start_date)
@ -63,8 +83,8 @@ def build_profit_loss(start_date, finish_date, dbsession):
)
# Get opening / closing stock
opening_stock = get_opening_stock(start_date, dbsession)
closing_stock = get_closing_stock(finish_date, dbsession)
opening_stock = get_opening_stock(start_date, db)
closing_stock = get_closing_stock(finish_date, db)
total_amount = (opening_stock - closing_stock) * -1
report.append(
@ -117,11 +137,11 @@ def build_profit_loss(start_date, finish_date, dbsession):
return sorted(report, key=lambda d: d["order"]), footer
def get_accumulated_profit(finish_date, dbsession):
def get_accumulated_profit(finish_date, db):
type_list = [i.id for i in AccountType.list() if i.balance_sheet is False]
accumulated_profit = (
dbsession.query(func.sum(Journal.amount * Journal.debit))
db.query(func.sum(Journal.amount * Journal.debit))
.join(Journal.voucher)
.join(Journal.account)
.filter(Voucher.date <= finish_date)

@ -1,39 +1,34 @@
from datetime import date, timedelta
def session_current_date(request):
session = request.session
if "currentDate" not in session:
session["currentDate"] = date.today().strftime("%d-%b-%Y")
return session["currentDate"]
def session_current_date(session):
if "date" not in session:
session["date"] = date.today().strftime("%d-%b-%Y")
return session["date"]
def session_current_date_set(request, date_):
session = request.session
session["currentDate"] = date_
return session["currentDate"]
def session_current_date_set(session, date_):
session["date"] = date_
return session["date"]
def session_period_start(request):
session = request.session
if "periodStart" not in session:
session["periodStart"] = get_first_day(date.today()).strftime("%d-%b-%Y")
return session["periodStart"]
def session_period_start(session):
if "start" not in session:
session["start"] = get_first_day(date.today()).strftime("%d-%b-%Y")
return session["start"]
def session_period_finish(request):
session = request.session
if "periodFinish" not in session:
session["periodFinish"] = get_last_day(date.today()).strftime("%d-%b-%Y")
return session["periodFinish"]
def session_period_finish(session):
if "finish" not in session:
session["finish"] = get_last_day(date.today()).strftime("%d-%b-%Y")
return session["finish"]
def session_period_set(start, finish, request):
session = request.session
session["periodStart"] = (
def session_period_set(start, finish, session):
session["start"] = (
start if isinstance(start, str) else start.strftime("%d-%b-%Y")
)
session["periodFinish"] = (
session["finish"] = (
finish if isinstance(finish, str) else finish.strftime("%d-%b-%Y")
)

@ -21,14 +21,9 @@ export class ProfitLossService {
}
list(startDate: string, finishDate): Observable<ProfitLoss> {
const options = {params: new HttpParams()};
if (startDate !== null) {
options.params = options.params.set('s', startDate);
}
if (finishDate !== null) {
options.params = options.params.set('f', finishDate);
}
return <Observable<ProfitLoss>>this.http.get<ProfitLoss>(url, options)
startDate = startDate ? `/${startDate}` : '';
finishDate = finishDate ? `/${finishDate}` : '';
return <Observable<ProfitLoss>>this.http.get<ProfitLoss>(`${url}${startDate}${finishDate}`)
.pipe(
catchError(this.log.handleError(serviceName, 'list'))
);

@ -8,3 +8,4 @@ psycopg2
python-multipart
pyjwt
alembic
itsdangerous