Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
beganovich committed Nov 17, 2024
2 parents 1ddcdf8 + 2633c45 commit c631c3c
Show file tree
Hide file tree
Showing 171 changed files with 21,413 additions and 17,465 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ VITE_HOSTED_SHOW_SMTP_SETTINGS=true

VITE_DISABLE_PREVENT_NAVIGATION_FEATURE=true

VITE_ENABLE_PEPPOL_STANDARD=true
VITE_ENABLE_PEPPOL_STANDARD=false

VITE_ENABLE_DISCARD_CHANGES_TRACKING=false

Expand Down
2 changes: 1 addition & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default defineConfig({
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000,
timeout: 10000,
},
/* Run tests in files in parallel */
fullyParallel: true,
Expand Down
2 changes: 2 additions & 0 deletions src/common/constants/exports/task-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export const taskMap: Record[] = [
{ trans: 'end_time', value: 'task.end_time', map: 'task' },
{ trans: 'duration', value: 'task.duration', map: 'task' },
{ trans: 'duration_words', value: 'task.duration_words', map: 'task' },
{ trans: 'log_duration', value: 'task.time_log', map: 'task' },
{ trans: 'log_duration_words', value: 'task.time_log_duration_words', map: 'task' },
{ trans: 'rate', value: 'task.rate', map: 'task' },
{ trans: 'number', value: 'task.number', map: 'task' },
{ trans: 'description', value: 'task.description', map: 'task' },
Expand Down
19 changes: 19 additions & 0 deletions src/common/guards/guards/white-label.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/

import { store } from '$app/common/stores/store';

export function whiteLabelPlan() {
return Boolean(
store.getState().companyUsers.api?.[
store.getState().companyUsers.currentIndex
]?.account.plan === 'white_label'
);
}
23 changes: 23 additions & 0 deletions src/common/helpers/peppol-countries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/

export const PEPPOL_COUNTRIES = [
'40',
'56',
'208',
'276',
'352',
'372',
'442',
'528',
'578',
'752',
'826',
];
4 changes: 3 additions & 1 deletion src/common/helpers/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ client.interceptors.response.use(
}

if (error.response?.status === 404) {
window.dispatchEvent(new CustomEvent('navigate.invalid.page'));
if (!error.response.config.url?.includes('einvoice')) {
window.dispatchEvent(new CustomEvent('navigate.invalid.page'));
}
}

if (
Expand Down
52 changes: 52 additions & 0 deletions src/common/helpers/tax-rates/tax-rates-combo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/

import { FeesAndLimitsEntry } from '$app/common/interfaces/company-gateway';
import { Expense } from '$app/common/interfaces/expense';
import { InvoiceItem } from '$app/common/interfaces/invoice-item';
import { Product } from '$app/common/interfaces/product';
import { RecurringExpense } from '$app/common/interfaces/recurring-expense';
import { ProductTableResource } from '$app/pages/invoices/common/components/ProductsTable';

type Resource =
| Expense
| ProductTableResource
| InvoiceItem
| Product
| RecurringExpense
| FeesAndLimitsEntry;

export type TaxNamePropertyType =
| (
| 'tax_name1'
| 'tax_name2'
| 'tax_name3'
| 'fee_tax_name1'
| 'fee_tax_name2'
| 'fee_tax_name3'
)
| undefined;

export function getTaxRateComboValue(
resource: Resource | undefined,
nameProperty: TaxNamePropertyType
): string {
if (!nameProperty) return '';

const taxRateProp = nameProperty.replace('name', 'rate') as keyof Resource;

if (resource && resource[taxRateProp]) {
return `${resource[nameProperty as keyof Resource]}||${
resource[taxRateProp]
}`;
}

return '';
}
23 changes: 23 additions & 0 deletions src/common/hooks/useCommonActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,25 @@ export function useAllCommonActions() {
{ value: 'restore', label: t('restore') },
{ value: 'delete', label: t('delete') },
],
credit: [
{ value: 'email_credit', label: t('email_credit') },
{ value: 'view_pdf', label: t('view_pdf') },
{ value: 'print_pdf', label: t('print_pdf') },
{ value: 'download_pdf', label: t('download_pdf') },
{ value: 'download_e_credit', label: t('download_e_credit') },
{ value: 'schedule', label: t('schedule') },
{ value: 'add_comment', label: t('add_comment') },
{ value: 'client_portal', label: t('client_portal') },
{ value: 'apply_credit', label: t('apply_credit') },
{ value: 'mark_sent', label: t('mark_sent') },
{ value: 'mark_paid', label: t('mark_paid') },
{ value: 'run_template', label: t('run_template') },
{ value: 'clone_to_credit', label: t('clone_to_credit') },
{ value: 'clone_to_other', label: t('clone_to_other') },
{ value: 'archive', label: t('archive') },
{ value: 'restore', label: t('restore') },
{ value: 'delete', label: t('delete') },
],
};

return actions;
Expand All @@ -53,6 +72,10 @@ export function useDefaultCommonActions() {
{ value: 'mark_sent', label: t('mark_sent') },
{ value: 'email_invoice', label: t('email_invoice') },
],
credit: [
{ value: 'mark_sent', label: t('mark_sent') },
{ value: 'email_credit', label: t('email_credit') },
],
};

return actions;
Expand Down
38 changes: 17 additions & 21 deletions src/common/hooks/useDateTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,19 @@

import dayjs from 'dayjs';
import { useCompanyTimeFormat } from './useCompanyTimeFormat';
import { useCompanyTimeZone } from './useCompanyTimeZone';
import { useCurrentCompanyDateFormats } from './useCurrentCompanyDateFormats';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);
interface Params {
formatOnlyTime?: boolean;
}

export function useDateTime(params?: Params) {
const { formatOnlyTime = false } = params || {};

export function useDateTime() {
const { timeZone: companyTimeZone } = useCompanyTimeZone();
const { timeFormat: companyTimeFormat } = useCompanyTimeFormat();
const { dateFormat: companyDateFormat } = useCurrentCompanyDateFormats();

return (
date: number | string,
dateFormat?: string,
timeFormat?: string,
timeZone?: string
) => {
return (date: number | string, dateFormat?: string, timeFormat?: string) => {
if (date === 0 || date === '' || date === undefined) {
return '';
}
Expand All @@ -37,16 +31,18 @@ export function useDateTime() {
timeFormat || companyTimeFormat
}`;

if (formatOnlyTime && typeof date === 'number') {
return dayjs.unix(date).format(timeFormat || companyTimeFormat);
}

if (formatOnlyTime && typeof date !== 'number') {
return dayjs(date).format(timeFormat || companyTimeFormat);
}

if (typeof date === 'number') {
return dayjs
.utc(date)
.tz(timeZone || companyTimeZone)
.format(finalFormat);
return dayjs.unix(date).format(finalFormat);
}

return dayjs
.utc(date)
.tz(timeZone || companyTimeZone)
.format(finalFormat);
return dayjs(date).format(finalFormat);
};
}
20 changes: 20 additions & 0 deletions src/common/hooks/usePaidOrSelfhost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/

import { isHosted, isSelfHosted } from '$app/common/helpers';
import dayjs from 'dayjs';
import { enterprisePlan } from '../guards/guards/enterprise-plan';
import { proPlan } from '../guards/guards/pro-plan';
import { useCurrentAccount } from './useCurrentAccount';
Expand All @@ -22,3 +23,22 @@ export function usePaidOrSelfHost() {

return (isHosted() && isPaidPlan) || isSelfHosted();
}

export function useIsPaid() {
const account = useCurrentAccount();

const isPaidPlan =
new Date(account?.plan_expires) > new Date() &&
(enterprisePlan() || proPlan());

return isPaidPlan;
}

export function useIsWhitelabelled() {
const account = useCurrentAccount();

return (
account?.plan_expires !== '' &&
!dayjs(account.plan_expires).isBefore(dayjs())
);
}
9 changes: 9 additions & 0 deletions src/common/hooks/useRefetch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export const keys = {
'/api/v1/activities/entity',
'/api/v1/activities',
'/api/v1/documents',
'/api/v1/einvoice/validateEntity-invoice',
'/api/v1/einvoice/validateEntity-company',
'/api/v1/einvoice/validateEntity-client',
],
},
designs: {
Expand Down Expand Up @@ -164,6 +167,8 @@ export const keys = {
'/api/v1/charts/totals_v2',
'/api/v1/charts/chart_summary_v2',
'/api/v1/documents',
'/api/v1/einvoice/validateEntity-client',
'/api/v1/einvoice/validateEntity-invoice',
],
},
products: {
Expand Down Expand Up @@ -218,6 +223,10 @@ export const keys = {
path: '/api/v1/activities',
dependencies: ['/api/v1/activities/entity'],
},
company_entity_validations: {
path: '/api/v1/einvoice/validateEntity-company',
dependencies: ['/api/v1/einvoice/validateEntity-invoice'],
},
};

export function useRefetch() {
Expand Down
2 changes: 2 additions & 0 deletions src/common/interfaces/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* @license https://www.elastic.co/licensing/elastic-license
*/

import { EInvoiceType } from '$app/pages/settings';
import { ClientContact } from './client-contact';
import { GroupSettings } from './group-settings';
import { TaxInfo } from './tax-info';
Expand Down Expand Up @@ -84,4 +85,5 @@ export interface Client extends Timestamps {
routing_id: string;
tax_info?: TaxInfo;
classification: string;
e_invoice: EInvoiceType;
}
5 changes: 5 additions & 0 deletions src/common/interfaces/company.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,11 @@ export interface Company {
inbound_mailbox_blacklist?: string;
inbound_mailbox_allow_unknown?: boolean;
expense_mailbox?: string;
legal_entity_id: string | null;
}

export interface Settings {
id?: string;
accept_client_input_quote_approval: boolean;
auto_archive_invoice: boolean;
auto_bill_standard_invoices: boolean;
Expand Down Expand Up @@ -340,6 +342,8 @@ export interface TaxData {
version: string;
seller_subregion: string;
regions: Regions;
acts_as_sender: boolean;
acts_as_receiver: boolean;
}

export interface Regions {
Expand Down Expand Up @@ -413,6 +417,7 @@ export interface TaxSetting {
tax_rate: number;
tax_name: string;
reduced_tax_rate: number;
vat_number: string;
}

export interface EURegion {
Expand Down
1 change: 1 addition & 0 deletions src/common/interfaces/statics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface Statics {
timezones: Timezone[];
templates: Templates;
bulk_updates: Record<string, string[]>;
license_key?: string;
}

export interface Bank {
Expand Down
19 changes: 16 additions & 3 deletions src/common/queries/expenses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,23 +90,36 @@ export function useExpensesQuery(params: ExpensesParams) {
);
}

const successMessages = {
bulk_update: 'updated_records',
};

export function useBulk() {
const queryClient = useQueryClient();
const invalidateQueryValue = useAtomValue(invalidationQueryAtom);

return (
ids: string[],
action: 'archive' | 'restore' | 'delete' | 'bulk_categorize',
action:
| 'archive'
| 'restore'
| 'delete'
| 'bulk_categorize'
| 'bulk_update',
rest?: Record<string, unknown>
) => {
toast.processing();

request('POST', endpoint('/api/v1/expenses/bulk'), {
return request('POST', endpoint('/api/v1/expenses/bulk'), {
action,
ids,
...rest,
}).then(() => {
toast.success(`${action}d_expense`);
const message =
successMessages[action as keyof typeof successMessages] ||
`${action}d_expense`;

toast.success(message);

invalidateQueryValue &&
queryClient.invalidateQueries([invalidateQueryValue]);
Expand Down
Loading

0 comments on commit c631c3c

Please sign in to comment.