80 lines
2.3 KiB
TypeScript
80 lines
2.3 KiB
TypeScript
import { BankOperationKind } from './bank-operation-kind';
|
|
|
|
export type OperationFields = {
|
|
cardId: string;
|
|
categoryId?: null | string;
|
|
kind: BankOperationKind;
|
|
originalExpenseId?: null | string;
|
|
targetCardId?: null | string;
|
|
};
|
|
|
|
export enum OperationFieldRule {
|
|
InvalidCombination = 'invalidCombination',
|
|
MissingOriginalExpense = 'missingOriginalExpense',
|
|
MissingTargetCard = 'missingTargetCard',
|
|
SameTargetCard = 'sameTargetCard',
|
|
}
|
|
|
|
function transferConflict(fields: OperationFields): null | OperationFieldRule {
|
|
if (!fields.targetCardId) {
|
|
return OperationFieldRule.MissingTargetCard;
|
|
}
|
|
if (fields.targetCardId === fields.cardId) {
|
|
return OperationFieldRule.SameTargetCard;
|
|
}
|
|
if (fields.categoryId || fields.originalExpenseId) {
|
|
return OperationFieldRule.InvalidCombination;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function expenseConflict(fields: OperationFields): null | OperationFieldRule {
|
|
if (fields.originalExpenseId) {
|
|
return OperationFieldRule.InvalidCombination;
|
|
}
|
|
// Expense without a category uses the user's default category in the service.
|
|
return null;
|
|
}
|
|
|
|
function refundConflict(fields: OperationFields): null | OperationFieldRule {
|
|
return fields.originalExpenseId
|
|
? null
|
|
: OperationFieldRule.MissingOriginalExpense;
|
|
}
|
|
|
|
/**
|
|
* Pure kind/field compatibility rules for bank operations; no Prisma or Nest.
|
|
* Returns the first violated rule, or null when the combination is allowed.
|
|
*/
|
|
export function operationFieldConflict(
|
|
fields: OperationFields,
|
|
): null | OperationFieldRule {
|
|
if (fields.kind === BankOperationKind.Transfer) {
|
|
return transferConflict(fields);
|
|
}
|
|
if (fields.targetCardId) return OperationFieldRule.InvalidCombination;
|
|
if (fields.kind === BankOperationKind.Expense) {
|
|
return expenseConflict(fields);
|
|
}
|
|
if (fields.categoryId) return OperationFieldRule.InvalidCombination;
|
|
if (fields.kind === BankOperationKind.Refund) {
|
|
return refundConflict(fields);
|
|
}
|
|
// Topup: no target, no category, no purchase link.
|
|
return fields.originalExpenseId
|
|
? OperationFieldRule.InvalidCombination
|
|
: null;
|
|
}
|
|
|
|
export function operationKindChanged(
|
|
oldKind: string,
|
|
newKind: string,
|
|
oldOriginalExpenseId: null | string,
|
|
newOriginalExpenseId: null | string,
|
|
): boolean {
|
|
return (
|
|
oldKind !== newKind ||
|
|
oldOriginalExpenseId !== newOriginalExpenseId
|
|
);
|
|
}
|