client side bug fixed
This commit is contained in:
parent
2aa572ad1f
commit
d3f55c830f
@ -2668,239 +2668,81 @@ const CompanyProfile = () => {
|
|||||||
return profiles[deletingRow];
|
return profiles[deletingRow];
|
||||||
}, [deletingRow, profiles]);
|
}, [deletingRow, profiles]);
|
||||||
|
|
||||||
// Enhanced Import Function with Validation
|
|
||||||
const handleImport = async () => {
|
const handleImport = async () => {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
const errorMsg = "Please select a CSV file to import.";
|
const msg = "Please select a CSV file to import.";
|
||||||
setImportError(errorMsg);
|
setImportError(msg);
|
||||||
setToastData({
|
setToastData({ message: msg, type: "error" });
|
||||||
message: errorMsg,
|
return;
|
||||||
type: "error",
|
|
||||||
});
|
|
||||||
throw new Error(errorMsg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
setImportLoading(true);
|
setImportLoading(true);
|
||||||
setImportError("");
|
setImportError("");
|
||||||
|
|
||||||
// Re-validate file before upload
|
try {
|
||||||
await validateFile(file);
|
await validateFile(file);
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
|
|
||||||
console.log('FormData entries before upload:');
|
const response = await uploadCompanyProfileCSV(formData);
|
||||||
for (let pair of formData.entries()) {
|
|
||||||
console.log(pair[0] + ': ', pair[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let response;
|
const { status, message, errors } = response || {};
|
||||||
let successMessage = "Company profiles imported successfully!";
|
|
||||||
|
|
||||||
try {
|
// Convert backend error object → readable string
|
||||||
console.log('Attempting first upload...');
|
const formattedErrors = errors
|
||||||
response = await uploadCompanyProfileCSV(formData);
|
?.map((e) => `Row ${e.row}: ${e.error}`)
|
||||||
successMessage = response.message || successMessage;
|
.join(", ");
|
||||||
} catch (firstError) {
|
|
||||||
console.log('First upload attempt failed, trying alternative:', firstError);
|
|
||||||
try {
|
|
||||||
console.log('Attempting alternative upload...');
|
|
||||||
response = await uploadCompanyProfileCSVAlternative(formData);
|
|
||||||
successMessage = response.message || successMessage;
|
|
||||||
} catch (secondError) {
|
|
||||||
console.log('Alternative upload also failed:', secondError);
|
|
||||||
|
|
||||||
let detailedErrorMessage = "Upload failed. Please try again.";
|
// FAILED
|
||||||
let validationErrorCount = 1; // Default count
|
if (status === false) {
|
||||||
|
const finalError =
|
||||||
|
formattedErrors || message || "Upload failed due to server error.";
|
||||||
|
|
||||||
// Extract validation error count from response if available
|
setImportError(finalError);
|
||||||
if (secondError.response?.data) {
|
|
||||||
const responseData = secondError.response.data;
|
|
||||||
|
|
||||||
// Try to extract validation error count from different response structures
|
|
||||||
if (responseData.validation_errors) {
|
|
||||||
validationErrorCount = responseData.validation_errors.length || 1;
|
|
||||||
} else if (responseData.errors) {
|
|
||||||
validationErrorCount = responseData.errors.length || 1;
|
|
||||||
} else if (responseData.details && Array.isArray(responseData.details)) {
|
|
||||||
validationErrorCount = responseData.details.length || 1;
|
|
||||||
} else if (typeof responseData === 'string') {
|
|
||||||
// Try to extract count from error message
|
|
||||||
const countMatch = responseData.match(/(\d+)\s*validation errors?/i);
|
|
||||||
if (countMatch) {
|
|
||||||
validationErrorCount = parseInt(countMatch[1]) || 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (secondError.response?.data?.message) {
|
|
||||||
detailedErrorMessage = secondError.response.data.message;
|
|
||||||
} else if (secondError.message) {
|
|
||||||
if (secondError.message.includes("Request failed with status code")) {
|
|
||||||
if (secondError.response?.data) {
|
|
||||||
const responseData = secondError.response.data;
|
|
||||||
if (typeof responseData === 'string' && responseData.includes("Duplicate Establishment IDs")) {
|
|
||||||
detailedErrorMessage = responseData;
|
|
||||||
} else if (responseData.error) {
|
|
||||||
detailedErrorMessage = responseData.error;
|
|
||||||
} else if (responseData.details) {
|
|
||||||
detailedErrorMessage = responseData.details;
|
|
||||||
} else {
|
|
||||||
detailedErrorMessage = "Data already exists in the system. Please remove or update the duplicate entries and try again.";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
detailedErrorMessage = "Server error occurred during upload. Please try again.";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
detailedErrorMessage = secondError.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enhanced validation error detection with dynamic count
|
|
||||||
if (detailedErrorMessage.includes("No file uploaded") ||
|
|
||||||
detailedErrorMessage.includes("No file found")) {
|
|
||||||
detailedErrorMessage = "Please select a valid CSV file to upload.";
|
|
||||||
} else if (detailedErrorMessage.includes("token") ||
|
|
||||||
detailedErrorMessage.includes("auth") ||
|
|
||||||
detailedErrorMessage.includes("Authentication")) {
|
|
||||||
detailedErrorMessage = "Authentication failed. Please check your login credentials.";
|
|
||||||
} else if (detailedErrorMessage.includes("400") ||
|
|
||||||
detailedErrorMessage.includes("Bad Request")) {
|
|
||||||
detailedErrorMessage = "Invalid file format or missing required data. Please check your CSV file.";
|
|
||||||
} else if (detailedErrorMessage.includes("Duplicate Establishment IDs") ||
|
|
||||||
detailedErrorMessage.includes("duplicate") ||
|
|
||||||
detailedErrorMessage.includes("already exist")) {
|
|
||||||
detailedErrorMessage = "Duplicate Establishment IDs found (in file or already exist in system). Resolve and re-upload.";
|
|
||||||
} else if (detailedErrorMessage.includes("validation error") ||
|
|
||||||
detailedErrorMessage.includes("validation errors") ||
|
|
||||||
detailedErrorMessage.includes("No establishments imported") ||
|
|
||||||
detailedErrorMessage.includes("HS Codes do not exist") ||
|
|
||||||
detailedErrorMessage.includes("HS Code")) {
|
|
||||||
// Format validation error with dynamic count and HS code message
|
|
||||||
detailedErrorMessage = `Import failed. ${validationErrorCount} HS Codes in your file do not exist in the Product Master. Please use the correct HS Code and try again.`;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(detailedErrorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the response indicates validation errors
|
|
||||||
if (response && (response.message?.includes("validation error") ||
|
|
||||||
response.message?.includes("validation errors") ||
|
|
||||||
response.message?.includes("No establishments imported") ||
|
|
||||||
response.message?.includes("HS Codes do not exist") ||
|
|
||||||
response.message?.includes("HS Code"))) {
|
|
||||||
|
|
||||||
let validationErrorCount = 1;
|
|
||||||
// Extract count from response if available
|
|
||||||
if (response.validation_errors) {
|
|
||||||
validationErrorCount = response.validation_errors.length || 1;
|
|
||||||
} else if (response.errors) {
|
|
||||||
validationErrorCount = response.errors.length || 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const validationErrorMessage = `Import failed. ${validationErrorCount} HS Codes in your file do not exist in the Product Master. Please use the correct HS Code and try again.`;
|
|
||||||
|
|
||||||
// Show validation error in red
|
|
||||||
setImportError(validationErrorMessage);
|
|
||||||
setToastData({
|
setToastData({
|
||||||
message: validationErrorMessage,
|
message: finalError,
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
throw new Error(validationErrorMessage);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show success message
|
// SUCCESS
|
||||||
setToastData({
|
setToastData({
|
||||||
message: successMessage,
|
message: message || "File uploaded successfully!",
|
||||||
type: "success",
|
type: "success",
|
||||||
});
|
});
|
||||||
|
|
||||||
closeImportModal();
|
// window.location.reload();
|
||||||
setImportLoading(true); // Show loader while refreshing data
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Refresh the data
|
|
||||||
const res = await fetchEstablishments();
|
|
||||||
const payload = res?.data ?? res;
|
|
||||||
const records = Array.isArray(payload?.data)
|
|
||||||
? payload.data
|
|
||||||
: Array.isArray(payload)
|
|
||||||
? payload
|
|
||||||
: [];
|
|
||||||
|
|
||||||
setProfiles(records.map(mapApiEstablishmentToProfile));
|
|
||||||
setTotalItems(records.length);
|
|
||||||
|
|
||||||
// Refresh the page immediately
|
|
||||||
window.location.reload();
|
|
||||||
} catch (refreshErr) {
|
|
||||||
console.log("Error refreshing data:", refreshErr);
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error importing CSV:", error);
|
console.error("Upload error:", error);
|
||||||
|
|
||||||
let errorMessage = error.message || "Upload failed. Please try again.";
|
const backend = error?.response?.data;
|
||||||
|
|
||||||
if (errorMessage.includes("Request failed with status code")) {
|
const formattedErrors = backend?.errors
|
||||||
const parts = errorMessage.split("Request failed with status code");
|
?.map((e) => `Row ${e.row}: ${e.error}`)
|
||||||
if (parts.length > 1) {
|
.join(", ");
|
||||||
const actualError = parts[1].replace(/^\d+\s*/, '').trim();
|
|
||||||
if (actualError && actualError.length > 0) {
|
|
||||||
errorMessage = actualError;
|
|
||||||
} else {
|
|
||||||
errorMessage = "Server error occurred. Please try again.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enhanced error message handling for validation errors with dynamic count
|
const errorMessage =
|
||||||
if (errorMessage.includes("expired") || errorMessage.includes("Authentication")) {
|
formattedErrors ||
|
||||||
errorMessage = "Authentication failed. Please check your login credentials.";
|
backend?.message ||
|
||||||
}
|
backend?.error ||
|
||||||
|
error?.message ||
|
||||||
if (errorMessage.includes("Duplicate Establishment IDs") ||
|
"Upload failed. Please try again.";
|
||||||
errorMessage.includes("duplicate") ||
|
|
||||||
errorMessage.includes("already exist")) {
|
|
||||||
errorMessage = "Duplicate Establishment IDs found (in file or already exist in system). Resolve and re-upload.";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorMessage.includes("validation error") ||
|
|
||||||
errorMessage.includes("validation errors") ||
|
|
||||||
errorMessage.includes("No establishments imported") ||
|
|
||||||
errorMessage.includes("HS Codes do not exist") ||
|
|
||||||
errorMessage.includes("HS Code")) {
|
|
||||||
|
|
||||||
let validationErrorCount = 1;
|
|
||||||
// Try to extract count from existing error message
|
|
||||||
const countMatch = errorMessage.match(/(\d+)\s*validation errors?/i);
|
|
||||||
if (countMatch) {
|
|
||||||
validationErrorCount = parseInt(countMatch[1]) || 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
errorMessage = `Import failed. ${validationErrorCount} HS Code${validationErrorCount > 1 ? "s" : ""} in your file ${validationErrorCount > 1 ? "do" : "does"} not exist in the Product Master. Please use the correct HS Code${validationErrorCount > 1 ? "s" : ""} and try again.`;
|
|
||||||
}
|
|
||||||
|
|
||||||
setImportError(errorMessage);
|
setImportError(errorMessage);
|
||||||
|
|
||||||
setToastData({
|
setToastData({
|
||||||
message: errorMessage,
|
message: errorMessage,
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
|
|
||||||
throw error;
|
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
setImportLoading(false);
|
setImportLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white w-full rounded-lg shadow-sm ring-1 ring-[#E5E7EB]">
|
<div className="bg-white w-full rounded-lg shadow-sm ring-1 ring-[#E5E7EB]">
|
||||||
{toast && (
|
{toast && (
|
||||||
|
|||||||
@ -1367,10 +1367,16 @@ const IsicHsCodes = () => {
|
|||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
inputMode="numeric"
|
||||||
|
pattern="[0-9]*"
|
||||||
value={form.code}
|
value={form.code}
|
||||||
onChange={handleFormChange("code")}
|
onChange={(e) => {
|
||||||
|
// Only allow numbers
|
||||||
|
const value = e.target.value.replace(/\D/g, '');
|
||||||
|
handleFormChange("code")({ target: { value } });
|
||||||
|
}}
|
||||||
disabled={modalMode === "view"}
|
disabled={modalMode === "view"}
|
||||||
className="w-full px-3 py-2 text-sm border border-[#CBA344] rounded-md focus:outline-none focus:ring-1 focus:ring-[#92722A] focus:border-[#92722A]"
|
className="w-full px-3 py-2 text-sm border border-[#CBA344] rounded-md focus:outline-none focus:ring-1 focus:ring-[#92722A] focus:border-[#92722A] [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
||||||
placeholder="Enter HS Code"
|
placeholder="Enter HS Code"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user