mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-25 16:04:46 +00:00
Merge pull request #42026 from ljain112/fix-bank-import
fix: Multiple fixes in Bank Statement Import
This commit is contained in:
@@ -130,52 +130,66 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
show_import_status(frm) {
|
show_import_status(frm) {
|
||||||
let import_log = JSON.parse(frm.doc.statement_import_log || "[]");
|
if (frm.doc.status == "Pending") return;
|
||||||
let successful_records = import_log.filter((log) => log.success);
|
|
||||||
let failed_records = import_log.filter((log) => !log.success);
|
|
||||||
if (successful_records.length === 0) return;
|
|
||||||
|
|
||||||
let message;
|
frappe.call({
|
||||||
if (failed_records.length === 0) {
|
method: "erpnext.accounts.doctype.bank_statement_import.bank_statement_import.get_import_status",
|
||||||
let message_args = [successful_records.length];
|
args: {
|
||||||
if (frm.doc.import_type === "Insert New Records") {
|
docname: frm.doc.name,
|
||||||
message =
|
},
|
||||||
successful_records.length > 1
|
callback: function (r) {
|
||||||
? __("Successfully imported {0} records.", message_args)
|
let successful_records = cint(r.message.success);
|
||||||
: __("Successfully imported {0} record.", message_args);
|
let failed_records = cint(r.message.failed);
|
||||||
} else {
|
let total_records = cint(r.message.total_records);
|
||||||
message =
|
|
||||||
successful_records.length > 1
|
if (!total_records) {
|
||||||
? __("Successfully updated {0} records.", message_args)
|
return;
|
||||||
: __("Successfully updated {0} record.", message_args);
|
}
|
||||||
}
|
|
||||||
} else {
|
let message;
|
||||||
let message_args = [successful_records.length, import_log.length];
|
if (failed_records === 0) {
|
||||||
if (frm.doc.import_type === "Insert New Records") {
|
let message_args = [successful_records];
|
||||||
message =
|
if (frm.doc.import_type === "Insert New Records") {
|
||||||
successful_records.length > 1
|
message =
|
||||||
? __(
|
successful_records > 1
|
||||||
"Successfully imported {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
? __("Successfully imported {0} records.", message_args)
|
||||||
message_args
|
: __("Successfully imported {0} record.", message_args);
|
||||||
)
|
} else {
|
||||||
: __(
|
message =
|
||||||
"Successfully imported {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
successful_records > 1
|
||||||
message_args
|
? __("Successfully updated {0} records.", message_args)
|
||||||
);
|
: __("Successfully updated {0} record.", message_args);
|
||||||
} else {
|
}
|
||||||
message =
|
} else {
|
||||||
successful_records.length > 1
|
let message_args = [successful_records, total_records];
|
||||||
? __(
|
if (frm.doc.import_type === "Insert New Records") {
|
||||||
"Successfully updated {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
message =
|
||||||
message_args
|
successful_records > 1
|
||||||
)
|
? __(
|
||||||
: __(
|
"Successfully imported {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||||
"Successfully updated {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
message_args
|
||||||
message_args
|
)
|
||||||
);
|
: __(
|
||||||
}
|
"Successfully imported {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||||
}
|
message_args
|
||||||
frm.dashboard.set_headline(message);
|
);
|
||||||
|
} else {
|
||||||
|
message =
|
||||||
|
successful_records > 1
|
||||||
|
? __(
|
||||||
|
"Successfully updated {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||||
|
message_args
|
||||||
|
)
|
||||||
|
: __(
|
||||||
|
"Successfully updated {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||||
|
message_args
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frm.dashboard.set_headline(message);
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
show_report_error_button(frm) {
|
show_report_error_button(frm) {
|
||||||
@@ -297,7 +311,7 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
// method: 'frappe.core.doctype.data_import.data_import.get_preview_from_template',
|
// method: 'frappe.core.doctype.data_import.data_import.get_preview_from_template',
|
||||||
|
|
||||||
show_import_preview(frm, preview_data) {
|
show_import_preview(frm, preview_data) {
|
||||||
let import_log = JSON.parse(frm.doc.statement_import_log || "[]");
|
let import_log = preview_data.import_log;
|
||||||
|
|
||||||
if (frm.import_preview && frm.import_preview.doctype === frm.doc.reference_doctype) {
|
if (frm.import_preview && frm.import_preview.doctype === frm.doc.reference_doctype) {
|
||||||
frm.import_preview.preview_data = preview_data;
|
frm.import_preview.preview_data = preview_data;
|
||||||
@@ -336,6 +350,15 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
export_import_log(frm) {
|
||||||
|
open_url_post(
|
||||||
|
"/api/method/erpnext.accounts.doctype.bank_statement_import.bank_statement_import.download_import_log",
|
||||||
|
{
|
||||||
|
data_import_name: frm.doc.name,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
show_import_warnings(frm, preview_data) {
|
show_import_warnings(frm, preview_data) {
|
||||||
let columns = preview_data.columns;
|
let columns = preview_data.columns;
|
||||||
let warnings = JSON.parse(frm.doc.template_warnings || "[]");
|
let warnings = JSON.parse(frm.doc.template_warnings || "[]");
|
||||||
@@ -411,49 +434,50 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
frm.trigger("show_import_log");
|
frm.trigger("show_import_log");
|
||||||
},
|
},
|
||||||
|
|
||||||
show_import_log(frm) {
|
render_import_log(frm) {
|
||||||
let import_log = JSON.parse(frm.doc.statement_import_log || "[]");
|
frappe.call({
|
||||||
let logs = import_log;
|
method: "erpnext.accounts.doctype.bank_statement_import.bank_statement_import.get_import_logs",
|
||||||
frm.toggle_display("import_log", false);
|
args: {
|
||||||
frm.toggle_display("import_log_section", logs.length > 0);
|
docname: frm.doc.name,
|
||||||
|
},
|
||||||
|
callback: function (r) {
|
||||||
|
let logs = r.message;
|
||||||
|
|
||||||
if (logs.length === 0) {
|
if (logs.length === 0) return;
|
||||||
frm.get_field("import_log_preview").$wrapper.empty();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let rows = logs
|
frm.toggle_display("import_log_section", true);
|
||||||
.map((log) => {
|
|
||||||
let html = "";
|
let rows = logs
|
||||||
if (log.success) {
|
.map((log) => {
|
||||||
if (frm.doc.import_type === "Insert New Records") {
|
let html = "";
|
||||||
html = __("Successfully imported {0}", [
|
if (log.success) {
|
||||||
`<span class="underline">${frappe.utils.get_form_link(
|
if (frm.doc.import_type === "Insert New Records") {
|
||||||
frm.doc.reference_doctype,
|
html = __("Successfully imported {0}", [
|
||||||
log.docname,
|
`<span class="underline">${frappe.utils.get_form_link(
|
||||||
true
|
frm.doc.reference_doctype,
|
||||||
)}<span>`,
|
log.docname,
|
||||||
]);
|
true
|
||||||
} else {
|
)}<span>`,
|
||||||
html = __("Successfully updated {0}", [
|
]);
|
||||||
`<span class="underline">${frappe.utils.get_form_link(
|
} else {
|
||||||
frm.doc.reference_doctype,
|
html = __("Successfully updated {0}", [
|
||||||
log.docname,
|
`<span class="underline">${frappe.utils.get_form_link(
|
||||||
true
|
frm.doc.reference_doctype,
|
||||||
)}<span>`,
|
log.docname,
|
||||||
]);
|
true
|
||||||
}
|
)}<span>`,
|
||||||
} else {
|
]);
|
||||||
let messages = log.messages
|
}
|
||||||
.map(JSON.parse)
|
} else {
|
||||||
.map((m) => {
|
let messages = JSON.parse(log.messages || "[]")
|
||||||
let title = m.title ? `<strong>${m.title}</strong>` : "";
|
.map((m) => {
|
||||||
let message = m.message ? `<div>${m.message}</div>` : "";
|
let title = m.title ? `<strong>${m.title}</strong>` : "";
|
||||||
return title + message;
|
let message = m.message ? `<div>${m.message}</div>` : "";
|
||||||
})
|
return title + message;
|
||||||
.join("");
|
})
|
||||||
let id = frappe.dom.get_unique_id();
|
.join("");
|
||||||
html = `${messages}
|
let id = frappe.dom.get_unique_id();
|
||||||
|
html = `${messages}
|
||||||
<button class="btn btn-default btn-xs" type="button" data-toggle="collapse" data-target="#${id}" aria-expanded="false" aria-controls="${id}" style="margin-top: 15px;">
|
<button class="btn btn-default btn-xs" type="button" data-toggle="collapse" data-target="#${id}" aria-expanded="false" aria-controls="${id}" style="margin-top: 15px;">
|
||||||
${__("Show Traceback")}
|
${__("Show Traceback")}
|
||||||
</button>
|
</button>
|
||||||
@@ -462,16 +486,16 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
<pre>${log.exception}</pre>
|
<pre>${log.exception}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
let indicator_color = log.success ? "green" : "red";
|
let indicator_color = log.success ? "green" : "red";
|
||||||
let title = log.success ? __("Success") : __("Failure");
|
let title = log.success ? __("Success") : __("Failure");
|
||||||
|
|
||||||
if (frm.doc.show_failed_logs && log.success) {
|
if (frm.doc.show_failed_logs && log.success) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return `<tr>
|
return `<tr>
|
||||||
<td>${log.row_indexes.join(", ")}</td>
|
<td>${JSON.parse(log.row_indexes).join(", ")}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="indicator ${indicator_color}">${title}</div>
|
<div class="indicator ${indicator_color}">${title}</div>
|
||||||
</td>
|
</td>
|
||||||
@@ -479,16 +503,16 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
${html}
|
${html}
|
||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
})
|
})
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
if (!rows && frm.doc.show_failed_logs) {
|
if (!rows && frm.doc.show_failed_logs) {
|
||||||
rows = `<tr><td class="text-center text-muted" colspan=3>
|
rows = `<tr><td class="text-center text-muted" colspan=3>
|
||||||
${__("No failed logs")}
|
${__("No failed logs")}
|
||||||
</td></tr>`;
|
</td></tr>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
frm.get_field("import_log_preview").$wrapper.html(`
|
frm.get_field("import_log_preview").$wrapper.html(`
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
<tr class="text-muted">
|
<tr class="text-muted">
|
||||||
<th width="10%">${__("Row Number")}</th>
|
<th width="10%">${__("Row Number")}</th>
|
||||||
@@ -498,5 +522,34 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
${rows}
|
${rows}
|
||||||
</table>
|
</table>
|
||||||
`);
|
`);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
show_import_log(frm) {
|
||||||
|
frm.toggle_display("import_log_section", false);
|
||||||
|
|
||||||
|
if (frm.is_new() || frm.import_in_progress) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: "frappe.client.get_count",
|
||||||
|
args: {
|
||||||
|
doctype: "Data Import Log",
|
||||||
|
filters: {
|
||||||
|
data_import: frm.doc.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
callback: function (r) {
|
||||||
|
let count = r.message;
|
||||||
|
if (count < 5000) {
|
||||||
|
frm.trigger("render_import_log");
|
||||||
|
} else {
|
||||||
|
frm.toggle_display("import_log_section", false);
|
||||||
|
frm.add_custom_button(__("Export Import Log"), () => frm.trigger("export_import_log"));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
"bank_account",
|
"bank_account",
|
||||||
"bank",
|
"bank",
|
||||||
"column_break_4",
|
"column_break_4",
|
||||||
|
"custom_delimiters",
|
||||||
|
"delimiter_options",
|
||||||
"google_sheets_url",
|
"google_sheets_url",
|
||||||
"refresh_google_sheet",
|
"refresh_google_sheet",
|
||||||
"html_5",
|
"html_5",
|
||||||
@@ -24,7 +26,6 @@
|
|||||||
"section_import_preview",
|
"section_import_preview",
|
||||||
"import_preview",
|
"import_preview",
|
||||||
"import_log_section",
|
"import_log_section",
|
||||||
"statement_import_log",
|
|
||||||
"show_failed_logs",
|
"show_failed_logs",
|
||||||
"import_log_preview",
|
"import_log_preview",
|
||||||
"reference_doctype",
|
"reference_doctype",
|
||||||
@@ -194,15 +195,23 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "statement_import_log",
|
"default": "0",
|
||||||
"fieldtype": "Code",
|
"fieldname": "custom_delimiters",
|
||||||
"label": "Statement Import Log",
|
"fieldtype": "Check",
|
||||||
"options": "JSON"
|
"label": "Custom delimiters"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": ",;\\t|",
|
||||||
|
"depends_on": "custom_delimiters",
|
||||||
|
"description": "If your CSV uses a different delimiter, add that character here, ensuring no spaces or additional characters are included.",
|
||||||
|
"fieldname": "delimiter_options",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Delimiter options"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hide_toolbar": 1,
|
"hide_toolbar": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-03-27 13:06:38.098765",
|
"modified": "2024-06-25 17:32:07.658250",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Statement Import",
|
"name": "Bank Statement Import",
|
||||||
|
|||||||
@@ -31,13 +31,14 @@ class BankStatementImport(DataImport):
|
|||||||
bank: DF.Link | None
|
bank: DF.Link | None
|
||||||
bank_account: DF.Link
|
bank_account: DF.Link
|
||||||
company: DF.Link
|
company: DF.Link
|
||||||
|
custom_delimiters: DF.Check
|
||||||
|
delimiter_options: DF.Data | None
|
||||||
google_sheets_url: DF.Data | None
|
google_sheets_url: DF.Data | None
|
||||||
import_file: DF.Attach | None
|
import_file: DF.Attach | None
|
||||||
import_type: DF.Literal["", "Insert New Records", "Update Existing Records"]
|
import_type: DF.Literal["", "Insert New Records", "Update Existing Records"]
|
||||||
mute_emails: DF.Check
|
mute_emails: DF.Check
|
||||||
reference_doctype: DF.Link
|
reference_doctype: DF.Link
|
||||||
show_failed_logs: DF.Check
|
show_failed_logs: DF.Check
|
||||||
statement_import_log: DF.Code | None
|
|
||||||
status: DF.Literal["Pending", "Success", "Partial Success", "Error"]
|
status: DF.Literal["Pending", "Success", "Partial Success", "Error"]
|
||||||
submit_after_import: DF.Check
|
submit_after_import: DF.Check
|
||||||
template_options: DF.Code | None
|
template_options: DF.Code | None
|
||||||
@@ -121,6 +122,11 @@ def download_errored_template(data_import_name):
|
|||||||
data_import.export_errored_rows()
|
data_import.export_errored_rows()
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def download_import_log(data_import_name):
|
||||||
|
return frappe.get_doc("Bank Statement Import", data_import_name).download_import_log()
|
||||||
|
|
||||||
|
|
||||||
def parse_data_from_template(raw_data):
|
def parse_data_from_template(raw_data):
|
||||||
data = []
|
data = []
|
||||||
|
|
||||||
@@ -242,6 +248,47 @@ def write_xlsx(data, sheet_name, wb=None, column_widths=None, file_path=None):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_import_status(docname):
|
||||||
|
import_status = {}
|
||||||
|
|
||||||
|
data_import = frappe.get_doc("Bank Statement Import", docname)
|
||||||
|
import_status["status"] = data_import.status
|
||||||
|
|
||||||
|
logs = frappe.get_all(
|
||||||
|
"Data Import Log",
|
||||||
|
fields=["count(*) as count", "success"],
|
||||||
|
filters={"data_import": docname},
|
||||||
|
group_by="success",
|
||||||
|
)
|
||||||
|
|
||||||
|
total_payload_count = 0
|
||||||
|
|
||||||
|
for log in logs:
|
||||||
|
total_payload_count += log.get("count", 0)
|
||||||
|
if log.get("success"):
|
||||||
|
import_status["success"] = log.get("count")
|
||||||
|
else:
|
||||||
|
import_status["failed"] = log.get("count")
|
||||||
|
|
||||||
|
import_status["total_records"] = total_payload_count
|
||||||
|
|
||||||
|
return import_status
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_import_logs(docname: str):
|
||||||
|
frappe.has_permission("Bank Statement Import")
|
||||||
|
|
||||||
|
return frappe.get_all(
|
||||||
|
"Data Import Log",
|
||||||
|
fields=["success", "docname", "messages", "exception", "row_indexes"],
|
||||||
|
filters={"data_import": docname},
|
||||||
|
limit_page_length=5000,
|
||||||
|
order_by="log_index",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def upload_bank_statement(**args):
|
def upload_bank_statement(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|||||||
Reference in New Issue
Block a user