Merge branch 'hotfix'

This commit is contained in:
Nabin Hait 2017-12-06 14:17:14 +05:30
commit 7ff6e378dd
10 changed files with 181 additions and 44 deletions

View File

@ -4,7 +4,7 @@ import inspect
import frappe
from erpnext.hooks import regional_overrides
__version__ = '9.2.19'
__version__ = '9.2.20'
def get_default_company(user=None):
'''Get default company for user'''

View File

@ -26,7 +26,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Series",
"length": 0,
@ -432,7 +432,7 @@
"options": "<pre><h5>Message Example</h5>\n\n&lt;p&gt;Dear {{ doc.contact_person }},&lt;/p&gt;\n\n&lt;p&gt;Requesting payment for {{ doc.doctype }}, {{ doc.name }} for {{ doc.grand_total }}.&lt;/p&gt;\n\n&lt;a href=\"{{ payment_url }}\"&gt; click here to pay &lt;/a&gt;\n\n</pre>\n",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@ -728,7 +728,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-13 14:29:20.388372",
"modified": "2017-12-02 15:50:41.775006",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",

View File

@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "hash",
@ -10,20 +11,24 @@
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Valuation and Total",
"default": "Total",
"fieldname": "category",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Consider Tax or Charge for",
"length": 0,
"no_copy": 0,
@ -34,6 +39,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@ -41,6 +47,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -52,7 +59,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Add or Deduct",
"length": 0,
"no_copy": 0,
@ -63,6 +72,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@ -70,6 +80,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -80,7 +91,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Type",
"length": 0,
"no_copy": 0,
@ -91,6 +104,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@ -98,6 +112,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -109,7 +124,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reference Row #",
"length": 0,
"no_copy": 0,
@ -119,6 +136,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -126,6 +144,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -137,7 +156,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Is this Tax included in Basic Rate?",
"length": 0,
"no_copy": 0,
@ -146,6 +167,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 1,
"reqd": 0,
"search_index": 0,
@ -153,6 +175,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -163,13 +186,16 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -177,6 +203,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -187,7 +214,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Account Head",
"length": 0,
"no_copy": 0,
@ -198,6 +227,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@ -205,6 +235,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -216,7 +247,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Cost Center",
"length": 0,
"no_copy": 0,
@ -227,6 +260,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -234,17 +268,20 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description",
"fieldtype": "Text Editor",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 0,
@ -255,6 +292,7 @@
"print_hide_if_no_value": 0,
"print_width": "300px",
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@ -263,6 +301,7 @@
"width": "300px"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -273,7 +312,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -281,6 +322,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -288,6 +330,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -298,7 +341,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Rate",
"length": 0,
"no_copy": 0,
@ -308,6 +353,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -315,6 +361,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -325,7 +372,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -333,6 +382,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -340,6 +390,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -350,7 +401,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Amount",
"length": 0,
"no_copy": 0,
@ -361,6 +414,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -368,6 +422,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -378,7 +433,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Tax Amount After Discount Amount",
"length": 0,
"no_copy": 0,
@ -388,6 +445,7 @@
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -395,6 +453,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -405,7 +464,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Total",
"length": 0,
"no_copy": 0,
@ -416,6 +477,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -423,6 +485,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -433,7 +496,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -441,6 +506,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -448,6 +514,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -458,7 +525,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amount (Company Currency)",
"length": 0,
"no_copy": 0,
@ -468,6 +537,7 @@
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -475,6 +545,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -485,7 +556,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total (Company Currency)",
"length": 0,
"no_copy": 0,
@ -495,6 +568,7 @@
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -502,6 +576,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -512,7 +587,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Tax Amount After Discount Amount",
"length": 0,
"no_copy": 0,
@ -522,6 +599,7 @@
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -529,6 +607,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -539,7 +618,9 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Item Wise Tax Detail ",
"length": 0,
"no_copy": 0,
@ -549,6 +630,7 @@
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -556,6 +638,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -565,8 +648,10 @@
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Parenttype",
"length": 0,
"no_copy": 0,
@ -576,6 +661,7 @@
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -583,17 +669,17 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 1,
"hide_toolbar": 0,
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-08-26 03:20:22.118330",
"modified": "2017-12-05 13:37:44.483509",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Taxes and Charges",
@ -602,5 +688,7 @@
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"track_changes": 1,
"track_seen": 0
}

View File

@ -86,17 +86,20 @@ def get_accumulated_depreciations(assets, filters):
for d in assets:
asset = frappe.get_doc("Asset", d.name)
asset_depreciations.setdefault(d.asset_category, frappe._dict({
"accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
"depreciation_amount_during_the_period": 0,
"depreciation_eliminated_during_the_period": 0
}))
if d.asset_category in asset_depreciations:
asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] += asset.opening_accumulated_depreciation
else:
asset_depreciations.setdefault(d.asset_category, frappe._dict({
"accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
"depreciation_amount_during_the_period": 0,
"depreciation_eliminated_during_the_period": 0
}))
depr = asset_depreciations[d.asset_category]
for schedule in asset.get("schedules"):
if getdate(schedule.schedule_date) < getdate(filters.from_date):
if not asset.disposal_date and getdate(asset.disposal_date) >= getdate(filters.from_date):
if not asset.disposal_date or getdate(asset.disposal_date) >= getdate(filters.from_date):
depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount)
elif getdate(schedule.schedule_date) <= getdate(filters.to_date):
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)

View File

@ -134,8 +134,12 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
"account": "'" + _("Total") + "'",
"account_name": "'" + _("Total") + "'",
"warn_if_negative": True,
"opening_debit": 0.0,
"opening_credit": 0.0,
"debit": 0.0,
"credit": 0.0,
"closing_debit": 0.0,
"closing_credit": 0.0,
"parent_account": None,
"indent": 0,
"has_value": True,
@ -156,7 +160,10 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
total_row["debit"] += d["debit"]
total_row["credit"] += d["credit"]
total_row["opening_debit"] += d["opening_debit"]
total_row["opening_credit"] += d["opening_credit"]
total_row["closing_debit"] += (d["opening_debit"] + d["debit"])
total_row["closing_credit"] += (d["opening_credit"] + d["credit"])
return total_row

View File

@ -232,7 +232,7 @@ class EmailDigest(Document):
"new_quotations","pending_quotations","sales_order","purchase_order","pending_sales_orders","pending_purchase_orders",
"invoiced_amount", "payables", "bank_balance", "credit_balance"):
if self.get(key):
cache_key = "email_digest:card:{0}:{1}:{2}".format(self.company, self.frequency, key)
cache_key = "email_digest:card:{0}:{1}:{2}:{3}".format(self.company, self.frequency, key, self.from_date)
card = cache.get(cache_key)
if card:

View File

@ -81,7 +81,7 @@ class ItemGroup(NestedSet, WebsiteGenerator):
@frappe.whitelist(allow_guest=True)
def get_product_list_for_group(product_group=None, start=0, limit=10, search=None):
child_groups = ", ".join(['"' + i[0] + '"' for i in get_child_groups(product_group)])
child_groups = ", ".join(['"' + frappe.db.escape(i[0]) + '"' for i in get_child_groups(product_group)])
# base query
query = """select name, item_name, item_code, route, image, website_image, thumbnail, item_group,

View File

@ -65,31 +65,38 @@ frappe.ui.form.on('Batch', {
// move - ask for target warehouse and make stock entry
rows.find('.btn-move').on('click', function() {
var $btn = $(this);
frappe.prompt({
fieldname: 'to_warehouse',
label: __('To Warehouse'),
fieldtype: 'Link',
options: 'Warehouse'
},
(data) => {
frappe.call({
method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
args: {
item_code: frm.doc.item,
batch_no: frm.doc.name,
qty: $btn.attr('data-qty'),
from_warehouse: $btn.attr('data-warehouse'),
to_warehouse: data.to_warehouse
},
callback: (r) => {
frappe.show_alert(__('Stock Entry {0} created',
['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
frm.refresh();
},
});
},
__('Select Target Warehouse'),
__('Move')
const fields = [
{
fieldname: 'to_warehouse',
label: __('To Warehouse'),
fieldtype: 'Link',
options: 'Warehouse'
}
];
frappe.prompt(
fields,
(data) => {
frappe.call({
method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
args: {
item_code: frm.doc.item,
batch_no: frm.doc.name,
qty: $btn.attr('data-qty'),
from_warehouse: $btn.attr('data-warehouse'),
to_warehouse: data.to_warehouse,
source_document: frm.doc.reference_name,
reference_doctype: frm.doc.reference_doctype
},
callback: (r) => {
frappe.show_alert(__('Stock Entry {0} created',
['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
frm.refresh();
},
});
},
__('Select Target Warehouse'),
__('Move')
);
});

View File

@ -12,6 +12,7 @@ from erpnext import set_perpetual_inventory
from erpnext.stock.doctype.serial_no.serial_no import SerialNoDuplicateError
from erpnext.accounts.doctype.account.test_account import get_inventory_account
class TestPurchaseReceipt(unittest.TestCase):
def setUp(self):
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
@ -259,7 +260,7 @@ class TestPurchaseReceipt(unittest.TestCase):
item_code = frappe.db.get_value('Item', {'has_serial_no': 1})
if not item_code:
item = make_item("Test Serial Item 1", dict(has_serial_no = 1))
item = make_item("Test Serial Item 1", dict(has_serial_no=1))
item_code = item.name
serial_no = random_string(5)
@ -273,11 +274,13 @@ class TestPurchaseReceipt(unittest.TestCase):
serial_no=serial_no, basic_rate=100, do_not_submit=True)
self.assertRaises(SerialNoDuplicateError, se.submit)
def get_gl_entries(voucher_type, voucher_no):
return frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type=%s and voucher_no=%s
order by account desc""", (voucher_type, voucher_no), as_dict=1)
def make_purchase_receipt(**args):
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
pr = frappe.new_doc("Purchase Receipt")

View File

@ -20,6 +20,16 @@ def make_stock_entry(**args):
:do_not_save: Optional flag
:do_not_submit: Optional flag
'''
def process_serial_numbers(serial_nos_list):
serial_nos_list = [
'\n'.join(serial_num['serial_no'] for serial_num in serial_nos_list)
]
uniques = list(set(serial_nos_list[0].split('\n')))
return '\n'.join(uniques)
s = frappe.new_doc("Stock Entry")
args = frappe._dict(args)
@ -77,6 +87,25 @@ def make_stock_entry(**args):
if not args.cost_center:
args.cost_center = frappe.get_value('Company', s.company, 'cost_center')
if not args.expense_account:
args.expense_account = frappe.get_value('Company', s.company, 'stock_adjustment_account')
# We can find out the serial number using the batch source document
serial_number = args.serial_no
if not args.serial_no and args.qty and args.batch_no:
serial_number_list = frappe.get_list(
doctype='Stock Ledger Entry',
fields=['serial_no'],
filters={
'batch_no': args.batch_no,
'warehouse': args.from_warehouse
}
)
serial_number = process_serial_numbers(serial_number_list)
args.serial_no = serial_number
s.append("items", {
"item_code": args.item,
"s_warehouse": args.source,