From bdf32afa2d7b4e961b30c59e7d45ba24ce85fd8c Mon Sep 17 00:00:00 2001
From: Ali <010109ali@gmail.com>
Date: Wed, 10 Jun 2026 17:52:03 +0000
Subject: [PATCH] refactor(kapital-bank): move client JS into bundle; update
settings, mappings, hooks, az locale
Co-Authored-By: Claude Opus 4.8 (1M context)
---
kapital_bank/hooks.py | 10 +-
.../kapital_bank_customer_mapping.json | 4 +-
.../kapital_bank_settings.js | 240 ++++++++++++++++++
.../kapital_bank_settings.py | 101 ++++++--
.../kapital_bank_supplier_mapping.json | 4 +-
kapital_bank/locale/az.po | 115 ++++-----
.../js/kapital_bank_import.bundle.js} | 47 ++--
7 files changed, 429 insertions(+), 92 deletions(-)
rename kapital_bank/{client/bank_transaction.js => public/js/kapital_bank_import.bundle.js} (92%)
diff --git a/kapital_bank/hooks.py b/kapital_bank/hooks.py
index 0302511..76f6676 100644
--- a/kapital_bank/hooks.py
+++ b/kapital_bank/hooks.py
@@ -15,15 +15,21 @@ after_migrate = "kapital_bank.setup.after_migrate"
# mapping-source select) lives in jey_erp/public/js/bank_reconciliation_tool.js
# and works with both Kapital Bank Settings and Bank Integration mappings via
# the universal resolver in jey_erp/bank_integration/mapping_resolver.py.
+# Kapital Bank importer (KBBTImport) + its registration into jey_erp's shared
+# "Import From..." bank-import menu. Loaded globally so it is available wherever
+# the menu appears (Bank Transaction / Payment Entry lists, Bank Reconciliation
+# Tool) — not only on the Bank Transaction doctype.
+app_include_js = [
+ "kapital_bank_import.bundle.js",
+]
+
doctype_js = {
"Payment Entry": "client/payment_entry.js",
- "Bank Transaction": "client/bank_transaction.js",
"Payment Request": "client/payment_request.js",
}
doctype_list_js = {
"Payment Entry": "client/payment_entry.js",
- "Bank Transaction": "client/bank_transaction.js",
"Kapital Bank Bank Code": "client/kapital_bank_bank_code.js",
}
diff --git a/kapital_bank/kapital_bank/doctype/kapital_bank_customer_mapping/kapital_bank_customer_mapping.json b/kapital_bank/kapital_bank/doctype/kapital_bank_customer_mapping/kapital_bank_customer_mapping.json
index a7efbea..f5c3d66 100644
--- a/kapital_bank/kapital_bank/doctype/kapital_bank_customer_mapping/kapital_bank_customer_mapping.json
+++ b/kapital_bank/kapital_bank/doctype/kapital_bank_customer_mapping/kapital_bank_customer_mapping.json
@@ -24,10 +24,12 @@
"reqd": 1
},
{
+ "fetch_from": "kb_customer_name.tax_id",
"fieldname": "tax_id",
"fieldtype": "Data",
"in_list_view": 1,
- "label": "Tax ID"
+ "label": "Tax ID",
+ "read_only": 1
},
{
"fieldname": "erp_customer",
diff --git a/kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js b/kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js
index 98e751a..d9ed018 100644
--- a/kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js
+++ b/kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js
@@ -184,6 +184,9 @@ frappe.ui.form.on('Kapital Bank Settings', {
});
});
+ // ── Workflow wizard (current step + expandable step list) ─────────────
+ _kb_render_form_wizard(frm);
+
// ── Populate data tabs ────────────────────────────────────────────────
load_data_tabs(frm);
}
@@ -1295,3 +1298,240 @@ function list_header(label, total_count, refresh_id) {
`;
}
+
+// ═══════════════════════════════════════════════════════════════════════════════
+// WORKFLOW WIZARD — compact bar at the top of the Kapital Bank Settings form.
+// Mirrors the Bank Integration Profile wizard, adapted to KB's API-driven flow:
+// connect → fetch from the bank → map accounts/cards & counterparties → rules →
+// import → reconcile. Shows the CURRENT step; clicking expands the full list.
+// ═══════════════════════════════════════════════════════════════════════════════
+
+function _kb_inject_wizard_styles() {
+ if (document.getElementById('kb-wizard-styles')) return;
+ const css = `
+ .kb-wizard { margin: 0 0 12px; border: 1px solid var(--border-color, #e2e6e9);
+ border-radius: 8px; background: var(--card-bg, #fff); overflow: hidden; }
+ .kb-wizard-bar { display: flex; align-items: center; gap: 9px; padding: 9px 12px;
+ cursor: pointer; user-select: none; }
+ .kb-wizard-bar:hover { background: var(--bg-light-gray, #f4f5f6); }
+ .kb-wizard-dot { width: 9px; height: 9px; border-radius: 50%;
+ background: var(--blue-500, #2490ef); flex: 0 0 auto; }
+ .kb-wizard-cur { flex: 1 1 auto; }
+ .kb-wizard-cur b { margin-right: 4px; }
+ .kb-wizard-toggle { font-size: 12px; color: var(--text-muted); white-space: nowrap;
+ display: inline-flex; align-items: center; gap: 4px; }
+ .kb-wizard-chev { display: inline-block;
+ transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1); }
+ .kb-wizard.open .kb-wizard-chev { transform: rotate(180deg); }
+ .kb-wizard-list { max-height: 0; overflow: hidden;
+ padding: 0 6px; border-top: 0 solid var(--border-color, #eef0f2);
+ transition: max-height 0.45s ease-in-out, padding 0.45s ease-in-out,
+ border-width 0.45s ease-in-out; }
+ .kb-wizard.open .kb-wizard-list { max-height: 640px; padding: 6px;
+ border-top-width: 1px; }
+ .kb-wizard-step { display: flex; align-items: flex-start; gap: 10px;
+ padding: 8px; border-radius: 6px; }
+ .kb-wizard-step-main { display: flex; align-items: flex-start; gap: 10px;
+ flex: 1 1 auto; cursor: pointer; min-width: 0; }
+ .kb-wizard-step:hover { background: var(--bg-light-gray, #f4f5f6); }
+ .kb-wizard-step.cur { background: var(--highlight-color, #f0f4ff); }
+ .kb-wizard-step.done { opacity: 0.65; }
+ .kb-wizard-step.skipped { opacity: 0.5; }
+ .kb-wizard-badge { flex: 0 0 22px; width: 22px; height: 22px; border-radius: 50%;
+ display: inline-flex; align-items: center; justify-content: center;
+ font-weight: 600; font-size: 12px; margin-top: 1px;
+ background: var(--control-bg, #f4f5f6); }
+ .kb-wizard-step.done .kb-wizard-badge { background: var(--green-100, #d4f3e0);
+ color: var(--green-600, #1f9d55); }
+ .kb-wizard-step.cur .kb-wizard-badge { background: var(--blue-500, #2490ef);
+ color: #fff; }
+ .kb-wizard-step-title { font-weight: 600; }
+ .kb-wizard-step-hint { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
+ .kb-wizard-tag { font-size: 11px; font-weight: 600; margin-left: 6px; }
+ .kb-wizard-tag.cur { color: var(--blue-600, #1373cc); }
+ .kb-wizard-tag.skip { color: var(--text-muted); }
+ .kb-wizard-skip { flex: 0 0 auto; font-size: 11px; color: var(--text-muted);
+ cursor: pointer; white-space: nowrap; padding: 2px 4px; align-self: center; }
+ .kb-wizard-skip:hover { color: var(--text-color, #1f272e); text-decoration: underline; }`;
+ const style = document.createElement('style');
+ style.id = 'kb-wizard-styles';
+ style.textContent = css;
+ document.head.appendChild(style);
+}
+
+// Skip state is per-user (localStorage). Single doctype, so a fixed key.
+function _kb_skip_key() { return 'kb_wizard_skipped::Kapital Bank Settings'; }
+function _kb_get_skipped() {
+ try { return JSON.parse(localStorage.getItem(_kb_skip_key()) || '[]'); }
+ catch (e) { return []; }
+}
+function _kb_set_skipped(arr) {
+ try { localStorage.setItem(_kb_skip_key(), JSON.stringify(arr)); } catch (e) { /* ignore */ }
+}
+
+// Focus a field that may live inside a custom_subtabs subtab. scroll_to_field only
+// activates the parent tab and leaves the subtab content hidden, so for subtab
+// fields we click the subtab button (its handler reveals the content).
+function _kb_focus_field(frm, fieldname) {
+ const wrapper = (frm.layout && frm.layout.wrapper) || frm.$wrapper;
+ const field = frm.get_field(fieldname);
+ const $pane = field && field.$wrapper ? field.$wrapper.closest('.tab-pane') : $();
+ const paneId = $pane.attr('id');
+ if (paneId) {
+ const $btn = wrapper.find(
+ `.sub-tab button.nav-link[data-target-id="${paneId}"], ` +
+ `.sub-tab a.nav-link[data-target-id="${paneId}"]`
+ );
+ if ($btn.length) {
+ $btn.first().trigger('click');
+ setTimeout(() => {
+ if (field.$wrapper && field.$wrapper[0]) {
+ field.$wrapper[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
+ }
+ }, 80);
+ return;
+ }
+ }
+ frm.scroll_to_field(fieldname);
+}
+
+function _kb_render_form_wizard(frm, keepOpen) {
+ frappe.call({
+ method: 'kapital_bank.bank_api.get_kb_reference_data_summary',
+ callback(r) {
+ const s = (r.message && r.message.summary) || {};
+ const g = (k) => s[k] || { total: 0, mapped: 0 };
+ const acc = g('accounts'), card = g('cards');
+ const cust = g('customers'), sup = g('suppliers'), pur = g('purposes');
+
+ const registryTotal = acc.total + card.total + cust.total + sup.total + pur.total;
+ const acctCardTotal = acc.total + card.total;
+ const acctCardMapped = acc.mapped + card.mapped;
+ const partyTotal = cust.total + sup.total;
+ const partyMapped = cust.mapped + sup.mapped;
+
+ const hasLogin = !!frm.doc.default_login;
+ const hasData = registryTotal > 0;
+ const acctCardDone = acctCardTotal > 0 && acctCardMapped === acctCardTotal;
+ const partyDone = partyTotal > 0 && partyMapped === partyTotal;
+ const hasTxnRules = (frm.doc.transaction_mappings || []).length > 0;
+
+ const skipped = _kb_get_skipped();
+
+ // Steps 6-7 live on other doctypes — always navigation, not skippable.
+ const steps = [
+ {
+ key: 'connect', done: hasLogin,
+ title: __('Connect Kapital Bank'),
+ hint: __('Set the default login and company defaults used to reach the bank API.'),
+ action: () => _kb_focus_field(frm, 'default_login'),
+ },
+ {
+ key: 'load', done: hasData,
+ title: __('Load data from the bank'),
+ hint: __('Fetch accounts, cards, counterparties and purposes from the Kapital Bank API.'),
+ action: () => show_load_data_dialog(frm),
+ },
+ {
+ key: 'mapacc', done: acctCardDone,
+ title: __('Map accounts & cards'),
+ hint: __('Link Kapital Bank accounts and cards to ERP Bank Accounts (Accounts / Cards menus above).'),
+ action: () => _kb_focus_field(frm, 'account_mappings'),
+ },
+ {
+ key: 'mapparty', done: partyDone,
+ title: __('Map counterparties'),
+ hint: __('Match or create customers and suppliers (Customers / Suppliers menus above).'),
+ action: () => _kb_focus_field(frm, 'customer_mappings'),
+ },
+ {
+ key: 'rules', done: hasTxnRules,
+ title: __('Configure transaction rules'),
+ hint: __('Define how purposes map to Payment Entries / Journal Entries.'),
+ action: () => _kb_focus_field(frm, 'transaction_mappings'),
+ },
+ {
+ key: 'import', off: true,
+ title: __('Import transactions'),
+ hint: __('In the Bank Transaction list: Bank Integrations → Import Bank Statement.'),
+ action: () => frappe.set_route('List', 'Bank Transaction'),
+ },
+ {
+ key: 'reconcile', off: true,
+ title: __('Create documents & reconcile'),
+ hint: __('In the Bank Reconciliation Tool: pick the account and Create & Reconcile.'),
+ action: () => frappe.set_route('Form', 'Bank Reconciliation Tool'),
+ },
+ ];
+ steps.forEach((st) => { st.skipped = !st.off && skipped.indexOf(st.key) !== -1; });
+
+ let currentIdx = steps.findIndex((st) => !st.off && !st.done && !st.skipped);
+ if (currentIdx === -1) currentIdx = 5; // all on-form steps done/skipped → "Import"
+ const cur = steps[currentIdx];
+
+ const esc = frappe.utils.escape_html;
+ const rows = steps.map((st, i) => {
+ const isCur = i === currentIdx;
+ let badge, cls, tag;
+ if (st.skipped) {
+ badge = '–'; cls = 'skipped';
+ tag = ` ${__('Skipped')}`;
+ } else if (st.done) {
+ badge = '✓'; cls = 'done'; tag = '';
+ } else if (isCur) {
+ badge = '➜'; cls = 'cur';
+ tag = ` ${__('Current step')}`;
+ } else {
+ badge = (i + 1); cls = 'todo'; tag = '';
+ }
+
+ const skipCtl = st.off ? '' :
+ `${
+ st.skipped ? __('Unskip') : __('Skip')}`;
+
+ return `
+
+
+
${badge}
+
+
${esc(st.title)}${tag}
+
${esc(st.hint)}
+
+
+ ${skipCtl}
+
`;
+ }).join('');
+
+ const html = `
+
+
+
+ ${__('Kapital Bank')} · ${esc(cur.title)}
+ ${__('Steps')}▾
+
+
${rows}
+
`;
+
+ _kb_inject_wizard_styles();
+
+ const $host = frm.$wrapper.find('.form-layout').first();
+ frm.$wrapper.find('.kb-wizard').remove();
+ const $w = $(html);
+ $host.prepend($w);
+
+ $w.find('.kb-wizard-bar').on('click', () => $w.toggleClass('open'));
+ $w.find('.kb-wizard-step-main').on('click', function () {
+ steps[$(this).data('kb-step')].action();
+ });
+ $w.find('.kb-wizard-skip').on('click', function (e) {
+ e.stopPropagation();
+ const key = $(this).data('kb-skip');
+ const set = _kb_get_skipped();
+ const idx = set.indexOf(key);
+ if (idx === -1) set.push(key); else set.splice(idx, 1);
+ _kb_set_skipped(set);
+ _kb_render_form_wizard(frm, /* keepOpen */ true);
+ });
+ },
+ });
+}
diff --git a/kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.py b/kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.py
index e6a3c4b..18b1443 100644
--- a/kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.py
+++ b/kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.py
@@ -4,22 +4,37 @@ from frappe.model.document import Document
class KapitalBankSettings(Document):
def on_update(self):
+ # Keep the registry records in sync with the mapping child tables, both ways:
+ # * a row with a linked target (Bank Account / ERP party) -> registry
+ # record becomes Mapped (and inherits its attributes);
+ # * removing a row OR clearing that link flips the record back to New.
self._sync_account_statuses()
self._sync_customer_statuses()
self._sync_supplier_statuses()
self._sync_card_statuses()
def _sync_account_statuses(self):
- """Reset Kapital Bank Account status to 'New' when its mapping row is removed
- from account_mappings, or when the row's Bank Account link is cleared."""
- mapped_ibans = {row.iban for row in self.account_mappings if row.iban and row.bank_account}
+ """Kapital Bank Account becomes Mapped when its mapping row links a Bank
+ Account, and reverts to New when the row is removed or the link cleared."""
+ mapped_ibans = set()
+ for row in self.account_mappings:
+ if not (row.iban and row.bank_account):
+ continue
+ mapped_ibans.add(row.iban)
+ current = frappe.db.get_value(
+ "Kapital Bank Account", row.iban, ["status", "bank_account"], as_dict=True
+ )
+ if not current:
+ continue
+ desired = {"status": "Mapped", "bank_account": row.bank_account}
+ if any(current.get(k) != v for k, v in desired.items()):
+ frappe.db.set_value("Kapital Bank Account", row.iban, desired, update_modified=False)
orphaned = frappe.get_all(
"Kapital Bank Account",
filters={"status": "Mapped"},
fields=["name"],
)
-
for account in orphaned:
if account.name not in mapped_ibans:
frappe.db.set_value(
@@ -33,16 +48,37 @@ class KapitalBankSettings(Document):
)
def _sync_customer_statuses(self):
- """Reset Kapital Bank Customer status to 'New' when its mapping row is removed
- from customer_mappings, or when the row's ERP Customer link is cleared."""
- mapped_names = {row.kb_customer_name for row in self.customer_mappings if row.kb_customer_name and row.erp_customer}
+ """Kapital Bank Customer becomes Mapped when its mapping row links an ERP
+ Customer, and reverts to New when the row is removed or the link cleared."""
+ mapped_names = set()
+ for row in self.customer_mappings:
+ if not (row.kb_customer_name and row.erp_customer):
+ continue
+ mapped_names.add(row.kb_customer_name)
+ current = frappe.db.get_value(
+ "Kapital Bank Customer", row.kb_customer_name,
+ ["status", "mapped_customer", "customer_group", "territory", "payment_terms"],
+ as_dict=True,
+ )
+ if not current:
+ continue
+ desired = {
+ "status": "Mapped",
+ "mapped_customer": row.erp_customer,
+ "customer_group": row.customer_group or None,
+ "territory": row.territory or None,
+ "payment_terms": row.payment_terms or None,
+ }
+ if any(current.get(k) != v for k, v in desired.items()):
+ frappe.db.set_value(
+ "Kapital Bank Customer", row.kb_customer_name, desired, update_modified=False
+ )
orphaned = frappe.get_all(
"Kapital Bank Customer",
filters={"status": "Mapped"},
fields=["name", "customer_name"],
)
-
for customer in orphaned:
if customer.name not in mapped_names:
frappe.db.set_value(
@@ -59,16 +95,36 @@ class KapitalBankSettings(Document):
)
def _sync_supplier_statuses(self):
- """Reset Kapital Bank Supplier status to 'New' when its mapping row is removed
- from supplier_mappings, or when the row's ERP Supplier link is cleared."""
- mapped_names = {row.kb_supplier_name for row in self.supplier_mappings if row.kb_supplier_name and row.erp_supplier}
+ """Kapital Bank Supplier becomes Mapped when its mapping row links an ERP
+ Supplier, and reverts to New when the row is removed or the link cleared."""
+ mapped_names = set()
+ for row in self.supplier_mappings:
+ if not (row.kb_supplier_name and row.erp_supplier):
+ continue
+ mapped_names.add(row.kb_supplier_name)
+ current = frappe.db.get_value(
+ "Kapital Bank Supplier", row.kb_supplier_name,
+ ["status", "mapped_supplier", "supplier_group", "payment_terms"],
+ as_dict=True,
+ )
+ if not current:
+ continue
+ desired = {
+ "status": "Mapped",
+ "mapped_supplier": row.erp_supplier,
+ "supplier_group": row.supplier_group or None,
+ "payment_terms": row.payment_terms or None,
+ }
+ if any(current.get(k) != v for k, v in desired.items()):
+ frappe.db.set_value(
+ "Kapital Bank Supplier", row.kb_supplier_name, desired, update_modified=False
+ )
orphaned = frappe.get_all(
"Kapital Bank Supplier",
filters={"status": "Mapped"},
fields=["name", "supplier_name"],
)
-
for supplier in orphaned:
if supplier.name not in mapped_names:
frappe.db.set_value(
@@ -84,16 +140,29 @@ class KapitalBankSettings(Document):
)
def _sync_card_statuses(self):
- """Reset Kapital Bank Card status to 'New' when its mapping row is removed
- from card_mappings, or when the row's Bank Account link is cleared."""
- mapped_accounts = {row.account_number for row in self.card_mappings if row.account_number and row.bank_account}
+ """Kapital Bank Card becomes Mapped when its mapping row links a Bank
+ Account, and reverts to New when the row is removed or the link cleared."""
+ mapped_accounts = set()
+ for row in self.card_mappings:
+ if not (row.account_number and row.bank_account):
+ continue
+ mapped_accounts.add(row.account_number)
+ current = frappe.db.get_value(
+ "Kapital Bank Card", row.account_number, ["status", "bank_account"], as_dict=True
+ )
+ if not current:
+ continue
+ desired = {"status": "Mapped", "bank_account": row.bank_account}
+ if any(current.get(k) != v for k, v in desired.items()):
+ frappe.db.set_value(
+ "Kapital Bank Card", row.account_number, desired, update_modified=False
+ )
orphaned = frappe.get_all(
"Kapital Bank Card",
filters={"status": "Mapped"},
fields=["name", "account_number"],
)
-
for card in orphaned:
if card.name not in mapped_accounts:
frappe.db.set_value(
diff --git a/kapital_bank/kapital_bank/doctype/kapital_bank_supplier_mapping/kapital_bank_supplier_mapping.json b/kapital_bank/kapital_bank/doctype/kapital_bank_supplier_mapping/kapital_bank_supplier_mapping.json
index d3c0408..746062d 100644
--- a/kapital_bank/kapital_bank/doctype/kapital_bank_supplier_mapping/kapital_bank_supplier_mapping.json
+++ b/kapital_bank/kapital_bank/doctype/kapital_bank_supplier_mapping/kapital_bank_supplier_mapping.json
@@ -23,10 +23,12 @@
"reqd": 1
},
{
+ "fetch_from": "kb_supplier_name.tax_id",
"fieldname": "tax_id",
"fieldtype": "Data",
"in_list_view": 1,
- "label": "Tax ID"
+ "label": "Tax ID",
+ "read_only": 1
},
{
"fieldname": "erp_supplier",
diff --git a/kapital_bank/locale/az.po b/kapital_bank/locale/az.po
index 7fe261d..8113b05 100644
--- a/kapital_bank/locale/az.po
+++ b/kapital_bank/locale/az.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Kapital Bank VERSION\n"
"Report-Msgid-Bugs-To: info@jeyerp.az\n"
"POT-Creation-Date: 2026-04-24 19:34+0000\n"
-"PO-Revision-Date: 2026-04-24 19:37+0000\n"
+"PO-Revision-Date: 2026-05-24 23:53+0000\n"
"Last-Translator: \n"
"Language-Team: Azerbaijani\n"
"Language: az\n"
@@ -17,6 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Generated-By: Babel 2.16.0\n"
+"X-Generator: Poedit 3.4.2\n"
#. AI-generated
#: kapital_bank/client/bank_transaction.js:206
@@ -65,8 +66,8 @@ msgid ""
"Bank"
msgstr ""
"Kapital Bank-dan kartları əldə etmək üçün \"Məlumatı"
-" Yüklə\" düyməsinə klikləyin
"
+"style=\"padding:20px;\">Kapital Bank-dan kartları əldə etmək üçün "
+"\"Məlumatı Yüklə\" düyməsinə klikləyin"
#. Content of the 'Customers List' (HTML) field in DocType 'Kapital Bank
#. Settings'
@@ -109,8 +110,8 @@ msgid ""
"irreversible. Are you sure?
"
msgstr ""
"XƏBƏRDARLIQ! Bu, bütün "
-"uyğunlaşdırılmamış hesablar üçün yeni Bank Hesabı qeydləri "
-"yaradacaq!
Bu əməliyyat geri qaytarıla bilməz. Əminsiniz?
"
+"uyğunlaşdırılmamış hesablar üçün yeni Bank Hesabı qeydləri yaradacaq!"
+"div>Bu əməliyyat geri qaytarıla bilməz. Əminsiniz?
"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:314
@@ -120,8 +121,8 @@ msgid ""
"irreversible. Are you sure?"
msgstr ""
"XƏBƏRDARLIQ! Bu, bütün "
-"uyğunlaşdırılmamış kartlar üçün yeni Bank Hesabı qeydləri "
-"yaradacaq!
Bu əməliyyat geri qaytarıla bilməz. Əminsiniz?
"
+"uyğunlaşdırılmamış kartlar üçün yeni Bank Hesabı qeydləri yaradacaq!"
+"div>Bu əməliyyat geri qaytarıla bilməz. Əminsiniz?
"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:693
@@ -131,8 +132,8 @@ msgid ""
"irreversible. Are you sure?"
msgstr ""
"XƏBƏRDARLIQ! Bu, bütün "
-"uyğunlaşdırılmamış müştərilər üçün yeni Müştəri qeydləri "
-"yaradacaq!
Bu əməliyyat geri qaytarıla bilməz. Əminsiniz?
"
+"uyğunlaşdırılmamış müştərilər üçün yeni Müştəri qeydləri yaradacaq!"
+"div>Bu əməliyyat geri qaytarıla bilməz. Əminsiniz?
"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:725
@@ -142,8 +143,8 @@ msgid ""
"irreversible. Are you sure?"
msgstr ""
"XƏBƏRDARLIQ! Bu, bütün "
-"uyğunlaşdırılmamış təchizatçılar üçün yeni Təchizatçı qeydləri "
-"yaradacaq!
Bu əməliyyat geri qaytarıla bilməz. Əminsiniz?
"
+"uyğunlaşdırılmamış təchizatçılar üçün yeni Təchizatçı qeydləri yaradacaq!"
+"div>Bu əməliyyat geri qaytarıla bilməz. Əminsiniz?
"
#. Option for the 'Source Type' (Select) field in DocType 'Kapital Bank
#. Transaction'
@@ -291,7 +292,7 @@ msgstr "{0} hesab uyğunlaşdırmaya əlavə edildi"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:589
msgid "Added {0} cards to mapping"
-msgstr "Eşləşdirməyə {0} kart əlavə edildi"
+msgstr "Uyğunlaşdırma {0} kart əlavə edildi"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:617
@@ -301,7 +302,7 @@ msgstr "Xəritələməyə {0} müştəri əlavə edildi"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:684
msgid "Added {0} rows to mapping ({1} purposes)"
-msgstr "Eşləməyə {0} sətir əlavə edildi ({1} məqsəd)"
+msgstr "Uyğunlaşdırmaya {0} sətir əlavə edildi ({1} təyinat üzrə)"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:645
@@ -369,13 +370,13 @@ msgstr "Çıxış etmək istədiyinizə əminsiniz?"
#: kapital_bank/kapital_bank/doctype/kapital_bank_api_test/kapital_bank_api_test.js:7
#: kapital_bank/kapital_bank/doctype/kapital_bank_api_test/kapital_bank_api_test.js:8
msgid "Auth"
-msgstr "Auth"
+msgstr "Təsdiq"
#. Label of the auth_status (Select) field in DocType 'Kapital Bank Login'
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_login/kapital_bank_login.json
msgid "Auth Status"
-msgstr "Autentifikasiya Statusu"
+msgstr "Təsdiq Statusu"
#. Option for the 'Auth Status' (Select) field in DocType 'Kapital Bank Login'
#. AI-generated
@@ -388,7 +389,7 @@ msgstr "Təsdiqlənib"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_login/kapital_bank_login.json
msgid "Authentication"
-msgstr "Autentifikasiya"
+msgstr "Təsdiqlənmə"
#. Option for the 'Mapping Type' (Select) field in DocType 'Kapital Bank
#. Customer Mapping'
@@ -465,7 +466,7 @@ msgstr "Bank köçürməsi uğurla ləğv edildi."
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_payment/kapital_bank_payment.json
msgid "Beneficiary Bank Code"
-msgstr "Benefisiar Bank Kodu"
+msgstr "Vəsaiti Alan Bankın Kodu"
#. Option for the 'Direction' (Select) field in DocType 'Kapital Bank Purpose'
#. AI-generated
@@ -619,9 +620,9 @@ msgstr ""
#: kapital_bank/client/bank_transaction.js:535
#: kapital_bank/client/payment_entry.js:493
msgid ""
-"Card transactions may already be imported from other accounts. The bank uses"
-" different reference numbers for card and account statements, so duplicates "
-"cannot be detected automatically."
+"Card transactions may already be imported from other accounts. The bank "
+"uses different reference numbers for card and account statements, so "
+"duplicates cannot be detected automatically."
msgstr ""
"Kart əməliyyatları artıq digər hesablardan idxal edilmiş ola bilər. Bank "
"kart və hesab çıxarışları üçün fərqli istinad nömrələrindən istifadə edir, "
@@ -733,8 +734,8 @@ msgid ""
"Consider replacement of Azerbaijani letters with Latin equivalents when "
"matching"
msgstr ""
-"Uyğunlaşdırarkən Azərbaycan hərflərinin Latın qarşılıqları ilə əvəzlənməsini"
-" nəzərə alın"
+"Uyğunlaşdırarkən Azərbaycan hərflərinin Latın qarşılıqları ilə "
+"əvəzlənməsini nəzərə alın"
#. Label of the cost_center (Link) field in DocType 'Kapital Bank Transaction
#. Mapping'
@@ -800,17 +801,17 @@ msgstr "Kartlar üçün Bank Hesabları yaradın"
#. AI-generated
#: kapital_bank/client/mapping.js:141
msgid "Create Mappings"
-msgstr "Xəritələmələr Yarat"
+msgstr "Uyğunlaşdırmalar Yaradın"
#. AI-generated
#: kapital_bank/client/mapping.js:8
msgid "Create Purpose Mapping"
-msgstr "Məqsəd Uyğunlaşdırması Yarat"
+msgstr "Təyinat Uyğunlaşdırması Yarat"
#. AI-generated
#: kapital_bank/client/mapping.js:116
msgid "Create Purpose Mappings"
-msgstr "Məqsəd Uyğunluqlarını Yarat"
+msgstr "Təyinat Uyğunlaşdırmaları Yarat"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:102
@@ -1001,7 +1002,7 @@ msgstr "Bitmə Tarixi"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.json
msgid "Default Bank"
-msgstr "Defolt Bank"
+msgstr "Əsas Bank"
#. Label of the default_party_settings_section (Section Break) field in
#. DocType
@@ -1009,48 +1010,48 @@ msgstr "Defolt Bank"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.json
msgid "Default Business Partner Settings"
-msgstr "Defolt Biznes Tərəfdaş Parametrləri"
+msgstr "Əsas Biznes Tərəfdaşı Tənzimləmələri"
#. Label of the default_company (Link) field in DocType 'Kapital Bank
#. Settings'
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.json
msgid "Default Company"
-msgstr "Defolt Şirkət"
+msgstr "Əsas Şirkət"
#. Label of the default_customer_group (Link) field in DocType 'Kapital Bank
#. Settings'
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.json
msgid "Default Customer Group"
-msgstr "Defolt Müştəri Qrupu"
+msgstr "Əsas Müştəri Qrupu"
#. Label of the default_login (Link) field in DocType 'Kapital Bank Settings'
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.json
msgid "Default Login"
-msgstr "Defolt giriş"
+msgstr "Əsas Giriş"
#. Label of the default_payment_terms (Link) field in DocType 'Kapital Bank
#. Settings'
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.json
msgid "Default Payment Terms"
-msgstr "Defolt Ödəniş Şərtləri"
+msgstr "Əsas Ödəniş Şərtləri"
#. Label of the default_supplier_group (Link) field in DocType 'Kapital Bank
#. Settings'
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.json
msgid "Default Supplier Group"
-msgstr "Defolt Təchizatçı Qrupu"
+msgstr "Əsas Təchizatçı Qrupu"
#. Label of the default_territory (Link) field in DocType 'Kapital Bank
#. Settings'
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.json
msgid "Default Territory"
-msgstr "Defolt Ərazi"
+msgstr "Əsas Ərazi"
#. AI-generated
#: kapital_bank/client/bank_reconciliation_tool.js:150
@@ -1091,8 +1092,8 @@ msgstr "Sənəd Növü"
msgid ""
"Document contains unsaved changes. Save before performing the operation?"
msgstr ""
-"Sənəddə yadda saxlanılmamış dəyişikliklər var. Əməliyyatı yerinə yetirməzdən"
-" əvvəl yadda saxlanılsın?"
+"Sənəddə yadda saxlanılmamış dəyişikliklər var. Əməliyyatı yerinə "
+"yetirməzdən əvvəl yadda saxlanılsın?"
#. AI-generated
#: kapital_bank/client/bank_reconciliation_tool.js:305
@@ -1289,8 +1290,8 @@ msgstr ""
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:405
msgid ""
-"Extract unique purposes from account statement transactions for the selected"
-" period"
+"Extract unique purposes from account statement transactions for the "
+"selected period"
msgstr ""
"Seçilmiş dövr üzrə hesab çıxarışı əməliyyatlarından unikal təyinatları "
"çıxarın"
@@ -1360,7 +1361,7 @@ msgstr "{0} Ödəniş Tələbində 'Məbləğ' sahəsi sıfırdır."
#. AI-generated
#: kapital_bank/payment_api.py:80
msgid "Field 'Beneficiary Bank Account' is not set."
-msgstr "\"Benefisiar Bank Hesabı\" sahəsi təyin edilməyib."
+msgstr "\"Vəsaiti alan bankın hesabı\"sahəsi təyin edilməyib."
#. AI-generated
#: kapital_bank/payment_api.py:87
@@ -1381,7 +1382,7 @@ msgstr ""
#. AI-generated
#: kapital_bank/payment_api.py:65
msgid "Field 'Kapital Bank Account' is not set."
-msgstr "'Kapital Bank Account' sahəsi təyin edilməyib."
+msgstr "'Kapital Bank Hesabı' sahəsi təyin edilməyib."
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:1091
@@ -1545,7 +1546,7 @@ msgstr "Aktivdir"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_login/kapital_bank_login.json
msgid "Is Default"
-msgstr "Defolt"
+msgstr "Əsasdır"
#. Label of the jwt_refresh_token (Password) field in DocType 'Kapital Bank
#. Login'
@@ -1645,19 +1646,19 @@ msgstr "Kapital Bank Müştəri Uyğunlaşdırması"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_login/kapital_bank_login.json
msgid "Kapital Bank Login"
-msgstr "Kapital Bank Login"
+msgstr "Kapital Bank Girişi"
#. Name of a DocType
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_payment/kapital_bank_payment.json
msgid "Kapital Bank Payment"
-msgstr "Kapital Bank Payment"
+msgstr "Kapital Bank Ödənişi"
#. Name of a DocType
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_purpose/kapital_bank_purpose.json
msgid "Kapital Bank Purpose"
-msgstr "Kapital Bank Purpose"
+msgstr "Kapital Bank Ödəniş Təyinatı"
#. Name of a DocType
#. AI-generated
@@ -1669,7 +1670,7 @@ msgstr "Kapital Bank Parametrləri"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_supplier/kapital_bank_supplier.json
msgid "Kapital Bank Supplier"
-msgstr "Kapital Bank Supplier"
+msgstr "Kapital Bank Təchizatçısı"
#. Name of a DocType
#. AI-generated
@@ -1857,7 +1858,7 @@ msgstr "Uyğunlaşdırılıb"
#: kapital_bank/kapital_bank/doctype/kapital_bank_customer_mapping/kapital_bank_customer_mapping.json
#: kapital_bank/kapital_bank/doctype/kapital_bank_supplier_mapping/kapital_bank_supplier_mapping.json
msgid "Mapping Type"
-msgstr "Xəritələmə Tipi"
+msgstr "Uyğunlaşdırma Növü"
#. Label of the mappings_tab (Tab Break) field in DocType 'Kapital Bank
#. Settings'
@@ -1981,7 +1982,7 @@ msgstr "Şəbəkə xətası"
#: kapital_bank/client/bank_reconciliation_tool.js:320
#: kapital_bank/client/mapping.js:192
msgid "Network error creating mappings"
-msgstr "Xəritələmələr yaradılarkən şəbəkə xətası"
+msgstr "Uyğunlaşdırmalar yaradılarkən şəbəkə xətası baş verdi"
#. AI-generated
#: kapital_bank/client/bank_transaction.js:517
@@ -2052,7 +2053,7 @@ msgstr ""
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:879
msgid "No cards in registry. Use \"Load Data\" to fetch from Kapital Bank."
msgstr ""
-"Reyestrdə kart yoxdur. Kapital Bank-dan əldə etmək üçün \"Load Data\" "
+"Reyestrdə kart yoxdur. Kapital Bank-dan əldə etmək üçün \"Məlumatı Yüklə\" "
"istifadə edin."
#. AI-generated
@@ -2095,8 +2096,8 @@ msgid ""
"No purposes registered yet. Use \"Load Data\" to extract purposes from "
"statements."
msgstr ""
-"Hələ heç bir məqsəd qeydiyyatdan keçməyib. Hesabatlardan məqsədləri çıxarmaq"
-" üçün \"Load Data\" düyməsindən istifadə edin."
+"Hələ heç bir məqsəd qeydiyyatdan keçməyib. Hesabatlardan məqsədləri "
+"çıxarmaq üçün \"Load Data\" düyməsindən istifadə edin."
#. AI-generated
#: kapital_bank/client/bank_reconciliation_tool.js:93
@@ -2153,7 +2154,7 @@ msgstr "Uyğunlaşdırılmamış təchizatçı tapılmadı"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_login/kapital_bank_login.json
msgid "Not Authenticated"
-msgstr "Autentifikasiya olunmayıb"
+msgstr "Təsdiqlənməyib"
#. Label of the notes (Data) field in DocType 'Kapital Bank Transaction
#. Mapping'
@@ -2297,7 +2298,7 @@ msgstr "Ödəniş Sorğusu {0} etibarsız statusa malikdir: {1}."
#. AI-generated
#: kapital_bank/payment_api.py:58
msgid "Payment Request {0} is not of type Outward."
-msgstr "Ödəniş Sorğusu {0} Outward tipində deyil."
+msgstr "Ödəniş Sorğusu {0} Məxaric tipində deyil."
#. AI-generated
#: kapital_bank/payment_api.py:55
@@ -2872,8 +2873,8 @@ msgid ""
"This will automatically match unmapped customers with similar Customer "
"names. Continue?"
msgstr ""
-"Bu, uyğunlaşdırılmamış müştəriləri oxşar Müştəri adları ilə avtomatik olaraq"
-" uyğunlaşdıracaq. Davam edilsin?"
+"Bu, uyğunlaşdırılmamış müştəriləri oxşar Müştəri adları ilə avtomatik "
+"olaraq uyğunlaşdıracaq. Davam edilsin?"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:209
@@ -2906,7 +2907,7 @@ msgstr "Bitiş Tarixi"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_payment/kapital_bank_payment.json
msgid "To Tax No"
-msgstr "Vergi No-ya qədər"
+msgstr "Müştərinin VÖEN"
#. Label of the token_expiry (Datetime) field in DocType 'Kapital Bank Login'
#. AI-generated
@@ -2947,7 +2948,7 @@ msgstr "Tapılan əməliyyatlar: "
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_api_test/kapital_bank_api_test.js:19
msgid "Transfer Status"
-msgstr "Transfer Statusu"
+msgstr "Köçürmə Statusu"
#. AI-generated
#: kapital_bank/client/payment_request.js:43
@@ -3089,7 +3090,7 @@ msgstr "artıq idxal edilib: {0}"
#: kapital_bank/client/bank_transaction.js:454
#: kapital_bank/client/payment_entry.js:415
msgid "cross-account duplicates: {0}"
-msgstr "hesablararası dublikatlar: {0}"
+msgstr "hesablararası təkrarlananlar: {0}"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:374
@@ -3106,7 +3107,7 @@ msgstr "digər valyuta hesabı: {0}"
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:374
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:1277
msgid "total"
-msgstr "Cəmi"
+msgstr "cəmi"
#. AI-generated
#: kapital_bank/kapital_bank/doctype/kapital_bank_settings/kapital_bank_settings.js:374
diff --git a/kapital_bank/client/bank_transaction.js b/kapital_bank/public/js/kapital_bank_import.bundle.js
similarity index 92%
rename from kapital_bank/client/bank_transaction.js
rename to kapital_bank/public/js/kapital_bank_import.bundle.js
index f518c9e..3e0cf99 100644
--- a/kapital_bank/client/bank_transaction.js
+++ b/kapital_bank/public/js/kapital_bank_import.bundle.js
@@ -721,20 +721,37 @@ KBBTImport.import = {
}
};
-// ======= LIST VIEW SETUP =======
-// Coexists with jey_erp's bank_transaction_list.js which creates the
-// shared "Import From..." button group; we add our item into the same group.
-(function () {
- const existing = frappe.listview_settings['Bank Transaction'] || {};
- const prevOnload = existing.onload;
- frappe.listview_settings['Bank Transaction'] = Object.assign({}, existing, {
- onload(listview) {
- if (typeof prevOnload === 'function') {
- try { prevOnload(listview); } catch (e) { console.error(e); }
+// ───────────────────────────────────────────────────────────────────────────────
+// Register Kapital Bank as a bank-import source in jey_erp's shared "Import
+// From..." menu (Bank Transaction list, Payment Entry list, Bank Reconciliation
+// Tool). Loaded globally via app_include_js, so KBBTImport is available wherever
+// the menu is shown — including the BRT, where the per-doctype script is not.
+// ───────────────────────────────────────────────────────────────────────────────
+
+window.KBBTImport = KBBTImport;
+
+frappe.provide('jey_erp');
+jey_erp.bank_sources = jey_erp.bank_sources || [];
+if (!jey_erp.bank_sources.some((s) => s.key === 'kapital')) {
+ jey_erp.bank_sources.push({
+ key: 'kapital',
+ label: __('Kapital Bank'),
+ importLabel: __('Kapital Bank (API)'),
+ settingsLabel: __('Kapital Bank Settings'),
+ runImport(ctx) {
+ ctx = ctx || {};
+ // Let the caller (e.g. the Bank Reconciliation Tool) react when the
+ // API import finishes — KBBTImport runs its own progress/list refresh,
+ // but the BRT needs to reload its reconciliation table afterwards.
+ if (typeof ctx.onComplete === 'function') {
+ const handler = (d) => {
+ frappe.realtime.off('kb_bt_import_complete', handler);
+ ctx.onComplete({ imported: (d && d.imported) || 0, errors: (d && d.errors) || [], transactions: [] });
+ };
+ frappe.realtime.on('kb_bt_import_complete', handler);
}
- listview.page.add_inner_button(__('Load from Kapital Bank'), function () {
- KBBTImport.import.showDialog();
- }, __('Import From...'));
- }
+ KBBTImport.import.showDialog();
+ },
+ goToSettings() { frappe.set_route('Form', 'Kapital Bank Settings'); },
});
-})();
+}