Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: release v15 #38383

Merged
merged 56 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
d01a480
refactor: optimize outstanding vouchers query
ruthra-kumar Nov 22, 2023
0c3c36f
Merge pull request #38280 from frappe/mergify/bp/version-15-hotfix/pr…
ruthra-kumar Nov 23, 2023
df70e04
chore: rename 'unreconcile payments' to 'unreconcile payment'
ruthra-kumar Nov 21, 2023
100ce27
chore: update new unreconcile doctype name in JS and PY files
ruthra-kumar Nov 21, 2023
fb4235c
Merge pull request #38282 from frappe/mergify/bp/version-15-hotfix/pr…
ruthra-kumar Nov 23, 2023
37d1f1a
fix: Supplier `Primary Contact` (backport #38268) (#38286)
mergify[bot] Nov 23, 2023
18613c5
fix: don't depreciate assets with no schedule on scrapping (backport …
mergify[bot] Nov 23, 2023
72647b8
feat: add Bank Transaction to connections in Journal and Payment Entr…
mergify[bot] Nov 23, 2023
4c9890a
fix: patch - Duplicate entry quality inspection parameter (backport #…
mergify[bot] Nov 23, 2023
30c349b
add flt() for None type error (backport #38299) (#38306)
mergify[bot] Nov 23, 2023
99c1fbf
fix: display all item rate stop messages (backport #38289) (#38307)
mergify[bot] Nov 23, 2023
3720b71
chore: index to speed up queries on JE child table reference
ruthra-kumar Nov 23, 2023
7282dd1
chore: speed up Purchase Invoice cancellation
ruthra-kumar Nov 23, 2023
314a91a
fix: skip fixed assets in parent
GursheenK Nov 22, 2023
fcd53be
feat: add disabled field in product bundle
GursheenK Nov 22, 2023
fb517e8
fix: filter bundle items based on disabled check
GursheenK Nov 22, 2023
5c12872
fix: has_product_bundle util to only check for enabled bundles
GursheenK Nov 22, 2023
c0de9c0
fix: validation for existing bundles
GursheenK Nov 22, 2023
e4d9ef1
fix: condition in other bundle utils
GursheenK Nov 22, 2023
3d46b32
fix: skip disabled bundles for non-report utils
GursheenK Nov 22, 2023
d076aca
chore: linting issues
GursheenK Nov 22, 2023
220a0f4
Merge pull request #38312 from frappe/mergify/bp/version-15-hotfix/pr…
ruthra-kumar Nov 24, 2023
deed9f5
perf: optimize total_purchase_cost update
ruthra-kumar Nov 23, 2023
28e695b
refactor: provide UI button to recalculate when needed
ruthra-kumar Nov 23, 2023
c06388f
refactor: make update_project_cost optional through Buying Settings
ruthra-kumar Nov 24, 2023
7fc4e21
refactor: update project costing based on frequency
ruthra-kumar Nov 24, 2023
2d6b2f7
Merge pull request #38319 from frappe/mergify/bp/version-15-hotfix/pr…
ruthra-kumar Nov 24, 2023
ca2ad17
fix: annual income and expenses in digest
GursheenK Nov 22, 2023
b9a1fac
fix: fiscal year using future date
GursheenK Nov 22, 2023
18f9650
Merge pull request #38325 from frappe/mergify/bp/version-15-hotfix/pr…
deepeshgarg007 Nov 24, 2023
64d9c5d
Merge pull request #38316 from frappe/mergify/bp/version-15-hotfix/pr…
deepeshgarg007 Nov 24, 2023
ea2c348
feat: new Report "Lost Quotations" (#38309)
barredterra Nov 24, 2023
e0f9c64
Merge pull request #38332 from frappe/mergify/bp/version-15-hotfix/pr…
deepeshgarg007 Nov 25, 2023
d6fe7eb
fix: job card overlap validation (backport #38345) (#38348)
mergify[bot] Nov 26, 2023
cda5ff4
refactor: bank transaction (#38182)
mergify[bot] Nov 26, 2023
3cbe599
fix(ux): Sales Order Stock Reservation Dialog (backport #38261) (#38344)
mergify[bot] Nov 26, 2023
85bd649
refactor: validate reposting settings for editables inv
GursheenK Nov 13, 2023
6a3c3b4
fix: do not set repost flag without validating voucher
GursheenK Nov 13, 2023
ac7615a
fix: allow on submit for child table fields
GursheenK Nov 13, 2023
25bf475
fix: check reposting settings before allowing editable si
GursheenK Nov 13, 2023
378dc50
chore: resolve conflict
ruthra-kumar Nov 27, 2023
5d993d4
Merge pull request #38356 from frappe/mergify/bp/version-15-hotfix/pr…
ruthra-kumar Nov 27, 2023
14174df
fix: Negative Qty and Rates in SO/PO (backport #38252) (#38357)
mergify[bot] Nov 27, 2023
4699887
fix: Payment Reco Issue and chart of account importer
mergify[bot] Nov 27, 2023
8564d58
refactor: handle rounding loss on AR/AP reports
ruthra-kumar Nov 27, 2023
7385db0
Merge pull request #38359 from frappe/mergify/bp/version-15-hotfix/pr…
ruthra-kumar Nov 27, 2023
721b429
fix: make parameters of `create_subscription_process` optional (and o…
sagarvora Nov 27, 2023
8c906b4
Merge pull request #38366 from frappe/mergify/bp/version-15-hotfix/pr…
sagarvora Nov 27, 2023
a6f3a10
chore: fix flaky test case (backport #38369) (#38373)
mergify[bot] Nov 28, 2023
922aef6
fix: Server Error while creating Product Bundle (backport #38377) (#3…
mergify[bot] Nov 28, 2023
573c4d2
chore: fix imports for renamed report
GursheenK Nov 28, 2023
b65c225
fix: serial no status (backport #38391) (#38397)
mergify[bot] Nov 28, 2023
33b3355
Merge pull request #38396 from frappe/mergify/bp/version-15-hotfix/pr…
GursheenK Nov 28, 2023
b1b065d
fix: create contact if existing customer doesn't have contact
shariquerik Nov 28, 2023
9f87374
Merge pull request #38400 from frappe/mergify/bp/version-15-hotfix/pr…
shariquerik Nov 28, 2023
c101855
fix: no fstring in translation (backport #38381) (#38387)
mergify[bot] Nov 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,9 @@ def reconcile_vouchers(bank_transaction_name, vouchers):
vouchers = json.loads(vouchers)
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
transaction.add_payment_entries(vouchers)
return frappe.get_doc("Bank Transaction", bank_transaction_name)
transaction.save()

return transaction


@frappe.whitelist()
Expand Down
17 changes: 13 additions & 4 deletions erpnext/accounts/doctype/bank_transaction/bank_transaction.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"status",
"bank_account",
"company",
"amended_from",
"section_break_4",
"deposit",
"withdrawal",
Expand All @@ -25,10 +26,10 @@
"transaction_id",
"transaction_type",
"section_break_14",
"column_break_oufv",
"payment_entries",
"section_break_18",
"allocated_amount",
"amended_from",
"column_break_17",
"unallocated_amount",
"party_section",
Expand Down Expand Up @@ -138,10 +139,12 @@
"fieldtype": "Section Break"
},
{
"allow_on_submit": 1,
"fieldname": "allocated_amount",
"fieldtype": "Currency",
"label": "Allocated Amount",
"options": "currency"
"options": "currency",
"read_only": 1
},
{
"fieldname": "amended_from",
Expand All @@ -157,10 +160,12 @@
"fieldtype": "Column Break"
},
{
"allow_on_submit": 1,
"fieldname": "unallocated_amount",
"fieldtype": "Currency",
"label": "Unallocated Amount",
"options": "currency"
"options": "currency",
"read_only": 1
},
{
"fieldname": "party_section",
Expand Down Expand Up @@ -225,11 +230,15 @@
"fieldname": "bank_party_account_number",
"fieldtype": "Data",
"label": "Party Account No. (Bank Statement)"
},
{
"fieldname": "column_break_oufv",
"fieldtype": "Column Break"
}
],
"is_submittable": 1,
"links": [],
"modified": "2023-06-06 13:58:12.821411",
"modified": "2023-11-18 18:32:47.203694",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Transaction",
Expand Down
139 changes: 61 additions & 78 deletions erpnext/accounts/doctype/bank_transaction/bank_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,73 @@
# For license information, please see license.txt

import frappe
from frappe import _
from frappe.utils import flt

from erpnext.controllers.status_updater import StatusUpdater


class BankTransaction(StatusUpdater):
def after_insert(self):
self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit))
def before_validate(self):
self.update_allocated_amount()

def on_submit(self):
self.clear_linked_payment_entries()
def validate(self):
self.validate_duplicate_references()

def validate_duplicate_references(self):
"""Make sure the same voucher is not allocated twice within the same Bank Transaction"""
if not self.payment_entries:
return

pe = []
for row in self.payment_entries:
reference = (row.payment_document, row.payment_entry)
if reference in pe:
frappe.throw(
_("{0} {1} is allocated twice in this Bank Transaction").format(
row.payment_document, row.payment_entry
)
)
pe.append(reference)

def update_allocated_amount(self):
self.allocated_amount = (
sum(p.allocated_amount for p in self.payment_entries) if self.payment_entries else 0.0
)
self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) - self.allocated_amount

def before_submit(self):
self.allocate_payment_entries()
self.set_status()

if frappe.db.get_single_value("Accounts Settings", "enable_party_matching"):
self.auto_set_party()

_saving_flag = False

# nosemgrep: frappe-semgrep-rules.rules.frappe-modifying-but-not-comitting
def on_update_after_submit(self):
"Run on save(). Avoid recursion caused by multiple saves"
if not self._saving_flag:
self._saving_flag = True
self.clear_linked_payment_entries()
self.update_allocations()
self._saving_flag = False
def before_update_after_submit(self):
self.validate_duplicate_references()
self.allocate_payment_entries()
self.update_allocated_amount()

def on_cancel(self):
self.clear_linked_payment_entries(for_cancel=True)
self.set_status(update=True)

def update_allocations(self):
"The doctype does not allow modifications after submission, so write to the db direct"
if self.payment_entries:
allocated_amount = sum(p.allocated_amount for p in self.payment_entries)
else:
allocated_amount = 0.0
for payment_entry in self.payment_entries:
self.clear_linked_payment_entry(payment_entry, for_cancel=True)

amount = abs(flt(self.withdrawal) - flt(self.deposit))
self.db_set("allocated_amount", flt(allocated_amount))
self.db_set("unallocated_amount", amount - flt(allocated_amount))
self.reload()
self.set_status(update=True)

def add_payment_entries(self, vouchers):
"Add the vouchers with zero allocation. Save() will perform the allocations and clearance"
if 0.0 >= self.unallocated_amount:
frappe.throw(frappe._("Bank Transaction {0} is already fully reconciled").format(self.name))
frappe.throw(_("Bank Transaction {0} is already fully reconciled").format(self.name))

added = False
for voucher in vouchers:
# Can't add same voucher twice
found = False
for pe in self.payment_entries:
if (
pe.payment_document == voucher["payment_doctype"]
and pe.payment_entry == voucher["payment_name"]
):
found = True

if not found:
pe = {
self.append(
"payment_entries",
{
"payment_document": voucher["payment_doctype"],
"payment_entry": voucher["payment_name"],
"allocated_amount": 0.0, # Temporary
}
child = self.append("payment_entries", pe)
added = True

# runs on_update_after_submit
if added:
self.save()
},
)

def allocate_payment_entries(self):
"""Refactored from bank reconciliation tool.
Expand All @@ -90,6 +85,7 @@ def allocate_payment_entries(self):
- clear means: set the latest transaction date as clearance date
"""
remaining_amount = self.unallocated_amount
to_remove = []
for payment_entry in self.payment_entries:
if payment_entry.allocated_amount == 0.0:
unallocated_amount, should_clear, latest_transaction = get_clearance_details(
Expand All @@ -99,49 +95,39 @@ def allocate_payment_entries(self):
if 0.0 == unallocated_amount:
if should_clear:
latest_transaction.clear_linked_payment_entry(payment_entry)
self.db_delete_payment_entry(payment_entry)
to_remove.append(payment_entry)

elif remaining_amount <= 0.0:
self.db_delete_payment_entry(payment_entry)
to_remove.append(payment_entry)

elif 0.0 < unallocated_amount and unallocated_amount <= remaining_amount:
payment_entry.db_set("allocated_amount", unallocated_amount)
elif 0.0 < unallocated_amount <= remaining_amount:
payment_entry.allocated_amount = unallocated_amount
remaining_amount -= unallocated_amount
if should_clear:
latest_transaction.clear_linked_payment_entry(payment_entry)

elif 0.0 < unallocated_amount and unallocated_amount > remaining_amount:
payment_entry.db_set("allocated_amount", remaining_amount)
elif 0.0 < unallocated_amount:
payment_entry.allocated_amount = remaining_amount
remaining_amount = 0.0

elif 0.0 > unallocated_amount:
self.db_delete_payment_entry(payment_entry)
frappe.throw(frappe._("Voucher {0} is over-allocated by {1}").format(unallocated_amount))

self.reload()
frappe.throw(_("Voucher {0} is over-allocated by {1}").format(unallocated_amount))

def db_delete_payment_entry(self, payment_entry):
frappe.db.delete("Bank Transaction Payments", {"name": payment_entry.name})
for payment_entry in to_remove:
self.remove(to_remove)

@frappe.whitelist()
def remove_payment_entries(self):
for payment_entry in self.payment_entries:
self.remove_payment_entry(payment_entry)
# runs on_update_after_submit
self.save()

self.save() # runs before_update_after_submit

def remove_payment_entry(self, payment_entry):
"Clear payment entry and clearance"
self.clear_linked_payment_entry(payment_entry, for_cancel=True)
self.remove(payment_entry)

def clear_linked_payment_entries(self, for_cancel=False):
if for_cancel:
for payment_entry in self.payment_entries:
self.clear_linked_payment_entry(payment_entry, for_cancel)
else:
self.allocate_payment_entries()

def clear_linked_payment_entry(self, payment_entry, for_cancel=False):
clearance_date = None if for_cancel else self.date
set_voucher_clearance(
Expand All @@ -162,11 +148,10 @@ def auto_set_party(self):
deposit=self.deposit,
).match()

if result:
party_type, party = result
frappe.db.set_value(
"Bank Transaction", self.name, field={"party_type": party_type, "party": party}
)
if not result:
return

self.party_type, self.party = result


@frappe.whitelist()
Expand Down Expand Up @@ -198,9 +183,7 @@ def get_clearance_details(transaction, payment_entry):
if gle["gl_account"] == gl_bank_account:
if gle["amount"] <= 0.0:
frappe.throw(
frappe._("Voucher {0} value is broken: {1}").format(
payment_entry.payment_entry, gle["amount"]
)
_("Voucher {0} value is broken: {1}").format(payment_entry.payment_entry, gle["amount"])
)

unmatched_gles -= 1
Expand All @@ -221,7 +204,7 @@ def get_clearance_details(transaction, payment_entry):

def get_related_bank_gl_entries(doctype, docname):
# nosemgrep: frappe-semgrep-rules.rules.frappe-using-db-sql
result = frappe.db.sql(
return frappe.db.sql(
"""
SELECT
ABS(gle.credit_in_account_currency - gle.debit_in_account_currency) AS amount,
Expand All @@ -239,7 +222,6 @@ def get_related_bank_gl_entries(doctype, docname):
dict(doctype=doctype, docname=docname),
as_dict=True,
)
return result


def get_total_allocated_amount(doctype, docname):
Expand Down Expand Up @@ -365,6 +347,7 @@ def set_voucher_clearance(doctype, docname, clearance_date, self):
if clearance_date:
vouchers = [{"payment_doctype": "Bank Transaction", "payment_name": self.name}]
bt.add_payment_entries(vouchers)
bt.save()
else:
for pe in bt.payment_entries:
if pe.payment_document == self.doctype and pe.payment_entry == self.name:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def generate_data_from_csv(file_doc, as_dict=False):
if as_dict:
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
else:
if not row[1]:
if not row[1] and len(row) > 1:
row[1] = row[0]
row[3] = row[2]
data.append(row)
Expand Down
2 changes: 1 addition & 1 deletion erpnext/accounts/doctype/journal_entry/journal_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ frappe.ui.form.on("Journal Entry", {
}, __('Make'));
}

erpnext.accounts.unreconcile_payments.add_unreconcile_btn(frm);
erpnext.accounts.unreconcile_payment.add_unreconcile_btn(frm);
},
before_save: function(frm) {
if ((frm.doc.docstatus == 0) && (!frm.doc.is_system_generated)) {
Expand Down
12 changes: 10 additions & 2 deletions erpnext/accounts/doctype/journal_entry/journal_entry.json
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,16 @@
"icon": "fa fa-file-text",
"idx": 176,
"is_submittable": 1,
"links": [],
"modified": "2023-08-10 14:32:22.366895",
"links": [
{
"is_child_table": 1,
"link_doctype": "Bank Transaction Payments",
"link_fieldname": "payment_entry",
"parent_doctype": "Bank Transaction",
"table_fieldname": "payment_entries"
}
],
"modified": "2023-11-23 12:11:04.128015",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry",
Expand Down
4 changes: 2 additions & 2 deletions erpnext/accounts/doctype/journal_entry/journal_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ def validate_against_jv(self):
).format(d.reference_name, d.account)
)
else:
dr_or_cr = "debit" if d.credit > 0 else "credit"
dr_or_cr = "debit" if flt(d.credit) > 0 else "credit"
valid = False
for jvd in against_entries:
if flt(jvd[dr_or_cr]) > 0:
Expand Down Expand Up @@ -868,7 +868,7 @@ def set_print_format_fields(self):
party_account_currency = d.account_currency

elif frappe.get_cached_value("Account", d.account, "account_type") in ["Bank", "Cash"]:
bank_amount += d.debit_in_account_currency or d.credit_in_account_currency
bank_amount += flt(d.debit_in_account_currency) or flt(d.credit_in_account_currency)
bank_account_currency = d.account_currency

if party_type and pay_to_recd_from:
Expand Down
Loading
Loading