Skip to content

Commit 1173f90

Browse files
committed
5446 add system test
1 parent ac46edd commit 1173f90

File tree

2 files changed

+82
-37
lines changed

2 files changed

+82
-37
lines changed

app/javascript/utils/audit_duplicates.js

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,61 @@
11
import $ from 'jquery';
22

33
$(() => {
4-
function checkForDuplicates(e, buttonName) {
5-
const form = $(this).closest('form');
6-
const itemCounts = {}; // Will look like: { "2": 3, "5": 1, "12": 2 }
7-
const itemNames = {}; // Will look like: { "2": "Item A", "5": "Item B", "12": "Item C" }
8-
const itemQuantities = {}; // Will look like: { "2": [{qty: 15, barcode: "123"}, {qty: 10, barcode: "456"}] }
4+
function processFormItems(form) {
5+
const itemCounts = {};
6+
const itemNames = {};
7+
const itemQuantities = {};
8+
const itemSections = [];
99

10-
form.find('select[name$="[item_id]"]').each(function() {
10+
form.find('select[name*="[item_id]"]').each(function() {
1111
const itemId = $(this).val();
1212
const itemText = $(this).find('option:selected').text();
1313
const section = $(this).closest('.line_item_section');
1414
const quantityInput = section.find('input[name*="[quantity]"]');
1515
const itemQuantity = parseInt(quantityInput.val()) || 0;
1616
const barcodeValue = section.find('.__barcode_item_lookup').val() || '';
1717

18-
if (!itemId || itemText === "Choose an item" || itemQuantity === 0) {
19-
section.remove();
18+
if (!itemId || itemId === '' || itemText === "Choose an item" || itemQuantity === 0) {
2019
return;
2120
}
2221

2322
itemCounts[itemId] = (itemCounts[itemId] || 0) + 1;
2423
itemNames[itemId] = itemText;
2524
if (!itemQuantities[itemId]) itemQuantities[itemId] = [];
2625
itemQuantities[itemId].push({ qty: itemQuantity, barcode: barcodeValue });
26+
itemSections.push({ itemId, section, quantity: itemQuantity });
2727
});
28+
29+
return { itemCounts, itemNames, itemQuantities, itemSections };
30+
}
31+
32+
function checkForDuplicates(e, buttonName) {
33+
e.preventDefault(); // Always prevent default first
34+
35+
const form = $(this).closest('form');
36+
const { itemCounts, itemNames, itemQuantities } = processFormItems(form);
2837

2938
// Check for duplicates
3039
const duplicates = Object.keys(itemCounts)
31-
.filter(itemId => itemCounts[itemId] > 1)
40+
.filter(itemId => itemId && itemId !== '' && itemCounts[itemId] > 1)
3241
.map(itemId => ({ name: itemNames[itemId], id: itemId }));
3342

3443
if (duplicates.length > 0) {
3544
// Show modal with duplicate items
3645
showDuplicateModal(duplicates, itemQuantities, form, buttonName);
37-
e.preventDefault();
38-
}
39-
// else, allow form submission to proceed
46+
return false;
47+
} else {
48+
// No duplicates, submit the form
49+
const hiddenBtn = $(`<button type="submit" name="${buttonName}" style="display:none;"></button>`);
50+
form.append(hiddenBtn);
51+
form.off('submit'); // Remove event handlers to avoid recursion
52+
hiddenBtn.trigger('click');
53+
}
4054
}
4155

42-
$("button[name='save_progress']").on('click', function (e) {
43-
checkForDuplicates.call(this, e, 'save_progress');
44-
});
45-
46-
$("button[name='confirm_audit']").on('click', function (e) {
47-
checkForDuplicates.call(this, e, 'confirm_audit');
56+
$(document).on('click', "button[name='save_progress'], button[name='confirm_audit']", function (e) {
57+
const buttonName = $(this).attr('name');
58+
checkForDuplicates.call(this, e, buttonName);
4859
});
4960

5061
function showDuplicateModal(duplicateItems, duplicateQuantities, form, buttonName) {
@@ -85,9 +96,6 @@ $(() => {
8596
</div>
8697
`;
8798

88-
// Remove existing modal
89-
$('#duplicateItemsModal').remove();
90-
9199
// Add and show modal
92100
$('body').append(modalHtml);
93101
$('#duplicateItemsModal').modal('show');
@@ -108,39 +116,31 @@ $(() => {
108116
const hiddenBtn = $(`<button type="submit" name="${buttonName}" style="display:none;"></button>`);
109117
form.append(hiddenBtn);
110118

111-
// Click the hidden button to submit with the correct parameter
119+
// // Click the hidden button to submit with the correct parameter
112120
hiddenBtn.trigger('click');
113121
});
114122
}
115123

116124
function mergeDuplicateItems(form) {
117-
const itemQuantities = {};
118-
const itemSections = [];
125+
const { itemSections } = processFormItems(form);
126+
const mergedQuantities = {};
119127

120-
// Collect all line items and their quantities
121-
form.find('select[name$="[item_id]"]').each(function() {
122-
const itemId = $(this).val();
123-
const section = $(this).closest('.line_item_section');
124-
const quantityInput = section.find('input[name*="[quantity]"]');
125-
const quantity = parseInt(quantityInput.val()) || 0;
126-
127-
if (itemId && itemId !== '') {
128-
itemSections.push({ itemId, section, quantity });
129-
itemQuantities[itemId] = (itemQuantities[itemId] || 0) + quantity;
130-
}
128+
// Calculate merged quantities
129+
itemSections.forEach(({ itemId, quantity }) => {
130+
mergedQuantities[itemId] = (mergedQuantities[itemId] || 0) + quantity;
131131
});
132132

133133
// Find duplicates and merge them
134134
const processedItems = new Set();
135135

136-
itemSections.forEach(({ itemId, section, quantity }) => {
136+
itemSections.forEach(({ itemId, section }) => {
137137
if (processedItems.has(itemId)) {
138138
// This is a duplicate - remove it
139139
section.remove();
140140
} else {
141141
// This is the first occurrence - update quantity to merged total
142142
const quantityInput = section.find('input[name*="[quantity]"]');
143-
quantityInput.val(itemQuantities[itemId]);
143+
quantityInput.val(mergedQuantities[itemId]);
144144
processedItems.add(itemId);
145145
}
146146
});

spec/system/audit_system_spec.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,51 @@
195195
expect(page).to have_content("Delete Audit")
196196
expect(page).to have_content("Finalize Audit")
197197
end
198+
199+
it "detects duplicate items and shows modal", js: true do
200+
# Disable server-side validation to test JS modal
201+
allow_any_instance_of(Audit).to receive(:line_items_unique_by_item_id)
202+
visit subject
203+
click_link "New Audit"
204+
205+
await_select2("#audit_line_items_attributes_0_item_id") do
206+
select storage_location.name, from: "Storage location"
207+
end
208+
209+
# Add first entry for the item
210+
select item.name, from: "audit_line_items_attributes_0_item_id"
211+
fill_in "audit_line_items_attributes_0_quantity", with: "10"
212+
213+
# Add a new line item row
214+
find("[data-form-input-target='addButton']").click
215+
216+
# Add second entry for the same item
217+
within all('.line_item_section').last do
218+
item_select = find('select[name*="[item_id]"]')
219+
select item.name, from: item_select[:id]
220+
quantity_input = find('input[name*="[quantity]"]')
221+
fill_in quantity_input[:id], with: "15"
222+
end
223+
224+
# Try to save - should trigger duplicate detection modal
225+
click_button "Save Progress"
226+
227+
# JavaScript modal should appear
228+
expect(page).to have_css("#duplicateItemsModal", visible: true)
229+
expect(page).to have_content("Multiple Item Entries Detected")
230+
expect(page).to have_content("Merge Items")
231+
expect(page).to have_content("Make Changes")
232+
233+
# Test merge functionality
234+
click_button "Merge Items"
235+
236+
# Should merge duplicates and submit successfully
237+
expect(page).to have_content("Audit's progress was successfully saved.")
238+
239+
# Verify only one line item with merged quantity (10 + 15 = 25)
240+
expect(Audit.last.line_items.count).to eq(1)
241+
expect(Audit.last.line_items.first.quantity).to eq(25)
242+
end
198243
end
199244

200245
context "with an existing audit" do

0 commit comments

Comments
 (0)