Voucher Post and Delete working!!
Also figured out why a lot of exceptions are generating 500 errors. Those errors are again caught by the general exception catcher in the end and re thrown. Need to fix this.
This commit is contained in:
parent
0177921e84
commit
8ae67863eb
brewman
overlord/src/app/core
@ -31,6 +31,7 @@ from .routers import (
|
|||||||
journal,
|
journal,
|
||||||
purchase,
|
purchase,
|
||||||
purchase_return,
|
purchase_return,
|
||||||
|
voucher,
|
||||||
)
|
)
|
||||||
from .routers.auth import client, user, role
|
from .routers.auth import client, user, role
|
||||||
from .routers.reports import (
|
from .routers.reports import (
|
||||||
@ -135,6 +136,7 @@ app.include_router(
|
|||||||
)
|
)
|
||||||
app.include_router(incentive.router, prefix="/api/incentive", tags=["vouchers"])
|
app.include_router(incentive.router, prefix="/api/incentive", tags=["vouchers"])
|
||||||
app.include_router(credit_salary.router, prefix="/api/credit-salary", tags=["vouchers"])
|
app.include_router(credit_salary.router, prefix="/api/credit-salary", tags=["vouchers"])
|
||||||
|
app.include_router(voucher.router, prefix="/api", tags=["vouchers"])
|
||||||
|
|
||||||
app.include_router(
|
app.include_router(
|
||||||
lock_information.router, prefix="/api/lock-information", tags=["settings"]
|
lock_information.router, prefix="/api/lock-information", tags=["settings"]
|
||||||
|
@ -39,11 +39,15 @@ def db_image(
|
|||||||
|
|
||||||
|
|
||||||
def save_files(voucher_id: uuid.UUID, i: List[bytes], t: List[bytes], db: Session):
|
def save_files(voucher_id: uuid.UUID, i: List[bytes], t: List[bytes], db: Session):
|
||||||
|
i = i or []
|
||||||
|
t = t or []
|
||||||
for index, value in enumerate(i):
|
for index, value in enumerate(i):
|
||||||
db.add(DbImage(voucher_id, "voucher", i[index], t[index]))
|
db.add(DbImage(voucher_id, "voucher", i[index], t[index]))
|
||||||
|
|
||||||
|
|
||||||
def update_files(voucher_id: uuid.UUID, data: List[output.ImageUpload], i: List[bytes], t: List[bytes], db: Session):
|
def update_files(voucher_id: uuid.UUID, data: List[output.ImageUpload], i: List[bytes], t: List[bytes], db: Session):
|
||||||
|
i = i or []
|
||||||
|
t = t or []
|
||||||
old = [f.id_ for f in data if f.id_]
|
old = [f.id_ for f in data if f.id_]
|
||||||
images = db.query(DbImage).filter(DbImage.resource_id == voucher_id).all()
|
images = db.query(DbImage).filter(DbImage.resource_id == voucher_id).all()
|
||||||
for image in [i for i in images if i.id not in old]:
|
for image in [i for i in images if i.id not in old]:
|
||||||
|
@ -178,7 +178,14 @@ def get_id(
|
|||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
|
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
|
||||||
|
if item is None:
|
||||||
|
raise ValueError("Voucher not found")
|
||||||
return voucher_info(item, db)
|
return voucher_info(item, db)
|
||||||
|
except ValueError as e:
|
||||||
|
db.rollback()
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail=str(e),
|
||||||
|
)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
@ -53,8 +53,6 @@ def save_route(
|
|||||||
user: UserToken = Security(get_user, scopes=["purchase-return"]),
|
user: UserToken = Security(get_user, scopes=["purchase-return"]),
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
i = i or []
|
|
||||||
t = t or []
|
|
||||||
item: Voucher = save(data, user, db)
|
item: Voucher = save(data, user, db)
|
||||||
save_inventories(item, data.inventories, db)
|
save_inventories(item, data.inventories, db)
|
||||||
save_journals(item, data.vendor, db)
|
save_journals(item, data.vendor, db)
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
|
import traceback
|
||||||
|
import uuid
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
import uuid
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
|
from fastapi import (
|
||||||
|
APIRouter,
|
||||||
|
HTTPException,
|
||||||
|
status,
|
||||||
|
Depends,
|
||||||
|
Security,
|
||||||
|
)
|
||||||
from sqlalchemy import func, or_
|
from sqlalchemy import func, or_
|
||||||
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from brewman.models.auth import User
|
|
||||||
from brewman.models.master import (
|
from brewman.models.master import (
|
||||||
AccountBase,
|
AccountBase,
|
||||||
CostCentre,
|
CostCentre,
|
||||||
@ -14,7 +23,6 @@ from brewman.models.master import (
|
|||||||
Account,
|
Account,
|
||||||
)
|
)
|
||||||
from brewman.models.voucher import (
|
from brewman.models.voucher import (
|
||||||
Voucher,
|
|
||||||
VoucherType,
|
VoucherType,
|
||||||
Inventory,
|
Inventory,
|
||||||
DbImage,
|
DbImage,
|
||||||
@ -22,97 +30,81 @@ from brewman.models.voucher import (
|
|||||||
Journal,
|
Journal,
|
||||||
)
|
)
|
||||||
from brewman.routers import get_lock_info
|
from brewman.routers import get_lock_info
|
||||||
from ...core.session import get_first_day
|
from brewman.core.session import get_first_day
|
||||||
|
from ..schemas import to_camel
|
||||||
from fastapi import APIRouter, Depends, Security, Request, HTTPException, status
|
from ..schemas.auth import UserToken
|
||||||
|
from ..core.security import get_current_active_user as get_user
|
||||||
from ...schemas.auth import UserToken
|
from ..db.session import SessionLocal
|
||||||
|
from ..models.voucher import Voucher
|
||||||
|
import brewman.schemas.voucher as output
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/voucher/{id}") # , request_param="p" "Post Vouchers"
|
# Dependency
|
||||||
def voucher_post(request):
|
def get_db() -> Session:
|
||||||
user = (
|
try:
|
||||||
request.dbsession.query(User)
|
db = SessionLocal()
|
||||||
.filter(User.id == uuid.UUID(request.authenticated_userid))
|
yield db
|
||||||
.one()
|
finally:
|
||||||
)
|
db.close()
|
||||||
voucher = (
|
|
||||||
request.dbsession.query(Voucher)
|
|
||||||
.filter(Voucher.id == uuid.UUID(request.matchdict["id"]))
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
start, finish = get_lock_info(request.dbsession)
|
|
||||||
if start is not None and start > voucher.date:
|
|
||||||
raise ValidationError(
|
|
||||||
f"Vouchers before {start.strftime('%d-%b-%Y')} have been locked."
|
|
||||||
)
|
|
||||||
elif finish is not None and finish < voucher.date:
|
|
||||||
raise ValidationError(
|
|
||||||
f"Vouchers after {finish.strftime('%d-%b-%Y')} have been locked."
|
|
||||||
)
|
|
||||||
voucher.posted = True
|
|
||||||
voucher.poster_id = user.id
|
|
||||||
transaction.commit()
|
|
||||||
new_voucher = (
|
|
||||||
request.dbsession.query(Voucher).filter(Voucher.id == voucher.id).first()
|
|
||||||
)
|
|
||||||
return voucher_info(new_voucher, request)
|
|
||||||
|
|
||||||
|
|
||||||
def check_delete_permissions(request, voucher):
|
@router.post("/post-voucher/{id_}", response_model=output.Voucher)
|
||||||
user = (
|
def post_voucher(
|
||||||
request.dbsession.query(User)
|
id_: uuid.UUID,
|
||||||
.filter(User.id == uuid.UUID(request.authenticated_userid))
|
db: Session = Depends(get_db),
|
||||||
.one()
|
user: UserToken = Security(get_user, scopes=["post-vouchers"]),
|
||||||
)
|
|
||||||
|
|
||||||
if voucher.posted and not request.has_permission("Edit Posted Vouchers"):
|
|
||||||
response = Response("You are not allowed to edit posted vouchers")
|
|
||||||
response.status_int = 403
|
|
||||||
return response
|
|
||||||
elif voucher.user_id != user.id and not request.has_permission(
|
|
||||||
"Edit Other User's Vouchers"
|
|
||||||
):
|
):
|
||||||
response = Response("You are not allowed to edit other user's vouchers")
|
try:
|
||||||
response.status_int = 403
|
voucher: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
|
||||||
return response
|
check_voucher_lock_info(voucher.date, voucher.date, db)
|
||||||
elif not request.has_permission(VoucherType.by_id(voucher.type).name):
|
voucher.posted = True
|
||||||
response = Response(
|
voucher.poster_id = user.id_
|
||||||
f"You are not allowed ({VoucherType.by_id(voucher.type).name}) vouchers"
|
db.commit()
|
||||||
|
return voucher_info(voucher, db)
|
||||||
|
except SQLAlchemyError as e:
|
||||||
|
db.rollback()
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e),
|
||||||
)
|
)
|
||||||
response.status_int = 403
|
except Exception:
|
||||||
return response
|
db.rollback()
|
||||||
start, finish = get_lock_info(request.dbsession)
|
raise HTTPException(
|
||||||
if start is not None and start > voucher.date:
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
response = Response(
|
detail=traceback.format_exc(),
|
||||||
f"Vouchers before {start.strftime('%d-%b-%Y')} have been locked."
|
|
||||||
)
|
)
|
||||||
response.status_int = 403
|
|
||||||
return response
|
|
||||||
elif finish is not None and finish < voucher.date:
|
|
||||||
response = Response(
|
|
||||||
f"Vouchers after {finish.strftime('%d-%b-%Y')} have been locked."
|
|
||||||
)
|
|
||||||
response.status_int = 403
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/api/voucher/{id}")
|
def check_delete_permissions(voucher: Voucher, user: UserToken):
|
||||||
def delete(request):
|
voucher_type = VoucherType.by_id(voucher.type).name.replace(" ", "-").lower()
|
||||||
voucher = (
|
if voucher_type in ["payment", "purchase"]:
|
||||||
request.dbsession.query(Voucher)
|
voucher_type = "journal"
|
||||||
.filter(Voucher.id == uuid.UUID(request.matchdict["id"]))
|
if voucher.posted and "edit-posted-vouchers" not in user.permissions:
|
||||||
.first()
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit posted vouchers",
|
||||||
)
|
)
|
||||||
images = (
|
elif voucher.user_id != user.id_ and "edit-other-user's-vouchers" not in user.permissions:
|
||||||
request.dbsession.query(DbImage).filter(DbImage.resource_id == voucher.id).all()
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit other user's vouchers",
|
||||||
)
|
)
|
||||||
permission = check_delete_permissions(request, voucher)
|
elif voucher_type not in user.permissions:
|
||||||
if permission is not None:
|
raise HTTPException(
|
||||||
return permission
|
status_code=status.HTTP_403_FORBIDDEN, detail=f"You are not allowed ({VoucherType.by_id(voucher.type).name}) vouchers",
|
||||||
json_voucher = voucher_info(voucher, request)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/delete/{id_}")
|
||||||
|
def delete_voucher(
|
||||||
|
id_: uuid.UUID,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
user: UserToken = Security(get_user),
|
||||||
|
):
|
||||||
|
voucher: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
|
||||||
|
images = db.query(DbImage).filter(DbImage.resource_id == voucher.id).all()
|
||||||
|
check_delete_permissions(voucher, user)
|
||||||
|
check_voucher_lock_info(None, voucher.date, db)
|
||||||
|
json_voucher = voucher_info(voucher, db)
|
||||||
batches_to_delete = []
|
batches_to_delete = []
|
||||||
if voucher.type == VoucherType.by_name("Issue").id:
|
if voucher.type == VoucherType.by_name("Issue").id:
|
||||||
for item in voucher.journals:
|
for item in voucher.journals:
|
||||||
@ -142,7 +134,7 @@ def delete(request):
|
|||||||
elif voucher.type == VoucherType.by_name("Purchase").id:
|
elif voucher.type == VoucherType.by_name("Purchase").id:
|
||||||
for item in voucher.inventories:
|
for item in voucher.inventories:
|
||||||
uses = (
|
uses = (
|
||||||
request.dbsession.query(func.count(Inventory.id))
|
db.query(func.count(Inventory.id))
|
||||||
.filter(Inventory.batch_id == item.batch.id)
|
.filter(Inventory.batch_id == item.batch.id)
|
||||||
.filter(Inventory.id != item.id)
|
.filter(Inventory.id != item.id)
|
||||||
.scalar()
|
.scalar()
|
||||||
@ -156,21 +148,12 @@ def delete(request):
|
|||||||
for item in voucher.inventories:
|
for item in voucher.inventories:
|
||||||
item.batch.quantity_remaining += item.quantity
|
item.batch.quantity_remaining += item.quantity
|
||||||
for b in batches_to_delete:
|
for b in batches_to_delete:
|
||||||
request.dbsession.delete(b)
|
db.delete(b)
|
||||||
request.dbsession.delete(voucher)
|
db.delete(voucher)
|
||||||
for image in images:
|
for image in images:
|
||||||
request.dbsession.delete(image)
|
db.delete(image)
|
||||||
transaction.commit()
|
db.commit()
|
||||||
return blank_voucher(info=json_voucher, dbsession=request.dbsession)
|
return blank_voucher(info=json_voucher, db=db)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/voucher/{id}")
|
|
||||||
def get_old(request):
|
|
||||||
id_ = request.matchdict.get("id", None)
|
|
||||||
voucher = (
|
|
||||||
request.dbsession.query(Voucher).filter(Voucher.id == uuid.UUID(id_)).first()
|
|
||||||
)
|
|
||||||
return voucher_info(voucher, request)
|
|
||||||
|
|
||||||
|
|
||||||
def voucher_info(voucher, db):
|
def voucher_info(voucher, db):
|
@ -24,7 +24,7 @@ export class VoucherService {
|
|||||||
const endpoint = type.replace(/ /g, '-').toLowerCase();
|
const endpoint = type.replace(/ /g, '-').toLowerCase();
|
||||||
return <Observable<Voucher>>this.http.get<Voucher>(`${url}/${endpoint}/${id}`)
|
return <Observable<Voucher>>this.http.get<Voucher>(`${url}/${endpoint}/${id}`)
|
||||||
.pipe(
|
.pipe(
|
||||||
catchError(this.log.handleError(serviceName, 'get'))
|
catchError(this.log.handleError(serviceName, 'Get Voucher'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ export class VoucherService {
|
|||||||
}
|
}
|
||||||
return <Observable<Voucher>>this.http.get<Voucher>(`${url}/${endpoint}`, options)
|
return <Observable<Voucher>>this.http.get<Voucher>(`${url}/${endpoint}`, options)
|
||||||
.pipe(
|
.pipe(
|
||||||
catchError(this.log.handleError(serviceName, 'getOfType'))
|
catchError(this.log.handleError(serviceName, 'Get Voucher of Type'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,22 +44,21 @@ export class VoucherService {
|
|||||||
const options = {params: new HttpParams().set('d', date)};
|
const options = {params: new HttpParams().set('d', date)};
|
||||||
return <Observable<Voucher>>this.http.get<Voucher>(`${url}/incentive`, options)
|
return <Observable<Voucher>>this.http.get<Voucher>(`${url}/incentive`, options)
|
||||||
.pipe(
|
.pipe(
|
||||||
catchError(this.log.handleError(serviceName, 'list'))
|
catchError(this.log.handleError(serviceName, 'Get Incentive'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
post(id: string): Observable<Voucher> {
|
post(id: string): Observable<Voucher> {
|
||||||
const options = {params: new HttpParams().set('p', '')};
|
return <Observable<Voucher>>this.http.post<Voucher>(`${url}/post-voucher/${id}`, {})
|
||||||
return <Observable<Voucher>>this.http.post<Voucher>(`${url}/${id}`, {}, options)
|
|
||||||
.pipe(
|
.pipe(
|
||||||
catchError(this.log.handleError(serviceName, 'list'))
|
catchError(this.log.handleError(serviceName, 'Post Voucher'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(id: string): Observable<Voucher> {
|
delete(id: string): Observable<Voucher> {
|
||||||
return <Observable<Voucher>>this.http.delete<Voucher>(`${url}/${id}`, httpOptions)
|
return <Observable<Voucher>>this.http.delete<Voucher>(`${url}/delete/${id}`, httpOptions)
|
||||||
.pipe(
|
.pipe(
|
||||||
catchError(this.log.handleError(serviceName, 'delete'))
|
catchError(this.log.handleError(serviceName, 'Delete Voucher'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +81,7 @@ export class VoucherService {
|
|||||||
fd.append('data', JSON.stringify(voucher));
|
fd.append('data', JSON.stringify(voucher));
|
||||||
return <Observable<Voucher>>this.http.post<Voucher>(`${url}/${endpoint}`, fd)
|
return <Observable<Voucher>>this.http.post<Voucher>(`${url}/${endpoint}`, fd)
|
||||||
.pipe(
|
.pipe(
|
||||||
catchError(this.log.handleError(serviceName, 'save'))
|
catchError(this.log.handleError(serviceName, 'Save Voucher'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +95,7 @@ export class VoucherService {
|
|||||||
fd.append('data', JSON.stringify(voucher));
|
fd.append('data', JSON.stringify(voucher));
|
||||||
return <Observable<Voucher>>this.http.put<Voucher>(`${url}/${endpoint}/${voucher.id}`, fd)
|
return <Observable<Voucher>>this.http.put<Voucher>(`${url}/${endpoint}/${voucher.id}`, fd)
|
||||||
.pipe(
|
.pipe(
|
||||||
catchError(this.log.handleError(serviceName, 'update'))
|
catchError(this.log.handleError(serviceName, 'Update Voucher'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user