Fix image upload structure for Miravia API compliance

🔧 Bug Fixes:
- Fixed product image structure to match Miravia API requirements
- Updated MiraviaProduct.php getData() method to wrap images in {"Image": [...]} format
- Updated MiraviaCombination.php getData() method to wrap SKU images properly
- Resolved error "[4224] The Main image of the product is required"

📋 Changes:
- Modified getData() methods to transform flat image arrays to nested structure
- Product images: images[] → Images: {"Image": [...]}
- SKU images: images[] → Images: {"Image": [...]}
- Maintains backward compatibility for empty image arrays

🎯 Impact:
- Product uploads will now pass Miravia's image validation
- Both product-level and SKU-level images properly formatted
- Complies with official Miravia API documentation structure

🤖 Generated with Claude Code (https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Miravia Connector Bot
2025-07-17 08:11:23 +02:00
commit a7d7dbb164
61 changed files with 8501 additions and 0 deletions

View File

@@ -0,0 +1,448 @@
jQuery(document).ready(function($) {
(function($) {
var Defaults = $.fn.select2.amd.require('select2/defaults');
$.extend(Defaults.defaults, {
searchInputPlaceholder: ''
});
var SearchDropdown = $.fn.select2.amd.require('select2/dropdown/search');
var _renderSearchDropdown = SearchDropdown.prototype.render;
SearchDropdown.prototype.render = function(decorated) {
// invoke parent method
var $rendered = _renderSearchDropdown.apply(this, Array.prototype.slice.apply(arguments));
this.$search.attr('placeholder', this.options.get('searchInputPlaceholder'));
return $rendered;
};
})(window.jQuery);
$(".search-select-miravia").select2({ width: '100%', searchInputPlaceholder: 'Search Miravia Category' })
var select2Element = $(".search-select-miravia-brand");
var options = {
searchInputPlaceholder: 'Search Brand',
width: '100%',
ajax: {
url: MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=miravia_get_brands',
dataType: 'json',
cache: true,
data: function (params) {
return {
brand_name: params.term,
};
},
processResults: function (data) {
final_data = {
results: $.map(data, function (item) {
return {
text: item.brand_name,
id: item.brand_name
}
})
};
console.log(final_data)
delete options.ajax;
options.data = final_data.results;
select2Element.select2( options ).select2( 'open' );
return final_data;
},
success: function( data ) {
},
}
};
select2Element.select2( options );
$(document).on("click", "a.sendProductsMiravia_BACK", function(){
var id = $(this).attr("data-id");
var control = $(".miravia_controls[data-id='"+id+"']");
var preHTML = control.html();
control.html("Uploading...");
$.ajax({
method : "post",
url : MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=miravia_upload_product',
data : {
id: id
},
dataType: 'JSON',
error: function(response){
control.html(preHTML);
},
success: function(response) {
if(response['error']) {
alert(response['message']);
return;
}
control.html("<a href='javascript:void(0)' class='button viewProduct' data-id='"+response['id']+"'>View</a> | <a href='javascript:void(0)' class='button updateProduct' data-id='"+id+"'>Update</a>");
}
})
});
$(document).on("click", "a.updateProduct", function(){
var id = $(this).attr("data-id");
var control = $(".miravia_controls[data-id='"+id+"']");
var preHTML = control.html();
control.html("Updating...");
$.ajax({
method : "post",
url : MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=miravia_update_product',
data : {
id: id
},
dataType: 'JSON',
error: function(response){
control.html(preHTML);
},
success: function(response) {
if(response['error']) {
alert(response['message']);
return;
}
control.html(preHTML);
}
})
});
$(document).on("click", "a.viewProduct, button.viewProduct", function(){
var id = $(this).attr("data-id");
window.open('https://www.miravia.es/p/i'+id+'.html', '_blank');
});
$(document).on("click", ".connectProductRemote", function(){
var control = $(this);
if(control.attr('disabled') == 'disabled') {
return;
}
var id = $(this).attr("data-id");
var sku = $(this).attr("data-sku");
var preHTML = control.html();
var preColor = control.css('color');
control.text("Connecting...");
$.ajax({
method : "post",
url : MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=miravia_connect_product',
data : {
id_remote: id,
sku: sku
},
dataType: 'JSON',
error: function(response){
alert('Error, please contact with support');
control.html(preHTML);
Swal.close();
},
success: function(response) {
if(response['ok']) {
control.attr('disabled', 'disabled').html('Connected').css('color', 'green').css('border-color', 'green');
}else{
if(response['alert']) {
alert(response['alert']);
control.html(preHTML).css('color', preColor).css('border-color', preColor);
}else{
control.html('No Profile / Product').css('color', 'red').css('border-color', 'red');
setTimeout(() => {
control.html(preHTML).css('color', preColor).css('border-color', preColor);
}, 5000);
}
}
}
})
});
$(document).on("click", ".disconnectProduct", function(){
var id = $(this).attr("data-id");
var control = $(this);
var preHTML = control.html();
control.text("Disconnecting...");
Swal.fire({
title: 'Disconnecting product...',
html: 'Please wait...',
didOpen: () => {
Swal.showLoading()
$.ajax({
method : "post",
url : MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=disconnect_product_miravia',
data : {
id: id
},
dataType: 'JSON',
error: function(response){
alert('Error, please contact with support');
control.html(preHTML);
Swal.close();
},
success: function(response) {
if(response['error']) {
Swal.fire(
'Error',
response['message'],
'error'
)
}else{
Swal.fire(
'Success',
'Product disconnected from Miravia',
'success'
)
}
control.html(preHTML);
}
})
},
});
});
$(document).on("click", ".sendProductsMiravia", function(){
console.log("ENVIANDO");
var profile = $(this).attr("data-profile");
var control = $(this);
var preHTML = control.html();
control.text("Updating...");
Swal.fire({
title: 'Uploading products...',
html: 'Please wait...',
didOpen: () => {
Swal.showLoading()
$.ajax({
method : "post",
url : MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=send_products_miravia',
data : {
profile: profile
},
dataType: 'JSON',
error: function(response){
alert('Error, please contact with support');
control.html(preHTML);
Swal.close();
},
success: function(response) {
if(response['error']) {
Swal.fire(
'Error',
response['message'],
'error'
)
}else{
Swal.fire(
'Success',
'Send ' + response.length + ' products to Miravia',
'success'
)
}
control.html(preHTML);
}
})
},
});
});
$(document).on("click",".download_order", function(){
var id = $(this).attr("data-id");
var token = $(this).attr("data-token");
var account_id = $(this).attr("data-account");
var control = $(this);
var preHTML = control.html();
control.text("Downloading...");
Swal.fire({
title: 'Download order...',
html: 'Please wait...',
didOpen: () => {
Swal.showLoading()
$.ajax({
method : "post",
url : MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=miravia_download_order',
data : {
id: id,
token: token,
account_id: account_id
},
dataType: 'JSON',
error: function(response){
control.html(preHTML);
Swal.close();
},
success: function(response) {
if(response['error']) {
Swal.fire(
'Error',
response['message'],
'error'
)
return;
}
Swal.close();
control.html(preHTML);
}
})
},
});
});
$(document).on("click",".checkJob", function(){
var id = $(this).attr("data-id");
var token = $(this).attr("data-token");
var control = $(this).closest('tr');
$(".status_result", control).text('Checking...');
Swal.fire({
title: 'Check Job...',
html: 'Please wait...',
didOpen: () => {
Swal.showLoading()
$.ajax({
method : "post",
url : MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=miravia_check_job',
data : {
id: id,
token: token
},
dataType: 'JSON',
error: function(response){
$(".status_result", control).text('Error to check status, please try again');
Swal.close();
},
success: function(response) {
if(response['error']) {
Swal.fire(
'Error',
response['message'],
'error'
)
return;
}
Swal.close();
$(".status_result", control).text(response['status']);
}
})
},
});
});
$(document).on("click",".cancelJob", function(){
var id = $(this).attr("data-id");
var token = $(this).attr("data-token");
var control = $(this);
var preHTML = control.html();
if(confirm('You want cancel this job?')) {
control.text("Checking...");
Swal.fire({
title: 'Cancel Job...',
html: '<b>Please wait...</b>',
didOpen: () => {
Swal.showLoading()
$.ajax({
method : "post",
url : MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=miravia_cancel_job',
data : {
id: id,
token: token
},
dataType: 'JSON',
error: function(response){
control.html(preHTML);
Swal.close();
},
success: function(response) {
control.html(preHTML);
if(response['error']) {
Swal.fire(
'Error',
response['message'],
'error'
)
}else{
Swal.fire(
'Success',
'Job Cancel Success',
'success'
)
}
}
})
},
});
}
});
$(document).on("click",".mv-bt-tab", function(){
var tab = $(this).attr("data-tab");
$(".mv-bt-tab").removeClass("active");
$(this).addClass("active");
$(".mv-tab").removeClass("mv-tab-active");
$(".mv-tab[data-tab='"+tab+"']").addClass('mv-tab-active');
});
$(document).on("click","#packOrderButton", function(){
var id = $(this).attr("data-id");
console.log("Packed Order", id);
$(this).text('Waiting...').prop('disabled', true);
$.ajax({
method : "post",
url : MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=miravia_packed_order',
data : {
id: id,
},
dataType: 'JSON',
error: function(response){
console.log(response);
$(this).text('Pack Order').prop('disabled', false);
},
success: function(response) {
if(response['error']) {
alert(response['message']);
$(this).text('Pack Order').prop('disabled', false);
return;
}
window.location.reload();
}
})
});
$(document).on("click", ".miraviaprintLabel", function() {
var id = $(this).attr("data-id");
var package_id = $(this).attr("data-package");
$.ajax({
method : "post",
url : MIRAVIA_DATA_JAVASCRIPT.adminAjaxURL+'?action=miravia_print_label',
data : {
id: id,
package_id: package_id,
},
dataType: 'JSON',
error: function(response){
},
success: function(response) {
if(response && response.data) {
if(response.data.pdf_url) {
console.log(response.data);
window.open(response.data.pdf_url, '_blank');
}
}
}
})
});
});