Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15288b270a | ||
|
|
5cfa02a6ef | ||
|
|
4f89cd1161 | ||
|
|
0d5012c961 | ||
|
|
e918644a5b | ||
|
|
eb7aa20def | ||
|
|
407967514f | ||
|
|
be40004a3d | ||
|
|
1fa16912d1 | ||
|
|
c891937d2b | ||
|
|
386a6c4964 | ||
|
|
b5d57fccf3 | ||
|
|
f42e4d3628 | ||
|
|
c534aaffa3 |
@@ -0,0 +1,61 @@
|
||||
# Version control & IDEs
|
||||
.git
|
||||
.gitignore
|
||||
.vscode
|
||||
.idea
|
||||
.agents
|
||||
.gemini
|
||||
|
||||
# Build artifacts & compiled outputs
|
||||
frontend
|
||||
dist
|
||||
**/dist
|
||||
out-tsc
|
||||
**/out-tsc
|
||||
bazel-out
|
||||
|
||||
# Dependencies & framework caches
|
||||
node_modules
|
||||
**/node_modules
|
||||
.angular
|
||||
**/.angular
|
||||
.nx
|
||||
**/.nx
|
||||
.sass-cache
|
||||
**/.sass-cache
|
||||
|
||||
# Python virtual environments & caches
|
||||
.venv
|
||||
**/__pycache__
|
||||
**/.mypy_cache
|
||||
**/.ruff_cache
|
||||
**/.pytest_cache
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.egg-info
|
||||
|
||||
# Testing & coverage
|
||||
coverage
|
||||
**/coverage
|
||||
.coverage
|
||||
htmlcov
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Environment & local deployment/dev files
|
||||
.env*
|
||||
!.env.example
|
||||
ansible
|
||||
deploy.sh
|
||||
lint.sh
|
||||
version_bump.sh
|
||||
Makefile
|
||||
README.md
|
||||
CHANGES.md
|
||||
typings
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
+47
-1
@@ -1,5 +1,51 @@
|
||||
# IDEs & System Files
|
||||
.idea/
|
||||
frontend
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Build outputs
|
||||
frontend/
|
||||
dist/
|
||||
**/dist/
|
||||
out-tsc/
|
||||
**/out-tsc/
|
||||
bazel-out/
|
||||
|
||||
# Angular & Nx caches
|
||||
.angular/
|
||||
**/.angular/
|
||||
.nx/
|
||||
**/.nx/
|
||||
.sass-cache/
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
**/node_modules/
|
||||
|
||||
# Python & Virtual Environments
|
||||
.venv/
|
||||
**/__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.egg-info/
|
||||
.mypy_cache/
|
||||
**/.mypy_cache/
|
||||
.ruff_cache/
|
||||
**/.ruff_cache/
|
||||
.pytest_cache/
|
||||
**/.pytest_cache/
|
||||
|
||||
# Testing & Coverage
|
||||
coverage/
|
||||
**/coverage/
|
||||
.coverage
|
||||
htmlcov/
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Ignore Pyright-generated stubs
|
||||
*.pyi
|
||||
|
||||
Vendored
+18
-1
@@ -27,19 +27,36 @@
|
||||
"files.exclude": {
|
||||
"**/__pycache__": true,
|
||||
"**/.mypy_cache": true,
|
||||
"**/.ruff_cache": true,
|
||||
"**/.pytest_cache": true,
|
||||
".idea": true,
|
||||
"**/node_modules": true,
|
||||
"typings": true,
|
||||
"frontend": true,
|
||||
"**/.angular": true,
|
||||
"**/.nx": true,
|
||||
"**/out-tsc": true,
|
||||
"**/dist": true,
|
||||
"**/.sass-cache": true,
|
||||
"**/coverage": true
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/__pycache__": true,
|
||||
"**/.mypy_cache": true,
|
||||
"**/.ruff_cache": true,
|
||||
"**/.pytest_cache": true,
|
||||
".idea": true,
|
||||
"**/node_modules": true,
|
||||
"**/poetry.lock": true,
|
||||
"**/package-lock.json": true,
|
||||
"/overlord/.angular/**": true,
|
||||
"typings": true,
|
||||
"frontend/**": true,
|
||||
"**/.angular/**": true,
|
||||
"**/.nx/**": true,
|
||||
"**/out-tsc/**": true,
|
||||
"**/dist/**": true,
|
||||
"**/.sass-cache/**": true,
|
||||
"**/coverage/**": true
|
||||
},
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.ruff": "always",
|
||||
|
||||
@@ -29,7 +29,6 @@ RUN \
|
||||
else echo "Lockfile not found." && exit 1; \
|
||||
fi
|
||||
|
||||
|
||||
FROM python:3.14-slim AS runner
|
||||
LABEL maintainer="Amritanshu <docker@tanshu.com>"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ build-production: ## Build the production docker image.
|
||||
--tag registry.tanshu.com/brewman:latest \
|
||||
$(if $(TAG),--tag registry.tanshu.com/brewman:$(TAG)) \
|
||||
--push \
|
||||
git@git.tanshu.com:tanshu/brewman.git
|
||||
git@git.tanshu.com:tanshu/brewman.git$(if $(TAG),#v$(TAG))
|
||||
|
||||
.PHONY: build-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
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "ee77296e69b7"
|
||||
down_revision = "09a4f0ca450f"
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "15.1.1"
|
||||
__version__ = "15.2.4"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "brewman"
|
||||
version = "15.1.1"
|
||||
version = "15.2.4"
|
||||
description = "Accounting plus inventory management for a restaurant."
|
||||
requires-python = ">=3.14"
|
||||
authors = [{ name = "tanshu", email = "git@tanshu.com" }]
|
||||
|
||||
Generated
+1
-1
@@ -211,7 +211,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "brewman"
|
||||
version = "15.0.0"
|
||||
version = "15.2.4"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "alembic" },
|
||||
|
||||
@@ -7,10 +7,10 @@ parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" || exit ; pwd -P )
|
||||
cd "$parent_path/overlord" || exit
|
||||
npx prettier --write src/app
|
||||
npx ng lint --fix
|
||||
cd "$parent_path/brewman" || exit
|
||||
|
||||
uvx ruff format .
|
||||
uvx ruff check . # Lint all files in the current directory (and any subdirectories)
|
||||
uvx bandit --recursive brewman
|
||||
uvx bandit --recursive .
|
||||
uvx safety check
|
||||
cd "$parent_path/brewman" || exit
|
||||
uv run ruff format .
|
||||
uv run ruff check . # Lint all files in the current directory (and any subdirectories)
|
||||
uv run bandit --recursive brewman
|
||||
uv run bandit --recursive .
|
||||
uv run safety check
|
||||
+11
-4
@@ -32,7 +32,9 @@
|
||||
"input": "public"
|
||||
}
|
||||
],
|
||||
"styles": ["src/styles.sass"]
|
||||
"styles": [
|
||||
"src/styles.sass"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
@@ -79,14 +81,19 @@
|
||||
"lint": {
|
||||
"builder": "@angular-eslint/builder:lint",
|
||||
"options": {
|
||||
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
|
||||
"lintFilePatterns": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.html"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"schematicCollections": ["@angular-eslint/schematics"],
|
||||
"schematicCollections": [
|
||||
"@angular-eslint/schematics"
|
||||
],
|
||||
"analytics": false
|
||||
},
|
||||
"schematics": {
|
||||
@@ -115,4 +122,4 @@
|
||||
"typeSeparator": "."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "overlord",
|
||||
"version": "15.1.1",
|
||||
"version": "15.2.4",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
|
||||
@@ -42,7 +42,6 @@ export interface AccountDetailFormData {
|
||||
MatButtonModule,
|
||||
FormField,
|
||||
FormRoot,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -44,7 +44,6 @@ export interface AccountListFormData {
|
||||
MatTableModule,
|
||||
MatSortModule,
|
||||
MatPaginatorModule,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export const environment = {
|
||||
ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry
|
||||
version: '15.1.1',
|
||||
version: '15.2.4',
|
||||
title: 'HnG / TGB',
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ export interface AttendanceFormData {
|
||||
MatOptionModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -39,7 +39,6 @@ import { BalanceSheetService } from './balance-sheet.service';
|
||||
MatPaginatorModule,
|
||||
CurrencyPipe,
|
||||
ClearPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -37,17 +37,13 @@ export interface ClientFormData {
|
||||
],
|
||||
})
|
||||
export class ClientDetailComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private ser = inject(ClientService);
|
||||
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
itemResource = this.ser.get(this.id);
|
||||
|
||||
item = computed(() => this.itemResource.value() ?? new Client());
|
||||
|
||||
model = linkedSignal({
|
||||
source: this.item,
|
||||
computation: (item): ClientFormData => ({
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<mat-label>Department</mat-label>
|
||||
<mat-select [formField]="form.costCentre">
|
||||
@for (at of costCentres(); track at) {
|
||||
<mat-option [value]="at.id">
|
||||
<mat-option [value]="at">
|
||||
{{ at.name }}
|
||||
</mat-option>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CurrencyPipe, DecimalPipe } from '@angular/common';
|
||||
import { Component, inject, computed, input, linkedSignal, signal, afterNextRender } from '@angular/core';
|
||||
import { form as createForm, FormField, FormRoot } from '@angular/forms/signals';
|
||||
import { form as createForm, FormField, FormRoot, required } from '@angular/forms/signals';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatOptionModule } from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
@@ -56,7 +56,6 @@ export interface ClosingStockFormData {
|
||||
MatPaginatorModule,
|
||||
DecimalPipe,
|
||||
CurrencyPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
@@ -73,11 +72,11 @@ export class ClosingStockComponent {
|
||||
pageIndex = signal(0);
|
||||
sortActive = signal('');
|
||||
sortDirection = signal('');
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
date = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
d = 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 });
|
||||
infoResource = this.ser.list(this.id, this.d);
|
||||
infoResource = this.ser.list(this.date, this.d);
|
||||
info = computed(() => this.infoResource.value() ?? new ClosingStock());
|
||||
costCentresResource = this.costCentreSer.list();
|
||||
|
||||
@@ -95,7 +94,10 @@ export class ClosingStockComponent {
|
||||
}),
|
||||
});
|
||||
|
||||
form = createForm(this.model);
|
||||
form = createForm(this.model, (f) => {
|
||||
required(f.costCentre);
|
||||
required(f.date);
|
||||
});
|
||||
|
||||
sortedList = computed(() => {
|
||||
const data = this.info().items ?? [];
|
||||
@@ -145,6 +147,9 @@ export class ClosingStockComponent {
|
||||
}
|
||||
|
||||
show() {
|
||||
if (this.form().invalid()) {
|
||||
return;
|
||||
}
|
||||
const info = this.getInfo();
|
||||
this.router.navigate(['closing-stock', info.date], {
|
||||
queryParams: {
|
||||
@@ -181,7 +186,7 @@ export class ClosingStockComponent {
|
||||
|
||||
return new ClosingStock({
|
||||
date: moment(formModel.date).format('DD-MMM-YYYY'),
|
||||
costCentre: new CostCentre({ id: formModel.costCentre?.id ?? '' }),
|
||||
costCentre: formModel.costCentre ?? new CostCentre(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -73,10 +73,6 @@ export class VoucherService {
|
||||
});
|
||||
}
|
||||
|
||||
getIncentive(date: Signal<string>): ResourceRef<Voucher | undefined> {
|
||||
return httpResource<Voucher>(() => `${url}/incentive?d=${date()}`);
|
||||
}
|
||||
|
||||
post(id: string): Observable<Voucher> {
|
||||
return this.http
|
||||
.post<Voucher>(`${url}/post-voucher/${id}`, {})
|
||||
|
||||
@@ -30,16 +30,12 @@ export interface CostCentreDetailFormData {
|
||||
],
|
||||
})
|
||||
export class CostCentreDetailComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private ser = inject(CostCentreService);
|
||||
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
itemResource = this.ser.get(this.id);
|
||||
|
||||
item = computed(() => this.itemResource.value() ?? new CostCentre());
|
||||
|
||||
model = linkedSignal({
|
||||
source: this.item,
|
||||
computation: (itemVal): CostCentreDetailFormData => ({
|
||||
|
||||
@@ -39,7 +39,6 @@ import { DaybookService } from './daybook.service';
|
||||
RouterModule,
|
||||
MatPaginatorModule,
|
||||
CurrencyPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -49,7 +49,6 @@ export interface EmployeeAttendanceFormData {
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -68,19 +68,15 @@ export interface EmployeeBenefitsFormData {
|
||||
],
|
||||
})
|
||||
export class EmployeeBenefitsComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
auth = inject(AuthService);
|
||||
private ser = inject(VoucherService);
|
||||
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));
|
||||
|
||||
item = linkedSignal(() => this.voucherResource.value() ?? new Voucher());
|
||||
|
||||
formModel = linkedSignal<Voucher, EmployeeBenefitsFormData>({
|
||||
source: this.item,
|
||||
computation: (v): EmployeeBenefitsFormData => ({
|
||||
|
||||
@@ -47,24 +47,19 @@ export interface EmployeeDetailFormData {
|
||||
MatOptionModule,
|
||||
MatDatepickerModule,
|
||||
MatButtonModule,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
export class EmployeeDetailComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private ser = inject(EmployeeService);
|
||||
private costCentreService = inject(CostCentreService);
|
||||
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
itemResource = this.ser.get(this.id);
|
||||
|
||||
item = computed(() => this.itemResource.value() ?? new Employee());
|
||||
|
||||
model = linkedSignal({
|
||||
source: this.item,
|
||||
computation: (itemVal): EmployeeDetailFormData => ({
|
||||
|
||||
@@ -42,7 +42,6 @@ import { EmployeeService } from '../employee.service';
|
||||
FormField,
|
||||
FormRoot,
|
||||
RouterModule,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<strong>{{ totalPoints() | number: '1.2-2' }}</strong> Point Value:
|
||||
<strong>{{ pointValue() | number: '1.2-2' }}</strong>
|
||||
</div>
|
||||
<mat-table #table [dataSource]="incentives()">
|
||||
<mat-table #table [dataSource]="model().incentives">
|
||||
<!-- Name Column -->
|
||||
<ng-container matColumnDef="name">
|
||||
<mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CurrencyPipe, DecimalPipe } from '@angular/common';
|
||||
import { signal, Component, inject, input, computed, linkedSignal } from '@angular/core';
|
||||
import { signal, Component, inject, input, computed, linkedSignal, effect } from '@angular/core';
|
||||
import { form as createForm, FormField, FormRoot } from '@angular/forms/signals';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
@@ -23,8 +23,8 @@ import { ConfirmDialogComponent } from '../shared/confirm-dialog/confirm-dialog.
|
||||
import { LocalTimePipe } from '../shared/local-time.pipe';
|
||||
|
||||
export interface IncentiveFormData {
|
||||
date: Date;
|
||||
incentives: { points: number }[];
|
||||
date: moment.Moment;
|
||||
incentives: Incentive[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
@@ -49,29 +49,34 @@ export interface IncentiveFormData {
|
||||
],
|
||||
})
|
||||
export class IncentiveComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
auth = inject(AuthService);
|
||||
private ser = inject(VoucherService);
|
||||
|
||||
voucherResource = this.ser.getVoucher(this.id, signal('Incentive'), signal(null), signal(null));
|
||||
|
||||
voucher = computed(() => this.voucherResource.value() ?? new Voucher());
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
d = input(null, { transform: (v: string | null | undefined): string | null => v ?? null });
|
||||
voucherResource = this.ser.getVoucher(this.id, signal('Incentive'), signal(null), this.d);
|
||||
voucher = computed(() => this.voucherResource.value() ?? new Voucher({ date: this.d() as string }));
|
||||
|
||||
model = linkedSignal({
|
||||
source: this.voucher,
|
||||
computation: (v): IncentiveFormData => ({
|
||||
date: moment(v.date, 'DD-MMM-YYYY').toDate(),
|
||||
incentives: v.incentives.map((x) => ({ points: x.points })),
|
||||
date: v.date ? moment(v.date, 'DD-MMM-YYYY') : moment(new Date()),
|
||||
incentives: v.incentives.map((x) => new Incentive({ ...x })),
|
||||
}),
|
||||
});
|
||||
|
||||
form = createForm(this.model);
|
||||
|
||||
incentives = linkedSignal(() => this.voucher().incentives);
|
||||
constructor() {
|
||||
effect(async () => {
|
||||
const date = this.form.date().value().format('DD-MMM-YYYY');
|
||||
if (date !== this.d() && !this.id()) {
|
||||
this.router.navigate(['/incentive'], { queryParams: { d: date }, replaceUrl: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
account: Account = new Account();
|
||||
accBal: AccountBalance | null = null;
|
||||
@@ -84,9 +89,10 @@ export class IncentiveComponent {
|
||||
}
|
||||
|
||||
totalPoints = computed(() => {
|
||||
return this.incentives()
|
||||
.map((item: Incentive, i: number) => item.daysWorked * (this.model().incentives[i]?.points ?? 0))
|
||||
.reduce((sum: number, item: number) => sum + item, 0);
|
||||
return this.model().incentives.reduce(
|
||||
(sum: number, item: Incentive) => sum + item.daysWorked * (item.points ?? 0),
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
pointValue = computed(() => {
|
||||
@@ -101,7 +107,7 @@ export class IncentiveComponent {
|
||||
this.model.update((m) => {
|
||||
const arr = [...m.incentives];
|
||||
if (arr[i]) {
|
||||
arr[i] = { ...arr[i], points: currentPoints - 1 };
|
||||
arr[i] = new Incentive({ ...arr[i], points: currentPoints - 1 });
|
||||
}
|
||||
return { ...m, incentives: arr };
|
||||
});
|
||||
@@ -113,7 +119,7 @@ export class IncentiveComponent {
|
||||
this.model.update((m) => {
|
||||
const arr = [...m.incentives];
|
||||
if (arr[i]) {
|
||||
arr[i] = { ...arr[i], points: currentPoints + 1 };
|
||||
arr[i] = new Incentive({ ...arr[i], points: currentPoints + 1 });
|
||||
}
|
||||
return { ...m, incentives: arr };
|
||||
});
|
||||
@@ -162,11 +168,7 @@ export class IncentiveComponent {
|
||||
const formModel = this.model();
|
||||
const v = this.voucher();
|
||||
v.date = moment(formModel.date).format('DD-MMM-YYYY');
|
||||
const array = formModel.incentives;
|
||||
|
||||
v.incentives.forEach((item: Incentive, index: number) => {
|
||||
item.points = array[index]?.points ?? 0;
|
||||
});
|
||||
v.incentives = formModel.incentives;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ export interface IssueDialogFormData {
|
||||
],
|
||||
})
|
||||
export class IssueDialogComponent {
|
||||
dialogRef = inject<MatDialogRef<IssueDialogComponent>>(MatDialogRef);
|
||||
readonly dialogRef = inject<MatDialogRef<IssueDialogComponent, Inventory>>(MatDialogRef);
|
||||
data = inject<{
|
||||
inventory: Inventory;
|
||||
date: string;
|
||||
|
||||
@@ -134,9 +134,9 @@
|
||||
<span class="flex">
|
||||
Created on <strong>{{ form.creationDate().value() | localTime }}</strong
|
||||
> and Last Edited on <strong>{{ form.lastEditDate().value() | localTime }}</strong
|
||||
> by <strong>{{ form.userName() }}</strong
|
||||
> by <strong>{{ form.userName().value().name }}</strong
|
||||
>.
|
||||
{{ form.posted() ? 'Posted by ' + form.poster() : '' }}
|
||||
{{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -58,7 +58,7 @@ export interface IssueFormModel {
|
||||
posted: boolean;
|
||||
creationDate: string;
|
||||
lastEditDate: string;
|
||||
userName: string;
|
||||
userName: User;
|
||||
poster: string;
|
||||
}
|
||||
|
||||
@@ -88,16 +88,11 @@ export interface IssueFormModel {
|
||||
DecimalPipe,
|
||||
CurrencyPipe,
|
||||
LocalTimePipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
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 dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
@@ -107,10 +102,11 @@ export class IssueComponent {
|
||||
private batchSer = inject(BatchService);
|
||||
private issueGridSer = inject(IssueGridService);
|
||||
private costCentreSer = inject(CostCentreService);
|
||||
|
||||
sortActive = 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);
|
||||
item = linkedSignal(() => this.itemResource.value() ?? new Voucher());
|
||||
|
||||
@@ -143,7 +139,7 @@ export class IssueComponent {
|
||||
posted: voucher.posted,
|
||||
creationDate: voucher.creationDate,
|
||||
lastEditDate: voucher.lastEditDate,
|
||||
userName: voucher.user?.name ?? '',
|
||||
userName: voucher.user ?? new User(),
|
||||
poster: voucher.poster ?? '',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -44,7 +44,7 @@ export interface JournalDialogFormData {
|
||||
export class JournalDialogComponent {
|
||||
private math = inject(MathService);
|
||||
private accountSer = inject(AccountService);
|
||||
dialogRef = inject<MatDialogRef<JournalDialogComponent>>(MatDialogRef);
|
||||
readonly dialogRef = inject<MatDialogRef<JournalDialogComponent, Journal>>(MatDialogRef);
|
||||
data = inject<{
|
||||
journal: Journal;
|
||||
date: string;
|
||||
|
||||
@@ -174,8 +174,8 @@
|
||||
<span class="flex">
|
||||
Created on <strong>{{ form.creationDate().value() | localTime }}</strong
|
||||
> and Last Edited on <strong>{{ form.lastEditDate().value() | localTime }}</strong
|
||||
> by <strong>{{ form.userName() }}</strong
|
||||
>. {{ form.posted() ? 'Posted by ' + form.poster() : '' }}
|
||||
> by <strong>{{ form.userName().value().name }}</strong
|
||||
>. {{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -26,6 +26,7 @@ import { AccountService } from '../core/account.service';
|
||||
import { CostCentre } from '../core/cost-centre';
|
||||
import { DbFile } from '../core/db-file';
|
||||
import { Journal } from '../core/journal';
|
||||
import { User } from '../core/user';
|
||||
import { Voucher } from '../core/voucher';
|
||||
import { VoucherService } from '../core/voucher.service';
|
||||
import { AccountingPipe } from '../shared/accounting.pipe';
|
||||
@@ -64,7 +65,7 @@ export interface JournalFormModel {
|
||||
posted: boolean;
|
||||
creationDate: string;
|
||||
lastEditDate: string;
|
||||
userName: string;
|
||||
userName: User;
|
||||
poster: string;
|
||||
}
|
||||
|
||||
@@ -98,7 +99,6 @@ export interface JournalFormModel {
|
||||
LocalTimePipe,
|
||||
FormRoot,
|
||||
FormField,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
@@ -195,7 +195,7 @@ export class JournalComponent {
|
||||
posted: voucher.posted,
|
||||
creationDate: voucher.creationDate,
|
||||
lastEditDate: voucher.lastEditDate,
|
||||
userName: voucher.user?.name ?? '',
|
||||
userName: voucher.user ?? new User(),
|
||||
poster: voucher.poster,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -65,8 +65,6 @@ import { LedgerService } from './ledger.service';
|
||||
CurrencyPipe,
|
||||
AccountingPipe,
|
||||
ClearPipe,
|
||||
ClearPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
@@ -90,7 +88,9 @@ export class LedgerComponent {
|
||||
sortDirection = signal('');
|
||||
infoResource = this.ser.list(this.id, this.startDate, this.finishDate);
|
||||
info = computed(() => this.infoResource.value() ?? new Ledger());
|
||||
|
||||
allTags = computed(() => this.tagsResource.value() ?? []);
|
||||
|
||||
tags = computed(() => {
|
||||
const data = this.info().body;
|
||||
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(() => {
|
||||
const data = this.info().body ?? [];
|
||||
const tags = this.tagsSignal();
|
||||
return data.filter(
|
||||
const filtered = data.filter(
|
||||
(x) =>
|
||||
(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);
|
||||
@@ -187,11 +188,37 @@ export class LedgerComponent {
|
||||
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() {
|
||||
const numSelected = this.selection.selected.length;
|
||||
|
||||
@@ -54,7 +54,6 @@ export interface MozimoDailyRegisterFormData {
|
||||
MatTooltipModule,
|
||||
FormField,
|
||||
FormRoot,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -59,7 +59,6 @@ export interface MozimoProductRegisterFormData {
|
||||
MatTooltipModule,
|
||||
FormField,
|
||||
FormRoot,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -40,22 +40,19 @@ import { NetTransactionsService } from './net-transactions.service';
|
||||
MatPaginatorModule,
|
||||
CurrencyPipe,
|
||||
AccountingPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
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 ser = inject(NetTransactionsService);
|
||||
|
||||
pageSize = signal(50);
|
||||
pageIndex = signal(0);
|
||||
sortActive = 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);
|
||||
|
||||
info = computed(() => this.infoResource.value() ?? new NetTransactions());
|
||||
|
||||
@@ -37,7 +37,7 @@ export interface PaymentDialogFormData {
|
||||
],
|
||||
})
|
||||
export class PaymentDialogComponent {
|
||||
dialogRef = inject<MatDialogRef<PaymentDialogComponent>>(MatDialogRef);
|
||||
readonly dialogRef = inject<MatDialogRef<PaymentDialogComponent, Journal>>(MatDialogRef);
|
||||
data = inject<{
|
||||
journal: Journal;
|
||||
date: string;
|
||||
|
||||
@@ -182,9 +182,9 @@
|
||||
<span class="flex">
|
||||
Created on <strong>{{ form.creationDate().value() | localTime }}</strong
|
||||
> and Last Edited on <strong>{{ form.lastEditDate().value() | localTime }}</strong
|
||||
> by <strong>{{ form.userName() }}</strong
|
||||
> by <strong>{{ form.userName().value().name }}</strong
|
||||
>.
|
||||
{{ form.posted() ? 'Posted by ' + form.poster() : '' }}
|
||||
{{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -65,7 +65,7 @@ export interface PaymentFormModel {
|
||||
posted: boolean;
|
||||
creationDate: string;
|
||||
lastEditDate: string;
|
||||
userName: string;
|
||||
userName: User;
|
||||
poster: string;
|
||||
}
|
||||
|
||||
@@ -98,17 +98,11 @@ export interface PaymentFormModel {
|
||||
CurrencyPipe,
|
||||
AccountingPipe,
|
||||
LocalTimePipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
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 dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
@@ -118,13 +112,14 @@ export class PaymentComponent {
|
||||
private ser = inject(VoucherService);
|
||||
private accountSer = inject(AccountService);
|
||||
private tagSer = inject(TagService);
|
||||
|
||||
sortActive = 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);
|
||||
item = linkedSignal(() => this.itemResource.value() ?? new Voucher());
|
||||
|
||||
formModel = linkedSignal<Voucher, PaymentFormModel>({
|
||||
source: this.item,
|
||||
computation: (voucher): PaymentFormModel => {
|
||||
@@ -158,7 +153,7 @@ export class PaymentComponent {
|
||||
posted: voucher.posted,
|
||||
creationDate: voucher.creationDate,
|
||||
lastEditDate: voucher.lastEditDate,
|
||||
userName: voucher.user?.name ?? '',
|
||||
userName: voucher.user ?? new User(),
|
||||
poster: voucher.poster ?? '',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -38,17 +38,13 @@ import { PeriodService } from '../period.service';
|
||||
],
|
||||
})
|
||||
export class PeriodDetailComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private ser = inject(PeriodService);
|
||||
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
itemResource = this.ser.get(this.id);
|
||||
|
||||
item = computed(() => this.itemResource.value() ?? new Period());
|
||||
|
||||
model = linkedSignal({
|
||||
source: this.item,
|
||||
computation: (item): PeriodFormData => ({
|
||||
|
||||
+1
-5
@@ -34,16 +34,12 @@ export interface ProductGroupDetailFormData {
|
||||
],
|
||||
})
|
||||
export class ProductGroupDetailComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private ser = inject(ProductGroupService);
|
||||
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
itemResource = this.ser.get(this.id);
|
||||
|
||||
item = computed(() => this.itemResource.value() ?? new ProductGroup());
|
||||
|
||||
model = linkedSignal({
|
||||
source: this.item,
|
||||
computation: (itemVal): ProductGroupDetailFormData => ({
|
||||
|
||||
@@ -27,7 +27,6 @@ import { ProductGroupService } from '../product-group.service';
|
||||
})
|
||||
export class ProductGroupListComponent {
|
||||
private ser = inject(ProductGroupService);
|
||||
|
||||
pageSize = signal(50);
|
||||
pageIndex = signal(0);
|
||||
sortActive = signal('');
|
||||
|
||||
@@ -32,7 +32,7 @@ export interface ProductDetailDialogFormData {
|
||||
],
|
||||
})
|
||||
export class ProductDetailDialogComponent {
|
||||
dialogRef = inject<MatDialogRef<ProductDetailDialogComponent>>(MatDialogRef);
|
||||
readonly dialogRef = inject<MatDialogRef<ProductDetailDialogComponent, StockKeepingUnit>>(MatDialogRef);
|
||||
data = inject<{
|
||||
item: StockKeepingUnit;
|
||||
isSold: boolean;
|
||||
|
||||
@@ -79,23 +79,19 @@ export interface ProductDetailFormModel {
|
||||
MatTableModule,
|
||||
MatIconModule,
|
||||
CurrencyPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
export class ProductDetailComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private ser = inject(ProductService);
|
||||
private pgSer = inject(ProductGroupService);
|
||||
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
itemResource = this.ser.get(this.id);
|
||||
item = linkedSignal(() => this.itemResource.value() ?? new Product());
|
||||
|
||||
formModel = linkedSignal<Product, ProductDetailFormModel>({
|
||||
source: this.item,
|
||||
computation: (itemVal): ProductDetailFormModel => ({
|
||||
|
||||
@@ -49,7 +49,6 @@ export interface ProductListFormData {
|
||||
MatPaginatorModule,
|
||||
PercentPipe,
|
||||
CurrencyPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -40,7 +40,6 @@ export interface ProfitLossFormData {
|
||||
MatSortModule,
|
||||
MatPaginatorModule,
|
||||
CurrencyPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
@@ -51,7 +50,6 @@ export class ProfitLossComponent {
|
||||
private ser = inject(ProfitLossService);
|
||||
pageSize = signal(50);
|
||||
pageIndex = signal(0);
|
||||
|
||||
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);
|
||||
|
||||
@@ -43,7 +43,6 @@ export interface PurchaseEntriesFormData {
|
||||
DecimalPipe,
|
||||
PercentPipe,
|
||||
CurrencyPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
@@ -52,12 +51,10 @@ export class PurchaseEntriesComponent {
|
||||
private route = inject(ActivatedRoute);
|
||||
private router = inject(Router);
|
||||
private ser = inject(PurchaseEntriesService);
|
||||
|
||||
pageSize = signal(50);
|
||||
pageIndex = signal(0);
|
||||
sortActive = signal('');
|
||||
sortDirection = signal('');
|
||||
|
||||
startDate = 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);
|
||||
|
||||
@@ -36,7 +36,7 @@ export interface PurchaseReturnDialogFormData {
|
||||
],
|
||||
})
|
||||
export class PurchaseReturnDialogComponent {
|
||||
dialogRef = inject<MatDialogRef<PurchaseReturnDialogComponent>>(MatDialogRef);
|
||||
readonly dialogRef = inject<MatDialogRef<PurchaseReturnDialogComponent, Inventory>>(MatDialogRef);
|
||||
data = inject<{
|
||||
inventory: Inventory;
|
||||
date: string;
|
||||
|
||||
@@ -207,9 +207,9 @@
|
||||
<span class="flex">
|
||||
Created on <strong>{{ form.creationDate().value() | localTime }}</strong
|
||||
> and Last Edited on <strong>{{ form.lastEditDate().value() | localTime }}</strong
|
||||
> by <strong>{{ form.userName() }}</strong
|
||||
> by <strong>{{ form.userName().value().name }}</strong
|
||||
>.
|
||||
{{ form.posted() ? 'Posted by ' + form.poster() : '' }}
|
||||
{{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -68,7 +68,7 @@ export interface PurchaseReturnFormModel {
|
||||
posted: boolean;
|
||||
creationDate: string;
|
||||
lastEditDate: string;
|
||||
userName: string;
|
||||
userName: User;
|
||||
poster: string;
|
||||
}
|
||||
|
||||
@@ -101,17 +101,11 @@ export interface PurchaseReturnFormModel {
|
||||
CurrencyPipe,
|
||||
AccountingPipe,
|
||||
LocalTimePipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
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 dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
@@ -122,10 +116,12 @@ export class PurchaseReturnComponent {
|
||||
private batchSer = inject(BatchService);
|
||||
private accountSer = inject(AccountService);
|
||||
private tagSer = inject(TagService);
|
||||
|
||||
sortActive = 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);
|
||||
item = linkedSignal(() => this.itemResource.value() ?? new Voucher());
|
||||
|
||||
@@ -161,7 +157,7 @@ export class PurchaseReturnComponent {
|
||||
posted: voucher.posted,
|
||||
creationDate: voucher.creationDate,
|
||||
lastEditDate: voucher.lastEditDate,
|
||||
userName: voucher.user?.name ?? '',
|
||||
userName: voucher.user ?? null,
|
||||
poster: voucher.poster ?? '',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -41,7 +41,7 @@ export interface PurchaseDialogFormData {
|
||||
],
|
||||
})
|
||||
export class PurchaseDialogComponent {
|
||||
dialogRef = inject<MatDialogRef<PurchaseDialogComponent>>(MatDialogRef);
|
||||
readonly dialogRef = inject<MatDialogRef<PurchaseDialogComponent, Inventory>>(MatDialogRef);
|
||||
data = inject<{
|
||||
inventory: Inventory;
|
||||
}>(MAT_DIALOG_DATA);
|
||||
|
||||
@@ -227,9 +227,9 @@
|
||||
<span class="flex">
|
||||
Created on <strong>{{ form.creationDate().value() | localTime }}</strong
|
||||
> and Last Edited on <strong>{{ form.lastEditDate().value() | localTime }}</strong
|
||||
> by <strong>{{ form.userName() }}</strong
|
||||
> by <strong>{{ form.userName().value().name }}</strong
|
||||
>.
|
||||
{{ form.posted() ? 'Posted by ' + form.poster() : '' }}
|
||||
{{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -73,7 +73,7 @@ export interface PurchaseFormModel {
|
||||
posted: boolean;
|
||||
creationDate: string;
|
||||
lastEditDate: string;
|
||||
userName: string;
|
||||
userName: User;
|
||||
poster: string;
|
||||
}
|
||||
|
||||
@@ -106,17 +106,11 @@ export interface PurchaseFormModel {
|
||||
CurrencyPipe,
|
||||
AccountingPipe,
|
||||
LocalTimePipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
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 dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
@@ -127,10 +121,12 @@ export class PurchaseComponent {
|
||||
private productSer = inject(ProductService);
|
||||
private accountSer = inject(AccountService);
|
||||
private tagSer = inject(TagService);
|
||||
|
||||
sortActive = 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);
|
||||
item = linkedSignal(() => this.itemResource.value() ?? new Voucher());
|
||||
|
||||
@@ -169,7 +165,7 @@ export class PurchaseComponent {
|
||||
posted: voucher.posted,
|
||||
creationDate: voucher.creationDate,
|
||||
lastEditDate: voucher.lastEditDate,
|
||||
userName: voucher.user?.name ?? '',
|
||||
userName: voucher.user ?? null,
|
||||
poster: voucher.poster ?? '',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -43,7 +43,6 @@ export interface PurchasesFormData {
|
||||
MatPaginatorModule,
|
||||
DecimalPipe,
|
||||
CurrencyPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -67,7 +67,6 @@ export interface RateContractDetailFormData {
|
||||
MatSortModule,
|
||||
MatIconModule,
|
||||
CurrencyPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -24,7 +24,6 @@ import { RateContractService } from '../rate-contract.service';
|
||||
MatPaginatorModule,
|
||||
CurrencyPipe,
|
||||
MatButtonModule,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -46,7 +46,6 @@ export interface RawMaterialCostFormData {
|
||||
DecimalPipe,
|
||||
PercentPipe,
|
||||
CurrencyPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -37,7 +37,7 @@ export interface ReceiptDialogFormData {
|
||||
],
|
||||
})
|
||||
export class ReceiptDialogComponent {
|
||||
dialogRef = inject<MatDialogRef<ReceiptDialogComponent>>(MatDialogRef);
|
||||
readonly dialogRef = inject<MatDialogRef<ReceiptDialogComponent, Journal>>(MatDialogRef);
|
||||
data = inject<{
|
||||
journal: Journal;
|
||||
date: string;
|
||||
|
||||
@@ -177,8 +177,8 @@
|
||||
<span class="flex">
|
||||
Created on <strong>{{ form.creationDate().value() | localTime }}</strong
|
||||
> and Last Edited on <strong>{{ form.lastEditDate().value() | localTime }}</strong
|
||||
> by <strong>{{ form.userName() }}</strong
|
||||
>. {{ form.posted() ? 'Posted by ' + form.poster() : '' }}
|
||||
> by <strong>{{ form.userName().value().name }}</strong
|
||||
>. {{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -65,7 +65,7 @@ export interface ReceiptFormModel {
|
||||
posted: boolean;
|
||||
creationDate: string;
|
||||
lastEditDate: string;
|
||||
userName: string;
|
||||
userName: User;
|
||||
poster: string;
|
||||
}
|
||||
|
||||
@@ -99,17 +99,11 @@ export interface ReceiptFormModel {
|
||||
CurrencyPipe,
|
||||
AccountingPipe,
|
||||
LocalTimePipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
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 dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
@@ -119,10 +113,12 @@ export class ReceiptComponent {
|
||||
private ser = inject(VoucherService);
|
||||
private accountSer = inject(AccountService);
|
||||
private tagSer = inject(TagService);
|
||||
|
||||
sortActive = 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);
|
||||
item = linkedSignal(() => this.itemResource.value() ?? new Voucher());
|
||||
|
||||
@@ -159,7 +155,7 @@ export class ReceiptComponent {
|
||||
posted: voucher.posted,
|
||||
creationDate: voucher.creationDate,
|
||||
lastEditDate: voucher.lastEditDate,
|
||||
userName: voucher.user?.name ?? '',
|
||||
userName: voucher.user ?? null,
|
||||
poster: voucher.poster ?? '',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -37,13 +37,11 @@ import { RecipeService } from '../recipe.service';
|
||||
MatSortModule,
|
||||
MatPaginatorModule,
|
||||
MatButtonModule,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
export class RecipeListComponent {
|
||||
p = input<string>();
|
||||
private ser = inject(RecipeService);
|
||||
private router = inject(Router);
|
||||
private periodSer = inject(PeriodService);
|
||||
@@ -54,6 +52,7 @@ export class RecipeListComponent {
|
||||
sortActive = signal('');
|
||||
sortDirection = signal('');
|
||||
|
||||
p = input<string>();
|
||||
model = signal({
|
||||
period: null as Period | null,
|
||||
productGroup: null as ProductGroup | string | null,
|
||||
|
||||
@@ -28,19 +28,17 @@ import { RoleService } from '../role.service';
|
||||
MatDividerModule,
|
||||
MatCheckboxModule,
|
||||
MatButtonModule,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
export class RoleDetailComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private dialog = inject(MatDialog);
|
||||
private ser = inject(RoleService);
|
||||
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
itemResource = this.ser.get(this.id);
|
||||
item = computed(() => this.itemResource.value() ?? new Role());
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/materia
|
||||
imports: [MatDialogModule, CdkScrollableModule, MatButtonModule],
|
||||
})
|
||||
export class ConfirmDialogComponent {
|
||||
dialogRef = inject<MatDialogRef<ConfirmDialogComponent>>(MatDialogRef);
|
||||
readonly dialogRef = inject<MatDialogRef<ConfirmDialogComponent>>(MatDialogRef);
|
||||
data = inject<{
|
||||
title: string;
|
||||
content: string;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
standalone: true,
|
||||
})
|
||||
export class ImageDialogComponent {
|
||||
dialogRef = inject<MatDialogRef<ImageDialogComponent>>(MatDialogRef);
|
||||
readonly dialogRef = inject<MatDialogRef<ImageDialogComponent>>(MatDialogRef);
|
||||
data = inject(MAT_DIALOG_DATA);
|
||||
|
||||
close(): void {
|
||||
|
||||
@@ -41,7 +41,6 @@ export interface StockMovementFormData {
|
||||
RouterModule,
|
||||
MatPaginatorModule,
|
||||
DecimalPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
@@ -55,6 +54,7 @@ export class StockMovementComponent {
|
||||
pageIndex = signal(0);
|
||||
sortActive = signal('');
|
||||
sortDirection = signal('');
|
||||
|
||||
startDate = 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 {
|
||||
dialogRef = inject<MatDialogRef<TagDialogComponent>>(MatDialogRef);
|
||||
readonly dialogRef = inject<MatDialogRef<TagDialogComponent>>(MatDialogRef);
|
||||
data = inject<{
|
||||
tags: Tag[];
|
||||
vouchers: LedgerItem[];
|
||||
|
||||
@@ -32,15 +32,13 @@ export interface TagDetailFormData {
|
||||
],
|
||||
})
|
||||
export class TagDetailComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private dialog = inject(MatDialog);
|
||||
private ser = inject(TagService);
|
||||
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
itemResource = this.ser.get(this.id);
|
||||
|
||||
item = computed(() => this.itemResource.value() ?? new Tag());
|
||||
|
||||
formModel = linkedSignal({
|
||||
|
||||
@@ -32,6 +32,7 @@ export class TagListComponent {
|
||||
pageIndex = signal(0);
|
||||
sortActive = signal('');
|
||||
sortDirection = signal('');
|
||||
|
||||
listResource = this.ser.list();
|
||||
list = computed(() => this.listResource.value() ?? []);
|
||||
sortedList = computed(() => {
|
||||
|
||||
+2
-3
@@ -127,20 +127,19 @@ function createEmptySkuForm(): TemporalProductSkuFormData {
|
||||
FormField,
|
||||
FormRoot,
|
||||
CurrencyPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
export class TemporalProductDetailComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private dialog = inject(MatDialog);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private ser = inject(TemporalProductService);
|
||||
private pgSer = inject(ProductGroupService);
|
||||
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
productDisplayedColumns = ['name', 'fractionUnits', 'productGroup', 'validFrom', 'validTill', 'actions'];
|
||||
skuDisplayedColumns = [
|
||||
'units',
|
||||
|
||||
-1
@@ -37,7 +37,6 @@ export interface TemporalProductListFormData {
|
||||
FormField,
|
||||
FormRoot,
|
||||
RouterLink,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -41,7 +41,6 @@ export interface TrialBalanceFormData {
|
||||
MatPaginatorModule,
|
||||
CurrencyPipe,
|
||||
AccountingPipe,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
|
||||
@@ -35,21 +35,18 @@ export interface UserDetailFormData {
|
||||
MatCheckboxModule,
|
||||
MatDividerModule,
|
||||
MatButtonModule,
|
||||
|
||||
SkeletonLoaderComponent,
|
||||
ErrorStateComponent,
|
||||
],
|
||||
})
|
||||
export class UserDetailComponent {
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
private router = inject(Router);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private dialog = inject(MatDialog);
|
||||
private ser = inject(UserService);
|
||||
|
||||
id = input(null, { transform: (v: string | null | undefined) => v ?? null });
|
||||
itemResource = this.ser.get(this.id);
|
||||
|
||||
item = computed(() => this.itemResource.value() ?? new User());
|
||||
|
||||
formModel = linkedSignal({
|
||||
|
||||
@@ -29,10 +29,12 @@ import { UserService } from '../user.service';
|
||||
})
|
||||
export class UserListComponent {
|
||||
private ser = inject(UserService);
|
||||
|
||||
pageSize = signal(50);
|
||||
pageIndex = signal(0);
|
||||
sortActive = signal('');
|
||||
sortDirection = signal('');
|
||||
|
||||
listResource = this.ser.list();
|
||||
list = computed(() => this.listResource.value() ?? []);
|
||||
sortedList = computed(() => {
|
||||
|
||||
+9
-1
@@ -3,6 +3,12 @@ set -euo pipefail
|
||||
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" || exit ; pwd -P )
|
||||
cd "$parent_path" || exit
|
||||
|
||||
last_commit_subject=$(git log -1 --format=%s)
|
||||
if [[ "$last_commit_subject" =~ ^Version\ Bump ]]; then
|
||||
echo "Last commit is already a version bump (\"$last_commit_subject\"). Nothing to do."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ 1 -eq "$#" ]
|
||||
then
|
||||
current_version=$(grep -m 1 '^version = ' brewman/pyproject.toml | sed -E 's/version = "([^"]+)"/\1/')
|
||||
@@ -31,7 +37,8 @@ then
|
||||
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
|
||||
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
|
||||
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
|
||||
@@ -43,4 +50,5 @@ else
|
||||
echo "Usage: $0 <major|minor|patch|version_string>"
|
||||
exit 1
|
||||
fi
|
||||
git push
|
||||
git push --tags
|
||||
|
||||
Reference in New Issue
Block a user