添加信用额度功能:在账户模型中新增信用额度字段,更新相关请求和响应结构,修改账户创建和修改逻辑,更新界面以支持信用额度的显示和编辑。
This commit is contained in:
@@ -713,6 +713,9 @@ func (a *AccountsApi) createNewAccountModel(uid int64, accountCreateReq *models.
|
||||
|
||||
if !isSubAccount && accountCreateReq.Category == models.ACCOUNT_CATEGORY_CREDIT_CARD {
|
||||
accountExtend.CreditCardStatementDate = &accountCreateReq.CreditCardStatementDate
|
||||
if accountCreateReq.CreditLimit > 0 {
|
||||
accountExtend.CreditLimit = &accountCreateReq.CreditLimit
|
||||
}
|
||||
}
|
||||
|
||||
return &models.Account{
|
||||
@@ -769,6 +772,9 @@ func (a *AccountsApi) getToUpdateAccount(uid int64, accountModifyReq *models.Acc
|
||||
|
||||
if !isSubAccount && accountModifyReq.Category == models.ACCOUNT_CATEGORY_CREDIT_CARD {
|
||||
newAccountExtend.CreditCardStatementDate = &accountModifyReq.CreditCardStatementDate
|
||||
if accountModifyReq.CreditLimit > 0 {
|
||||
newAccountExtend.CreditLimit = &accountModifyReq.CreditLimit
|
||||
}
|
||||
}
|
||||
|
||||
newAccount := &models.Account{
|
||||
@@ -804,6 +810,12 @@ func (a *AccountsApi) getToUpdateAccount(uid int64, accountModifyReq *models.Acc
|
||||
return newAccount
|
||||
}
|
||||
|
||||
if newAccountExtend.CreditLimit != oldAccountExtend.CreditLimit {
|
||||
if newAccountExtend.CreditLimit == nil || oldAccountExtend.CreditLimit == nil || *newAccountExtend.CreditLimit != *oldAccountExtend.CreditLimit {
|
||||
return newAccount
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -90,7 +90,8 @@ type Account struct {
|
||||
|
||||
// AccountExtend represents account extend data stored in database
|
||||
type AccountExtend struct {
|
||||
CreditCardStatementDate *int `json:"creditCardStatementDate"`
|
||||
CreditCardStatementDate *int `json:"creditCardStatementDate"`
|
||||
CreditLimit *int64 `json:"creditLimit"`
|
||||
}
|
||||
|
||||
// AccountCreateRequest represents all parameters of account creation request
|
||||
@@ -105,6 +106,7 @@ type AccountCreateRequest struct {
|
||||
BalanceTime int64 `json:"balanceTime"`
|
||||
Comment string `json:"comment" binding:"max=255"`
|
||||
CreditCardStatementDate int `json:"creditCardStatementDate" binding:"min=0,max=28"`
|
||||
CreditLimit int64 `json:"creditLimit" binding:"min=0"`
|
||||
SubAccounts []*AccountCreateRequest `json:"subAccounts" binding:"omitempty"`
|
||||
ClientSessionId string `json:"clientSessionId"`
|
||||
}
|
||||
@@ -121,6 +123,7 @@ type AccountModifyRequest struct {
|
||||
BalanceTime *int64 `json:"balanceTime" binding:"omitempty"`
|
||||
Comment string `json:"comment" binding:"max=255"`
|
||||
CreditCardStatementDate int `json:"creditCardStatementDate" binding:"min=0,max=28"`
|
||||
CreditLimit int64 `json:"creditLimit" binding:"min=0"`
|
||||
Hidden bool `json:"hidden"`
|
||||
SubAccounts []*AccountModifyRequest `json:"subAccounts" binding:"omitempty"`
|
||||
ClientSessionId string `json:"clientSessionId"`
|
||||
@@ -171,6 +174,7 @@ type AccountInfoResponse struct {
|
||||
Balance int64 `json:"balance"`
|
||||
Comment string `json:"comment"`
|
||||
CreditCardStatementDate *int `json:"creditCardStatementDate,omitempty"`
|
||||
CreditLimit *int64 `json:"creditLimit,omitempty"`
|
||||
DisplayOrder int32 `json:"displayOrder"`
|
||||
IsAsset bool `json:"isAsset,omitempty"`
|
||||
IsLiability bool `json:"isLiability,omitempty"`
|
||||
@@ -181,10 +185,14 @@ type AccountInfoResponse struct {
|
||||
// ToAccountInfoResponse returns a view-object according to database model
|
||||
func (a *Account) ToAccountInfoResponse() *AccountInfoResponse {
|
||||
var creditCardStatementDate *int
|
||||
var creditLimit *int64
|
||||
|
||||
if a.ParentAccountId == LevelOneAccountParentId && a.Category == ACCOUNT_CATEGORY_CREDIT_CARD {
|
||||
if a.Extend != nil {
|
||||
creditCardStatementDate = a.Extend.CreditCardStatementDate
|
||||
if a.Extend.CreditLimit != nil && *a.Extend.CreditLimit > 0 {
|
||||
creditLimit = a.Extend.CreditLimit
|
||||
}
|
||||
} else {
|
||||
creditCardStatementDate = &defaultCreditCardAccountStatementDate
|
||||
}
|
||||
@@ -202,6 +210,7 @@ func (a *Account) ToAccountInfoResponse() *AccountInfoResponse {
|
||||
Balance: a.Balance,
|
||||
Comment: a.Comment,
|
||||
CreditCardStatementDate: creditCardStatementDate,
|
||||
CreditLimit: creditLimit,
|
||||
DisplayOrder: a.DisplayOrder,
|
||||
IsAsset: assetAccountCategory[a.Category],
|
||||
IsLiability: liabilityAccountCategory[a.Category],
|
||||
|
||||
@@ -1860,6 +1860,8 @@
|
||||
"Balance Time": "Balance Time",
|
||||
"Sub-account Balance Time": "Sub-account Balance Time",
|
||||
"Statement Date": "Statement Date",
|
||||
"Credit Limit": "Credit Limit",
|
||||
"Available": "Available",
|
||||
"Description": "Description",
|
||||
"Your account description (optional)": "Your account description (optional)",
|
||||
"Your sub-account description (optional)": "Your sub-account description (optional)",
|
||||
|
||||
@@ -1860,6 +1860,8 @@
|
||||
"Balance Time": "余额时间",
|
||||
"Sub-account Balance Time": "子账户余额时间",
|
||||
"Statement Date": "账单日",
|
||||
"Credit Limit": "信用额度",
|
||||
"Available": "可用额度",
|
||||
"Description": "描述",
|
||||
"Your account description (optional)": "你的账户描述 (可选)",
|
||||
"Your sub-account description (optional)": "你的子账户描述 (可选)",
|
||||
|
||||
+21
-6
@@ -17,6 +17,7 @@ export class Account implements AccountInfoResponse {
|
||||
public balanceTime?: number;
|
||||
public comment: string;
|
||||
public creditCardStatementDate?: number;
|
||||
public creditLimit?: number;
|
||||
public displayOrder: number;
|
||||
public visible: boolean;
|
||||
public subAccounts?: Account[];
|
||||
@@ -24,7 +25,7 @@ export class Account implements AccountInfoResponse {
|
||||
private readonly _isAsset?: boolean;
|
||||
private readonly _isLiability?: boolean;
|
||||
|
||||
protected constructor(id: string, name: string, parentId: string, category: number, type: number, icon: string, color: string, currency: string, balance: number, comment: string, displayOrder: number, visible: boolean, balanceTime?: number, creditCardStatementDate?: number, isAsset?: boolean, isLiability?: boolean, subAccounts?: Account[]) {
|
||||
protected constructor(id: string, name: string, parentId: string, category: number, type: number, icon: string, color: string, currency: string, balance: number, comment: string, displayOrder: number, visible: boolean, balanceTime?: number, creditCardStatementDate?: number, isAsset?: boolean, isLiability?: boolean, subAccounts?: Account[], creditLimit?: number) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.parentId = parentId;
|
||||
@@ -39,6 +40,7 @@ export class Account implements AccountInfoResponse {
|
||||
this.displayOrder = displayOrder;
|
||||
this.visible = visible;
|
||||
this.creditCardStatementDate = creditCardStatementDate;
|
||||
this.creditLimit = creditLimit;
|
||||
this._isAsset = isAsset;
|
||||
this._isLiability = isLiability;
|
||||
|
||||
@@ -95,7 +97,8 @@ export class Account implements AccountInfoResponse {
|
||||
this.comment === other.comment &&
|
||||
this.displayOrder === other.displayOrder &&
|
||||
this.visible === other.visible &&
|
||||
this.creditCardStatementDate === other.creditCardStatementDate;
|
||||
this.creditCardStatementDate === other.creditCardStatementDate &&
|
||||
this.creditLimit === other.creditLimit;
|
||||
|
||||
if (!isEqual) {
|
||||
return false;
|
||||
@@ -130,6 +133,7 @@ export class Account implements AccountInfoResponse {
|
||||
this.balanceTime = other.balanceTime;
|
||||
this.comment = other.comment;
|
||||
this.creditCardStatementDate = other.creditCardStatementDate;
|
||||
this.creditLimit = other.creditLimit;
|
||||
this.visible = other.visible;
|
||||
}
|
||||
|
||||
@@ -181,6 +185,7 @@ export class Account implements AccountInfoResponse {
|
||||
balanceTime: (parentAccount || this.type === AccountType.SingleAccount.type) && this.balanceTime ? this.balanceTime : 0,
|
||||
comment: this.comment,
|
||||
creditCardStatementDate: !parentAccount && this.category === AccountCategory.CreditCard.type ? this.creditCardStatementDate : undefined,
|
||||
creditLimit: !parentAccount && this.category === AccountCategory.CreditCard.type ? (this.creditLimit ?? 0) : undefined,
|
||||
subAccounts: !parentAccount ? subAccountCreateRequests : undefined,
|
||||
clientSessionId: !parentAccount ? clientSessionId : undefined
|
||||
};
|
||||
@@ -214,6 +219,7 @@ export class Account implements AccountInfoResponse {
|
||||
balanceTime: parentAccount && (!this.id || this.id === '0') ? this.balanceTime : undefined,
|
||||
comment: this.comment,
|
||||
creditCardStatementDate: !parentAccount && this.category === AccountCategory.CreditCard.type ? this.creditCardStatementDate : undefined,
|
||||
creditLimit: !parentAccount && this.category === AccountCategory.CreditCard.type ? (this.creditLimit ?? 0) : undefined,
|
||||
hidden: !this.visible,
|
||||
subAccounts: !parentAccount ? subAccountModifyRequests : undefined,
|
||||
clientSessionId: !parentAccount ? clientSessionId : undefined
|
||||
@@ -365,7 +371,9 @@ export class Account implements AccountInfoResponse {
|
||||
this.balanceTime,
|
||||
this.creditCardStatementDate,
|
||||
this.isAsset,
|
||||
this.isLiability
|
||||
this.isLiability,
|
||||
undefined,
|
||||
this.creditLimit
|
||||
);
|
||||
}
|
||||
|
||||
@@ -387,7 +395,9 @@ export class Account implements AccountInfoResponse {
|
||||
this.creditCardStatementDate,
|
||||
this.isAsset,
|
||||
this.isLiability,
|
||||
typeof(this.subAccounts) !== 'undefined' ? Account.cloneAccounts(this.subAccounts) : undefined);
|
||||
typeof(this.subAccounts) !== 'undefined' ? Account.cloneAccounts(this.subAccounts) : undefined,
|
||||
this.creditLimit
|
||||
);
|
||||
}
|
||||
|
||||
public createNewSubAccount(currency: string, balanceTime: number): Account {
|
||||
@@ -446,7 +456,8 @@ export class Account implements AccountInfoResponse {
|
||||
accountResponse.creditCardStatementDate,
|
||||
accountResponse.isAsset,
|
||||
accountResponse.isLiability,
|
||||
accountResponse.subAccounts ? Account.ofMulti(accountResponse.subAccounts) : undefined
|
||||
accountResponse.subAccounts ? Account.ofMulti(accountResponse.subAccounts) : undefined,
|
||||
accountResponse.creditLimit
|
||||
);
|
||||
}
|
||||
|
||||
@@ -560,7 +571,8 @@ export class AccountWithDisplayBalance extends Account {
|
||||
account.creditCardStatementDate,
|
||||
account.isAsset,
|
||||
account.isLiability,
|
||||
account.subAccounts
|
||||
account.subAccounts,
|
||||
account.creditLimit
|
||||
);
|
||||
|
||||
this.displayBalance = displayBalance;
|
||||
@@ -582,6 +594,7 @@ export interface AccountCreateRequest {
|
||||
readonly balanceTime: number;
|
||||
readonly comment: string;
|
||||
readonly creditCardStatementDate?: number;
|
||||
readonly creditLimit?: number;
|
||||
readonly subAccounts?: AccountCreateRequest[];
|
||||
readonly clientSessionId?: string;
|
||||
}
|
||||
@@ -597,6 +610,7 @@ export interface AccountModifyRequest {
|
||||
readonly balanceTime?: number;
|
||||
readonly comment: string;
|
||||
readonly creditCardStatementDate?: number;
|
||||
readonly creditLimit?: number;
|
||||
readonly hidden: boolean;
|
||||
readonly subAccounts?: AccountModifyRequest[];
|
||||
readonly clientSessionId?: string;
|
||||
@@ -614,6 +628,7 @@ export interface AccountInfoResponse {
|
||||
readonly balance: number;
|
||||
readonly comment: string;
|
||||
readonly creditCardStatementDate?: number;
|
||||
readonly creditLimit?: number;
|
||||
readonly displayOrder: number;
|
||||
readonly isAsset?: boolean;
|
||||
readonly isLiability?: boolean;
|
||||
|
||||
@@ -201,6 +201,24 @@
|
||||
</list-item-selection-popup>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item
|
||||
link="#" no-chevron
|
||||
class="list-item-with-header-and-title"
|
||||
:header="tt('Credit Limit')"
|
||||
:title="formatCreditLimitDisplay(account)"
|
||||
v-if="isAccountSupportCreditCardStatementDate"
|
||||
@click="accountContext.showCreditLimitSheet = true"
|
||||
>
|
||||
<number-pad-sheet :min-value="0"
|
||||
:max-value="TRANSACTION_MAX_AMOUNT"
|
||||
:currency="account.currency"
|
||||
:flip-negative="false"
|
||||
v-model:show="accountContext.showCreditLimitSheet"
|
||||
:model-value="account.creditLimit ?? 0"
|
||||
@update:model-value="account.creditLimit = $event > 0 ? $event : undefined"
|
||||
></number-pad-sheet>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item
|
||||
link="#" no-chevron
|
||||
class="list-item-with-header-and-title"
|
||||
@@ -334,6 +352,24 @@
|
||||
</list-item-selection-popup>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item
|
||||
link="#" no-chevron
|
||||
class="list-item-with-header-and-title"
|
||||
:header="tt('Credit Limit')"
|
||||
:title="formatCreditLimitDisplay(account)"
|
||||
v-if="isAccountSupportCreditCardStatementDate"
|
||||
@click="accountContext.showCreditLimitSheet = true"
|
||||
>
|
||||
<number-pad-sheet :min-value="0"
|
||||
:max-value="TRANSACTION_MAX_AMOUNT"
|
||||
:currency="account.currency"
|
||||
:flip-negative="false"
|
||||
v-model:show="accountContext.showCreditLimitSheet"
|
||||
:model-value="account.creditLimit ?? 0"
|
||||
@update:model-value="account.creditLimit = $event > 0 ? $event : undefined"
|
||||
></number-pad-sheet>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item :title="tt('Visible')" v-if="editAccountId">
|
||||
<f7-toggle :checked="account.visible" @toggle:change="account.visible = $event"></f7-toggle>
|
||||
</f7-list-item>
|
||||
@@ -550,6 +586,7 @@ interface AccountContext {
|
||||
showColorSelectionSheet: boolean;
|
||||
showCurrencyPopup: boolean;
|
||||
showCreditCardStatementDatePopup: boolean;
|
||||
showCreditLimitSheet: boolean;
|
||||
showBalanceSheet: boolean;
|
||||
showBalanceDateTimeSheet: boolean;
|
||||
balanceDateTimeSheetMode: string;
|
||||
@@ -600,6 +637,7 @@ const DEFAULT_ACCOUNT_CONTEXT: AccountContext = {
|
||||
showColorSelectionSheet: false,
|
||||
showCurrencyPopup: false,
|
||||
showCreditCardStatementDatePopup: false,
|
||||
showCreditLimitSheet: false,
|
||||
showBalanceSheet: false,
|
||||
showBalanceDateTimeSheet: false,
|
||||
balanceDateTimeSheetMode: 'time'
|
||||
@@ -621,6 +659,13 @@ function formatAccountDisplayBalance(selectedAccount: Account): string {
|
||||
return formatAmountToLocalizedNumeralsWithCurrency(balance, selectedAccount.currency);
|
||||
}
|
||||
|
||||
function formatCreditLimitDisplay(selectedAccount: Account): string {
|
||||
if (!selectedAccount.creditLimit) {
|
||||
return tt('Not set');
|
||||
}
|
||||
return formatAmountToLocalizedNumeralsWithCurrency(selectedAccount.creditLimit, selectedAccount.currency);
|
||||
}
|
||||
|
||||
function formatAccountBalanceDate(account: Account): string {
|
||||
if (!isDefined(account.balanceTime)) {
|
||||
return '';
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
<div class="nested-list-item-title">
|
||||
<span>{{ account.name }}</span>
|
||||
<div class="item-footer" v-if="account.comment">{{ account.comment }}</div>
|
||||
<div class="item-footer" v-if="account.creditLimit">{{ tt('Available') }}: {{ getRemainingCredit(account) }}</div>
|
||||
</div>
|
||||
<div class="nested-list-item-after" v-if="account.type === AccountType.MultiSubAccounts.type">
|
||||
<span>{{ accountBalance(account) }}</span>
|
||||
@@ -241,7 +242,7 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt, getCurrentLanguageTextDirection } = useI18n();
|
||||
const { tt, getCurrentLanguageTextDirection, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
|
||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const {
|
||||
@@ -288,6 +289,14 @@ const noAvailableAccount = computed<boolean>(() => {
|
||||
}
|
||||
});
|
||||
|
||||
function getRemainingCredit(account: Account): string {
|
||||
if (!account.creditLimit) {
|
||||
return '';
|
||||
}
|
||||
const remaining = account.creditLimit + account.balance; // balance is negative for credit cards
|
||||
return formatAmountToLocalizedNumeralsWithCurrency(remaining, account.currency);
|
||||
}
|
||||
|
||||
function hasAccount(accountCategory: AccountCategory, visibleOnly: boolean): boolean {
|
||||
return accountsStore.hasAccount(accountCategory, visibleOnly);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user