From 005d45032fe76b740932eb6abeb966e95a681fe8 Mon Sep 17 00:00:00 2001 From: tanshu Date: Sun, 20 Sep 2020 09:56:35 +0530 Subject: [PATCH] Fix: Reset stock was not working because: 1. The frontend did not set the date format and that mangled the date string sent 2. Backend was broken and was not acceping data in json format Fix: Ledger would occasionally crap out due to rounding and floating point madness, removed the rounding limitation --- brewman/routers/reset_stock.py | 17 +++------ brewman/schemas/reports.py | 4 +-- brewman/schemas/settings.py | 28 +++++++++++++-- overlord/src/app/auth/auth.service.ts | 4 --- overlord/src/app/ledger/ledger.module.ts | 20 +++++------ overlord/src/app/settings/settings.module.ts | 37 ++++++++++++++------ 6 files changed, 70 insertions(+), 40 deletions(-) diff --git a/brewman/routers/reset_stock.py b/brewman/routers/reset_stock.py index c56be587..2beabeb2 100644 --- a/brewman/routers/reset_stock.py +++ b/brewman/routers/reset_stock.py @@ -1,6 +1,4 @@ import uuid -from datetime import datetime -from decimal import Decimal from fastapi import ( APIRouter, @@ -15,6 +13,7 @@ from ..models.master import Product, CostCentre, AccountBase from ..schemas.auth import UserToken from ..core.security import get_current_active_user as get_user from ..db.session import SessionLocal +from ..schemas.settings import ResetStock router = APIRouter() @@ -31,22 +30,16 @@ def get_db() -> Session: @router.post("/{id_}") def rebase( id_: uuid.UUID, - quantity: Decimal, - stockDate: str, - resetDate: str, + item: ResetStock, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["reset-stock"]), ): product: Product = db.query(Product).filter(Product.id == id_).first() - quantity = round(quantity, 2) - stock_date = datetime.strptime(stockDate, "%d-%b-%Y").date() - reset_date = datetime.strptime(resetDate, "%d-%b-%Y").date() - - if reset_date > stock_date: + if item.reset_date > item.stock_date: raise ValueError("Reset cannot be after the stock date") - change = quantity - get_closing_stock(product, stock_date, db=db) + change = round(item.quantity, 2) - get_closing_stock(product, item.stock_date, db=db) if change == 0: return {"No Change Needed"} final = get_closing_stock(product, db=db) @@ -56,7 +49,7 @@ def rebase( batch = get_last_batch(product, db) set_batches(batch, final + change, db) - create_voucher(batch, change, reset_date, user.id_, db) + create_voucher(batch, change, item.reset_date, user.id_, db) db.commit() return {} diff --git a/brewman/schemas/reports.py b/brewman/schemas/reports.py index cb02faa0..6536f9ef 100644 --- a/brewman/schemas/reports.py +++ b/brewman/schemas/reports.py @@ -15,8 +15,8 @@ class LedgerItem(BaseModel): url: List[str] type_: str narration: str - debit: Decimal = Field(multiple_of=0.01) - credit: Decimal = Field(multiple_of=0.01) + debit: Decimal + credit: Decimal posted: bool @validator("date_", pre=True) diff --git a/brewman/schemas/settings.py b/brewman/schemas/settings.py index 515b2450..7351a92b 100644 --- a/brewman/schemas/settings.py +++ b/brewman/schemas/settings.py @@ -1,5 +1,5 @@ -import uuid -from typing import List, Optional +from decimal import Decimal +from typing import Optional from datetime import datetime, date from pydantic import BaseModel, validator @@ -38,3 +38,27 @@ class LockInformation(BaseModel): class Maintenance(BaseModel): enabled: bool user: Optional[str] + + +class ResetStock(BaseModel): + quantity: Decimal + stock_date: date + reset_date: date + + class Config: + alias_generator = to_camel + json_encoders = { + date: lambda v: v.strftime("%d-%b-%Y"), + } + + @validator("stock_date", pre=True) + def parse_stock_date(cls, value): + if isinstance(value, date): + return value + return datetime.strptime(value, "%d-%b-%Y").date() + + @validator("reset_date", pre=True) + def parse_reset_date(cls, value): + if isinstance(value, date): + return value + return datetime.strptime(value, "%d-%b-%Y").date() diff --git a/overlord/src/app/auth/auth.service.ts b/overlord/src/app/auth/auth.service.ts index 50b02777..2f06431c 100644 --- a/overlord/src/app/auth/auth.service.ts +++ b/overlord/src/app/auth/auth.service.ts @@ -90,10 +90,6 @@ export class AuthService { return Date.now() > (this.user.exp - (environment.ACCESS_TOKEN_REFRESH_MINUTES * 60)) * 1000; } - expired(): boolean { - return Date.now() > this.user.exp * 1000; - } - logout() { // remove user from local storage to log user out localStorage.removeItem(JWT_USER); diff --git a/overlord/src/app/ledger/ledger.module.ts b/overlord/src/app/ledger/ledger.module.ts index 5be263d0..bbfcb7df 100644 --- a/overlord/src/app/ledger/ledger.module.ts +++ b/overlord/src/app/ledger/ledger.module.ts @@ -1,5 +1,5 @@ -import {NgModule} from '@angular/core'; -import {CommonModule} from '@angular/common'; +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; @@ -13,14 +13,14 @@ import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSortModule } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; -import {SharedModule} from '../shared/shared.module'; -import {ReactiveFormsModule} from '@angular/forms'; -import {CdkTableModule} from '@angular/cdk/table'; -import {LedgerRoutingModule} from './ledger-routing.module'; -import {LedgerComponent} from './ledger.component'; -import {MomentDateAdapter} from '@angular/material-moment-adapter'; -import {A11yModule} from '@angular/cdk/a11y'; -import {FlexLayoutModule} from '@angular/flex-layout'; +import { SharedModule } from '../shared/shared.module'; +import { ReactiveFormsModule } from '@angular/forms'; +import { CdkTableModule } from '@angular/cdk/table'; +import { LedgerRoutingModule } from './ledger-routing.module'; +import { LedgerComponent } from './ledger.component'; +import { MomentDateAdapter } from '@angular/material-moment-adapter'; +import { A11yModule } from '@angular/cdk/a11y'; +import { FlexLayoutModule } from '@angular/flex-layout'; export const MY_FORMATS = { parse: { diff --git a/overlord/src/app/settings/settings.module.ts b/overlord/src/app/settings/settings.module.ts index f13e2be7..eb5c6009 100644 --- a/overlord/src/app/settings/settings.module.ts +++ b/overlord/src/app/settings/settings.module.ts @@ -1,10 +1,10 @@ -import {NgModule} from '@angular/core'; -import {CommonModule} from '@angular/common'; +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatNativeDateModule } from '@angular/material/core'; +import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatNativeDateModule} from '@angular/material/core'; import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatDialogModule } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -16,13 +16,26 @@ import { MatSelectModule } from '@angular/material/select'; import { MatSortModule } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; import { MatTabsModule } from '@angular/material/tabs'; -import {ReactiveFormsModule} from '@angular/forms'; -import {CdkTableModule} from '@angular/cdk/table'; -import {A11yModule} from '@angular/cdk/a11y'; -import {FlexLayoutModule} from '@angular/flex-layout'; -import {SharedModule} from '../shared/shared.module'; -import {SettingsComponent} from './settings.component'; -import {SettingsRoutingModule} from './settings-routing.module'; +import { ReactiveFormsModule } from '@angular/forms'; +import { CdkTableModule } from '@angular/cdk/table'; +import { A11yModule } from '@angular/cdk/a11y'; +import { FlexLayoutModule } from '@angular/flex-layout'; +import { SharedModule } from '../shared/shared.module'; +import { SettingsComponent } from './settings.component'; +import { SettingsRoutingModule } from './settings-routing.module'; +import {MomentDateAdapter} from "@angular/material-moment-adapter"; + +export const MY_FORMATS = { + parse: { + dateInput: 'DD-MMM-YYYY', + }, + display: { + dateInput: 'DD-MMM-YYYY', + monthYearLabel: 'MMM YYYY', + dateA11yLabel: 'DD-MMM-YYYY', + monthYearA11yLabel: 'MMM YYYY', + }, +}; @NgModule({ imports: [ @@ -52,6 +65,10 @@ import {SettingsRoutingModule} from './settings-routing.module'; ], declarations: [ SettingsComponent + ], + providers: [ + {provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]}, + {provide: MAT_DATE_FORMATS, useValue: MY_FORMATS}, ] }) export class SettingsModule {