Skip to content

Commit 5de4102

Browse files
fix(sales invoice): toggle Get Items From button based on is_return and POS view (backport #52594) (#54138)
Co-authored-by: NaviN <[email protected]> Co-authored-by: Navin-S-R <[email protected]> fix(sales invoice): toggle Get Items From button based on is_return and POS view (#52594)
1 parent 4f1203d commit 5de4102

2 files changed

Lines changed: 135 additions & 100 deletions

File tree

erpnext/accounts/doctype/sales_invoice/sales_invoice.js

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

177171
this.set_default_print_format();
178172
if (doc.docstatus == 1 && !doc.inter_company_invoice_reference) {
@@ -258,6 +252,93 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
258252
}
259253
}
260254

255+
toggle_get_items() {
256+
const buttons = ["Sales Order", "Quotation", "Timesheet", "Delivery Note"];
257+
258+
buttons.forEach((label) => {
259+
this.frm.remove_custom_button(label, "Get Items From");
260+
});
261+
262+
if (cint(this.frm.doc.docstatus) !== 0 || this.frm.page.current_view_name === "pos") {
263+
return;
264+
}
265+
266+
if (!this.frm.doc.is_return) {
267+
this.frm.cscript.sales_order_btn();
268+
this.frm.cscript.quotation_btn();
269+
this.frm.cscript.timesheet_btn();
270+
}
271+
272+
this.frm.cscript.delivery_note_btn();
273+
}
274+
275+
timesheet_btn() {
276+
var me = this;
277+
278+
me.frm.add_custom_button(
279+
__("Timesheet"),
280+
function () {
281+
let d = new frappe.ui.Dialog({
282+
title: __("Fetch Timesheet"),
283+
fields: [
284+
{
285+
label: __("From"),
286+
fieldname: "from_time",
287+
fieldtype: "Date",
288+
reqd: 1,
289+
},
290+
{
291+
label: __("Item Code"),
292+
fieldname: "item_code",
293+
fieldtype: "Link",
294+
options: "Item",
295+
get_query: () => {
296+
return {
297+
query: "erpnext.controllers.queries.item_query",
298+
filters: {
299+
is_sales_item: 1,
300+
customer: me.frm.doc.customer,
301+
has_variants: 0,
302+
},
303+
};
304+
},
305+
},
306+
{
307+
fieldtype: "Column Break",
308+
fieldname: "col_break_1",
309+
},
310+
{
311+
label: __("To"),
312+
fieldname: "to_time",
313+
fieldtype: "Date",
314+
reqd: 1,
315+
},
316+
{
317+
label: __("Project"),
318+
fieldname: "project",
319+
fieldtype: "Link",
320+
options: "Project",
321+
default: me.frm.doc.project,
322+
},
323+
],
324+
primary_action: function () {
325+
const data = d.get_values();
326+
me.frm.events.add_timesheet_data(me.frm, {
327+
from_time: data.from_time,
328+
to_time: data.to_time,
329+
project: data.project,
330+
item_code: data.item_code,
331+
});
332+
d.hide();
333+
},
334+
primary_action_label: __("Get Timesheets"),
335+
});
336+
d.show();
337+
},
338+
__("Get Items From")
339+
);
340+
}
341+
261342
sales_order_btn() {
262343
var me = this;
263344
this.$sales_order_btn = this.frm.add_custom_button(
@@ -322,6 +403,12 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
322403
this.$delivery_note_btn = this.frm.add_custom_button(
323404
__("Delivery Note"),
324405
function () {
406+
if (!me.frm.doc.customer) {
407+
frappe.throw({
408+
title: __("Mandatory"),
409+
message: __("Please Select a Customer"),
410+
});
411+
}
325412
erpnext.utils.map_current_doc({
326413
method: "erpnext.stock.doctype.delivery_note.delivery_note.make_sales_invoice",
327414
source_doctype: "Delivery Note",
@@ -334,7 +421,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
334421
var filters = {
335422
docstatus: 1,
336423
company: me.frm.doc.company,
337-
is_return: 0,
424+
is_return: me.frm.doc.is_return,
338425
};
339426
if (me.frm.doc.customer) filters["customer"] = me.frm.doc.customer;
340427
return {
@@ -594,6 +681,14 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
594681

595682
this.calculate_taxes_and_totals();
596683
}
684+
685+
apply_tds(frm) {
686+
this.frm.clear_table("tax_withholding_entries");
687+
}
688+
689+
is_return() {
690+
this.toggle_get_items();
691+
}
597692
};
598693

599694
// for backward compatibility: combine new and previous states
@@ -1039,71 +1134,6 @@ frappe.ui.form.on("Sales Invoice", {
10391134
},
10401135

10411136
refresh: function (frm) {
1042-
if (frm.doc.docstatus === 0 && !frm.doc.is_return) {
1043-
frm.add_custom_button(
1044-
__("Timesheet"),
1045-
function () {
1046-
let d = new frappe.ui.Dialog({
1047-
title: __("Fetch Timesheet"),
1048-
fields: [
1049-
{
1050-
label: __("From"),
1051-
fieldname: "from_time",
1052-
fieldtype: "Date",
1053-
reqd: 1,
1054-
},
1055-
{
1056-
label: __("Item Code"),
1057-
fieldname: "item_code",
1058-
fieldtype: "Link",
1059-
options: "Item",
1060-
get_query: () => {
1061-
return {
1062-
query: "erpnext.controllers.queries.item_query",
1063-
filters: {
1064-
is_sales_item: 1,
1065-
customer: frm.doc.customer,
1066-
has_variants: 0,
1067-
},
1068-
};
1069-
},
1070-
},
1071-
{
1072-
fieldtype: "Column Break",
1073-
fieldname: "col_break_1",
1074-
},
1075-
{
1076-
label: __("To"),
1077-
fieldname: "to_time",
1078-
fieldtype: "Date",
1079-
reqd: 1,
1080-
},
1081-
{
1082-
label: __("Project"),
1083-
fieldname: "project",
1084-
fieldtype: "Link",
1085-
options: "Project",
1086-
default: frm.doc.project,
1087-
},
1088-
],
1089-
primary_action: function () {
1090-
const data = d.get_values();
1091-
frm.events.add_timesheet_data(frm, {
1092-
from_time: data.from_time,
1093-
to_time: data.to_time,
1094-
project: data.project,
1095-
item_code: data.item_code,
1096-
});
1097-
d.hide();
1098-
},
1099-
primary_action_label: __("Get Timesheets"),
1100-
});
1101-
d.show();
1102-
},
1103-
__("Get Items From")
1104-
);
1105-
}
1106-
11071137
if (frm.doc.is_debit_note) {
11081138
frm.set_df_property("return_against", "label", __("Adjustment Against"));
11091139
}

erpnext/controllers/queries.py

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -356,38 +356,43 @@ def get_project_name(doctype, txt, searchfield, start, page_len, filters):
356356

357357
@frappe.whitelist()
358358
@frappe.validate_and_sanitize_search_inputs
359-
def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len, filters, as_dict):
360-
doctype = "Delivery Note"
359+
def get_delivery_notes_to_be_billed(
360+
doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict, as_dict: bool = False
361+
):
362+
DeliveryNote = frappe.qb.DocType("Delivery Note")
363+
361364
fields = get_fields(doctype, ["name", "customer", "posting_date"])
362365

363-
return frappe.db.sql(
364-
"""
365-
select {fields}
366-
from `tabDelivery Note`
367-
where `tabDelivery Note`.`{key}` like {txt} and
368-
`tabDelivery Note`.docstatus = 1
369-
and status not in ('Stopped', 'Closed') {fcond}
370-
and (
371-
(`tabDelivery Note`.is_return = 0 and `tabDelivery Note`.per_billed < 100)
372-
or (`tabDelivery Note`.grand_total = 0 and `tabDelivery Note`.per_billed < 100)
373-
or (
374-
`tabDelivery Note`.is_return = 1
375-
and return_against in (select name from `tabDelivery Note` where per_billed < 100)
366+
original_dn = (
367+
frappe.qb.from_(DeliveryNote)
368+
.select(DeliveryNote.name)
369+
.where((DeliveryNote.docstatus == 1) & (DeliveryNote.is_return == 0) & (DeliveryNote.per_billed > 0))
370+
)
371+
372+
query = (
373+
frappe.qb.from_(DeliveryNote)
374+
.select(*[DeliveryNote[f] for f in fields])
375+
.where(
376+
(DeliveryNote.docstatus == 1)
377+
& (DeliveryNote.status.notin(["Stopped", "Closed"]))
378+
& (DeliveryNote[searchfield].like(f"%{txt}%"))
379+
& (
380+
((DeliveryNote.is_return == 0) & (DeliveryNote.per_billed < 100))
381+
| ((DeliveryNote.grand_total == 0) & (DeliveryNote.per_billed < 100))
382+
| (
383+
(DeliveryNote.is_return == 1)
384+
& (DeliveryNote.per_billed < 100)
385+
& (DeliveryNote.return_against.isin(original_dn))
376386
)
377387
)
378-
{mcond} order by `tabDelivery Note`.`{key}` asc limit {page_len} offset {start}
379-
""".format(
380-
fields=", ".join([f"`tabDelivery Note`.{f}" for f in fields]),
381-
key=searchfield,
382-
fcond=get_filters_cond(doctype, filters, []),
383-
mcond=get_match_cond(doctype),
384-
start=start,
385-
page_len=page_len,
386-
txt="%(txt)s",
387-
),
388-
{"txt": ("%%%s%%" % txt)},
389-
as_dict=as_dict,
388+
)
390389
)
390+
if filters and isinstance(filters, dict):
391+
for key, value in filters.items():
392+
query = query.where(DeliveryNote[key] == value)
393+
394+
query = query.orderby(DeliveryNote[searchfield], order=Order.asc).limit(page_len).offset(start)
395+
return query.run(as_dict=as_dict)
391396

392397

393398
@frappe.whitelist()

0 commit comments

Comments
 (0)