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,
purchase,
purchase_return,
voucher,
)
from .routers.auth import client, user, role
from .routers.reports import (
@ -135,6 +136,7 @@ app.include_router(
)
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(voucher.router, prefix="/api", tags=["vouchers"])
app.include_router(
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):
i = i or []
t = t or []
for index, value in enumerate(i):
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):
i = i or []
t = t or []
old = [f.id_ for f in data if f.id_]
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]:

@ -178,7 +178,14 @@ def get_id(
):
try:
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
if item is None:
raise ValueError("Voucher not found")
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:
db.rollback()
raise HTTPException(

@ -53,8 +53,6 @@ def save_route(
user: UserToken = Security(get_user, scopes=["purchase-return"]),
):
try:
i = i or []
t = t or []
item: Voucher = save(data, user, db)
save_inventories(item, data.inventories, db)
save_journals(item, data.vendor, db)

@ -1,11 +1,20 @@
import traceback
import uuid
from typing import Optional
from datetime import datetime, date
import uuid
from decimal import Decimal
from fastapi import (
APIRouter,
HTTPException,
status,
Depends,
Security,
)
from sqlalchemy import func, or_
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from brewman.models.auth import User
from brewman.models.master import (
AccountBase,
CostCentre,
@ -14,7 +23,6 @@ from brewman.models.master import (
Account,
)
from brewman.models.voucher import (
Voucher,
VoucherType,
Inventory,
DbImage,
@ -22,97 +30,81 @@ from brewman.models.voucher import (
Journal,
)
from brewman.routers import get_lock_info
from ...core.session import get_first_day
from fastapi import APIRouter, Depends, Security, Request, HTTPException, status
from ...schemas.auth import UserToken
from brewman.core.session import get_first_day
from ..schemas import to_camel
from ..schemas.auth import UserToken
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionLocal
from ..models.voucher import Voucher
import brewman.schemas.voucher as output
router = APIRouter()
@router.post("/api/voucher/{id}") # , request_param="p" "Post Vouchers"
def voucher_post(request):
user = (
request.dbsession.query(User)
.filter(User.id == uuid.UUID(request.authenticated_userid))
.one()
)
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)
# Dependency
def get_db() -> Session:
try:
db = SessionLocal()
yield db
finally:
db.close()
def check_delete_permissions(request, voucher):
user = (
request.dbsession.query(User)
.filter(User.id == uuid.UUID(request.authenticated_userid))
.one()
)
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")
response.status_int = 403
return response
elif not request.has_permission(VoucherType.by_id(voucher.type).name):
response = Response(
f"You are not allowed ({VoucherType.by_id(voucher.type).name}) vouchers"
@router.post("/post-voucher/{id_}", response_model=output.Voucher)
def post_voucher(
id_: uuid.UUID,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["post-vouchers"]),
):
try:
voucher: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
check_voucher_lock_info(voucher.date, voucher.date, db)
voucher.posted = True
voucher.poster_id = user.id_
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
return response
start, finish = get_lock_info(request.dbsession)
if start is not None and start > voucher.date:
response = Response(
f"Vouchers before {start.strftime('%d-%b-%Y')} have been locked."
except Exception:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=traceback.format_exc(),
)
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 delete(request):
voucher = (
request.dbsession.query(Voucher)
.filter(Voucher.id == uuid.UUID(request.matchdict["id"]))
.first()
)
images = (
request.dbsession.query(DbImage).filter(DbImage.resource_id == voucher.id).all()
)
permission = check_delete_permissions(request, voucher)
if permission is not None:
return permission
json_voucher = voucher_info(voucher, request)
def check_delete_permissions(voucher: Voucher, user: UserToken):
voucher_type = VoucherType.by_id(voucher.type).name.replace(" ", "-").lower()
if voucher_type in ["payment", "purchase"]:
voucher_type = "journal"
if voucher.posted and "edit-posted-vouchers" not in user.permissions:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit posted vouchers",
)
elif voucher.user_id != user.id_ and "edit-other-user's-vouchers" not in user.permissions:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit other user's vouchers",
)
elif voucher_type not in user.permissions:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=f"You are not allowed ({VoucherType.by_id(voucher.type).name}) vouchers",
)
@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 = []
if voucher.type == VoucherType.by_name("Issue").id:
for item in voucher.journals:
@ -142,7 +134,7 @@ def delete(request):
elif voucher.type == VoucherType.by_name("Purchase").id:
for item in voucher.inventories:
uses = (
request.dbsession.query(func.count(Inventory.id))
db.query(func.count(Inventory.id))
.filter(Inventory.batch_id == item.batch.id)
.filter(Inventory.id != item.id)
.scalar()
@ -156,21 +148,12 @@ def delete(request):
for item in voucher.inventories:
item.batch.quantity_remaining += item.quantity
for b in batches_to_delete:
request.dbsession.delete(b)
request.dbsession.delete(voucher)
db.delete(b)
db.delete(voucher)
for image in images:
request.dbsession.delete(image)
transaction.commit()
return blank_voucher(info=json_voucher, dbsession=request.dbsession)
@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)
db.delete(image)
db.commit()
return blank_voucher(info=json_voucher, db=db)
def voucher_info(voucher, db):

@ -24,7 +24,7 @@ export class VoucherService {
const endpoint = type.replace(/ /g, '-').toLowerCase();
return <Observable<Voucher>>this.http.get<Voucher>(`${url}/${endpoint}/${id}`)
.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)
.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)};
return <Observable<Voucher>>this.http.get<Voucher>(`${url}/incentive`, options)
.pipe(
catchError(this.log.handleError(serviceName, 'list'))
catchError(this.log.handleError(serviceName, 'Get Incentive'))
);
}
post(id: string): Observable<Voucher> {
const options = {params: new HttpParams().set('p', '')};
return <Observable<Voucher>>this.http.post<Voucher>(`${url}/${id}`, {}, options)
return <Observable<Voucher>>this.http.post<Voucher>(`${url}/post-voucher/${id}`, {})
.pipe(
catchError(this.log.handleError(serviceName, 'list'))
catchError(this.log.handleError(serviceName, 'Post 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(
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));
return <Observable<Voucher>>this.http.post<Voucher>(`${url}/${endpoint}`, fd)
.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));
return <Observable<Voucher>>this.http.put<Voucher>(`${url}/${endpoint}/${voucher.id}`, fd)
.pipe(
catchError(this.log.handleError(serviceName, 'update'))
catchError(this.log.handleError(serviceName, 'Update Voucher'))
);
}