chore: save pending changes
This commit is contained in:
@@ -0,0 +1 @@
|
||||
ALTER TABLE "BankCard" ADD COLUMN "paymentSystem" TEXT CHECK ("paymentSystem" IN ('mir', 'visa', 'mastercard'));
|
||||
@@ -47,6 +47,7 @@ model BankCard {
|
||||
name String
|
||||
bankName String?
|
||||
lastFour String?
|
||||
paymentSystem String?
|
||||
openingBalanceKopecks BigInt
|
||||
openingDate String
|
||||
version Int @default(1)
|
||||
|
||||
@@ -25,6 +25,7 @@ import { MoneyDto } from '../common/money.dto';
|
||||
|
||||
const trim = ({ value }: { value: unknown }) =>
|
||||
typeof value === 'string' ? value.trim() : value;
|
||||
export const bankPaymentSystems = ['mir', 'visa', 'mastercard'] as const;
|
||||
export const bankOperationKinds = [
|
||||
'expense',
|
||||
'topup',
|
||||
@@ -57,6 +58,10 @@ export class CreateBankCardDto {
|
||||
@IsOptional()
|
||||
@Matches(/^[0-9]{4}$/)
|
||||
lastFour?: string | null;
|
||||
@ApiPropertyOptional({ enum: bankPaymentSystems, nullable: true })
|
||||
@IsOptional()
|
||||
@IsIn(bankPaymentSystems)
|
||||
paymentSystem?: string | null;
|
||||
@ApiProperty({ type: RubMoneyInputDto })
|
||||
@IsDefined()
|
||||
@ValidateNested()
|
||||
@@ -180,6 +185,8 @@ export class BankCardDto {
|
||||
@ApiProperty({ type: String }) name: string;
|
||||
@ApiProperty({ type: String, nullable: true }) bankName: string | null;
|
||||
@ApiProperty({ type: String, nullable: true }) lastFour: string | null;
|
||||
@ApiProperty({ enum: bankPaymentSystems, nullable: true }) paymentSystem:
|
||||
string | null;
|
||||
@ApiProperty({ type: MoneyDto }) openingBalance: MoneyDto;
|
||||
@ApiProperty({ type: String }) openingDate: string;
|
||||
@ApiProperty({ type: MoneyDto }) balance: MoneyDto;
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
moscowToday,
|
||||
} from './bank-card.calculations';
|
||||
import {
|
||||
bankPaymentSystems,
|
||||
BankCardDto,
|
||||
BankOperationDto,
|
||||
BankOperationsQueryDto,
|
||||
@@ -84,7 +85,13 @@ function cardInput(dto: CreateBankCardDto) {
|
||||
const bankName = dto.bankName?.trim() || null;
|
||||
if (bankName && bankName.length > 100) fail();
|
||||
if (dto.lastFour != null && !/^\d{4}$/.test(dto.lastFour)) fail();
|
||||
if (
|
||||
dto.paymentSystem != null &&
|
||||
!bankPaymentSystems.some((system) => system === dto.paymentSystem)
|
||||
)
|
||||
fail();
|
||||
return {
|
||||
...(dto.paymentSystem == null ? {} : { paymentSystem: dto.paymentSystem }),
|
||||
name: name(dto.name, 100),
|
||||
bankName,
|
||||
lastFour: dto.lastFour || null,
|
||||
@@ -180,6 +187,7 @@ export class BankCardsService {
|
||||
name: card.name,
|
||||
bankName: card.bankName,
|
||||
lastFour: card.lastFour,
|
||||
paymentSystem: card.paymentSystem,
|
||||
openingDate: card.openingDate,
|
||||
openingBalance: rubMoney(card.openingBalanceKopecks),
|
||||
balance: rubMoney(bankBalance(card.id, card.openingBalanceKopecks, rows)),
|
||||
@@ -292,6 +300,10 @@ export class BankCardsService {
|
||||
dto.lastFour === undefined
|
||||
? (previous.lastFour ?? undefined)
|
||||
: (dto.lastFour ?? undefined),
|
||||
paymentSystem:
|
||||
dto.paymentSystem === undefined
|
||||
? previous.paymentSystem
|
||||
: dto.paymentSystem,
|
||||
openingBalance:
|
||||
dto.openingBalance ?? rubMoney(previous.openingBalanceKopecks),
|
||||
openingDate: dto.openingDate ?? previous.openingDate,
|
||||
@@ -316,6 +328,7 @@ export class BankCardsService {
|
||||
where: { id, userId, version: dto.version },
|
||||
data: {
|
||||
...input,
|
||||
paymentSystem: input.paymentSystem ?? null,
|
||||
version: { increment: 1 },
|
||||
...(dto.archived === undefined
|
||||
? {}
|
||||
|
||||
@@ -709,4 +709,28 @@ describe('Manual bank cards configured HTTP and real SQLite', () => {
|
||||
}),
|
||||
).rejects.toMatchObject({ code: 'P2002' });
|
||||
});
|
||||
it('persists payment systems, preserves omitted metadata and allows clearing', async () => {
|
||||
const card = await createCard('1000', owner, { paymentSystem: 'mir' });
|
||||
expect((await getCard(card.id)).paymentSystem).toBe('mir');
|
||||
await auth('patch', '/' + card.id)
|
||||
.send({ version: 1, name: 'Renamed' })
|
||||
.expect(200);
|
||||
expect((await getCard(card.id)).paymentSystem).toBe('mir');
|
||||
await auth('patch', '/' + card.id)
|
||||
.send({ version: 2, paymentSystem: 'visa' })
|
||||
.expect(200);
|
||||
expect((await getCard(card.id)).paymentSystem).toBe('visa');
|
||||
await auth('patch', '/' + card.id)
|
||||
.send({ version: 3, paymentSystem: 'unknown' })
|
||||
.expect(400);
|
||||
await auth('patch', '/' + card.id)
|
||||
.send({ version: 3, paymentSystem: null })
|
||||
.expect(200);
|
||||
expect((await getCard(card.id)).paymentSystem).toBeNull();
|
||||
expect((await createCard()).paymentSystem).toBeNull();
|
||||
expect(
|
||||
(await createCard('1000', owner, { paymentSystem: 'mastercard' }))
|
||||
.paymentSystem,
|
||||
).toBe('mastercard');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user