Compare commits

...
9 Commits
Author SHA1 Message Date
tanshu 407967514f Version Bump v15.2.1 2026-08-26 19:05:18 +05:30
tanshu be40004a3d Ledger now showing running totals. 2026-08-26 13:35:01 +00:00
tanshu 1fa16912d1 Version Bump v15.2.0 2026-08-26 12:00:32 +05:30
tanshu c891937d2b Version Bump v15.1.4 2026-08-26 11:59:15 +05:30
tanshu 386a6c4964 Version Bump v15.1.3 2026-08-26 11:51:55 +05:30
tanshu b5d57fccf3 Still fixing the error 2026-08-26 06:21:50 +00:00
tanshu f42e4d3628 Version Bump v15.1.2 2026-08-26 11:48:24 +05:30
tanshu c534aaffa3 version bump would make the lock file out of date. 2026-08-26 06:18:09 +00:00
tanshu 141f82f832 Version Bump v15.1.1 2026-08-26 06:14:01 +00:00
63 changed files with 105 additions and 154 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ build-production: ## Build the production docker image.
--tag registry.tanshu.com/brewman:latest \ --tag registry.tanshu.com/brewman:latest \
$(if $(TAG),--tag registry.tanshu.com/brewman:$(TAG)) \ $(if $(TAG),--tag registry.tanshu.com/brewman:$(TAG)) \
--push \ --push \
git@git.tanshu.com:tanshu/brewman.git git@git.tanshu.com:tanshu/brewman.git$(if $(TAG),#v$(TAG))
.PHONY: build-check .PHONY: build-check
build-check: ## Multi-arch build without push (compile check) build-check: ## Multi-arch build without push (compile check)
@@ -6,9 +6,11 @@ Create Date: 2026-08-26 05:54:36.396717
""" """
from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = "ee77296e69b7" revision = "ee77296e69b7"
down_revision = "09a4f0ca450f" down_revision = "09a4f0ca450f"
+1 -1
View File
@@ -1 +1 @@
__version__ = "15.1.0" __version__ = "15.2.1"
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "brewman" name = "brewman"
version = "15.1.0" version = "15.2.1"
description = "Accounting plus inventory management for a restaurant." description = "Accounting plus inventory management for a restaurant."
requires-python = ">=3.14" requires-python = ">=3.14"
authors = [{ name = "tanshu", email = "git@tanshu.com" }] authors = [{ name = "tanshu", email = "git@tanshu.com" }]
+1 -1
View File
@@ -211,7 +211,7 @@ wheels = [
[[package]] [[package]]
name = "brewman" name = "brewman"
version = "15.0.0" version = "15.2.1"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "alembic" }, { name = "alembic" },
+11 -4
View File
@@ -32,7 +32,9 @@
"input": "public" "input": "public"
} }
], ],
"styles": ["src/styles.sass"] "styles": [
"src/styles.sass"
]
}, },
"configurations": { "configurations": {
"production": { "production": {
@@ -79,14 +81,19 @@
"lint": { "lint": {
"builder": "@angular-eslint/builder:lint", "builder": "@angular-eslint/builder:lint",
"options": { "options": {
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"] "lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
} }
} }
} }
} }
}, },
"cli": { "cli": {
"schematicCollections": ["@angular-eslint/schematics"], "schematicCollections": [
"@angular-eslint/schematics"
],
"analytics": false "analytics": false
}, },
"schematics": { "schematics": {
@@ -115,4 +122,4 @@
"typeSeparator": "." "typeSeparator": "."
} }
} }
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "overlord", "name": "overlord",
"version": "15.1.0", "version": "15.2.1",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve", "start": "ng serve",
@@ -42,7 +42,6 @@ export interface AccountDetailFormData {
MatButtonModule, MatButtonModule,
FormField, FormField,
FormRoot, FormRoot,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -44,7 +44,6 @@ export interface AccountListFormData {
MatTableModule, MatTableModule,
MatSortModule, MatSortModule,
MatPaginatorModule, MatPaginatorModule,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
+1 -1
View File
@@ -1,6 +1,6 @@
export const environment = { export const environment = {
ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry
version: '15.1.0', version: '15.2.1',
title: 'HnG / TGB', title: 'HnG / TGB',
}; };
@@ -45,7 +45,6 @@ export interface AttendanceFormData {
MatOptionModule, MatOptionModule,
MatIconModule, MatIconModule,
MatChipsModule, MatChipsModule,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -39,7 +39,6 @@ import { BalanceSheetService } from './balance-sheet.service';
MatPaginatorModule, MatPaginatorModule,
CurrencyPipe, CurrencyPipe,
ClearPipe, ClearPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -37,17 +37,13 @@ export interface ClientFormData {
], ],
}) })
export class ClientDetailComponent { export class ClientDetailComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
private ser = inject(ClientService); private ser = inject(ClientService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
itemResource = this.ser.get(this.id); itemResource = this.ser.get(this.id);
item = computed(() => this.itemResource.value() ?? new Client()); item = computed(() => this.itemResource.value() ?? new Client());
model = linkedSignal({ model = linkedSignal({
source: this.item, source: this.item,
computation: (item): ClientFormData => ({ computation: (item): ClientFormData => ({
@@ -56,7 +56,6 @@ export interface ClosingStockFormData {
MatPaginatorModule, MatPaginatorModule,
DecimalPipe, DecimalPipe,
CurrencyPipe, CurrencyPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -30,16 +30,12 @@ export interface CostCentreDetailFormData {
], ],
}) })
export class CostCentreDetailComponent { export class CostCentreDetailComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
private ser = inject(CostCentreService); private ser = inject(CostCentreService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
itemResource = this.ser.get(this.id); itemResource = this.ser.get(this.id);
item = computed(() => this.itemResource.value() ?? new CostCentre()); item = computed(() => this.itemResource.value() ?? new CostCentre());
model = linkedSignal({ model = linkedSignal({
source: this.item, source: this.item,
computation: (itemVal): CostCentreDetailFormData => ({ computation: (itemVal): CostCentreDetailFormData => ({
@@ -39,7 +39,6 @@ import { DaybookService } from './daybook.service';
RouterModule, RouterModule,
MatPaginatorModule, MatPaginatorModule,
CurrencyPipe, CurrencyPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -49,7 +49,6 @@ export interface EmployeeAttendanceFormData {
MatSelectModule, MatSelectModule,
MatIconModule, MatIconModule,
MatChipsModule, MatChipsModule,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -68,19 +68,15 @@ export interface EmployeeBenefitsFormData {
], ],
}) })
export class EmployeeBenefitsComponent { export class EmployeeBenefitsComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
auth = inject(AuthService); auth = inject(AuthService);
private ser = inject(VoucherService); private ser = inject(VoucherService);
private employeeSer = inject(EmployeeService); private employeeSer = inject(EmployeeService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
voucherResource = this.ser.getVoucher(this.id, signal('Employee Benefit'), signal(null), signal(null)); voucherResource = this.ser.getVoucher(this.id, signal('Employee Benefit'), signal(null), signal(null));
item = linkedSignal(() => this.voucherResource.value() ?? new Voucher()); item = linkedSignal(() => this.voucherResource.value() ?? new Voucher());
formModel = linkedSignal<Voucher, EmployeeBenefitsFormData>({ formModel = linkedSignal<Voucher, EmployeeBenefitsFormData>({
source: this.item, source: this.item,
computation: (v): EmployeeBenefitsFormData => ({ computation: (v): EmployeeBenefitsFormData => ({
@@ -47,24 +47,19 @@ export interface EmployeeDetailFormData {
MatOptionModule, MatOptionModule,
MatDatepickerModule, MatDatepickerModule,
MatButtonModule, MatButtonModule,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class EmployeeDetailComponent { export class EmployeeDetailComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
private ser = inject(EmployeeService); private ser = inject(EmployeeService);
private costCentreService = inject(CostCentreService); private costCentreService = inject(CostCentreService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
itemResource = this.ser.get(this.id); itemResource = this.ser.get(this.id);
item = computed(() => this.itemResource.value() ?? new Employee()); item = computed(() => this.itemResource.value() ?? new Employee());
model = linkedSignal({ model = linkedSignal({
source: this.item, source: this.item,
computation: (itemVal): EmployeeDetailFormData => ({ computation: (itemVal): EmployeeDetailFormData => ({
@@ -42,7 +42,6 @@ import { EmployeeService } from '../employee.service';
FormField, FormField,
FormRoot, FormRoot,
RouterModule, RouterModule,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -49,18 +49,14 @@ export interface IncentiveFormData {
], ],
}) })
export class IncentiveComponent { export class IncentiveComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
auth = inject(AuthService); auth = inject(AuthService);
private ser = inject(VoucherService); private ser = inject(VoucherService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
voucherResource = this.ser.getVoucher(this.id, signal('Incentive'), signal(null), signal(null)); voucherResource = this.ser.getVoucher(this.id, signal('Incentive'), signal(null), signal(null));
voucher = computed(() => this.voucherResource.value() ?? new Voucher()); voucher = computed(() => this.voucherResource.value() ?? new Voucher());
model = linkedSignal({ model = linkedSignal({
source: this.voucher, source: this.voucher,
computation: (v): IncentiveFormData => ({ computation: (v): IncentiveFormData => ({
@@ -36,7 +36,7 @@ export interface IssueDialogFormData {
], ],
}) })
export class IssueDialogComponent { export class IssueDialogComponent {
dialogRef = inject<MatDialogRef<IssueDialogComponent>>(MatDialogRef); readonly dialogRef = inject<MatDialogRef<IssueDialogComponent, Inventory>>(MatDialogRef);
data = inject<{ data = inject<{
inventory: Inventory; inventory: Inventory;
date: string; date: string;
+3 -7
View File
@@ -88,16 +88,11 @@ export interface IssueFormModel {
DecimalPipe, DecimalPipe,
CurrencyPipe, CurrencyPipe,
LocalTimePipe, LocalTimePipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class IssueComponent { export class IssueComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
d = input(null, { transform: (v: string | null | undefined) => v ?? null });
type = signal('Issue');
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
@@ -107,10 +102,11 @@ export class IssueComponent {
private batchSer = inject(BatchService); private batchSer = inject(BatchService);
private issueGridSer = inject(IssueGridService); private issueGridSer = inject(IssueGridService);
private costCentreSer = inject(CostCentreService); private costCentreSer = inject(CostCentreService);
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
d = input(null, { transform: (v: string | null | undefined) => v ?? null });
type = signal('Issue');
itemResource = this.ser.getVoucher(this.id, this.type, signal(null), this.d); itemResource = this.ser.getVoucher(this.id, this.type, signal(null), this.d);
item = linkedSignal(() => this.itemResource.value() ?? new Voucher()); item = linkedSignal(() => this.itemResource.value() ?? new Voucher());
@@ -44,7 +44,7 @@ export interface JournalDialogFormData {
export class JournalDialogComponent { export class JournalDialogComponent {
private math = inject(MathService); private math = inject(MathService);
private accountSer = inject(AccountService); private accountSer = inject(AccountService);
dialogRef = inject<MatDialogRef<JournalDialogComponent>>(MatDialogRef); readonly dialogRef = inject<MatDialogRef<JournalDialogComponent, Journal>>(MatDialogRef);
data = inject<{ data = inject<{
journal: Journal; journal: Journal;
date: string; date: string;
@@ -98,7 +98,6 @@ export interface JournalFormModel {
LocalTimePipe, LocalTimePipe,
FormRoot, FormRoot,
FormField, FormField,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
+33 -6
View File
@@ -65,8 +65,6 @@ import { LedgerService } from './ledger.service';
CurrencyPipe, CurrencyPipe,
AccountingPipe, AccountingPipe,
ClearPipe, ClearPipe,
ClearPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -90,7 +88,9 @@ export class LedgerComponent {
sortDirection = signal(''); sortDirection = signal('');
infoResource = this.ser.list(this.id, this.startDate, this.finishDate); infoResource = this.ser.list(this.id, this.startDate, this.finishDate);
info = computed(() => this.infoResource.value() ?? new Ledger()); info = computed(() => this.infoResource.value() ?? new Ledger());
allTags = computed(() => this.tagsResource.value() ?? []); allTags = computed(() => this.tagsResource.value() ?? []);
tags = computed(() => { tags = computed(() => {
const data = this.info().body; const data = this.info().body;
return ['(None)', ...Array.from(new Set(data.map((x) => x.tags).reduce((list, t) => list.concat(t), [])))]; return ['(None)', ...Array.from(new Set(data.map((x) => x.tags).reduce((list, t) => list.concat(t), [])))];
@@ -101,10 +101,11 @@ export class LedgerComponent {
filteredList = computed(() => { filteredList = computed(() => {
const data = this.info().body ?? []; const data = this.info().body ?? [];
const tags = this.tagsSignal(); const tags = this.tagsSignal();
return data.filter( const filtered = data.filter(
(x) => (x) =>
(x.tags.length === 0 && tags.indexOf('(None)') !== -1) || x.tags.filter((t) => tags.includes(t)).length > 0, (x.tags.length === 0 && tags.indexOf('(None)') !== -1) || x.tags.filter((t) => tags.includes(t)).length > 0,
); );
return this.calculateTotals([...filtered]);
}); });
length = computed(() => this.filteredList().length); length = computed(() => this.filteredList().length);
@@ -187,11 +188,37 @@ export class LedgerComponent {
this.selectedRowId = id; this.selectedRowId = id;
} }
debit = computed(() => this.filteredList().reduce((acc, row) => acc + row.debit, 0)); debit = computed(() =>
this.filteredList()
.filter((item) => item.type !== 'Opening Balance')
.reduce((acc, row) => acc + row.debit, 0),
);
credit = computed(() => this.filteredList().reduce((acc, row) => acc + row.credit, 0)); credit = computed(() =>
this.filteredList()
.filter((item) => item.type !== 'Opening Balance')
.reduce((acc, row) => acc + row.credit, 0),
);
running = computed(() => this.filteredList().reduce((acc, row) => acc + row.debit - row.credit, 0)); running = computed(() => {
const list = this.filteredList();
return list.length ? (list[list.length - 1]?.running ?? 0) : 0;
});
calculateTotals(data: LedgerItem[]) {
let running = 0;
data.forEach((item) => {
if (item.type !== 'Opening Balance') {
if (item.posted) {
running += item.debit - item.credit;
}
} else {
running += item.debit - item.credit;
}
item.running = running;
});
return data;
}
isAllSelected() { isAllSelected() {
const numSelected = this.selection.selected.length; const numSelected = this.selection.selected.length;
@@ -54,7 +54,6 @@ export interface MozimoDailyRegisterFormData {
MatTooltipModule, MatTooltipModule,
FormField, FormField,
FormRoot, FormRoot,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -59,7 +59,6 @@ export interface MozimoProductRegisterFormData {
MatTooltipModule, MatTooltipModule,
FormField, FormField,
FormRoot, FormRoot,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -40,22 +40,19 @@ import { NetTransactionsService } from './net-transactions.service';
MatPaginatorModule, MatPaginatorModule,
CurrencyPipe, CurrencyPipe,
AccountingPipe, AccountingPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class NetTransactionsComponent { export class NetTransactionsComponent {
startDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
finishDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private ser = inject(NetTransactionsService); private ser = inject(NetTransactionsService);
pageSize = signal(50); pageSize = signal(50);
pageIndex = signal(0); pageIndex = signal(0);
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
startDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
finishDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
infoResource = this.ser.list(this.startDate, this.finishDate); infoResource = this.ser.list(this.startDate, this.finishDate);
info = computed(() => this.infoResource.value() ?? new NetTransactions()); info = computed(() => this.infoResource.value() ?? new NetTransactions());
@@ -37,7 +37,7 @@ export interface PaymentDialogFormData {
], ],
}) })
export class PaymentDialogComponent { export class PaymentDialogComponent {
dialogRef = inject<MatDialogRef<PaymentDialogComponent>>(MatDialogRef); readonly dialogRef = inject<MatDialogRef<PaymentDialogComponent, Journal>>(MatDialogRef);
data = inject<{ data = inject<{
journal: Journal; journal: Journal;
date: string; date: string;
@@ -98,17 +98,11 @@ export interface PaymentFormModel {
CurrencyPipe, CurrencyPipe,
AccountingPipe, AccountingPipe,
LocalTimePipe, LocalTimePipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class PaymentComponent { export class PaymentComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
d = input(null, { transform: (v: string | null | undefined) => v ?? null });
a = input(null, { transform: (v: string | null | undefined) => v ?? null });
type = signal('Payment');
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
@@ -118,13 +112,14 @@ export class PaymentComponent {
private ser = inject(VoucherService); private ser = inject(VoucherService);
private accountSer = inject(AccountService); private accountSer = inject(AccountService);
private tagSer = inject(TagService); private tagSer = inject(TagService);
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
d = input(null, { transform: (v: string | null | undefined) => v ?? null });
a = input(null, { transform: (v: string | null | undefined) => v ?? null });
type = signal('Payment');
itemResource = this.ser.getVoucher(this.id, this.type, this.a, this.d); itemResource = this.ser.getVoucher(this.id, this.type, this.a, this.d);
item = linkedSignal(() => this.itemResource.value() ?? new Voucher()); item = linkedSignal(() => this.itemResource.value() ?? new Voucher());
formModel = linkedSignal<Voucher, PaymentFormModel>({ formModel = linkedSignal<Voucher, PaymentFormModel>({
source: this.item, source: this.item,
computation: (voucher): PaymentFormModel => { computation: (voucher): PaymentFormModel => {
@@ -38,17 +38,13 @@ import { PeriodService } from '../period.service';
], ],
}) })
export class PeriodDetailComponent { export class PeriodDetailComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
private ser = inject(PeriodService); private ser = inject(PeriodService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
itemResource = this.ser.get(this.id); itemResource = this.ser.get(this.id);
item = computed(() => this.itemResource.value() ?? new Period()); item = computed(() => this.itemResource.value() ?? new Period());
model = linkedSignal({ model = linkedSignal({
source: this.item, source: this.item,
computation: (item): PeriodFormData => ({ computation: (item): PeriodFormData => ({
@@ -34,16 +34,12 @@ export interface ProductGroupDetailFormData {
], ],
}) })
export class ProductGroupDetailComponent { export class ProductGroupDetailComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
private ser = inject(ProductGroupService); private ser = inject(ProductGroupService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
itemResource = this.ser.get(this.id); itemResource = this.ser.get(this.id);
item = computed(() => this.itemResource.value() ?? new ProductGroup()); item = computed(() => this.itemResource.value() ?? new ProductGroup());
model = linkedSignal({ model = linkedSignal({
source: this.item, source: this.item,
computation: (itemVal): ProductGroupDetailFormData => ({ computation: (itemVal): ProductGroupDetailFormData => ({
@@ -27,7 +27,6 @@ import { ProductGroupService } from '../product-group.service';
}) })
export class ProductGroupListComponent { export class ProductGroupListComponent {
private ser = inject(ProductGroupService); private ser = inject(ProductGroupService);
pageSize = signal(50); pageSize = signal(50);
pageIndex = signal(0); pageIndex = signal(0);
sortActive = signal(''); sortActive = signal('');
@@ -32,7 +32,7 @@ export interface ProductDetailDialogFormData {
], ],
}) })
export class ProductDetailDialogComponent { export class ProductDetailDialogComponent {
dialogRef = inject<MatDialogRef<ProductDetailDialogComponent>>(MatDialogRef); readonly dialogRef = inject<MatDialogRef<ProductDetailDialogComponent, StockKeepingUnit>>(MatDialogRef);
data = inject<{ data = inject<{
item: StockKeepingUnit; item: StockKeepingUnit;
isSold: boolean; isSold: boolean;
@@ -79,23 +79,19 @@ export interface ProductDetailFormModel {
MatTableModule, MatTableModule,
MatIconModule, MatIconModule,
CurrencyPipe, CurrencyPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class ProductDetailComponent { export class ProductDetailComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
private ser = inject(ProductService); private ser = inject(ProductService);
private pgSer = inject(ProductGroupService); private pgSer = inject(ProductGroupService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
itemResource = this.ser.get(this.id); itemResource = this.ser.get(this.id);
item = linkedSignal(() => this.itemResource.value() ?? new Product()); item = linkedSignal(() => this.itemResource.value() ?? new Product());
formModel = linkedSignal<Product, ProductDetailFormModel>({ formModel = linkedSignal<Product, ProductDetailFormModel>({
source: this.item, source: this.item,
computation: (itemVal): ProductDetailFormModel => ({ computation: (itemVal): ProductDetailFormModel => ({
@@ -49,7 +49,6 @@ export interface ProductListFormData {
MatPaginatorModule, MatPaginatorModule,
PercentPipe, PercentPipe,
CurrencyPipe, CurrencyPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -40,7 +40,6 @@ export interface ProfitLossFormData {
MatSortModule, MatSortModule,
MatPaginatorModule, MatPaginatorModule,
CurrencyPipe, CurrencyPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -51,7 +50,6 @@ export class ProfitLossComponent {
private ser = inject(ProfitLossService); private ser = inject(ProfitLossService);
pageSize = signal(50); pageSize = signal(50);
pageIndex = signal(0); pageIndex = signal(0);
startDate = input(null, { transform: (v: string | null | undefined) => v ?? null }); startDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
finishDate = input(null, { transform: (v: string | null | undefined) => v ?? null }); finishDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
infoResource = this.ser.list(this.startDate, this.finishDate); infoResource = this.ser.list(this.startDate, this.finishDate);
@@ -43,7 +43,6 @@ export interface PurchaseEntriesFormData {
DecimalPipe, DecimalPipe,
PercentPipe, PercentPipe,
CurrencyPipe, CurrencyPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -52,12 +51,10 @@ export class PurchaseEntriesComponent {
private route = inject(ActivatedRoute); private route = inject(ActivatedRoute);
private router = inject(Router); private router = inject(Router);
private ser = inject(PurchaseEntriesService); private ser = inject(PurchaseEntriesService);
pageSize = signal(50); pageSize = signal(50);
pageIndex = signal(0); pageIndex = signal(0);
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
startDate = input(null, { transform: (v: string | null | undefined) => v ?? null }); startDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
finishDate = input(null, { transform: (v: string | null | undefined) => v ?? null }); finishDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
resource = this.ser.list(this.startDate, this.finishDate); resource = this.ser.list(this.startDate, this.finishDate);
@@ -36,7 +36,7 @@ export interface PurchaseReturnDialogFormData {
], ],
}) })
export class PurchaseReturnDialogComponent { export class PurchaseReturnDialogComponent {
dialogRef = inject<MatDialogRef<PurchaseReturnDialogComponent>>(MatDialogRef); readonly dialogRef = inject<MatDialogRef<PurchaseReturnDialogComponent, Inventory>>(MatDialogRef);
data = inject<{ data = inject<{
inventory: Inventory; inventory: Inventory;
date: string; date: string;
@@ -101,17 +101,11 @@ export interface PurchaseReturnFormModel {
CurrencyPipe, CurrencyPipe,
AccountingPipe, AccountingPipe,
LocalTimePipe, LocalTimePipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class PurchaseReturnComponent { export class PurchaseReturnComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
d = input(null, { transform: (v: string | null | undefined) => v ?? null });
a = input(null, { transform: (v: string | null | undefined) => v ?? null });
type = signal('Purchase Return');
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
@@ -122,10 +116,12 @@ export class PurchaseReturnComponent {
private batchSer = inject(BatchService); private batchSer = inject(BatchService);
private accountSer = inject(AccountService); private accountSer = inject(AccountService);
private tagSer = inject(TagService); private tagSer = inject(TagService);
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
d = input(null, { transform: (v: string | null | undefined) => v ?? null });
a = input(null, { transform: (v: string | null | undefined) => v ?? null });
type = signal('Purchase Return');
itemResource = this.ser.getVoucher(this.id, this.type, this.a, this.d); itemResource = this.ser.getVoucher(this.id, this.type, this.a, this.d);
item = linkedSignal(() => this.itemResource.value() ?? new Voucher()); item = linkedSignal(() => this.itemResource.value() ?? new Voucher());
@@ -41,7 +41,7 @@ export interface PurchaseDialogFormData {
], ],
}) })
export class PurchaseDialogComponent { export class PurchaseDialogComponent {
dialogRef = inject<MatDialogRef<PurchaseDialogComponent>>(MatDialogRef); readonly dialogRef = inject<MatDialogRef<PurchaseDialogComponent, Inventory>>(MatDialogRef);
data = inject<{ data = inject<{
inventory: Inventory; inventory: Inventory;
}>(MAT_DIALOG_DATA); }>(MAT_DIALOG_DATA);
@@ -106,17 +106,11 @@ export interface PurchaseFormModel {
CurrencyPipe, CurrencyPipe,
AccountingPipe, AccountingPipe,
LocalTimePipe, LocalTimePipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class PurchaseComponent { export class PurchaseComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
d = input(null, { transform: (v: string | null | undefined) => v ?? null });
a = input(null, { transform: (v: string | null | undefined) => v ?? null });
type = signal('Purchase');
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
@@ -127,10 +121,12 @@ export class PurchaseComponent {
private productSer = inject(ProductService); private productSer = inject(ProductService);
private accountSer = inject(AccountService); private accountSer = inject(AccountService);
private tagSer = inject(TagService); private tagSer = inject(TagService);
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
d = input(null, { transform: (v: string | null | undefined) => v ?? null });
a = input(null, { transform: (v: string | null | undefined) => v ?? null });
type = signal('Purchase');
itemResource = this.ser.getVoucher(this.id, this.type, this.a, this.d); itemResource = this.ser.getVoucher(this.id, this.type, this.a, this.d);
item = linkedSignal(() => this.itemResource.value() ?? new Voucher()); item = linkedSignal(() => this.itemResource.value() ?? new Voucher());
@@ -43,7 +43,6 @@ export interface PurchasesFormData {
MatPaginatorModule, MatPaginatorModule,
DecimalPipe, DecimalPipe,
CurrencyPipe, CurrencyPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -67,7 +67,6 @@ export interface RateContractDetailFormData {
MatSortModule, MatSortModule,
MatIconModule, MatIconModule,
CurrencyPipe, CurrencyPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -24,7 +24,6 @@ import { RateContractService } from '../rate-contract.service';
MatPaginatorModule, MatPaginatorModule,
CurrencyPipe, CurrencyPipe,
MatButtonModule, MatButtonModule,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -46,7 +46,6 @@ export interface RawMaterialCostFormData {
DecimalPipe, DecimalPipe,
PercentPipe, PercentPipe,
CurrencyPipe, CurrencyPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -37,7 +37,7 @@ export interface ReceiptDialogFormData {
], ],
}) })
export class ReceiptDialogComponent { export class ReceiptDialogComponent {
dialogRef = inject<MatDialogRef<ReceiptDialogComponent>>(MatDialogRef); readonly dialogRef = inject<MatDialogRef<ReceiptDialogComponent, Journal>>(MatDialogRef);
data = inject<{ data = inject<{
journal: Journal; journal: Journal;
date: string; date: string;
@@ -99,17 +99,11 @@ export interface ReceiptFormModel {
CurrencyPipe, CurrencyPipe,
AccountingPipe, AccountingPipe,
LocalTimePipe, LocalTimePipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class ReceiptComponent { export class ReceiptComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
d = input(null, { transform: (v: string | null | undefined) => v ?? null });
a = input(null, { transform: (v: string | null | undefined) => v ?? null });
type = signal('Receipt');
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
@@ -119,10 +113,12 @@ export class ReceiptComponent {
private ser = inject(VoucherService); private ser = inject(VoucherService);
private accountSer = inject(AccountService); private accountSer = inject(AccountService);
private tagSer = inject(TagService); private tagSer = inject(TagService);
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
d = input(null, { transform: (v: string | null | undefined) => v ?? null });
a = input(null, { transform: (v: string | null | undefined) => v ?? null });
type = signal('Receipt');
itemResource = this.ser.getVoucher(this.id, this.type, this.a, this.d); itemResource = this.ser.getVoucher(this.id, this.type, this.a, this.d);
item = linkedSignal(() => this.itemResource.value() ?? new Voucher()); item = linkedSignal(() => this.itemResource.value() ?? new Voucher());
@@ -37,13 +37,11 @@ import { RecipeService } from '../recipe.service';
MatSortModule, MatSortModule,
MatPaginatorModule, MatPaginatorModule,
MatButtonModule, MatButtonModule,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class RecipeListComponent { export class RecipeListComponent {
p = input<string>();
private ser = inject(RecipeService); private ser = inject(RecipeService);
private router = inject(Router); private router = inject(Router);
private periodSer = inject(PeriodService); private periodSer = inject(PeriodService);
@@ -54,6 +52,7 @@ export class RecipeListComponent {
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
p = input<string>();
model = signal({ model = signal({
period: null as Period | null, period: null as Period | null,
productGroup: null as ProductGroup | string | null, productGroup: null as ProductGroup | string | null,
@@ -28,19 +28,17 @@ import { RoleService } from '../role.service';
MatDividerModule, MatDividerModule,
MatCheckboxModule, MatCheckboxModule,
MatButtonModule, MatButtonModule,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class RoleDetailComponent { export class RoleDetailComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private ser = inject(RoleService); private ser = inject(RoleService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
itemResource = this.ser.get(this.id); itemResource = this.ser.get(this.id);
item = computed(() => this.itemResource.value() ?? new Role()); item = computed(() => this.itemResource.value() ?? new Role());
@@ -10,7 +10,7 @@ import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/materia
imports: [MatDialogModule, CdkScrollableModule, MatButtonModule], imports: [MatDialogModule, CdkScrollableModule, MatButtonModule],
}) })
export class ConfirmDialogComponent { export class ConfirmDialogComponent {
dialogRef = inject<MatDialogRef<ConfirmDialogComponent>>(MatDialogRef); readonly dialogRef = inject<MatDialogRef<ConfirmDialogComponent>>(MatDialogRef);
data = inject<{ data = inject<{
title: string; title: string;
content: string; content: string;
@@ -8,7 +8,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
standalone: true, standalone: true,
}) })
export class ImageDialogComponent { export class ImageDialogComponent {
dialogRef = inject<MatDialogRef<ImageDialogComponent>>(MatDialogRef); readonly dialogRef = inject<MatDialogRef<ImageDialogComponent>>(MatDialogRef);
data = inject(MAT_DIALOG_DATA); data = inject(MAT_DIALOG_DATA);
close(): void { close(): void {
@@ -41,7 +41,6 @@ export interface StockMovementFormData {
RouterModule, RouterModule,
MatPaginatorModule, MatPaginatorModule,
DecimalPipe, DecimalPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -55,6 +54,7 @@ export class StockMovementComponent {
pageIndex = signal(0); pageIndex = signal(0);
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
startDate = input(null, { transform: (v: string | null | undefined) => v ?? null }); startDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
finishDate = input(null, { transform: (v: string | null | undefined) => v ?? null }); finishDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
@@ -33,7 +33,7 @@ export interface TagDialogFormData {
], ],
}) })
export class TagDialogComponent implements OnInit { export class TagDialogComponent implements OnInit {
dialogRef = inject<MatDialogRef<TagDialogComponent>>(MatDialogRef); readonly dialogRef = inject<MatDialogRef<TagDialogComponent>>(MatDialogRef);
data = inject<{ data = inject<{
tags: Tag[]; tags: Tag[];
vouchers: LedgerItem[]; vouchers: LedgerItem[];
@@ -32,15 +32,13 @@ export interface TagDetailFormData {
], ],
}) })
export class TagDetailComponent { export class TagDetailComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private ser = inject(TagService); private ser = inject(TagService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
itemResource = this.ser.get(this.id); itemResource = this.ser.get(this.id);
item = computed(() => this.itemResource.value() ?? new Tag()); item = computed(() => this.itemResource.value() ?? new Tag());
formModel = linkedSignal({ formModel = linkedSignal({
@@ -32,6 +32,7 @@ export class TagListComponent {
pageIndex = signal(0); pageIndex = signal(0);
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
listResource = this.ser.list(); listResource = this.ser.list();
list = computed(() => this.listResource.value() ?? []); list = computed(() => this.listResource.value() ?? []);
sortedList = computed(() => { sortedList = computed(() => {
@@ -127,20 +127,19 @@ function createEmptySkuForm(): TemporalProductSkuFormData {
FormField, FormField,
FormRoot, FormRoot,
CurrencyPipe, CurrencyPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class TemporalProductDetailComponent { export class TemporalProductDetailComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
private ser = inject(TemporalProductService); private ser = inject(TemporalProductService);
private pgSer = inject(ProductGroupService); private pgSer = inject(ProductGroupService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
productDisplayedColumns = ['name', 'fractionUnits', 'productGroup', 'validFrom', 'validTill', 'actions']; productDisplayedColumns = ['name', 'fractionUnits', 'productGroup', 'validFrom', 'validTill', 'actions'];
skuDisplayedColumns = [ skuDisplayedColumns = [
'units', 'units',
@@ -37,7 +37,6 @@ export interface TemporalProductListFormData {
FormField, FormField,
FormRoot, FormRoot,
RouterLink, RouterLink,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -41,7 +41,6 @@ export interface TrialBalanceFormData {
MatPaginatorModule, MatPaginatorModule,
CurrencyPipe, CurrencyPipe,
AccountingPipe, AccountingPipe,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
@@ -35,21 +35,18 @@ export interface UserDetailFormData {
MatCheckboxModule, MatCheckboxModule,
MatDividerModule, MatDividerModule,
MatButtonModule, MatButtonModule,
SkeletonLoaderComponent, SkeletonLoaderComponent,
ErrorStateComponent, ErrorStateComponent,
], ],
}) })
export class UserDetailComponent { export class UserDetailComponent {
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
private router = inject(Router); private router = inject(Router);
private snackBar = inject(MatSnackBar); private snackBar = inject(MatSnackBar);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
private ser = inject(UserService); private ser = inject(UserService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
itemResource = this.ser.get(this.id); itemResource = this.ser.get(this.id);
item = computed(() => this.itemResource.value() ?? new User()); item = computed(() => this.itemResource.value() ?? new User());
formModel = linkedSignal({ formModel = linkedSignal({
@@ -29,10 +29,12 @@ import { UserService } from '../user.service';
}) })
export class UserListComponent { export class UserListComponent {
private ser = inject(UserService); private ser = inject(UserService);
pageSize = signal(50); pageSize = signal(50);
pageIndex = signal(0); pageIndex = signal(0);
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
listResource = this.ser.list(); listResource = this.ser.list();
list = computed(() => this.listResource.value() ?? []); list = computed(() => this.listResource.value() ?? []);
sortedList = computed(() => { sortedList = computed(() => {
+3 -1
View File
@@ -31,7 +31,8 @@ then
sed --in-place --regexp-extended 's/"([0-9]{1,2}.[0-9]+.[0-9]+)"/"'"$new_version"'"/g' brewman/brewman/__version__.py sed --in-place --regexp-extended 's/"([0-9]{1,2}.[0-9]+.[0-9]+)"/"'"$new_version"'"/g' brewman/brewman/__version__.py
git add brewman/brewman/__version__.py git add brewman/brewman/__version__.py
sed --in-place --regexp-extended 's/version = "([0-9]{1,2}.[0-9]+.[0-9]+)"/version = "'"$new_version"'"/g' brewman/pyproject.toml sed --in-place --regexp-extended 's/version = "([0-9]{1,2}.[0-9]+.[0-9]+)"/version = "'"$new_version"'"/g' brewman/pyproject.toml
git add brewman/pyproject.toml (cd brewman && uv lock)
git add brewman/pyproject.toml brewman/uv.lock
sed --in-place --regexp-extended 's/version: '\''([0-9]*.[0-9]+.[0-9]+)'\''/version: '\'"$new_version"\''/g' overlord/src/app/app.environment.ts sed --in-place --regexp-extended 's/version: '\''([0-9]*.[0-9]+.[0-9]+)'\''/version: '\'"$new_version"\''/g' overlord/src/app/app.environment.ts
git add overlord/src/app/app.environment.ts git add overlord/src/app/app.environment.ts
sed --in-place --regexp-extended 's/"version": "([0-9]{1,2}.[0-9]+.[0-9]+)"/"version": "'"$new_version"'"/g' overlord/package.json sed --in-place --regexp-extended 's/"version": "([0-9]{1,2}.[0-9]+.[0-9]+)"/"version": "'"$new_version"'"/g' overlord/package.json
@@ -43,4 +44,5 @@ else
echo "Usage: $0 <major|minor|patch|version_string>" echo "Usage: $0 <major|minor|patch|version_string>"
exit 1 exit 1
fi fi
git push
git push --tags git push --tags