Fix: Batch Integrity

Fix: Cash Flow
Fix: Non Contract Purchase
Fix: Stock Movement
Fix: Trial Balance
This commit is contained in:
2025-07-16 07:14:09 +00:00
parent 846a7209ee
commit b1d5ff7df6
9 changed files with 40 additions and 42 deletions

View File

@ -52,10 +52,10 @@ def negative_batches(db: Session) -> list[schemas.BatchIntegrity]:
select(Batch, ProductVersion.name, inv_sum)
.join(Batch.sku)
.join(StockKeepingUnit.product)
.join(ProductVersion, onclause=product_version_onclause)
.join(Batch.inventories)
.join(Inventory.voucher)
.join(Voucher.journals)
.join(ProductVersion, onclause=product_version_onclause)
.where(
Journal.cost_centre_id == CostCentre.cost_centre_purchase(),
)
@ -121,9 +121,9 @@ def batch_dates(db: Session) -> list[schemas.BatchIntegrity]:
select(Batch)
.join(Batch.sku)
.join(StockKeepingUnit.product)
.join(ProductVersion, onclause=product_version_onclause)
.join(Batch.inventories)
.join(Inventory.voucher)
.join(ProductVersion, onclause=product_version_onclause)
.where(Voucher.date_ < Batch.name)
.options(
contains_eager(Batch.sku).contains_eager(StockKeepingUnit.product),

View File

@ -114,15 +114,15 @@ def build_report(
amount=round(amount * -1, 2),
)
)
cash_id_sq = select(func.distinct(AccountType.id)).where(AccountType.name == "Cash").subquery()
opening: Decimal = db.execute(
select(func.sum(Journal.amount * Journal.debit))
.join(Journal.voucher)
.join(Journal.account)
.where(
Voucher.date_ < start_date,
not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])),
AccountBase.type_id == select(AccountType.id).where(AccountType.name == "Cash"),
Voucher.voucher_type.not_in([VoucherType.ISSUE, VoucherType.CLOSING_STOCK]),
AccountBase.type_id == cash_id_sq,
)
).scalar() or Decimal(0)
@ -132,8 +132,8 @@ def build_report(
.join(Journal.account)
.where(
Voucher.date_ <= finish_date,
not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])),
AccountBase.type_id == select(AccountType.id).where(AccountType.name == "Cash"),
Voucher.voucher_type.not_in([VoucherType.ISSUE, VoucherType.CLOSING_STOCK]),
AccountBase.type_id == cash_id_sq,
)
).scalar() or Decimal(0)

View File

@ -1,6 +1,6 @@
from fastapi import APIRouter, Security
from sqlalchemy import and_, or_, select
from sqlalchemy.orm import Session, contains_eager, joinedload
from sqlalchemy.orm import Session, contains_eager
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionFuture
@ -36,9 +36,7 @@ def report(db: Session) -> list[schemas.NonContractPurchase]:
.join(RateContract.vendor)
.join(RateContract.items)
.options(
joinedload(RateContract.items, innerjoin=True),
contains_eager(RateContract.items),
joinedload(RateContract.vendor, innerjoin=True),
contains_eager(RateContract.vendor),
)
)

View File

@ -2,8 +2,8 @@ from datetime import date, datetime
from decimal import Decimal
from fastapi import APIRouter, Request, Security
from sqlalchemy import and_, not_, or_
from sqlalchemy.orm import Session, contains_eager
from sqlalchemy import and_, or_
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import func, select
from ...core.security import get_current_active_user as get_user
@ -89,12 +89,6 @@ def build_stock_movement(start_date: date, finish_date: date, db: Session) -> li
.join(StockKeepingUnit.product)
.join(ProductVersion, onclause=product_version_onclause)
.join(ProductVersion.product_group)
.options(
contains_eager(SkuVersion.sku)
.contains_eager(StockKeepingUnit.product)
.contains_eager(Product.versions)
.contains_eager(ProductVersion.product_group)
)
.where(Voucher.date_ < start_date, Journal.cost_centre_id == CostCentre.cost_centre_purchase())
.group_by(StockKeepingUnit, Product, ProductVersion, ProductGroup, SkuVersion) # type: ignore
).all()
@ -120,16 +114,10 @@ def build_stock_movement(start_date: date, finish_date: date, db: Session) -> li
.join(StockKeepingUnit.product)
.join(ProductVersion, onclause=product_version_onclause)
.join(ProductVersion.product_group)
.options(
contains_eager(SkuVersion.sku)
.contains_eager(StockKeepingUnit.product)
.contains_eager(Product.versions)
.contains_eager(ProductVersion.product_group)
)
.where(
Voucher.date_ >= start_date,
Voucher.date_ <= finish_date,
not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])),
Voucher.voucher_type.not_in([VoucherType.ISSUE, VoucherType.CLOSING_STOCK]),
Journal.cost_centre_id == CostCentre.cost_centre_purchase(),
)
.group_by(StockKeepingUnit, Product, ProductVersion, ProductGroup, SkuVersion) # type: ignore
@ -159,12 +147,6 @@ def build_stock_movement(start_date: date, finish_date: date, db: Session) -> li
.join(StockKeepingUnit.product)
.join(ProductVersion, onclause=product_version_onclause)
.join(ProductVersion.product_group)
.options(
contains_eager(SkuVersion.sku)
.contains_eager(StockKeepingUnit.product)
.contains_eager(Product.versions)
.contains_eager(ProductVersion.product_group)
)
.where(
Voucher.date_ >= start_date,
Voucher.date_ <= finish_date,

View File

@ -1,8 +1,7 @@
from datetime import date, datetime
from fastapi import APIRouter, Request, Security
from sqlalchemy import not_
from sqlalchemy.orm import Session, contains_eager, joinedload
from sqlalchemy.orm import Session, contains_eager
from sqlalchemy.sql.expression import func, select
from ...core.security import get_current_active_user as get_user
@ -51,12 +50,11 @@ def build_report(date_: date, db: Session) -> list[schemas.TrialBalanceItem]:
.join(AccountBase.type_)
.where(
Voucher.date_ <= date_,
not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])),
Voucher.voucher_type.not_in([VoucherType.ISSUE, VoucherType.CLOSING_STOCK]),
)
.group_by(AccountBase, AccountType) # type: ignore
.order_by(AccountBase.type_id, func.abs(amount_sum).desc())
.options(
joinedload(AccountBase.type_, innerjoin=True),
contains_eager(AccountBase.type_),
)
).all()

View File

@ -1,3 +1,3 @@
.basic-container {
padding: 30px;
}
// .basic-container {
// padding: 30px;
// }

View File

@ -1,5 +1,5 @@
import { LayoutModule } from '@angular/cdk/layout';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { provideHttpClient, withInterceptors, withFetch } from '@angular/common/http';
import { ApplicationConfig, importProvidersFrom, LOCALE_ID, provideZonelessChangeDetection } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
@ -51,7 +51,7 @@ export const appConfig: ApplicationConfig = {
),
{ provide: LOCALE_ID, useValue: 'en-IN' },
AuthService,
provideHttpClient(withInterceptors([refreshInterceptor, jwtInterceptor, authInterceptor])),
provideHttpClient(withFetch(), withInterceptors([refreshInterceptor, jwtInterceptor, authInterceptor])),
provideAnimations(),
provideRouter(
routes,

View File

@ -1,6 +1,15 @@
import { SelectionModel } from '@angular/cdk/collections';
import { AsyncPipe, CurrencyPipe } from '@angular/common';
import { AfterViewInit, Component, ElementRef, HostListener, inject, OnInit, ViewChild } from '@angular/core';
import {
AfterViewInit,
Component,
ElementRef,
HostListener,
inject,
OnInit,
ViewChild,
ChangeDetectorRef,
} from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
import { MatButtonModule } from '@angular/material/button';
@ -66,6 +75,7 @@ export class LedgerComponent implements OnInit, AfterViewInit {
private toCsv = inject(ToCsvService);
private accountSer = inject(AccountService);
private tagSer = inject(TagService);
private cd = inject(ChangeDetectorRef);
@ViewChild('accountElement', { static: true }) accountElement!: ElementRef<HTMLInputElement>;
@ViewChild('startDateElement', { static: true }) startDate!: ElementRef<HTMLInputElement>;
@ -139,6 +149,7 @@ export class LedgerComponent implements OnInit, AfterViewInit {
this.dataSource.sort = this.sort;
}
this.selection.clear();
this.cd.detectChanges();
});
}

View File

@ -1,5 +1,6 @@
import { CurrencyPipe } from '@angular/common';
import { Component, inject, OnInit, ViewChild } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
import { MatSort, MatSortModule } from '@angular/material/sort';
@ -13,7 +14,15 @@ import { RateContractListDatasource } from './rate-contract-list-datasource';
selector: 'app-rate-contract-list',
templateUrl: './rate-contract-list.component.html',
styleUrls: ['./rate-contract-list.component.css'],
imports: [RouterModule, MatIconModule, MatTableModule, MatSortModule, MatPaginatorModule, CurrencyPipe],
imports: [
RouterModule,
MatIconModule,
MatTableModule,
MatSortModule,
MatPaginatorModule,
CurrencyPipe,
MatButtonModule,
],
})
export class RateContractListComponent implements OnInit {
private route = inject(ActivatedRoute);