Account done

This commit is contained in:
tanshu 2020-05-08 16:18:50 +05:30
parent 2466efb208
commit 6765f0a93e
4 changed files with 129 additions and 92 deletions

@ -1,17 +1,19 @@
import traceback
import uuid
from typing import List
from datetime import datetime
from fastapi import APIRouter, Depends, Security
from pydantic import ValidationError
from fastapi import APIRouter, HTTPException, status, Depends, Security
from sqlalchemy import func
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import joinedload_all, Session
from ..core.security import User, get_current_active_user as get_user
from ..db.session import SessionLocal
from ..models.master import CostCentre, Account, AccountType, AccountBase
from ..models.validation_exception import ValidationError
from ..models.voucher import Voucher, Journal, VoucherType
from ..schemas.master import Account as AccountSchema
import brewman.schemas.master as schemas
router = APIRouter()
@ -24,11 +26,14 @@ def get_db():
db.close()
@router.post("/")
def save(data: AccountSchema, db: Session = Depends(get_db), user: User = Security(get_user, scopes=["accounts"])):
@router.post("/", response_model=schemas.Account)
def save(
data: schemas.AccountSaveUpdate,
db: Session = Depends(get_db),
user: User = Security(get_user, scopes=["accounts"]),
):
try:
item = Account(
code=0,
name=data.name,
type=data.type,
is_starred=data.is_starred,
@ -38,56 +43,85 @@ def save(data: AccountSchema, db: Session = Depends(get_db), user: User = Securi
).create(db)
db.commit()
return account_info(item.id, db)
except:
except SQLAlchemyError as e:
db.rollback()
finally:
db.close()
@router.put("/{id_}")
def update(id_: uuid.UUID, db: Session = Depends(get_db), user: User = Security(get_user, scopes=["accounts"])):
item = (
db.query(Account)
.filter(Account.id == id_)
.first()
)
if item.is_fixture:
raise ValidationError(
"{0} is a fixture and cannot be edited or deleted.".format(item.name)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
)
except Exception:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=traceback.format_exc(),
)
new_type = int(request.json_body["type"])
if not item.type == new_type:
item.code = Account.get_code(new_type, request.dbsession)
item.type = new_type
item.name = request.json_body["name"]
item.is_active = request.json_body["isActive"]
item.is_reconcilable = request.json_body["isReconcilable"]
item.is_starred = request.json_body["isStarred"]
item.cost_centre_id = uuid.UUID(request.json_body["costCentre"]["id"])
transaction.commit()
return account_info(item.id, request.dbsession)
@router.delete("/{id}") # "Accounts"
def delete(id_: uuid.UUID, db: Session = Depends(get_db), user: User = Security(get_user, scopes=["accounts"])):
account = (
db.query(Account)
.filter(Account.id == id_)
.first()
)
can_delete, reason = account.can_delete(request.has_permission("Advanced Delete"))
@router.put("/{id_}", response_model=schemas.Account)
def update(
id_: uuid.UUID,
data: schemas.AccountSaveUpdate,
db: Session = Depends(get_db),
user: User = Security(get_user, scopes=["accounts"]),
):
try:
item: Account = db.query(Account).filter(Account.id == id_).first()
if item.is_fixture:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"{item.name} is a fixture and cannot be edited or deleted.",
)
if not item.type == data.type:
item.code = Account.get_code(data.type, db)
item.type = data.type
item.name = data.name
item.is_active = data.is_active
item.is_reconcilable = data.is_reconcilable
item.is_starred = data.is_starred
item.cost_centre_id = data.cost_centre.id_
db.commit()
return account_info(item.id, db)
except SQLAlchemyError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e),
)
except Exception:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=traceback.format_exc(),
)
@router.delete("/{id}")
def delete(
id_: uuid.UUID,
db: Session = Depends(get_db),
user: User = Security(get_user, scopes=["accounts"]),
):
account: Account = db.query(Account).filter(Account.id == id_).first()
can_delete, reason = account.can_delete("Advanced Delete" in user.permissions)
if can_delete:
delete_with_data(account, db)
transaction.commit()
db.commit()
return account_info(None, db)
else:
transaction.abort()
response = Response("Cannot delete account because {0}".format(reason))
response.status_int = 500
return response
db.abort()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Cannot delete account because {reason}",
)
@router.get("/list") # "Authenticated"
@router.get("/")
def show_blank(
db: Session = Depends(get_db), user: User = Security(get_user, scopes=["accounts"])
):
return account_info(None, db)
@router.get("/list")
async def show_list(db: Session = Depends(get_db), user: User = Depends(get_user)):
list_ = (
db.query(Account)
@ -113,9 +147,16 @@ async def show_list(db: Session = Depends(get_db), user: User = Depends(get_user
return accounts
@router.get("/query") # "Authenticated"
async def show_term(q: str, t: int = None, r: bool = None, a: bool = None, c: int = None,
db: Session = Depends(get_db), current_user: User = Depends(get_user)):
@router.get("/query")
async def show_term(
q: str,
t: int = None,
r: bool = None,
a: bool = None,
c: int = None,
db: Session = Depends(get_db),
current_user: User = Depends(get_user),
):
count = c
list_ = []
@ -126,29 +167,32 @@ async def show_term(q: str, t: int = None, r: bool = None, a: bool = None, c: in
return {"user": current_user.name, "list": list_}
@router.get("/{id_}/balance") # "Authenticated"
async def show_balance(id_: uuid.UUID, d: str = None, db: Session = Depends(get_db), user: User = Depends(get_user)):
date = (
None
if d is None or d == ""
else datetime.datetime.strptime(d, "%d-%b-%Y")
)
@router.get("/{id_}/balance")
async def show_balance(
id_: uuid.UUID,
d: str = None,
db: Session = Depends(get_db),
user: User = Depends(get_user),
):
date = None if d is None or d == "" else datetime.datetime.strptime(d, "%d-%b-%Y")
return {"date": balance(id_, date, db), "total": balance(id_, None, db)}
@router.get("/{id_}") # "Accounts"
def show_id(id_: uuid.UUID, db: Session = Depends(get_db), user: User = Security(get_user, scopes=["accounts"])):
@router.get("/{id_}")
def show_id(
id_: uuid.UUID,
db: Session = Depends(get_db),
user: User = Security(get_user, scopes=["accounts"]),
):
return account_info(id_, db)
def balance(id_: uuid.UUID, date, dbsession: Session):
account = dbsession.query(AccountBase).filter(AccountBase.id == id_).first()
def balance(id_: uuid.UUID, date, db: Session):
account = db.query(AccountBase).filter(AccountBase.id == id_).first()
if not account.type_object.balance_sheet:
return 0
bal = dbsession.query(func.sum(Journal.amount * Journal.debit)).join(
Journal.voucher
)
bal = db.query(func.sum(Journal.amount * Journal.debit)).join(Journal.voucher)
if date is not None:
bal = bal.filter(Voucher.date <= date)
@ -160,11 +204,6 @@ def balance(id_: uuid.UUID, date, dbsession: Session):
return 0 if bal is None else bal
@router.get("/") # "Accounts"
def show_blank(db: Session = Depends(get_db), user: User = Security(get_user, scopes=["accounts"])):
return account_info(None, db)
def account_info(id_, db):
if id_ is None:
account = {
@ -198,7 +237,7 @@ def delete_with_data(account, db):
suspense_account = (
db.query(Account).filter(Account.id == Account.suspense()).first()
)
query = (
query: List[Voucher] = (
db.query(Voucher)
.options(joinedload_all(Voucher.journals, Journal.account, innerjoin=True))
.filter(Voucher.journals.any(Journal.account_id == account.id))
@ -219,8 +258,8 @@ def delete_with_data(account, db):
else:
if sus_jnl is None:
acc_jnl.account = suspense_account
voucher.narration += "\nSuspense \u20B9{0:,.2f} is {1}".format(
acc_jnl.amount, account.name
voucher.narration += (
f"\nSuspense \u20B9{acc_jnl.amount:,.2f} is {account.name}"
)
else:
amount = (sus_jnl.debit * sus_jnl.amount) + (
@ -232,9 +271,7 @@ def delete_with_data(account, db):
else:
sus_jnl.amount = abs(amount)
sus_jnl.debit = -1 if amount < 0 else 1
voucher.narration += "\nDeleted \u20B9{0:,.2f} of {1}".format(
acc_jnl.amount * acc_jnl.debit, account.name
)
voucher.narration += f"\nDeleted \u20B9{acc_jnl.amount * acc_jnl.debit:,.2f} of {account.name}"
if voucher.type in (
VoucherType.by_name("Payment").id,
VoucherType.by_name("Receipt").id,

@ -1,12 +1,14 @@
from fastapi import APIRouter, Depends
from ..core.security import User, get_current_active_user as get_user
from brewman.models.master import AccountType
from fastapi import APIRouter
router = APIRouter()
@router.get("/") # "Authenticated"
def account_type_list(request):
account_types = []
for item in AccountType.list():
account_types.append({"id": item.id, "name": item.name})
return account_types
@router.get("/")
def account_type_list(user: User = Depends(get_user)):
return [
{"id": item.id, "name": item.name}
for item in AccountType.list()
]

@ -1,19 +1,14 @@
import traceback
import uuid
from typing import List, Optional
from sqlalchemy.exc import SQLAlchemyError
import brewman.schemas.master as schemas
from fastapi import APIRouter, HTTPException, status, Depends, Security
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
import brewman.schemas.master as schemas
from ..core.security import User, get_current_active_user as get_user
from ..db.session import SessionLocal
from ..models.master import CostCentre
router = APIRouter()

@ -62,15 +62,18 @@ class CostCentre(CostCentreSaveUpdate):
is_fixture: bool = Field(alias="isFixture")
class Account(BaseModel):
id_: uuid.UUID
code: int
class AccountSaveUpdate(BaseModel):
name: str
type: int
is_starred: bool
is_active: bool
is_reconcilable: bool
cost_centre: CostCentre
class Account(AccountSaveUpdate):
id_: uuid.UUID = Field(alias="id")
code: int
is_fixture: bool