| 35268 |
aman |
1 |
// Show Scratch Offers
|
|
|
2 |
$(document).on('click', '.scratch-offers', function () {
|
|
|
3 |
doGetAjaxRequestHandler(`${context}/store/offer/showScratchOffers`, function (response) {
|
|
|
4 |
$('#main-content').html(response);
|
|
|
5 |
});
|
|
|
6 |
});
|
|
|
7 |
|
|
|
8 |
// Offer image input
|
|
|
9 |
$(document).on('click', '.add-offer-image', function () {
|
|
|
10 |
const newEntry = `
|
|
|
11 |
<div class="offer-image-entry">
|
|
|
12 |
<input type="file" class="form-control offer-image-file" accept="image/*" required>
|
|
|
13 |
<input type="hidden" class="offer-image-id" name="offerImageIds[]">
|
|
|
14 |
</div>`;
|
|
|
15 |
$('.offer-images-container').append(newEntry);
|
|
|
16 |
});
|
|
|
17 |
|
|
|
18 |
// Handle offer image upload
|
|
|
19 |
$(document).on('input', '.offer-image-file', function () {
|
|
|
20 |
const $input = $(this);
|
|
|
21 |
const $hiddenInput = $input.siblings('.offer-image-id');
|
|
|
22 |
const files = Array.from($input[0].files);
|
|
|
23 |
|
|
|
24 |
if (!files.length) {
|
|
|
25 |
alert('Please select images');
|
|
|
26 |
return;
|
|
|
27 |
}
|
|
|
28 |
|
|
|
29 |
console.log("files", files);
|
|
|
30 |
|
|
|
31 |
// Process all files
|
|
|
32 |
const uploadPromises = files.map(file => {
|
|
|
33 |
return new Promise((resolve, reject) => {
|
|
|
34 |
uploadDocument(file, (documentId) => {
|
|
|
35 |
if (documentId) {
|
|
|
36 |
resolve(documentId);
|
|
|
37 |
} else {
|
|
|
38 |
reject(`Upload failed for ${file.name}`);
|
|
|
39 |
}
|
|
|
40 |
});
|
|
|
41 |
});
|
|
|
42 |
});
|
|
|
43 |
|
|
|
44 |
Promise.all(uploadPromises)
|
|
|
45 |
.then(newDocIds => {
|
|
|
46 |
// Get existing IDs and append new ones
|
|
|
47 |
const existingIds = $hiddenInput.val()
|
|
|
48 |
? $hiddenInput.val().split(',')
|
|
|
49 |
: [];
|
|
|
50 |
const allIds = [...existingIds, ...newDocIds];
|
|
|
51 |
$hiddenInput.val(allIds.join(','));
|
|
|
52 |
console.log('Uploaded IDs:', allIds);
|
|
|
53 |
})
|
|
|
54 |
.catch(error => {
|
|
|
55 |
console.error(error);
|
|
|
56 |
alert(`Error: ${error}. Some files might not have uploaded.`);
|
|
|
57 |
$input.val(''); // Clear input on error
|
|
|
58 |
});
|
|
|
59 |
});
|
|
|
60 |
|
|
|
61 |
// Unified gift handling for both create/edit modals
|
|
|
62 |
$(document).on('click', '.add-gift', function () {
|
|
|
63 |
// Get current gift index
|
|
|
64 |
const index = $('.gift-row').length;
|
|
|
65 |
|
|
|
66 |
const giftRow = $('tr.gift-row:first').clone();
|
|
|
67 |
giftRow.find('input, select, textarea').val('');
|
|
|
68 |
giftRow.find('.default-gift-radio').prop('checked', false);
|
|
|
69 |
giftRow.find('.multiselect-container').remove();
|
|
|
70 |
giftRow.find('button.multiselect').remove();
|
|
|
71 |
giftRow.append('<td class="align-middle">\n' +
|
|
|
72 |
' <button type="button" class="btn btn-sm btn-danger remove-gift">' +
|
|
|
73 |
' <i class="fa fa-times"></i>' +
|
|
|
74 |
' </button>' +
|
|
|
75 |
' </td>');
|
|
|
76 |
console.log(giftRow);
|
|
|
77 |
|
|
|
78 |
// Append new row to table body
|
|
|
79 |
$(this).closest('table').find('tbody').append(giftRow);
|
|
|
80 |
initMultiselect(giftRow.find('select[name="productCategory"]'), 'Categories');
|
|
|
81 |
initMultiselect(giftRow.find('.partnerInfo'), 'Partner');
|
|
|
82 |
});
|
|
|
83 |
|
|
|
84 |
// Remove gift row
|
|
|
85 |
$(document).on('click', '.remove-gift', function () {
|
|
|
86 |
$(this).closest('tr').remove();
|
|
|
87 |
});
|
|
|
88 |
|
|
|
89 |
// Handle gift thumbnail uploads
|
|
|
90 |
$(document).on('input', '.gift-thumbnail-file', function () {
|
|
|
91 |
const file = this.files[0];
|
|
|
92 |
const $hiddenInput = $(this).siblings('.gift-thumbnail-id');
|
|
|
93 |
if (file && confirm('Confirm gift thumbnail upload?')) {
|
|
|
94 |
uploadDocument(file, function (documentId) {
|
|
|
95 |
if (documentId) {
|
|
|
96 |
$hiddenInput.val(documentId);
|
|
|
97 |
} else {
|
|
|
98 |
alert('Thumbnail upload failed. Please try again.');
|
|
|
99 |
$(this).val('');
|
|
|
100 |
}
|
|
|
101 |
});
|
|
|
102 |
} else {
|
|
|
103 |
$(this).val('');
|
|
|
104 |
}
|
|
|
105 |
});
|
|
|
106 |
// Submit offer handler
|
|
|
107 |
$(document).on('click', '.submit-offer', function () {
|
|
|
108 |
const form = $('#offerForm');
|
|
|
109 |
// console.log("this is the form data" + form);
|
|
|
110 |
const requiredFields = form.find('[required]');
|
|
|
111 |
const offerImageIds = $('[name="offerImageIds[]"]').map((i, el) => el.value).get();
|
|
|
112 |
if (offerImageIds.some(id => !id)) {
|
|
|
113 |
alert('Please complete all image uploads.');
|
|
|
114 |
return;
|
|
|
115 |
}
|
|
|
116 |
if (!validateRequiredFields(requiredFields)) {
|
|
|
117 |
window.alert('Please fill all required fields');
|
|
|
118 |
return;
|
|
|
119 |
}
|
|
|
120 |
|
|
|
121 |
const formData = {
|
|
|
122 |
name: form.find('[name="name"]').val(),
|
|
|
123 |
description: form.find('[name="description"]').val(),
|
|
|
124 |
offerType: "Scratch Card",
|
|
|
125 |
startDate: form.find('[name="start_date"]').val(),
|
|
|
126 |
endDate: form.find('[name="end_date"]').val(),
|
|
|
127 |
termsCondition: form.find('[name="termsCondition"]').val(),
|
|
|
128 |
userLimit: form.find('[name="userLimit"]').val(),
|
|
|
129 |
scratchValidity: form.find('[name="scratchValidity"]').val(),
|
|
|
130 |
productCategory: form.find('[name="productCategory"]').val().toString(),
|
|
|
131 |
paymentMethod: form.find('[name="paymentMethod"]').val().toString(),
|
|
|
132 |
offerImage: form.find('[name="offerImageIds[]"]').map(function () {
|
|
|
133 |
return $(this).val();
|
|
|
134 |
}).get().join(','),
|
|
|
135 |
active: form.find('[name="isActive"]').is(':checked'),
|
|
|
136 |
classification: form.find(".classification").val().toString(),
|
|
|
137 |
gifts: []
|
|
|
138 |
};
|
|
|
139 |
$('#offerModal').on('show.bs.modal', function () {
|
|
|
140 |
// Reset form inputs
|
|
|
141 |
$('#offerForm')[0].reset();
|
|
|
142 |
|
|
|
143 |
// Remove all dynamically added gift rows except the first
|
|
|
144 |
$('.gift-row:not(:first)').remove();
|
|
|
145 |
|
|
|
146 |
// Clear the first gift row's inputs
|
|
|
147 |
$('.gift-row:first').find('input, select, textarea').val('');
|
|
|
148 |
|
|
|
149 |
// Clear offer images container
|
|
|
150 |
$('.offer-images-container').html(`
|
|
|
151 |
<div class="offer-image-entry">
|
|
|
152 |
<input type="file" class="form-control offer-image-file" accept="image/*" required>
|
|
|
153 |
<input type="hidden" class="offer-image-id" name="offerImageIds[]">
|
|
|
154 |
</div>
|
|
|
155 |
`);
|
|
|
156 |
|
|
|
157 |
// Reinitialize multiselects
|
|
|
158 |
initMultiselect('select[name="productCategory"]', 'Categories');
|
|
|
159 |
initMultiselect('select[name="partnerInfo"]', 'Partner');
|
|
|
160 |
initMultiselect('select[name="paymentMethod"]', 'Payment method');
|
|
|
161 |
|
|
|
162 |
// Reset any file inputs in remaining gift rows
|
|
|
163 |
$('.gift-thumbnail-file, .fofo-store-file').val('');
|
|
|
164 |
$('.gift-thumbnail-id, .fofo-store-id').val('');
|
|
|
165 |
});
|
|
|
166 |
|
|
|
167 |
$('.dynamic-table tr.gift-row').each(function () {
|
|
|
168 |
initMultiselect($(this).find('.product-category'), 'Categories');
|
|
|
169 |
const row = $(this);
|
|
|
170 |
console.log("Product categofy {}", row.find('.product-category').val());
|
|
|
171 |
formData.gifts.push({
|
|
|
172 |
id: row.find('[name="gifts[].id"]').val() || null,
|
|
|
173 |
name: row.find('.gift-name').val(),
|
|
|
174 |
minCartValue: row.find('.gift-min-cart').val(),
|
|
|
175 |
maxCartValue: row.find('.gift-max-cart').val(),
|
|
|
176 |
maxRedemptions: row.find('.gift-redemptions').val(),
|
|
|
177 |
thumbnailUrl: row.find('.gift-thumbnail-id').val(),
|
|
|
178 |
productCategory: row.find('.gift-product-category').val() ? row.find('.gift-product-category').val().toString() : "",
|
|
|
179 |
fofoStore: row.find('.fofo-store-id').val() + row.find('.partnerInfo').val(),
|
|
|
180 |
partnerInfo: row.find('.partnerInfo').val(),
|
|
|
181 |
isDefault: row.find('.default-gift-radio').is(':checked')
|
|
|
182 |
|
|
|
183 |
});
|
|
|
184 |
});
|
|
|
185 |
|
|
|
186 |
// Debug: Check collected data
|
|
|
187 |
console.log("Submitting gift data:", formData.gifts);
|
|
|
188 |
|
|
|
189 |
doAjaxRequestWithJsonHandler(
|
|
|
190 |
`${context}/store/offer/createoffer`,
|
|
|
191 |
"POST",
|
|
|
192 |
JSON.stringify(formData),
|
|
|
193 |
function (response) {
|
|
|
194 |
if (response) {
|
|
|
195 |
$('#offerModal').modal('hide');
|
|
|
196 |
$('body').removeClass('modal-open');
|
|
|
197 |
$('.modal-backdrop').remove();
|
|
|
198 |
refreshOfferTable();
|
|
|
199 |
alert('Offer created successfully!');
|
|
|
200 |
} else {
|
|
|
201 |
alert("Cannot create the offer, please Try Again");
|
|
|
202 |
}
|
|
|
203 |
}
|
|
|
204 |
);
|
|
|
205 |
});
|
|
|
206 |
// Edit Form handler
|
|
|
207 |
$(document).on('click', '.edit-offer', function () {
|
|
|
208 |
const id = $(this).val();
|
|
|
209 |
doGetAjaxRequestHandler(`${context}/store/offer/editOffer/${id}`, function (response) {
|
|
|
210 |
$('#edit-modal-content').html(response);
|
|
|
211 |
$('#editOfferModal').modal('show');
|
|
|
212 |
});
|
|
|
213 |
});
|
|
|
214 |
|
|
|
215 |
// Delete offer handler
|
|
|
216 |
$(document).on('click', '.delete-offer', function () {
|
|
|
217 |
const id = $(this).val();
|
|
|
218 |
console.log("this is the id" + id);
|
|
|
219 |
if (confirm('Are you sure you want to delete this offer?')) {
|
|
|
220 |
doDeleteAjaxRequestHandler(
|
|
|
221 |
`${context}/store/offer/deleteOffer/${id}`,
|
|
|
222 |
function (res) {
|
|
|
223 |
if (res) {
|
|
|
224 |
alert('Offer deleted successfully!');
|
|
|
225 |
refreshOfferTable();
|
|
|
226 |
} else {
|
|
|
227 |
alert('Can Not Delete ongoing Offer!');
|
|
|
228 |
}
|
|
|
229 |
});
|
|
|
230 |
}
|
|
|
231 |
});
|
|
|
232 |
// Delete gift handler
|
|
|
233 |
$(document).on('click', '.delete-gift', function () {
|
|
|
234 |
const id = $(this).val();
|
|
|
235 |
console.log("this is the id" + id);
|
|
|
236 |
if (confirm('Are you sure you want to delete this gift?')) {
|
|
|
237 |
doDeleteAjaxRequestHandler(
|
|
|
238 |
`${context}/store/gift/deleteGift/${id}`,
|
|
|
239 |
function () {
|
|
|
240 |
refreshOfferTable();
|
|
|
241 |
$('#giftModal').modal('hide');
|
|
|
242 |
$('body').removeClass('modal-open');
|
|
|
243 |
$('.modal-backdrop').remove();
|
|
|
244 |
alert('Gift deleted successfully!');
|
|
|
245 |
|
|
|
246 |
}
|
|
|
247 |
);
|
|
|
248 |
}
|
|
|
249 |
});
|
|
|
250 |
// Get Gift by id
|
|
|
251 |
$(document).on('click', '.get-offerby-id', function () {
|
|
|
252 |
const id = $(this).val();
|
|
|
253 |
$('#loading-spinner').show();
|
|
|
254 |
doGetAjaxRequestHandler(
|
|
|
255 |
`${context}/store/giftsByOfferId/${id}`,
|
|
|
256 |
function (response) {
|
|
|
257 |
$('#gift-content').html(response);
|
|
|
258 |
$('#giftModal').modal('show');
|
|
|
259 |
$('#loading-spinner').hide();
|
|
|
260 |
},
|
|
|
261 |
function (error) {
|
|
|
262 |
$('#loading-spinner').hide();
|
|
|
263 |
console.error('API Error:', error);
|
|
|
264 |
alert('Error loading gifts. Check the console for details.');
|
|
|
265 |
}
|
|
|
266 |
);
|
|
|
267 |
});
|
|
|
268 |
|
|
|
269 |
// Referesh Offer Table
|
|
|
270 |
function refreshOfferTable() {
|
|
|
271 |
doGetAjaxRequestHandler(`${context}/store/offer/showScratchOffers`, function (response) {
|
|
|
272 |
$('#main-content').html(response);
|
|
|
273 |
});
|
|
|
274 |
}
|
|
|
275 |
|
|
|
276 |
// Update the update button handler
|
|
|
277 |
// Fixed Update button handler
|
|
|
278 |
$(document).on('click', '.update-offer', function () {
|
|
|
279 |
const form = $('#editofferForm');
|
|
|
280 |
const offerId = $(this).data('offer-id');
|
|
|
281 |
|
|
|
282 |
// Debug: Log form existence and fields
|
|
|
283 |
console.log('Form found:', form.length);
|
|
|
284 |
console.log('Offer ID:', offerId);
|
|
|
285 |
|
|
|
286 |
const formData = {
|
|
|
287 |
id: form.find('[name="id"]').val(),
|
|
|
288 |
name: form.find('[name="name"]').val(),
|
|
|
289 |
description: form.find('[name="description"]').val(),
|
|
|
290 |
offerType: "Scratch Card",
|
|
|
291 |
startDate: form.find('[name="start_date"]').val(),
|
|
|
292 |
endDate: form.find('[name="end_date"]').val(),
|
|
|
293 |
termsCondition: form.find('[name="termsCondition"]').val(),
|
|
|
294 |
userLimit: parseInt(form.find('[name="userLimit"]').val()) || 0,
|
|
|
295 |
scratchValidity: parseInt(form.find('[name="scratchValidity"]').val()) || 0,
|
|
|
296 |
productCategory: form.find('[name="productCategory"]').val() ? form.find('[name="productCategory"]').val().join(',') : '',
|
|
|
297 |
paymentMethod: form.find('[name="paymentMethod"]').val() ? form.find('[name="paymentMethod"]').val().join(',') : '',
|
|
|
298 |
classification: form.find('[name="classification"]').val() || '',
|
|
|
299 |
gifts: []
|
|
|
300 |
};
|
|
|
301 |
|
|
|
302 |
// Debug: Log basic form data
|
|
|
303 |
console.log('Basic form data collected:', formData);
|
|
|
304 |
|
|
|
305 |
// Process gifts with better error handling
|
|
|
306 |
// Simplified approach using class selectors
|
|
|
307 |
$('#giftsContainer tbody tr.gift-row').each(function (index) {
|
|
|
308 |
const row = $(this);
|
|
|
309 |
|
|
|
310 |
// Use class-based selectors (more reliable)
|
|
|
311 |
const giftId = row.find('input[name*="gifts"][name*="id"]').val();
|
|
|
312 |
const giftName = row.find('.gift-name').val();
|
|
|
313 |
const minCartValue = row.find('.gift-min-cart').val();
|
|
|
314 |
const maxCartValue = row.find('.gift-max-cart').val();
|
|
|
315 |
const maxRedemptions = row.find('.gift-redemptions').val();
|
|
|
316 |
const thumbnailId = row.find('.gift-thumbnail-id').val();
|
|
|
317 |
|
|
|
318 |
// Handle multiselects
|
|
|
319 |
const productCategory = row.find('.gift-product-category').val() ?
|
|
|
320 |
row.find('.gift-product-category').val().join(',') : '';
|
|
|
321 |
const partnerInfo = row.find('.partnerInfo').val() ?
|
|
|
322 |
row.find('.partnerInfo').val().join(',') : '';
|
|
|
323 |
const fofoStoreHidden = row.find('.fofo-store-id').val() || '';
|
|
|
324 |
const fofoStore = fofoStoreHidden + (partnerInfo ? (fofoStoreHidden ? ',' : '') + partnerInfo : '');
|
|
|
325 |
|
|
|
326 |
console.log(`Gift ${index} data:`, {
|
|
|
327 |
id: giftId,
|
|
|
328 |
name: giftName,
|
|
|
329 |
minCartValue,
|
|
|
330 |
maxCartValue,
|
|
|
331 |
maxRedemptions,
|
|
|
332 |
productCategory,
|
|
|
333 |
fofoStore
|
|
|
334 |
});
|
|
|
335 |
|
|
|
336 |
if (!giftName || !minCartValue || !maxCartValue || !maxRedemptions) {
|
|
|
337 |
alert(`Gift ${index + 1} is missing required fields`);
|
|
|
338 |
return false;
|
|
|
339 |
}
|
|
|
340 |
|
|
|
341 |
formData.gifts.push({
|
|
|
342 |
id: giftId ? parseInt(giftId) : null,
|
|
|
343 |
name: giftName,
|
|
|
344 |
minCartValue: parseFloat(minCartValue),
|
|
|
345 |
maxCartValue: parseFloat(maxCartValue),
|
|
|
346 |
maxRedemptions: parseInt(maxRedemptions),
|
|
|
347 |
thumbnailUrl: thumbnailId,
|
|
|
348 |
productCategory: productCategory,
|
|
|
349 |
fofoStore: fofoStore,
|
|
|
350 |
partnerInfo: partnerInfo,
|
|
|
351 |
isDefault: row.find('.default-gift-radio').is(':checked')
|
|
|
352 |
});
|
|
|
353 |
});
|
|
|
354 |
|
|
|
355 |
// Validate main form data
|
|
|
356 |
if (!formData.name || !formData.startDate || !formData.endDate) {
|
|
|
357 |
alert('Please fill in all required fields');
|
|
|
358 |
return;
|
|
|
359 |
}
|
|
|
360 |
|
|
|
361 |
// Submit the form
|
|
|
362 |
doPutAjaxRequestWithJsonHandler(
|
|
|
363 |
`${context}/store/offer/updateOffer/${parseInt(offerId)}`,
|
|
|
364 |
JSON.stringify(formData),
|
|
|
365 |
function (response) {
|
|
|
366 |
console.log('Update response:', response);
|
|
|
367 |
$('#editOfferModal').modal('hide');
|
|
|
368 |
$('body').removeClass('modal-open');
|
|
|
369 |
$('.modal-backdrop').remove();
|
|
|
370 |
refreshOfferTable();
|
|
|
371 |
alert('Offer updated successfully!');
|
|
|
372 |
},
|
|
|
373 |
function (error) {
|
|
|
374 |
console.error('Update failed:', error);
|
|
|
375 |
alert('Failed to update offer. Please try again.');
|
|
|
376 |
}
|
|
|
377 |
);
|
|
|
378 |
});
|
|
|
379 |
|
|
|
380 |
// Update Offer Status
|
|
|
381 |
$(document).on('change', '.switch-small input[name="isActive"]', function (e) {
|
|
|
382 |
e.preventDefault();
|
|
|
383 |
var $checkbox = $(this);
|
|
|
384 |
var $switchContainer = $checkbox.closest('.switch-small');
|
|
|
385 |
var offerId = $switchContainer.data('offer-id');
|
|
|
386 |
var newStatus = $checkbox.is(':checked');
|
|
|
387 |
var statusText = newStatus ? 'activate' : 'deactivate';
|
|
|
388 |
if (!confirm('Are you sure you want to ' + statusText + ' this offer?')) {
|
|
|
389 |
$checkbox.prop('checked', !newStatus);
|
|
|
390 |
return;
|
|
|
391 |
}
|
|
|
392 |
var payload = {active: newStatus};
|
|
|
393 |
doPutAjaxRequestWithJsonHandler(
|
|
|
394 |
`${context}/store/offer/updateStatus/${offerId}`,
|
|
|
395 |
JSON.stringify(payload),
|
|
|
396 |
function (response) {
|
|
|
397 |
alert('Offer status updated successfully!');
|
|
|
398 |
},
|
|
|
399 |
function (xhr, status, error) {
|
|
|
400 |
alert('Error updating status: ' + error);
|
|
|
401 |
$checkbox.prop('checked', !newStatus);
|
|
|
402 |
}
|
|
|
403 |
);
|
|
|
404 |
});
|
|
|
405 |
|
|
|
406 |
// Upload fofo-store csv file
|
|
|
407 |
$(document).on('change', '.fofo-store-file', function () {
|
|
|
408 |
const file = this.files[0];
|
|
|
409 |
const row = $(this).closest('.gift-row');
|
|
|
410 |
const hiddenInput = row.find('.fofo-store-id');
|
|
|
411 |
|
|
|
412 |
if (file && file.name.endsWith('.csv')) {
|
|
|
413 |
const reader = new FileReader();
|
|
|
414 |
|
|
|
415 |
reader.onload = function (e) {
|
|
|
416 |
const text = e.target.result;
|
|
|
417 |
const lines = text.split('\n').filter(line => line.trim() !== '');
|
|
|
418 |
const fofoIds = [];
|
|
|
419 |
|
|
|
420 |
// Skip header row (assuming first line is header)
|
|
|
421 |
for (let i = 1; i < lines.length; i++) {
|
|
|
422 |
const columns = lines[i].split(',');
|
|
|
423 |
if (columns[2]) {
|
|
|
424 |
fofoIds.push(columns[2].trim());
|
|
|
425 |
}
|
|
|
426 |
}
|
|
|
427 |
hiddenInput.val(fofoIds.join(','));
|
|
|
428 |
};
|
|
|
429 |
reader.readAsText(file);
|
|
|
430 |
} else {
|
|
|
431 |
alert('Please upload a valid CSV file');
|
|
|
432 |
hiddenInput.val('');
|
|
|
433 |
}
|
|
|
434 |
});
|
|
|
435 |
|
|
|
436 |
function initMultiselect(selector, name) {
|
|
|
437 |
$(selector).multiselect('destroy');
|
|
|
438 |
$(selector).multiselect({
|
|
|
439 |
includeSelectAllOption: true,
|
|
|
440 |
maxHeight: 200,
|
|
|
441 |
enableFiltering: true,
|
|
|
442 |
nonSelectedText: 'Select ' + name,
|
|
|
443 |
nSelectedText: name + ' selected',
|
|
|
444 |
buttonWidth: '100%'
|
|
|
445 |
});
|
|
|
446 |
}
|