[FIX] website_sale_aplicoop: align pricing and drafts

This commit is contained in:
snt 2026-02-27 19:39:25 +01:00
parent aef57a3de4
commit a9c1f1f609
4 changed files with 258 additions and 533 deletions

View file

@ -1313,6 +1313,7 @@
var orderData = {
order_id: this.orderId,
items: items,
merge_action: "replace",
};
var xhr = new XMLHttpRequest();
@ -1332,9 +1333,6 @@
data.sale_order_id +
")";
self._showNotification("✓ " + successMsg, "success", 5000);
} else if (data.existing_draft) {
// A draft already exists - show modal with merge/replace options
self._showDraftConflictModal(data);
} else {
self._showNotification(
"Error: " + (data.error || labels.error_unknown || "Unknown error"),
@ -1536,9 +1534,6 @@
labels.draft_saved ||
"Order saved as draft successfully";
self._showNotification("\u2713 " + successMsg, "success", 5000);
} else if (data.existing_draft) {
// A draft already exists - show modal with merge/replace options
self._showDraftConflictModal(data);
} else {
self._showNotification(
"Error: " + (data.error || labels.error_unknown || "Unknown error"),
@ -1576,306 +1571,6 @@
xhr.send(JSON.stringify(orderData));
},
_showDraftConflictModal: function (data) {
/**
* Show modal with merge/replace options for existing draft.
* Uses labels from window.groupOrderShop.labels or falls back to defaults.
*/
var self = this;
// Get labels - they should already be loaded by page init
var labels =
window.groupOrderShop && window.groupOrderShop.labels
? window.groupOrderShop.labels
: self._getDefaultLabels();
console.log(
"[_showDraftConflictModal] Using labels:",
Object.keys(labels).length,
"keys available"
);
var existing_items = data.existing_items || [];
var current_items = data.current_items || [];
var existing_draft_id = data.existing_draft_id;
// Create modal HTML with inline styles (no Bootstrap needed)
var modalHTML = `
<div id="draftConflictModal" style="
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
">
<div style="
background: white;
border-radius: 8px;
max-width: 500px;
width: 90%;
max-height: 90vh;
overflow-y: auto;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
">
<!-- Header -->
<div style="
padding: 20px;
border-bottom: 1px solid #ddd;
display: flex;
justify-content: space-between;
align-items: center;
">
<h5 style="margin: 0; font-size: 1.25rem;">${
labels.draft_already_exists || "Draft Already Exists"
}</h5>
<button class="draft-modal-close" style="
background: none;
border: none;
font-size: 24px;
cursor: pointer;
color: #666;
">×</button>
</div>
<!-- Body -->
<div style="padding: 20px;">
<p><strong>${
labels.draft_exists_message || "A draft already exists"
}</strong></p>
<p style="margin-top: 15px;">${
labels.draft_two_options || "You have two options:"
}</p>
<!-- Option 1 -->
<div style="
border: 1px solid #ddd;
border-radius: 4px;
margin-bottom: 15px;
overflow: hidden;
">
<div style="
background: #17a2b8;
color: white;
padding: 10px 15px;
font-weight: bold;
">
<i class="fa fa-code-fork"></i> ${
labels.draft_option1_title || "Option 1"
}
</div>
<div style="padding: 15px;">
<p>${labels.draft_option1_desc || "Merge with existing"}</p>
<ul style="margin: 10px 0; padding-left: 20px; font-size: 0.9rem;">
<li>${existing_items.length} ${
labels.draft_items_count || "items"
} - ${labels.draft_existing_items || "Existing"}</li>
<li>${current_items.length} ${
labels.draft_items_count || "items"
} - ${labels.draft_current_items || "Current"}</li>
</ul>
<p style="color: #666; font-size: 0.85rem; margin: 10px 0 0 0;">
${labels.draft_merge_note || "Products will be merged"}
</p>
</div>
</div>
<!-- Option 2 -->
<div style="
border: 1px solid #ddd;
border-radius: 4px;
overflow: hidden;
">
<div style="
background: #ffc107;
color: black;
padding: 10px 15px;
font-weight: bold;
">
<i class="fa fa-refresh"></i> ${
labels.draft_option2_title || "Option 2"
}
</div>
<div style="padding: 15px;">
<p>${labels.draft_option2_desc || "Replace with current"}</p>
<p style="color: #666; font-size: 0.85rem; margin: 0;">
<i class="fa fa-exclamation-triangle"></i> ${
labels.draft_replace_warning ||
"Old draft will be deleted"
}
</p>
</div>
</div>
</div>
<!-- Footer -->
<div style="
padding: 15px 20px;
border-top: 1px solid #ddd;
display: flex;
gap: 10px;
justify-content: flex-end;
">
<button class="draft-modal-close" style="
padding: 8px 16px;
background: #6c757d;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
">${labels.cancel || "Cancel"}</button>
<button id="mergeBtn" data-existing-id="${existing_draft_id}" style="
padding: 8px 16px;
background: #17a2b8;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
">
<i class="fa fa-code-fork"></i> ${labels.draft_merge_btn || "Merge"}
</button>
<button id="replaceBtn" data-existing-id="${existing_draft_id}" style="
padding: 8px 16px;
background: #ffc107;
color: black;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
">
<i class="fa fa-refresh"></i> ${
labels.draft_replace_btn || "Replace"
}
</button>
</div>
</div>
</div>
`;
// Remove existing modal if any
var existingModal = document.getElementById("draftConflictModal");
if (existingModal) {
existingModal.remove();
}
// Add modal to body
document.body.insertAdjacentHTML("beforeend", modalHTML);
var modalElement = document.getElementById("draftConflictModal");
// Handle close buttons
document.querySelectorAll(".draft-modal-close").forEach(function (btn) {
btn.addEventListener("click", function () {
modalElement.remove();
});
});
// Handle merge button
document.getElementById("mergeBtn").addEventListener("click", function () {
var existingId = this.getAttribute("data-existing-id");
modalElement.remove();
self._executeSaveDraftWithAction("merge", existingId);
});
// Handle replace button
document.getElementById("replaceBtn").addEventListener("click", function () {
var existingId = this.getAttribute("data-existing-id");
modalElement.remove();
self._executeSaveDraftWithAction("replace", existingId);
});
// Close modal when clicking outside
modalElement.addEventListener("click", function (e) {
if (e.target === modalElement) {
modalElement.remove();
}
});
},
_executeSaveDraftWithAction: function (action, existingDraftId) {
/**
* Execute save draft with merge or replace action.
*/
var self = this;
var items = [];
Object.keys(this.cart).forEach(function (productId) {
var item = self.cart[productId];
items.push({
product_id: productId,
product_name: item.name,
quantity: item.qty,
product_price: item.price,
});
});
var orderData = {
order_id: this.orderId,
items: items,
merge_action: action,
existing_draft_id: existingDraftId,
};
var xhr = new XMLHttpRequest();
xhr.open("POST", "/eskaera/save-order", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = function () {
if (xhr.status === 200) {
try {
var data = JSON.parse(xhr.responseText);
console.log("Response:", data);
if (data.success) {
// Use server-provided labels instead of hardcoding
var labels = self._getLabels();
// Use the translated messages from server
var msg = data.merged
? "✓ " +
(labels.draft_merged_success || "Draft merged successfully")
: "✓ " +
(labels.draft_replaced_success || "Draft replaced successfully");
self._showNotification(msg, "success", 5000);
} else {
var labels = self._getLabels();
self._showNotification(
"Error: " + (data.error || labels.error_unknown || "Unknown error"),
"danger"
);
}
} catch (e) {
console.error("Error parsing response:", e);
self._showNotification("Error processing response", "danger");
}
} else {
try {
var errorData = JSON.parse(xhr.responseText);
self._showNotification(
"Error " + xhr.status + ": " + (errorData.error || "Request error"),
"danger"
);
} catch (e) {
self._showNotification(
"Error saving order (HTTP " + xhr.status + ")",
"danger"
);
}
}
};
xhr.onerror = function () {
self._showNotification("Connection error", "danger");
};
xhr.send(JSON.stringify(orderData));
},
_confirmOrder: function () {
console.log("=== _confirmOrder started ===");
console.log("orderId:", this.orderId);