Skip to content

Commit f626b3f

Browse files
authored
Merge pull request #17 from Acumatica/pre-release-bug-fixes
Pre release bug fixes
2 parents f3a2cd7 + 8cf192c commit f626b3f

File tree

5 files changed

+81
-13
lines changed

5 files changed

+81
-13
lines changed

acumate-plugin/src/backend-metadata-utils.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,20 @@ export function buildBackendViewMap(structure: GraphStructure | undefined): Map<
8484
continue;
8585
}
8686

87-
const metadata: BackendViewMetadata = {
88-
viewName: view.name ?? key,
89-
normalizedName: lookupKey,
90-
view,
91-
fields: buildBackendFieldMap(view),
92-
};
87+
let metadata = views.get(lookupKey);
88+
if (!metadata) {
89+
metadata = {
90+
viewName: view.name ?? key,
91+
normalizedName: lookupKey,
92+
view,
93+
fields: buildBackendFieldMap(view),
94+
};
95+
views.set(lookupKey, metadata);
96+
} else {
97+
mergeBackendFields(metadata.fields, view);
98+
}
9399

94-
views.set(lookupKey, metadata);
95-
if (normalizedKey && normalizedKey !== lookupKey && !views.has(normalizedKey)) {
100+
if (normalizedKey && !views.has(normalizedKey)) {
96101
views.set(normalizedKey, metadata);
97102
}
98103
}
@@ -132,3 +137,12 @@ export function buildBackendFieldMap(view: View | undefined): Map<string, Backen
132137

133138
return fields;
134139
}
140+
141+
function mergeBackendFields(target: Map<string, BackendFieldMetadata>, sourceView: View) {
142+
const incomingFields = buildBackendFieldMap(sourceView);
143+
for (const [fieldKey, fieldMetadata] of incomingFields) {
144+
if (!target.has(fieldKey)) {
145+
target.set(fieldKey, fieldMetadata);
146+
}
147+
}
148+
}

acumate-plugin/src/test/fixtures/screens/SO/SO301000/extensions/SO301000_FieldSelectors.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
<field name="AMEstimateQty" append="#missing-target"></field>
44
<field name="AMInvalidSelector" move="#fsOrderTotals-Totals [name='CuryGoodsExtPriceTotal'"></field>
55
<field name="AMUnknownField" before="#fsCalculatedAmounts-Totals [name='BlanketOpenQty']"></field>
6+
<qp-tab id="tab-Move" after="#tab-PutAway111"></qp-tab>
67
</template>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as assert from 'assert';
2+
import { describe, it } from 'mocha';
3+
import { buildBackendViewMap } from '../../backend-metadata-utils';
4+
import { GraphStructure } from '../../model/graph-structure';
5+
import { View } from '../../model/view';
6+
7+
describe('backend metadata utilities', () => {
8+
it('merges duplicate backend views and preserves the first metadata instance', () => {
9+
const baseTransactionsView: View = {
10+
name: 'transactions',
11+
cacheName: 'Purchase Receipt Line',
12+
cacheType: 'POReceiptLine',
13+
fields: {
14+
ReceiptNbr: { name: 'ReceiptNbr' },
15+
},
16+
};
17+
18+
const secondaryTransactionsView: View = {
19+
name: 'Transactions',
20+
cacheName: 'Purchase Receipt Line (Alt)',
21+
cacheType: 'POReceiptLine',
22+
fields: {
23+
ReceiptDate: { name: 'ReceiptDate' },
24+
},
25+
};
26+
27+
const structure: GraphStructure = {
28+
name: 'PX.Objects.PO.POReceiptEntry',
29+
views: {
30+
transactions: baseTransactionsView,
31+
transactionsPOLine: secondaryTransactionsView,
32+
},
33+
};
34+
35+
const backendViewMap = buildBackendViewMap(structure);
36+
const canonical = backendViewMap.get('transactions');
37+
assert.ok(canonical, 'Expected canonical transactions view metadata');
38+
assert.strictEqual(canonical.view, baseTransactionsView, 'First view definition should be preserved');
39+
assert.ok(canonical.fields.has('receiptnbr'), 'Original field should remain');
40+
assert.ok(canonical.fields.has('receiptdate'), 'Fields from duplicate view should be merged');
41+
42+
const aliasMetadata = backendViewMap.get('transactionspoline');
43+
assert.strictEqual(aliasMetadata, canonical, 'Alternate view keys should reference the canonical metadata');
44+
});
45+
});

acumate-plugin/src/test/suite/htmlValidation.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,16 @@ describe('HTML validation diagnostics', () => {
370370
);
371371
});
372372

373+
it('validates customization selectors on non-field elements', async () => {
374+
const document = await vscode.workspace.openTextDocument(screenSelectorExtensionFixture);
375+
await validateHtmlFile(document);
376+
const diagnostics = AcuMateContext.HtmlValidator?.get(document.uri) ?? [];
377+
assert.ok(
378+
diagnostics.some(d => d.message.includes('after selector') && d.message.includes('tab-PutAway111')),
379+
'Expected diagnostic when qp-tab after selector targets missing element'
380+
);
381+
});
382+
373383
it('derives view metadata from selector targets when <field> lacks a parent view', async () => {
374384
const document = await vscode.workspace.openTextDocument(screenSelectorExtensionFixture);
375385
await validateHtmlFile(document);

acumate-plugin/src/validation/htmlValidation/html-validation.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ function validateDom(
183183
: `The <${node.name}> element must define an id attribute.`;
184184
pushHtmlDiagnostic(diagnostics, suppression, range, message);
185185
}
186+
187+
validateCustomizationSelectors(node);
186188
}
187189

188190
if (
@@ -292,10 +294,6 @@ function validateDom(
292294
validateConfigBinding(node.attribs["config.bind"], node);
293295
}
294296

295-
if (node.type === "tag" && node.name === "field") {
296-
validateFieldCustomizationSelectors(node);
297-
}
298-
299297
if (
300298
node.type === "tag" &&
301299
(node.name === "field" || node.name === "qp-field") &&
@@ -387,7 +385,7 @@ function validateDom(
387385
}
388386
}
389387

390-
function validateFieldCustomizationSelectors(node: any) {
388+
function validateCustomizationSelectors(node: any) {
391389
if (!baseScreenDocument) {
392390
return;
393391
}

0 commit comments

Comments
 (0)