Skip to content

Commit

Permalink
Merge pull request #35665 from frappe/version-13-hotfix
Browse files Browse the repository at this point in the history
chore: release v13
  • Loading branch information
deepeshgarg007 committed Jun 14, 2023
2 parents f182fc1 + c2bf8e3 commit e75ca14
Show file tree
Hide file tree
Showing 19 changed files with 312 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"submit_journal_entries",
"print_settings",
"show_inclusive_tax_in_print",
"show_taxes_as_table_in_print",
"column_break_12",
"show_payment_schedule_in_print",
"currency_exchange_section",
Expand Down Expand Up @@ -293,14 +294,20 @@
"fieldname": "book_tax_discount_loss",
"fieldtype": "Check",
"label": "Book Tax Loss on Early Payment Discount"
},
{
"default": "0",
"fieldname": "show_taxes_as_table_in_print",
"fieldtype": "Check",
"label": "Show Taxes as Table in Print"
}
],
"icon": "icon-cog",
"idx": 1,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2023-04-14 17:22:03.680886",
"modified": "2023-06-13 18:47:46.430291",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
Expand Down
68 changes: 56 additions & 12 deletions erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,57 @@ def validate_payment_type_with_outstanding(self):
)

def validate_allocated_amount(self):
for d in self.get("references"):
if self.payment_type == "Internal Transfer" or self.party_type in ("Donor"):
return

latest_references = get_outstanding_reference_documents(
{
"posting_date": self.posting_date,
"company": self.company,
"party_type": self.party_type,
"payment_type": self.payment_type,
"party": self.party,
"party_account": self.paid_from if self.payment_type == "Receive" else self.paid_to,
}
)

# Group latest_references by (voucher_type, voucher_no)
latest_lookup = {}
for d in latest_references:
d = frappe._dict(d)
latest_lookup.update({(d.voucher_type, d.voucher_no): d})

for d in self.get("references").copy():
latest = latest_lookup.get((d.reference_doctype, d.reference_name))

# The reference has already been fully paid
if not latest:
frappe.throw(
_("{0} {1} has already been fully paid.").format(d.reference_doctype, d.reference_name)
)
# The reference has already been partly paid
elif (
latest.outstanding_amount < latest.invoice_amount
and d.outstanding_amount != latest.outstanding_amount
):
frappe.throw(
_(
"{0} {1} has already been partly paid. Please use the 'Get Outstanding Invoice' button to get the latest outstanding amount."
).format(d.reference_doctype, d.reference_name)
)

d.outstanding_amount = latest.outstanding_amount

fail_message = _("Row #{0}: Allocated Amount cannot be greater than outstanding amount.")

if (flt(d.allocated_amount)) > 0:
if flt(d.allocated_amount) > flt(d.outstanding_amount):
frappe.throw(
_("Row #{0}: Allocated Amount cannot be greater than outstanding amount.").format(d.idx)
)
frappe.throw(fail_message.format(d.idx))

# Check for negative outstanding invoices as well
if flt(d.allocated_amount) < 0:
if flt(d.allocated_amount) < flt(d.outstanding_amount):
frappe.throw(
_("Row #{0}: Allocated Amount cannot be greater than outstanding amount.").format(d.idx)
)
frappe.throw(fail_message.format(d.idx))

def delink_advance_entry_references(self):
for reference in self.references:
Expand Down Expand Up @@ -391,7 +429,7 @@ def validate_paid_invoices(self):
for k, v in no_oustanding_refs.items():
frappe.msgprint(
_(
"{} - {} now have {} as they had no outstanding amount left before submitting the Payment Entry."
"{} - {} now has {} as it had no outstanding amount left before submitting the Payment Entry."
).format(
_(k),
frappe.bold(", ".join(d.reference_name for d in v)),
Expand Down Expand Up @@ -1457,7 +1495,7 @@ def get_orders_to_be_billed(
if voucher_type:
doc = frappe.get_doc({"doctype": voucher_type})
condition = ""
if doc and hasattr(doc, "cost_center"):
if doc and hasattr(doc, "cost_center") and doc.cost_center:
condition = " and cost_center='%s'" % cost_center

orders = []
Expand Down Expand Up @@ -1503,9 +1541,15 @@ def get_orders_to_be_billed(

order_list = []
for d in orders:
if not (
flt(d.outstanding_amount) >= flt(filters.get("outstanding_amt_greater_than"))
and flt(d.outstanding_amount) <= flt(filters.get("outstanding_amt_less_than"))
if (
filters
and filters.get("outstanding_amt_greater_than")
and filters.get("outstanding_amt_less_than")
and not (
flt(filters.get("outstanding_amt_greater_than"))
<= flt(d.outstanding_amount)
<= flt(filters.get("outstanding_amt_less_than"))
)
):
continue

Expand Down
24 changes: 24 additions & 0 deletions erpnext/accounts/doctype/payment_entry/test_payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,30 @@ def test_payment_entry_against_onhold_purchase_invoice(self):

self.assertTrue("is on hold" in str(err.exception).lower())

def test_duplicate_payment_entry_allocate_amount(self):
si = create_sales_invoice()

pe_draft = get_payment_entry("Sales Invoice", si.name)
pe_draft.insert()

pe = get_payment_entry("Sales Invoice", si.name)
pe.submit()

self.assertRaises(frappe.ValidationError, pe_draft.submit)

def test_duplicate_payment_entry_partial_allocate_amount(self):
si = create_sales_invoice()

pe_draft = get_payment_entry("Sales Invoice", si.name)
pe_draft.insert()

pe = get_payment_entry("Sales Invoice", si.name)
pe.received_amount = si.total / 2
pe.references[0].allocated_amount = si.total / 2
pe.submit()

self.assertRaises(frappe.ValidationError, pe_draft.submit)


def create_payment_entry(**args):
payment_entry = frappe.new_doc("Payment Entry")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import cint, getdate
from frappe.utils import cint, flt, getdate


class TaxWithholdingCategory(Document):
Expand Down Expand Up @@ -520,8 +520,13 @@ def get_tds_amount_from_ldc(ldc, parties, pan_no, tax_details, posting_date, net
tds_amount = 0
limit_consumed = frappe.db.get_value(
"Purchase Invoice",
{"supplier": ("in", parties), "apply_tds": 1, "docstatus": 1},
"sum(net_total)",
{
"supplier": ("in", parties),
"apply_tds": 1,
"docstatus": 1,
"posting_date": ("between", (ldc.valid_from, ldc.valid_upto)),
},
"sum(tax_withholding_net_total)",
)

if is_valid_certificate(
Expand All @@ -535,10 +540,10 @@ def get_tds_amount_from_ldc(ldc, parties, pan_no, tax_details, posting_date, net


def get_ltds_amount(current_amount, deducted_amount, certificate_limit, rate, tax_details):
if current_amount < (certificate_limit - deducted_amount):
if certificate_limit - flt(deducted_amount) - flt(current_amount) >= 0:
return current_amount * rate / 100
else:
ltds_amount = certificate_limit - deducted_amount
ltds_amount = certificate_limit - flt(deducted_amount)
tds_amount = current_amount - ltds_amount

return ltds_amount * rate / 100 + tds_amount * tax_details.rate / 100
Expand All @@ -549,9 +554,9 @@ def is_valid_certificate(
):
valid = False

if (
getdate(valid_from) <= getdate(posting_date) <= getdate(valid_upto)
) and certificate_limit > deducted_amount:
available_amount = flt(certificate_limit) - flt(deducted_amount) - flt(current_amount)

if (getdate(valid_from) <= getdate(posting_date) <= getdate(valid_upto)) and available_amount > 0:
valid = True

return valid
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
{
"add_total_row": 0,
"apply_user_permissions": 1,
"creation": "2016-04-08 14:49:58.133098",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 2,
"is_standard": "Yes",
"modified": "2017-02-24 20:08:26.084484",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Asset Depreciation Ledger",
"owner": "Administrator",
"ref_doctype": "Asset",
"report_name": "Asset Depreciation Ledger",
"report_type": "Script Report",
"add_total_row": 1,
"columns": [],
"creation": "2016-04-08 14:49:58.133098",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 2,
"is_standard": "Yes",
"modified": "2023-06-06 09:00:07.435151",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Asset Depreciation Ledger",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Asset",
"report_name": "Asset Depreciation Ledger",
"report_type": "Script Report",
"roles": [
{
"role": "Accounts User"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
{
"add_total_row": 0,
"apply_user_permissions": 1,
"creation": "2016-04-08 14:56:37.235981",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 2,
"is_standard": "Yes",
"modified": "2017-02-24 20:08:18.660476",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Asset Depreciations and Balances",
"owner": "Administrator",
"ref_doctype": "Asset",
"report_name": "Asset Depreciations and Balances",
"report_type": "Script Report",
"add_total_row": 1,
"columns": [],
"creation": "2016-04-08 14:56:37.235981",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 2,
"is_standard": "Yes",
"modified": "2023-06-06 11:33:29.611277",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Asset Depreciations and Balances",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Asset",
"report_name": "Asset Depreciations and Balances",
"report_type": "Script Report",
"roles": [
{
"role": "Accounts User"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,9 @@ def get_items(filters, additional_query_columns, additional_conditions=None):
`tabSales Invoice`.posting_date, `tabSales Invoice`.debit_to,
`tabSales Invoice`.unrealized_profit_loss_account,
`tabSales Invoice`.is_internal_customer,
`tabSales Invoice`.project, `tabSales Invoice`.customer, `tabSales Invoice`.remarks,
`tabSales Invoice`.customer, `tabSales Invoice`.remarks,
`tabSales Invoice`.territory, `tabSales Invoice`.company, `tabSales Invoice`.base_net_total,
`tabSales Invoice Item`.project,
`tabSales Invoice Item`.item_code, `tabSales Invoice Item`.description,
`tabSales Invoice Item`.`item_name`, `tabSales Invoice Item`.`item_group`,
`tabSales Invoice Item`.sales_order, `tabSales Invoice Item`.delivery_note,
Expand Down
27 changes: 21 additions & 6 deletions erpnext/assets/doctype/asset/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from erpnext.assets.doctype.asset.depreciation import (
get_depreciation_accounts,
get_disposal_account_and_cost_center,
is_first_day_of_the_month,
is_last_day_of_the_month,
)
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
Expand Down Expand Up @@ -364,8 +365,14 @@ def make_depreciation_schedule(self, date_of_disposal):
break

# For first row
if n == 0 and has_pro_rata and not self.opening_accumulated_depreciation:
from_date = add_days(self.available_for_use_date, -1)
if (
n == 0
and (has_pro_rata or has_wdv_or_dd_non_yearly_pro_rata)
and not self.opening_accumulated_depreciation
):
from_date = add_days(
self.available_for_use_date, -1
) # needed to calc depr amount for available_for_use_date too
depreciation_amount, days, months = self.get_pro_rata_amt(
finance_book,
depreciation_amount,
Expand All @@ -374,10 +381,18 @@ def make_depreciation_schedule(self, date_of_disposal):
has_wdv_or_dd_non_yearly_pro_rata,
)
elif n == 0 and has_wdv_or_dd_non_yearly_pro_rata and self.opening_accumulated_depreciation:
from_date = add_months(
getdate(self.available_for_use_date),
(self.number_of_depreciations_booked * finance_book.frequency_of_depreciation),
)
if not is_first_day_of_the_month(getdate(self.available_for_use_date)):
from_date = get_last_day(
add_months(
getdate(self.available_for_use_date),
((self.number_of_depreciations_booked - 1) * finance_book.frequency_of_depreciation),
)
)
else:
from_date = add_months(
getdate(add_days(self.available_for_use_date, -1)),
(self.number_of_depreciations_booked * finance_book.frequency_of_depreciation),
)
depreciation_amount, days, months = self.get_pro_rata_amt(
finance_book,
depreciation_amount,
Expand Down
7 changes: 7 additions & 0 deletions erpnext/assets/doctype/asset/depreciation.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
add_months,
cint,
flt,
get_first_day,
get_last_day,
get_link_to_form,
getdate,
Expand Down Expand Up @@ -543,3 +544,9 @@ def is_last_day_of_the_month(date):
last_day_of_the_month = get_last_day(date)

return getdate(last_day_of_the_month) == getdate(date)


def is_first_day_of_the_month(date):
first_day_of_the_month = get_first_day(date)

return getdate(first_day_of_the_month) == getdate(date)
4 changes: 2 additions & 2 deletions erpnext/assets/doctype/asset/test_asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -686,14 +686,14 @@ def test_schedule_for_double_declining_method_for_existing_asset(self):
number_of_depreciations_booked=1,
opening_accumulated_depreciation=50000,
expected_value_after_useful_life=10000,
depreciation_start_date="2030-12-31",
depreciation_start_date="2031-12-31",
total_number_of_depreciations=3,
frequency_of_depreciation=12,
)

self.assertEqual(asset.status, "Draft")

expected_schedules = [["2030-12-31", 33333.50, 83333.50], ["2031-12-31", 6666.50, 90000.0]]
expected_schedules = [["2031-12-31", 33333.50, 83333.50], ["2032-12-31", 6666.50, 90000.0]]

schedules = [
[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
Expand Down
3 changes: 3 additions & 0 deletions erpnext/controllers/accounts_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,9 @@ def is_inclusive_tax(self):

return is_inclusive

def should_show_taxes_as_table_in_print(self):
return cint(frappe.db.get_single_value("Accounts Settings", "show_taxes_as_table_in_print"))

def validate_advance_entries(self):
order_field = "sales_order" if self.doctype == "Sales Invoice" else "purchase_order"
order_list = list(set(d.get(order_field) for d in self.get("items") if d.get(order_field)))
Expand Down
Loading

0 comments on commit e75ca14

Please sign in to comment.