mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-03 13:38:27 +00:00
Merge branch 'develop' of https://github.com/frappe/erpnext into missing-condition-in-asset-depreciation-report
This commit is contained in:
@@ -515,6 +515,23 @@ class TestJournalEntry(unittest.TestCase):
|
||||
self.assertEqual(row.debit_in_account_currency, 100)
|
||||
self.assertEqual(row.credit_in_account_currency, 100)
|
||||
|
||||
def test_transaction_exchange_rate_on_journals(self):
|
||||
jv = make_journal_entry("_Test Bank - _TC", "_Test Receivable USD - _TC", 100, save=False)
|
||||
jv.accounts[0].update({"debit_in_account_currency": 8500, "exchange_rate": 1})
|
||||
jv.accounts[1].update({"party_type": "Customer", "party": "_Test Customer USD", "exchange_rate": 85})
|
||||
jv.submit()
|
||||
actual = frappe.db.get_all(
|
||||
"GL Entry",
|
||||
filters={"voucher_no": jv.name, "is_cancelled": 0},
|
||||
fields=["account", "transaction_exchange_rate"],
|
||||
order_by="account",
|
||||
)
|
||||
expected = [
|
||||
{"account": "_Test Bank - _TC", "transaction_exchange_rate": 1.0},
|
||||
{"account": "_Test Receivable USD - _TC", "transaction_exchange_rate": 85.0},
|
||||
]
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
|
||||
def make_journal_entry(
|
||||
account1,
|
||||
|
||||
@@ -233,9 +233,21 @@ class PaymentEntry(AccountsController):
|
||||
self.is_opening = "No"
|
||||
return
|
||||
|
||||
liability_account = get_party_account(
|
||||
self.party_type, self.party, self.company, include_advance=True
|
||||
)[1]
|
||||
accounts = get_party_account(self.party_type, self.party, self.company, include_advance=True)
|
||||
|
||||
liability_account = accounts[1] if len(accounts) > 1 else None
|
||||
fieldname = (
|
||||
"default_advance_received_account"
|
||||
if self.party_type == "Customer"
|
||||
else "default_advance_paid_account"
|
||||
)
|
||||
|
||||
if not liability_account:
|
||||
throw(
|
||||
_("Please set default {0} in Company {1}").format(
|
||||
frappe.bold(frappe.get_meta("Company").get_label(fieldname)), frappe.bold(self.company)
|
||||
)
|
||||
)
|
||||
|
||||
self.set(self.party_account_field, liability_account)
|
||||
|
||||
|
||||
@@ -40,6 +40,19 @@ erpnext.selling.POSInvoiceController = class POSInvoiceController extends erpnex
|
||||
};
|
||||
});
|
||||
|
||||
this.frm.set_query("item_code", "items", function (doc) {
|
||||
return {
|
||||
query: "erpnext.accounts.doctype.pos_invoice.pos_invoice.item_query",
|
||||
filters: {
|
||||
has_variants: ["=", 0],
|
||||
is_sales_item: ["=", 1],
|
||||
disabled: ["=", 0],
|
||||
is_fixed_asset: ["=", 0],
|
||||
pos_profile: ["=", doc.pos_profile],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import frappe
|
||||
from frappe import _, bold
|
||||
from frappe.query_builder.functions import IfNull, Sum
|
||||
from frappe.utils import cint, flt, get_link_to_form, getdate, nowdate
|
||||
from frappe.utils.nestedset import get_descendants_of
|
||||
|
||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import validate_loyalty_points
|
||||
from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request
|
||||
@@ -15,6 +16,7 @@ from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
|
||||
update_multi_mode_option,
|
||||
)
|
||||
from erpnext.accounts.party import get_due_date, get_party_account
|
||||
from erpnext.controllers.queries import item_query as _item_query
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
|
||||
|
||||
@@ -450,7 +452,7 @@ class POSInvoice(SalesInvoice):
|
||||
if self.is_return and entry.amount > 0:
|
||||
frappe.throw(_("Row #{0} (Payment Table): Amount must be negative").format(entry.idx))
|
||||
|
||||
if self.is_return:
|
||||
if self.is_return and self.docstatus != 0:
|
||||
invoice_total = self.rounded_total or self.grand_total
|
||||
total_amount_in_payments = flt(total_amount_in_payments, self.precision("grand_total"))
|
||||
if total_amount_in_payments and total_amount_in_payments < invoice_total:
|
||||
@@ -840,3 +842,29 @@ def add_return_modes(doc, pos_profile):
|
||||
]:
|
||||
payment_mode = get_mode_of_payment_info(mode_of_payment, doc.company)
|
||||
append_payment(payment_mode[0])
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
@frappe.validate_and_sanitize_search_inputs
|
||||
def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=False):
|
||||
if pos_profile := filters.get("pos_profile")[1]:
|
||||
pos_profile = frappe.get_cached_doc("POS Profile", pos_profile)
|
||||
if item_groups := get_item_group(pos_profile):
|
||||
filters["item_group"] = ["in", tuple(item_groups)]
|
||||
|
||||
del filters["pos_profile"]
|
||||
|
||||
else:
|
||||
filters.pop("pos_profile", None)
|
||||
|
||||
return _item_query(doctype, txt, searchfield, start, page_len, filters, as_dict)
|
||||
|
||||
|
||||
def get_item_group(pos_profile):
|
||||
item_groups = []
|
||||
if pos_profile.get("item_groups"):
|
||||
# Get items based on the item groups defined in the POS profile
|
||||
for row in pos_profile.get("item_groups"):
|
||||
item_groups.extend(get_descendants_of("Item Group", row.item_group))
|
||||
|
||||
return list(set(item_groups))
|
||||
|
||||
@@ -338,6 +338,7 @@ class SalesInvoice(SellingController):
|
||||
if self.redeem_loyalty_points and self.loyalty_points and not self.is_consolidated:
|
||||
validate_loyalty_points(self, self.loyalty_points)
|
||||
|
||||
self.allow_write_off_only_on_pos()
|
||||
self.reset_default_field_value("set_warehouse", "items", "warehouse")
|
||||
|
||||
def validate_accounts(self):
|
||||
@@ -1031,6 +1032,10 @@ class SalesInvoice(SellingController):
|
||||
),
|
||||
)
|
||||
|
||||
def allow_write_off_only_on_pos(self):
|
||||
if not self.is_pos and self.write_off_account:
|
||||
self.write_off_account = None
|
||||
|
||||
def validate_write_off_account(self):
|
||||
if flt(self.write_off_amount) and not self.write_off_account:
|
||||
self.write_off_account = frappe.get_cached_value("Company", self.company, "write_off_account")
|
||||
|
||||
@@ -185,7 +185,7 @@ def get_tax_template(posting_date, args):
|
||||
conditions.append("(from_date is null) and (to_date is null)")
|
||||
|
||||
conditions.append(
|
||||
"ifnull(tax_category, '') = {}".format(frappe.db.escape(cstr(args.get("tax_category"))))
|
||||
"ifnull(tax_category, '') = {}".format(frappe.db.escape(cstr(args.get("tax_category")), False))
|
||||
)
|
||||
if "tax_category" in args.keys():
|
||||
del args["tax_category"]
|
||||
|
||||
@@ -95,7 +95,7 @@ def execute(filters=None):
|
||||
filters.periodicity, period_list, filters.accumulated_values, company=filters.company
|
||||
)
|
||||
|
||||
chart = get_chart_data(filters, columns, asset, liability, equity)
|
||||
chart = get_chart_data(filters, columns, asset, liability, equity, currency)
|
||||
|
||||
report_summary, primitive_summary = get_report_summary(
|
||||
period_list, asset, liability, equity, provisional_profit_loss, currency, filters
|
||||
@@ -221,7 +221,7 @@ def get_report_summary(
|
||||
], (net_asset - net_liability + net_equity)
|
||||
|
||||
|
||||
def get_chart_data(filters, columns, asset, liability, equity):
|
||||
def get_chart_data(filters, columns, asset, liability, equity, currency):
|
||||
labels = [d.get("label") for d in columns[2:]]
|
||||
|
||||
asset_data, liability_data, equity_data = [], [], []
|
||||
@@ -249,4 +249,8 @@ def get_chart_data(filters, columns, asset, liability, equity):
|
||||
else:
|
||||
chart["type"] = "line"
|
||||
|
||||
chart["fieldtype"] = "Currency"
|
||||
chart["options"] = "currency"
|
||||
chart["currency"] = currency
|
||||
|
||||
return chart
|
||||
|
||||
@@ -120,7 +120,7 @@ def execute(filters=None):
|
||||
)
|
||||
columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company, True)
|
||||
|
||||
chart = get_chart_data(columns, data)
|
||||
chart = get_chart_data(columns, data, company_currency)
|
||||
|
||||
report_summary = get_report_summary(summary_data, company_currency)
|
||||
|
||||
@@ -261,7 +261,7 @@ def get_report_summary(summary_data, currency):
|
||||
return report_summary
|
||||
|
||||
|
||||
def get_chart_data(columns, data):
|
||||
def get_chart_data(columns, data, currency):
|
||||
labels = [d.get("label") for d in columns[2:]]
|
||||
print(data)
|
||||
datasets = [
|
||||
@@ -277,5 +277,7 @@ def get_chart_data(columns, data):
|
||||
chart = {"data": {"labels": labels, "datasets": datasets}, "type": "bar"}
|
||||
|
||||
chart["fieldtype"] = "Currency"
|
||||
chart["options"] = "currency"
|
||||
chart["currency"] = currency
|
||||
|
||||
return chart
|
||||
|
||||
@@ -115,7 +115,7 @@ def get_balance_sheet_data(fiscal_year, companies, columns, filters):
|
||||
True,
|
||||
)
|
||||
|
||||
chart = get_chart_data(filters, columns, asset, liability, equity)
|
||||
chart = get_chart_data(filters, columns, asset, liability, equity, company_currency)
|
||||
|
||||
return data, message, chart, report_summary
|
||||
|
||||
@@ -173,7 +173,7 @@ def get_profit_loss_data(fiscal_year, companies, columns, filters):
|
||||
if net_profit_loss:
|
||||
data.append(net_profit_loss)
|
||||
|
||||
chart = get_pl_chart_data(filters, columns, income, expense, net_profit_loss)
|
||||
chart = get_pl_chart_data(filters, columns, income, expense, net_profit_loss, company_currency)
|
||||
|
||||
report_summary, primitive_summary = get_pl_summary(
|
||||
companies, "", income, expense, net_profit_loss, company_currency, filters, True
|
||||
|
||||
@@ -199,8 +199,7 @@ class General_Payment_Ledger_Comparison:
|
||||
dict(
|
||||
label=_("Voucher Type"),
|
||||
fieldname="voucher_type",
|
||||
fieldtype="Link",
|
||||
options="DocType",
|
||||
fieldtype="Data",
|
||||
width="100",
|
||||
)
|
||||
)
|
||||
@@ -219,8 +218,7 @@ class General_Payment_Ledger_Comparison:
|
||||
dict(
|
||||
label=_("Party Type"),
|
||||
fieldname="party_type",
|
||||
fieldtype="Link",
|
||||
options="DocType",
|
||||
fieldtype="Data",
|
||||
width="100",
|
||||
)
|
||||
)
|
||||
|
||||
@@ -59,11 +59,11 @@ def execute(filters=None):
|
||||
|
||||
columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company)
|
||||
|
||||
chart = get_chart_data(filters, columns, income, expense, net_profit_loss)
|
||||
|
||||
currency = filters.presentation_currency or frappe.get_cached_value(
|
||||
"Company", filters.company, "default_currency"
|
||||
)
|
||||
chart = get_chart_data(filters, columns, income, expense, net_profit_loss, currency)
|
||||
|
||||
report_summary, primitive_summary = get_report_summary(
|
||||
period_list, filters.periodicity, income, expense, net_profit_loss, currency, filters
|
||||
)
|
||||
@@ -152,7 +152,7 @@ def get_net_profit_loss(income, expense, period_list, company, currency=None, co
|
||||
return net_profit_loss
|
||||
|
||||
|
||||
def get_chart_data(filters, columns, income, expense, net_profit_loss):
|
||||
def get_chart_data(filters, columns, income, expense, net_profit_loss, currency):
|
||||
labels = [d.get("label") for d in columns[2:]]
|
||||
|
||||
income_data, expense_data, net_profit = [], [], []
|
||||
@@ -181,5 +181,7 @@ def get_chart_data(filters, columns, income, expense, net_profit_loss):
|
||||
chart["type"] = "line"
|
||||
|
||||
chart["fieldtype"] = "Currency"
|
||||
chart["options"] = "currency"
|
||||
chart["currency"] = currency
|
||||
|
||||
return chart
|
||||
|
||||
@@ -1039,7 +1039,9 @@ class AccountsController(TransactionBase):
|
||||
gl_dict.update(
|
||||
{
|
||||
"transaction_currency": self.get("currency") or self.company_currency,
|
||||
"transaction_exchange_rate": self.get("conversion_rate", 1),
|
||||
"transaction_exchange_rate": item.get("exchange_rate", 1)
|
||||
if self.doctype == "Journal Entry" and item
|
||||
else self.get("conversion_rate", 1),
|
||||
"debit_in_transaction_currency": self.get_value_in_transaction_currency(
|
||||
account_currency, gl_dict, "debit"
|
||||
),
|
||||
|
||||
@@ -15,10 +15,11 @@ erpnext.sales_common = {
|
||||
onload() {
|
||||
super.onload();
|
||||
this.setup_queries();
|
||||
this.frm.set_query("shipping_rule", function () {
|
||||
this.frm.set_query("shipping_rule", function (doc) {
|
||||
return {
|
||||
filters: {
|
||||
shipping_rule_type: "Selling",
|
||||
company: doc.company,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
{
|
||||
"chart_name": "Oldest Items",
|
||||
"chart_type": "Report",
|
||||
"creation": "2020-07-20 21:01:04.336845",
|
||||
"creation": "2022-03-30 00:58:02.041721",
|
||||
"custom_options": "{\"colors\": [\"#5e64ff\"]}",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"to_date\":\"frappe.datetime.nowdate()\"}",
|
||||
"filters_json": "{\"range1\":30,\"range2\":60,\"range3\":90,\"show_warehouse_wise_stock\":0}",
|
||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"to_date\":\"frappe.datetime.nowdate()\",\"range1\":\"30\",\"range2\":\"60\",\"range3\":\"90\"}",
|
||||
"filters_json": "{\"range\":\"30, 60, 90\",\"show_warehouse_wise_stock\":0}",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"modified": "2020-07-29 14:50:26.846482",
|
||||
"modified": "2024-09-23 22:37:51.392999",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Oldest Items",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"owner": "rohitw1991@gmail.com",
|
||||
"report_name": "Stock Ageing",
|
||||
"roles": [],
|
||||
"timeseries": 0,
|
||||
"type": "Bar",
|
||||
"use_report_chart": 1,
|
||||
|
||||
Reference in New Issue
Block a user