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:
parent
6dbab6442f
commit
85d05392b8
@ -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
|
Loading…
x
Reference in New Issue
Block a user