@mj-biz-apps/sales-ng 6.5.0 → 6.7.0
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/dist/lib/custom/company-from-pipeline.d.ts +66 -0
- package/dist/lib/custom/company-from-pipeline.d.ts.map +1 -0
- package/dist/lib/custom/company-from-pipeline.js +67 -0
- package/dist/lib/custom/company-from-pipeline.js.map +1 -0
- package/dist/lib/custom/deal-form.component.d.ts +27 -0
- package/dist/lib/custom/deal-form.component.d.ts.map +1 -1
- package/dist/lib/custom/deal-form.component.js +115 -30
- package/dist/lib/custom/deal-form.component.js.map +1 -1
- package/dist/lib/custom/deal-stage-event-form.component.js +6 -4
- package/dist/lib/custom/deal-stage-event-form.component.js.map +1 -1
- package/dist/lib/data/entity-names.d.ts +11 -0
- package/dist/lib/data/entity-names.d.ts.map +1 -1
- package/dist/lib/data/entity-names.js +11 -0
- package/dist/lib/data/entity-names.js.map +1 -1
- package/dist/lib/form-panels/deal-form.panels.d.ts +172 -4
- package/dist/lib/form-panels/deal-form.panels.d.ts.map +1 -1
- package/dist/lib/form-panels/deal-form.panels.js +960 -338
- package/dist/lib/form-panels/deal-form.panels.js.map +1 -1
- package/dist/lib/form-panels/deal-hero.panel.d.ts +62 -2
- package/dist/lib/form-panels/deal-hero.panel.d.ts.map +1 -1
- package/dist/lib/form-panels/deal-hero.panel.js +226 -68
- package/dist/lib/form-panels/deal-hero.panel.js.map +1 -1
- package/dist/lib/form-panels/deal-line-editor.component.d.ts +241 -0
- package/dist/lib/form-panels/deal-line-editor.component.d.ts.map +1 -0
- package/dist/lib/form-panels/deal-line-editor.component.js +882 -0
- package/dist/lib/form-panels/deal-line-editor.component.js.map +1 -0
- package/dist/lib/form-panels/deal-related-links.d.ts +70 -0
- package/dist/lib/form-panels/deal-related-links.d.ts.map +1 -0
- package/dist/lib/form-panels/deal-related-links.js +86 -0
- package/dist/lib/form-panels/deal-related-links.js.map +1 -0
- package/dist/lib/form-panels/order-related-links.d.ts +84 -0
- package/dist/lib/form-panels/order-related-links.d.ts.map +1 -0
- package/dist/lib/form-panels/order-related-links.js +66 -0
- package/dist/lib/form-panels/order-related-links.js.map +1 -0
- package/dist/lib/form-panels/order-related.panel.d.ts +53 -0
- package/dist/lib/form-panels/order-related.panel.d.ts.map +1 -0
- package/dist/lib/form-panels/order-related.panel.js +175 -0
- package/dist/lib/form-panels/order-related.panel.js.map +1 -0
- package/dist/lib/form-panels/party-deals.panels.d.ts.map +1 -1
- package/dist/lib/form-panels/party-deals.panels.js +47 -39
- package/dist/lib/form-panels/party-deals.panels.js.map +1 -1
- package/dist/lib/generated/Entities/mjBizAppsSalesDeal/mjbizappssalesdeal.form.component.js +51 -29
- package/dist/lib/generated/Entities/mjBizAppsSalesDeal/mjbizappssalesdeal.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/mjBizAppsSalesDealStageEvent/mjbizappssalesdealstageevent.form.component.js +6 -4
- package/dist/lib/generated/Entities/mjBizAppsSalesDealStageEvent/mjbizappssalesdealstageevent.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/mjBizAppsSalesPipelineStage/mjbizappssalespipelinestage.form.component.js +2 -2
- package/dist/lib/generated/Entities/mjBizAppsSalesSalesAccount/mjbizappssalessalesaccount.form.component.js +2 -2
- package/dist/lib/generated/Entities/mjBizAppsSalesSalesAccount/mjbizappssalessalesaccount.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/mjBizAppsSalesSalesContact/mjbizappssalessalescontact.form.component.js +2 -2
- package/dist/lib/generated/Entities/mjBizAppsSalesSalesContact/mjbizappssalessalescontact.form.component.js.map +1 -1
- package/dist/lib/generated/generated-forms.module.d.ts +102 -27
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
- package/dist/lib/generated/generated-forms.module.js +492 -42
- package/dist/lib/generated/generated-forms.module.js.map +1 -1
- package/dist/lib/workspace/deal-workspace.component.d.ts +58 -4
- package/dist/lib/workspace/deal-workspace.component.d.ts.map +1 -1
- package/dist/lib/workspace/deal-workspace.component.js +110 -34
- package/dist/lib/workspace/deal-workspace.component.js.map +1 -1
- package/dist/lib/workspace/deal-workspace.validation.d.ts +18 -0
- package/dist/lib/workspace/deal-workspace.validation.d.ts.map +1 -1
- package/dist/lib/workspace/deal-workspace.validation.js +18 -0
- package/dist/lib/workspace/deal-workspace.validation.js.map +1 -1
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +6 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Supplying `Deal.CompanyID` on a new deal, so the form can be saved at all.
|
|
3
|
+
*
|
|
4
|
+
* ── THE DEFECT THIS EXISTS FOR ──────────────────────────────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* A new deal could not be saved through the form. `Deal.CompanyID` is `NOT NULL` with no default, the
|
|
7
|
+
* form renders it as a server-maintained field (correctly — a rep must not choose the selling company),
|
|
8
|
+
* and `DealEntityServer.stampCompanyFromPipeline()` fills it on save. But `BaseFormComponent.SaveRecord`
|
|
9
|
+
* runs `Validate()` FIRST and returns early when it fails, so the save never reached the server that was
|
|
10
|
+
* going to supply the value. Required, unsettable, and filled too late: the record was unsaveable.
|
|
11
|
+
*
|
|
12
|
+
* It worked in the deal workspace because `SelectPipeline` stamped it client-side — "so the record
|
|
13
|
+
* validates locally", in its own words. Unmounting the workspace (9d6ef9e) took the only code that did
|
|
14
|
+
* this with it, and the form was never given the equivalent. That is the whole bug.
|
|
15
|
+
*
|
|
16
|
+
* ── WHY THE CLIENT MAY WRITE A SERVER-OWNED FIELD HERE, WHICH LOOKS WRONG ───────────────────────
|
|
17
|
+
*
|
|
18
|
+
* It is not the client DECIDING the selling company. It is the client pre-filling the answer the server
|
|
19
|
+
* is about to write, read from the SAME authority the server reads — the pipeline. `stampCompanyFromPipeline`
|
|
20
|
+
* overwrites whatever arrives, so the two cannot disagree: if this stamps the wrong value the server
|
|
21
|
+
* replaces it, and if it stamps the right one the server writes it again. The pipeline remains the only
|
|
22
|
+
* thing that can be correct about which company is selling.
|
|
23
|
+
*
|
|
24
|
+
* That is also why this does not make `CompanyID` editable. `deal-form.panels.ts` keeps it
|
|
25
|
+
* `serverMaintained: true` and `server-owned-fields.ts` refuses a user's edit to it. Those stay exactly
|
|
26
|
+
* as they were — what changes is that the value now arrives without a user having to supply one.
|
|
27
|
+
*
|
|
28
|
+
* ── KEYED ON THE CAUSE, NOT ON `IsSaved` ────────────────────────────────────────────────────────
|
|
29
|
+
*
|
|
30
|
+
* The obvious guard is "new deals only". The cause is not newness, it is an ABSENT CompanyID with a
|
|
31
|
+
* pipeline available to resolve it — so that is what is tested. A saved deal always has one (the column
|
|
32
|
+
* is NOT NULL), so the extra breadth costs nothing today and survives a path that creates a deal some
|
|
33
|
+
* other way tomorrow. A guard keyed on a threshold gets outgrown; one keyed on a cause does not.
|
|
34
|
+
*
|
|
35
|
+
* @module @mj-biz-apps/sales-ng
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* The one column read off a pipeline. CodeGen generates no `PipelineEntity` subclass, and this only
|
|
39
|
+
* ever reads — so the view runs `ResultType: 'simple'` and the row is typed here rather than borrowed.
|
|
40
|
+
*/
|
|
41
|
+
export interface PipelineCompanyRow {
|
|
42
|
+
CompanyID: string | null;
|
|
43
|
+
}
|
|
44
|
+
/** What the decision needs to know. Kept flat so it can be tested without an entity or a DOM. */
|
|
45
|
+
export interface CompanyStampState {
|
|
46
|
+
/** True when the form actually holds a record. */
|
|
47
|
+
HasRecord: boolean;
|
|
48
|
+
/** The pipeline the deal is in, as currently chosen. */
|
|
49
|
+
PipelineID: string | null;
|
|
50
|
+
/** The company currently on the deal, if any. */
|
|
51
|
+
CompanyID: string | null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Whether `CompanyID` should be resolved from the pipeline and stamped.
|
|
55
|
+
*
|
|
56
|
+
* Pure and exported so the rule can be pinned without a database. Each clause is a way the stamp would
|
|
57
|
+
* be wrong:
|
|
58
|
+
*
|
|
59
|
+
* - no record, nothing to stamp;
|
|
60
|
+
* - no pipeline chosen yet, so there is no authority to read the company FROM — the rep has not made
|
|
61
|
+
* the choice that decides it, and inventing one would be the client deciding after all;
|
|
62
|
+
* - a company already present is left alone. On a saved deal that is the stored value, and overwriting
|
|
63
|
+
* it here would make this code an authority it is explicitly not.
|
|
64
|
+
*/
|
|
65
|
+
export declare function ShouldStampCompanyFromPipeline(state: CompanyStampState): boolean;
|
|
66
|
+
//# sourceMappingURL=company-from-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"company-from-pipeline.d.ts","sourceRoot":"","sources":["../../../src/lib/custom/company-from-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,iGAAiG;AACjG,MAAM,WAAW,iBAAiB;IAC9B,kDAAkD;IAClD,SAAS,EAAE,OAAO,CAAC;IACnB,wDAAwD;IACxD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iDAAiD;IACjD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAQhF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Supplying `Deal.CompanyID` on a new deal, so the form can be saved at all.
|
|
3
|
+
*
|
|
4
|
+
* ── THE DEFECT THIS EXISTS FOR ──────────────────────────────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* A new deal could not be saved through the form. `Deal.CompanyID` is `NOT NULL` with no default, the
|
|
7
|
+
* form renders it as a server-maintained field (correctly — a rep must not choose the selling company),
|
|
8
|
+
* and `DealEntityServer.stampCompanyFromPipeline()` fills it on save. But `BaseFormComponent.SaveRecord`
|
|
9
|
+
* runs `Validate()` FIRST and returns early when it fails, so the save never reached the server that was
|
|
10
|
+
* going to supply the value. Required, unsettable, and filled too late: the record was unsaveable.
|
|
11
|
+
*
|
|
12
|
+
* It worked in the deal workspace because `SelectPipeline` stamped it client-side — "so the record
|
|
13
|
+
* validates locally", in its own words. Unmounting the workspace (9d6ef9e) took the only code that did
|
|
14
|
+
* this with it, and the form was never given the equivalent. That is the whole bug.
|
|
15
|
+
*
|
|
16
|
+
* ── WHY THE CLIENT MAY WRITE A SERVER-OWNED FIELD HERE, WHICH LOOKS WRONG ───────────────────────
|
|
17
|
+
*
|
|
18
|
+
* It is not the client DECIDING the selling company. It is the client pre-filling the answer the server
|
|
19
|
+
* is about to write, read from the SAME authority the server reads — the pipeline. `stampCompanyFromPipeline`
|
|
20
|
+
* overwrites whatever arrives, so the two cannot disagree: if this stamps the wrong value the server
|
|
21
|
+
* replaces it, and if it stamps the right one the server writes it again. The pipeline remains the only
|
|
22
|
+
* thing that can be correct about which company is selling.
|
|
23
|
+
*
|
|
24
|
+
* That is also why this does not make `CompanyID` editable. `deal-form.panels.ts` keeps it
|
|
25
|
+
* `serverMaintained: true` and `server-owned-fields.ts` refuses a user's edit to it. Those stay exactly
|
|
26
|
+
* as they were — what changes is that the value now arrives without a user having to supply one.
|
|
27
|
+
*
|
|
28
|
+
* ── KEYED ON THE CAUSE, NOT ON `IsSaved` ────────────────────────────────────────────────────────
|
|
29
|
+
*
|
|
30
|
+
* The obvious guard is "new deals only". The cause is not newness, it is an ABSENT CompanyID with a
|
|
31
|
+
* pipeline available to resolve it — so that is what is tested. A saved deal always has one (the column
|
|
32
|
+
* is NOT NULL), so the extra breadth costs nothing today and survives a path that creates a deal some
|
|
33
|
+
* other way tomorrow. A guard keyed on a threshold gets outgrown; one keyed on a cause does not.
|
|
34
|
+
*
|
|
35
|
+
* @module @mj-biz-apps/sales-ng
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Whether `CompanyID` should be resolved from the pipeline and stamped.
|
|
39
|
+
*
|
|
40
|
+
* Pure and exported so the rule can be pinned without a database. Each clause is a way the stamp would
|
|
41
|
+
* be wrong:
|
|
42
|
+
*
|
|
43
|
+
* - no record, nothing to stamp;
|
|
44
|
+
* - no pipeline chosen yet, so there is no authority to read the company FROM — the rep has not made
|
|
45
|
+
* the choice that decides it, and inventing one would be the client deciding after all;
|
|
46
|
+
* - a company already present is left alone. On a saved deal that is the stored value, and overwriting
|
|
47
|
+
* it here would make this code an authority it is explicitly not.
|
|
48
|
+
*/
|
|
49
|
+
export function ShouldStampCompanyFromPipeline(state) {
|
|
50
|
+
if (!state.HasRecord) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
if (!isSet(state.PipelineID)) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
return !isSet(state.CompanyID);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A GUID field counts as absent when it is null, undefined, or blank.
|
|
60
|
+
*
|
|
61
|
+
* The empty string matters: a picker that has been opened and cleared leaves `''`, not null, and a
|
|
62
|
+
* truthiness test alone would have treated `' '` as a real company id.
|
|
63
|
+
*/
|
|
64
|
+
function isSet(value) {
|
|
65
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=company-from-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"company-from-pipeline.js","sourceRoot":"","sources":["../../../src/lib/custom/company-from-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAoBH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,8BAA8B,CAAC,KAAwB;IACnE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,SAAS,KAAK,CAAC,KAAgC;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -12,6 +12,15 @@ export declare class DealFormComponentExtended extends mjBizAppsSalesDealFormCom
|
|
|
12
12
|
* the lock, by `ResolveDealLockState`, and handed to the panels; nothing here reads a status name.
|
|
13
13
|
*/
|
|
14
14
|
IsLost: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the PERSISTED status is a WIN — read as its own flag, never inferred from `!IsLost`.
|
|
17
|
+
*
|
|
18
|
+
* golive#226: the Order and Contract chips belong on a won deal and on no other, because an open
|
|
19
|
+
* deal's order is still a draft nobody should be editing directly. golive#231's outcome tiles read
|
|
20
|
+
* the same flag. Resolved with the lock, from the same status row; the panels read it here rather
|
|
21
|
+
* than asking again.
|
|
22
|
+
*/
|
|
23
|
+
IsWon: boolean;
|
|
15
24
|
/** Shown when locked, so the greyed-out-ness the form cannot render is at least explained. */
|
|
16
25
|
LockNotice: string | null;
|
|
17
26
|
/** Set when `Deal.Amount` no longer matches its order's total. Null when trustworthy, absent or locked. */
|
|
@@ -37,6 +46,24 @@ export declare class DealFormComponentExtended extends mjBizAppsSalesDealFormCom
|
|
|
37
46
|
* is passed here. A locked deal never warns.
|
|
38
47
|
*/
|
|
39
48
|
private resolveAmountFreshness;
|
|
49
|
+
/**
|
|
50
|
+
* Fills the selling company from the pipeline before the save is validated.
|
|
51
|
+
*
|
|
52
|
+
* WHY IT IS HERE AND NOT IN `Validate()`. `SaveRecord` calls `Validate()` and returns early when it
|
|
53
|
+
* fails, so a stamp applied inside validation would be racing the thing it exists to satisfy. This
|
|
54
|
+
* runs before `super.SaveRecord()` — which is what puts it ahead of the validator.
|
|
55
|
+
*
|
|
56
|
+
* `company-from-pipeline.ts` holds the decision and the reasoning, including why the client is
|
|
57
|
+
* allowed to write a server-owned field at all. This method owns only the lookup.
|
|
58
|
+
*
|
|
59
|
+
* A pipeline that cannot be read is NOT an error here. The stamp is best-effort: if it fails, the
|
|
60
|
+
* save proceeds and validation refuses exactly as it did before, which is the behaviour this is
|
|
61
|
+
* replacing rather than something it makes worse. Swallowing a real problem is the risk, so the
|
|
62
|
+
* refusal the user then sees still names `CompanyID`.
|
|
63
|
+
*/
|
|
64
|
+
SaveRecord(StopEditModeAfterSave: boolean): Promise<boolean>;
|
|
65
|
+
/** Reads the chosen pipeline's company and writes it to the deal. See `SaveRecord` for why. */
|
|
66
|
+
private stampCompanyFromPipeline;
|
|
40
67
|
/**
|
|
41
68
|
* Refuses a locked edit BEFORE the round trip, naming the fields.
|
|
42
69
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deal-form.component.d.ts","sourceRoot":"","sources":["../../../src/lib/custom/deal-form.component.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"deal-form.component.d.ts","sourceRoot":"","sources":["../../../src/lib/custom/deal-form.component.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,OAAO,EAAE,+BAA+B,EAAE,MAAM,4EAA4E,CAAC;;AAI7H,0GAA0G;AAC1G,qBAMa,yBAA0B,SAAQ,+BAA+B;IAC1E,6EAA6E;IACtE,QAAQ,UAAS;IAExB;;;;;OAKG;IACI,MAAM,UAAS;IAEtB;;;;;;;OAOG;IACI,KAAK,UAAS;IAErB,8FAA8F;IACvF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAExC,2GAA2G;IACpG,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEzB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/C,qGAAqG;IAC9F,kBAAkB,IAAI,SAAS,MAAM,EAAE,GAAG,IAAI;IAIrD;;;;;OAKG;YACW,gBAAgB;IAS9B;;;;;;;;;OASG;YACW,sBAAsB;IAepC;;;;;;;;;;;;;;OAcG;IACmB,UAAU,CAAC,qBAAqB,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlF,+FAA+F;YACjF,wBAAwB;IAiCtC;;;;;OAKG;IACa,QAAQ,IAAI,gBAAgB;yCA5InC,yBAAyB;2CAAzB,yBAAyB;CA6KrC;AAED,gCAAgC;AAChC,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
|