Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76975d88f3 | ||
|
|
8c189cac21 | ||
|
|
985993f273 | ||
|
|
3df19b7eb8 | ||
|
|
09b11e7e79 | ||
|
|
15288b270a | ||
|
|
5cfa02a6ef | ||
|
|
4f89cd1161 | ||
|
|
0d5012c961 |
@@ -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
+32
-4
@@ -1,13 +1,24 @@
|
||||
{
|
||||
// Use WSL paths + Poetry venv interpreter
|
||||
"python.defaultInterpreterPath": "${workspaceFolder}/brewman/.venv/bin/python",
|
||||
"python.defaultInterpreterPath": "/brewman/.venv/bin/python",
|
||||
"python.terminal.useEnvFile": true,
|
||||
"python.venvFolders": [
|
||||
"barker/.venv",
|
||||
"frank/.venv",
|
||||
".venv"
|
||||
],
|
||||
"python.venvPath": "${workspaceFolder}/barker",
|
||||
"python.terminal.activateEnvironment": true,
|
||||
// Quality-of-life
|
||||
// Quality-of-life
|
||||
/* --- Pylance: keep IntelliSense, disable type checking --- */
|
||||
// "python.analysis.typeCheckingMode": "off",
|
||||
// "python.analysis.diagnosticMode": "openFilesOnly",
|
||||
"python.analysis.typeCheckingMode": "basic",
|
||||
"python.analysis.extraPaths": [
|
||||
"${workspaceFolder}/brewman",
|
||||
"./brewman"
|
||||
],
|
||||
"python.autoComplete.extraPaths": [
|
||||
"${workspaceFolder}/brewman",
|
||||
"./brewman"
|
||||
],
|
||||
// Ruff (you have ruff installed via poetry)
|
||||
@@ -27,19 +38,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>"
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "15.2.2"
|
||||
__version__ = "15.2.6"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "brewman"
|
||||
version = "15.2.2"
|
||||
version = "15.2.6"
|
||||
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.2.2"
|
||||
version = "15.2.6"
|
||||
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
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "overlord",
|
||||
"version": "15.2.2",
|
||||
"version": "15.2.6",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
|
||||
@@ -10,7 +10,7 @@ import { MomentDateAdapter } from '@angular/material-moment-adapter';
|
||||
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
|
||||
import { MAT_SNACK_BAR_DEFAULT_OPTIONS } from '@angular/material/snack-bar';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { provideRouter, withComponentInputBinding, withRouterConfig } from '@angular/router';
|
||||
import { provideRouter, withComponentInputBinding } from '@angular/router';
|
||||
|
||||
import { dateFormat } from './app.environment';
|
||||
import { routes } from './app.routes';
|
||||
@@ -33,13 +33,7 @@ export const appConfig: ApplicationConfig = {
|
||||
...(isDevMode() ? [delayInterceptor] : []),
|
||||
]),
|
||||
),
|
||||
provideRouter(
|
||||
routes,
|
||||
withRouterConfig({
|
||||
onSameUrlNavigation: 'reload',
|
||||
}),
|
||||
withComponentInputBinding(),
|
||||
),
|
||||
provideRouter(routes, withComponentInputBinding()),
|
||||
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
|
||||
{ provide: MAT_DATE_FORMATS, useValue: dateFormat },
|
||||
{ provide: MAT_SNACK_BAR_DEFAULT_OPTIONS, useValue: { duration: 3000 } },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export const environment = {
|
||||
ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry
|
||||
version: '15.2.2',
|
||||
version: '15.2.6',
|
||||
title: 'HnG / TGB',
|
||||
};
|
||||
|
||||
|
||||
@@ -99,7 +99,11 @@ export class AttendanceComponent {
|
||||
|
||||
show() {
|
||||
const date = moment(this.model().date).format('DD-MMM-YYYY');
|
||||
this.router.navigate(['/attendance', date]);
|
||||
if (this.date() === date) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['/attendance', date]);
|
||||
}
|
||||
}
|
||||
|
||||
save() {
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Attendance',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':date',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Attendance',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -112,7 +112,11 @@ export class BalanceSheetComponent {
|
||||
|
||||
show() {
|
||||
const date = this.getDate();
|
||||
this.router.navigate(['balance-sheet', date]);
|
||||
if (this.date() === date) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['balance-sheet', date]);
|
||||
}
|
||||
}
|
||||
|
||||
getDate(): string {
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Balance Sheet',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':date',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Balance Sheet',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Product Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -105,12 +105,16 @@ export class CashFlowComponent {
|
||||
|
||||
show() {
|
||||
const info = this.getInfo();
|
||||
this.router.navigate(['cash-flow'], {
|
||||
queryParams: {
|
||||
startDate: info.startDate,
|
||||
finishDate: info.finishDate,
|
||||
},
|
||||
});
|
||||
if (this.startDate() === info.startDate && this.finishDate() === info.finishDate) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['cash-flow'], {
|
||||
queryParams: {
|
||||
startDate: info.startDate,
|
||||
finishDate: info.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getInfo(): CashFlow {
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Cash Flow',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Cash Flow',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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';
|
||||
@@ -94,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 ?? [];
|
||||
@@ -144,12 +147,19 @@ export class ClosingStockComponent {
|
||||
}
|
||||
|
||||
show() {
|
||||
if (this.form().invalid()) {
|
||||
return;
|
||||
}
|
||||
const info = this.getInfo();
|
||||
this.router.navigate(['closing-stock', info.date], {
|
||||
queryParams: {
|
||||
d: info.costCentre.id,
|
||||
},
|
||||
});
|
||||
if (this.date() === info.date && this.d() === info.costCentre.id) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['closing-stock', info.date], {
|
||||
queryParams: {
|
||||
d: info.costCentre.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
save() {
|
||||
@@ -180,7 +190,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(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Closing Stock',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':date',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Closing Stock',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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}`, {})
|
||||
|
||||
@@ -127,12 +127,16 @@ export class DaybookComponent {
|
||||
|
||||
show() {
|
||||
const l = this.prepareSubmit();
|
||||
this.router.navigate(['daybook'], {
|
||||
queryParams: {
|
||||
startDate: l.startDate,
|
||||
finishDate: l.finishDate,
|
||||
},
|
||||
});
|
||||
if (this.startDate() === l.startDate && this.finishDate() === l.finishDate) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['daybook'], {
|
||||
queryParams: {
|
||||
startDate: l.startDate,
|
||||
finishDate: l.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
prepareSubmit(): Daybook {
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Daybook',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -126,12 +126,20 @@ export class EmployeeAttendanceComponent {
|
||||
currentInfo.employee =
|
||||
typeof formValue.employee !== 'string' && formValue.employee ? formValue.employee : undefined;
|
||||
if (currentInfo.employee) {
|
||||
this.router.navigate(['/employee-attendance', currentInfo.employee.id], {
|
||||
queryParams: {
|
||||
startDate: currentInfo.startDate,
|
||||
finishDate: currentInfo.finishDate,
|
||||
},
|
||||
});
|
||||
if (
|
||||
this.id() === currentInfo.employee.id &&
|
||||
this.startDate() === currentInfo.startDate &&
|
||||
this.finishDate() === currentInfo.finishDate
|
||||
) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['/employee-attendance', currentInfo.employee.id], {
|
||||
queryParams: {
|
||||
startDate: currentInfo.startDate,
|
||||
finishDate: currentInfo.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Attendance',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Attendance',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'employee-benefit',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'employee-benefit',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'employee-benefit',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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({
|
||||
@@ -55,19 +55,28 @@ export class IncentiveComponent {
|
||||
auth = inject(AuthService);
|
||||
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));
|
||||
voucher = computed(() => this.voucherResource.value() ?? new Voucher());
|
||||
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;
|
||||
@@ -80,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(() => {
|
||||
@@ -97,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 };
|
||||
});
|
||||
@@ -109,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 };
|
||||
});
|
||||
@@ -158,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'incentive',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'incentive',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -139,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 ?? '',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Issue',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Issue',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -194,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,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Journal',
|
||||
},
|
||||
runGuardsAndResolvers: 'paramsChange',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Journal',
|
||||
},
|
||||
runGuardsAndResolvers: 'paramsChange',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -260,7 +260,13 @@ export class LedgerComponent {
|
||||
|
||||
show() {
|
||||
const info = this.getInfo();
|
||||
if (info.account) {
|
||||
if (
|
||||
this.id() === info.account?.id &&
|
||||
this.startDate() === info.startDate &&
|
||||
this.finishDate() === info.finishDate
|
||||
) {
|
||||
this.infoResource.reload();
|
||||
} else if (info.account) {
|
||||
this.router.navigate(['ledger', info.account.id], {
|
||||
queryParams: {
|
||||
startDate: info.startDate,
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -111,7 +111,11 @@ export class MozimoDailyRegisterComponent {
|
||||
|
||||
show() {
|
||||
const date = moment(this.model().date).format('DD-MMM-YYYY');
|
||||
this.router.navigate(['/mozimo-daily-register', date]);
|
||||
if (this.date() === date) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['/mozimo-daily-register', date]);
|
||||
}
|
||||
}
|
||||
|
||||
save() {
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Product Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':date',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Product Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -136,12 +136,20 @@ export class MozimoProductRegisterComponent {
|
||||
show() {
|
||||
const info = this.getInfo();
|
||||
if (info.product) {
|
||||
this.router.navigate(['mozimo-product-register', info.product.id], {
|
||||
queryParams: {
|
||||
startDate: info.startDate,
|
||||
finishDate: info.finishDate,
|
||||
},
|
||||
});
|
||||
if (
|
||||
this.id() === info.product.id &&
|
||||
this.startDate() === info.startDate &&
|
||||
this.finishDate() === info.finishDate
|
||||
) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['mozimo-product-register', info.product.id], {
|
||||
queryParams: {
|
||||
startDate: info.startDate,
|
||||
finishDate: info.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Product Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Product Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -117,12 +117,16 @@ export class NetTransactionsComponent {
|
||||
|
||||
show() {
|
||||
const l = this.prepareSubmit();
|
||||
this.router.navigate(['net-transactions'], {
|
||||
queryParams: {
|
||||
startDate: l.startDate,
|
||||
finishDate: l.finishDate,
|
||||
},
|
||||
});
|
||||
if (this.startDate() === l.startDate && this.finishDate() === l.finishDate) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['net-transactions'], {
|
||||
queryParams: {
|
||||
startDate: l.startDate,
|
||||
finishDate: l.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
prepareSubmit(): NetTransactions {
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Net Transactions',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Product Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -153,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 ?? '',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'journal',
|
||||
},
|
||||
runGuardsAndResolvers: 'paramsChange',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'journal',
|
||||
},
|
||||
runGuardsAndResolvers: 'paramsChange',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -211,12 +211,20 @@ export class ProductLedgerComponent {
|
||||
show() {
|
||||
const info = this.getInfo();
|
||||
if (info.product) {
|
||||
this.router.navigate(['product-ledger', info.product.id], {
|
||||
queryParams: {
|
||||
startDate: info.startDate,
|
||||
finishDate: info.finishDate,
|
||||
},
|
||||
});
|
||||
if (
|
||||
this.id() === info.product.id &&
|
||||
this.startDate() === info.startDate &&
|
||||
this.finishDate() === info.finishDate
|
||||
) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['product-ledger', info.product.id], {
|
||||
queryParams: {
|
||||
startDate: info.startDate,
|
||||
finishDate: info.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Product Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Product Ledger',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -117,12 +117,16 @@ export class ProfitLossComponent {
|
||||
|
||||
show() {
|
||||
const info = this.getInfo();
|
||||
this.router.navigate(['profit-loss'], {
|
||||
queryParams: {
|
||||
startDate: info.startDate,
|
||||
finishDate: info.finishDate,
|
||||
},
|
||||
});
|
||||
if (this.startDate() === info.startDate && this.finishDate() === info.finishDate) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['profit-loss'], {
|
||||
queryParams: {
|
||||
startDate: info.startDate,
|
||||
finishDate: info.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getInfo(): ProfitLoss {
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Profit & Loss',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -121,12 +121,16 @@ export class PurchaseEntriesComponent {
|
||||
|
||||
show() {
|
||||
const l = this.prepareSubmit();
|
||||
this.router.navigate(['purchase-entries'], {
|
||||
queryParams: {
|
||||
startDate: l.startDate,
|
||||
finishDate: l.finishDate,
|
||||
},
|
||||
});
|
||||
if (this.startDate() === l.startDate && this.finishDate() === l.finishDate) {
|
||||
this.resource.reload();
|
||||
} else {
|
||||
this.router.navigate(['purchase-entries'], {
|
||||
queryParams: {
|
||||
startDate: l.startDate,
|
||||
finishDate: l.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
prepareSubmit(): PurchaseEntries {
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Purchase Entries',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -157,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 ?? '',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Purchase Return',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Purchase Return',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -165,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 ?? '',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Purchase',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Purchase',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -115,12 +115,16 @@ export class PurchasesComponent {
|
||||
|
||||
show() {
|
||||
const l = this.prepareSubmit();
|
||||
this.router.navigate(['purchases'], {
|
||||
queryParams: {
|
||||
startDate: l.startDate,
|
||||
finishDate: l.finishDate,
|
||||
},
|
||||
});
|
||||
if (this.startDate() === l.startDate && this.finishDate() === l.finishDate) {
|
||||
this.resource.reload();
|
||||
} else {
|
||||
this.router.navigate(['purchases'], {
|
||||
queryParams: {
|
||||
startDate: l.startDate,
|
||||
finishDate: l.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
prepareSubmit(): Purchases {
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Purchases',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -131,12 +131,16 @@ export class RawMaterialCostComponent {
|
||||
|
||||
show() {
|
||||
const model = this.prepareSubmit();
|
||||
this.router.navigate(['raw-material-cost'], {
|
||||
queryParams: {
|
||||
startDate: model.startDate,
|
||||
finishDate: model.finishDate,
|
||||
},
|
||||
});
|
||||
if (!this.id() && this.startDate() === model.startDate && this.finishDate() === model.finishDate) {
|
||||
this.infoResource.reload();
|
||||
} else {
|
||||
this.router.navigate(['raw-material-cost'], {
|
||||
queryParams: {
|
||||
startDate: model.startDate,
|
||||
finishDate: model.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
prepareSubmit(): RawMaterialCost {
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Raw Material Cost',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Raw Material Cost',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -155,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 ?? '',
|
||||
};
|
||||
},
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'journal',
|
||||
},
|
||||
runGuardsAndResolvers: 'paramsChange',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'journal',
|
||||
},
|
||||
runGuardsAndResolvers: 'paramsChange',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
<div class="row-container">
|
||||
<mat-form-field class="flex-auto">
|
||||
<mat-select [formField]="form.period">
|
||||
@for (p of periods(); track p.id) {
|
||||
<mat-option [value]="p"> {{ p.validFrom }} to {{ p.validTill }} </mat-option>
|
||||
@for (p of periods(); track p) {
|
||||
<mat-option [value]="p.id"> {{ p.validFrom }} to {{ p.validTill }} </mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-auto">
|
||||
<mat-label>Product Type</mat-label>
|
||||
<mat-select [formField]="form.productGroup" (selectionChange)="filterProductGroup($event.value)">
|
||||
<mat-option>-- All Products --</mat-option>
|
||||
@for (mc of productGroups(); track mc.id) {
|
||||
<mat-select [formField]="form.productGroup">
|
||||
<mat-option [value]="null">-- All Products --</mat-option>
|
||||
@for (mc of productGroups(); track mc) {
|
||||
<mat-option [value]="mc.id">
|
||||
{{ mc.name }}
|
||||
</mat-option>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, inject, input, computed, effect, signal } from '@angular/core';
|
||||
import { Component, inject, input, computed, effect, signal, linkedSignal } from '@angular/core';
|
||||
import { form as createForm, FormField, FormRoot } from '@angular/forms/signals';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatOptionModule } from '@angular/material/core';
|
||||
@@ -11,7 +11,6 @@ import { MatSortModule, Sort } from '@angular/material/sort';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { Router, RouterModule } from '@angular/router';
|
||||
|
||||
import { ProductGroup } from '../../core/product-group';
|
||||
import { Period } from '../../period/period';
|
||||
import { PeriodService } from '../../period/period.service';
|
||||
import { ProductGroupService } from '../../product-group/product-group.service';
|
||||
@@ -19,6 +18,10 @@ import { ErrorStateComponent } from '../../shared/error-state/error-state.compon
|
||||
import { SkeletonLoaderComponent } from '../../shared/skeleton-loader/skeleton-loader.component';
|
||||
import { RecipeService } from '../recipe.service';
|
||||
|
||||
export interface RecipeListFormData {
|
||||
period: string | null;
|
||||
productGroup: string | null;
|
||||
}
|
||||
@Component({
|
||||
selector: 'app-recipe-list',
|
||||
templateUrl: './recipe-list.component.html',
|
||||
@@ -52,31 +55,34 @@ export class RecipeListComponent {
|
||||
sortActive = signal('');
|
||||
sortDirection = signal('');
|
||||
|
||||
p = input<string>();
|
||||
model = signal({
|
||||
period: null as Period | null,
|
||||
productGroup: null as ProductGroup | string | null,
|
||||
});
|
||||
|
||||
form = createForm(this.model);
|
||||
p = input('', { transform: (v: string | null | undefined) => v ?? null });
|
||||
|
||||
periodsResource = this.periodSer.list();
|
||||
periods = computed(() => this.periodsResource.value() ?? []);
|
||||
|
||||
model = linkedSignal<string | null, RecipeListFormData>({
|
||||
source: () => this.p(),
|
||||
computation: (period) => ({
|
||||
period: period,
|
||||
productGroup: null,
|
||||
}),
|
||||
});
|
||||
|
||||
form = createForm(this.model);
|
||||
|
||||
productGroupsResource = this.productGroupSer.list();
|
||||
productGroups = computed(() => this.productGroupsResource.value() ?? []);
|
||||
|
||||
periodFilter = computed(() => this.p() || '');
|
||||
resource = this.ser.list(this.periodFilter);
|
||||
resource = this.ser.list(this.p);
|
||||
productGroupFilter = computed(() => this.model().productGroup ?? null);
|
||||
|
||||
info = computed(() => this.resource.value() ?? []);
|
||||
sortedList = computed(() => {
|
||||
let data = this.info() ?? [];
|
||||
|
||||
const pg = this.model().productGroup;
|
||||
const pg = this.productGroupFilter();
|
||||
if (pg) {
|
||||
const pgId = typeof pg === 'string' ? pg : pg.id;
|
||||
data = data.filter((r) => r.productGroupId === pgId);
|
||||
data = data.filter((r) => r.productGroupId === pg);
|
||||
}
|
||||
|
||||
const active = this.sortActive();
|
||||
@@ -118,18 +124,13 @@ export class RecipeListComponent {
|
||||
const x = this.model().period;
|
||||
if (!x) return;
|
||||
this.router.navigate([], {
|
||||
queryParams: { p: x.id },
|
||||
queryParams: { p: x },
|
||||
replaceUrl: true,
|
||||
queryParamsHandling: 'merge',
|
||||
});
|
||||
this.period = x;
|
||||
});
|
||||
}
|
||||
|
||||
filterProductGroup(val: string) {
|
||||
this.model.update((m) => ({ ...m, productGroup: val }));
|
||||
}
|
||||
|
||||
handlePageEvent(e: PageEvent) {
|
||||
this.pageSize.set(e.pageSize);
|
||||
this.pageIndex.set(e.pageIndex);
|
||||
|
||||
@@ -12,7 +12,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Recipes',
|
||||
},
|
||||
runGuardsAndResolvers: 'paramsOrQueryParamsChange',
|
||||
},
|
||||
{
|
||||
path: 'new',
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Maintenance', // 'Lock Date'
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -114,12 +114,16 @@ export class StockMovementComponent {
|
||||
|
||||
show() {
|
||||
const l = this.prepareSubmit();
|
||||
this.router.navigate(['stock-movement'], {
|
||||
queryParams: {
|
||||
startDate: l.startDate,
|
||||
finishDate: l.finishDate,
|
||||
},
|
||||
});
|
||||
if (this.startDate() === l.startDate && this.finishDate() === l.finishDate) {
|
||||
this.resource.reload();
|
||||
} else {
|
||||
this.router.navigate(['stock-movement'], {
|
||||
queryParams: {
|
||||
startDate: l.startDate,
|
||||
finishDate: l.finishDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
prepareSubmit(): StockMovement {
|
||||
|
||||
@@ -11,6 +11,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Stock Movement',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
<mat-form-field class="flex-auto basis-30">
|
||||
<mat-label>Product Group</mat-label>
|
||||
<mat-select [formField]="form.productGroup">
|
||||
<mat-option>-- All Products --</mat-option>
|
||||
<mat-option [value]="null">-- All Products --</mat-option>
|
||||
@for (pg of productGroups(); track pg) {
|
||||
<mat-option [value]="pg.id">
|
||||
{{ pg.name }}
|
||||
|
||||
+4
-10
@@ -9,7 +9,6 @@ import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
||||
|
||||
import { Product, StockKeepingUnit } from '../../core/product';
|
||||
import { ProductGroupService } from '../../product-group/product-group.service';
|
||||
import { ErrorStateComponent } from '../../shared/error-state/error-state.component';
|
||||
import { SkeletonLoaderComponent } from '../../shared/skeleton-loader/skeleton-loader.component';
|
||||
@@ -18,7 +17,7 @@ import { TemporalProductService } from '../temporal-product.service';
|
||||
|
||||
export interface TemporalProductListFormData {
|
||||
filter: string;
|
||||
productGroup: Product | StockKeepingUnit | string | null;
|
||||
productGroup: string | null;
|
||||
}
|
||||
|
||||
@Component({
|
||||
@@ -66,16 +65,11 @@ export class TemporalProductListComponent {
|
||||
form = createForm(this.formModel);
|
||||
filterSignal = computed(() => this.formModel().filter);
|
||||
debouncedFilter = debounced(this.filterSignal, 150);
|
||||
productGroupFilter = computed(() => this.formModel().productGroup ?? null);
|
||||
filteredList = computed(() => {
|
||||
const data = this.list();
|
||||
const search = this.debouncedFilter.value() ?? '';
|
||||
const productGroup = this.formModel().productGroup;
|
||||
const groupId =
|
||||
typeof productGroup === 'string'
|
||||
? productGroup
|
||||
: productGroup && 'id' in productGroup
|
||||
? (productGroup.id ?? '')
|
||||
: '';
|
||||
const productGroup = this.productGroupFilter();
|
||||
|
||||
const tokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
||||
|
||||
@@ -97,7 +91,7 @@ export class TemporalProductListComponent {
|
||||
}),
|
||||
);
|
||||
|
||||
const matchesProductGroup = !groupId || products.some((k) => (k.productGroup?.id ?? '') === groupId);
|
||||
const matchesProductGroup = !productGroup || products.some((k) => k.productGroup?.id === productGroup);
|
||||
return matchesSearch && matchesProductGroup;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -109,7 +109,11 @@ export class TrialBalanceComponent {
|
||||
|
||||
show() {
|
||||
const info = this.getInfo();
|
||||
this.router.navigate(['trial-balance', info.date]);
|
||||
if (this.date() === info.date) {
|
||||
this.resource.reload();
|
||||
} else {
|
||||
this.router.navigate(['trial-balance', info.date]);
|
||||
}
|
||||
}
|
||||
|
||||
getInfo(): TrialBalance {
|
||||
|
||||
@@ -11,7 +11,6 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Trial Balance',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':date',
|
||||
@@ -20,6 +19,5 @@ export const routes: Routes = [
|
||||
data: {
|
||||
permission: 'Trial Balance',
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -32,12 +32,12 @@ a
|
||||
text-decoration: underline
|
||||
|
||||
|
||||
button.mat-primary
|
||||
button.mat-primary:not(:disabled)
|
||||
background: var(--mat-sys-primary) !important
|
||||
color: var(--mat-sys-on-primary) !important
|
||||
|
||||
|
||||
button.mat-warn
|
||||
button.mat-warn:not(:disabled)
|
||||
background: var(--mat-sys-error) !important
|
||||
color: var(--mat-sys-on-error) !important
|
||||
|
||||
|
||||
@@ -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/')
|
||||
|
||||
Reference in New Issue
Block a user