Skip to content

Commit e65596f

Browse files
authored
Merge pull request #54283 from frappe/version-16-hotfix
2 parents a1c43ae + bd50a0f commit e65596f

67 files changed

Lines changed: 1562 additions & 1051 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

erpnext/accounts/doctype/journal_entry/journal_entry.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,31 +1541,31 @@ def get_against_jv(doctype, txt, searchfield, start, page_len, filters):
15411541
if not frappe.db.has_column("Journal Entry", searchfield):
15421542
return []
15431543

1544-
return frappe.db.sql(
1545-
f"""
1546-
SELECT jv.name, jv.posting_date, jv.user_remark
1547-
FROM `tabJournal Entry` jv, `tabJournal Entry Account` jv_detail
1548-
WHERE jv_detail.parent = jv.name
1549-
AND jv_detail.account = %(account)s
1550-
AND IFNULL(jv_detail.party, '') = %(party)s
1551-
AND (
1552-
jv_detail.reference_type IS NULL
1553-
OR jv_detail.reference_type = ''
1554-
)
1555-
AND jv.docstatus = 1
1556-
AND jv.`{searchfield}` LIKE %(txt)s
1557-
ORDER BY jv.name DESC
1558-
LIMIT %(limit)s offset %(offset)s
1559-
""",
1560-
dict(
1561-
account=filters.get("account"),
1562-
party=cstr(filters.get("party")),
1563-
txt=f"%{txt}%",
1564-
offset=start,
1565-
limit=page_len,
1566-
),
1544+
JournalEntry = frappe.qb.DocType("Journal Entry")
1545+
JournalEntryAccount = frappe.qb.DocType("Journal Entry Account")
1546+
1547+
query = (
1548+
frappe.qb.from_(JournalEntry)
1549+
.join(JournalEntryAccount)
1550+
.on(JournalEntryAccount.parent == JournalEntry.name)
1551+
.select(JournalEntry.name, JournalEntry.posting_date, JournalEntry.user_remark)
1552+
.where(JournalEntryAccount.account == filters.get("account"))
1553+
.where(JournalEntryAccount.reference_type.isnull() | (JournalEntryAccount.reference_type == ""))
1554+
.where(JournalEntry.docstatus == 1)
1555+
.where(JournalEntry[searchfield].like(f"%{txt}%"))
1556+
.orderby(JournalEntry.name, order=frappe.qb.desc)
1557+
.limit(page_len)
1558+
.offset(start)
15671559
)
15681560

1561+
party = filters.get("party")
1562+
if party:
1563+
query = query.where(JournalEntryAccount.party == party)
1564+
else:
1565+
query = query.where(JournalEntryAccount.party.isnull() | (JournalEntryAccount.party == ""))
1566+
1567+
return query.run()
1568+
15691569

15701570
@frappe.whitelist()
15711571
def get_outstanding(args):

erpnext/accounts/doctype/payment_entry/payment_entry.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ frappe.ui.form.on("Payment Entry", {
824824
paid_amount: function (frm) {
825825
frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
826826
let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
827-
if (frm.doc.paid_amount) {
827+
if (!frm.doc.received_amount) {
828828
if (frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
829829
frm.set_value("received_amount", frm.doc.paid_amount);
830830
} else if (company_currency == frm.doc.paid_to_account_currency) {
@@ -845,7 +845,7 @@ frappe.ui.form.on("Payment Entry", {
845845
flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate)
846846
);
847847

848-
if (frm.doc.received_amount) {
848+
if (!frm.doc.paid_amount) {
849849
if (frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
850850
frm.set_value("paid_amount", frm.doc.received_amount);
851851
if (frm.doc.target_exchange_rate) {

erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,6 @@ def create_remarks(self):
332332
if self.bill_date:
333333
self.remarks += " " + _("dated {0}").format(formatdate(self.bill_date))
334334

335-
else:
336-
self.remarks = _("No Remarks")
337-
338335
def set_missing_values(self, for_validate=False):
339336
if not self.credit_to:
340337
self.credit_to = get_party_account("Supplier", self.supplier, self.company)

erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,6 @@
740740
"label": "Valuation Rate",
741741
"no_copy": 1,
742742
"options": "Company:company:default_currency",
743-
"precision": "6",
744743
"print_hide": 1,
745744
"read_only": 1
746745
},
@@ -1008,7 +1007,7 @@
10081007
"idx": 1,
10091008
"istable": 1,
10101009
"links": [],
1011-
"modified": "2026-03-25 18:03:33.522195",
1010+
"modified": "2026-04-07 15:40:45.687554",
10121011
"modified_by": "Administrator",
10131012
"module": "Accounts",
10141013
"name": "Purchase Invoice Item",

erpnext/accounts/doctype/sales_invoice/sales_invoice.js

Lines changed: 99 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
165165
);
166166
}
167167
}
168-
169-
// Show buttons only when pos view is active
170-
if (cint(doc.docstatus == 0) && this.frm.page.current_view_name !== "pos" && !doc.is_return) {
171-
this.frm.cscript.sales_order_btn();
172-
this.frm.cscript.delivery_note_btn();
173-
this.frm.cscript.quotation_btn();
174-
}
168+
this.toggle_get_items();
175169

176170
this.set_default_print_format();
177171
if (doc.docstatus == 1 && !doc.inter_company_invoice_reference) {
@@ -260,6 +254,93 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
260254
}
261255
}
262256

257+
toggle_get_items() {
258+
const buttons = ["Sales Order", "Quotation", "Timesheet", "Delivery Note"];
259+
260+
buttons.forEach((label) => {
261+
this.frm.remove_custom_button(label, "Get Items From");
262+
});
263+
264+
if (cint(this.frm.doc.docstatus) !== 0 || this.frm.page.current_view_name === "pos") {
265+
return;
266+
}
267+
268+
if (!this.frm.doc.is_return) {
269+
this.frm.cscript.sales_order_btn();
270+
this.frm.cscript.quotation_btn();
271+
this.frm.cscript.timesheet_btn();
272+
}
273+
274+
this.frm.cscript.delivery_note_btn();
275+
}
276+
277+
timesheet_btn() {
278+
var me = this;
279+
280+
me.frm.add_custom_button(
281+
__("Timesheet"),
282+
function () {
283+
let d = new frappe.ui.Dialog({
284+
title: __("Fetch Timesheet"),
285+
fields: [
286+
{
287+
label: __("From"),
288+
fieldname: "from_time",
289+
fieldtype: "Date",
290+
reqd: 1,
291+
},
292+
{
293+
label: __("Item Code"),
294+
fieldname: "item_code",
295+
fieldtype: "Link",
296+
options: "Item",
297+
get_query: () => {
298+
return {
299+
query: "erpnext.controllers.queries.item_query",
300+
filters: {
301+
is_sales_item: 1,
302+
customer: me.frm.doc.customer,
303+
has_variants: 0,
304+
},
305+
};
306+
},
307+
},
308+
{
309+
fieldtype: "Column Break",
310+
fieldname: "col_break_1",
311+
},
312+
{
313+
label: __("To"),
314+
fieldname: "to_time",
315+
fieldtype: "Date",
316+
reqd: 1,
317+
},
318+
{
319+
label: __("Project"),
320+
fieldname: "project",
321+
fieldtype: "Link",
322+
options: "Project",
323+
default: me.frm.doc.project,
324+
},
325+
],
326+
primary_action: function () {
327+
const data = d.get_values();
328+
me.frm.events.add_timesheet_data(me.frm, {
329+
from_time: data.from_time,
330+
to_time: data.to_time,
331+
project: data.project,
332+
item_code: data.item_code,
333+
});
334+
d.hide();
335+
},
336+
primary_action_label: __("Get Timesheets"),
337+
});
338+
d.show();
339+
},
340+
__("Get Items From")
341+
);
342+
}
343+
263344
sales_order_btn() {
264345
var me = this;
265346

@@ -331,6 +412,12 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
331412
this.$delivery_note_btn = this.frm.add_custom_button(
332413
__("Delivery Note"),
333414
function () {
415+
if (!me.frm.doc.customer) {
416+
frappe.throw({
417+
title: __("Mandatory"),
418+
message: __("Please Select a Customer"),
419+
});
420+
}
334421
erpnext.utils.map_current_doc({
335422
method: "erpnext.stock.doctype.delivery_note.delivery_note.make_sales_invoice",
336423
source_doctype: "Delivery Note",
@@ -343,7 +430,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
343430
var filters = {
344431
docstatus: 1,
345432
company: me.frm.doc.company,
346-
is_return: 0,
433+
is_return: me.frm.doc.is_return,
347434
};
348435
if (me.frm.doc.customer) filters["customer"] = me.frm.doc.customer;
349436
return {
@@ -610,6 +697,10 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
610697
apply_tds(frm) {
611698
this.frm.clear_table("tax_withholding_entries");
612699
}
700+
701+
is_return() {
702+
this.toggle_get_items();
703+
}
613704
};
614705

615706
// for backward compatibility: combine new and previous states
@@ -1061,71 +1152,6 @@ frappe.ui.form.on("Sales Invoice", {
10611152
},
10621153

10631154
refresh: function (frm) {
1064-
if (frm.doc.docstatus === 0 && !frm.doc.is_return) {
1065-
frm.add_custom_button(
1066-
__("Timesheet"),
1067-
function () {
1068-
let d = new frappe.ui.Dialog({
1069-
title: __("Fetch Timesheet"),
1070-
fields: [
1071-
{
1072-
label: __("From"),
1073-
fieldname: "from_time",
1074-
fieldtype: "Date",
1075-
reqd: 1,
1076-
},
1077-
{
1078-
label: __("Item Code"),
1079-
fieldname: "item_code",
1080-
fieldtype: "Link",
1081-
options: "Item",
1082-
get_query: () => {
1083-
return {
1084-
query: "erpnext.controllers.queries.item_query",
1085-
filters: {
1086-
is_sales_item: 1,
1087-
customer: frm.doc.customer,
1088-
has_variants: 0,
1089-
},
1090-
};
1091-
},
1092-
},
1093-
{
1094-
fieldtype: "Column Break",
1095-
fieldname: "col_break_1",
1096-
},
1097-
{
1098-
label: __("To"),
1099-
fieldname: "to_time",
1100-
fieldtype: "Date",
1101-
reqd: 1,
1102-
},
1103-
{
1104-
label: __("Project"),
1105-
fieldname: "project",
1106-
fieldtype: "Link",
1107-
options: "Project",
1108-
default: frm.doc.project,
1109-
},
1110-
],
1111-
primary_action: function () {
1112-
const data = d.get_values();
1113-
frm.events.add_timesheet_data(frm, {
1114-
from_time: data.from_time,
1115-
to_time: data.to_time,
1116-
project: data.project,
1117-
item_code: data.item_code,
1118-
});
1119-
d.hide();
1120-
},
1121-
primary_action_label: __("Get Timesheets"),
1122-
});
1123-
d.show();
1124-
},
1125-
__("Get Items From")
1126-
);
1127-
}
1128-
11291155
if (frm.doc.is_debit_note) {
11301156
frm.set_df_property("return_against", "label", __("Adjustment Against"));
11311157
}

erpnext/accounts/doctype/sales_invoice/sales_invoice.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,9 +1101,6 @@ def add_remarks(self):
11011101
if self.po_date:
11021102
self.remarks += " " + _("dated {0}").format(formatdate(self.po_date))
11031103

1104-
else:
1105-
self.remarks = _("No Remarks")
1106-
11071104
def validate_auto_set_posting_time(self):
11081105
# Don't auto set the posting date and time if invoice is amended
11091106
if self.is_new() and self.amended_from:

erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2887,7 +2887,7 @@ def test_internal_transfer_gl_precision_issues(self):
28872887
si.submit()
28882888

28892889
# Check if adjustment entry is created
2890-
self.assertTrue(
2890+
self.assertFalse(
28912891
frappe.db.exists(
28922892
"GL Entry",
28932893
{

0 commit comments

Comments
 (0)