diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index a2f5455f2f7..cda0adc7257 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -428,7 +428,10 @@ frappe.ui.form.on("Journal Entry Account", { } }, cost_center: function (frm, dt, dn) { - erpnext.journal_entry.set_account_details(frm, dt, dn); + // Don't reset for Gain/Loss type journals, as it will make Debit and Credit values '0' + if (frm.doc.voucher_type != "Exchange Gain Or Loss") { + erpnext.journal_entry.set_account_details(frm, dt, dn); + } }, account: function (frm, dt, dn) { diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json index bd43fb77c23..d3db789c336 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.json +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json @@ -576,6 +576,7 @@ "fieldtype": "Select", "hidden": 1, "label": "Payment Order Status", + "no_copy": 1, "options": "Initiated\nPayment Ordered", "read_only": 1 }, diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 2a86d0daf45..6a1a5f3a7c9 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -1817,9 +1817,9 @@ def validate_inter_company_party(doctype, party, company, inter_company_referenc companies = [d.company for d in companies] if not company in companies: frappe.throw( - _("{0} not allowed to transact with {1}. Please change the Company.").format( - partytype, company - ) + _( + "{0} not allowed to transact with {1}. Please change the Company or add the Company in the 'Allowed To Transact With'-Section in the Customer record." + ).format(_(partytype), company) ) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index c3ebb018ae9..609a4abe66f 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -673,7 +673,7 @@ class ReceivablePayableReport(object): else: future_amount_field = "future_amount_in_base_currency" - if row.remaining_balance > 0 and future.get(future_amount_field): + if row.remaining_balance != 0 and future.get(future_amount_field): if future.get(future_amount_field) > row.outstanding: row.future_amount = row.outstanding future[future_amount_field] = future.get(future_amount_field) - row.outstanding diff --git a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py index de49139adc1..01129824bca 100644 --- a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py @@ -469,11 +469,30 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): ) def test_future_payments(self): + sr = self.create_sales_invoice(do_not_submit=True) + sr.is_return = 1 + sr.items[0].qty = -1 + sr.items[0].rate = 10 + sr.calculate_taxes_and_totals() + sr.submit() + si = self.create_sales_invoice() pe = get_payment_entry(si.doctype, si.name) + pe.append( + "references", + { + "reference_doctype": sr.doctype, + "reference_name": sr.name, + "due_date": sr.due_date, + "total_amount": sr.grand_total, + "outstanding_amount": sr.outstanding_amount, + "allocated_amount": sr.outstanding_amount, + }, + ) + pe.posting_date = add_days(today(), 1) - pe.paid_amount = 90.0 - pe.references[0].allocated_amount = 90.0 + pe.paid_amount = 80 + pe.references[0].allocated_amount = 90.0 # pe.paid_amount + sr.grand_total pe.save().submit() filters = { "company": self.company, @@ -485,16 +504,21 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): "show_future_payments": True, } report = execute(filters)[1] - self.assertEqual(len(report), 1) + self.assertEqual(len(report), 2) - expected_data = [100.0, 100.0, 10.0, 90.0] + expected_data = {sr.name: [10.0, -10.0, 0.0, -10], si.name: [100.0, 100.0, 10.0, 90.0]} - row = report[0] - self.assertEqual( - expected_data, [row.invoiced, row.outstanding, row.remaining_balance, row.future_amount] - ) + rows = report[:2] + for row in rows: + self.assertEqual( + expected_data[row.voucher_no], + [row.invoiced or row.paid, row.outstanding, row.remaining_balance, row.future_amount], + ) pe.cancel() + sr.load_from_db() # Outstanding amount is updated so a updated timestamp is needed. + sr.cancel() + # full payment in future date pe = get_payment_entry(si.doctype, si.name) pe.posting_date = add_days(today(), 1) diff --git a/erpnext/accounts/report/pos_register/pos_register.py b/erpnext/accounts/report/pos_register/pos_register.py index 488bb9957c9..3c687d0b48e 100644 --- a/erpnext/accounts/report/pos_register/pos_register.py +++ b/erpnext/accounts/report/pos_register/pos_register.py @@ -59,10 +59,11 @@ def get_pos_entries(filters, group_by_field): order_by += ", p.{}".format(group_by_field) select_mop_field = ", p.base_paid_amount - p.change_amount as paid_amount " + # nosemgrep return frappe.db.sql( """ SELECT - p.posting_date, p.name as pos_invoice, p.pos_profile, + p.posting_date, p.name as pos_invoice, p.pos_profile, p.company, p.owner, p.customer, p.is_return, p.base_grand_total as grand_total {select_mop_field} FROM `tabPOS Invoice` p {from_sales_invoice_payment} @@ -207,14 +208,14 @@ def get_columns(filters): "label": _("Grand Total"), "fieldname": "grand_total", "fieldtype": "Currency", - "options": "company:currency", + "options": "Company:company:default_currency", "width": 120, }, { "label": _("Paid Amount"), "fieldname": "paid_amount", "fieldtype": "Currency", - "options": "company:currency", + "options": "Company:company:default_currency", "width": 120, }, { @@ -224,6 +225,13 @@ def get_columns(filters): "width": 150, }, {"label": _("Is Return"), "fieldname": "is_return", "fieldtype": "Data", "width": 80}, + { + "label": _("Company"), + "fieldname": "company", + "fieldtype": "Link", + "options": "Company", + "width": 120, + }, ] return columns diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py index 45811a93444..4150494e22f 100644 --- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py @@ -149,6 +149,7 @@ def get_data(filters): "asset_category": asset.asset_category, "purchase_date": asset.purchase_date, "asset_value": asset_value, + "company": asset.company, } data.append(row) @@ -379,30 +380,37 @@ def get_columns(filters): "label": _("Gross Purchase Amount"), "fieldname": "gross_purchase_amount", "fieldtype": "Currency", - "options": "company:currency", + "options": "Company:company:default_currency", "width": 250, }, { "label": _("Opening Accumulated Depreciation"), "fieldname": "opening_accumulated_depreciation", "fieldtype": "Currency", - "options": "company:currency", + "options": "Company:company:default_currency", "width": 250, }, { "label": _("Depreciated Amount"), "fieldname": "depreciated_amount", "fieldtype": "Currency", - "options": "company:currency", + "options": "Company:company:default_currency", "width": 250, }, { "label": _("Asset Value"), "fieldname": "asset_value", "fieldtype": "Currency", - "options": "company:currency", + "options": "Company:company:default_currency", "width": 250, }, + { + "label": _("Company"), + "fieldname": "company", + "fieldtype": "Link", + "options": "Company", + "width": 120, + }, ] return [ @@ -433,28 +441,28 @@ def get_columns(filters): "label": _("Gross Purchase Amount"), "fieldname": "gross_purchase_amount", "fieldtype": "Currency", - "options": "company:currency", + "options": "Company:company:default_currency", "width": 100, }, { "label": _("Asset Value"), "fieldname": "asset_value", "fieldtype": "Currency", - "options": "company:currency", + "options": "Company:company:default_currency", "width": 100, }, { "label": _("Opening Accumulated Depreciation"), "fieldname": "opening_accumulated_depreciation", "fieldtype": "Currency", - "options": "company:currency", + "options": "Company:company:default_currency", "width": 90, }, { "label": _("Depreciated Amount"), "fieldname": "depreciated_amount", "fieldtype": "Currency", - "options": "company:currency", + "options": "Company:company:default_currency", "width": 100, }, { @@ -479,4 +487,11 @@ def get_columns(filters): "options": "Location", "width": 100, }, + { + "label": _("Company"), + "fieldname": "company", + "fieldtype": "Link", + "options": "Company", + "width": 120, + }, ] diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json index f13ceb04a50..d87db06a4a9 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json @@ -461,7 +461,7 @@ }, { "fieldname": "other_charges_calculation", - "fieldtype": "Markdown Editor", + "fieldtype": "Text Editor", "label": "Taxes and Charges Calculation", "no_copy": 1, "oldfieldtype": "HTML", @@ -927,7 +927,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2024-03-20 16:03:59.069145", + "modified": "2024-03-28 10:20:30.231915", "modified_by": "Administrator", "module": "Buying", "name": "Supplier Quotation", @@ -995,4 +995,4 @@ "states": [], "timeline_field": "supplier", "title_field": "title" -} \ No newline at end of file +} diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index bc3ec7f93c2..8d7d888c2c9 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -669,7 +669,7 @@ class StockController(AccountsController): self.validate_multi_currency() self.validate_packed_items() - if self.get("is_internal_supplier"): + if self.get("is_internal_supplier") and self.docstatus == 1: self.validate_internal_transfer_qty() else: self.validate_internal_transfer_warehouse() diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index a402bb5aed2..0a389b602a5 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -965,6 +965,9 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): for tax in get_taxes_and_charges(master_doctype, target.get("taxes_and_charges")): target.append("taxes", tax) + if not target.get("items"): + frappe.throw(_("All items have already been received")) + def update_details(source_doc, target_doc, source_parent): target_doc.inter_company_invoice_reference = source_doc.name if target_doc.doctype == "Purchase Receipt": @@ -1020,6 +1023,10 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): shipping_address_name=target_doc.shipping_address_name, ) + def update_item(source, target, source_parent): + if source_parent.doctype == "Delivery Note" and source.received_qty: + target.qty = flt(source.qty) + flt(source.returned_qty) - flt(source.received_qty) + doclist = get_mapped_doc( doctype, source_name, @@ -1043,6 +1050,8 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None): "Material_request_item": "material_request_item", }, "field_no_map": ["warehouse"], + "condition": lambda item: item.received_qty < item.qty + item.returned_qty, + "postprocess": update_item, }, }, target_doc, diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index ca31a9a3d31..81658c42e91 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -9,17 +9,7 @@ import frappe from frappe import _ from frappe.model.mapper import get_mapped_doc from frappe.query_builder.functions import Sum -from frappe.utils import ( - cint, - comma_or, - cstr, - flt, - format_time, - formatdate, - getdate, - month_diff, - nowdate, -) +from frappe.utils import cint, comma_or, cstr, flt, format_time, formatdate, getdate, nowdate import erpnext from erpnext.accounts.general_ledger import process_gl_map @@ -168,41 +158,6 @@ class StockEntry(StockController): self.reset_default_field_value("from_warehouse", "items", "s_warehouse") self.reset_default_field_value("to_warehouse", "items", "t_warehouse") - def submit(self): - if self.is_enqueue_action(): - frappe.msgprint( - _( - "The task has been enqueued as a background job. In case there is any issue on processing in background, the system will add a comment about the error on this Stock Entry and revert to the Draft stage" - ) - ) - self.queue_action("submit", timeout=2000) - else: - self._submit() - - def cancel(self): - if self.is_enqueue_action(): - frappe.msgprint( - _( - "The task has been enqueued as a background job. In case there is any issue on processing in background, the system will add a comment about the error on this Stock Entry and revert to the Submitted stage" - ) - ) - self.queue_action("cancel", timeout=2000) - else: - self._cancel() - - def is_enqueue_action(self, force=False) -> bool: - if force: - return True - - if frappe.flags.in_test: - return False - - # If line items are more than 100 or record is older than 6 months - if len(self.items) > 50 or month_diff(nowdate(), self.posting_date) > 6: - return True - - return False - def on_submit(self): self.update_stock_ledger() diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 771dae53864..c6814558ce1 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -1702,36 +1702,6 @@ class TestStockEntry(FrappeTestCase): self.assertRaises(frappe.ValidationError, sr_doc.submit) - def test_enqueue_action(self): - frappe.flags.in_test = False - item_code = "Test Enqueue Item - 001" - create_item(item_code=item_code, is_stock_item=1, valuation_rate=10) - - doc = make_stock_entry( - item_code=item_code, - posting_date=add_to_date(today(), months=-7), - posting_time="00:00:00", - purpose="Material Receipt", - qty=10, - to_warehouse="_Test Warehouse - _TC", - do_not_submit=True, - ) - - self.assertTrue(doc.is_enqueue_action()) - - doc = make_stock_entry( - item_code=item_code, - posting_date=today(), - posting_time="00:00:00", - purpose="Material Receipt", - qty=10, - to_warehouse="_Test Warehouse - _TC", - do_not_submit=True, - ) - - self.assertFalse(doc.is_enqueue_action()) - frappe.flags.in_test = True - def test_auto_reorder_level(self): from erpnext.stock.reorder_item import reorder_item diff --git a/erpnext/stock/doctype/warehouse/warehouse.js b/erpnext/stock/doctype/warehouse/warehouse.js index 4f44db023dd..9457c25b22d 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.js +++ b/erpnext/stock/doctype/warehouse/warehouse.js @@ -49,6 +49,7 @@ frappe.ui.form.on("Warehouse", { frm.add_custom_button(__("Stock Balance"), function () { frappe.set_route("query-report", "Stock Balance", { warehouse: frm.doc.name, + company: frm.doc.company, }); });