Skip to content

Commit 3fa359f

Browse files
authored
Merge branch 'master' into FAT-26217
2 parents 077c352 + 2396893 commit 3fa359f

13 files changed

Lines changed: 599 additions & 17 deletions
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
import { Permissions } from '../../../support/dictionary';
2+
import {
3+
APPLICATION_NAMES,
4+
EXPENSE_CLASS_STATUSES,
5+
FUND_DISTRIBUTION_TYPES,
6+
INVOICE_STATUSES,
7+
ORDER_STATUSES,
8+
} from '../../../support/constants';
9+
import { ExpenseClasses } from '../../../support/fragments/settings/finance';
10+
import {
11+
Budgets,
12+
FundDetails,
13+
FinanceHelper,
14+
Funds,
15+
GroupDetails,
16+
Groups,
17+
} from '../../../support/fragments/finance';
18+
import FinanceDetails from '../../../support/fragments/finance/financeDetails';
19+
import { NewOrganization, Organizations } from '../../../support/fragments/organizations';
20+
import { BasicOrderLine, NewOrder, Orders } from '../../../support/fragments/orders';
21+
import { Invoices } from '../../../support/fragments/invoices';
22+
import TopMenu from '../../../support/fragments/topMenu';
23+
import TopMenuNavigation from '../../../support/fragments/topMenuNavigation';
24+
import Users from '../../../support/fragments/users/users';
25+
26+
describe('Finance', () => {
27+
describe('Funds', () => {
28+
const testData = {
29+
expenseClass: ExpenseClasses.getDefaultExpenseClass(),
30+
organization: NewOrganization.getDefaultOrganization(),
31+
user: {},
32+
};
33+
34+
before('Create test data', () => {
35+
cy.getAdminToken().then(() => {
36+
ExpenseClasses.createExpenseClassViaApi(testData.expenseClass);
37+
38+
const group = Groups.getDefaultGroup();
39+
Groups.createViaApi(group).then((groupResponse) => {
40+
testData.group = groupResponse;
41+
42+
const { fiscalYear, fund, budget } = Budgets.createBudgetWithFundLedgerAndFYViaApi({
43+
budget: {
44+
allocated: 1000,
45+
statusExpenseClasses: [
46+
{
47+
status: EXPENSE_CLASS_STATUSES.ACTIVE,
48+
expenseClassId: testData.expenseClass.id,
49+
},
50+
],
51+
},
52+
});
53+
54+
testData.fiscalYear = fiscalYear;
55+
testData.fund = fund;
56+
testData.budget = budget;
57+
58+
Funds.getFundsViaApi({ query: `id=="${fund.id}"` }).then(({ funds }) => {
59+
Funds.updateFundViaApi(funds[0], [group.id]);
60+
});
61+
62+
Organizations.createOrganizationViaApi(testData.organization);
63+
64+
// Order #1 with expense class, linked to Fund A
65+
const order1 = {
66+
...NewOrder.getDefaultOrder({ vendorId: testData.organization.id }),
67+
reEncumber: true,
68+
};
69+
const orderLine1 = BasicOrderLine.getDefaultOrderLine({
70+
listUnitPrice: 10,
71+
fundDistribution: [
72+
{
73+
code: fund.code,
74+
fundId: fund.id,
75+
expenseClassId: testData.expenseClass.id,
76+
distributionType: FUND_DISTRIBUTION_TYPES.PERCENTAGE,
77+
value: 100,
78+
},
79+
],
80+
});
81+
82+
Orders.createOrderWithOrderLineViaApi(order1, orderLine1).then((createdOrder1) => {
83+
testData.order1 = createdOrder1;
84+
testData.orderLine1 = orderLine1;
85+
Orders.updateOrderViaApi({ ...createdOrder1, workflowStatus: ORDER_STATUSES.OPEN });
86+
});
87+
88+
// Invoice #1 linked to Order #1
89+
cy.then(() => {
90+
Invoices.createInvoiceWithInvoiceLineViaApi({
91+
vendorId: testData.organization.id,
92+
poLineId: testData.orderLine1.id,
93+
exportToAccounting: false,
94+
fundDistributions: [
95+
{
96+
code: fund.code,
97+
fundId: fund.id,
98+
expenseClassId: testData.expenseClass.id,
99+
distributionType: FUND_DISTRIBUTION_TYPES.PERCENTAGE,
100+
value: 100,
101+
},
102+
],
103+
subTotal: 10,
104+
releaseEncumbrance: true,
105+
}).then((invoice1) => {
106+
testData.invoice1 = invoice1;
107+
});
108+
});
109+
110+
// Approve and Pay Invoice #1
111+
cy.then(() => {
112+
Invoices.changeInvoiceStatusViaApi({
113+
invoice: testData.invoice1,
114+
status: INVOICE_STATUSES.APPROVED,
115+
});
116+
});
117+
cy.then(() => {
118+
Invoices.changeInvoiceStatusViaApi({
119+
invoice: testData.invoice1,
120+
status: INVOICE_STATUSES.PAID,
121+
});
122+
});
123+
124+
// Set expense class to Inactive on the budget
125+
cy.then(() => {
126+
Budgets.getBudgetByIdViaApi(testData.budget.id).then((budgetResp) => {
127+
Budgets.updateBudgetViaApi({
128+
...budgetResp,
129+
statusExpenseClasses: budgetResp.statusExpenseClasses.map((ec) => ({
130+
...ec,
131+
status: EXPENSE_CLASS_STATUSES.INACTIVE,
132+
})),
133+
});
134+
});
135+
});
136+
137+
// Order #2 without expense class, linked to Fund A
138+
const order2 = {
139+
...NewOrder.getDefaultOrder({ vendorId: testData.organization.id }),
140+
reEncumber: true,
141+
};
142+
const orderLine2 = BasicOrderLine.getDefaultOrderLine({
143+
listUnitPrice: 20,
144+
fundDistribution: [
145+
{
146+
code: fund.code,
147+
fundId: fund.id,
148+
distributionType: FUND_DISTRIBUTION_TYPES.PERCENTAGE,
149+
value: 100,
150+
},
151+
],
152+
});
153+
154+
cy.then(() => {
155+
Orders.createOrderWithOrderLineViaApi(order2, orderLine2).then((createdOrder2) => {
156+
testData.order2 = createdOrder2;
157+
testData.orderLine2 = orderLine2;
158+
Orders.updateOrderViaApi({ ...createdOrder2, workflowStatus: ORDER_STATUSES.OPEN });
159+
});
160+
});
161+
162+
// Invoice #2 linked to Order #2
163+
cy.then(() => {
164+
Invoices.createInvoiceWithInvoiceLineViaApi({
165+
vendorId: testData.organization.id,
166+
poLineId: testData.orderLine2.id,
167+
exportToAccounting: false,
168+
fundDistributions: [
169+
{
170+
code: fund.code,
171+
fundId: fund.id,
172+
distributionType: FUND_DISTRIBUTION_TYPES.PERCENTAGE,
173+
value: 100,
174+
},
175+
],
176+
subTotal: 20,
177+
releaseEncumbrance: true,
178+
}).then((invoice2) => {
179+
testData.invoice2 = invoice2;
180+
});
181+
});
182+
183+
// Approve and Pay Invoice #2
184+
cy.then(() => {
185+
Invoices.changeInvoiceStatusViaApi({
186+
invoice: testData.invoice2,
187+
status: INVOICE_STATUSES.APPROVED,
188+
});
189+
});
190+
cy.then(() => {
191+
Invoices.changeInvoiceStatusViaApi({
192+
invoice: testData.invoice2,
193+
status: INVOICE_STATUSES.PAID,
194+
});
195+
});
196+
});
197+
});
198+
199+
cy.createTempUser([
200+
Permissions.uiFinanceViewFundAndBudget.gui,
201+
Permissions.uiFinanceViewFiscalYear.gui,
202+
Permissions.uiFinanceViewGroups.gui,
203+
]).then((userProperties) => {
204+
testData.user = userProperties;
205+
206+
cy.login(testData.user.username, testData.user.password, {
207+
path: TopMenu.fundPath,
208+
waiter: Funds.waitLoading,
209+
});
210+
});
211+
});
212+
213+
after('Delete test data', () => {
214+
cy.getAdminToken().then(() => {
215+
Users.deleteViaApi(testData.user.userId);
216+
Organizations.deleteOrganizationViaApi(testData.organization.id);
217+
});
218+
});
219+
220+
it(
221+
'C805786 Totals for transactions created after expense class was set to inactive are displayed correctly in the expense class summary (thunderjet)',
222+
{ tags: ['criticalPath', 'thunderjet', 'C805786'] },
223+
() => {
224+
Funds.searchByName(testData.fund.name);
225+
Funds.selectFund(testData.fund.name);
226+
FundDetails.checkFundDetails({
227+
currentExpenseClasses: [
228+
{
229+
name: 'Unassigned',
230+
encumbered: '$0.00',
231+
awaitingPayment: '$0.00',
232+
expended: '$20.00',
233+
percentExpended: '66.67%',
234+
},
235+
{
236+
name: testData.expenseClass.name,
237+
encumbered: '$0.00',
238+
awaitingPayment: '$0.00',
239+
expended: '$10.00',
240+
percentExpended: '33.33%',
241+
status: EXPENSE_CLASS_STATUSES.INACTIVE,
242+
},
243+
],
244+
});
245+
FinanceDetails.checkUnassignedExpenseClassTooltip('currentExpenseClasses');
246+
247+
const BudgetDetails = FundDetails.openCurrentBudgetDetails();
248+
BudgetDetails.checkBudgetDetails({
249+
expenseClasses: [
250+
{
251+
name: 'Unassigned',
252+
encumbered: '$0.00',
253+
awaitingPayment: '$0.00',
254+
expended: '$20.00',
255+
percentExpended: '66.67%',
256+
},
257+
{
258+
name: testData.expenseClass.name,
259+
encumbered: '$0.00',
260+
awaitingPayment: '$0.00',
261+
expended: '$10.00',
262+
percentExpended: '33.33%',
263+
status: EXPENSE_CLASS_STATUSES.INACTIVE,
264+
},
265+
],
266+
});
267+
FinanceDetails.checkUnassignedExpenseClassTooltip('expense-classes');
268+
269+
BudgetDetails.closeBudgetDetails();
270+
TopMenuNavigation.navigateToApp(APPLICATION_NAMES.FINANCE);
271+
FinanceHelper.selectGroupsNavigation();
272+
Groups.waitLoading();
273+
Groups.searchByName(testData.group.name);
274+
Groups.selectGroupByName(testData.group.name);
275+
Groups.checkFYInGroup(testData.fiscalYear.code);
276+
GroupDetails.checkGroupDetails({
277+
expenseClasses: [
278+
{
279+
name: 'Unassigned',
280+
encumbered: '$0.00',
281+
awaitingPayment: '$0.00',
282+
expended: '$20.00',
283+
percentExpended: '66.67%',
284+
},
285+
{
286+
name: testData.expenseClass.name,
287+
encumbered: '$0.00',
288+
awaitingPayment: '$0.00',
289+
expended: '$10.00',
290+
percentExpended: '33.33%',
291+
},
292+
],
293+
});
294+
FinanceDetails.checkUnassignedExpenseClassTooltip('expenseClasses');
295+
},
296+
);
297+
});
298+
});

0 commit comments

Comments
 (0)