@accounter/client 0.0.8-alpha-20251029124401-d15137847e8450b1ecf3e3cfa6b68dda7239ca45 → 0.0.8-alpha-20251029124558-c1dac18cef0a90c88021bcb6e06319cc55ec33d9
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 +1 -1
- package/dist/assets/{Checkbox-Cxbop3qM.js → Checkbox-w99PhJ6L.js} +2 -2
- package/dist/assets/{MultiSelect-D1XVjXLN.js → MultiSelect-9BbcXHjB.js} +1 -1
- package/dist/assets/{Pagination-DMimIHM4.js → Pagination-BVQu3Yj6.js} +1 -1
- package/dist/assets/{Progress-CP4jnh2x.js → Progress-BKRQuJXK.js} +1 -1
- package/dist/assets/{Table-DTU12O53.js → Table-CR8S5Pp5.js} +1 -1
- package/dist/assets/{Typography-IL0wuZeq.js → Typography-D1_XzAPj.js} +1 -1
- package/dist/assets/{YearPickerInput-CPL_XozD.js → YearPickerInput-dCiPlZqk.js} +1 -1
- package/dist/assets/{accordion-DKLV9b0H.js → accordion-QkFWsf0a.js} +1 -1
- package/dist/assets/{accountant-approvals-CdX2nUgB.js → accountant-approvals-AD_TNBTH.js} +1 -1
- package/dist/assets/{accounter-table-CeZ4q0re.js → accounter-table-CBigzB_s.js} +1 -1
- package/dist/assets/{addDays-sGeEkIxC.js → addDays-CjlJbHpj.js} +1 -1
- package/dist/assets/{all-charges-BJvp1ecZ.js → all-charges-BdHR-QjC.js} +1 -1
- package/dist/assets/{arrow-up-down-DkEXGAin.js → arrow-up-down-Cq3mRkaO.js} +1 -1
- package/dist/assets/{building-2-BcYhLAVP.js → building-2-BE02hpsM.js} +1 -1
- package/dist/assets/{business-CO7M6XNI.js → business-CX0D-23F.js} +17 -7
- package/dist/assets/business-extended-info-BRde-LSv.js +13 -0
- package/dist/assets/{business-header-BG2B-PcM.js → business-header-CMH3yBZc.js} +1 -1
- package/dist/assets/business-ledger-filters-DQ4D4mv8.js +1 -0
- package/dist/assets/business-ledger-single-BSeNj9f2.js +1 -0
- package/dist/assets/business-trip-CX-3yJmB.js +1 -0
- package/dist/assets/{charge-Bm0hPNT7.js → charge-BzCN_Szu.js} +1 -1
- package/dist/assets/{charges-filters-DjnsiGzC.js → charges-filters-C7YlWAFn.js} +1 -1
- package/dist/assets/{charges-ledger-validation-CoHDjCf2.js → charges-ledger-validation-DqM92cc-.js} +1 -1
- package/dist/assets/charges-table-BOnvwci9.js +62 -0
- package/dist/assets/{chart-SbwWAyei.js → chart-OVHXA3Uy.js} +1 -1
- package/dist/assets/{data-table-pagination-DtnUvTOC.js → data-table-pagination-BLbPHs4o.js} +1 -1
- package/dist/assets/download-csv-button-C5J9ow3I.js +1 -0
- package/dist/assets/{editable-business-trip-xFRu5fSA.js → editable-business-trip-Ito1rWaY.js} +1 -1
- package/dist/assets/{funnel-WdA7f2As.js → funnel-IYKnhWOy.js} +1 -1
- package/dist/assets/{index-BOhdfO95.js → index-2j4tFkfX.js} +1 -1
- package/dist/assets/{index-VzPCd0L-.js → index-4YPOH-A_.js} +2 -2
- package/dist/assets/index-B3W0RNqC.js +1 -0
- package/dist/assets/{index-Vq1FAgYe.js → index-BOmTn4-L.js} +1 -1
- package/dist/assets/{index-BaEmw40f.js → index-C8HkbFzQ.js} +1 -1
- package/dist/assets/{index-9JObwNSb.js → index-CP5LZIWs.js} +1 -1
- package/dist/assets/{index-Ct0AJEN9.js → index-CY5Ok8zP.js} +2 -2
- package/dist/assets/{index-DPvrbbz9.js → index-CcJvt1sI.js} +119 -119
- package/dist/assets/{index-BIdEjDD3.js → index-Cn-lknzD.js} +1 -1
- package/dist/assets/{index-Ey6XKYuP.js → index-CnlrBGcj.js} +2 -2
- package/dist/assets/{index-1loWF1jV.js → index-D1Hpe746.js} +1 -1
- package/dist/assets/{index-BxnmQCT9.js → index-D31j2-8X.js} +1 -1
- package/dist/assets/{index-mN2sZqiu.js → index-D68aCDMG.js} +7 -7
- package/dist/assets/index-DE0nwhFR.js +1 -0
- package/dist/assets/{index-CwbqTlM4.js → index-DGxxgGxy.js} +2 -2
- package/dist/assets/{index-W6Xv87pg.js → index-DKVhuSlP.js} +1 -1
- package/dist/assets/{index-DjQIiDMo.js → index-DeFWFAwx.js} +1 -1
- package/dist/assets/{index-Bw5hpWBz.js → index-DjPei962.js} +2 -2
- package/dist/assets/{index-CdAUtS2Q.js → index-Dvp0RPEc.js} +1 -1
- package/dist/assets/{index-CfsTscFv.js → index-a32atud-.js} +1 -1
- package/dist/assets/{index-CXH_lcpK.js → index-kSig9eXf.js} +2 -2
- package/dist/assets/index-ofME77ND.js +6 -0
- package/dist/assets/{index-Bm3ZL2dx.js → index-ofu4jqHf.js} +1 -1
- package/dist/assets/{index--LMZMPY_.js → index-qLJISPWb.js} +1 -1
- package/dist/assets/{index-p1BcqxXQ.js → index-smNUtwvf.js} +1 -1
- package/dist/assets/{index.es-C3XngPKv.js → index.es-D7_nzQqR.js} +1 -1
- package/dist/assets/{insert-business-trip-modal-BHY3QQup.js → insert-business-trip-modal-D08ePEzY.js} +2 -2
- package/dist/assets/issue-document-D2L9kG1u.js +1 -0
- package/dist/assets/{list-plus-ZvPwjqZn.js → list-plus-Cv8qnwZd.js} +1 -1
- package/dist/assets/{login-page-CsXdm3AZ.js → login-page-sUXp3XoV.js} +1 -1
- package/dist/assets/{match-document-modal-Cqimg0VE.js → match-document-modal-D2TgC0aR.js} +4 -4
- package/dist/assets/{missing-info-charges-DxLGt6Xs.js → missing-info-charges-BJnQHRZs.js} +1 -1
- package/dist/assets/{modal-Nvfe-DMu.js → modal-DOtlViK5.js} +1 -1
- package/dist/assets/{page-layout-SHFb6rY4.js → page-layout-BNHKLJFL.js} +1 -1
- package/dist/assets/{page-not-found-BZ6s-Q5n.js → page-not-found-j9vQhz-c.js} +1 -1
- package/dist/assets/{panel-top-open-C3Q9X7Tg.js → panel-top-open-DQ1wo5PZ.js} +1 -1
- package/dist/assets/{pencil-CPPx1BhC.js → pencil-BWTnh6hj.js} +1 -1
- package/dist/assets/{report-commentary-row-DpYgprQr.js → report-commentary-row-DBOCwi7X.js} +1 -1
- package/dist/assets/{save-D-W46u2J.js → save-DuIXDTLc.js} +1 -1
- package/dist/assets/{similar-transactions-modal-zQY2R-sr.js → similar-transactions-modal-DDVojjq0.js} +1 -1
- package/dist/assets/sub-CIKovQuv.js +1 -0
- package/dist/assets/subMonths-GbNm9rnx.js +1 -0
- package/dist/assets/{summary-DwX_dmjr.js → summary-BV3HUEgI.js} +1 -1
- package/dist/assets/{toggle-expansion-button-Bh24n-cz.js → toggle-expansion-button-Bdpb_YfG.js} +1 -1
- package/dist/assets/tooltip-Cy3vJ3fy.js +1 -0
- package/dist/assets/{use-url-query-COmN7DHP.js → use-url-query-D-GsTMWL.js} +1 -1
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/src/components/business/balance-section.tsx +26 -0
- package/src/components/business/index.tsx +31 -1
- package/src/components/business/ledger-section.tsx +49 -0
- package/src/components/business/transactions-section.tsx +24 -2
- package/src/components/{business-transactions → business-ledger}/business-extended-info.tsx +25 -27
- package/src/components/{business-transactions/business-transactions-filters.tsx → business-ledger/business-ledger-filters.tsx} +12 -12
- package/src/components/{business-transactions/business-transactions-single.tsx → business-ledger/business-ledger-single.tsx} +13 -13
- package/src/components/{business-transactions → business-ledger}/download-csv.tsx +25 -25
- package/src/components/{business-transactions → business-ledger}/index.tsx +15 -15
- package/src/components/charges/charge-extended-info.tsx +45 -4
- package/src/components/layout/sidelinks.tsx +2 -2
- package/src/components/ledger-table/columns.tsx +4 -4
- package/src/components/ledger-table/index.tsx +141 -181
- package/src/components/reports/conto/custom-node.tsx +1 -1
- package/src/components/reports/trial-balance-report/trial-balance-report-account.tsx +1 -1
- package/src/components/transactions-table/columns.tsx +9 -9
- package/src/components/transactions-table/index.tsx +45 -21
- package/src/gql/gql.ts +30 -12
- package/src/gql/graphql.ts +181 -406
- package/src/router/config.tsx +14 -14
- package/src/router/routes.ts +2 -2
- package/dist/assets/business-extended-info-MUfOmQ_B.js +0 -13
- package/dist/assets/business-transactions-filters-Cijy7ryl.js +0 -1
- package/dist/assets/business-transactions-single-DZqMwNkv.js +0 -1
- package/dist/assets/business-trip-C7G814AY.js +0 -1
- package/dist/assets/charges-table-C_4dY1Ic.js +0 -62
- package/dist/assets/download-csv-button-D9_6J2pA.js +0 -1
- package/dist/assets/index-Bx-qi8fd.js +0 -1
- package/dist/assets/index-D3-tv-Kb.js +0 -1
- package/dist/assets/index-DFgRsYAU.js +0 -6
- package/dist/assets/issue-document-BpzcqnRu.js +0 -1
- package/dist/assets/sub-7frHBT3Y.js +0 -1
- package/dist/assets/subMonths-CY79vHaS.js +0 -1
- package/dist/assets/tooltip-BaULIFLC.js +0 -1
- package/src/app.tsx +0 -108
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { useContext, type ReactElement } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
ArrowLeftRight,
|
|
4
4
|
Building2,
|
|
5
|
+
ChartLine,
|
|
5
6
|
DollarSign,
|
|
6
7
|
FileCheck,
|
|
7
8
|
FileText,
|
|
9
|
+
Notebook,
|
|
8
10
|
Plug,
|
|
9
11
|
Settings,
|
|
10
12
|
Shield,
|
|
@@ -13,8 +15,10 @@ import {
|
|
|
13
15
|
import { useSearchParams } from 'react-router-dom';
|
|
14
16
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs.js';
|
|
15
17
|
import { getFragmentData, type FragmentType } from '@/gql/index.js';
|
|
18
|
+
import { FiltersContext } from '@/providers/filters-context.js';
|
|
16
19
|
import { BusinessPageFragmentDoc } from '../../gql/graphql.js';
|
|
17
20
|
import { AdminBusinessSection } from './admin-business-section.js';
|
|
21
|
+
import { BalanceSection } from './balance-section.js';
|
|
18
22
|
import { BusinessHeader } from './business-header.js';
|
|
19
23
|
import { ChargesSection } from './charges-section.jsx';
|
|
20
24
|
import { ChartsSection } from './charts-section.jsx';
|
|
@@ -23,6 +27,7 @@ import { ContactInfoSection } from './contact-info-section.jsx';
|
|
|
23
27
|
import { ContractsSection } from './contracts-section.jsx';
|
|
24
28
|
import { DocumentsSection } from './documents-section.jsx';
|
|
25
29
|
import { IntegrationsSection } from './integrations-section.jsx';
|
|
30
|
+
import { LedgerSection } from './ledger-section.js';
|
|
26
31
|
import { TransactionsSection } from './transactions-section.js';
|
|
27
32
|
|
|
28
33
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
@@ -53,6 +58,9 @@ interface Props {
|
|
|
53
58
|
export default function Business({ data, refetchBusiness }: Props): ReactElement {
|
|
54
59
|
const business = getFragmentData(BusinessPageFragmentDoc, data);
|
|
55
60
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
61
|
+
const { setFiltersContext } = useContext(FiltersContext);
|
|
62
|
+
|
|
63
|
+
setFiltersContext(null);
|
|
56
64
|
|
|
57
65
|
const activeTab = searchParams.get('tab') || 'contact';
|
|
58
66
|
|
|
@@ -109,6 +117,20 @@ export default function Business({ data, refetchBusiness }: Props): ReactElement
|
|
|
109
117
|
<FileText className="h-4 w-4" />
|
|
110
118
|
<span className="hidden sm:inline">Documents</span>
|
|
111
119
|
</TabsTrigger>
|
|
120
|
+
<TabsTrigger
|
|
121
|
+
value="ledger"
|
|
122
|
+
className="flex items-center gap-2 data-[state=active]:bg-background"
|
|
123
|
+
>
|
|
124
|
+
<Notebook className="h-4 w-4" />
|
|
125
|
+
<span className="hidden sm:inline">Ledger</span>
|
|
126
|
+
</TabsTrigger>
|
|
127
|
+
<TabsTrigger
|
|
128
|
+
value="balance"
|
|
129
|
+
className="flex items-center gap-2 data-[state=active]:bg-background"
|
|
130
|
+
>
|
|
131
|
+
<ChartLine className="h-4 w-4" />
|
|
132
|
+
<span className="hidden sm:inline">Balance</span>
|
|
133
|
+
</TabsTrigger>
|
|
112
134
|
{isClient && (
|
|
113
135
|
<>
|
|
114
136
|
<TabsTrigger
|
|
@@ -165,6 +187,14 @@ export default function Business({ data, refetchBusiness }: Props): ReactElement
|
|
|
165
187
|
<DocumentsSection businessId={business.id} />
|
|
166
188
|
</TabsContent>
|
|
167
189
|
|
|
190
|
+
<TabsContent value="ledger" className="mt-0">
|
|
191
|
+
<LedgerSection businessId={business.id} />
|
|
192
|
+
</TabsContent>
|
|
193
|
+
|
|
194
|
+
<TabsContent value="balance" className="mt-0">
|
|
195
|
+
<BalanceSection businessId={business.id} />
|
|
196
|
+
</TabsContent>
|
|
197
|
+
|
|
168
198
|
{isClient && (
|
|
169
199
|
<>
|
|
170
200
|
<TabsContent value="contracts" className="mt-0">
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { useQuery } from 'urql';
|
|
2
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card.js';
|
|
3
|
+
import { BusinessLedgerSectionDocument } from '@/gql/graphql.js';
|
|
4
|
+
import { LedgerTable } from '../ledger-table';
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
7
|
+
/* GraphQL */ `
|
|
8
|
+
query BusinessLedgerSection($businessId: UUID!) {
|
|
9
|
+
ledgerRecordsByFinancialEntity(financialEntityId: $businessId) {
|
|
10
|
+
id
|
|
11
|
+
...LedgerRecordsTableFields
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
interface Props {
|
|
17
|
+
businessId: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function LedgerSection({ businessId }: Props) {
|
|
21
|
+
const [{ data, fetching }] = useQuery({
|
|
22
|
+
query: BusinessLedgerSectionDocument,
|
|
23
|
+
variables: {
|
|
24
|
+
businessId,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (fetching) {
|
|
29
|
+
return <div>Loading ledger records...</div>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Card>
|
|
34
|
+
<CardHeader className="flex w-full justify-between items-center">
|
|
35
|
+
<div className="flex items-center justify-between">
|
|
36
|
+
<div>
|
|
37
|
+
<CardTitle>Ledger Records</CardTitle>
|
|
38
|
+
<CardDescription>Complete ledger history for this business</CardDescription>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</CardHeader>
|
|
42
|
+
<CardContent>
|
|
43
|
+
<div className="rounded-md border">
|
|
44
|
+
<LedgerTable ledgerRecordsData={data?.ledgerRecordsByFinancialEntity ?? []} />
|
|
45
|
+
</div>
|
|
46
|
+
</CardContent>
|
|
47
|
+
</Card>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -1,11 +1,33 @@
|
|
|
1
|
+
import { useQuery } from 'urql';
|
|
1
2
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card.js';
|
|
2
|
-
import {
|
|
3
|
+
import { BusinessTransactionsSectionDocument } from '@/gql/graphql.js';
|
|
4
|
+
import { TransactionsTable } from '../transactions-table';
|
|
3
5
|
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
7
|
+
/* GraphQL */ `
|
|
8
|
+
query BusinessTransactionsSection($businessId: UUID!) {
|
|
9
|
+
transactionsByFinancialEntity(financialEntityID: $businessId) {
|
|
10
|
+
id
|
|
11
|
+
...TransactionForTransactionsTableFields
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
`;
|
|
4
15
|
interface Props {
|
|
5
16
|
businessId: string;
|
|
6
17
|
}
|
|
7
18
|
|
|
8
19
|
export function TransactionsSection({ businessId }: Props) {
|
|
20
|
+
const [{ data, fetching }] = useQuery({
|
|
21
|
+
query: BusinessTransactionsSectionDocument,
|
|
22
|
+
variables: {
|
|
23
|
+
businessId,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
if (fetching) {
|
|
28
|
+
return <div>Loading transactions...</div>;
|
|
29
|
+
}
|
|
30
|
+
|
|
9
31
|
return (
|
|
10
32
|
<Card>
|
|
11
33
|
<CardHeader className="flex w-full justify-between items-center">
|
|
@@ -18,7 +40,7 @@ export function TransactionsSection({ businessId }: Props) {
|
|
|
18
40
|
</CardHeader>
|
|
19
41
|
<CardContent>
|
|
20
42
|
<div className="rounded-md border">
|
|
21
|
-
<
|
|
43
|
+
<TransactionsTable transactionsProps={data?.transactionsByFinancialEntity ?? []} />
|
|
22
44
|
</div>
|
|
23
45
|
</CardContent>
|
|
24
46
|
</Card>
|
|
@@ -6,10 +6,10 @@ import { useQuery } from 'urql';
|
|
|
6
6
|
import { ROUTES } from '@/router/routes.js';
|
|
7
7
|
import { Mark, Table, Tooltip } from '@mantine/core';
|
|
8
8
|
import {
|
|
9
|
-
|
|
9
|
+
BusinessLedgerInfoDocument,
|
|
10
10
|
Currency,
|
|
11
|
+
type BusinessLedgerInfoQuery,
|
|
11
12
|
type BusinessTransactionsFilter,
|
|
12
|
-
type BusinessTransactionsInfoQuery,
|
|
13
13
|
} from '../../gql/graphql.js';
|
|
14
14
|
import { FIAT_CURRENCIES, formatAmountWithCurrency } from '../../helpers/index.js';
|
|
15
15
|
import { AccounterLoader } from '../common/index.js';
|
|
@@ -18,7 +18,7 @@ import { DownloadCSV } from './download-csv.js';
|
|
|
18
18
|
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
20
20
|
/* GraphQL */ `
|
|
21
|
-
query
|
|
21
|
+
query BusinessLedgerInfo($filters: BusinessTransactionsFilter) {
|
|
22
22
|
businessTransactionsFromLedgerRecords(filters: $filters) {
|
|
23
23
|
... on BusinessTransactionsFromLedgerRecordsSuccessfulResult {
|
|
24
24
|
businessTransactions {
|
|
@@ -54,8 +54,8 @@ import { DownloadCSV } from './download-csv.js';
|
|
|
54
54
|
}
|
|
55
55
|
`;
|
|
56
56
|
|
|
57
|
-
export type
|
|
58
|
-
|
|
57
|
+
export type ExtendedLedger = Extract<
|
|
58
|
+
BusinessLedgerInfoQuery['businessTransactionsFromLedgerRecords'],
|
|
59
59
|
{ __typename?: 'BusinessTransactionsFromLedgerRecordsSuccessfulResult' }
|
|
60
60
|
>['businessTransactions'][number] & {
|
|
61
61
|
ilsBalance: number;
|
|
@@ -71,7 +71,7 @@ export function BusinessExtendedInfo({ businessID, filter }: Props): ReactElemen
|
|
|
71
71
|
const [isExtendAllCurrencies, setISExtendAllCurrencies] = useState(false);
|
|
72
72
|
const { fromDate, ownerIds, toDate } = filter ?? {};
|
|
73
73
|
const [{ data, fetching }] = useQuery({
|
|
74
|
-
query:
|
|
74
|
+
query: BusinessLedgerInfoDocument,
|
|
75
75
|
variables: {
|
|
76
76
|
filters: {
|
|
77
77
|
fromDate,
|
|
@@ -82,44 +82,42 @@ export function BusinessExtendedInfo({ businessID, filter }: Props): ReactElemen
|
|
|
82
82
|
},
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
const
|
|
85
|
+
const ledgerRecords =
|
|
86
86
|
data?.businessTransactionsFromLedgerRecords.__typename === 'CommonError'
|
|
87
87
|
? []
|
|
88
88
|
: (data?.businessTransactionsFromLedgerRecords.businessTransactions.sort((a, b) =>
|
|
89
89
|
a.invoiceDate > b.invoiceDate ? 1 : -1,
|
|
90
90
|
) ?? []);
|
|
91
91
|
|
|
92
|
-
const
|
|
93
|
-
for (let i = 0; i <
|
|
94
|
-
const { __typename, ...
|
|
92
|
+
const extendedLedgerRecords: Array<ExtendedLedger> = [];
|
|
93
|
+
for (let i = 0; i < ledgerRecords.length; i++) {
|
|
94
|
+
const { __typename, ...coreRecord } = ledgerRecords[i];
|
|
95
95
|
const ilsBalance =
|
|
96
96
|
i === 0
|
|
97
|
-
?
|
|
98
|
-
: (
|
|
97
|
+
? coreRecord.amount.raw
|
|
98
|
+
: (extendedLedgerRecords[i - 1].ilsBalance ?? 0) + coreRecord.amount.raw;
|
|
99
99
|
const foreignCurrenciesBalance: Record<string, number> = {};
|
|
100
100
|
Object.values(Currency).map(currency => {
|
|
101
101
|
if (currency !== Currency.Ils) {
|
|
102
102
|
const key = `${currency.toLowerCase()}Balance`;
|
|
103
103
|
foreignCurrenciesBalance[key] =
|
|
104
104
|
i === 0
|
|
105
|
-
? ((
|
|
106
|
-
?
|
|
105
|
+
? ((coreRecord.foreignAmount?.currency === currency
|
|
106
|
+
? coreRecord.foreignAmount?.raw
|
|
107
107
|
: 0) ?? 0)
|
|
108
|
-
: (
|
|
109
|
-
(
|
|
110
|
-
? coreTransaction.foreignAmount?.raw
|
|
111
|
-
: 0);
|
|
108
|
+
: (extendedLedgerRecords[i - 1]?.[key] ?? 0) +
|
|
109
|
+
(coreRecord.foreignAmount?.currency === currency ? coreRecord.foreignAmount?.raw : 0);
|
|
112
110
|
}
|
|
113
111
|
});
|
|
114
|
-
|
|
115
|
-
...
|
|
112
|
+
extendedLedgerRecords.push({
|
|
113
|
+
...coreRecord,
|
|
116
114
|
ilsBalance,
|
|
117
115
|
...foreignCurrenciesBalance,
|
|
118
|
-
} as (typeof
|
|
116
|
+
} as (typeof extendedLedgerRecords)[number]);
|
|
119
117
|
}
|
|
120
118
|
|
|
121
119
|
const currencies = new Set(
|
|
122
|
-
|
|
120
|
+
ledgerRecords.filter(t => t.foreignAmount?.currency).map(t => t.foreignAmount!.currency),
|
|
123
121
|
);
|
|
124
122
|
const isEur = isExtendAllCurrencies || currencies.has(Currency.Eur);
|
|
125
123
|
const isUsd = isExtendAllCurrencies || currencies.has(Currency.Usd);
|
|
@@ -129,7 +127,7 @@ export function BusinessExtendedInfo({ businessID, filter }: Props): ReactElemen
|
|
|
129
127
|
const isAud = isExtendAllCurrencies || currencies.has(Currency.Aud);
|
|
130
128
|
const isSek = isExtendAllCurrencies || currencies.has(Currency.Sek);
|
|
131
129
|
|
|
132
|
-
const businessName =
|
|
130
|
+
const businessName = ledgerRecords[0]?.business.name ?? 'unknown';
|
|
133
131
|
|
|
134
132
|
return (
|
|
135
133
|
<div className="flex flex-row gap-5">
|
|
@@ -216,7 +214,7 @@ export function BusinessExtendedInfo({ businessID, filter }: Props): ReactElemen
|
|
|
216
214
|
<th>Counter Account</th>
|
|
217
215
|
<th>
|
|
218
216
|
<DownloadCSV
|
|
219
|
-
|
|
217
|
+
ledgerRecords={extendedLedgerRecords}
|
|
220
218
|
businessName={businessName}
|
|
221
219
|
fromDate={filter?.fromDate ?? undefined}
|
|
222
220
|
toDate={filter?.toDate ?? undefined}
|
|
@@ -225,7 +223,7 @@ export function BusinessExtendedInfo({ businessID, filter }: Props): ReactElemen
|
|
|
225
223
|
</tr>
|
|
226
224
|
</thead>
|
|
227
225
|
<tbody>
|
|
228
|
-
{
|
|
226
|
+
{extendedLedgerRecords.map((row, index) => (
|
|
229
227
|
<tr
|
|
230
228
|
key={index}
|
|
231
229
|
className="cursor-pointer"
|
|
@@ -299,7 +297,7 @@ export function CurrencyCells({
|
|
|
299
297
|
data,
|
|
300
298
|
}: {
|
|
301
299
|
currency: Currency;
|
|
302
|
-
data:
|
|
300
|
+
data: ExtendedLedger;
|
|
303
301
|
}): ReactElement {
|
|
304
302
|
const foreignAmount =
|
|
305
303
|
data.foreignAmount && data.foreignAmount.currency === currency ? data.foreignAmount : null;
|
|
@@ -329,7 +327,7 @@ const currenciesToExtend = Object.values(Currency).filter(
|
|
|
329
327
|
currency => !FIAT_CURRENCIES.includes(currency),
|
|
330
328
|
);
|
|
331
329
|
|
|
332
|
-
export function ExtendedCurrencyCells({ data }: { data:
|
|
330
|
+
export function ExtendedCurrencyCells({ data }: { data: ExtendedLedger }): ReactElement {
|
|
333
331
|
return (
|
|
334
332
|
<>
|
|
335
333
|
{currenciesToExtend.map(currency => (
|
|
@@ -9,29 +9,29 @@ import { type BusinessTransactionsFilter } from '../../gql/graphql.js';
|
|
|
9
9
|
import { isObjectEmpty, TIMELESS_DATE_REGEX } from '../../helpers/index.js';
|
|
10
10
|
import { useGetBusinesses } from '../../hooks/use-get-businesses.js';
|
|
11
11
|
import { useUrlQuery } from '../../hooks/use-url-query.js';
|
|
12
|
-
import { UserContext } from '../../providers/user-provider.
|
|
12
|
+
import { UserContext } from '../../providers/user-provider.jsx';
|
|
13
13
|
import { PopUpModal } from '../common/index.js';
|
|
14
|
-
import { Button } from '../ui/button.
|
|
14
|
+
import { Button } from '../ui/button.jsx';
|
|
15
15
|
|
|
16
|
-
export function
|
|
16
|
+
export function encodeLedgerRecordsFilters(
|
|
17
17
|
filter?: BusinessTransactionsFilter | null,
|
|
18
18
|
): string | null {
|
|
19
19
|
return !filter || isObjectEmpty(filter) ? null : encodeURIComponent(JSON.stringify(filter));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
interface
|
|
22
|
+
interface BusinessLedgerRecordsFilterFormProps {
|
|
23
23
|
filter: BusinessTransactionsFilter;
|
|
24
24
|
setFilter: (filter: BusinessTransactionsFilter) => void;
|
|
25
25
|
closeModal: () => void;
|
|
26
26
|
single?: boolean;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function
|
|
29
|
+
function BusinessLedgerRecordsFilterForm({
|
|
30
30
|
filter,
|
|
31
31
|
setFilter,
|
|
32
32
|
closeModal,
|
|
33
33
|
single = false,
|
|
34
|
-
}:
|
|
34
|
+
}: BusinessLedgerRecordsFilterFormProps): ReactElement {
|
|
35
35
|
const { control, handleSubmit } = useForm<BusinessTransactionsFilter>({
|
|
36
36
|
defaultValues: { ...filter },
|
|
37
37
|
});
|
|
@@ -199,15 +199,15 @@ function BusinessTransactionsFilterForm({
|
|
|
199
199
|
);
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
interface
|
|
202
|
+
interface BusinessLedgerRecordsFilterProps {
|
|
203
203
|
filter: BusinessTransactionsFilter;
|
|
204
204
|
setFilter: (filter: BusinessTransactionsFilter) => void;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
export function
|
|
207
|
+
export function BusinessLedgerRecordsFilters({
|
|
208
208
|
filter,
|
|
209
209
|
setFilter,
|
|
210
|
-
}:
|
|
210
|
+
}: BusinessLedgerRecordsFilterProps): ReactElement {
|
|
211
211
|
const [opened, setOpened] = useState(false);
|
|
212
212
|
const [isFiltered, setIsFiltered] = useState(!isObjectEmpty(filter));
|
|
213
213
|
const { get, set } = useUrlQuery();
|
|
@@ -232,9 +232,9 @@ export function BusinessTransactionsFilters({
|
|
|
232
232
|
// update url on filter change
|
|
233
233
|
useEffect(() => {
|
|
234
234
|
const newFilter = isObjectEmpty(filter) ? null : encodeURIComponent(JSON.stringify(filter));
|
|
235
|
-
const oldFilter = get('
|
|
235
|
+
const oldFilter = get('ledgerRecordsFilters');
|
|
236
236
|
if (newFilter !== oldFilter) {
|
|
237
|
-
set('
|
|
237
|
+
set('ledgerRecordsFilters', newFilter);
|
|
238
238
|
}
|
|
239
239
|
}, [filter, get, set]);
|
|
240
240
|
|
|
@@ -244,7 +244,7 @@ export function BusinessTransactionsFilters({
|
|
|
244
244
|
opened={opened}
|
|
245
245
|
onClose={(): void => setOpened(false)}
|
|
246
246
|
content={
|
|
247
|
-
<
|
|
247
|
+
<BusinessLedgerRecordsFilterForm
|
|
248
248
|
single
|
|
249
249
|
filter={filter}
|
|
250
250
|
setFilter={onSetFilter}
|
|
@@ -3,31 +3,31 @@ import { useParams } from 'react-router-dom';
|
|
|
3
3
|
import { useQuery } from 'urql';
|
|
4
4
|
import { Mark } from '@mantine/core';
|
|
5
5
|
import {
|
|
6
|
-
|
|
6
|
+
BusinessLedgerRecordsSummeryDocument,
|
|
7
7
|
Currency,
|
|
8
|
+
type BusinessLedgerRecordsSummeryQuery,
|
|
8
9
|
type BusinessTransactionsFilter,
|
|
9
|
-
type BusinessTransactionsSummeryQuery,
|
|
10
10
|
} from '../../gql/graphql.js';
|
|
11
11
|
import { useUrlQuery } from '../../hooks/use-url-query.js';
|
|
12
12
|
import { FiltersContext } from '../../providers/filters-context.js';
|
|
13
13
|
import { AccounterLoader, AccounterTable } from '../common/index.js';
|
|
14
14
|
import { BusinessExtendedInfo } from './business-extended-info.js';
|
|
15
|
-
import {
|
|
15
|
+
import { BusinessLedgerRecordsFilters } from './business-ledger-filters.js';
|
|
16
16
|
|
|
17
17
|
type Props = {
|
|
18
18
|
businessId?: string;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
export const
|
|
21
|
+
export const BusinessLedgerRecordsSingle = ({ businessId }: Props): ReactElement => {
|
|
22
22
|
const { businessId: businessIdFromUrl } = useParams<{ businessId: string }>();
|
|
23
23
|
const { get } = useUrlQuery();
|
|
24
24
|
const { setFiltersContext } = useContext(FiltersContext);
|
|
25
25
|
const id = businessId || businessIdFromUrl;
|
|
26
26
|
const [filter, setFilter] = useState<BusinessTransactionsFilter>(
|
|
27
|
-
get('
|
|
27
|
+
get('ledgerRecordsFilters')
|
|
28
28
|
? {
|
|
29
29
|
...(JSON.parse(
|
|
30
|
-
decodeURIComponent(get('
|
|
30
|
+
decodeURIComponent(get('ledgerRecordsFilters') as string),
|
|
31
31
|
) as BusinessTransactionsFilter),
|
|
32
32
|
businessIDs: id ? [id] : [],
|
|
33
33
|
}
|
|
@@ -36,17 +36,17 @@ export const BusinessTransactionsSingle = ({ businessId }: Props): ReactElement
|
|
|
36
36
|
},
|
|
37
37
|
);
|
|
38
38
|
const [{ data, fetching }] = useQuery({
|
|
39
|
-
query:
|
|
39
|
+
query: BusinessLedgerRecordsSummeryDocument,
|
|
40
40
|
variables: {
|
|
41
41
|
filters: filter,
|
|
42
42
|
},
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
useEffect(() => {
|
|
46
|
-
setFiltersContext(<
|
|
46
|
+
setFiltersContext(<BusinessLedgerRecordsFilters filter={filter} setFilter={setFilter} />);
|
|
47
47
|
}, [data, filter, setFiltersContext, setFilter]);
|
|
48
48
|
|
|
49
|
-
const
|
|
49
|
+
const businessLedgerRecordsSum = useMemo(() => {
|
|
50
50
|
if (data?.businessTransactionsSumFromLedgerRecords.__typename === 'CommonError') {
|
|
51
51
|
return [];
|
|
52
52
|
}
|
|
@@ -68,7 +68,7 @@ export const BusinessTransactionsSingle = ({ businessId }: Props): ReactElement
|
|
|
68
68
|
striped
|
|
69
69
|
highlightOnHover
|
|
70
70
|
stickyHeader
|
|
71
|
-
items={
|
|
71
|
+
items={businessLedgerRecordsSum}
|
|
72
72
|
columns={[
|
|
73
73
|
{
|
|
74
74
|
title: 'Business Name',
|
|
@@ -106,14 +106,14 @@ export const BusinessTransactionsSingle = ({ businessId }: Props): ReactElement
|
|
|
106
106
|
);
|
|
107
107
|
};
|
|
108
108
|
|
|
109
|
-
type
|
|
110
|
-
|
|
109
|
+
type BusinessLedgerRecordsSum = Extract<
|
|
110
|
+
BusinessLedgerRecordsSummeryQuery['businessTransactionsSumFromLedgerRecords'],
|
|
111
111
|
{ businessTransactionsSum: unknown }
|
|
112
112
|
>['businessTransactionsSum'][number];
|
|
113
113
|
|
|
114
114
|
type CellInfo = {
|
|
115
115
|
title: ReactNode;
|
|
116
|
-
value: (data:
|
|
116
|
+
value: (data: BusinessLedgerRecordsSum) => string | ReactNode;
|
|
117
117
|
style?: React.CSSProperties;
|
|
118
118
|
};
|
|
119
119
|
|
|
@@ -3,47 +3,47 @@ import { format } from 'date-fns';
|
|
|
3
3
|
import { Currency } from '../../gql/graphql.js';
|
|
4
4
|
import { currencyCodeToSymbol, type TimelessDateString } from '../../helpers/index.js';
|
|
5
5
|
import { DownloadCSVButton } from '../common/index.js';
|
|
6
|
-
import type {
|
|
6
|
+
import type { ExtendedLedger } from './business-extended-info.js';
|
|
7
7
|
|
|
8
8
|
interface Props {
|
|
9
|
-
|
|
9
|
+
ledgerRecords: Array<ExtendedLedger>;
|
|
10
10
|
businessName: string;
|
|
11
11
|
fromDate?: TimelessDateString;
|
|
12
12
|
toDate?: TimelessDateString;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export const DownloadCSV = ({
|
|
16
|
-
|
|
16
|
+
ledgerRecords,
|
|
17
17
|
businessName,
|
|
18
18
|
fromDate,
|
|
19
19
|
toDate,
|
|
20
20
|
}: Props): ReactElement => {
|
|
21
21
|
const createFileVariables = useCallback(async () => {
|
|
22
|
-
const csvData = convertToCSV(
|
|
23
|
-
const fileName = `business_${businessName}
|
|
22
|
+
const csvData = convertToCSV(ledgerRecords);
|
|
23
|
+
const fileName = `business_${businessName}_ledger_records${fromDate ? `_${fromDate}` : ''}${toDate ? `_${toDate}` : ''}`;
|
|
24
24
|
return {
|
|
25
25
|
fileName,
|
|
26
26
|
fileContent: csvData,
|
|
27
27
|
};
|
|
28
|
-
}, [
|
|
28
|
+
}, [ledgerRecords, businessName, fromDate, toDate]);
|
|
29
29
|
|
|
30
30
|
return <DownloadCSVButton createFileVariables={createFileVariables} />;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
const convertToCSV = (
|
|
33
|
+
const convertToCSV = (ledgerRecords: Array<ExtendedLedger>): string => {
|
|
34
34
|
let csvString = '';
|
|
35
35
|
|
|
36
36
|
const currencies = Array.from(
|
|
37
37
|
new Set(
|
|
38
|
-
|
|
38
|
+
ledgerRecords.filter(t => t.foreignAmount?.currency).map(t => t.foreignAmount!.currency),
|
|
39
39
|
),
|
|
40
40
|
);
|
|
41
41
|
|
|
42
42
|
csvString += `Sorting Date,Date,Amount,Amount Balance,${getHeadersFromForeignCurrencies(currencies)}Reference,Details,Counter Account\r\n`;
|
|
43
43
|
|
|
44
|
-
for (const
|
|
45
|
-
const
|
|
46
|
-
csvString +=
|
|
44
|
+
for (const record of ledgerRecords) {
|
|
45
|
+
const stringifiedRecord = handleLedgerRecord(record, currencies);
|
|
46
|
+
csvString += stringifiedRecord;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
return csvString;
|
|
@@ -59,13 +59,13 @@ function getHeadersFromForeignCurrencies(currencies: Array<Currency>): string {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function getAmountsFromForeignCurrencies(
|
|
62
|
-
|
|
62
|
+
ledgerRecord: ExtendedLedger,
|
|
63
63
|
currencies: Array<Currency>,
|
|
64
64
|
): string {
|
|
65
65
|
let amounts = '';
|
|
66
66
|
currencies.map(currency => {
|
|
67
|
-
if (
|
|
68
|
-
amounts += `${
|
|
67
|
+
if (ledgerRecord.foreignAmount && ledgerRecord.foreignAmount.currency === currency) {
|
|
68
|
+
amounts += `${ledgerRecord.foreignAmount.raw},${ledgerRecord[`${currency.toLowerCase()}Balance` as keyof ExtendedLedger] ?? 0},`;
|
|
69
69
|
} else {
|
|
70
70
|
amounts += ',,';
|
|
71
71
|
}
|
|
@@ -73,21 +73,21 @@ function getAmountsFromForeignCurrencies(
|
|
|
73
73
|
return amounts;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function
|
|
77
|
-
let
|
|
76
|
+
function handleLedgerRecord(ledgerRecord: ExtendedLedger, currencies: Array<Currency>): string {
|
|
77
|
+
let ledgerRecordString = '';
|
|
78
78
|
|
|
79
|
-
const sortingDate =
|
|
80
|
-
? format(new Date(
|
|
79
|
+
const sortingDate = ledgerRecord.invoiceDate
|
|
80
|
+
? format(new Date(ledgerRecord.invoiceDate), 'yyy-MM-dd')
|
|
81
81
|
: null;
|
|
82
|
-
const date =
|
|
83
|
-
? format(new Date(
|
|
82
|
+
const date = ledgerRecord.invoiceDate
|
|
83
|
+
? format(new Date(ledgerRecord.invoiceDate), 'dd/MM/yy')
|
|
84
84
|
: null;
|
|
85
|
-
const ilsAmount =
|
|
86
|
-
const { ilsBalance, reference, details } =
|
|
87
|
-
const counterAccount =
|
|
85
|
+
const ilsAmount = ledgerRecord.amount.raw;
|
|
86
|
+
const { ilsBalance, reference, details } = ledgerRecord;
|
|
87
|
+
const counterAccount = ledgerRecord.counterAccount?.name ?? '';
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
return
|
|
89
|
+
ledgerRecordString += `${sortingDate},${date},${ilsAmount},${ilsBalance},${getAmountsFromForeignCurrencies(ledgerRecord, currencies)}${sanitizeString(reference ?? '')},${sanitizeString(details ?? '')},${sanitizeString(counterAccount)},\r\n`;
|
|
90
|
+
return ledgerRecordString;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
function sanitizeString(content: string | number): string {
|