diff --git a/brewman/models/voucher.py b/brewman/models/voucher.py index 25bc881c..0666ed7f 100644 --- a/brewman/models/voucher.py +++ b/brewman/models/voucher.py @@ -80,8 +80,18 @@ class Voucher(Base): "User", primaryjoin="User.id==Voucher.poster_id", cascade=None ) - journals = relationship("Journal", back_populates="voucher", cascade="delete, delete-orphan", cascade_backrefs=False,) - inventories = relationship("Inventory",back_populates="voucher",cascade="delete, delete-orphan",cascade_backrefs=False,) + journals = relationship( + "Journal", + back_populates="voucher", + cascade="delete, delete-orphan", + cascade_backrefs=False, + ) + inventories = relationship( + "Inventory", + back_populates="voucher", + cascade="delete, delete-orphan", + cascade_backrefs=False, + ) salary_deductions = relationship( "SalaryDeduction", backref="voucher", @@ -153,9 +163,13 @@ class Journal(Base): id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) debit = Column("debit", Integer) amount = Column("amount", Numeric) - voucher_id = Column("voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False, index=True) + voucher_id = Column( + "voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False, index=True + ) account_id = Column("account_id", GUID(), ForeignKey("accounts.id"), nullable=False) - cost_centre_id = Column("cost_centre_id", GUID(), ForeignKey("cost_centres.id"), nullable=False) + cost_centre_id = Column( + "cost_centre_id", GUID(), ForeignKey("cost_centres.id"), nullable=False + ) voucher = relationship("Voucher", back_populates="journals") account = relationship("AccountBase", back_populates="journals") @@ -233,12 +247,8 @@ class SalaryDeduction(Base): class Incentive(Base): __tablename__ = "incentives" id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) - voucher_id = Column( - "voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False - ) - journal_id = Column( - "journal_id", GUID(), ForeignKey("journals.id"), nullable=False - ) + voucher_id = Column("voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False) + journal_id = Column("journal_id", GUID(), ForeignKey("journals.id"), nullable=False) days_worked = Column("days_worked", Integer, nullable=False) points = Column("points", Numeric(precision=5, scale=2), nullable=False) @@ -271,7 +281,9 @@ class Inventory(Base): __tablename__ = "inventories" __table_args__ = (UniqueConstraint("voucher_id", "batch_id"),) id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) - voucher_id = Column("voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False, index=True) + voucher_id = Column( + "voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False, index=True + ) product_id = Column("product_id", GUID(), ForeignKey("products.id"), nullable=False) batch_id = Column("batch_id", GUID(), ForeignKey("batches.id"), nullable=False) quantity = Column("quantity", Numeric) diff --git a/brewman/routers/reports/purchase_entries.py b/brewman/routers/reports/purchase_entries.py index 46742363..d16c7735 100644 --- a/brewman/routers/reports/purchase_entries.py +++ b/brewman/routers/reports/purchase_entries.py @@ -1,5 +1,5 @@ -import datetime - +from datetime import datetime, date +from typing import List from fastapi import APIRouter, Depends, Security, Request from sqlalchemy.orm import Session @@ -7,6 +7,7 @@ from ...schemas.auth import UserToken from ...core.security import get_current_active_user as get_user from ...db.session import SessionLocal from brewman.models.voucher import Voucher, VoucherType +import brewman.schemas.reports as schemas from ...core.session import ( set_period, get_start_date, @@ -25,10 +26,9 @@ def get_db() -> Session: db.close() -@router.get("") +@router.get("", response_model=schemas.PurchaseEntries) def report_blank( - request: Request, - user: UserToken = Security(get_user, scopes=["purchase-entries"]), + request: Request, user: UserToken = Security(get_user, scopes=["purchase-entries"]), ): return { "startDate": get_start_date(request.session), @@ -37,24 +37,24 @@ def report_blank( } -@router.get("/{start}/{finish}") +@router.get("/{start}/{finish}", response_model=schemas.PurchaseEntries) def report_data( start: str, finish: str, request: Request, db: Session = Depends(get_db), - user: UserToken = Security(get_user, scopes=["net-transactions"]), + user: UserToken = Security(get_user, scopes=["purchase-entries"]), ): - body = build_report(start, finish, db) + start_date = datetime.strptime(start, "%d-%b-%Y") + finish_date = datetime.strptime(finish, "%d-%b-%Y") + body = build_report(start_date, finish_date, db) set_period(start, finish, request.session) return {"startDate": start, "finishDate": finish, "body": body} -def build_report(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") +def build_report(start_date: date, finish_date, db): body = [] - query = ( + query: List[Voucher] = ( db.query(Voucher) .filter(Voucher.date >= start_date) .filter(Voucher.date <= finish_date) @@ -70,11 +70,16 @@ def build_report(start_date, finish_date, db): row = { "date": voucher.date.strftime("%d-%b-%Y"), "supplier": journal.account.name, - "products": [], + "url": [ + "/", + VoucherType.by_id(voucher.type).name.replace(" ", "-").lower(), + str(voucher.id), + ], "product": item.product.full_name, "quantity": item.quantity, "rate": item.rate, "tax": item.tax, + "discount": item.discount, "amount": item.amount, } body.append(row) diff --git a/brewman/schemas/reports.py b/brewman/schemas/reports.py index 720fc91c..2d4dff22 100644 --- a/brewman/schemas/reports.py +++ b/brewman/schemas/reports.py @@ -371,3 +371,53 @@ class ProfitLoss(BaseModel): value, "%d-%b-%Y" ).date() + + +class PurchaseEntriesItem(BaseModel): + date_: date + url: List[str] + supplier: str + product: str + quantity: Decimal + rate: Decimal + tax: Decimal + discount: Decimal + amount: Decimal + + @validator("date_", pre=True) + def parse_date(cls, value): + return datetime.strptime( + value, + "%d-%b-%Y" + ).date() + + class Config: + anystr_strip_whitespace = True + alias_generator = to_camel + + +class PurchaseEntries(BaseModel): + start_date: date + finish_date: date + body: List[PurchaseEntriesItem] + + class Config: + anystr_strip_whitespace = True + alias_generator = to_camel + json_encoders = { + date: lambda v: v.strftime("%d-%b-%Y") + } + + @validator("start_date", pre=True) + def parse_start_date(cls, value): + return datetime.strptime( + value, + "%d-%b-%Y" + ).date() + + @validator("finish_date", pre=True) + def parse_finish_date(cls, value): + return datetime.strptime( + value, + "%d-%b-%Y" + ).date() diff --git a/overlord/src/app/purchase-entries/purchase-entries.component.html b/overlord/src/app/purchase-entries/purchase-entries.component.html index f41dfca1..1f23c5de 100644 --- a/overlord/src/app/purchase-entries/purchase-entries.component.html +++ b/overlord/src/app/purchase-entries/purchase-entries.component.html @@ -32,7 +32,7 @@ Supplier - {{row.supplier}} + {{row.supplier}} diff --git a/overlord/src/app/purchase-entries/purchase-entries.component.ts b/overlord/src/app/purchase-entries/purchase-entries.component.ts index 049d5d45..78cc2b18 100644 --- a/overlord/src/app/purchase-entries/purchase-entries.component.ts +++ b/overlord/src/app/purchase-entries/purchase-entries.component.ts @@ -32,12 +32,7 @@ export class PurchaseEntriesComponent implements OnInit { } ngOnInit() { - this.route.data.pipe(map( - (data: { info: PurchaseEntries }) => { - data.info.body = data.info.body.map(x => ({...x, url: x['type'].replace(/ /g, '-').toLowerCase()})); - return data; - } - )).subscribe((data: { info: PurchaseEntries }) => { + this.route.data.subscribe((data: { info: PurchaseEntries }) => { this.info = data.info; this.form.setValue({ startDate: moment(this.info.startDate, 'DD-MMM-YYYY').toDate(), diff --git a/overlord/src/app/purchase-entries/purchase-entries.ts b/overlord/src/app/purchase-entries/purchase-entries.ts index 6eb2fce3..ed623a8d 100644 --- a/overlord/src/app/purchase-entries/purchase-entries.ts +++ b/overlord/src/app/purchase-entries/purchase-entries.ts @@ -1,7 +1,9 @@ export class PurchaseEntriesItem { + id: string; date: string; supplier: string; + url: string[]; product: string; quantity: number; rate: number;