From b768f18294c6c572152cd2b46355740e869ecc61 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Mon, 19 Aug 2024 13:08:09 +0200 Subject: [PATCH 1/3] chore: change subscription prices --- .../webapp/src/constants/subscriptionModels.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/webapp/src/constants/subscriptionModels.tsx b/packages/webapp/src/constants/subscriptionModels.tsx index e1a6ba35c..736fa6b35 100644 --- a/packages/webapp/src/constants/subscriptionModels.tsx +++ b/packages/webapp/src/constants/subscriptionModels.tsx @@ -44,9 +44,9 @@ export const SubscriptionPlans = [ }, { text: 'Unlimited User Seats' }, ], - monthlyPrice: '$10', + monthlyPrice: '$20', monthlyPriceLabel: 'Per month', - annuallyPrice: '$7.5', + annuallyPrice: '$15', annuallyPriceLabel: 'Per month', monthlyVariantId: '446152', // monthlyVariantId: '450016', @@ -78,9 +78,9 @@ export const SubscriptionPlans = [ { text: 'Smart Financial Reports' }, { text: 'Advanced Inventory Reports' }, ], - monthlyPrice: '$20', + monthlyPrice: '$40', monthlyPriceLabel: 'Per month', - annuallyPrice: '$15', + annuallyPrice: '$30', annuallyPriceLabel: 'Per month', // monthlyVariantId: '450028', monthlyVariantId: '446155', @@ -101,9 +101,9 @@ export const SubscriptionPlans = [ }, { text: 'Analysis Cost Center' }, ], - monthlyPrice: '$25', + monthlyPrice: '$55', monthlyPriceLabel: 'Per month', - annuallyPrice: '$19', + annuallyPrice: '$40', annuallyPriceLabel: 'Per month', featured: true, // monthlyVariantId: '450031', @@ -128,9 +128,9 @@ export const SubscriptionPlans = [ hint: 'Track the organization inventory in multiple warehouses and transfer goods between them.', }, ], - monthlyPrice: '$40', + monthlyPrice: '$60', monthlyPriceLabel: 'Per month', - annuallyPrice: '$30', + annuallyPrice: '$45', annuallyPriceLabel: 'Per month', // monthlyVariantId: '450024', monthlyVariantId: '446167', From 8b90ce5f6cbe7b8206541b3019329e81922a8b06 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Wed, 21 Aug 2024 19:32:59 +0200 Subject: [PATCH 2/3] fix: cannot import items income and cost accounts --- packages/server/src/models/Item.Settings.ts | 8 ++--- .../server/src/services/Items/CreateItem.ts | 10 ++++++ .../server/src/services/Items/EditItem.ts | 10 ++++++ .../src/services/Items/ItemValidators.ts | 36 +++++++++++++++++++ .../server/src/services/Items/constants.ts | 5 +++ 5 files changed, 65 insertions(+), 4 deletions(-) diff --git a/packages/server/src/models/Item.Settings.ts b/packages/server/src/models/Item.Settings.ts index af8968366..2c88be0d5 100644 --- a/packages/server/src/models/Item.Settings.ts +++ b/packages/server/src/models/Item.Settings.ts @@ -257,25 +257,25 @@ export default { name: 'item.field.sell_price', fieldType: 'number', }, - cost_price: { + costPrice: { name: 'item.field.cost_price', fieldType: 'number', }, - costAccount: { + costAccountId: { name: 'item.field.cost_account', fieldType: 'relation', relationModel: 'Account', relationImportMatch: ['name', 'code'], importHint: 'Matches the account name or code.', }, - sellAccount: { + sellAccountId: { name: 'item.field.sell_account', fieldType: 'relation', relationModel: 'Account', relationImportMatch: ['name', 'code'], importHint: 'Matches the account name or code.', }, - inventoryAccount: { + inventoryAccountId: { name: 'item.field.inventory_account', fieldType: 'relation', relationModel: 'Account', diff --git a/packages/server/src/services/Items/CreateItem.ts b/packages/server/src/services/Items/CreateItem.ts index 5de01aec9..3ce935ee3 100644 --- a/packages/server/src/services/Items/CreateItem.ts +++ b/packages/server/src/services/Items/CreateItem.ts @@ -43,12 +43,22 @@ export class CreateItem { itemDTO.sellAccountId ); } + // Validate the income account id existance if the item is sellable. + this.validators.validateIncomeAccountExistance( + itemDTO.sellable, + itemDTO.sellAccountId + ); if (itemDTO.costAccountId) { await this.validators.validateItemCostAccountExistance( tenantId, itemDTO.costAccountId ); } + // Validate the cost account id existance if the item is purchasable. + this.validators.validateCostAccountExistance( + itemDTO.purchasable, + itemDTO.costAccountId + ); if (itemDTO.inventoryAccountId) { await this.validators.validateItemInventoryAccountExistance( tenantId, diff --git a/packages/server/src/services/Items/EditItem.ts b/packages/server/src/services/Items/EditItem.ts index 6e230921f..17ac8240e 100644 --- a/packages/server/src/services/Items/EditItem.ts +++ b/packages/server/src/services/Items/EditItem.ts @@ -55,6 +55,11 @@ export class EditItem { itemDTO.categoryId ); } + // Validate the income account id existance if the item is sellable. + this.validators.validateIncomeAccountExistance( + itemDTO.sellable, + itemDTO.sellAccountId + ); // Validate the sell account existance on the storage. if (itemDTO.sellAccountId) { await this.validators.validateItemSellAccountExistance( @@ -62,6 +67,11 @@ export class EditItem { itemDTO.sellAccountId ); } + // Validate the cost account id existance if the item is purchasable. + this.validators.validateCostAccountExistance( + itemDTO.purchasable, + itemDTO.costAccountId + ); // Validate the cost account existance on the storage. if (itemDTO.costAccountId) { await this.validators.validateItemCostAccountExistance( diff --git a/packages/server/src/services/Items/ItemValidators.ts b/packages/server/src/services/Items/ItemValidators.ts index c81ac9c7e..3468ad1d0 100644 --- a/packages/server/src/services/Items/ItemValidators.ts +++ b/packages/server/src/services/Items/ItemValidators.ts @@ -85,6 +85,42 @@ export class ItemsValidators { } } + /** + * Validates income account existance. + * @param {number|null} sellable - Detarmines if the item sellable. + * @param {number|null} incomeAccountId - Income account id. + * @throws {ServiceError(ERRORS.INCOME_ACCOUNT_REQUIRED_WITH_SELLABLE_ITEM)} + */ + public validateIncomeAccountExistance( + sellable?: boolean, + incomeAccountId?: number + ) { + if (sellable && !incomeAccountId) { + throw new ServiceError( + ERRORS.INCOME_ACCOUNT_REQUIRED_WITH_SELLABLE_ITEM, + 'Income account is require with sellable item.' + ); + } + } + + /** + * Validates the cost account existance. + * @param {boolean|null} purchasable - Detarmines if the item purchasble. + * @param {number|null} costAccountId - Cost account id. + * @throws {ServiceError(ERRORS.COST_ACCOUNT_REQUIRED_WITH_PURCHASABLE_ITEM)} + */ + public validateCostAccountExistance( + purchasable: boolean, + costAccountId?: number + ) { + if (purchasable && !costAccountId) { + throw new ServiceError( + ERRORS.COST_ACCOUNT_REQUIRED_WITH_PURCHASABLE_ITEM, + 'The cost account is required with purchasable item.' + ); + } + } + /** * Validate item inventory account existance and type. * @param {number} tenantId diff --git a/packages/server/src/services/Items/constants.ts b/packages/server/src/services/Items/constants.ts index 3d571c527..9b4089687 100644 --- a/packages/server/src/services/Items/constants.ts +++ b/packages/server/src/services/Items/constants.ts @@ -26,6 +26,11 @@ export const ERRORS = { PURCHASE_TAX_RATE_NOT_FOUND: 'PURCHASE_TAX_RATE_NOT_FOUND', SELL_TAX_RATE_NOT_FOUND: 'SELL_TAX_RATE_NOT_FOUND', + + INCOME_ACCOUNT_REQUIRED_WITH_SELLABLE_ITEM: + 'INCOME_ACCOUNT_REQUIRED_WITH_SELLABLE_ITEM', + COST_ACCOUNT_REQUIRED_WITH_PURCHASABLE_ITEM: + 'COST_ACCOUNT_REQUIRED_WITH_PURCHASABLE_ITEM', }; export const DEFAULT_VIEW_COLUMNS = []; From dffcfe50aa1b74d78c6fd83e5ec6ea62950063d2 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Wed, 21 Aug 2024 21:19:59 +0200 Subject: [PATCH 3/3] fix: some bank account details hidden --- .../server/src/lib/Transformer/Transformer.ts | 4 +++ .../Cashflow/CashflowAccountTransformer.ts | 27 +++++++++++++++++-- .../src/components/BankAccounts/index.tsx | 15 ++++++----- .../ExcludedTransactions/_utils.tsx | 3 ++- .../CashFlowAccounts/CashflowAccountsGrid.tsx | 7 ++++- 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/packages/server/src/lib/Transformer/Transformer.ts b/packages/server/src/lib/Transformer/Transformer.ts index 20efb4415..23613f748 100644 --- a/packages/server/src/lib/Transformer/Transformer.ts +++ b/packages/server/src/lib/Transformer/Transformer.ts @@ -164,6 +164,10 @@ export class Transformer { return date ? moment(date).format(this.dateFormat) : ''; } + protected formatDateFromNow(date){ + return date ? moment(date).fromNow(true) : ''; + } + /** * * @param number diff --git a/packages/server/src/services/Cashflow/CashflowAccountTransformer.ts b/packages/server/src/services/Cashflow/CashflowAccountTransformer.ts index e89104655..c78730041 100644 --- a/packages/server/src/services/Cashflow/CashflowAccountTransformer.ts +++ b/packages/server/src/services/Cashflow/CashflowAccountTransformer.ts @@ -8,7 +8,12 @@ export class CashflowAccountTransformer extends Transformer { * @returns {string[]} */ public includeAttributes = (): string[] => { - return ['formattedAmount']; + return [ + 'formattedAmount', + 'lastFeedsUpdatedAt', + 'lastFeedsUpdatedAtFormatted', + 'lastFeedsUpdatedFromNow', + ]; }; /** @@ -29,7 +34,7 @@ export class CashflowAccountTransformer extends Transformer { /** * Retrieve formatted account amount. - * @param {IAccount} invoice + * @param {IAccount} invoice * @returns {string} */ protected formattedAmount = (account: IAccount): string => { @@ -37,4 +42,22 @@ export class CashflowAccountTransformer extends Transformer { currencyCode: account.currencyCode, }); }; + + /** + * Retrieves the last feeds update at formatted date. + * @param {IAccount} account + * @returns {string} + */ + protected lastFeedsUpdatedAtFormatted(account: IAccount): string { + return this.formatDate(account.lastFeedsUpdatedAt); + } + + /** + * Retrieves the last feeds updated from now. + * @param {IAccount} account + * @returns {string} + */ + protected lastFeedsUpdatedFromNow(account: IAccount): string { + return this.formatDateFromNow(account.lastFeedsUpdatedAt); + } } diff --git a/packages/webapp/src/components/BankAccounts/index.tsx b/packages/webapp/src/components/BankAccounts/index.tsx index 98e411a4c..02f5f5697 100644 --- a/packages/webapp/src/components/BankAccounts/index.tsx +++ b/packages/webapp/src/components/BankAccounts/index.tsx @@ -62,6 +62,7 @@ export function BankAccount({ balance, loading = false, updatedBeforeText, + uncategorizedTransactionsCount, ...restProps }) { return ( @@ -77,17 +78,19 @@ export function BankAccount({ - {false && ( + {uncategorizedTransactionsCount > 0 && ( + )} + {updatedBeforeText && ( + )} - diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/_utils.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/_utils.tsx index d82f902bb..23a08b7e9 100644 --- a/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/_utils.tsx +++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/_utils.tsx @@ -37,12 +37,13 @@ export function useExcludedTransactionsColumns() { () => [ { Header: 'Date', - accessor: 'formatted_date', + accessor: 'formatted_date', width: 110, }, { Header: 'Description', accessor: descriptionAccessor, + textOverview: true, }, { Header: 'Payee', diff --git a/packages/webapp/src/containers/CashFlow/CashFlowAccounts/CashflowAccountsGrid.tsx b/packages/webapp/src/containers/CashFlow/CashFlowAccounts/CashflowAccountsGrid.tsx index 297c26eb0..8c8315e84 100644 --- a/packages/webapp/src/containers/CashFlow/CashFlowAccounts/CashflowAccountsGrid.tsx +++ b/packages/webapp/src/containers/CashFlow/CashFlowAccounts/CashflowAccountsGrid.tsx @@ -123,7 +123,12 @@ function CashflowBankAccount({ code={account.code} balance={!isNull(account.amount) ? account.formatted_amount : '-'} type={account.account_type} - updatedBeforeText={getUpdatedBeforeText(account.createdAt)} + updatedBeforeText={ + account.last_feeds_updated_from_now + ? `Updated ${account.last_feeds_updated_from_now} ago` + : '' + } + uncategorizedTransactionsCount={account.uncategorized_transactions} />