@accounter/client 0.0.8-alpha-20251028123001-a8ce4e53bbde9f6eeded7bfeea650700f6a63130 → 0.0.8-alpha-20251028124234-328844c99a42b68aa9e2f32fd86da80b4832f631
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -27
- package/dist/assets/{Checkbox-sjgv9dlI.js → Checkbox-BR6kGuhg.js} +2 -2
- package/dist/assets/MultiSelect-BqcJrWnD.js +1 -0
- package/dist/assets/Pagination-6Sv5LXxl.js +1 -0
- package/dist/assets/{Progress-DKypjBbn.js → Progress-7xtiFwK3.js} +1 -1
- package/dist/assets/Table-C5zxD95i.js +1 -0
- package/dist/assets/Typography-CMzSQZKD.js +1 -0
- package/dist/assets/YearPickerInput-CllwSjcn.js +1 -0
- package/dist/assets/{accordion-Cfc9ae4H.js → accordion-CMR2fANH.js} +1 -1
- package/dist/assets/accountant-approvals-BHFXpHHc.js +1 -0
- package/dist/assets/accounter-table-CpeQD4PG.js +1 -0
- package/dist/assets/addDays-DvwuJbUs.js +1 -0
- package/dist/assets/all-charges-At7WJXuW.js +1 -0
- package/dist/assets/{arrow-up-down-DapQ791y.js → arrow-up-down-DPG1l9S1.js} +1 -1
- package/dist/assets/{building-2-B5JpJWrx.js → building-2-BgvPBt2Z.js} +1 -1
- package/dist/assets/business-DKvbSnga.js +32 -0
- package/dist/assets/business-extended-info-7CM8px2e.js +13 -0
- package/dist/assets/{business-header-BK89Rfvy.js → business-header-u2sfE_d8.js} +1 -1
- package/dist/assets/business-transactions-filters-DmpO9Bwo.js +1 -0
- package/dist/assets/business-transactions-single-rF6JbAL7.js +1 -0
- package/dist/assets/business-trip-BGrp09N7.js +1 -0
- package/dist/assets/charge-C-EaA1Xc.js +1 -0
- package/dist/assets/charges-filters-Dq-8QHH-.js +1 -0
- package/dist/assets/charges-ledger-validation-DlkzVow7.js +1 -0
- package/dist/assets/charges-table-Cncs1HLi.js +62 -0
- package/dist/assets/{chart-0bAgDGey.js → chart-ByngRufj.js} +6 -6
- package/dist/assets/create-event-handler-BiA-1lGu.js +1 -0
- package/dist/assets/{data-table-pagination-BgCuddCb.js → data-table-pagination-D4OEFmX_.js} +1 -1
- package/dist/assets/download-csv-button-Df5rDeDc.js +1 -0
- package/dist/assets/editable-business-trip-Bav24z0u.js +16 -0
- package/dist/assets/funnel-BJ71hzoq.js +6 -0
- package/dist/assets/index-BRv0JZw4.js +1 -0
- package/dist/assets/index-BXlS8oD_.js +1 -0
- package/dist/assets/{index-DaSgVGNd.js → index-BetG0HVN.js} +3 -3
- package/dist/assets/index-BplSRMAq.css +1 -0
- package/dist/assets/{index-Dnafld8G.js → index-Bsl7tJp_.js} +16 -16
- package/dist/assets/{index-DLRffFbF.js → index-CLUhAJ3t.js} +7 -7
- package/dist/assets/index-Cix5qjA-.js +2 -0
- package/dist/assets/index-CizLtiES.js +1 -0
- package/dist/assets/index-DKBzv0gc.js +1 -0
- package/dist/assets/index-DR_5jpS4.js +6 -0
- package/dist/assets/index-DTmtILfq.js +1 -0
- package/dist/assets/index-DU0G7FZm.js +1 -0
- package/dist/assets/index-DUWRgLfu.js +9 -0
- package/dist/assets/index-DYZPWG4k.js +2 -0
- package/dist/assets/index-DdUE2_44.js +1 -0
- package/dist/assets/index-De5dvO0S.js +1 -0
- package/dist/assets/index-Des3eR4f.js +1 -0
- package/dist/assets/index-DpYwi5kf.js +6 -0
- package/dist/assets/index-GzyQZkbY.js +1 -0
- package/dist/assets/index-HzLXi-qB.js +1 -0
- package/dist/assets/index-Ji28AZwq.js +1 -0
- package/dist/assets/{index-D92U_VYB.js → index-UMFH47hN.js} +2 -2
- package/dist/assets/index-fuT9duEO.js +1 -0
- package/dist/assets/{index-BBpGo89I.js → index-vChLJwSt.js} +2 -2
- package/dist/assets/index-wck8Xuay.js +1 -0
- package/dist/assets/index-wyU9I4Kz.js +768 -0
- package/dist/assets/{index.es-JpTIgXoh.js → index.es-NphQjU3m.js} +1 -1
- package/dist/assets/insert-business-trip-modal-vS1QrUJz.js +6 -0
- package/dist/assets/issue-document-pIswc_8i.js +1 -0
- package/dist/assets/list-plus-Dy3vzJVy.js +6 -0
- package/dist/assets/login-page-YXRfklK1.js +1 -0
- package/dist/assets/match-document-modal-BPG_hljb.js +16 -0
- package/dist/assets/missing-info-charges-D8dUfChs.js +1 -0
- package/dist/assets/modal-D47umnak.js +1 -0
- package/dist/assets/page-layout-BG0XvWfD.js +1 -0
- package/dist/assets/page-not-found-Cy6oIIb1.js +1 -0
- package/dist/assets/panel-top-open-B1rhJYjQ.js +11 -0
- package/dist/assets/{pencil-CEfu8zQ4.js → pencil-tV0FsM6V.js} +1 -1
- package/dist/assets/report-commentary-row-BL2RkIHq.js +1 -0
- package/dist/assets/{save-Drpbh6u3.js → save-Czmh3tvC.js} +1 -1
- package/dist/assets/similar-transactions-modal-MQeC2gtu.js +1 -0
- package/dist/assets/sub-B4_VmmF9.js +1 -0
- package/dist/assets/subMonths-DG7w6bCY.js +1 -0
- package/dist/assets/summary-DvHtnArZ.js +1 -0
- package/dist/assets/switch-GSloW_Ey.js +1 -0
- package/dist/assets/toggle-expansion-button-lwJYTklN.js +1 -0
- package/dist/assets/tooltip-BbKSwLCX.js +1 -0
- package/dist/assets/use-url-query-CUVSXgm0.js +1 -0
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/src/components/business/contracts-section.tsx +4 -18
- package/src/components/business-transactions/business-extended-info.tsx +5 -5
- package/src/components/business-transactions/index.tsx +1 -28
- package/src/components/businesses/index.tsx +6 -2
- package/src/components/charges/cells/business-trip.tsx +6 -1
- package/src/components/charges/cells/counterparty.tsx +4 -28
- package/src/components/clients/contracts/modify-contract-dialog.tsx +11 -64
- package/src/components/common/business-trip-report/parts/core-expense-row.tsx +2 -2
- package/src/components/common/business-trip-report/parts/report-header.tsx +2 -1
- package/src/components/common/business-trip-report/parts/uncategorized-transactions.tsx +2 -2
- package/src/components/common/buttons/charge-navigate-button.tsx +12 -11
- package/src/components/common/modals/edit-charge-modal.tsx +2 -2
- package/src/components/common/modals/insert-document-modal.tsx +2 -2
- package/src/components/common/modals/match-document-modal.tsx +2 -2
- package/src/components/common/new-documents-list.tsx +2 -2
- package/src/components/documents-table/cells/creditor.tsx +2 -11
- package/src/components/documents-table/cells/debtor.tsx +2 -11
- package/src/components/ledger-table/counterparty-cell.tsx +4 -33
- package/src/components/reports/conto/index.tsx +1 -18
- package/src/components/reports/trial-balance-report/index.tsx +1 -17
- package/src/components/screens/businesses/business.tsx +0 -4
- package/src/components/screens/charges/all-charges.tsx +1 -17
- package/src/components/screens/charges/charge.tsx +0 -4
- package/src/components/screens/reports/balance-report/index.tsx +0 -14
- package/src/components/screens/reports/depreciation-report/index.tsx +0 -14
- package/src/components/transactions-table/cells/counterparty.tsx +2 -23
- package/src/components/transactions-table/cells-legacy/counterparty.tsx +3 -26
- package/src/gql/gql.ts +6 -6
- package/src/gql/graphql.ts +7 -7
- package/src/hooks/use-get-all-contracts.ts +1 -1
- package/src/providers/urql.tsx +2 -2
- package/dist/assets/Typography-CJfovWMc.js +0 -1
- package/dist/assets/accountant-approvals-DhCtddzR.js +0 -1
- package/dist/assets/all-charges-H_xH1cUe.js +0 -1
- package/dist/assets/business-BtKmlUZR.js +0 -32
- package/dist/assets/business-transactions-single-Dv6-AKgI.js +0 -1
- package/dist/assets/business-trip-DIBdq8Jq.js +0 -1
- package/dist/assets/charges-filters-CTMCRKNm.js +0 -1
- package/dist/assets/charges-ledger-validation-c6jklgQz.js +0 -1
- package/dist/assets/editable-business-trip-Cr87pQT-.js +0 -16
- package/dist/assets/index-B8QopG0Z.js +0 -1
- package/dist/assets/index-BVZuWqUd.js +0 -1
- package/dist/assets/index-Bt7NK9UB.js +0 -1
- package/dist/assets/index-CBPTpZHL.css +0 -1
- package/dist/assets/index-CKfzp5hU.js +0 -1
- package/dist/assets/index-CTzkpoqF.js +0 -2
- package/dist/assets/index-CaSs1tPq.js +0 -1
- package/dist/assets/index-Cgl63fgb.js +0 -1
- package/dist/assets/index-ChwFk-6u.js +0 -1
- package/dist/assets/index-CnHbGv9H.js +0 -1
- package/dist/assets/index-CnKUadG6.js +0 -886
- package/dist/assets/index-CpqDv0tU.js +0 -1
- package/dist/assets/index-CtfXFlRt.js +0 -1
- package/dist/assets/index-Cyg6_G-8.js +0 -9
- package/dist/assets/index-b4v6_EXH.js +0 -6
- package/dist/assets/index-f6-rwrBW.js +0 -1
- package/dist/assets/index-mXqFMX5P.js +0 -1
- package/dist/assets/index-sUDYfUlt.js +0 -1
- package/dist/assets/index-tgi4TEs-.js +0 -2
- package/dist/assets/issue-document-CejQASYM.js +0 -1
- package/dist/assets/login-page-ByDrdoxH.js +0 -1
- package/dist/assets/missing-info-charges-DHt03bdz.js +0 -1
- package/dist/assets/page-not-found-Bhi5OU5Q.js +0 -1
- package/dist/assets/report-commentary-row-CmDH8P-d.js +0 -1
- package/dist/assets/sub-DBgZtyi3.js +0 -1
- package/dist/assets/subMonths-J6RX2Vo3.js +0 -1
- package/src/components/charges/helpers.ts +0 -15
package/package.json
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
query ClientContractsSection($clientId: UUID!) {
|
|
22
22
|
contractsByClient(clientId: $clientId) {
|
|
23
23
|
id
|
|
24
|
-
|
|
24
|
+
purchaseOrder
|
|
25
25
|
startDate
|
|
26
26
|
endDate
|
|
27
27
|
amount {
|
|
@@ -46,7 +46,7 @@ function convertContractDataToFormValues(
|
|
|
46
46
|
id: contract.id,
|
|
47
47
|
// TODO: activate this field later. requires additional backend support
|
|
48
48
|
// operationsLimit: 0, // Placeholder, as this field is not in the query
|
|
49
|
-
|
|
49
|
+
po: contract.purchaseOrder ?? undefined,
|
|
50
50
|
startDate: contract.startDate,
|
|
51
51
|
endDate: contract.endDate,
|
|
52
52
|
paymentAmount: contract.amount.raw,
|
|
@@ -130,22 +130,8 @@ export function ContractsSection({ clientId }: Props) {
|
|
|
130
130
|
</div>
|
|
131
131
|
|
|
132
132
|
<div className="space-y-0">
|
|
133
|
-
<p className="text-sm text-muted-foreground">PO
|
|
134
|
-
<p className="text-sm font-medium font-mono">
|
|
135
|
-
{contract.purchaseOrders.toReversed()[0] ?? ''}
|
|
136
|
-
</p>
|
|
137
|
-
{contract.purchaseOrders.length > 1 && (
|
|
138
|
-
<div className="space-x-1">
|
|
139
|
-
{contract.purchaseOrders
|
|
140
|
-
.toReversed()
|
|
141
|
-
.slice(1)
|
|
142
|
-
.map(po => (
|
|
143
|
-
<span key={po} className="text-xs font-thin font-mono">
|
|
144
|
-
{po}
|
|
145
|
-
</span>
|
|
146
|
-
))}
|
|
147
|
-
</div>
|
|
148
|
-
)}
|
|
133
|
+
<p className="text-sm text-muted-foreground">PO Number</p>
|
|
134
|
+
<p className="text-sm font-medium font-mono">{contract.purchaseOrder}</p>
|
|
149
135
|
</div>
|
|
150
136
|
|
|
151
137
|
{/* TODO: activate this field later. requires additional backend support */}
|
|
@@ -3,6 +3,7 @@ import { format } from 'date-fns';
|
|
|
3
3
|
import { ChevronsLeftRightEllipsis, ChevronsRightLeft } from 'lucide-react';
|
|
4
4
|
import { Link } from 'react-router-dom';
|
|
5
5
|
import { useQuery } from 'urql';
|
|
6
|
+
import { ROUTES } from '@/router/routes.js';
|
|
6
7
|
import { Mark, Table, Tooltip } from '@mantine/core';
|
|
7
8
|
import {
|
|
8
9
|
BusinessTransactionsInfoDocument,
|
|
@@ -12,10 +13,8 @@ import {
|
|
|
12
13
|
} from '../../gql/graphql.js';
|
|
13
14
|
import { FIAT_CURRENCIES, formatAmountWithCurrency } from '../../helpers/index.js';
|
|
14
15
|
import { AccounterLoader } from '../common/index.js';
|
|
15
|
-
import { getChargeHref } from '../screens/charges/charge.js';
|
|
16
16
|
import { Button } from '../ui/button.js';
|
|
17
17
|
import { DownloadCSV } from './download-csv.js';
|
|
18
|
-
import { getBusinessTransactionsHref } from './index.js';
|
|
19
18
|
|
|
20
19
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
21
20
|
/* GraphQL */ `
|
|
@@ -229,14 +228,15 @@ export function BusinessExtendedInfo({ businessID, filter }: Props): ReactElemen
|
|
|
229
228
|
{extendedTransactions.map((row, index) => (
|
|
230
229
|
<tr
|
|
231
230
|
key={index}
|
|
231
|
+
className="cursor-pointer"
|
|
232
232
|
onClick={event => {
|
|
233
233
|
event.stopPropagation();
|
|
234
|
-
window.open(
|
|
234
|
+
window.open(ROUTES.CHARGES.DETAIL(row.chargeId), '_blank', 'noreferrer');
|
|
235
235
|
}}
|
|
236
236
|
>
|
|
237
237
|
<td>
|
|
238
238
|
<Link
|
|
239
|
-
to={
|
|
239
|
+
to={ROUTES.BUSINESSES.DETAIL(row.business.id)}
|
|
240
240
|
target="_blank"
|
|
241
241
|
rel="noreferrer"
|
|
242
242
|
onClick={event => event.stopPropagation()}
|
|
@@ -274,7 +274,7 @@ export function BusinessExtendedInfo({ businessID, filter }: Props): ReactElemen
|
|
|
274
274
|
<td>
|
|
275
275
|
{row.counterAccount && (
|
|
276
276
|
<Link
|
|
277
|
-
to={
|
|
277
|
+
to={ROUTES.BUSINESSES.DETAIL(row.counterAccount.id)}
|
|
278
278
|
target="_blank"
|
|
279
279
|
rel="noreferrer"
|
|
280
280
|
onClick={event => event.stopPropagation()}
|
|
@@ -21,10 +21,7 @@ import { AccounterTableRow } from '../common/index.js';
|
|
|
21
21
|
import { PageLayout } from '../layout/page-layout.js';
|
|
22
22
|
import { Button } from '../ui/button.js';
|
|
23
23
|
import { BusinessExtendedInfo } from './business-extended-info.js';
|
|
24
|
-
import {
|
|
25
|
-
BusinessTransactionsFilters,
|
|
26
|
-
encodeTransactionsFilters,
|
|
27
|
-
} from './business-transactions-filters.js';
|
|
24
|
+
import { BusinessTransactionsFilters } from './business-transactions-filters.js';
|
|
28
25
|
|
|
29
26
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
30
27
|
/* GraphQL */ `
|
|
@@ -69,30 +66,6 @@ import {
|
|
|
69
66
|
}
|
|
70
67
|
`;
|
|
71
68
|
|
|
72
|
-
export function getBusinessTransactionsHref(filter?: BusinessTransactionsFilter | null): string {
|
|
73
|
-
const params = new URLSearchParams();
|
|
74
|
-
|
|
75
|
-
let businessId: string | undefined = undefined;
|
|
76
|
-
let adjustedFilter = filter;
|
|
77
|
-
if (filter?.businessIDs && filter.businessIDs.length === 1) {
|
|
78
|
-
const { businessIDs, ...rest } = filter;
|
|
79
|
-
businessId = businessIDs[0];
|
|
80
|
-
adjustedFilter = rest;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const transactionsFilters = encodeTransactionsFilters(adjustedFilter);
|
|
84
|
-
if (transactionsFilters) {
|
|
85
|
-
// Add it as a single encoded parameter
|
|
86
|
-
params.append('transactionsFilters', transactionsFilters);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const queryParams = params.size > 0 ? `?${params}` : '';
|
|
90
|
-
if (businessId) {
|
|
91
|
-
return `/businesses/${businessId}/transactions${queryParams}`;
|
|
92
|
-
}
|
|
93
|
-
return `/businesses/transactions${queryParams}`;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
69
|
type BusinessTransactionsSum = Extract<
|
|
97
70
|
BusinessTransactionsSummeryQuery['businessTransactionsSumFromLedgerRecords'],
|
|
98
71
|
{ businessTransactionsSum: unknown }
|
|
@@ -159,12 +159,16 @@ export const Businesses = (): ReactElement => {
|
|
|
159
159
|
tabIndex={0}
|
|
160
160
|
className="flex-1 cursor-pointer"
|
|
161
161
|
onClick={(): void => {
|
|
162
|
-
navigate(ROUTES.BUSINESSES.DETAIL(business.id)
|
|
162
|
+
navigate(ROUTES.BUSINESSES.DETAIL(business.id), {
|
|
163
|
+
state: { from: ROUTES.BUSINESSES.ALL },
|
|
164
|
+
});
|
|
163
165
|
}}
|
|
164
166
|
onKeyDown={(e): void => {
|
|
165
167
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
166
168
|
e.preventDefault();
|
|
167
|
-
navigate(ROUTES.BUSINESSES.DETAIL(business.id)
|
|
169
|
+
navigate(ROUTES.BUSINESSES.DETAIL(business.id), {
|
|
170
|
+
state: { from: ROUTES.BUSINESSES.ALL },
|
|
171
|
+
});
|
|
168
172
|
}
|
|
169
173
|
}}
|
|
170
174
|
>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
|
+
import { ROUTES } from '@/router/routes.js';
|
|
3
4
|
import { ChargesTableBusinessTripFieldsFragmentDoc } from '../../../gql/graphql.js';
|
|
4
5
|
import { getFragmentData, type FragmentType } from '../../../gql/index.js';
|
|
5
6
|
|
|
@@ -30,7 +31,11 @@ export const BusinessTrip = ({ data }: Props): ReactElement => {
|
|
|
30
31
|
return (
|
|
31
32
|
<td>
|
|
32
33
|
<Link
|
|
33
|
-
to={
|
|
34
|
+
to={
|
|
35
|
+
charge.businessTrip?.id
|
|
36
|
+
? ROUTES.BUSINESS_TRIPS.DETAIL(charge.businessTrip?.id)
|
|
37
|
+
: ROUTES.BUSINESS_TRIPS.ROOT
|
|
38
|
+
}
|
|
34
39
|
target="_blank"
|
|
35
40
|
rel="noreferrer"
|
|
36
41
|
onClick={event => event.stopPropagation()}
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo, type ReactElement } from 'react';
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
|
+
import { ROUTES } from '@/router/routes.js';
|
|
3
4
|
import { Indicator } from '@mantine/core';
|
|
4
|
-
import {
|
|
5
|
-
ChargesTableEntityFieldsFragmentDoc,
|
|
6
|
-
MissingChargeInfo,
|
|
7
|
-
type ChargeFilter,
|
|
8
|
-
} from '../../../gql/graphql.js';
|
|
5
|
+
import { ChargesTableEntityFieldsFragmentDoc, MissingChargeInfo } from '../../../gql/graphql.js';
|
|
9
6
|
import { getFragmentData, type FragmentType } from '../../../gql/index.js';
|
|
10
|
-
import { useUrlQuery } from '../../../hooks/use-url-query.js';
|
|
11
|
-
import { getBusinessTransactionsHref } from '../../business-transactions/index.js';
|
|
12
7
|
|
|
13
8
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
14
9
|
/* GraphQL */ `
|
|
@@ -32,7 +27,6 @@ type Props = {
|
|
|
32
27
|
};
|
|
33
28
|
|
|
34
29
|
export const Counterparty = ({ data }: Props): ReactElement => {
|
|
35
|
-
const { get } = useUrlQuery();
|
|
36
30
|
const { counterparty, validationData, __typename } = getFragmentData(
|
|
37
31
|
ChargesTableEntityFieldsFragmentDoc,
|
|
38
32
|
data,
|
|
@@ -59,31 +53,13 @@ export const Counterparty = ({ data }: Props): ReactElement => {
|
|
|
59
53
|
);
|
|
60
54
|
const { name, id } = counterparty ?? { name: 'Missing', id: undefined };
|
|
61
55
|
|
|
62
|
-
const encodedFilters = get('chargesFilters');
|
|
63
|
-
|
|
64
|
-
const getHref = useCallback(
|
|
65
|
-
(businessID: string) => {
|
|
66
|
-
const currentFilters = encodedFilters
|
|
67
|
-
? (JSON.parse(decodeURIComponent(encodedFilters as string)) as ChargeFilter)
|
|
68
|
-
: {};
|
|
69
|
-
|
|
70
|
-
return getBusinessTransactionsHref({
|
|
71
|
-
fromDate: currentFilters.fromDate,
|
|
72
|
-
toDate: currentFilters.toDate,
|
|
73
|
-
ownerIds: currentFilters.byOwners,
|
|
74
|
-
businessIDs: [businessID],
|
|
75
|
-
});
|
|
76
|
-
},
|
|
77
|
-
[encodedFilters],
|
|
78
|
-
);
|
|
79
|
-
|
|
80
56
|
return (
|
|
81
57
|
<td>
|
|
82
58
|
<div className="flex flex-wrap">
|
|
83
59
|
<Indicator inline size={12} disabled={!isError} color="red" zIndex="auto">
|
|
84
60
|
{!isError && id && (
|
|
85
61
|
<Link
|
|
86
|
-
to={
|
|
62
|
+
to={ROUTES.BUSINESSES.DETAIL(id)}
|
|
87
63
|
target="_blank"
|
|
88
64
|
rel="noreferrer"
|
|
89
65
|
onClick={event => event.stopPropagation()}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { format } from 'date-fns';
|
|
3
|
-
import { Plus
|
|
3
|
+
import { Plus } from 'lucide-react';
|
|
4
4
|
import { useForm } from 'react-hook-form';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
import { Badge } from '@/components/ui/badge.js';
|
|
7
6
|
import { Button } from '@/components/ui/button.js';
|
|
8
7
|
import {
|
|
9
8
|
Dialog,
|
|
@@ -49,7 +48,7 @@ const contractFormSchema = z.object({
|
|
|
49
48
|
// operationsLimit: z.number().optional(),
|
|
50
49
|
startDate: z.iso.date('Start date is required'),
|
|
51
50
|
endDate: z.iso.date('End date is required'),
|
|
52
|
-
|
|
51
|
+
po: z.string().optional(),
|
|
53
52
|
paymentAmount: z.number().min(0, 'Payment amount must be non-negative'),
|
|
54
53
|
paymentCurrency: z.enum(Object.values(Currency), 'Currency is required'),
|
|
55
54
|
productType: z.enum(Object.values(Product)).optional(),
|
|
@@ -68,7 +67,7 @@ const newContractDefaultValues: ContractFormValues = {
|
|
|
68
67
|
// operationsLimit: 0,
|
|
69
68
|
startDate: '',
|
|
70
69
|
endDate: '',
|
|
71
|
-
|
|
70
|
+
po: undefined,
|
|
72
71
|
paymentAmount: 0,
|
|
73
72
|
paymentCurrency: Currency.Usd,
|
|
74
73
|
productType: Product.Hive,
|
|
@@ -89,7 +88,6 @@ interface Props {
|
|
|
89
88
|
export function ModifyContractDialog({ clientId, contract, onDone }: Props) {
|
|
90
89
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
91
90
|
const [editingContract, setEditingContract] = useState<ContractFormValues | null>(null);
|
|
92
|
-
const [newPO, setNewPO] = useState('');
|
|
93
91
|
|
|
94
92
|
const { updateContract, updating } = useUpdateContract();
|
|
95
93
|
const { createContract, creating } = useCreateContract();
|
|
@@ -99,26 +97,6 @@ export function ModifyContractDialog({ clientId, contract, onDone }: Props) {
|
|
|
99
97
|
defaultValues: contract || newContractDefaultValues,
|
|
100
98
|
});
|
|
101
99
|
|
|
102
|
-
const addPO = () => {
|
|
103
|
-
const trimmedPO = newPO.trim();
|
|
104
|
-
if (trimmedPO) {
|
|
105
|
-
const currentLinks = form.getValues('pos');
|
|
106
|
-
if (!currentLinks.includes(trimmedPO)) {
|
|
107
|
-
form.setValue('pos', [...currentLinks, trimmedPO], { shouldDirty: true });
|
|
108
|
-
}
|
|
109
|
-
setNewPO('');
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const removePO = (index: number) => {
|
|
114
|
-
const currentLinks = form.getValues('pos');
|
|
115
|
-
form.setValue(
|
|
116
|
-
'pos',
|
|
117
|
-
currentLinks.filter((_, i) => i !== index),
|
|
118
|
-
{ shouldDirty: true },
|
|
119
|
-
);
|
|
120
|
-
};
|
|
121
|
-
|
|
122
100
|
useEffect(() => {
|
|
123
101
|
if (contract) {
|
|
124
102
|
setEditingContract(contract);
|
|
@@ -127,7 +105,7 @@ export function ModifyContractDialog({ clientId, contract, onDone }: Props) {
|
|
|
127
105
|
// operationsLimit: contract.operationsLimit,
|
|
128
106
|
startDate: contract.startDate,
|
|
129
107
|
endDate: contract.endDate,
|
|
130
|
-
|
|
108
|
+
po: contract.po,
|
|
131
109
|
paymentAmount: contract.paymentAmount,
|
|
132
110
|
paymentCurrency: contract.paymentCurrency,
|
|
133
111
|
productType: contract.productType,
|
|
@@ -163,7 +141,7 @@ export function ModifyContractDialog({ clientId, contract, onDone }: Props) {
|
|
|
163
141
|
msCloud: values.msCloudLink,
|
|
164
142
|
plan: values.subscriptionPlan,
|
|
165
143
|
product: values.productType,
|
|
166
|
-
|
|
144
|
+
purchaseOrder: values.po,
|
|
167
145
|
remarks: values.defaultRemark,
|
|
168
146
|
startDate: format(new Date(values.startDate), 'yyyy-MM-dd') as TimelessDateString,
|
|
169
147
|
},
|
|
@@ -185,7 +163,7 @@ export function ModifyContractDialog({ clientId, contract, onDone }: Props) {
|
|
|
185
163
|
msCloud: values.msCloudLink,
|
|
186
164
|
plan: values.subscriptionPlan,
|
|
187
165
|
product: values.productType,
|
|
188
|
-
|
|
166
|
+
purchaseOrder: values.po,
|
|
189
167
|
remarks: values.defaultRemark,
|
|
190
168
|
startDate: format(new Date(values.startDate), 'yyyy-MM-dd') as TimelessDateString,
|
|
191
169
|
},
|
|
@@ -233,46 +211,15 @@ export function ModifyContractDialog({ clientId, contract, onDone }: Props) {
|
|
|
233
211
|
</FormItem>
|
|
234
212
|
)}
|
|
235
213
|
/> */}
|
|
236
|
-
|
|
237
214
|
<FormField
|
|
238
215
|
control={form.control}
|
|
239
|
-
name="
|
|
216
|
+
name="po"
|
|
240
217
|
render={({ field }) => (
|
|
241
218
|
<FormItem>
|
|
242
|
-
<FormLabel>
|
|
243
|
-
<
|
|
244
|
-
<Input
|
|
245
|
-
|
|
246
|
-
value={newPO}
|
|
247
|
-
onChange={e => setNewPO(e.target.value)}
|
|
248
|
-
onKeyDown={e => {
|
|
249
|
-
if (e.key === 'Enter') {
|
|
250
|
-
e.preventDefault();
|
|
251
|
-
addPO();
|
|
252
|
-
}
|
|
253
|
-
}}
|
|
254
|
-
/>
|
|
255
|
-
<Button type="button" size="sm" onClick={addPO}>
|
|
256
|
-
<Plus className="h-4 w-4" />
|
|
257
|
-
</Button>
|
|
258
|
-
</div>
|
|
259
|
-
<div className="flex flex-wrap gap-2 mt-2">
|
|
260
|
-
{field.value?.map((link, index) => (
|
|
261
|
-
<Badge key={link} variant="secondary" className="gap-1 max-w-xs truncate">
|
|
262
|
-
{link}
|
|
263
|
-
{index === field.value.length - 1 && (
|
|
264
|
-
<Button
|
|
265
|
-
variant="ghost"
|
|
266
|
-
size="icon"
|
|
267
|
-
className="p-0 size-3"
|
|
268
|
-
onClick={() => removePO(index)}
|
|
269
|
-
>
|
|
270
|
-
<X className="size-3 cursor-pointer flex-shrink-0" />
|
|
271
|
-
</Button>
|
|
272
|
-
)}
|
|
273
|
-
</Badge>
|
|
274
|
-
))}
|
|
275
|
-
</div>
|
|
219
|
+
<FormLabel>PO Number</FormLabel>
|
|
220
|
+
<FormControl>
|
|
221
|
+
<Input placeholder="PO-2024-001" {...field} />
|
|
222
|
+
</FormControl>
|
|
276
223
|
<FormMessage />
|
|
277
224
|
</FormItem>
|
|
278
225
|
)}
|
|
@@ -4,6 +4,7 @@ import { Controller, type Control } from 'react-hook-form';
|
|
|
4
4
|
import { Link } from 'react-router-dom';
|
|
5
5
|
import { toast } from 'sonner';
|
|
6
6
|
import { useQuery } from 'urql';
|
|
7
|
+
import { ROUTES } from '@/router/routes.js';
|
|
7
8
|
import { Select, Text } from '@mantine/core';
|
|
8
9
|
import { DatePickerInput } from '@mantine/dates';
|
|
9
10
|
import {
|
|
@@ -14,7 +15,6 @@ import {
|
|
|
14
15
|
} from '../../../../gql/graphql.js';
|
|
15
16
|
import { getFragmentData, type FragmentType } from '../../../../gql/index.js';
|
|
16
17
|
import { TIMELESS_DATE_REGEX } from '../../../../helpers/consts.js';
|
|
17
|
-
import { getChargeHref } from '../../../screens/charges/charge.js';
|
|
18
18
|
import { CurrencyInput } from '../../index.js';
|
|
19
19
|
|
|
20
20
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
@@ -239,7 +239,7 @@ export const CoreExpenseRow = ({
|
|
|
239
239
|
{linkedChargeIds.map(id => (
|
|
240
240
|
<Link
|
|
241
241
|
key={id}
|
|
242
|
-
to={
|
|
242
|
+
to={ROUTES.CHARGES.DETAIL(id)}
|
|
243
243
|
target="_blank"
|
|
244
244
|
rel="noreferrer"
|
|
245
245
|
onClick={event => event.stopPropagation()}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import { differenceInDays, format, setHours } from 'date-fns';
|
|
3
|
+
import { ROUTES } from '@/router/routes.js';
|
|
3
4
|
import { Grid, Text } from '@mantine/core';
|
|
4
5
|
import { BusinessTripReportHeaderFieldsFragmentDoc } from '../../../../gql/graphql.js';
|
|
5
6
|
import { getFragmentData, type FragmentType } from '../../../../gql/index.js';
|
|
@@ -43,7 +44,7 @@ export const ReportHeader = ({ data, onChange }: Props): ReactElement => {
|
|
|
43
44
|
<AccountantApproval data={businessTrip} onChange={onChange} />
|
|
44
45
|
<CopyToClipboardButton
|
|
45
46
|
isLink
|
|
46
|
-
content={`${window.location.origin}
|
|
47
|
+
content={`${window.location.origin}${ROUTES.BUSINESS_TRIPS.DETAIL(businessTrip.id)}`}
|
|
47
48
|
/>
|
|
48
49
|
<BusinessTripToggleMenu businessTripId={businessTrip.id} />
|
|
49
50
|
</div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import { AlertCircle } from 'lucide-react';
|
|
3
3
|
import { Link } from 'react-router-dom';
|
|
4
|
+
import { ROUTES } from '@/router/routes.js';
|
|
4
5
|
import { Popover, Table, Text } from '@mantine/core';
|
|
5
6
|
import { useDisclosure } from '@mantine/hooks';
|
|
6
7
|
import {
|
|
@@ -10,7 +11,6 @@ import {
|
|
|
10
11
|
} from '../../../../gql/graphql.js';
|
|
11
12
|
import { getFragmentData, type FragmentType } from '../../../../gql/index.js';
|
|
12
13
|
import { formatStringifyAmount } from '../../../../helpers/index.js';
|
|
13
|
-
import { getChargeHref } from '../../../screens/charges/charge.js';
|
|
14
14
|
import {
|
|
15
15
|
Account,
|
|
16
16
|
Counterparty,
|
|
@@ -94,7 +94,7 @@ export const UncategorizedTransactions = ({ data, onChange }: Props): ReactEleme
|
|
|
94
94
|
<Amount data={uncategorizedTransaction} />
|
|
95
95
|
<td>
|
|
96
96
|
<Link
|
|
97
|
-
to={
|
|
97
|
+
to={ROUTES.CHARGES.DETAIL(uncategorizedTransaction.transaction.chargeId)}
|
|
98
98
|
target="_blank"
|
|
99
99
|
rel="noreferrer"
|
|
100
100
|
onClick={event => event.stopPropagation()}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { ComponentProps, ReactElement } from 'react';
|
|
2
2
|
import { ExternalLink } from 'lucide-react';
|
|
3
|
+
import { Link } from 'react-router-dom';
|
|
3
4
|
import { Tooltip } from '@mantine/core';
|
|
4
5
|
import { cn } from '../../../lib/utils.js';
|
|
5
|
-
import {
|
|
6
|
+
import { ROUTES } from '../../../router/routes.js';
|
|
6
7
|
import { Button } from '../../ui/button.js';
|
|
7
8
|
|
|
8
9
|
export function ChargeNavigateButton(
|
|
@@ -10,17 +11,17 @@ export function ChargeNavigateButton(
|
|
|
10
11
|
): ReactElement {
|
|
11
12
|
return (
|
|
12
13
|
<Tooltip label="To Charge">
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
className={cn('size-7.5', props.className)}
|
|
20
|
-
variant="ghost"
|
|
14
|
+
<Link
|
|
15
|
+
to={ROUTES.CHARGES.DETAIL(props.chargeId)}
|
|
16
|
+
target="_blank"
|
|
17
|
+
rel="noreferrer"
|
|
18
|
+
onClick={event => event.stopPropagation()}
|
|
19
|
+
className="inline-block"
|
|
21
20
|
>
|
|
22
|
-
<
|
|
23
|
-
|
|
21
|
+
<Button {...props} className={cn('size-7.5', props.className)} variant="ghost">
|
|
22
|
+
<ExternalLink className="size-5" />
|
|
23
|
+
</Button>
|
|
24
|
+
</Link>
|
|
24
25
|
</Tooltip>
|
|
25
26
|
);
|
|
26
27
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import { useQuery } from 'urql';
|
|
3
|
+
import { ROUTES } from '@/router/routes.js';
|
|
3
4
|
import { Loader } from '@mantine/core';
|
|
4
5
|
import { EditChargeDocument } from '../../../gql/graphql.js';
|
|
5
|
-
import { getChargeHref } from '../../screens/charges/charge.js';
|
|
6
6
|
import { CopyToClipboardButton, EditCharge, PopUpDrawer } from '../index.js';
|
|
7
7
|
|
|
8
8
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
@@ -89,7 +89,7 @@ export const EditChargeModalContent = ({
|
|
|
89
89
|
ID: {chargeId}
|
|
90
90
|
<CopyToClipboardButton
|
|
91
91
|
isLink
|
|
92
|
-
content={`${window.location.origin}${
|
|
92
|
+
content={`${window.location.origin}${ROUTES.CHARGES.DETAIL(chargeId)}`}
|
|
93
93
|
/>
|
|
94
94
|
</div>
|
|
95
95
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ROUTES } from '@/router/routes.js';
|
|
3
3
|
import { CopyToClipboardButton, InsertDocument, PopUpDrawer } from '../index.js';
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
@@ -24,7 +24,7 @@ export const InsertDocumentModal = ({
|
|
|
24
24
|
Charge ID: {chargeId}
|
|
25
25
|
<CopyToClipboardButton
|
|
26
26
|
isLink
|
|
27
|
-
content={`${window.location.origin}${
|
|
27
|
+
content={`${window.location.origin}${ROUTES.CHARGES.DETAIL(chargeId)}`}
|
|
28
28
|
/>
|
|
29
29
|
</div>
|
|
30
30
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ROUTES } from '@/router/routes.js';
|
|
3
3
|
import { DocumentsToChargeMatcher } from '../documents-to-charge-matcher/index.js';
|
|
4
4
|
import { CopyToClipboardButton, PopUpDrawer } from '../index.js';
|
|
5
5
|
|
|
@@ -25,7 +25,7 @@ export const MatchDocumentModal = ({
|
|
|
25
25
|
Charge ID: {chargeId}
|
|
26
26
|
<CopyToClipboardButton
|
|
27
27
|
isLink
|
|
28
|
-
content={`${window.location.origin}${
|
|
28
|
+
content={`${window.location.origin}${ROUTES.CHARGES.DETAIL(chargeId)}`}
|
|
29
29
|
/>
|
|
30
30
|
</div>
|
|
31
31
|
</div>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
|
+
import { ROUTES } from '@/router/routes.js';
|
|
3
4
|
import { NewFetchedDocumentFieldsFragmentDoc } from '../../gql/graphql.js';
|
|
4
5
|
import { getFragmentData, type FragmentType } from '../../gql/index.js';
|
|
5
|
-
import { getChargeHref } from '../screens/charges/charge.js';
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
8
8
|
/* GraphQL */ `
|
|
@@ -34,7 +34,7 @@ export const NewDocumentsList = ({ data }: Props): ReactElement => {
|
|
|
34
34
|
.map(doc => (
|
|
35
35
|
<Link
|
|
36
36
|
key={doc.id}
|
|
37
|
-
to={
|
|
37
|
+
to={ROUTES.CHARGES.DETAIL(doc.charge!.id)}
|
|
38
38
|
target="_blank"
|
|
39
39
|
rel="noreferrer"
|
|
40
40
|
onClick={event => event.stopPropagation()}
|
|
@@ -3,9 +3,8 @@ import { Link } from 'react-router-dom';
|
|
|
3
3
|
import { DocumentType } from '@/gql/graphql.js';
|
|
4
4
|
import { useGetBusinesses } from '@/hooks/use-get-businesses.js';
|
|
5
5
|
import { useUpdateDocument } from '@/hooks/use-update-document.js';
|
|
6
|
-
import {
|
|
6
|
+
import { ROUTES } from '@/router/routes.js';
|
|
7
7
|
import { Indicator } from '@mantine/core';
|
|
8
|
-
import { getBusinessHref } from '../../charges/helpers.js';
|
|
9
8
|
import { ConfirmMiniButton, InsertBusiness, SelectWithSearch } from '../../common/index.js';
|
|
10
9
|
import type { DocumentsTableRowType } from '../columns.js';
|
|
11
10
|
|
|
@@ -20,7 +19,6 @@ type Props = {
|
|
|
20
19
|
};
|
|
21
20
|
|
|
22
21
|
export const Creditor = ({ document, onChange }: Props): ReactElement => {
|
|
23
|
-
const { get } = useUrlQuery();
|
|
24
22
|
const dbCreditor = 'creditor' in document ? document.creditor : undefined;
|
|
25
23
|
|
|
26
24
|
const shouldHaveCreditor =
|
|
@@ -30,13 +28,6 @@ export const Creditor = ({ document, onChange }: Props): ReactElement => {
|
|
|
30
28
|
|
|
31
29
|
const { selectableBusinesses, refresh: refreshBusinesses } = useGetBusinesses();
|
|
32
30
|
|
|
33
|
-
const encodedFilters = get('chargesFilters');
|
|
34
|
-
|
|
35
|
-
const getHref = useCallback(
|
|
36
|
-
(businessId: string) => getBusinessHref(businessId, encodedFilters as string),
|
|
37
|
-
[encodedFilters],
|
|
38
|
-
);
|
|
39
|
-
|
|
40
31
|
const suggestedCreditor = useMemo(() => {
|
|
41
32
|
if (dbCreditor || !('missingInfoSuggestions' in document) || !document.missingInfoSuggestions) {
|
|
42
33
|
// case when creditor is already set or no suggestions
|
|
@@ -106,7 +97,7 @@ export const Creditor = ({ document, onChange }: Props): ReactElement => {
|
|
|
106
97
|
{shouldHaveCreditor &&
|
|
107
98
|
(id ? (
|
|
108
99
|
<Link
|
|
109
|
-
to={
|
|
100
|
+
to={ROUTES.BUSINESSES.DETAIL(id)}
|
|
110
101
|
target="_blank"
|
|
111
102
|
rel="noreferrer"
|
|
112
103
|
onClick={event => event.stopPropagation()}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { useCallback, useMemo, useState, type ReactElement } from 'react';
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
3
|
import { useGetBusinesses } from '@/hooks/use-get-businesses.js';
|
|
4
|
+
import { ROUTES } from '@/router/routes.js';
|
|
4
5
|
import { Indicator } from '@mantine/core';
|
|
5
6
|
import { DocumentType } from '../../../gql/graphql.js';
|
|
6
7
|
import { useUpdateDocument } from '../../../hooks/use-update-document.js';
|
|
7
|
-
import { useUrlQuery } from '../../../hooks/use-url-query.js';
|
|
8
|
-
import { getBusinessHref } from '../../charges/helpers.js';
|
|
9
8
|
import { ConfirmMiniButton, InsertBusiness, SelectWithSearch } from '../../common/index.js';
|
|
10
9
|
import type { DocumentsTableRowType } from '../columns.js';
|
|
11
10
|
import { COUNTERPARTIES_LESS_DOCUMENT_TYPES } from './index.js';
|
|
@@ -16,7 +15,6 @@ type Props = {
|
|
|
16
15
|
};
|
|
17
16
|
|
|
18
17
|
export const Debtor = ({ document, onChange }: Props): ReactElement => {
|
|
19
|
-
const { get } = useUrlQuery();
|
|
20
18
|
const dbDebtor = 'debtor' in document ? document.debtor : undefined;
|
|
21
19
|
|
|
22
20
|
const shouldHaveDebtor =
|
|
@@ -26,13 +24,6 @@ export const Debtor = ({ document, onChange }: Props): ReactElement => {
|
|
|
26
24
|
|
|
27
25
|
const { selectableBusinesses, refresh: refreshBusinesses } = useGetBusinesses();
|
|
28
26
|
|
|
29
|
-
const encodedFilters = get('chargesFilters');
|
|
30
|
-
|
|
31
|
-
const getHref = useCallback(
|
|
32
|
-
(businessId: string) => getBusinessHref(businessId, encodedFilters as string),
|
|
33
|
-
[encodedFilters],
|
|
34
|
-
);
|
|
35
|
-
|
|
36
27
|
const suggestedDebtor = useMemo(() => {
|
|
37
28
|
if (dbDebtor || !('missingInfoSuggestions' in document) || !document.missingInfoSuggestions) {
|
|
38
29
|
// case when creditor is already set or no suggestions
|
|
@@ -102,7 +93,7 @@ export const Debtor = ({ document, onChange }: Props): ReactElement => {
|
|
|
102
93
|
{shouldHaveDebtor &&
|
|
103
94
|
(id ? (
|
|
104
95
|
<Link
|
|
105
|
-
to={
|
|
96
|
+
to={ROUTES.BUSINESSES.DETAIL(id)}
|
|
106
97
|
target="_blank"
|
|
107
98
|
rel="noreferrer"
|
|
108
99
|
onClick={event => event.stopPropagation()}
|