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:
Amritanshu Agrawal 2020-05-30 12:06:37 +05:30
parent 0177921e84
commit 8ae67863eb
6 changed files with 104 additions and 111 deletions

@ -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'))
); );
} }