Compare commits

...
6 Commits
Author SHA1 Message Date
tanshu 15288b270a Version Bump v15.2.4 2026-08-29 17:08:09 +05:30
tanshu 5cfa02a6ef Fix user and poster not showing in vouchers 2026-08-29 11:37:54 +00:00
tanshu 4f89cd1161 Version Bump v15.2.3 2026-08-27 14:12:11 +05:30
tanshu 0d5012c961 incentive and closing stock fixed 2026-08-27 08:42:05 +00:00
tanshu e918644a5b Version Bump v15.2.2 2026-08-27 12:35:59 +05:30
tanshu eb7aa20def Closing Stock route sent date, but we were taking id as input. 2026-08-27 07:05:46 +00:00
28 changed files with 205 additions and 67 deletions
+61
View File
@@ -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
View File
@@ -1,5 +1,51 @@
# IDEs & System Files
.idea/ .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 # Ignore Pyright-generated stubs
*.pyi *.pyi
+18 -1
View File
@@ -27,19 +27,36 @@
"files.exclude": { "files.exclude": {
"**/__pycache__": true, "**/__pycache__": true,
"**/.mypy_cache": true, "**/.mypy_cache": true,
"**/.ruff_cache": true,
"**/.pytest_cache": true,
".idea": true, ".idea": true,
"**/node_modules": true, "**/node_modules": true,
"typings": true, "typings": true,
"frontend": true,
"**/.angular": true,
"**/.nx": true,
"**/out-tsc": true,
"**/dist": true,
"**/.sass-cache": true,
"**/coverage": true
}, },
"search.exclude": { "search.exclude": {
"**/__pycache__": true, "**/__pycache__": true,
"**/.mypy_cache": true, "**/.mypy_cache": true,
"**/.ruff_cache": true,
"**/.pytest_cache": true,
".idea": true, ".idea": true,
"**/node_modules": true, "**/node_modules": true,
"**/poetry.lock": true, "**/poetry.lock": true,
"**/package-lock.json": true, "**/package-lock.json": true,
"/overlord/.angular/**": true,
"typings": true, "typings": true,
"frontend/**": true,
"**/.angular/**": true,
"**/.nx/**": true,
"**/out-tsc/**": true,
"**/dist/**": true,
"**/.sass-cache/**": true,
"**/coverage/**": true
}, },
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll.ruff": "always", "source.fixAll.ruff": "always",
-1
View File
@@ -29,7 +29,6 @@ RUN \
else echo "Lockfile not found." && exit 1; \ else echo "Lockfile not found." && exit 1; \
fi fi
FROM python:3.14-slim AS runner FROM python:3.14-slim AS runner
LABEL maintainer="Amritanshu <docker@tanshu.com>" LABEL maintainer="Amritanshu <docker@tanshu.com>"
+1 -1
View File
@@ -1 +1 @@
__version__ = "15.2.1" __version__ = "15.2.4"
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "brewman" name = "brewman"
version = "15.2.1" version = "15.2.4"
description = "Accounting plus inventory management for a restaurant." description = "Accounting plus inventory management for a restaurant."
requires-python = ">=3.14" requires-python = ">=3.14"
authors = [{ name = "tanshu", email = "git@tanshu.com" }] authors = [{ name = "tanshu", email = "git@tanshu.com" }]
+1 -1
View File
@@ -211,7 +211,7 @@ wheels = [
[[package]] [[package]]
name = "brewman" name = "brewman"
version = "15.2.1" version = "15.2.4"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "alembic" }, { name = "alembic" },
+6 -6
View File
@@ -7,10 +7,10 @@ parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" || exit ; pwd -P )
cd "$parent_path/overlord" || exit cd "$parent_path/overlord" || exit
npx prettier --write src/app npx prettier --write src/app
npx ng lint --fix npx ng lint --fix
cd "$parent_path/brewman" || exit
uvx ruff format . cd "$parent_path/brewman" || exit
uvx ruff check . # Lint all files in the current directory (and any subdirectories) uv run ruff format .
uvx bandit --recursive brewman uv run ruff check . # Lint all files in the current directory (and any subdirectories)
uvx bandit --recursive . uv run bandit --recursive brewman
uvx safety check uv run bandit --recursive .
uv run safety check
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "overlord", "name": "overlord",
"version": "15.2.1", "version": "15.2.4",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve", "start": "ng serve",
+1 -1
View File
@@ -1,6 +1,6 @@
export const environment = { export const environment = {
ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry
version: '15.2.1', version: '15.2.4',
title: 'HnG / TGB', title: 'HnG / TGB',
}; };
@@ -13,7 +13,7 @@
<mat-label>Department</mat-label> <mat-label>Department</mat-label>
<mat-select [formField]="form.costCentre"> <mat-select [formField]="form.costCentre">
@for (at of costCentres(); track at) { @for (at of costCentres(); track at) {
<mat-option [value]="at.id"> <mat-option [value]="at">
{{ at.name }} {{ at.name }}
</mat-option> </mat-option>
} }
@@ -1,6 +1,6 @@
import { CurrencyPipe, DecimalPipe } from '@angular/common'; import { CurrencyPipe, DecimalPipe } from '@angular/common';
import { Component, inject, computed, input, linkedSignal, signal, afterNextRender } from '@angular/core'; 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 { MatButtonModule } from '@angular/material/button';
import { MatOptionModule } from '@angular/material/core'; import { MatOptionModule } from '@angular/material/core';
import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatDatepickerModule } from '@angular/material/datepicker';
@@ -72,11 +72,11 @@ export class ClosingStockComponent {
pageIndex = signal(0); pageIndex = signal(0);
sortActive = signal(''); sortActive = signal('');
sortDirection = 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 }); d = input(null, { transform: (v: string | null | undefined) => v ?? null });
startDate = input(null, { transform: (v: string | null | undefined) => v ?? null }); startDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
finishDate = input(null, { transform: (v: string | null | undefined) => v ?? null }); finishDate = input(null, { transform: (v: string | null | undefined) => v ?? null });
infoResource = this.ser.list(this.id, this.d); infoResource = this.ser.list(this.date, this.d);
info = computed(() => this.infoResource.value() ?? new ClosingStock()); info = computed(() => this.infoResource.value() ?? new ClosingStock());
costCentresResource = this.costCentreSer.list(); costCentresResource = this.costCentreSer.list();
@@ -94,7 +94,10 @@ export class ClosingStockComponent {
}), }),
}); });
form = createForm(this.model); form = createForm(this.model, (f) => {
required(f.costCentre);
required(f.date);
});
sortedList = computed(() => { sortedList = computed(() => {
const data = this.info().items ?? []; const data = this.info().items ?? [];
@@ -144,6 +147,9 @@ export class ClosingStockComponent {
} }
show() { show() {
if (this.form().invalid()) {
return;
}
const info = this.getInfo(); const info = this.getInfo();
this.router.navigate(['closing-stock', info.date], { this.router.navigate(['closing-stock', info.date], {
queryParams: { queryParams: {
@@ -180,7 +186,7 @@ export class ClosingStockComponent {
return new ClosingStock({ return new ClosingStock({
date: moment(formModel.date).format('DD-MMM-YYYY'), date: moment(formModel.date).format('DD-MMM-YYYY'),
costCentre: new CostCentre({ id: formModel.costCentre?.id ?? '' }), costCentre: formModel.costCentre ?? new CostCentre(),
}); });
} }
-4
View File
@@ -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> { post(id: string): Observable<Voucher> {
return this.http return this.http
.post<Voucher>(`${url}/post-voucher/${id}`, {}) .post<Voucher>(`${url}/post-voucher/${id}`, {})
@@ -21,7 +21,7 @@
<strong>{{ totalPoints() | number: '1.2-2' }}</strong> Point Value: <strong>{{ totalPoints() | number: '1.2-2' }}</strong> Point Value:
<strong>{{ pointValue() | number: '1.2-2' }}</strong> <strong>{{ pointValue() | number: '1.2-2' }}</strong>
</div> </div>
<mat-table #table [dataSource]="incentives()"> <mat-table #table [dataSource]="model().incentives">
<!-- Name Column --> <!-- Name Column -->
<ng-container matColumnDef="name"> <ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef>Name</mat-header-cell> <mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
@@ -1,5 +1,5 @@
import { CurrencyPipe, DecimalPipe } from '@angular/common'; 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 { form as createForm, FormField, FormRoot } from '@angular/forms/signals';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatDatepickerModule } from '@angular/material/datepicker'; 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'; import { LocalTimePipe } from '../shared/local-time.pipe';
export interface IncentiveFormData { export interface IncentiveFormData {
date: Date; date: moment.Moment;
incentives: { points: number }[]; incentives: Incentive[];
} }
@Component({ @Component({
@@ -55,19 +55,28 @@ export class IncentiveComponent {
auth = inject(AuthService); auth = inject(AuthService);
private ser = inject(VoucherService); private ser = inject(VoucherService);
id = input(null, { transform: (v: string | null | undefined) => v ?? null }); id = input(null, { transform: (v: string | null | undefined) => v ?? null });
voucherResource = this.ser.getVoucher(this.id, signal('Incentive'), signal(null), signal(null)); d = input(null, { transform: (v: string | null | undefined): string | null => v ?? null });
voucher = computed(() => this.voucherResource.value() ?? new Voucher()); 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({ model = linkedSignal({
source: this.voucher, source: this.voucher,
computation: (v): IncentiveFormData => ({ computation: (v): IncentiveFormData => ({
date: moment(v.date, 'DD-MMM-YYYY').toDate(), date: v.date ? moment(v.date, 'DD-MMM-YYYY') : moment(new Date()),
incentives: v.incentives.map((x) => ({ points: x.points })), incentives: v.incentives.map((x) => new Incentive({ ...x })),
}), }),
}); });
form = createForm(this.model); 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(); account: Account = new Account();
accBal: AccountBalance | null = null; accBal: AccountBalance | null = null;
@@ -80,9 +89,10 @@ export class IncentiveComponent {
} }
totalPoints = computed(() => { totalPoints = computed(() => {
return this.incentives() return this.model().incentives.reduce(
.map((item: Incentive, i: number) => item.daysWorked * (this.model().incentives[i]?.points ?? 0)) (sum: number, item: Incentive) => sum + item.daysWorked * (item.points ?? 0),
.reduce((sum: number, item: number) => sum + item, 0); 0,
);
}); });
pointValue = computed(() => { pointValue = computed(() => {
@@ -97,7 +107,7 @@ export class IncentiveComponent {
this.model.update((m) => { this.model.update((m) => {
const arr = [...m.incentives]; const arr = [...m.incentives];
if (arr[i]) { if (arr[i]) {
arr[i] = { ...arr[i], points: currentPoints - 1 }; arr[i] = new Incentive({ ...arr[i], points: currentPoints - 1 });
} }
return { ...m, incentives: arr }; return { ...m, incentives: arr };
}); });
@@ -109,7 +119,7 @@ export class IncentiveComponent {
this.model.update((m) => { this.model.update((m) => {
const arr = [...m.incentives]; const arr = [...m.incentives];
if (arr[i]) { if (arr[i]) {
arr[i] = { ...arr[i], points: currentPoints + 1 }; arr[i] = new Incentive({ ...arr[i], points: currentPoints + 1 });
} }
return { ...m, incentives: arr }; return { ...m, incentives: arr };
}); });
@@ -158,11 +168,7 @@ export class IncentiveComponent {
const formModel = this.model(); const formModel = this.model();
const v = this.voucher(); const v = this.voucher();
v.date = moment(formModel.date).format('DD-MMM-YYYY'); v.date = moment(formModel.date).format('DD-MMM-YYYY');
const array = formModel.incentives; v.incentives = formModel.incentives;
v.incentives.forEach((item: Incentive, index: number) => {
item.points = array[index]?.points ?? 0;
});
return v; return v;
} }
+2 -2
View File
@@ -134,9 +134,9 @@
<span class="flex"> <span class="flex">
Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong
>&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong >&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong
>&nbsp;by&nbsp; <strong>{{ form.userName() }}</strong >&nbsp;by&nbsp;<strong>{{ form.userName().value().name }}</strong
>. >.
{{ form.posted() ? 'Posted by ' + form.poster() : '' }} {{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
</span> </span>
} }
</div> </div>
+2 -2
View File
@@ -58,7 +58,7 @@ export interface IssueFormModel {
posted: boolean; posted: boolean;
creationDate: string; creationDate: string;
lastEditDate: string; lastEditDate: string;
userName: string; userName: User;
poster: string; poster: string;
} }
@@ -139,7 +139,7 @@ export class IssueComponent {
posted: voucher.posted, posted: voucher.posted,
creationDate: voucher.creationDate, creationDate: voucher.creationDate,
lastEditDate: voucher.lastEditDate, lastEditDate: voucher.lastEditDate,
userName: voucher.user?.name ?? '', userName: voucher.user ?? new User(),
poster: voucher.poster ?? '', poster: voucher.poster ?? '',
}; };
}, },
@@ -174,8 +174,8 @@
<span class="flex"> <span class="flex">
Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong
>&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong >&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong
>&nbsp;by&nbsp; <strong>{{ form.userName() }}</strong >&nbsp;by&nbsp;<strong>{{ form.userName().value().name }}</strong
>. {{ form.posted() ? 'Posted by ' + form.poster() : '' }} >. {{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
</span> </span>
} }
</div> </div>
@@ -26,6 +26,7 @@ import { AccountService } from '../core/account.service';
import { CostCentre } from '../core/cost-centre'; import { CostCentre } from '../core/cost-centre';
import { DbFile } from '../core/db-file'; import { DbFile } from '../core/db-file';
import { Journal } from '../core/journal'; import { Journal } from '../core/journal';
import { User } from '../core/user';
import { Voucher } from '../core/voucher'; import { Voucher } from '../core/voucher';
import { VoucherService } from '../core/voucher.service'; import { VoucherService } from '../core/voucher.service';
import { AccountingPipe } from '../shared/accounting.pipe'; import { AccountingPipe } from '../shared/accounting.pipe';
@@ -64,7 +65,7 @@ export interface JournalFormModel {
posted: boolean; posted: boolean;
creationDate: string; creationDate: string;
lastEditDate: string; lastEditDate: string;
userName: string; userName: User;
poster: string; poster: string;
} }
@@ -194,7 +195,7 @@ export class JournalComponent {
posted: voucher.posted, posted: voucher.posted,
creationDate: voucher.creationDate, creationDate: voucher.creationDate,
lastEditDate: voucher.lastEditDate, lastEditDate: voucher.lastEditDate,
userName: voucher.user?.name ?? '', userName: voucher.user ?? new User(),
poster: voucher.poster, poster: voucher.poster,
}), }),
}); });
@@ -182,9 +182,9 @@
<span class="flex"> <span class="flex">
Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong
>&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong >&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong
>&nbsp;by&nbsp; <strong>{{ form.userName() }}</strong >&nbsp;by&nbsp;<strong>{{ form.userName().value().name }}</strong
>. >.
{{ form.posted() ? 'Posted by ' + form.poster() : '' }} {{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
</span> </span>
} }
</div> </div>
@@ -65,7 +65,7 @@ export interface PaymentFormModel {
posted: boolean; posted: boolean;
creationDate: string; creationDate: string;
lastEditDate: string; lastEditDate: string;
userName: string; userName: User;
poster: string; poster: string;
} }
@@ -153,7 +153,7 @@ export class PaymentComponent {
posted: voucher.posted, posted: voucher.posted,
creationDate: voucher.creationDate, creationDate: voucher.creationDate,
lastEditDate: voucher.lastEditDate, lastEditDate: voucher.lastEditDate,
userName: voucher.user?.name ?? '', userName: voucher.user ?? new User(),
poster: voucher.poster ?? '', poster: voucher.poster ?? '',
}; };
}, },
@@ -207,9 +207,9 @@
<span class="flex"> <span class="flex">
Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong
>&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong >&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong
>&nbsp;by&nbsp; <strong>{{ form.userName() }}</strong >&nbsp;by&nbsp;<strong>{{ form.userName().value().name }}</strong
>. >.
{{ form.posted() ? 'Posted by ' + form.poster() : '' }} {{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
</span> </span>
} }
</div> </div>
@@ -68,7 +68,7 @@ export interface PurchaseReturnFormModel {
posted: boolean; posted: boolean;
creationDate: string; creationDate: string;
lastEditDate: string; lastEditDate: string;
userName: string; userName: User;
poster: string; poster: string;
} }
@@ -157,7 +157,7 @@ export class PurchaseReturnComponent {
posted: voucher.posted, posted: voucher.posted,
creationDate: voucher.creationDate, creationDate: voucher.creationDate,
lastEditDate: voucher.lastEditDate, lastEditDate: voucher.lastEditDate,
userName: voucher.user?.name ?? '', userName: voucher.user ?? null,
poster: voucher.poster ?? '', poster: voucher.poster ?? '',
}; };
}, },
@@ -227,9 +227,9 @@
<span class="flex"> <span class="flex">
Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong
>&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong >&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong
>&nbsp;by&nbsp; <strong>{{ form.userName() }}</strong >&nbsp;by&nbsp;<strong>{{ form.userName().value().name }}</strong
>. >.
{{ form.posted() ? 'Posted by ' + form.poster() : '' }} {{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
</span> </span>
} }
</div> </div>
@@ -73,7 +73,7 @@ export interface PurchaseFormModel {
posted: boolean; posted: boolean;
creationDate: string; creationDate: string;
lastEditDate: string; lastEditDate: string;
userName: string; userName: User;
poster: string; poster: string;
} }
@@ -165,7 +165,7 @@ export class PurchaseComponent {
posted: voucher.posted, posted: voucher.posted,
creationDate: voucher.creationDate, creationDate: voucher.creationDate,
lastEditDate: voucher.lastEditDate, lastEditDate: voucher.lastEditDate,
userName: voucher.user?.name ?? '', userName: voucher.user ?? null,
poster: voucher.poster ?? '', poster: voucher.poster ?? '',
}; };
}, },
@@ -177,8 +177,8 @@
<span class="flex"> <span class="flex">
Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong Created on&nbsp;<strong>{{ form.creationDate().value() | localTime }}</strong
>&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong >&nbsp;and Last Edited on&nbsp; <strong>{{ form.lastEditDate().value() | localTime }}</strong
>&nbsp;by&nbsp; <strong>{{ form.userName() }}</strong >&nbsp;by&nbsp;<strong>{{ form.userName().value().name }}</strong
>. {{ form.posted() ? 'Posted by ' + form.poster() : '' }} >. {{ form.posted().value() ? 'Posted by ' + form.poster().value() : '' }}
</span> </span>
} }
</div> </div>
@@ -65,7 +65,7 @@ export interface ReceiptFormModel {
posted: boolean; posted: boolean;
creationDate: string; creationDate: string;
lastEditDate: string; lastEditDate: string;
userName: string; userName: User;
poster: string; poster: string;
} }
@@ -155,7 +155,7 @@ export class ReceiptComponent {
posted: voucher.posted, posted: voucher.posted,
creationDate: voucher.creationDate, creationDate: voucher.creationDate,
lastEditDate: voucher.lastEditDate, lastEditDate: voucher.lastEditDate,
userName: voucher.user?.name ?? '', userName: voucher.user ?? null,
poster: voucher.poster ?? '', poster: voucher.poster ?? '',
}; };
}, },
+6
View File
@@ -3,6 +3,12 @@ set -euo pipefail
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" || exit ; pwd -P ) parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" || exit ; pwd -P )
cd "$parent_path" || exit 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 "$#" ] if [ 1 -eq "$#" ]
then then
current_version=$(grep -m 1 '^version = ' brewman/pyproject.toml | sed -E 's/version = "([^"]+)"/\1/') current_version=$(grep -m 1 '^version = ' brewman/pyproject.toml | sed -E 's/version = "([^"]+)"/\1/')