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/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/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/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 = [];
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/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',
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}
/>