Merge pull request #34326 from frappe/version-13-hotfix

chore: release v13
This commit is contained in:
Deepesh Garg
2023-03-07 16:11:57 +05:30
committed by GitHub
9 changed files with 50 additions and 16 deletions

View File

@@ -131,7 +131,7 @@ def validate_returned_items(doc):
)
elif ref.serial_no:
if not d.serial_no:
if d.qty and not d.serial_no:
frappe.throw(_("Row # {0}: Serial No is mandatory").format(d.idx))
else:
serial_nos = get_serial_nos(d.serial_no)
@@ -393,6 +393,16 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None):
if serial_nos:
target_doc.serial_no = "\n".join(serial_nos)
if source_doc.get("rejected_serial_no"):
returned_serial_nos = get_returned_serial_nos(
source_doc, source_parent, serial_no_field="rejected_serial_no"
)
rejected_serial_nos = list(
set(get_serial_nos(source_doc.rejected_serial_no)) - set(returned_serial_nos)
)
if rejected_serial_nos:
target_doc.rejected_serial_no = "\n".join(rejected_serial_nos)
if doctype == "Purchase Receipt":
returned_qty_map = get_returned_qty_map_for_row(
source_parent.name, source_parent.supplier, source_doc.name, doctype
@@ -587,7 +597,7 @@ def get_filters(
return filters
def get_returned_serial_nos(child_doc, parent_doc):
def get_returned_serial_nos(child_doc, parent_doc, serial_no_field="serial_no"):
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
return_ref_field = frappe.scrub(child_doc.doctype)
@@ -596,7 +606,7 @@ def get_returned_serial_nos(child_doc, parent_doc):
serial_nos = []
fields = ["`{0}`.`serial_no`".format("tab" + child_doc.doctype)]
fields = [f"`{'tab' + child_doc.doctype}`.`{serial_no_field}`"]
filters = [
[parent_doc.doctype, "return_against", "=", parent_doc.name],
@@ -606,6 +616,6 @@ def get_returned_serial_nos(child_doc, parent_doc):
]
for row in frappe.get_all(parent_doc.doctype, fields=fields, filters=filters):
serial_nos.extend(get_serial_nos(row.serial_no))
serial_nos.extend(get_serial_nos(row.get(serial_no_field)))
return serial_nos

View File

@@ -86,6 +86,9 @@ class SellingController(StockController):
)
if not self.meta.get_field("sales_team"):
party_details.pop("sales_team")
else:
self.set("sales_team", party_details.get("sales_team"))
self.update_if_missing(party_details)
elif lead:

View File

@@ -1975,11 +1975,13 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
get_advances: function() {
if(!this.frm.is_return) {
var me = this;
return this.frm.call({
method: "set_advances",
doc: this.frm.doc,
callback: function(r, rt) {
refresh_field("advances");
me.frm.dirty();
}
})
}

View File

@@ -417,7 +417,14 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
args: args,
callback: function(r) {
if(r.message) {
frappe.model.set_value(doc.doctype, doc.name, 'batch_no', r.message);
if (r.message.batch_no != null) {
frappe.model.set_value(doc.doctype, doc.name, 'batch_no', r.message.batch_no);
} else if (r.message.msg_print) {
frappe.show_alert({
message: r.message.msg_print,
indicator:'orange'
}, 5);
}
}
}
});

View File

@@ -260,7 +260,9 @@ def set_batch_nos(doc, warehouse_field, throw=False, child_table="items"):
warehouse = d.get(warehouse_field, None)
if warehouse and qty > 0 and frappe.db.get_value("Item", d.item_code, "has_batch_no"):
if not d.batch_no:
d.batch_no = get_batch_no(d.item_code, warehouse, qty, throw, d.serial_no)
d.batch_no = get_batch_no(d.item_code, warehouse, qty, throw, d.serial_no).get(
"batch_no", None
)
else:
batch_qty = get_batch_qty(batch_no=d.batch_no, warehouse=warehouse)
if flt(batch_qty, d.precision("qty")) < flt(qty, d.precision("qty")):
@@ -282,6 +284,7 @@ def get_batch_no(item_code, warehouse, qty=1, throw=False, serial_no=None):
"""
batch_no = None
message = None
batches = get_batches(item_code, warehouse, qty, throw, serial_no)
for batch in batches:
@@ -290,15 +293,18 @@ def get_batch_no(item_code, warehouse, qty=1, throw=False, serial_no=None):
break
if not batch_no:
frappe.msgprint(
_(
"Please select a Batch for Item {0}. Unable to find a single batch that fulfills this requirement"
).format(frappe.bold(item_code))
)
message = _(
"Please select a Batch for Item {0}. Unable to find a single batch that fulfills this requirement"
).format(frappe.bold(item_code))
if throw:
frappe.msgprint(
_(
"Please select a Batch for Item {0}. Unable to find a single batch that fulfills this requirement"
).format(frappe.bold(item_code))
)
raise UnableToSelectBatchError
return batch_no
return {"batch_no": batch_no, "msg_print": message}
def get_batches(item_code, warehouse, qty=1, throw=False, serial_no=None):

View File

@@ -99,7 +99,8 @@ class TestBatch(FrappeTestCase):
# shipped from FEFO batch
self.assertEqual(
delivery_note.items[0].batch_no, get_batch_no(item_code, receipt.items[0].warehouse, batch_qty)
delivery_note.items[0].batch_no,
get_batch_no(item_code, receipt.items[0].warehouse, batch_qty).get("batch_no", None),
)
def test_delivery_note_fail(self):
@@ -145,7 +146,8 @@ class TestBatch(FrappeTestCase):
# assert same batch is selected
self.assertEqual(
stock_entry.items[0].batch_no, get_batch_no(item_code, receipt.items[0].warehouse, batch_qty)
stock_entry.items[0].batch_no,
get_batch_no(item_code, receipt.items[0].warehouse, batch_qty).get("batch_no", None),
)
def test_batch_split(self):

View File

@@ -1262,7 +1262,9 @@ class StockEntry(StockController):
and ret.get("has_batch_no")
and not args.get("batch_no")
):
args.batch_no = get_batch_no(args["item_code"], args["s_warehouse"], args["qty"])
args.batch_no = get_batch_no(args["item_code"], args["s_warehouse"], args["qty"]).get(
"batch_no", None
)
if (
self.purpose == "Send to Subcontractor" and self.get("purchase_order") and args.get("item_code")

View File

@@ -153,7 +153,7 @@ def update_stock(args, out):
):
if out.has_batch_no and not args.get("batch_no"):
out.batch_no = get_batch_no(out.item_code, out.warehouse, out.qty)
out.batch_no = get_batch_no(out.item_code, out.warehouse, out.qty).get("batch_no", None)
actual_batch_qty = get_batch_qty(out.batch_no, out.warehouse, out.item_code)
if actual_batch_qty:
out.update(actual_batch_qty)

View File

@@ -9897,3 +9897,5 @@ Total Asset,Aktiva,
Total Liability,Verbindlichkeiten,
Total Equity,Eigenkapital,
Warehouse wise Stock Value,Warenwert nach Lager,
Discount Validity,Frist für den Rabatt,
Discount Validity Based On,Frist für den Rabatt berechnet sich nach,
Can't render this file because it is too large.