mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 00:14:50 +00:00
Merge branch 'responsive' of github.com:webnotes/erpnext into responsive
Conflicts: selling/doctype/lead/lead.txt
This commit is contained in:
@@ -57,17 +57,10 @@ cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc
|
||||
|
||||
|
||||
cur_frm.cscript.get_items = function(doc,dt,dn) {
|
||||
var callback = function(r,rt){
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
if(r.message){
|
||||
doc.sales_order_no = r.message;
|
||||
if(doc.sales_order_no) {
|
||||
unhide_field(['customer_address','contact_person','territory','customer_group']);
|
||||
}
|
||||
cur_frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'pull_sales_order_details','',callback);
|
||||
wn.model.map_current_doc({
|
||||
method: "selling.doctype.sales_order.sales_order.make_delivery_note",
|
||||
source_name: cur_frm.doc.sales_order_no,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -60,19 +60,6 @@ class DocType(SellingController):
|
||||
"""Get Commission rate of Sales Partner"""
|
||||
return get_obj('Sales Common').get_comm_rate(sales_partner, self)
|
||||
|
||||
|
||||
def pull_sales_order_details(self):
|
||||
self.validate_prev_docname()
|
||||
self.doclist = self.doc.clear_table(self.doclist,'other_charges')
|
||||
|
||||
if self.doc.sales_order_no:
|
||||
get_obj('DocType Mapper', 'Sales Order-Delivery Note').dt_map('Sales Order', 'Delivery Note', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Delivery Note'],['Sales Order Item', 'Delivery Note Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]")
|
||||
else:
|
||||
msgprint("Please select Sales Order No. whose details need to be pulled")
|
||||
|
||||
return cstr(self.doc.sales_order_no)
|
||||
|
||||
|
||||
def validate_prev_docname(self):
|
||||
"""Validates that Sales Order is not pulled twice"""
|
||||
for d in getlist(self.doclist, 'delivery_note_details'):
|
||||
|
||||
@@ -21,6 +21,8 @@ cur_frm.cscript.refresh = function(doc) {
|
||||
// make sensitive fields(has_serial_no, is_stock_item, valuation_method)
|
||||
// read only if any stock ledger entry exists
|
||||
|
||||
cur_frm.cscript.make_dashboard()
|
||||
|
||||
cur_frm.toggle_display("naming_series", sys_defaults.item_naming_by=="Naming Series"
|
||||
&& doc.__islocal)
|
||||
cur_frm.toggle_display("item_code", sys_defaults.item_naming_by!="Naming Series"
|
||||
@@ -36,6 +38,12 @@ cur_frm.cscript.refresh = function(doc) {
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_dashboard = function() {
|
||||
cur_frm.dashboard.reset();
|
||||
if(doc.__islocal)
|
||||
return;
|
||||
}
|
||||
|
||||
cur_frm.cscript.item_code = function(doc) {
|
||||
if(!doc.item_name) cur_frm.set_value("item_name", doc.item_code);
|
||||
if(!doc.description) cur_frm.set_value("description", doc.item_code);
|
||||
|
||||
@@ -204,7 +204,7 @@ class DocType(DocListController):
|
||||
|
||||
if vals and ((self.doc.is_stock_item == "No" and vals.is_stock_item == "Yes") or
|
||||
vals.has_serial_no != self.doc.has_serial_no or
|
||||
vals.valuation_method != self.doc.valuation_method):
|
||||
cstr(vals.valuation_method) != cstr(self.doc.valuation_method)):
|
||||
if self.check_if_sle_exists() == "exists":
|
||||
webnotes.msgprint(_("As there are existing stock transactions for this \
|
||||
item, you can not change the values of 'Has Serial No', \
|
||||
|
||||
@@ -24,6 +24,16 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten
|
||||
refresh: function(doc) {
|
||||
this._super();
|
||||
|
||||
// dashboard
|
||||
cur_frm.dashboard.reset();
|
||||
if(doc.docstatus===1) {
|
||||
if(doc.status==="Stopped") {
|
||||
cur_frm.dashboard.set_headline_alert(wn._("Stopped"), "alert-danger", "icon-stop")
|
||||
}
|
||||
cur_frm.dashboard.add_progress(cint(doc.per_ordered) + "% "
|
||||
+ wn._("Fulfilled"), cint(doc.per_ordered));
|
||||
}
|
||||
|
||||
if(doc.docstatus == 1 && doc.status != 'Stopped'){
|
||||
if(doc.material_request_type === "Purchase")
|
||||
cur_frm.add_custom_button("Make Supplier Quotation", cur_frm.cscript.make_supplier_quotation);
|
||||
@@ -92,13 +102,19 @@ cur_frm.cscript['Unstop Material Request'] = function(){
|
||||
};
|
||||
|
||||
cur_frm.cscript['Make Purchase Order'] = function() {
|
||||
cur_frm.map([["Material Request", "Purchase Order"], ["Material Request Item", "Purchase Order Item"]]);
|
||||
cur_frm.map([
|
||||
["Material Request", "Purchase Order"],
|
||||
["Material Request Item", "Purchase Order Item"]]);
|
||||
};
|
||||
|
||||
cur_frm.cscript.make_supplier_quotation = function() {
|
||||
cur_frm.map([["Material Request", "Supplier Quotation"], ["Material Request Item", "Supplier Quotation Item"]]);
|
||||
cur_frm.map([
|
||||
["Material Request", "Supplier Quotation"],
|
||||
["Material Request Item", "Supplier Quotation Item"]]);
|
||||
};
|
||||
|
||||
cur_frm.cscript.make_stock_entry = function() {
|
||||
cur_frm.map([["Material Request", "Stock Entry"], ["Material Request Item", "Stock Entry Detail"]]);
|
||||
cur_frm.map([
|
||||
["Material Request", "Stock Entry"],
|
||||
["Material Request Item", "Stock Entry Detail"]]);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-03-07 14:48:38",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-11 16:16:36",
|
||||
"modified": "2013-07-04 10:24:53",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -44,6 +44,13 @@
|
||||
"doctype": "DocType",
|
||||
"name": "Material Request"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "type_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Type",
|
||||
"options": "icon-pushpin"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "material_request_type",
|
||||
@@ -76,7 +83,8 @@
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Items",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-shopping-cart"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
@@ -92,8 +100,7 @@
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "section_break1",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "Simple"
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -131,12 +138,12 @@
|
||||
},
|
||||
{
|
||||
"default": "Give additional details about the indent.",
|
||||
"description": "Filing in Additional Information about the Material Request will help you analyze your data better.",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-file-text"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -287,7 +294,8 @@
|
||||
"fieldname": "terms_section_break",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Terms and Conditions",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-legal"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
|
||||
@@ -466,20 +466,23 @@ class DocType(StockController):
|
||||
item_dict = self.get_bom_raw_materials(self.doc.fg_completed_qty)
|
||||
|
||||
# add raw materials to Stock Entry Detail table
|
||||
self.add_to_stock_entry_detail(self.doc.from_warehouse, self.doc.to_warehouse,
|
||||
item_dict)
|
||||
self.add_to_stock_entry_detail(item_dict)
|
||||
|
||||
# add finished good item to Stock Entry Detail table -- along with bom_no
|
||||
if self.doc.production_order and self.doc.purpose == "Manufacture/Repack":
|
||||
self.add_to_stock_entry_detail(None, pro_obj.doc.fg_warehouse, {
|
||||
self.doc.to_warehouse = pro_obj.doc.fg_warehouse
|
||||
self.add_to_stock_entry_detail({
|
||||
cstr(pro_obj.doc.production_item):
|
||||
[self.doc.fg_completed_qty, pro_obj.doc.description, pro_obj.doc.stock_uom]
|
||||
}, bom_no=pro_obj.doc.bom_no)
|
||||
|
||||
elif self.doc.purpose in ["Material Receipt", "Manufacture/Repack"]:
|
||||
if self.doc.purpose=="Material Receipt":
|
||||
self.doc.from_warehouse = ""
|
||||
|
||||
item = webnotes.conn.sql("""select item, description, uom from `tabBOM`
|
||||
where name=%s""", (self.doc.bom_no,), as_dict=1)
|
||||
self.add_to_stock_entry_detail(None, self.doc.to_warehouse, {
|
||||
self.add_to_stock_entry_detail({
|
||||
item[0]["item"] :
|
||||
[self.doc.fg_completed_qty, item[0]["description"], item[0]["uom"]]
|
||||
}, bom_no=self.doc.bom_no)
|
||||
@@ -492,36 +495,56 @@ class DocType(StockController):
|
||||
child items of sub-contracted and sub assembly items
|
||||
and sub assembly items itself.
|
||||
"""
|
||||
# item dict = { item_code: [qty, description, stock_uom] }
|
||||
# item dict = { item_code: {qty, description, stock_uom} }
|
||||
item_dict = {}
|
||||
|
||||
def _make_items_dict(items_list):
|
||||
"""makes dict of unique items with it's qty"""
|
||||
for item in items_list:
|
||||
if item_dict.has_key(item.item_code):
|
||||
item_dict[item.item_code][0] += flt(item.qty)
|
||||
item_dict[item.item_code]["qty"] += flt(item.qty)
|
||||
else:
|
||||
item_dict[item.item_code] = [flt(item.qty), item.description, item.stock_uom]
|
||||
item_dict[item.item_code] = {
|
||||
"qty": flt(item.qty),
|
||||
"description": item.description,
|
||||
"stock_uom": item.stock_uom,
|
||||
"from_warehouse": item.default_warehouse
|
||||
}
|
||||
|
||||
if self.doc.use_multi_level_bom:
|
||||
# get all raw materials with sub assembly childs
|
||||
fl_bom_sa_child_item = sql("""select fb.item_code,
|
||||
ifnull(sum(fb.qty_consumed_per_unit),0)*%s as qty, fb.description, fb.stock_uom
|
||||
from `tabBOM Explosion Item` fb,`tabItem` it
|
||||
where it.name = fb.item_code and ifnull(it.is_pro_applicable, 'No') = 'No'
|
||||
and ifnull(it.is_sub_contracted_item, 'No') = 'No' and fb.docstatus < 2
|
||||
and fb.parent=%s group by item_code, stock_uom""",
|
||||
fl_bom_sa_child_item = sql("""select
|
||||
fb.item_code,
|
||||
ifnull(sum(fb.qty_consumed_per_unit),0)*%s as qty,
|
||||
fb.description,
|
||||
fb.stock_uom,
|
||||
it.default_warehouse
|
||||
from
|
||||
`tabBOM Explosion Item` fb,`tabItem` it
|
||||
where
|
||||
it.name = fb.item_code
|
||||
and ifnull(it.is_pro_applicable, 'No') = 'No'
|
||||
and ifnull(it.is_sub_contracted_item, 'No') = 'No'
|
||||
and fb.docstatus < 2
|
||||
and fb.parent=%s group by item_code, stock_uom""",
|
||||
(qty, self.doc.bom_no), as_dict=1)
|
||||
|
||||
if fl_bom_sa_child_item:
|
||||
_make_items_dict(fl_bom_sa_child_item)
|
||||
else:
|
||||
# Get all raw materials considering multi level BOM,
|
||||
# if multi level bom consider childs of Sub-Assembly items
|
||||
fl_bom_sa_items = sql("""select item_code,
|
||||
ifnull(sum(qty_consumed_per_unit), 0) *%s as qty,
|
||||
description, stock_uom from `tabBOM Item`
|
||||
where parent = %s and docstatus < 2
|
||||
# get only BOM items
|
||||
fl_bom_sa_items = sql("""select
|
||||
`tabItem`.item_code,
|
||||
ifnull(sum(`tabBOM Item`.qty_consumed_per_unit), 0) *%s as qty,
|
||||
`tabItem`.description,
|
||||
`tabItem`.stock_uom,
|
||||
`tabItem`.default_warehouse
|
||||
from
|
||||
`tabBOM Item`, `tabItem`
|
||||
where
|
||||
`tabBOM Item`.parent = %s and
|
||||
`tabBOM Item`.item_code = tabItem.name
|
||||
`tabBOM Item`.docstatus < 2
|
||||
group by item_code""", (qty, self.doc.bom_no), as_dict=1)
|
||||
|
||||
if fl_bom_sa_items:
|
||||
@@ -534,30 +557,30 @@ class DocType(StockController):
|
||||
issue (item quantity) that is pending to issue or desire to transfer,
|
||||
whichever is less
|
||||
"""
|
||||
item_qty = self.get_bom_raw_materials(1)
|
||||
item_dict = self.get_bom_raw_materials(1)
|
||||
issued_item_qty = self.get_issued_qty()
|
||||
|
||||
max_qty = flt(pro_obj.doc.qty)
|
||||
only_pending_fetched = []
|
||||
|
||||
for item in item_qty:
|
||||
pending_to_issue = (max_qty * item_qty[item][0]) - issued_item_qty.get(item, 0)
|
||||
desire_to_transfer = flt(self.doc.fg_completed_qty) * item_qty[item][0]
|
||||
for item in item_dict:
|
||||
pending_to_issue = (max_qty * item_dict[item]["qty"]) - issued_item_qty.get(item, 0)
|
||||
desire_to_transfer = flt(self.doc.fg_completed_qty) * item_dict[item]["qty"]
|
||||
|
||||
if desire_to_transfer <= pending_to_issue:
|
||||
item_qty[item][0] = desire_to_transfer
|
||||
item_dict[item]["qty"] = desire_to_transfer
|
||||
else:
|
||||
item_qty[item][0] = pending_to_issue
|
||||
item_dict[item]["qty"] = pending_to_issue
|
||||
if pending_to_issue:
|
||||
only_pending_fetched.append(item)
|
||||
|
||||
# delete items with 0 qty
|
||||
for item in item_qty.keys():
|
||||
if not item_qty[item][0]:
|
||||
del item_qty[item]
|
||||
for item in item_dict.keys():
|
||||
if not item_dict[item]["qty"]:
|
||||
del item_dict[item]
|
||||
|
||||
# show some message
|
||||
if not len(item_qty):
|
||||
if not len(item_dict):
|
||||
webnotes.msgprint(_("""All items have already been transferred \
|
||||
for this Production Order."""))
|
||||
|
||||
@@ -565,7 +588,7 @@ class DocType(StockController):
|
||||
webnotes.msgprint(_("""Only quantities pending to be transferred \
|
||||
were fetched for the following items:\n""" + "\n".join(only_pending_fetched)))
|
||||
|
||||
return item_qty
|
||||
return item_dict
|
||||
|
||||
def get_issued_qty(self):
|
||||
issued_item_qty = {}
|
||||
@@ -579,18 +602,20 @@ class DocType(StockController):
|
||||
|
||||
return issued_item_qty
|
||||
|
||||
def add_to_stock_entry_detail(self, source_wh, target_wh, item_dict, bom_no=None):
|
||||
def add_to_stock_entry_detail(self, item_dict, bom_no=None):
|
||||
for d in item_dict:
|
||||
se_child = addchild(self.doc, 'mtn_details', 'Stock Entry Detail',
|
||||
self.doclist)
|
||||
se_child.s_warehouse = source_wh
|
||||
se_child.t_warehouse = target_wh
|
||||
se_child.s_warehouse = item_dict[d].get("from_warehouse", self.doc.from_warehouse)
|
||||
se_child.t_warehouse = item_dict[d].get("to_warehouse", self.doc.to_warehouse)
|
||||
se_child.item_code = cstr(d)
|
||||
se_child.description = item_dict[d][1]
|
||||
se_child.uom = item_dict[d][2]
|
||||
se_child.stock_uom = item_dict[d][2]
|
||||
se_child.qty = flt(item_dict[d][0])
|
||||
se_child.transfer_qty = flt(item_dict[d][0])
|
||||
se_child.description = item_dict[d]["description"]
|
||||
se_child.uom = item_dict[d]["stock_uom"]
|
||||
se_child.stock_uom = item_dict[d]["stock_uom"]
|
||||
se_child.qty = flt(item_dict[d]["qty"])
|
||||
|
||||
# in stock uom
|
||||
se_child.transfer_qty = flt(item_dict[d]["qty"])
|
||||
se_child.conversion_factor = 1.00
|
||||
|
||||
# to be assigned for finished item
|
||||
|
||||
@@ -6,6 +6,11 @@ import webnotes, unittest
|
||||
from webnotes.utils import flt
|
||||
|
||||
class TestStockEntry(unittest.TestCase):
|
||||
def tearDown(self):
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
if hasattr(self, "old_default_company"):
|
||||
webnotes.conn.set_default("company", self.old_default_company)
|
||||
|
||||
def test_auto_material_request(self):
|
||||
webnotes.conn.sql("""delete from `tabMaterial Request Item`""")
|
||||
webnotes.conn.sql("""delete from `tabMaterial Request`""")
|
||||
@@ -72,8 +77,6 @@ class TestStockEntry(unittest.TestCase):
|
||||
["Stock Adjustment - _TC", 5000.0, 0.0]
|
||||
])
|
||||
)
|
||||
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
|
||||
def test_material_issue_gl_entry(self):
|
||||
self._clear_stock()
|
||||
@@ -115,9 +118,6 @@ class TestStockEntry(unittest.TestCase):
|
||||
])
|
||||
)
|
||||
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
webnotes.conn.set_default("company", self.old_default_company)
|
||||
|
||||
def test_material_transfer_gl_entry(self):
|
||||
self._clear_stock()
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||
@@ -149,10 +149,7 @@ class TestStockEntry(unittest.TestCase):
|
||||
gl_entries = webnotes.conn.sql("""select * from `tabGL Entry`
|
||||
where voucher_type = 'Stock Entry' and voucher_no=%s""", mtn.doc.name)
|
||||
self.assertFalse(gl_entries)
|
||||
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
webnotes.conn.set_default("company", self.old_default_company)
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -7,6 +7,11 @@ wn.module_page["Stock"] = [
|
||||
top: true,
|
||||
icon: "icon-copy",
|
||||
items: [
|
||||
{
|
||||
label: wn._("Item"),
|
||||
description: wn._("All Products or Services."),
|
||||
doctype:"Item"
|
||||
},
|
||||
{
|
||||
label: wn._("Material Request"),
|
||||
description: wn._("Requests for items."),
|
||||
@@ -33,11 +38,6 @@ wn.module_page["Stock"] = [
|
||||
title: wn._("Masters"),
|
||||
icon: "icon-book",
|
||||
items: [
|
||||
{
|
||||
label: wn._("Item"),
|
||||
description: wn._("All Products or Services."),
|
||||
doctype:"Item"
|
||||
},
|
||||
{
|
||||
label: wn._("Serial No"),
|
||||
description: wn._("Single unit of an Item."),
|
||||
|
||||
Reference in New Issue
Block a user