Skip to content

Commit 8ea8da9

Browse files
committed
MODFQMMGR-746 Add invoice ET migration
This migration switches queries from simple_invoice to composite_invoice, and moves references to the old invoice.bill_to field to the new version in the composite. Other ETs that contain simple_invoice will only get field warnings if they reference the bill_to field.
1 parent 509b43d commit 8ea8da9

5 files changed

Lines changed: 250 additions & 2 deletions

File tree

src/main/java/org/folio/fqm/migration/MigrationStrategyRepository.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.folio.fqm.migration.strategies.impl.V21NotContainsAllToNeqOperatorMigration;
2525
import org.folio.fqm.migration.strategies.impl.V22UserCustomFieldMigration;
2626
import org.folio.fqm.migration.strategies.impl.V23UserCreatedUpdatedDateFieldDeprecation;
27+
import org.folio.fqm.migration.strategies.impl.V24InvoiceSimpleToCompositeMigration;
2728
import org.folio.fqm.migration.strategies.impl.V2ResourceTypeConsolidation;
2829
import org.folio.fqm.migration.strategies.impl.V3RamsonsFieldCleanup;
2930
import org.folio.fqm.migration.strategies.impl.V4DateFieldTimezoneAddition;
@@ -76,7 +77,8 @@ public MigrationStrategyRepository(
7677
new V20ContainsAllToEqOperatorMigration(),
7778
new V21NotContainsAllToNeqOperatorMigration(),
7879
new V22UserCustomFieldMigration(),
79-
new V23UserCreatedUpdatedDateFieldDeprecation()
80+
new V23UserCreatedUpdatedDateFieldDeprecation(),
81+
new V24InvoiceSimpleToCompositeMigration()
8082
// adding a strategy? be sure to update the `CURRENT_VERSION` in MigrationConfiguration!
8183
);
8284
}

src/main/java/org/folio/fqm/migration/strategies/AbstractSimpleMigrationStrategy.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ public MigratableQueryInformation additionalChanges(Void v, MigratableQueryInfor
161161
protected static String getNewFieldName(Map<String, String> fieldChanges, String oldFieldName) {
162162
if (MigrationConfiguration.VERSION_KEY.equals(oldFieldName)) {
163163
return oldFieldName;
164+
} else if (fieldChanges.containsKey(oldFieldName)) { // specific field changes take priority over wildcards
165+
return fieldChanges.get(oldFieldName);
164166
} else if (fieldChanges.containsKey("*")) {
165167
return fieldChanges.get("*").formatted(oldFieldName);
166168
} else {
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package org.folio.fqm.migration.strategies.impl;
2+
3+
import java.util.Map;
4+
import java.util.UUID;
5+
import lombok.RequiredArgsConstructor;
6+
import lombok.extern.log4j.Log4j2;
7+
import org.folio.fqm.migration.strategies.AbstractSimpleMigrationStrategy;
8+
import org.folio.fqm.migration.warnings.FieldWarningFactory;
9+
import org.folio.fqm.migration.warnings.RemovedFieldWarning;
10+
11+
/**
12+
* Version 24, migrates from simple_invoice to composite_invoice entity type.
13+
* All fields from simple_invoice get "invoice." prepended to their names.
14+
* The (now non-existent) bill_to field is specifically migrated to bill_to.address.
15+
* For other composites containing simple_invoice, a warning is issued for bill_to references.
16+
*/
17+
@Log4j2
18+
@RequiredArgsConstructor
19+
public class V24InvoiceSimpleToCompositeMigration extends AbstractSimpleMigrationStrategy {
20+
21+
private static final UUID SIMPLE_INVOICE_ID = UUID.fromString("4d626ce1-1880-48d2-9d4c-81667fdc5dbb");
22+
private static final UUID COMPOSITE_INVOICE_ID = UUID.fromString("5c4cb0c9-c8bf-4fe5-b844-4de90ca445dc");
23+
private static final UUID COMPOSITE_INVOICE_LINE_ID = UUID.fromString("a2ea9d7a-3ed3-41c7-9cdd-f433e029ea0f");
24+
private static final UUID COMPOSITE_ORDER_INVOICE_ANALYTICS_ID = UUID.fromString("f3ccbf49-8e3e-4f5c-a60e-04ad80543a4a");
25+
private static final UUID COMPOSITE_INVOICE_VOUCHER_LINE_LEDGER_FUND_ORG_ID = UUID.fromString("8ddd1e32-5c85-46ab-8bf3-1ec9a76c18cf");
26+
private static final UUID COMPOSITE_INVOICE_VOUCHER_LINE_ORG_ID = UUID.fromString("2028a343-5603-4e86-99d5-c7de322c1709");
27+
28+
@Override
29+
public String getMaximumApplicableVersion() {
30+
return "24";
31+
}
32+
33+
@Override
34+
public String getLabel() {
35+
return "V24 Invoice simple to composite migration";
36+
}
37+
38+
@Override
39+
public Map<UUID, Map<String, FieldWarningFactory>> getFieldWarnings() {
40+
FieldWarningFactory billToWarning = RemovedFieldWarning.withoutAlternative();
41+
return Map.of(
42+
COMPOSITE_INVOICE_LINE_ID,
43+
Map.of("invoice.bill_to", billToWarning),
44+
COMPOSITE_ORDER_INVOICE_ANALYTICS_ID,
45+
Map.of("invoice.bill_to", billToWarning),
46+
COMPOSITE_INVOICE_VOUCHER_LINE_LEDGER_FUND_ORG_ID,
47+
Map.of("invoice.bill_to", billToWarning),
48+
COMPOSITE_INVOICE_VOUCHER_LINE_ORG_ID,
49+
Map.of("invoice.bill_to", billToWarning)
50+
);
51+
}
52+
53+
@Override
54+
public Map<UUID, UUID> getEntityTypeChanges() {
55+
return Map.of(SIMPLE_INVOICE_ID, COMPOSITE_INVOICE_ID);
56+
}
57+
58+
@Override
59+
public Map<UUID, Map<String, String>> getFieldChanges() {
60+
return Map.of(
61+
SIMPLE_INVOICE_ID,
62+
Map.of(
63+
"*", "invoice.%s",
64+
"bill_to", "bill_to.address"
65+
)
66+
);
67+
}
68+
}

src/test/java/org/folio/fqm/migration/AbstractSimpleMigrationStrategyTest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public Map<UUID, Map<String, String>> getFieldChanges() {
6969
return Map.ofEntries(
7070
Map.entry(UUID_A, Map.of("foo", "bar")),
7171
Map.entry(UUID_E, Map.of("foo", "bar")),
72-
Map.entry(UUID_F, Map.of("*", "bar.%s"))
72+
Map.entry(UUID_F, Map.of("*", "bar.%s", "specific", "override"))
7373
);
7474
}
7575

@@ -215,6 +215,19 @@ static List<Arguments> sourcesForMigrationResults() {
215215
List.of("bar.field1", "bar.foo", "bar.field2")
216216
)
217217
),
218+
// No ET change, FQL changes (wildcard with specific override)
219+
Arguments.of(
220+
new MigratableQueryInformation(
221+
UUID_F,
222+
"{\"_version\":\"version\",\"specific\":{\"$eq\":\"foo\"}}",
223+
List.of("specific")
224+
),
225+
new MigratableQueryInformation(
226+
UUID_F,
227+
"{\"_version\":\"version\",\"override\":{\"$eq\":\"foo\"}}",
228+
List.of("override")
229+
)
230+
),
218231
// No changes
219232
Arguments.of(
220233
new MigratableQueryInformation(
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package org.folio.fqm.migration.strategies.impl;
2+
3+
import java.util.List;
4+
import java.util.UUID;
5+
import org.folio.fqm.migration.MigratableQueryInformation;
6+
import org.folio.fqm.migration.strategies.MigrationStrategy;
7+
import org.folio.fqm.migration.warnings.RemovedFieldWarning;
8+
import org.junit.jupiter.params.provider.Arguments;
9+
10+
public class V24InvoiceSimpleToCompositeMigrationTest extends TestTemplate {
11+
12+
private static final UUID SIMPLE_INVOICE_ID = UUID.fromString("4d626ce1-1880-48d2-9d4c-81667fdc5dbb");
13+
private static final UUID COMPOSITE_INVOICE_ID = UUID.fromString("5c4cb0c9-c8bf-4fe5-b844-4de90ca445dc");
14+
private static final UUID COMPOSITE_INVOICE_LINE_ID = UUID.fromString("a2ea9d7a-3ed3-41c7-9cdd-f433e029ea0f");
15+
private static final UUID COMPOSITE_ORDER_INVOICE_ANALYTICS_ID = UUID.fromString("f3ccbf49-8e3e-4f5c-a60e-04ad80543a4a");
16+
private static final UUID COMPOSITE_INVOICE_VOUCHER_LINE_LEDGER_FUND_ORG_ID = UUID.fromString("8ddd1e32-5c85-46ab-8bf3-1ec9a76c18cf");
17+
private static final UUID COMPOSITE_INVOICE_VOUCHER_LINE_ORG_ID = UUID.fromString("2028a343-5603-4e86-99d5-c7de322c1709");
18+
19+
@Override
20+
public MigrationStrategy getStrategy() {
21+
return new V24InvoiceSimpleToCompositeMigration();
22+
}
23+
24+
@Override
25+
public List<Arguments> getExpectedTransformations() {
26+
return List.of(
27+
Arguments.of(
28+
"Migrate bill_to to bill_to.address and other fields to invoice.field",
29+
MigratableQueryInformation
30+
.builder()
31+
.entityTypeId(SIMPLE_INVOICE_ID)
32+
.fqlQuery(
33+
"{\"bill_to\": {\"$eq\": \"some address\"}, \"accounting_code\": {\"$eq\": \"abc\"}, \"bill_to_id\": {\"$eq\": \"some-uuid\"}}"
34+
)
35+
.fields(List.of("bill_to", "accounting_code", "bill_to_id"))
36+
.build(),
37+
MigratableQueryInformation
38+
.builder()
39+
.entityTypeId(COMPOSITE_INVOICE_ID)
40+
.fqlQuery(
41+
"{\"$and\": [{\"bill_to.address\": {\"$eq\": \"some address\"}}, {\"invoice.accounting_code\": {\"$eq\": \"abc\"}}, {\"invoice.bill_to_id\": {\"$eq\": \"some-uuid\"}}]}"
42+
)
43+
.fields(List.of("bill_to.address", "invoice.accounting_code", "invoice.bill_to_id"))
44+
.build()
45+
),
46+
Arguments.of(
47+
"Warn for bill_to and do not migrate other fields in a composite containing simple_invoice (invoice_line case)",
48+
MigratableQueryInformation
49+
.builder()
50+
.entityTypeId(COMPOSITE_INVOICE_LINE_ID)
51+
.fqlQuery(
52+
"{\"invoice.bill_to\": {\"$eq\": \"some address\"}, \"invoice.accounting_code\": {\"$eq\": \"abc\"}}"
53+
)
54+
.fields(List.of("invoice.bill_to", "invoice.accounting_code"))
55+
.build(),
56+
MigratableQueryInformation
57+
.builder()
58+
.entityTypeId(COMPOSITE_INVOICE_LINE_ID)
59+
.fqlQuery(
60+
"{\"invoice.accounting_code\": {\"$eq\": \"abc\"}}"
61+
)
62+
.fields(List.of("invoice.accounting_code"))
63+
.warnings(List.of(
64+
RemovedFieldWarning.withoutAlternative().apply("", "invoice.bill_to", "{\n \"$eq\" : \"some address\"\n}"),
65+
RemovedFieldWarning.withoutAlternative().apply("", "invoice.bill_to", null)
66+
))
67+
.hadBreakingChanges(true)
68+
.build()
69+
),
70+
Arguments.of(
71+
"Warn for bill_to and do not migrate other fields in a composite containing simple_invoice (analytics case)",
72+
MigratableQueryInformation
73+
.builder()
74+
.entityTypeId(COMPOSITE_ORDER_INVOICE_ANALYTICS_ID)
75+
.fqlQuery(
76+
"{\"invoice.bill_to\": {\"$eq\": \"some address\"}, \"invoice.accounting_code\": {\"$eq\": \"abc\"}}"
77+
)
78+
.fields(List.of("invoice.bill_to", "invoice.accounting_code"))
79+
.build(),
80+
MigratableQueryInformation
81+
.builder()
82+
.entityTypeId(COMPOSITE_ORDER_INVOICE_ANALYTICS_ID)
83+
.fqlQuery(
84+
"{\"invoice.accounting_code\": {\"$eq\": \"abc\"}}"
85+
)
86+
.fields(List.of("invoice.accounting_code"))
87+
.warnings(List.of(
88+
RemovedFieldWarning.withoutAlternative().apply("", "invoice.bill_to", "{\n \"$eq\" : \"some address\"\n}"),
89+
RemovedFieldWarning.withoutAlternative().apply("", "invoice.bill_to", null)
90+
))
91+
.hadBreakingChanges(true)
92+
.build()
93+
),
94+
Arguments.of(
95+
"Warn for bill_to and do not migrate other fields in a composite containing simple_invoice (voucher line ledger fund org case)",
96+
MigratableQueryInformation
97+
.builder()
98+
.entityTypeId(COMPOSITE_INVOICE_VOUCHER_LINE_LEDGER_FUND_ORG_ID)
99+
.fqlQuery(
100+
"{\"invoice.bill_to\": {\"$eq\": \"some address\"}, \"invoice.accounting_code\": {\"$eq\": \"abc\"}}"
101+
)
102+
.fields(List.of("invoice.bill_to", "invoice.accounting_code"))
103+
.build(),
104+
MigratableQueryInformation
105+
.builder()
106+
.entityTypeId(COMPOSITE_INVOICE_VOUCHER_LINE_LEDGER_FUND_ORG_ID)
107+
.fqlQuery(
108+
"{\"invoice.accounting_code\": {\"$eq\": \"abc\"}}"
109+
)
110+
.fields(List.of("invoice.accounting_code"))
111+
.warnings(List.of(
112+
RemovedFieldWarning.withoutAlternative().apply("", "invoice.bill_to", "{\n \"$eq\" : \"some address\"\n}"),
113+
RemovedFieldWarning.withoutAlternative().apply("", "invoice.bill_to", null)
114+
))
115+
.hadBreakingChanges(true)
116+
.build()
117+
),
118+
Arguments.of(
119+
"Warn for bill_to and do not migrate other fields in a composite containing simple_invoice (voucher line org case)",
120+
MigratableQueryInformation
121+
.builder()
122+
.entityTypeId(COMPOSITE_INVOICE_VOUCHER_LINE_ORG_ID)
123+
.fqlQuery(
124+
"{\"invoice.bill_to\": {\"$eq\": \"some address\"}, \"invoice.accounting_code\": {\"$eq\": \"abc\"}}"
125+
)
126+
.fields(List.of("invoice.bill_to", "invoice.accounting_code"))
127+
.build(),
128+
MigratableQueryInformation
129+
.builder()
130+
.entityTypeId(COMPOSITE_INVOICE_VOUCHER_LINE_ORG_ID)
131+
.fqlQuery(
132+
"{\"invoice.accounting_code\": {\"$eq\": \"abc\"}}"
133+
)
134+
.fields(List.of("invoice.accounting_code"))
135+
.warnings(List.of(
136+
RemovedFieldWarning.withoutAlternative().apply("", "invoice.bill_to", "{\n \"$eq\" : \"some address\"\n}"),
137+
RemovedFieldWarning.withoutAlternative().apply("", "invoice.bill_to", null)
138+
))
139+
.hadBreakingChanges(true)
140+
.build()
141+
),
142+
Arguments.of(
143+
"Do not over-migrate already-migrated fields in composite_invoice",
144+
MigratableQueryInformation
145+
.builder()
146+
.entityTypeId(COMPOSITE_INVOICE_ID)
147+
.fqlQuery(
148+
"{\"bill_to.address\": {\"$eq\": \"some address\"}, \"invoice.accounting_code\": {\"$eq\": \"abc\"}}"
149+
)
150+
.fields(List.of("bill_to.address", "invoice.accounting_code"))
151+
.build(),
152+
MigratableQueryInformation
153+
.builder()
154+
.entityTypeId(COMPOSITE_INVOICE_ID)
155+
.fqlQuery(
156+
"{\"$and\": [{\"bill_to.address\": {\"$eq\": \"some address\"}}, {\"invoice.accounting_code\": {\"$eq\": \"abc\"}}]}"
157+
)
158+
.fields(List.of("bill_to.address", "invoice.accounting_code"))
159+
.build()
160+
)
161+
);
162+
}
163+
}

0 commit comments

Comments
 (0)