mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-13 10:11:20 +00:00
Merge branch 'master' of github.com:webnotes/erpnext
This commit is contained in:
@@ -225,7 +225,12 @@ class DocType(SellingController):
|
||||
bin = sql("select actual_qty, projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
|
||||
d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
|
||||
d.projected_qty = bin and flt(bin[0]['projected_qty']) or 0
|
||||
|
||||
|
||||
def on_update(self):
|
||||
self.doclist = get_obj('Sales Common').make_packing_list(self,'delivery_note_details')
|
||||
sl = get_obj('Stock Ledger')
|
||||
sl.scrub_serial_nos(self)
|
||||
sl.scrub_serial_nos(self, 'packing_details')
|
||||
|
||||
def on_submit(self):
|
||||
self.validate_packed_qty()
|
||||
@@ -252,6 +257,7 @@ class DocType(SellingController):
|
||||
|
||||
self.credit_limit()
|
||||
|
||||
self.set_buying_amount()
|
||||
self.make_gl_entries()
|
||||
|
||||
# set DN status
|
||||
@@ -387,13 +393,19 @@ class DocType(SellingController):
|
||||
if amount != 0:
|
||||
total = (amount/self.doc.net_total)*self.doc.grand_total
|
||||
get_obj('Sales Common').check_credit(self, total)
|
||||
|
||||
|
||||
def on_update(self):
|
||||
self.doclist = get_obj('Sales Common').make_packing_list(self,'delivery_note_details')
|
||||
sl = get_obj('Stock Ledger')
|
||||
sl.scrub_serial_nos(self)
|
||||
sl.scrub_serial_nos(self, 'packing_details')
|
||||
|
||||
def set_buying_amount(self):
|
||||
from stock.utils import get_buying_amount, get_sales_bom
|
||||
stock_ledger_entries = self.get_stock_ledger_entries()
|
||||
item_sales_bom = get_sales_bom()
|
||||
|
||||
if stock_ledger_entries:
|
||||
for item in self.doclist.get({"parentfield": "delivery_note_details"}):
|
||||
item.buying_amount = get_buying_amount(item.item_code, item.warehouse, item.qty,
|
||||
self.doc.doctype, self.doc.name, item.name, stock_ledger_entries,
|
||||
item_sales_bom)
|
||||
webnotes.conn.set_value("Delivery Note Item", item.name, "buying_amount",
|
||||
item.buying_amount)
|
||||
|
||||
self.validate_warehouse()
|
||||
|
||||
@@ -435,38 +447,6 @@ class DocType(SellingController):
|
||||
make_gl_entries(gl_entries, cancel=self.doc.docstatus == 2)
|
||||
|
||||
def get_total_buying_amount(self):
|
||||
from stock.utils import get_buying_amount, get_sales_bom
|
||||
stock_ledger_entries = self.get_stock_ledger_entries()
|
||||
item_sales_bom = get_sales_bom()
|
||||
total_buying_amount = 0
|
||||
|
||||
if stock_ledger_entries:
|
||||
for item in self.doclist.get({"parentfield": "delivery_note_details"}):
|
||||
buying_amount = get_buying_amount(item.item_code, item.warehouse, item.qty,
|
||||
self.doc.name, item.name, stock_ledger_entries, item_sales_bom)
|
||||
total_buying_amount += buying_amount
|
||||
|
||||
total_buying_amount = sum([item.buying_amount for item in
|
||||
self.doclist.get({"parentfield": "delivery_note_details"})])
|
||||
return total_buying_amount
|
||||
|
||||
def get_stock_ledger_entries(self):
|
||||
item_list, warehouse_list = self.get_distinct_item_warehouse()
|
||||
if item_list and warehouse_list:
|
||||
return webnotes.conn.sql("""select item_code, voucher_type, voucher_no,
|
||||
voucher_detail_no, posting_date, posting_time, stock_value,
|
||||
warehouse, actual_qty as qty from `tabStock Ledger Entry`
|
||||
where ifnull(`is_cancelled`, "No") = "No" and company = %s
|
||||
and item_code in (%s) and warehouse in (%s)
|
||||
order by item_code desc, warehouse desc, posting_date desc,
|
||||
posting_time desc, name desc""" %
|
||||
('%s', ', '.join(['%s']*len(item_list)), ', '.join(['%s']*len(warehouse_list))),
|
||||
tuple([self.doc.company] + item_list + warehouse_list), as_dict=1)
|
||||
|
||||
def get_distinct_item_warehouse(self):
|
||||
item_list = []
|
||||
warehouse_list = []
|
||||
for item in self.doclist.get({"parentfield": "delivery_note_details"}) \
|
||||
+ self.doclist.get({"parentfield": "packing_details"}):
|
||||
item_list.append(item.item_code)
|
||||
warehouse_list.append(item.warehouse)
|
||||
|
||||
return list(set(item_list)), list(set(warehouse_list))
|
||||
@@ -48,6 +48,8 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
|
||||
def test_delivery_note_gl_entry(self):
|
||||
webnotes.conn.sql("""delete from `tabBin`""")
|
||||
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
||||
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||
self.assertEqual(cint(webnotes.defaults.get_global_default("auto_inventory_accounting")), 1)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-02-22 01:28:00",
|
||||
"creation": "2013-03-07 11:42:59",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-03-07 07:03:20",
|
||||
"modified": "2013-03-07 15:46:43",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -30,7 +30,8 @@
|
||||
"fieldname": "barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Barcode",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -42,6 +43,7 @@
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"print_width": "150px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"width": "150px"
|
||||
@@ -64,6 +66,7 @@
|
||||
"oldfieldtype": "Data",
|
||||
"print_hide": 1,
|
||||
"print_width": "150px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"width": "150px"
|
||||
},
|
||||
@@ -75,6 +78,7 @@
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
"print_width": "300px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"width": "300px"
|
||||
},
|
||||
@@ -87,6 +91,7 @@
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"width": "100px"
|
||||
},
|
||||
@@ -115,6 +120,7 @@
|
||||
"options": "currency",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"reqd": 0,
|
||||
"width": "100px"
|
||||
},
|
||||
@@ -128,6 +134,7 @@
|
||||
"oldfieldtype": "Float",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
@@ -140,6 +147,7 @@
|
||||
"options": "currency",
|
||||
"print_hide": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 0,
|
||||
"reqd": 0,
|
||||
"width": "150px"
|
||||
},
|
||||
@@ -181,6 +189,7 @@
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"print_width": "150px",
|
||||
"read_only": 0,
|
||||
"reqd": 0,
|
||||
"width": "150px"
|
||||
},
|
||||
@@ -208,6 +217,7 @@
|
||||
"options": "Warehouse",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
@@ -219,7 +229,8 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "serial_no",
|
||||
"oldfieldtype": "Text",
|
||||
"print_hide": 0
|
||||
"print_hide": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -229,7 +240,8 @@
|
||||
"oldfieldname": "batch_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Batch",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -375,6 +387,17 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "buying_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Buying Amount",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"doctype": "DocField",
|
||||
@@ -383,6 +406,7 @@
|
||||
"label": "Page Break",
|
||||
"oldfieldname": "page_break",
|
||||
"oldfieldtype": "Check",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
}
|
||||
]
|
||||
@@ -127,4 +127,23 @@ test_records = [
|
||||
"is_sub_contracted_item": "Yes",
|
||||
"stock_uom": "_Test UOM"
|
||||
}],
|
||||
[{
|
||||
"doctype": "Item",
|
||||
"item_code": "_Test Non Stock Item",
|
||||
"item_name": "_Test Non Stock Item",
|
||||
"description": "_Test Non Stock Item",
|
||||
"item_group": "_Test Item Group Desktops",
|
||||
"is_stock_item": "No",
|
||||
"is_asset_item": "No",
|
||||
"has_batch_no": "No",
|
||||
"has_serial_no": "No",
|
||||
"is_purchase_item": "Yes",
|
||||
"is_sales_item": "Yes",
|
||||
"is_service_item": "No",
|
||||
"is_sample_item": "No",
|
||||
"inspection_required": "No",
|
||||
"is_pro_applicable": "No",
|
||||
"is_sub_contracted_item": "No",
|
||||
"stock_uom": "_Test UOM"
|
||||
}],
|
||||
]
|
||||
@@ -21,6 +21,77 @@ class TestStockEntry(unittest.TestCase):
|
||||
where item_code='_Test Item'""")
|
||||
|
||||
self.assertTrue(mr_name)
|
||||
|
||||
def test_material_receipt_gl_entry(self):
|
||||
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||
|
||||
mr = webnotes.bean(copy=test_records[0])
|
||||
mr.insert()
|
||||
mr.submit()
|
||||
|
||||
stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company",
|
||||
"stock_in_hand_account")
|
||||
|
||||
self.check_stock_ledger_entries("Stock Entry", mr.doc.name,
|
||||
[["_Test Item", "_Test Warehouse", 50.0]])
|
||||
|
||||
self.check_gl_entries("Stock Entry", mr.doc.name,
|
||||
sorted([
|
||||
[stock_in_hand_account, 5000.0, 0.0],
|
||||
["Stock Adjustment - _TC", 0.0, 5000.0]
|
||||
])
|
||||
)
|
||||
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
|
||||
def test_material_issue_gl_entry(self):
|
||||
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||
|
||||
mr = webnotes.bean(copy=test_records[0])
|
||||
mr.insert()
|
||||
mr.submit()
|
||||
|
||||
stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company",
|
||||
"stock_in_hand_account")
|
||||
|
||||
self.check_stock_ledger_entries("Stock Entry", mr.doc.name,
|
||||
[["_Test Item", "_Test Warehouse", 50.0]])
|
||||
|
||||
self.check_gl_entries("Stock Entry", mr.doc.name,
|
||||
sorted([
|
||||
[stock_in_hand_account, 5000.0, 0.0],
|
||||
["Stock Adjustment - _TC", 0.0, 5000.0]
|
||||
])
|
||||
)
|
||||
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
|
||||
def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle):
|
||||
# check stock ledger entries
|
||||
sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry`
|
||||
where voucher_type = %s and voucher_no = %s order by item_code, warehouse""",
|
||||
(voucher_type, voucher_no), as_dict=1)
|
||||
self.assertTrue(sle)
|
||||
|
||||
for i, sle in enumerate(sle):
|
||||
self.assertEquals(expected_sle[i][0], sle.item_code)
|
||||
self.assertEquals(expected_sle[i][1], sle.warehouse)
|
||||
self.assertEquals(expected_sle[i][2], sle.actual_qty)
|
||||
|
||||
def check_gl_entries(self, voucher_type, voucher_no, expected_gl_entries):
|
||||
# check gl entries
|
||||
|
||||
gl_entries = webnotes.conn.sql("""select account, debit, credit
|
||||
from `tabGL Entry` where voucher_type=%s and voucher_no=%s
|
||||
order by account asc, debit asc""", (voucher_type, voucher_no), as_dict=1)
|
||||
self.assertTrue(gl_entries)
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_gl_entries[i][0], gle.account)
|
||||
self.assertEquals(expected_gl_entries[i][1], gle.debit)
|
||||
self.assertEquals(expected_gl_entries[i][2], gle.credit)
|
||||
|
||||
test_records = [
|
||||
[
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-01-10 16:34:30",
|
||||
"creation": "2013-03-07 18:50:32",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-02-04 11:35:53",
|
||||
"modified": "2013-03-11 17:58:45",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -21,7 +21,8 @@
|
||||
"name": "__common__",
|
||||
"parent": "Warehouse",
|
||||
"parentfield": "fields",
|
||||
"parenttype": "DocType"
|
||||
"parenttype": "DocType",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
@@ -190,7 +191,7 @@
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "This feature is for merging duplicate warehouses. It will replace all the links of this warehouse by \"Merge With\" warehouse. After merging you can delete this warehouse, as stock level for this warehouse will be zero.",
|
||||
"description": "This feature is for merging duplicate warehouses. It will replace all the links of this warehouse by \"Merge Into\" warehouse. After merging you can delete this warehouse, as stock level for this warehouse will be zero.",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "merge_warehouses_section",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -201,7 +202,7 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "merge_with",
|
||||
"fieldtype": "Link",
|
||||
"label": "Merge With",
|
||||
"label": "Merge Into",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 2
|
||||
},
|
||||
@@ -221,24 +222,6 @@
|
||||
"role": "Material Master Manager",
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"role": "Material User",
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 2,
|
||||
"role": "Material User",
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
@@ -248,6 +231,26 @@
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"role": "Material Manager",
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"role": "Material User",
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 2,
|
||||
|
||||
@@ -36,7 +36,6 @@ def update_entries_after(args, verbose=1):
|
||||
}
|
||||
"""
|
||||
previous_sle = get_sle_before_datetime(args)
|
||||
|
||||
qty_after_transaction = flt(previous_sle.get("qty_after_transaction"))
|
||||
valuation_rate = flt(previous_sle.get("valuation_rate"))
|
||||
stock_queue = json.loads(previous_sle.get("stock_queue") or "[]")
|
||||
@@ -214,7 +213,6 @@ def get_moving_average_values(qty_after_transaction, sle, valuation_rate):
|
||||
def get_fifo_values(qty_after_transaction, sle, stock_queue):
|
||||
incoming_rate = flt(sle.incoming_rate)
|
||||
actual_qty = flt(sle.actual_qty)
|
||||
|
||||
if not stock_queue:
|
||||
stock_queue.append([0, 0])
|
||||
|
||||
|
||||
@@ -164,23 +164,24 @@ def get_warehouse_list(doctype, txt, searchfield, start, page_len, filters):
|
||||
wlist.append([w])
|
||||
return wlist
|
||||
|
||||
def get_buying_amount(item_code, warehouse, qty, voucher_no, voucher_detail_no,
|
||||
def get_buying_amount(item_code, warehouse, qty, voucher_type, voucher_no, voucher_detail_no,
|
||||
stock_ledger_entries, item_sales_bom):
|
||||
if item_sales_bom.get(item_code):
|
||||
# sales bom item
|
||||
buying_amount = 0.0
|
||||
for bom_item in item_sales_bom[item_code]:
|
||||
buying_amount += _get_buying_amount(voucher_no, "[** No Item Row **]",
|
||||
buying_amount += _get_buying_amount(voucher_type, voucher_no, "[** No Item Row **]",
|
||||
item_code, warehouse, bom_item.qty * qty, stock_ledger_entries)
|
||||
return buying_amount
|
||||
else:
|
||||
# doesn't have sales bom
|
||||
return _get_buying_amount(voucher_no, voucher_detail_no, item_code, warehouse, qty,
|
||||
stock_ledger_entries)
|
||||
return _get_buying_amount(voucher_type, voucher_no, voucher_detail_no,
|
||||
item_code, warehouse, qty, stock_ledger_entries)
|
||||
|
||||
def _get_buying_amount(voucher_no, item_row, item_code, warehouse, qty, stock_ledger_entries):
|
||||
def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse, qty,
|
||||
stock_ledger_entries):
|
||||
for i, sle in enumerate(stock_ledger_entries):
|
||||
if sle.voucher_type == "Delivery Note" and sle.voucher_no == voucher_no:
|
||||
if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no:
|
||||
if (sle.voucher_detail_no == item_row) or \
|
||||
(sle.item_code == item_code and sle.warehouse == warehouse and \
|
||||
abs(flt(sle.qty)) == qty):
|
||||
|
||||
Reference in New Issue
Block a user