Merge branch 'develop' into fix-22-23-05686

This commit is contained in:
Sagar Sharma 2023-03-14 11:44:39 +05:30 committed by GitHub
commit 6c88fb7a8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 102 additions and 81 deletions

View File

@ -15,7 +15,7 @@
</div> </div>
<h2 class="text-center">{{ _("STATEMENTS OF ACCOUNTS") }}</h2> <h2 class="text-center">{{ _("STATEMENTS OF ACCOUNTS") }}</h2>
<div> <div>
<h5 style="float: left;">{{ _("Customer: ") }} <b>{{filters.party[0] }}</b></h5> <h5 style="float: left;">{{ _("Customer: ") }} <b>{{filters.party_name[0] }}</b></h5>
<h5 style="float: right;"> <h5 style="float: right;">
{{ _("Date: ") }} {{ _("Date: ") }}
<b>{{ frappe.format(filters.from_date, 'Date')}} <b>{{ frappe.format(filters.from_date, 'Date')}}

View File

@ -24,7 +24,7 @@ from erpnext.accounts.report.general_ledger.general_ledger import execute as get
class ProcessStatementOfAccounts(Document): class ProcessStatementOfAccounts(Document):
def validate(self): def validate(self):
if not self.subject: if not self.subject:
self.subject = "Statement Of Accounts for {{ customer.name }}" self.subject = "Statement Of Accounts for {{ customer.customer_name }}"
if not self.body: if not self.body:
self.body = "Hello {{ customer.name }},<br>PFA your Statement Of Accounts from {{ doc.from_date }} to {{ doc.to_date }}." self.body = "Hello {{ customer.name }},<br>PFA your Statement Of Accounts from {{ doc.from_date }} to {{ doc.to_date }}."
@ -87,6 +87,7 @@ def get_report_pdf(doc, consolidated=True):
"account": [doc.account] if doc.account else None, "account": [doc.account] if doc.account else None,
"party_type": "Customer", "party_type": "Customer",
"party": [entry.customer], "party": [entry.customer],
"party_name": [entry.customer_name] if entry.customer_name else None,
"presentation_currency": presentation_currency, "presentation_currency": presentation_currency,
"group_by": doc.group_by, "group_by": doc.group_by,
"currency": doc.currency, "currency": doc.currency,
@ -156,7 +157,7 @@ def get_customers_based_on_territory_or_customer_group(customer_collection, coll
] ]
return frappe.get_list( return frappe.get_list(
"Customer", "Customer",
fields=["name", "email_id"], fields=["name", "customer_name", "email_id"],
filters=[[fields_dict[customer_collection], "IN", selected]], filters=[[fields_dict[customer_collection], "IN", selected]],
) )
@ -179,7 +180,7 @@ def get_customers_based_on_sales_person(sales_person):
if sales_person_records.get("Customer"): if sales_person_records.get("Customer"):
return frappe.get_list( return frappe.get_list(
"Customer", "Customer",
fields=["name", "email_id"], fields=["name", "customer_name", "email_id"],
filters=[["name", "in", list(sales_person_records["Customer"])]], filters=[["name", "in", list(sales_person_records["Customer"])]],
) )
else: else:
@ -228,7 +229,7 @@ def fetch_customers(customer_collection, collection_name, primary_mandatory):
if customer_collection == "Sales Partner": if customer_collection == "Sales Partner":
customers = frappe.get_list( customers = frappe.get_list(
"Customer", "Customer",
fields=["name", "email_id"], fields=["name", "customer_name", "email_id"],
filters=[["default_sales_partner", "=", collection_name]], filters=[["default_sales_partner", "=", collection_name]],
) )
else: else:
@ -245,7 +246,12 @@ def fetch_customers(customer_collection, collection_name, primary_mandatory):
continue continue
customer_list.append( customer_list.append(
{"name": customer.name, "primary_email": primary_email, "billing_email": billing_email} {
"name": customer.name,
"customer_name": customer.customer_name,
"primary_email": primary_email,
"billing_email": billing_email,
}
) )
return customer_list return customer_list

View File

@ -1,12 +1,12 @@
{ {
"actions": [], "actions": [],
"allow_workflow": 1,
"creation": "2020-08-03 16:35:21.852178", "creation": "2020-08-03 16:35:21.852178",
"doctype": "DocType", "doctype": "DocType",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [ "field_order": [
"customer", "customer",
"customer_name",
"billing_email", "billing_email",
"primary_email" "primary_email"
], ],
@ -30,11 +30,18 @@
"fieldtype": "Read Only", "fieldtype": "Read Only",
"in_list_view": 1, "in_list_view": 1,
"label": "Billing Email" "label": "Billing Email"
},
{
"fetch_from": "customer.customer_name",
"fieldname": "customer_name",
"fieldtype": "Data",
"label": "Customer Name",
"read_only": 1
} }
], ],
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2020-08-03 22:55:38.875601", "modified": "2023-03-13 00:12:34.508086",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Process Statement Of Accounts Customer", "name": "Process Statement Of Accounts Customer",
@ -43,5 +50,6 @@
"quick_entry": 1, "quick_entry": 1,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"states": [],
"track_changes": 1 "track_changes": 1
} }

View File

@ -32,9 +32,6 @@
"cost_center", "cost_center",
"dimension_col_break", "dimension_col_break",
"project", "project",
"column_break_27",
"campaign",
"source",
"currency_and_price_list", "currency_and_price_list",
"currency", "currency",
"conversion_rate", "conversion_rate",
@ -203,7 +200,9 @@
"more_information", "more_information",
"status", "status",
"inter_company_invoice_reference", "inter_company_invoice_reference",
"campaign",
"represents_company", "represents_company",
"source",
"customer_group", "customer_group",
"col_break23", "col_break23",
"is_internal_customer", "is_internal_customer",
@ -2083,10 +2082,6 @@
"fieldname": "company_addr_col_break", "fieldname": "company_addr_col_break",
"fieldtype": "Column Break" "fieldtype": "Column Break"
}, },
{
"fieldname": "column_break_27",
"fieldtype": "Column Break"
},
{ {
"fieldname": "column_break_52", "fieldname": "column_break_52",
"fieldtype": "Column Break" "fieldtype": "Column Break"
@ -2143,11 +2138,10 @@
"link_fieldname": "consolidated_invoice" "link_fieldname": "consolidated_invoice"
} }
], ],
"modified": "2023-01-28 19:45:47.538163", "modified": "2023-03-13 11:43:15.883055",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Sales Invoice", "name": "Sales Invoice",
"name_case": "Title Case",
"naming_rule": "By \"Naming Series\" field", "naming_rule": "By \"Naming Series\" field",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [

View File

@ -266,16 +266,16 @@ class TestSalesInvoice(unittest.TestCase):
"_Test Account Education Cess - _TC": [3, 1618, 0.06, 32.36], "_Test Account Education Cess - _TC": [3, 1618, 0.06, 32.36],
"_Test Account S&H Education Cess - _TC": [1.5, 1619.5, 0.03, 32.39], "_Test Account S&H Education Cess - _TC": [1.5, 1619.5, 0.03, 32.39],
"_Test Account CST - _TC": [32.5, 1652, 0.65, 33.04], "_Test Account CST - _TC": [32.5, 1652, 0.65, 33.04],
"_Test Account VAT - _TC": [156.5, 1808.5, 3.13, 36.17], "_Test Account VAT - _TC": [156.0, 1808.0, 3.12, 36.16],
"_Test Account Discount - _TC": [-181.0, 1627.5, -3.62, 32.55], "_Test Account Discount - _TC": [-181.0, 1627.0, -3.62, 32.54],
} }
for d in si.get("taxes"): for d in si.get("taxes"):
for i, k in enumerate(expected_values["keys"]): for i, k in enumerate(expected_values["keys"]):
self.assertEqual(d.get(k), expected_values[d.account_head][i]) self.assertEqual(d.get(k), expected_values[d.account_head][i])
self.assertEqual(si.base_grand_total, 1627.5) self.assertEqual(si.base_grand_total, 1627.0)
self.assertEqual(si.grand_total, 32.55) self.assertEqual(si.grand_total, 32.54)
def test_sales_invoice_with_discount_and_inclusive_tax(self): def test_sales_invoice_with_discount_and_inclusive_tax(self):
si = create_sales_invoice(qty=100, rate=50, do_not_save=True) si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
@ -401,10 +401,10 @@ class TestSalesInvoice(unittest.TestCase):
"_Test Account S&H Education Cess - _TC": [1.4, 1.30, 1297.67], "_Test Account S&H Education Cess - _TC": [1.4, 1.30, 1297.67],
"_Test Account CST - _TC": [27.88, 25.95, 1323.62], "_Test Account CST - _TC": [27.88, 25.95, 1323.62],
"_Test Account VAT - _TC": [156.25, 145.43, 1469.05], "_Test Account VAT - _TC": [156.25, 145.43, 1469.05],
"_Test Account Customs Duty - _TC": [125, 116.35, 1585.40], "_Test Account Customs Duty - _TC": [125, 116.34, 1585.39],
"_Test Account Shipping Charges - _TC": [100, 100, 1685.40], "_Test Account Shipping Charges - _TC": [100, 100, 1685.39],
"_Test Account Discount - _TC": [-180.33, -168.54, 1516.86], "_Test Account Discount - _TC": [-180.33, -168.54, 1516.85],
"_Test Account Service Tax - _TC": [-18.03, -16.85, 1500.01], "_Test Account Service Tax - _TC": [-18.03, -16.85, 1500.00],
} }
for d in si.get("taxes"): for d in si.get("taxes"):
@ -413,7 +413,7 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEqual(si.base_grand_total, 1500) self.assertEqual(si.base_grand_total, 1500)
self.assertEqual(si.grand_total, 1500) self.assertEqual(si.grand_total, 1500)
self.assertEqual(si.rounding_adjustment, -0.01) self.assertEqual(si.rounding_adjustment, 0.0)
def test_discount_amount_gl_entry(self): def test_discount_amount_gl_entry(self):
frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC") frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC")
@ -454,7 +454,7 @@ class TestSalesInvoice(unittest.TestCase):
[test_records[3]["taxes"][2]["account_head"], 0.0, 1.30], [test_records[3]["taxes"][2]["account_head"], 0.0, 1.30],
[test_records[3]["taxes"][3]["account_head"], 0.0, 25.95], [test_records[3]["taxes"][3]["account_head"], 0.0, 25.95],
[test_records[3]["taxes"][4]["account_head"], 0.0, 145.43], [test_records[3]["taxes"][4]["account_head"], 0.0, 145.43],
[test_records[3]["taxes"][5]["account_head"], 0.0, 116.35], [test_records[3]["taxes"][5]["account_head"], 0.0, 116.34],
[test_records[3]["taxes"][6]["account_head"], 0.0, 100], [test_records[3]["taxes"][6]["account_head"], 0.0, 100],
[test_records[3]["taxes"][7]["account_head"], 168.54, 0.0], [test_records[3]["taxes"][7]["account_head"], 168.54, 0.0],
["_Test Account Service Tax - _TC", 16.85, 0.0], ["_Test Account Service Tax - _TC", 16.85, 0.0],
@ -1614,7 +1614,7 @@ class TestSalesInvoice(unittest.TestCase):
"_Test Account Education Cess - _TC": [1.4, 1.4, 1.4], "_Test Account Education Cess - _TC": [1.4, 1.4, 1.4],
"_Test Account S&H Education Cess - _TC": [0.7, 0.7, 0.7], "_Test Account S&H Education Cess - _TC": [0.7, 0.7, 0.7],
"_Test Account CST - _TC": [17.19, 17.19, 17.19], "_Test Account CST - _TC": [17.19, 17.19, 17.19],
"_Test Account VAT - _TC": [78.13, 78.13, 78.13], "_Test Account VAT - _TC": [78.12, 78.12, 78.12],
"_Test Account Discount - _TC": [-95.49, -95.49, -95.49], "_Test Account Discount - _TC": [-95.49, -95.49, -95.49],
} }
@ -1623,9 +1623,9 @@ class TestSalesInvoice(unittest.TestCase):
if expected_values.get(d.account_head): if expected_values.get(d.account_head):
self.assertEqual(d.get(k), expected_values[d.account_head][i]) self.assertEqual(d.get(k), expected_values[d.account_head][i])
self.assertEqual(si.total_taxes_and_charges, 234.43) self.assertEqual(si.total_taxes_and_charges, 234.42)
self.assertEqual(si.base_grand_total, 859.43) self.assertEqual(si.base_grand_total, 859.42)
self.assertEqual(si.grand_total, 859.43) self.assertEqual(si.grand_total, 859.42)
def test_multi_currency_gle(self): def test_multi_currency_gle(self):
si = create_sales_invoice( si = create_sales_invoice(
@ -1985,17 +1985,17 @@ class TestSalesInvoice(unittest.TestCase):
) )
si.save() si.save()
si.submit() si.submit()
self.assertEqual(si.net_total, 19453.13) self.assertEqual(si.net_total, 19453.12)
self.assertEqual(si.grand_total, 24900) self.assertEqual(si.grand_total, 24900)
self.assertEqual(si.total_taxes_and_charges, 5446.88) self.assertEqual(si.total_taxes_and_charges, 5446.88)
self.assertEqual(si.rounding_adjustment, -0.01) self.assertEqual(si.rounding_adjustment, 0.0)
expected_values = dict( expected_values = dict(
(d[0], d) (d[0], d)
for d in [ for d in [
[si.debit_to, 24900, 0.0], [si.debit_to, 24900, 0.0],
["_Test Account Service Tax - _TC", 0.0, 5446.88], ["_Test Account Service Tax - _TC", 0.0, 5446.88],
["Sales - _TC", 0.0, 19453.13], ["Sales - _TC", 0.0, 19453.12],
["Round Off - _TC", 0.01, 0.0], ["Round Off - _TC", 0.01, 0.0],
] ]
) )

View File

@ -32,6 +32,16 @@ from erpnext import get_company_currency
from erpnext.accounts.utils import get_fiscal_year from erpnext.accounts.utils import get_fiscal_year
from erpnext.exceptions import InvalidAccountCurrency, PartyDisabled, PartyFrozen from erpnext.exceptions import InvalidAccountCurrency, PartyDisabled, PartyFrozen
PURCHASE_TRANSACTION_TYPES = {"Purchase Order", "Purchase Receipt", "Purchase Invoice"}
SALES_TRANSACTION_TYPES = {
"Quotation",
"Sales Order",
"Delivery Note",
"Sales Invoice",
"POS Invoice",
}
TRANSACTION_TYPES = PURCHASE_TRANSACTION_TYPES | SALES_TRANSACTION_TYPES
class DuplicatePartyAccountError(frappe.ValidationError): class DuplicatePartyAccountError(frappe.ValidationError):
pass pass
@ -124,12 +134,6 @@ def _get_party_details(
set_other_values(party_details, party, party_type) set_other_values(party_details, party, party_type)
set_price_list(party_details, party, party_type, price_list, pos_profile) set_price_list(party_details, party, party_type, price_list, pos_profile)
party_details["tax_category"] = get_address_tax_category(
party.get("tax_category"),
party_address,
shipping_address if party_type != "Supplier" else party_address,
)
tax_template = set_taxes( tax_template = set_taxes(
party.name, party.name,
party_type, party_type,
@ -211,20 +215,10 @@ def set_address_details(
else: else:
party_details.update(get_company_address(company)) party_details.update(get_company_address(company))
if doctype and doctype in [ if doctype in SALES_TRANSACTION_TYPES and party_details.company_address:
"Delivery Note", party_details.update(get_fetch_values(doctype, "company_address", party_details.company_address))
"Sales Invoice",
"Sales Order",
"Quotation",
"POS Invoice",
]:
if party_details.company_address:
party_details.update(
get_fetch_values(doctype, "company_address", party_details.company_address)
)
get_regional_address_details(party_details, doctype, company)
elif doctype and doctype in ["Purchase Invoice", "Purchase Order", "Purchase Receipt"]: if doctype in PURCHASE_TRANSACTION_TYPES:
if shipping_address: if shipping_address:
party_details.update( party_details.update(
shipping_address=shipping_address, shipping_address=shipping_address,
@ -250,9 +244,21 @@ def set_address_details(
**get_fetch_values(doctype, "shipping_address", party_details.billing_address) **get_fetch_values(doctype, "shipping_address", party_details.billing_address)
) )
party_address, shipping_address = (
party_details.get(billing_address_field),
party_details.shipping_address_name,
)
party_details["tax_category"] = get_address_tax_category(
party.get("tax_category"),
party_address,
shipping_address if party_type != "Supplier" else party_address,
)
if doctype in TRANSACTION_TYPES:
get_regional_address_details(party_details, doctype, company) get_regional_address_details(party_details, doctype, company)
return party_details.get(billing_address_field), party_details.shipping_address_name return party_address, shipping_address
@erpnext.allow_regional @erpnext.allow_regional

View File

@ -78,7 +78,6 @@ def validate_filters(filters):
def get_data(filters): def get_data(filters):
accounts = frappe.db.sql( accounts = frappe.db.sql(
"""select name, account_number, parent_account, account_name, root_type, report_type, lft, rgt """select name, account_number, parent_account, account_name, root_type, report_type, lft, rgt
@ -118,12 +117,10 @@ def get_data(filters):
ignore_closing_entries=not flt(filters.with_period_closing_entry), ignore_closing_entries=not flt(filters.with_period_closing_entry),
) )
total_row = calculate_values( calculate_values(accounts, gl_entries_by_account, opening_balances)
accounts, gl_entries_by_account, opening_balances, filters, company_currency
)
accumulate_values_into_parents(accounts, accounts_by_name) accumulate_values_into_parents(accounts, accounts_by_name)
data = prepare_data(accounts, filters, total_row, parent_children_map, company_currency) data = prepare_data(accounts, filters, parent_children_map, company_currency)
data = filter_out_zero_value_rows( data = filter_out_zero_value_rows(
data, parent_children_map, show_zero_values=filters.get("show_zero_values") data, parent_children_map, show_zero_values=filters.get("show_zero_values")
) )
@ -218,7 +215,7 @@ def get_rootwise_opening_balances(filters, report_type):
return opening return opening
def calculate_values(accounts, gl_entries_by_account, opening_balances, filters, company_currency): def calculate_values(accounts, gl_entries_by_account, opening_balances):
init = { init = {
"opening_debit": 0.0, "opening_debit": 0.0,
"opening_credit": 0.0, "opening_credit": 0.0,
@ -228,22 +225,6 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
"closing_credit": 0.0, "closing_credit": 0.0,
} }
total_row = {
"account": "'" + _("Total") + "'",
"account_name": "'" + _("Total") + "'",
"warn_if_negative": True,
"opening_debit": 0.0,
"opening_credit": 0.0,
"debit": 0.0,
"credit": 0.0,
"closing_debit": 0.0,
"closing_credit": 0.0,
"parent_account": None,
"indent": 0,
"has_value": True,
"currency": company_currency,
}
for d in accounts: for d in accounts:
d.update(init.copy()) d.update(init.copy())
@ -261,6 +242,26 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
prepare_opening_closing(d) prepare_opening_closing(d)
def calculate_total_row(accounts, company_currency):
total_row = {
"account": "'" + _("Total") + "'",
"account_name": "'" + _("Total") + "'",
"warn_if_negative": True,
"opening_debit": 0.0,
"opening_credit": 0.0,
"debit": 0.0,
"credit": 0.0,
"closing_debit": 0.0,
"closing_credit": 0.0,
"parent_account": None,
"indent": 0,
"has_value": True,
"currency": company_currency,
}
for d in accounts:
if not d.parent_account:
for field in value_fields: for field in value_fields:
total_row[field] += d[field] total_row[field] += d[field]
@ -274,7 +275,7 @@ def accumulate_values_into_parents(accounts, accounts_by_name):
accounts_by_name[d.parent_account][key] += d[key] accounts_by_name[d.parent_account][key] += d[key]
def prepare_data(accounts, filters, total_row, parent_children_map, company_currency): def prepare_data(accounts, filters, parent_children_map, company_currency):
data = [] data = []
for d in accounts: for d in accounts:
@ -305,6 +306,7 @@ def prepare_data(accounts, filters, total_row, parent_children_map, company_curr
row["has_value"] = has_value row["has_value"] = has_value
data.append(row) data.append(row)
total_row = calculate_total_row(accounts, company_currency)
data.extend([{}, total_row]) data.extend([{}, total_row])
return data return data

View File

@ -5,6 +5,8 @@ frappe.ui.form.on("Timesheet", {
setup: function(frm) { setup: function(frm) {
frappe.require("/assets/erpnext/js/projects/timer.js"); frappe.require("/assets/erpnext/js/projects/timer.js");
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice'];
frm.fields_dict.employee.get_query = function() { frm.fields_dict.employee.get_query = function() {
return { return {
filters:{ filters:{

View File

@ -46,6 +46,9 @@ def get_data(filters):
# task has no end date, hence no delay # task has no end date, hence no delay
task.delay = 0 task.delay = 0
task.status = _(task.status)
task.priority = _(task.priority)
# Sort by descending order of delay # Sort by descending order of delay
tasks.sort(key=lambda x: x["delay"], reverse=True) tasks.sort(key=lambda x: x["delay"], reverse=True)
return tasks return tasks
@ -73,7 +76,7 @@ def get_chart_data(data):
on_track = on_track + 1 on_track = on_track + 1
charts = { charts = {
"data": { "data": {
"labels": ["On Track", "Delayed"], "labels": [_("On Track"), _("Delayed")],
"datasets": [{"name": "Delayed", "values": [on_track, delay]}], "datasets": [{"name": "Delayed", "values": [on_track, delay]}],
}, },
"type": "percentage", "type": "percentage",

View File

@ -2801,7 +2801,7 @@ Stock Ledger Entries and GL Entries are reposted for the selected Purchase Recei
Stock Levels,Niveaux du Stocks, Stock Levels,Niveaux du Stocks,
Stock Liabilities,Passif du Stock, Stock Liabilities,Passif du Stock,
Stock Options,Options du Stock, Stock Options,Options du Stock,
Stock Qty,Qté en Stock, Stock Qty,Qté en unité de stock,
Stock Received But Not Billed,Stock Reçus Mais Non Facturés, Stock Received But Not Billed,Stock Reçus Mais Non Facturés,
Stock Reports,Rapports de stock, Stock Reports,Rapports de stock,
Stock Summary,Résumé du Stock, Stock Summary,Résumé du Stock,

Can't render this file because it is too large.