mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-19 17:24:26 +08:00
support filtering geographic location and pictures in insights explorer
This commit is contained in:
@@ -21,7 +21,9 @@ export enum TransactionExplorerConditionFieldType {
|
|||||||
DestinationAccount = 'destinationAccount',
|
DestinationAccount = 'destinationAccount',
|
||||||
SourceAmount = 'sourceAmount',
|
SourceAmount = 'sourceAmount',
|
||||||
DestinationAmount = 'destinationAmount',
|
DestinationAmount = 'destinationAmount',
|
||||||
|
GeoLocation = 'geoLocation',
|
||||||
TransactionTag = 'transactionTag',
|
TransactionTag = 'transactionTag',
|
||||||
|
Pictures = 'pictures',
|
||||||
Description = 'description'
|
Description = 'description'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +37,9 @@ export class TransactionExplorerConditionField implements NameValue {
|
|||||||
public static readonly DestinationAccount = new TransactionExplorerConditionField('Destination Account', TransactionExplorerConditionFieldType.DestinationAccount);
|
public static readonly DestinationAccount = new TransactionExplorerConditionField('Destination Account', TransactionExplorerConditionFieldType.DestinationAccount);
|
||||||
public static readonly SourceAmount = new TransactionExplorerConditionField('Amount', TransactionExplorerConditionFieldType.SourceAmount);
|
public static readonly SourceAmount = new TransactionExplorerConditionField('Amount', TransactionExplorerConditionFieldType.SourceAmount);
|
||||||
public static readonly DestinationAmount = new TransactionExplorerConditionField('Transfer In Amount', TransactionExplorerConditionFieldType.DestinationAmount);
|
public static readonly DestinationAmount = new TransactionExplorerConditionField('Transfer In Amount', TransactionExplorerConditionFieldType.DestinationAmount);
|
||||||
|
public static readonly GeoLocation = new TransactionExplorerConditionField('Geographic Location', TransactionExplorerConditionFieldType.GeoLocation);
|
||||||
public static readonly TransactionTag = new TransactionExplorerConditionField('Tags', TransactionExplorerConditionFieldType.TransactionTag);
|
public static readonly TransactionTag = new TransactionExplorerConditionField('Tags', TransactionExplorerConditionFieldType.TransactionTag);
|
||||||
|
public static readonly Pictures = new TransactionExplorerConditionField('Pictures', TransactionExplorerConditionFieldType.Pictures);
|
||||||
public static readonly Description = new TransactionExplorerConditionField('Description', TransactionExplorerConditionFieldType.Description);
|
public static readonly Description = new TransactionExplorerConditionField('Description', TransactionExplorerConditionFieldType.Description);
|
||||||
|
|
||||||
public readonly name: string;
|
public readonly name: string;
|
||||||
|
|||||||
+1
-1
@@ -509,7 +509,7 @@ export default {
|
|||||||
return axios.get<ApiResponse<TransactionInfoPageWrapperResponse2>>(`v1/transactions/list/by_month.json?year=${req.year}&month=${req.month}&type=${req.type}&category_ids=${req.categoryIds}&account_ids=${req.accountIds}&tag_filter=${tagFilter}&amount_filter=${amountFilter}&keyword=${keyword}&trim_account=true&trim_category=true&trim_tag=true`);
|
return axios.get<ApiResponse<TransactionInfoPageWrapperResponse2>>(`v1/transactions/list/by_month.json?year=${req.year}&month=${req.month}&type=${req.type}&category_ids=${req.categoryIds}&account_ids=${req.accountIds}&tag_filter=${tagFilter}&amount_filter=${amountFilter}&keyword=${keyword}&trim_account=true&trim_category=true&trim_tag=true`);
|
||||||
},
|
},
|
||||||
getAllTransactions: (req: TransactionAllListRequest): ApiResponsePromise<TransactionInfoResponse[]> => {
|
getAllTransactions: (req: TransactionAllListRequest): ApiResponsePromise<TransactionInfoResponse[]> => {
|
||||||
return axios.get<ApiResponse<TransactionInfoResponse[]>>(`v1/transactions/list/all.json?trim_account=true&trim_category=true&trim_tag=true&start_time=${req.startTime}&end_time=${req.endTime}`);
|
return axios.get<ApiResponse<TransactionInfoResponse[]>>(`v1/transactions/list/all.json?trim_account=true&with_pictures=${!!req.withPictures}&trim_category=true&trim_tag=true&start_time=${req.startTime}&end_time=${req.endTime}`);
|
||||||
},
|
},
|
||||||
getReconciliationStatements: (req: TransactionReconciliationStatementRequest): ApiResponsePromise<TransactionReconciliationStatementResponse> => {
|
getReconciliationStatements: (req: TransactionReconciliationStatementRequest): ApiResponsePromise<TransactionReconciliationStatementResponse> => {
|
||||||
return axios.get<ApiResponse<TransactionReconciliationStatementResponse>>(`v1/transactions/reconciliation_statements.json?account_id=${req.accountId}&start_time=${req.startTime}&end_time=${req.endTime}`);
|
return axios.get<ApiResponse<TransactionReconciliationStatementResponse>>(`v1/transactions/reconciliation_statements.json?account_id=${req.accountId}&start_time=${req.startTime}&end_time=${req.endTime}`);
|
||||||
|
|||||||
@@ -51,9 +51,15 @@ export class TransactionExplorerQuery {
|
|||||||
case TransactionExplorerConditionField.DestinationAmount:
|
case TransactionExplorerConditionField.DestinationAmount:
|
||||||
condition = new TransactionExplorerDestinationAmountCondition(TransactionExplorerConditionOperatorType.Between, [0, 0]);
|
condition = new TransactionExplorerDestinationAmountCondition(TransactionExplorerConditionOperatorType.Between, [0, 0]);
|
||||||
break;
|
break;
|
||||||
|
case TransactionExplorerConditionField.GeoLocation:
|
||||||
|
condition = new TransactionExplorerGeoLocationCondition(TransactionExplorerConditionOperatorType.IsNotEmpty, []);
|
||||||
|
break;
|
||||||
case TransactionExplorerConditionField.TransactionTag:
|
case TransactionExplorerConditionField.TransactionTag:
|
||||||
condition = new TransactionExplorerTransactionTagCondition(TransactionExplorerConditionOperatorType.HasAny, []);
|
condition = new TransactionExplorerTransactionTagCondition(TransactionExplorerConditionOperatorType.HasAny, []);
|
||||||
break;
|
break;
|
||||||
|
case TransactionExplorerConditionField.Pictures:
|
||||||
|
condition = new TransactionExplorerPicturesCondition(TransactionExplorerConditionOperatorType.IsNotEmpty, []);
|
||||||
|
break;
|
||||||
case TransactionExplorerConditionField.Description:
|
case TransactionExplorerConditionField.Description:
|
||||||
condition = new TransactionExplorerDescriptionCondition(TransactionExplorerConditionOperatorType.Contains, '');
|
condition = new TransactionExplorerDescriptionCondition(TransactionExplorerConditionOperatorType.Contains, '');
|
||||||
break;
|
break;
|
||||||
@@ -302,9 +308,15 @@ export class TransactionExplorerConditionWithRelation {
|
|||||||
case TransactionExplorerConditionField.DestinationAmount.value:
|
case TransactionExplorerConditionField.DestinationAmount.value:
|
||||||
operatorTypes = TransactionExplorerDestinationAmountCondition.supportedOperators;
|
operatorTypes = TransactionExplorerDestinationAmountCondition.supportedOperators;
|
||||||
break;
|
break;
|
||||||
|
case TransactionExplorerConditionField.GeoLocation.value:
|
||||||
|
operatorTypes = TransactionExplorerGeoLocationCondition.supportedOperators;
|
||||||
|
break;
|
||||||
case TransactionExplorerConditionField.TransactionTag.value:
|
case TransactionExplorerConditionField.TransactionTag.value:
|
||||||
operatorTypes = TransactionExplorerTransactionTagCondition.supportedOperators;
|
operatorTypes = TransactionExplorerTransactionTagCondition.supportedOperators;
|
||||||
break;
|
break;
|
||||||
|
case TransactionExplorerConditionField.Pictures.value:
|
||||||
|
operatorTypes = TransactionExplorerPicturesCondition.supportedOperators;
|
||||||
|
break;
|
||||||
case TransactionExplorerConditionField.Description.value:
|
case TransactionExplorerConditionField.Description.value:
|
||||||
operatorTypes = TransactionExplorerDescriptionCondition.supportedOperators;
|
operatorTypes = TransactionExplorerDescriptionCondition.supportedOperators;
|
||||||
break;
|
break;
|
||||||
@@ -385,11 +397,21 @@ export class TransactionExplorerConditionWithRelation {
|
|||||||
condition = new TransactionExplorerDestinationAmountCondition(conditionOperator as AmountConditionOperator, conditionValue as [number, number]);
|
condition = new TransactionExplorerDestinationAmountCondition(conditionOperator as AmountConditionOperator, conditionValue as [number, number]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TransactionExplorerConditionField.GeoLocation.value:
|
||||||
|
if (TransactionExplorerGeoLocationCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue)) {
|
||||||
|
condition = new TransactionExplorerGeoLocationCondition(conditionOperator as GeoLocationConditionOperator, conditionValue as string[]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TransactionExplorerConditionField.TransactionTag.value:
|
case TransactionExplorerConditionField.TransactionTag.value:
|
||||||
if (TransactionExplorerTransactionTagCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue)) {
|
if (TransactionExplorerTransactionTagCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue)) {
|
||||||
condition = new TransactionExplorerTransactionTagCondition(conditionOperator as TransactionTagConditionOperator, conditionValue as string[]);
|
condition = new TransactionExplorerTransactionTagCondition(conditionOperator as TransactionTagConditionOperator, conditionValue as string[]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TransactionExplorerConditionField.Pictures.value:
|
||||||
|
if (TransactionExplorerPicturesCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue)) {
|
||||||
|
condition = new TransactionExplorerPicturesCondition(conditionOperator as PicturesConditionOperator, conditionValue as string[]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TransactionExplorerConditionField.Description.value:
|
case TransactionExplorerConditionField.Description.value:
|
||||||
if (TransactionExplorerDescriptionCondition.supportedOperators[conditionOperator] && typeof conditionValue === 'string') {
|
if (TransactionExplorerDescriptionCondition.supportedOperators[conditionOperator] && typeof conditionValue === 'string') {
|
||||||
condition = new TransactionExplorerDescriptionCondition(conditionOperator as DescriptionConditionOperator, conditionValue);
|
condition = new TransactionExplorerDescriptionCondition(conditionOperator as DescriptionConditionOperator, conditionValue);
|
||||||
@@ -690,6 +712,53 @@ export class TransactionExplorerDestinationAmountCondition extends AbstractTrans
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GeoLocationConditionOperator = TransactionExplorerConditionOperatorType.IsEmpty |
|
||||||
|
TransactionExplorerConditionOperatorType.IsNotEmpty;
|
||||||
|
|
||||||
|
export class TransactionExplorerGeoLocationCondition implements TransactionExplorerCondition<TransactionExplorerConditionFieldType.GeoLocation, string[]> {
|
||||||
|
public static readonly supportedOperators: PartialRecord<TransactionExplorerConditionOperatorType, true> = {
|
||||||
|
[TransactionExplorerConditionOperatorType.IsEmpty]: true,
|
||||||
|
[TransactionExplorerConditionOperatorType.IsNotEmpty]: true
|
||||||
|
};
|
||||||
|
|
||||||
|
public readonly field = TransactionExplorerConditionFieldType.GeoLocation;
|
||||||
|
public readonly operator: GeoLocationConditionOperator = TransactionExplorerConditionOperatorType.IsNotEmpty;
|
||||||
|
public value: string[];
|
||||||
|
|
||||||
|
constructor(operator: GeoLocationConditionOperator, value: string[]) {
|
||||||
|
this.operator = operator;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValueForStore(): string[] {
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.IsEmpty || this.operator === TransactionExplorerConditionOperatorType.IsNotEmpty) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public match(transaction: TransactionInsightDataItem): boolean {
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.IsEmpty) {
|
||||||
|
return !transaction.geoLocation;
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.IsNotEmpty) {
|
||||||
|
return !!transaction.geoLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toExpression(): string {
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.IsEmpty) {
|
||||||
|
return `geo_location IS EMPTY`;
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.IsNotEmpty) {
|
||||||
|
return `geo_location IS NOT EMPTY`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type TransactionTagConditionOperator = TransactionExplorerConditionOperatorType.IsEmpty |
|
type TransactionTagConditionOperator = TransactionExplorerConditionOperatorType.IsEmpty |
|
||||||
TransactionExplorerConditionOperatorType.IsNotEmpty |
|
TransactionExplorerConditionOperatorType.IsNotEmpty |
|
||||||
TransactionExplorerConditionOperatorType.Equals |
|
TransactionExplorerConditionOperatorType.Equals |
|
||||||
@@ -825,6 +894,53 @@ export class TransactionExplorerTransactionTagCondition implements TransactionEx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PicturesConditionOperator = TransactionExplorerConditionOperatorType.IsEmpty |
|
||||||
|
TransactionExplorerConditionOperatorType.IsNotEmpty;
|
||||||
|
|
||||||
|
export class TransactionExplorerPicturesCondition implements TransactionExplorerCondition<TransactionExplorerConditionFieldType.Pictures, string[]> {
|
||||||
|
public static readonly supportedOperators: PartialRecord<TransactionExplorerConditionOperatorType, true> = {
|
||||||
|
[TransactionExplorerConditionOperatorType.IsEmpty]: true,
|
||||||
|
[TransactionExplorerConditionOperatorType.IsNotEmpty]: true
|
||||||
|
};
|
||||||
|
|
||||||
|
public readonly field = TransactionExplorerConditionFieldType.Pictures;
|
||||||
|
public readonly operator: PicturesConditionOperator = TransactionExplorerConditionOperatorType.IsNotEmpty;
|
||||||
|
public value: string[];
|
||||||
|
|
||||||
|
constructor(operator: PicturesConditionOperator, value: string[]) {
|
||||||
|
this.operator = operator;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValueForStore(): string[] {
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.IsEmpty || this.operator === TransactionExplorerConditionOperatorType.IsNotEmpty) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public match(transaction: TransactionInsightDataItem): boolean {
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.IsEmpty) {
|
||||||
|
return !transaction.pictures || transaction.pictures.length < 1;
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.IsNotEmpty) {
|
||||||
|
return !!transaction.pictures && transaction.pictures.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toExpression(): string {
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.IsEmpty) {
|
||||||
|
return `pictures IS EMPTY`;
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.IsNotEmpty) {
|
||||||
|
return `pictures IS NOT EMPTY`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type DescriptionConditionOperator = TransactionExplorerConditionOperatorType.IsEmpty |
|
type DescriptionConditionOperator = TransactionExplorerConditionOperatorType.IsEmpty |
|
||||||
TransactionExplorerConditionOperatorType.IsNotEmpty |
|
TransactionExplorerConditionOperatorType.IsNotEmpty |
|
||||||
TransactionExplorerConditionOperatorType.Equals |
|
TransactionExplorerConditionOperatorType.Equals |
|
||||||
|
|||||||
@@ -600,6 +600,7 @@ export interface TransactionListInMonthByPageRequest {
|
|||||||
export interface TransactionAllListRequest {
|
export interface TransactionAllListRequest {
|
||||||
readonly startTime: number;
|
readonly startTime: number;
|
||||||
readonly endTime: number;
|
readonly endTime: number;
|
||||||
|
readonly withPictures?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TransactionReconciliationStatementRequest {
|
export interface TransactionReconciliationStatementRequest {
|
||||||
|
|||||||
@@ -857,7 +857,8 @@ export const useExplorersStore = defineStore('explorers', () => {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
services.getAllTransactions({
|
services.getAllTransactions({
|
||||||
startTime: transactionExplorerFilter.value.startTime,
|
startTime: transactionExplorerFilter.value.startTime,
|
||||||
endTime: transactionExplorerFilter.value.endTime
|
endTime: transactionExplorerFilter.value.endTime,
|
||||||
|
withPictures: true
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
const data = response.data;
|
const data = response.data;
|
||||||
|
|
||||||
|
|||||||
@@ -221,6 +221,11 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<v-text-field disabled density="compact"
|
||||||
|
:placeholder="tt('None')"
|
||||||
|
v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.GeoLocation.value"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="d-flex w-100" v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.TransactionTag.value">
|
<div class="d-flex w-100" v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.TransactionTag.value">
|
||||||
<v-text-field
|
<v-text-field
|
||||||
disabled
|
disabled
|
||||||
@@ -283,6 +288,11 @@
|
|||||||
</v-autocomplete>
|
</v-autocomplete>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<v-text-field disabled density="compact"
|
||||||
|
:placeholder="tt('None')"
|
||||||
|
v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.Pictures.value"
|
||||||
|
/>
|
||||||
|
|
||||||
<v-text-field disabled density="compact"
|
<v-text-field disabled density="compact"
|
||||||
:placeholder="tt('None')"
|
:placeholder="tt('None')"
|
||||||
v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.Description.value &&
|
v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.Description.value &&
|
||||||
|
|||||||
Reference in New Issue
Block a user