@zeniai/client-epic-state 5.2.4 → 5.2.6
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/lib/epic.js +14 -4
- package/lib/esm/epic.js +14 -4
- package/lib/esm/index.js +4 -3
- package/lib/esm/view/accountList/accountListReducer.js +1 -0
- package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +411 -9
- package/lib/esm/view/aiCfoView/aiCfoViewSelector.js +49 -0
- package/lib/esm/view/aiCfoView/epics/deleteSkillEpic.js +23 -0
- package/lib/esm/view/aiCfoView/epics/fetchSkillDetailEpic.js +35 -0
- package/lib/esm/view/aiCfoView/epics/fetchSkillVersionBodyEpic.js +45 -0
- package/lib/esm/view/aiCfoView/epics/fetchSkillVersionsEpic.js +37 -0
- package/lib/esm/view/aiCfoView/epics/fetchSkillsEpic.js +11 -6
- package/lib/esm/view/aiCfoView/epics/saveSkillEpic.js +72 -0
- package/lib/esm/view/aiCfoView/epics/setSkillVisibilityEpic.js +32 -0
- package/lib/esm/view/aiCfoView/epics/toSkillDetail.js +102 -0
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +8 -0
- package/lib/esm/view/invoicing/invoicingQboView/epics/fetchInvoicingAccountingPickersEpic.js +29 -0
- package/lib/esm/view/invoicing/invoicingQboView/invoicingQboViewPayload.js +0 -23
- package/lib/esm/view/invoicing/invoicingQboView/invoicingQboViewReducer.js +3 -40
- package/lib/esm/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +124 -6
- package/lib/index.d.ts +7 -5
- package/lib/index.js +31 -14
- package/lib/view/accountList/accountListReducer.js +1 -0
- package/lib/view/accountList/accountListState.d.ts +1 -1
- package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +85 -0
- package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +67 -2
- package/lib/view/aiCfoView/aiCfoViewReducer.js +413 -10
- package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +7 -1
- package/lib/view/aiCfoView/aiCfoViewSelector.js +54 -0
- package/lib/view/aiCfoView/aiCfoViewState.d.ts +143 -1
- package/lib/view/aiCfoView/epics/deleteSkillEpic.d.ts +8 -0
- package/lib/view/aiCfoView/epics/deleteSkillEpic.js +27 -0
- package/lib/view/aiCfoView/epics/fetchSkillDetailEpic.d.ts +8 -0
- package/lib/view/aiCfoView/epics/fetchSkillDetailEpic.js +39 -0
- package/lib/view/aiCfoView/epics/fetchSkillVersionBodyEpic.d.ts +13 -0
- package/lib/view/aiCfoView/epics/fetchSkillVersionBodyEpic.js +49 -0
- package/lib/view/aiCfoView/epics/fetchSkillVersionsEpic.d.ts +8 -0
- package/lib/view/aiCfoView/epics/fetchSkillVersionsEpic.js +41 -0
- package/lib/view/aiCfoView/epics/fetchSkillsEpic.js +11 -6
- package/lib/view/aiCfoView/epics/saveSkillEpic.d.ts +14 -0
- package/lib/view/aiCfoView/epics/saveSkillEpic.js +76 -0
- package/lib/view/aiCfoView/epics/setSkillVisibilityEpic.d.ts +14 -0
- package/lib/view/aiCfoView/epics/setSkillVisibilityEpic.js +36 -0
- package/lib/view/aiCfoView/epics/toSkillDetail.d.ts +88 -0
- package/lib/view/aiCfoView/epics/toSkillDetail.js +110 -0
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.d.ts +9 -0
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +8 -0
- package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingAccountingPickersEpic.d.ts +5 -0
- package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingAccountingPickersEpic.js +33 -0
- package/lib/view/invoicing/invoicingQboView/epics/invoicingQboViewActionType.d.ts +4 -2
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewPayload.d.ts +0 -26
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewPayload.js +0 -24
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewReducer.d.ts +2 -10
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewReducer.js +4 -41
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.d.ts +43 -6
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +128 -7
- package/lib/view/invoicing/invoicingQboView/invoicingQboViewState.d.ts +1 -5
- package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
- package/package.json +1 -1
- package/lib/esm/view/invoicing/invoicingQboView/epics/fetchInvoicingQboAccountsEpic.js +0 -25
- package/lib/esm/view/invoicing/invoicingQboView/epics/fetchInvoicingQboClassesEpic.js +0 -15
- package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingQboAccountsEpic.d.ts +0 -6
- package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingQboAccountsEpic.js +0 -29
- package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingQboClassesEpic.d.ts +0 -6
- package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingQboClassesEpic.js +0 -19
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { SkillDetailDataPayload, SkillSummaryPayload } from '../aiCfoViewPayload';
|
|
2
|
+
import { Skill, SkillDetail, SkillVisibility } from '../aiCfoViewState';
|
|
3
|
+
/**
|
|
4
|
+
* A wire string narrowed to {@link SkillVisibility}, or null.
|
|
5
|
+
*
|
|
6
|
+
* A converter rather than passing the raw string through, because `Skill.visibility` is a
|
|
7
|
+
* union on the state type and this is the boundary where an unvalidated payload becomes
|
|
8
|
+
* it — the repo's rule about explicit converters at scalar boundaries instead of a bare
|
|
9
|
+
* cast.
|
|
10
|
+
*
|
|
11
|
+
* Unrecognised maps to NULL, not to `'private'`. Null already means "does not apply" for a
|
|
12
|
+
* Zeni default, and consumers show no audience badge for it — so an unknown tier renders
|
|
13
|
+
* as no badge. Defaulting to `'private'` would instead label a skill the whole tenant can
|
|
14
|
+
* run as author-only, which is a confident lie rather than a visible gap.
|
|
15
|
+
*/
|
|
16
|
+
export declare const toSkillVisibility: (raw: string | null | undefined) => SkillVisibility | null;
|
|
17
|
+
/**
|
|
18
|
+
* What the version-body read needs, and nothing more.
|
|
19
|
+
*
|
|
20
|
+
* A `Pick` of the payload rather than a type of its own: `SkillDetailDataPayload` now
|
|
21
|
+
* marks the three unchecked fields optional itself, the same way `SkillSummaryPayload`
|
|
22
|
+
* does, so there is one idiom for "this endpoint is not schema-validated" instead of two.
|
|
23
|
+
*/
|
|
24
|
+
type PromptBody = Pick<SkillDetailDataPayload, 'instructions'>;
|
|
25
|
+
/**
|
|
26
|
+
* Everything about a skill summary EXCEPT `exampleHints`, which no shared mapper can
|
|
27
|
+
* honestly supply.
|
|
28
|
+
*
|
|
29
|
+
* Only the LIST route returns `parameter_hints`; the detail and write routes do not. A
|
|
30
|
+
* shared mapper hardcoding `exampleHints: []` would put a "try: …" line under a skill
|
|
31
|
+
* that has hints, or drop them from the menu — so the field is `Omit`ted and each caller
|
|
32
|
+
* spreads in what its own route actually knows.
|
|
33
|
+
*
|
|
34
|
+
* Returning `Omit<Skill, 'exampleHints'>` rather than duplicating the mapper is what
|
|
35
|
+
* makes a new `Skill` field land in one place: this function stops compiling until the
|
|
36
|
+
* field is mapped, and both callers inherit it. The previous shape — two full copies —
|
|
37
|
+
* is how `isMine` was nearly added to only one of them, which would have silently
|
|
38
|
+
* withheld the edit and delete controls on whichever surface was missed.
|
|
39
|
+
*/
|
|
40
|
+
export declare const toBaseSkill: (payload: SkillSummaryPayload) => Omit<Skill, "exampleHints">;
|
|
41
|
+
/**
|
|
42
|
+
* Whether a 2xx body carries a prompt.
|
|
43
|
+
*
|
|
44
|
+
* Narrows to {@link PromptBody} and NOT to the whole payload, because the only consumer —
|
|
45
|
+
* the version-body read — dereferences `instructions` and nothing else. Asserting the
|
|
46
|
+
* whole shape here would claim `skill` was checked when it was not, and tying the read to
|
|
47
|
+
* it would fail a response whose prompt was fine and whose `skill` block was malformed,
|
|
48
|
+
* which is exactly what happened when this was one predicate instead of two.
|
|
49
|
+
*
|
|
50
|
+
* Takes `unknown`: the input is an unvalidated network body, and typing the parameter as
|
|
51
|
+
* the payload interface would assume the very thing being checked.
|
|
52
|
+
*/
|
|
53
|
+
export declare const hasPromptBody: (data: unknown) => data is PromptBody;
|
|
54
|
+
/**
|
|
55
|
+
* Whether a 2xx body can build a whole {@link SkillDetail}.
|
|
56
|
+
*
|
|
57
|
+
* Narrows to the payload type itself, which is now truthful: the two fields this checks
|
|
58
|
+
* are the two the interface still declares required, and the other three are optional
|
|
59
|
+
* there. Stricter than {@link hasPromptBody} by exactly one field. Four epics read this shape
|
|
60
|
+
* and each used to guard it differently — `data != null`, `data?.skill != null`, and a
|
|
61
|
+
* real `instructions` check — so one malformed response became a failure in one place, an
|
|
62
|
+
* empty prompt in another, and `undefined` in a third.
|
|
63
|
+
*/
|
|
64
|
+
export declare const isSkillDetailPayload: (data: unknown) => data is SkillDetailDataPayload;
|
|
65
|
+
/**
|
|
66
|
+
* The detail payload every write route answers with.
|
|
67
|
+
*
|
|
68
|
+
* Shared because three epics need it — save, visibility, and the detail read — and a
|
|
69
|
+
* fourth copy is how one of them quietly stops carrying a field the others do.
|
|
70
|
+
*
|
|
71
|
+
* The coercions are not defensive habit; the payload type makes them mandatory — the
|
|
72
|
+
* three optional fields cannot be assigned to a non-optional `SkillDetail` without one.
|
|
73
|
+
* Which fields get coerced and which do not is the deliberate part:
|
|
74
|
+
*
|
|
75
|
+
* - `instructions` is load-bearing and already proven, so it passes through. Defaulting a
|
|
76
|
+
* missing prompt to `''` is the one thing this module exists to prevent: the user
|
|
77
|
+
* cannot tell an empty prompt from a skill that has one, and may save over the real
|
|
78
|
+
* thing.
|
|
79
|
+
* - `instructionsCharCount` falls back to the prompt's own length, NOT to 0. A 12,000
|
|
80
|
+
* character prompt displayed as "0 characters" is a lie the user can see, and the
|
|
81
|
+
* prompt is right here to measure. Approximate only for astral-plane characters, where
|
|
82
|
+
* UTF-16 units and the server's count differ — a rounding error, against a guaranteed
|
|
83
|
+
* wrong answer.
|
|
84
|
+
* - `artifact` and `artifactTitle` degrade to empty. They render a preview card, so
|
|
85
|
+
* losing them costs a card; failing the whole read would cost the user the skill.
|
|
86
|
+
*/
|
|
87
|
+
export declare const toSkillDetail: (payload: SkillDetailDataPayload) => SkillDetail;
|
|
88
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toSkillDetail = exports.isSkillDetailPayload = exports.hasPromptBody = exports.toBaseSkill = exports.toSkillVisibility = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Every value `SkillVisibility` admits, as data so the converter below cannot drift from
|
|
6
|
+
* the type. Adding a tier to the union without adding it here is a compile error.
|
|
7
|
+
*/
|
|
8
|
+
const SKILL_VISIBILITIES = ['private', 'tenant'];
|
|
9
|
+
/**
|
|
10
|
+
* A wire string narrowed to {@link SkillVisibility}, or null.
|
|
11
|
+
*
|
|
12
|
+
* A converter rather than passing the raw string through, because `Skill.visibility` is a
|
|
13
|
+
* union on the state type and this is the boundary where an unvalidated payload becomes
|
|
14
|
+
* it — the repo's rule about explicit converters at scalar boundaries instead of a bare
|
|
15
|
+
* cast.
|
|
16
|
+
*
|
|
17
|
+
* Unrecognised maps to NULL, not to `'private'`. Null already means "does not apply" for a
|
|
18
|
+
* Zeni default, and consumers show no audience badge for it — so an unknown tier renders
|
|
19
|
+
* as no badge. Defaulting to `'private'` would instead label a skill the whole tenant can
|
|
20
|
+
* run as author-only, which is a confident lie rather than a visible gap.
|
|
21
|
+
*/
|
|
22
|
+
const toSkillVisibility = (raw) => SKILL_VISIBILITIES.find((known) => known === raw) ?? null;
|
|
23
|
+
exports.toSkillVisibility = toSkillVisibility;
|
|
24
|
+
/**
|
|
25
|
+
* Everything about a skill summary EXCEPT `exampleHints`, which no shared mapper can
|
|
26
|
+
* honestly supply.
|
|
27
|
+
*
|
|
28
|
+
* Only the LIST route returns `parameter_hints`; the detail and write routes do not. A
|
|
29
|
+
* shared mapper hardcoding `exampleHints: []` would put a "try: …" line under a skill
|
|
30
|
+
* that has hints, or drop them from the menu — so the field is `Omit`ted and each caller
|
|
31
|
+
* spreads in what its own route actually knows.
|
|
32
|
+
*
|
|
33
|
+
* Returning `Omit<Skill, 'exampleHints'>` rather than duplicating the mapper is what
|
|
34
|
+
* makes a new `Skill` field land in one place: this function stops compiling until the
|
|
35
|
+
* field is mapped, and both callers inherit it. The previous shape — two full copies —
|
|
36
|
+
* is how `isMine` was nearly added to only one of them, which would have silently
|
|
37
|
+
* withheld the edit and delete controls on whichever surface was missed.
|
|
38
|
+
*/
|
|
39
|
+
const toBaseSkill = (payload) => ({
|
|
40
|
+
macroId: payload.macro_id,
|
|
41
|
+
name: payload.name,
|
|
42
|
+
displayName: payload.display_name,
|
|
43
|
+
description: payload.description,
|
|
44
|
+
semver: payload.semver,
|
|
45
|
+
hasScripts: payload.has_scripts === true,
|
|
46
|
+
// === true, so an absent field withholds the write controls rather than offering ones
|
|
47
|
+
// the API refuses.
|
|
48
|
+
isMine: payload.is_mine === true,
|
|
49
|
+
isOwnedByTenant: payload.is_owned_by_tenant === true,
|
|
50
|
+
updatedAt: payload.updated_at ?? null,
|
|
51
|
+
visibility: (0, exports.toSkillVisibility)(payload.visibility),
|
|
52
|
+
});
|
|
53
|
+
exports.toBaseSkill = toBaseSkill;
|
|
54
|
+
/**
|
|
55
|
+
* Whether a 2xx body carries a prompt.
|
|
56
|
+
*
|
|
57
|
+
* Narrows to {@link PromptBody} and NOT to the whole payload, because the only consumer —
|
|
58
|
+
* the version-body read — dereferences `instructions` and nothing else. Asserting the
|
|
59
|
+
* whole shape here would claim `skill` was checked when it was not, and tying the read to
|
|
60
|
+
* it would fail a response whose prompt was fine and whose `skill` block was malformed,
|
|
61
|
+
* which is exactly what happened when this was one predicate instead of two.
|
|
62
|
+
*
|
|
63
|
+
* Takes `unknown`: the input is an unvalidated network body, and typing the parameter as
|
|
64
|
+
* the payload interface would assume the very thing being checked.
|
|
65
|
+
*/
|
|
66
|
+
const hasPromptBody = (data) => typeof data?.instructions ===
|
|
67
|
+
'string';
|
|
68
|
+
exports.hasPromptBody = hasPromptBody;
|
|
69
|
+
/**
|
|
70
|
+
* Whether a 2xx body can build a whole {@link SkillDetail}.
|
|
71
|
+
*
|
|
72
|
+
* Narrows to the payload type itself, which is now truthful: the two fields this checks
|
|
73
|
+
* are the two the interface still declares required, and the other three are optional
|
|
74
|
+
* there. Stricter than {@link hasPromptBody} by exactly one field. Four epics read this shape
|
|
75
|
+
* and each used to guard it differently — `data != null`, `data?.skill != null`, and a
|
|
76
|
+
* real `instructions` check — so one malformed response became a failure in one place, an
|
|
77
|
+
* empty prompt in another, and `undefined` in a third.
|
|
78
|
+
*/
|
|
79
|
+
const isSkillDetailPayload = (data) => (0, exports.hasPromptBody)(data) && data.skill != null;
|
|
80
|
+
exports.isSkillDetailPayload = isSkillDetailPayload;
|
|
81
|
+
/**
|
|
82
|
+
* The detail payload every write route answers with.
|
|
83
|
+
*
|
|
84
|
+
* Shared because three epics need it — save, visibility, and the detail read — and a
|
|
85
|
+
* fourth copy is how one of them quietly stops carrying a field the others do.
|
|
86
|
+
*
|
|
87
|
+
* The coercions are not defensive habit; the payload type makes them mandatory — the
|
|
88
|
+
* three optional fields cannot be assigned to a non-optional `SkillDetail` without one.
|
|
89
|
+
* Which fields get coerced and which do not is the deliberate part:
|
|
90
|
+
*
|
|
91
|
+
* - `instructions` is load-bearing and already proven, so it passes through. Defaulting a
|
|
92
|
+
* missing prompt to `''` is the one thing this module exists to prevent: the user
|
|
93
|
+
* cannot tell an empty prompt from a skill that has one, and may save over the real
|
|
94
|
+
* thing.
|
|
95
|
+
* - `instructionsCharCount` falls back to the prompt's own length, NOT to 0. A 12,000
|
|
96
|
+
* character prompt displayed as "0 characters" is a lie the user can see, and the
|
|
97
|
+
* prompt is right here to measure. Approximate only for astral-plane characters, where
|
|
98
|
+
* UTF-16 units and the server's count differ — a rounding error, against a guaranteed
|
|
99
|
+
* wrong answer.
|
|
100
|
+
* - `artifact` and `artifactTitle` degrade to empty. They render a preview card, so
|
|
101
|
+
* losing them costs a card; failing the whole read would cost the user the skill.
|
|
102
|
+
*/
|
|
103
|
+
const toSkillDetail = (payload) => ({
|
|
104
|
+
skill: { ...(0, exports.toBaseSkill)(payload.skill), exampleHints: [] },
|
|
105
|
+
instructions: payload.instructions,
|
|
106
|
+
instructionsCharCount: payload.instructions_char_count ?? payload.instructions.length,
|
|
107
|
+
artifact: payload.artifact ?? '',
|
|
108
|
+
artifactTitle: payload.artifact_title ?? '',
|
|
109
|
+
});
|
|
110
|
+
exports.toSkillDetail = toSkillDetail;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { NestedAccountHierarchyForReport } from '../../../commonStateTypes/accountView/nestedAccountID';
|
|
2
|
+
import { NestedClassHierarchyForReport } from '../../../commonStateTypes/classesView/nestedClassID';
|
|
1
3
|
import { FetchStateAndError, ID } from '../../../commonStateTypes/common';
|
|
2
4
|
import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport';
|
|
3
5
|
import { InvoicingFieldHelpByCode, InvoicingNamedOption, InvoicingNamedOptionsByKey } from '../../../entity/invoicing/invoicingCommonPayload';
|
|
@@ -40,6 +42,13 @@ export interface InvoicingCatalogItemFormView extends SelectorView {
|
|
|
40
42
|
periodUnitOptions: InvoicingNamedOption[];
|
|
41
43
|
pricingModelValues: readonly string[];
|
|
42
44
|
prorationValues: readonly string[];
|
|
45
|
+
/**
|
|
46
|
+
* Account and class trees for the price-point pickers, already narrowed to the
|
|
47
|
+
* income accounts a price may post to. Empty until QBO is connected — the form
|
|
48
|
+
* must not offer a mapping that cannot be pushed.
|
|
49
|
+
*/
|
|
50
|
+
qboClassHierarchy: NestedClassHierarchyForReport[];
|
|
51
|
+
qboIncomeAccountHierarchy: NestedAccountHierarchyForReport[];
|
|
43
52
|
tierTypeValues: readonly string[];
|
|
44
53
|
trialEndActionOptions: InvoicingNamedOption[];
|
|
45
54
|
trialUnitOptions: InvoicingNamedOption[];
|
|
@@ -4,6 +4,7 @@ exports.getInvoicingCatalogItemFormView = exports.getInvoicingApplicableCatalogI
|
|
|
4
4
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
5
5
|
const planSelector_1 = require("../../../entity/invoicing/plan/planSelector");
|
|
6
6
|
const invoicingConfigViewSelector_1 = require("../invoicingConfigView/invoicingConfigViewSelector");
|
|
7
|
+
const invoicingQboViewSelector_1 = require("../invoicingQboView/invoicingQboViewSelector");
|
|
7
8
|
const invoicingCatalogItemFormConfig_1 = require("./invoicingCatalogItemFormConfig");
|
|
8
9
|
const getEditInvoicingCatalogItemDetailViewState = (state) => ({
|
|
9
10
|
fetchState: state.editInvoicingCatalogItemDetailViewState.fetchState,
|
|
@@ -54,9 +55,16 @@ const getInvoicingCatalogItemFormView = (state, id) => {
|
|
|
54
55
|
const applicableItemOptions = id != null
|
|
55
56
|
? allApplicableItemOptions.filter((option) => option.id !== id)
|
|
56
57
|
: allApplicableItemOptions;
|
|
58
|
+
const isQboConnected = (0, invoicingQboViewSelector_1.isInvoicingQboConnected)(state);
|
|
57
59
|
const { billingPeriodUnitOptions, catalogItemTypeOptions, catalogTierTypeOptionsByPricingModel, catalogTrialEndActionOptions, catalogTrialUnitOptions, } = (0, invoicingConfigViewSelector_1.getInvoicingConfigView)(state);
|
|
58
60
|
return {
|
|
59
61
|
fieldHelp: (0, invoicingConfigViewSelector_1.invoicingFieldHelpForGroup)(state, 'catalog'),
|
|
62
|
+
qboClassHierarchy: isQboConnected
|
|
63
|
+
? (0, invoicingQboViewSelector_1.getInvoicingQboView)(state).nestedClassHierarchy
|
|
64
|
+
: [],
|
|
65
|
+
qboIncomeAccountHierarchy: isQboConnected
|
|
66
|
+
? (0, invoicingQboViewSelector_1.invoicingAccountHierarchyForTypes)(state, invoicingQboViewSelector_1.INVOICING_INCOME_ACCOUNT_TYPES)
|
|
67
|
+
: [],
|
|
60
68
|
applicabilityValues: invoicingCatalogItemFormConfig_1.INVOICING_CATALOG_APPLICABILITY_VALUES,
|
|
61
69
|
applicableItemOptions,
|
|
62
70
|
localData,
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { RootState } from '../../../../rootStateTypes';
|
|
4
|
+
import { InvoicingQboViewActionType } from './invoicingQboViewActionType';
|
|
5
|
+
export declare const fetchInvoicingAccountingPickersEpic: (actions$: ActionsObservable<InvoicingQboViewActionType>, state$: StateObservable<RootState>) => Observable<InvoicingQboViewActionType>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchInvoicingAccountingPickersEpic = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const accountListReducer_1 = require("../../../accountList/accountListReducer");
|
|
7
|
+
const classListReducer_1 = require("../../../classList/classListReducer");
|
|
8
|
+
const invoicingQboViewReducer_1 = require("../invoicingQboViewReducer");
|
|
9
|
+
const invoicingQboViewSelector_1 = require("../invoicingQboViewSelector");
|
|
10
|
+
// Tops up the shared account and class lists, skipping either when the store
|
|
11
|
+
// already holds it or has it in flight.
|
|
12
|
+
const fetchInvoicingAccountingPickersEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(invoicingQboViewReducer_1.fetchInvoicingAccountingPickers.match), (0, operators_1.withLatestFrom)(state$), (0, operators_1.mergeMap)(([, state]) => {
|
|
13
|
+
const actions = [];
|
|
14
|
+
const accountList = state.accountListState.byReportId[invoicingQboViewSelector_1.INVOICING_ACCOUNT_LIST_KEY];
|
|
15
|
+
if (accountList.hasValidState() === false &&
|
|
16
|
+
accountList.fetchState !== 'In-Progress') {
|
|
17
|
+
// AP/AR accounts cannot back an invoicing mapping, so they are excluded
|
|
18
|
+
// here — which is why this uses invoicing's own bucket rather than the
|
|
19
|
+
// general `accountList` other screens fill without those exclusions.
|
|
20
|
+
actions.push((0, accountListReducer_1.fetchAccountList)(invoicingQboViewSelector_1.INVOICING_ACCOUNT_LIST_KEY, true, true, true));
|
|
21
|
+
}
|
|
22
|
+
const classList = state.classListState;
|
|
23
|
+
if (classList.hasValidState() === false &&
|
|
24
|
+
classList.fetchState !== 'In-Progress') {
|
|
25
|
+
// Without deleted classes, matching almost every other caller of this
|
|
26
|
+
// single global slice. Asking for deleted rows here would have handed
|
|
27
|
+
// them to the vendor and transaction screens too — and the picker
|
|
28
|
+
// filters deleted classes out anyway, so there is nothing to gain.
|
|
29
|
+
actions.push((0, classListReducer_1.fetchClassList)());
|
|
30
|
+
}
|
|
31
|
+
return actions.length > 0 ? (0, rxjs_1.from)(actions) : rxjs_1.EMPTY;
|
|
32
|
+
}));
|
|
33
|
+
exports.fetchInvoicingAccountingPickersEpic = fetchInvoicingAccountingPickersEpic;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { fetchAccountList } from '../../../accountList/accountListReducer';
|
|
3
|
+
import { fetchClassList } from '../../../classList/classListReducer';
|
|
4
|
+
import { fetchInvoicingAccountingPickers, fetchInvoicingQboConnection, fetchInvoicingQboSyncHealth, retryInvoicingQboSyncTask, retryInvoicingQboSyncTaskFailure, retryInvoicingQboSyncTaskSuccess, startInvoicingQboBackfill, startInvoicingQboBackfillFailure, startInvoicingQboBackfillSuccess, updateInvoicingQboConnection, updateInvoicingQboConnectionFailure, updateInvoicingQboSyncHealth, updateInvoicingQboSyncHealthFailure } from '../invoicingQboViewReducer';
|
|
5
|
+
export type InvoicingQboViewActionType = ReturnType<typeof openSnackbar> | ReturnType<typeof fetchInvoicingQboConnection> | ReturnType<typeof updateInvoicingQboConnection> | ReturnType<typeof updateInvoicingQboConnectionFailure> | ReturnType<typeof fetchInvoicingAccountingPickers> | ReturnType<typeof fetchAccountList> | ReturnType<typeof fetchClassList> | ReturnType<typeof fetchInvoicingQboSyncHealth> | ReturnType<typeof updateInvoicingQboSyncHealth> | ReturnType<typeof updateInvoicingQboSyncHealthFailure> | ReturnType<typeof retryInvoicingQboSyncTask> | ReturnType<typeof retryInvoicingQboSyncTaskSuccess> | ReturnType<typeof retryInvoicingQboSyncTaskFailure> | ReturnType<typeof startInvoicingQboBackfill> | ReturnType<typeof startInvoicingQboBackfillSuccess> | ReturnType<typeof startInvoicingQboBackfillFailure>;
|
|
@@ -12,31 +12,6 @@ export interface InvoicingQboConnection {
|
|
|
12
12
|
realmId?: string;
|
|
13
13
|
}
|
|
14
14
|
export declare function mapInvoicingQboConnection(payload: InvoicingQboConnectionPayload): InvoicingQboConnection;
|
|
15
|
-
/**
|
|
16
|
-
* A single row from the QBO accounts / classes endpoints. The rows carry the
|
|
17
|
-
* QBO id plus one or more name fields depending on the entity — inspect
|
|
18
|
-
* loosely, render the name, submit the id.
|
|
19
|
-
*/
|
|
20
|
-
export interface InvoicingQboAccountRowPayload {
|
|
21
|
-
account_id?: string | null;
|
|
22
|
-
account_name?: string | null;
|
|
23
|
-
account_type?: string | null;
|
|
24
|
-
accounting_class_name?: string | null;
|
|
25
|
-
fully_qualified_name?: string | null;
|
|
26
|
-
id?: string | null;
|
|
27
|
-
name?: string | null;
|
|
28
|
-
qbo_accounting_class_name?: string | null;
|
|
29
|
-
qbo_id?: string | null;
|
|
30
|
-
}
|
|
31
|
-
export interface InvoicingQboAccountOption {
|
|
32
|
-
id: string;
|
|
33
|
-
name: string;
|
|
34
|
-
accountType?: string;
|
|
35
|
-
}
|
|
36
|
-
export declare function mapInvoicingQboAccountOptions(rows: InvoicingQboAccountRowPayload[]): InvoicingQboAccountOption[];
|
|
37
|
-
export interface InvoicingQboAccountsPayload {
|
|
38
|
-
accounts: InvoicingQboAccountRowPayload[];
|
|
39
|
-
}
|
|
40
15
|
export interface InvoicingQboFailedTaskPayload {
|
|
41
16
|
attempts: number;
|
|
42
17
|
entity_id: string;
|
|
@@ -73,7 +48,6 @@ export interface InvoicingQboBackfillPayload {
|
|
|
73
48
|
start_date?: string | null;
|
|
74
49
|
}
|
|
75
50
|
export type InvoicingQboConnectionResponse = ZeniAPIResponse<InvoicingQboConnectionPayload>;
|
|
76
|
-
export type InvoicingQboAccountsResponse = ZeniAPIResponse<InvoicingQboAccountsPayload>;
|
|
77
51
|
export type InvoicingQboSyncHealthResponse = ZeniAPIResponse<InvoicingQboSyncHealthPayload>;
|
|
78
52
|
export type InvoicingQboRetryTaskResponse = ZeniAPIResponse<InvoicingQboRetryTaskPayload>;
|
|
79
53
|
export type InvoicingQboBackfillResponse = ZeniAPIResponse<InvoicingQboBackfillPayload>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.mapInvoicingQboConnection = mapInvoicingQboConnection;
|
|
4
|
-
exports.mapInvoicingQboAccountOptions = mapInvoicingQboAccountOptions;
|
|
5
4
|
exports.mapInvoicingQboSyncHealth = mapInvoicingQboSyncHealth;
|
|
6
5
|
function mapInvoicingQboConnection(payload) {
|
|
7
6
|
return {
|
|
@@ -11,29 +10,6 @@ function mapInvoicingQboConnection(payload) {
|
|
|
11
10
|
realmId: payload.realm_id ?? undefined,
|
|
12
11
|
};
|
|
13
12
|
}
|
|
14
|
-
function mapInvoicingQboAccountOptions(rows) {
|
|
15
|
-
return rows.flatMap((row) => {
|
|
16
|
-
// Only qbo_id is a valid QBO AccountRef/ClassRef value — platform-internal
|
|
17
|
-
// ids (account_id / id) are display metadata and must never be submitted.
|
|
18
|
-
const accountId = row.qbo_id ?? row.id ?? row.account_id ?? '';
|
|
19
|
-
if (accountId === '') {
|
|
20
|
-
return [];
|
|
21
|
-
}
|
|
22
|
-
const accountName = row.name ??
|
|
23
|
-
row.account_name ??
|
|
24
|
-
row.accounting_class_name ??
|
|
25
|
-
row.qbo_accounting_class_name ??
|
|
26
|
-
row.fully_qualified_name ??
|
|
27
|
-
accountId;
|
|
28
|
-
return [
|
|
29
|
-
{
|
|
30
|
-
id: accountId,
|
|
31
|
-
name: accountName,
|
|
32
|
-
accountType: row.account_type ?? undefined,
|
|
33
|
-
},
|
|
34
|
-
];
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
13
|
function mapInvoicingQboSyncHealth(payload) {
|
|
38
14
|
return {
|
|
39
15
|
connection: payload.connection != null
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import { ZeniAPIStatus } from '../../../responsePayload';
|
|
2
|
-
import {
|
|
2
|
+
import { InvoicingQboConnection, InvoicingQboSyncHealth } from './invoicingQboViewPayload';
|
|
3
3
|
import { InvoicingQboViewState } from './invoicingQboViewState';
|
|
4
4
|
export declare const initialState: InvoicingQboViewState;
|
|
5
|
-
export declare const fetchInvoicingQboConnection: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingQboView/fetchInvoicingQboConnection">, updateInvoicingQboConnection: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingQboConnection, "invoicingQboView/updateInvoicingQboConnection">, updateInvoicingQboConnectionFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingQboView/updateInvoicingQboConnectionFailure">,
|
|
6
|
-
accountTypes: string;
|
|
7
|
-
}, "invoicingQboView/fetchInvoicingQboAccounts", never, never>, updateInvoicingQboAccounts: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
8
|
-
accounts: InvoicingQboAccountOption[];
|
|
9
|
-
accountTypes: string;
|
|
10
|
-
}, "invoicingQboView/updateInvoicingQboAccounts">, updateInvoicingQboAccountsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
11
|
-
accountTypes: string;
|
|
12
|
-
status: ZeniAPIStatus;
|
|
13
|
-
}, "invoicingQboView/updateInvoicingQboAccountsFailure">, fetchInvoicingQboClasses: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingQboView/fetchInvoicingQboClasses">, updateInvoicingQboClasses: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingQboAccountOption[], "invoicingQboView/updateInvoicingQboClasses">, updateInvoicingQboClassesFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingQboView/updateInvoicingQboClassesFailure">, fetchInvoicingQboSyncHealth: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingQboView/fetchInvoicingQboSyncHealth">, updateInvoicingQboSyncHealth: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingQboSyncHealth, "invoicingQboView/updateInvoicingQboSyncHealth">, updateInvoicingQboSyncHealthFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingQboView/updateInvoicingQboSyncHealthFailure">, retryInvoicingQboSyncTask: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[taskId: string], {
|
|
5
|
+
export declare const fetchInvoicingQboConnection: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingQboView/fetchInvoicingQboConnection">, updateInvoicingQboConnection: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingQboConnection, "invoicingQboView/updateInvoicingQboConnection">, updateInvoicingQboConnectionFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingQboView/updateInvoicingQboConnectionFailure">, fetchInvoicingAccountingPickers: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingQboView/fetchInvoicingAccountingPickers">, fetchInvoicingQboSyncHealth: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"invoicingQboView/fetchInvoicingQboSyncHealth">, updateInvoicingQboSyncHealth: import("@reduxjs/toolkit").ActionCreatorWithPayload<InvoicingQboSyncHealth, "invoicingQboView/updateInvoicingQboSyncHealth">, updateInvoicingQboSyncHealthFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingQboView/updateInvoicingQboSyncHealthFailure">, retryInvoicingQboSyncTask: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[taskId: string], {
|
|
14
6
|
taskId: string;
|
|
15
7
|
}, "invoicingQboView/retryInvoicingQboSyncTask", never, never>, retryInvoicingQboSyncTaskSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
16
8
|
status: string;
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.startInvoicingQboBackfillFailure = exports.startInvoicingQboBackfillSuccess = exports.startInvoicingQboBackfill = exports.retryInvoicingQboSyncTaskFailure = exports.retryInvoicingQboSyncTaskSuccess = exports.retryInvoicingQboSyncTask = exports.updateInvoicingQboSyncHealthFailure = exports.updateInvoicingQboSyncHealth = exports.fetchInvoicingQboSyncHealth = exports.
|
|
4
|
+
exports.startInvoicingQboBackfillFailure = exports.startInvoicingQboBackfillSuccess = exports.startInvoicingQboBackfill = exports.retryInvoicingQboSyncTaskFailure = exports.retryInvoicingQboSyncTaskSuccess = exports.retryInvoicingQboSyncTask = exports.updateInvoicingQboSyncHealthFailure = exports.updateInvoicingQboSyncHealth = exports.fetchInvoicingQboSyncHealth = exports.fetchInvoicingAccountingPickers = exports.updateInvoicingQboConnectionFailure = exports.updateInvoicingQboConnection = exports.fetchInvoicingQboConnection = exports.initialState = void 0;
|
|
5
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
6
|
const rootActions_1 = require("../../../rootActions");
|
|
7
7
|
exports.initialState = {
|
|
8
|
-
accountsByAccountTypes: {},
|
|
9
|
-
accountsFetchStateByAccountTypes: {},
|
|
10
8
|
backfillFetchState: { fetchState: 'Not-Started', error: undefined },
|
|
11
|
-
classes: [],
|
|
12
|
-
classesFetchState: { fetchState: 'Not-Started', error: undefined },
|
|
13
9
|
connection: undefined,
|
|
14
10
|
connectionFetchState: { fetchState: 'Not-Started', error: undefined },
|
|
15
11
|
retryFetchStateByTaskId: {},
|
|
@@ -33,41 +29,8 @@ const invoicingQboView = (0, toolkit_1.createSlice)({
|
|
|
33
29
|
updateInvoicingQboConnectionFailure(draft, action) {
|
|
34
30
|
draft.connectionFetchState = { fetchState: 'Error', error: action.payload };
|
|
35
31
|
},
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
draft.accountsFetchStateByAccountTypes[action.payload.accountTypes] = {
|
|
39
|
-
fetchState: 'In-Progress',
|
|
40
|
-
error: undefined,
|
|
41
|
-
};
|
|
42
|
-
},
|
|
43
|
-
prepare(accountTypes) {
|
|
44
|
-
return { payload: { accountTypes } };
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
updateInvoicingQboAccounts(draft, action) {
|
|
48
|
-
draft.accountsByAccountTypes[action.payload.accountTypes] =
|
|
49
|
-
action.payload.accounts;
|
|
50
|
-
draft.accountsFetchStateByAccountTypes[action.payload.accountTypes] = {
|
|
51
|
-
fetchState: 'Completed',
|
|
52
|
-
error: undefined,
|
|
53
|
-
};
|
|
54
|
-
},
|
|
55
|
-
updateInvoicingQboAccountsFailure(draft, action) {
|
|
56
|
-
draft.accountsFetchStateByAccountTypes[action.payload.accountTypes] = {
|
|
57
|
-
fetchState: 'Error',
|
|
58
|
-
error: action.payload.status,
|
|
59
|
-
};
|
|
60
|
-
},
|
|
61
|
-
fetchInvoicingQboClasses(draft) {
|
|
62
|
-
draft.classesFetchState = { fetchState: 'In-Progress', error: undefined };
|
|
63
|
-
},
|
|
64
|
-
updateInvoicingQboClasses(draft, action) {
|
|
65
|
-
draft.classes = action.payload;
|
|
66
|
-
draft.classesFetchState = { fetchState: 'Completed', error: undefined };
|
|
67
|
-
},
|
|
68
|
-
updateInvoicingQboClassesFailure(draft, action) {
|
|
69
|
-
draft.classesFetchState = { fetchState: 'Error', error: action.payload };
|
|
70
|
-
},
|
|
32
|
+
// No state of its own: the epic decides which shared lists to load.
|
|
33
|
+
fetchInvoicingAccountingPickers() { },
|
|
71
34
|
fetchInvoicingQboSyncHealth(draft) {
|
|
72
35
|
draft.syncHealthFetchState = {
|
|
73
36
|
fetchState: 'In-Progress',
|
|
@@ -131,5 +94,5 @@ const invoicingQboView = (0, toolkit_1.createSlice)({
|
|
|
131
94
|
});
|
|
132
95
|
},
|
|
133
96
|
});
|
|
134
|
-
_a = invoicingQboView.actions, exports.fetchInvoicingQboConnection = _a.fetchInvoicingQboConnection, exports.updateInvoicingQboConnection = _a.updateInvoicingQboConnection, exports.updateInvoicingQboConnectionFailure = _a.updateInvoicingQboConnectionFailure, exports.
|
|
97
|
+
_a = invoicingQboView.actions, exports.fetchInvoicingQboConnection = _a.fetchInvoicingQboConnection, exports.updateInvoicingQboConnection = _a.updateInvoicingQboConnection, exports.updateInvoicingQboConnectionFailure = _a.updateInvoicingQboConnectionFailure, exports.fetchInvoicingAccountingPickers = _a.fetchInvoicingAccountingPickers, exports.fetchInvoicingQboSyncHealth = _a.fetchInvoicingQboSyncHealth, exports.updateInvoicingQboSyncHealth = _a.updateInvoicingQboSyncHealth, exports.updateInvoicingQboSyncHealthFailure = _a.updateInvoicingQboSyncHealthFailure, exports.retryInvoicingQboSyncTask = _a.retryInvoicingQboSyncTask, exports.retryInvoicingQboSyncTaskSuccess = _a.retryInvoicingQboSyncTaskSuccess, exports.retryInvoicingQboSyncTaskFailure = _a.retryInvoicingQboSyncTaskFailure, exports.startInvoicingQboBackfill = _a.startInvoicingQboBackfill, exports.startInvoicingQboBackfillSuccess = _a.startInvoicingQboBackfillSuccess, exports.startInvoicingQboBackfillFailure = _a.startInvoicingQboBackfillFailure;
|
|
135
98
|
exports.default = invoicingQboView.reducer;
|
|
@@ -1,21 +1,58 @@
|
|
|
1
|
+
import { NestedAccountHierarchyForReport } from '../../../commonStateTypes/accountView/nestedAccountID';
|
|
2
|
+
import { NestedClassHierarchyForReport } from '../../../commonStateTypes/classesView/nestedClassID';
|
|
1
3
|
import { FetchStateAndError } from '../../../commonStateTypes/common';
|
|
4
|
+
import { AccountType } from '../../../entity/account/accountState';
|
|
2
5
|
import { RootState } from '../../../rootStateTypes';
|
|
3
|
-
import {
|
|
6
|
+
import { InvoicingQboConnection, InvoicingQboSyncHealth } from './invoicingQboViewPayload';
|
|
7
|
+
export declare const INVOICING_ACCOUNT_LIST_KEY: "invoicingAccountList";
|
|
8
|
+
/** Whether QBO is connected, without building the option lists to find out. */
|
|
9
|
+
export declare const isInvoicingQboConnected: (state: RootState) => boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Account types that can back invoicing revenue. Named here so screens ask for
|
|
12
|
+
* "income accounts" rather than repeating the accounting service's vocabulary.
|
|
13
|
+
*/
|
|
14
|
+
export declare const INVOICING_INCOME_ACCOUNT_TYPES: readonly AccountType[];
|
|
15
|
+
/** An account or class as the invoicing pickers render and submit it. */
|
|
16
|
+
export interface InvoicingAccountingOption {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
accountType?: string;
|
|
20
|
+
}
|
|
4
21
|
export interface InvoicingQboView {
|
|
5
|
-
|
|
6
|
-
|
|
22
|
+
accounts: InvoicingAccountingOption[];
|
|
23
|
+
accountsFetchState: FetchStateAndError;
|
|
7
24
|
backfillState: FetchStateAndError;
|
|
8
|
-
classes:
|
|
25
|
+
classes: InvoicingAccountingOption[];
|
|
9
26
|
classesFetchState: FetchStateAndError;
|
|
10
27
|
connectionFetchState: FetchStateAndError;
|
|
28
|
+
/**
|
|
29
|
+
* The account and class trees the grouped pickers render. The flat option
|
|
30
|
+
* lists above stay for callers that only need id and name.
|
|
31
|
+
*/
|
|
32
|
+
nestedAccountHierarchy: NestedAccountHierarchyForReport[];
|
|
33
|
+
nestedClassHierarchy: NestedClassHierarchyForReport[];
|
|
11
34
|
retryFetchStateByTaskId: Record<string, FetchStateAndError>;
|
|
12
35
|
syncHealthFetchState: FetchStateAndError;
|
|
13
36
|
connection?: InvoicingQboConnection;
|
|
14
37
|
syncHealth?: InvoicingQboSyncHealth;
|
|
15
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* The accounts valid for one QBO mapping kind, whose `accountTypes` is a
|
|
41
|
+
* comma-separated list of QuickBooks type names. An unrecognised list yields no
|
|
42
|
+
* accounts rather than every account: offering a bank account where income is
|
|
43
|
+
* required would post a mapping QuickBooks rejects.
|
|
44
|
+
*/
|
|
45
|
+
export declare const invoicingAccountsForQboAccountTypes: (accounts: InvoicingAccountingOption[], accountTypes: string) => InvoicingAccountingOption[];
|
|
46
|
+
/**
|
|
47
|
+
* The account tree narrowed to the given account types. The tree itself carries
|
|
48
|
+
* no account type, so the flat account list supplies that and the matching
|
|
49
|
+
* `qboId`s are kept — which is why callers that only need "income accounts, as a
|
|
50
|
+
* tree" do not have to hold a second flat list to filter with.
|
|
51
|
+
*/
|
|
52
|
+
export declare const invoicingAccountHierarchyForTypes: (state: RootState, accountTypes: readonly AccountType[]) => NestedAccountHierarchyForReport[];
|
|
16
53
|
/**
|
|
17
54
|
* Single bundled view for the QBO integration settings screen — the
|
|
18
|
-
* connection,
|
|
19
|
-
*
|
|
55
|
+
* connection, the account and class options, sync health, and the fetch/action
|
|
56
|
+
* states for each of them.
|
|
20
57
|
*/
|
|
21
58
|
export declare const getInvoicingQboView: (state: RootState) => InvoicingQboView;
|