feat: Material Request and Stock Entry Enhancement (#22671)

* feat: send to warehouse

* adding warehouse validation

* fix: review changes

* fix: review changes

* stock entry enhancement

* fix: review changes
This commit is contained in:
Anupam Kumar 2020-08-12 17:55:02 +05:30 committed by GitHub
parent e0cc421e50
commit 674d1b0803
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 177 additions and 140 deletions

View File

@ -718,3 +718,4 @@ erpnext.patches.v13_0.delete_report_requested_items_to_order
erpnext.patches.v12_0.update_item_tax_template_company erpnext.patches.v12_0.update_item_tax_template_company
erpnext.patches.v13_0.move_branch_code_to_bank_account erpnext.patches.v13_0.move_branch_code_to_bank_account
erpnext.patches.v13_0.healthcare_lab_module_rename_doctypes erpnext.patches.v13_0.healthcare_lab_module_rename_doctypes
erpnext.patches.v13_0.stock_entry_enhancements

View File

@ -19,7 +19,7 @@ def create_stock_entry_types():
for purpose in ["Material Issue", "Material Receipt", "Material Transfer", for purpose in ["Material Issue", "Material Receipt", "Material Transfer",
"Material Transfer for Manufacture", "Material Consumption for Manufacture", "Manufacture", "Material Transfer for Manufacture", "Material Consumption for Manufacture", "Manufacture",
"Repack", "Send to Subcontractor", "Send to Warehouse", "Receive at Warehouse"]: "Repack", "Send to Subcontractor"]:
ste_type = frappe.get_doc({ ste_type = frappe.get_doc({
'doctype': 'Stock Entry Type', 'doctype': 'Stock Entry Type',

View File

@ -0,0 +1,27 @@
# Copyright(c) 2020, Frappe Technologies Pvt.Ltd.and Contributors
# License: GNU General Public License v3.See license.txt
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc("stock", "doctype", "stock_entry")
if frappe.db.has_column("Stock Entry", "add_to_transit"):
frappe.db.sql("""
UPDATE `tabStock Entry` SET
stock_entry_type = 'Material Transfer',
purpose = 'Material Transfer',
add_to_transit = 1 WHERE stock_entry_type = 'Send to Warehouse'
""")
frappe.db.sql("""UPDATE `tabStock Entry` SET
stock_entry_type = 'Material Transfer',
purpose = 'Material Transfer'
WHERE stock_entry_type = 'Receive at Warehouse'
""")
frappe.reload_doc("stock", "doctype", "warehouse_type")
if not frappe.db.exists('Warehouse Type', 'Transit'):
doc = frappe.new_doc('Warehouse Type')
doc.name = 'Transit'
doc.insert()

View File

@ -34,6 +34,16 @@ frappe.ui.form.on("Company", {
frm.set_query("default_buying_terms", function() { frm.set_query("default_buying_terms", function() {
return { filters: { buying: 1 } }; return { filters: { buying: 1 } };
}); });
frm.set_query("default_in_transit_warehouse", function() {
return {
filters:{
'warehouse_type' : 'Transit',
'is_group': 0,
'company': frm.doc.company
}
};
});
}, },
company_name: function(frm) { company_name: function(frm) {

View File

@ -25,6 +25,7 @@
"default_selling_terms", "default_selling_terms",
"default_buying_terms", "default_buying_terms",
"default_warehouse_for_sales_return", "default_warehouse_for_sales_return",
"default_in_transit_warehouse",
"column_break_10", "column_break_10",
"country", "country",
"create_chart_of_accounts_based_on", "create_chart_of_accounts_based_on",
@ -733,6 +734,12 @@
"fieldname": "enable_perpetual_inventory_for_non_stock_items", "fieldname": "enable_perpetual_inventory_for_non_stock_items",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Enable Perpetual Inventory For Non Stock Items" "label": "Enable Perpetual Inventory For Non Stock Items"
},
{
"fieldname": "default_in_transit_warehouse",
"fieldtype": "Link",
"label": "Default In Transit Warehouse",
"options": "Warehouse"
} }
], ],
"icon": "fa fa-building", "icon": "fa fa-building",
@ -740,7 +747,7 @@
"image_field": "company_logo", "image_field": "company_logo",
"is_tree": 1, "is_tree": 1,
"links": [], "links": [],
"modified": "2020-06-24 12:45:31.462195", "modified": "2020-08-06 00:38:08.311216",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Setup", "module": "Setup",
"name": "Company", "name": "Company",

View File

@ -140,7 +140,8 @@ class Company(NestedSet):
{"warehouse_name": _("All Warehouses"), "is_group": 1}, {"warehouse_name": _("All Warehouses"), "is_group": 1},
{"warehouse_name": _("Stores"), "is_group": 0}, {"warehouse_name": _("Stores"), "is_group": 0},
{"warehouse_name": _("Work In Progress"), "is_group": 0}, {"warehouse_name": _("Work In Progress"), "is_group": 0},
{"warehouse_name": _("Finished Goods"), "is_group": 0}]: {"warehouse_name": _("Finished Goods"), "is_group": 0},
{"warehouse_name": _("Goods In Transit"), "is_group": 0, "warehouse_type": "Transit"}]:
if not frappe.db.exists("Warehouse", "{0} - {1}".format(wh_detail["warehouse_name"], self.abbr)): if not frappe.db.exists("Warehouse", "{0} - {1}".format(wh_detail["warehouse_name"], self.abbr)):
warehouse = frappe.get_doc({ warehouse = frappe.get_doc({
@ -149,7 +150,8 @@ class Company(NestedSet):
"is_group": wh_detail["is_group"], "is_group": wh_detail["is_group"],
"company": self.name, "company": self.name,
"parent_warehouse": "{0} - {1}".format(_("All Warehouses"), self.abbr) \ "parent_warehouse": "{0} - {1}".format(_("All Warehouses"), self.abbr) \
if not wh_detail["is_group"] else "" if not wh_detail["is_group"] else "",
"warehouse_type" : wh_detail["warehouse_type"] if "warehouse_type" in wh_detail else None
}) })
warehouse.flags.ignore_permissions = True warehouse.flags.ignore_permissions = True
warehouse.flags.ignore_mandatory = True warehouse.flags.ignore_mandatory = True

View File

@ -95,8 +95,6 @@ def install(country=None):
{'doctype': 'Stock Entry Type', 'name': 'Send to Subcontractor', 'purpose': 'Send to Subcontractor'}, {'doctype': 'Stock Entry Type', 'name': 'Send to Subcontractor', 'purpose': 'Send to Subcontractor'},
{'doctype': 'Stock Entry Type', 'name': 'Material Transfer for Manufacture', 'purpose': 'Material Transfer for Manufacture'}, {'doctype': 'Stock Entry Type', 'name': 'Material Transfer for Manufacture', 'purpose': 'Material Transfer for Manufacture'},
{'doctype': 'Stock Entry Type', 'name': 'Material Consumption for Manufacture', 'purpose': 'Material Consumption for Manufacture'}, {'doctype': 'Stock Entry Type', 'name': 'Material Consumption for Manufacture', 'purpose': 'Material Consumption for Manufacture'},
{'doctype': 'Stock Entry Type', 'name': 'Send to Warehouse', 'purpose': 'Send to Warehouse'},
{'doctype': 'Stock Entry Type', 'name': 'Receive at Warehouse', 'purpose': 'Receive at Warehouse'},
# Designation # Designation
{'doctype': 'Designation', 'designation_name': _('CEO')}, {'doctype': 'Designation', 'designation_name': _('CEO')},
@ -244,7 +242,10 @@ def install(country=None):
{"doctype": "Sales Stage", "stage_name": _("Identifying Decision Makers")}, {"doctype": "Sales Stage", "stage_name": _("Identifying Decision Makers")},
{"doctype": "Sales Stage", "stage_name": _("Perception Analysis")}, {"doctype": "Sales Stage", "stage_name": _("Perception Analysis")},
{"doctype": "Sales Stage", "stage_name": _("Proposal/Price Quote")}, {"doctype": "Sales Stage", "stage_name": _("Proposal/Price Quote")},
{"doctype": "Sales Stage", "stage_name": _("Negotiation/Review")} {"doctype": "Sales Stage", "stage_name": _("Negotiation/Review")},
# Warehouse Type
{'doctype': 'Warehouse Type', 'name': 'Transit'},
] ]
from erpnext.setup.setup_wizard.data.industry_type import get_industry_types from erpnext.setup.setup_wizard.data.industry_type import get_industry_types

View File

@ -11,6 +11,7 @@
"naming_series", "naming_series",
"title", "title",
"material_request_type", "material_request_type",
"transfer_status",
"customer", "customer",
"column_break_2", "column_break_2",
"schedule_date", "schedule_date",
@ -303,13 +304,22 @@
"fieldtype": "Link", "fieldtype": "Link",
"label": "Set From Warehouse", "label": "Set From Warehouse",
"options": "Warehouse" "options": "Warehouse"
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.add_to_transit == 1",
"fieldname": "transfer_status",
"fieldtype": "Select",
"label": "Transfer Status",
"options": "\nNot Started\nIn Transit\nCompleted",
"read_only": 1
} }
], ],
"icon": "fa fa-ticket", "icon": "fa fa-ticket",
"idx": 70, "idx": 70,
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2020-05-01 20:21:09.990867", "modified": "2020-08-10 13:27:54.891058",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Material Request", "name": "Material Request",

View File

@ -1,8 +1,16 @@
frappe.listview_settings['Material Request'] = { frappe.listview_settings['Material Request'] = {
add_fields: ["material_request_type", "status", "per_ordered", "per_received"], add_fields: ["material_request_type", "status", "per_ordered", "per_received", "transfer_status"],
get_indicator: function(doc) { get_indicator: function(doc) {
if(doc.status=="Stopped") { if(doc.status=="Stopped") {
return [__("Stopped"), "red", "status,=,Stopped"]; return [__("Stopped"), "red", "status,=,Stopped"];
} else if(doc.transfer_status && doc.docstatus != 2) {
if (doc.transfer_status == "Not Started") {
return [__("Not Started"), "orange"];
} else if (doc.transfer_status == "In Transit") {
return [__("In Transit"), "yellow"];
} else if (doc.transfer_status == "Completed") {
return [__("Completed"), "green"];
}
} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 0) { } else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 0) {
return [__("Pending"), "orange", "per_ordered,=,0"]; return [__("Pending"), "orange", "per_ordered,=,0"];
} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) < 100) { } else if(doc.docstatus==1 && flt(doc.per_ordered, 2) < 100) {

View File

@ -19,7 +19,6 @@ frappe.ui.form.on('Stock Entry', {
filters: [ filters: [
['Stock Entry', 'docstatus', '=', 1], ['Stock Entry', 'docstatus', '=', 1],
['Stock Entry', 'per_transferred', '<','100'], ['Stock Entry', 'per_transferred', '<','100'],
['Stock Entry', 'purpose', '=', 'Send to Warehouse']
] ]
} }
}); });
@ -171,9 +170,9 @@ frappe.ui.form.on('Stock Entry', {
} }
} }
if (frm.doc.docstatus === 1 && frm.doc.purpose == 'Send to Warehouse') { if (frm.doc.docstatus === 1) {
if (frm.doc.per_transferred < 100) { if (frm.doc.add_to_transit && frm.doc.purpose=='Material Transfer' && frm.doc.per_transferred < 100) {
frm.add_custom_button(__('Receive at Warehouse Entry'), function() { frm.add_custom_button('End Transit', function() {
frappe.model.open_mapped_doc({ frappe.model.open_mapped_doc({
method: "erpnext.stock.doctype.stock_entry.stock_entry.make_stock_in_entry", method: "erpnext.stock.doctype.stock_entry.stock_entry.make_stock_in_entry",
frm: frm frm: frm
@ -266,6 +265,7 @@ frappe.ui.form.on('Stock Entry', {
stock_entry_type: function(frm){ stock_entry_type: function(frm){
frm.remove_custom_button('Bill of Materials', "Get items from"); frm.remove_custom_button('Bill of Materials', "Get items from");
frm.events.show_bom_custom_button(frm); frm.events.show_bom_custom_button(frm);
frm.trigger('add_to_transit');
}, },
purpose: function(frm) { purpose: function(frm) {
@ -532,6 +532,26 @@ frappe.ui.form.on('Stock Entry', {
target_warehouse_address: function(frm) { target_warehouse_address: function(frm) {
erpnext.utils.get_address_display(frm, 'target_warehouse_address', 'target_address_display', false); erpnext.utils.get_address_display(frm, 'target_warehouse_address', 'target_address_display', false);
},
add_to_transit: function(frm) {
if(frm.doc.add_to_transit && frm.doc.purpose=='Material Transfer') {
frm.set_value('stock_entry_type', 'Material Transfer');
frm.fields_dict.to_warehouse.get_query = function() {
return {
filters:{
'warehouse_type' : 'Transit',
'is_group': 0,
'company': frm.doc.company
}
};
};
frappe.db.get_value('Company', frm.doc.company, 'default_in_transit_warehouse', (r) => {
if (r.default_in_transit_warehouse) {
frm.set_value('to_warehouse', r.default_in_transit_warehouse);
}
});
}
} }
}) })
@ -754,6 +774,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
} }
erpnext.hide_company(); erpnext.hide_company();
erpnext.utils.add_item(this.frm); erpnext.utils.add_item(this.frm);
this.frm.trigger('add_to_transit');
}, },
scan_barcode: function() { scan_barcode: function() {
@ -919,8 +940,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
doc.purpose!='Material Issue'); doc.purpose!='Material Issue');
this.frm.fields_dict["items"].grid.set_column_disp("additional_cost", doc.purpose!='Material Issue'); this.frm.fields_dict["items"].grid.set_column_disp("additional_cost", doc.purpose!='Material Issue');
this.frm.toggle_reqd("outgoing_stock_entry",
doc.purpose == 'Receive at Warehouse' ? 1: 0);
}, },
supplier: function(doc) { supplier: function(doc) {

View File

@ -13,6 +13,7 @@
"stock_entry_type", "stock_entry_type",
"outgoing_stock_entry", "outgoing_stock_entry",
"purpose", "purpose",
"add_to_transit",
"work_order", "work_order",
"purchase_order", "purchase_order",
"delivery_note_no", "delivery_note_no",
@ -116,11 +117,12 @@
"reqd": 1 "reqd": 1
}, },
{ {
"depends_on": "eval:doc.purpose == 'Receive at Warehouse'", "depends_on": "eval:doc.purpose == 'Material Transfer'",
"fieldname": "outgoing_stock_entry", "fieldname": "outgoing_stock_entry",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Stock Entry (Outward GIT)", "label": "Stock Entry (Outward GIT)",
"options": "Stock Entry" "options": "Stock Entry",
"read_only": 1
}, },
{ {
"bold": 1, "bold": 1,
@ -132,7 +134,7 @@
"label": "Purpose", "label": "Purpose",
"oldfieldname": "purpose", "oldfieldname": "purpose",
"oldfieldtype": "Select", "oldfieldtype": "Select",
"options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nMaterial Consumption for Manufacture\nManufacture\nRepack\nSend to Subcontractor\nSend to Warehouse\nReceive at Warehouse", "options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nMaterial Consumption for Manufacture\nManufacture\nRepack\nSend to Subcontractor",
"read_only": 1 "read_only": 1
}, },
{ {
@ -630,13 +632,21 @@
{ {
"fieldname": "print_settings_col_break", "fieldname": "print_settings_col_break",
"fieldtype": "Column Break" "fieldtype": "Column Break"
},
{
"default": "0",
"depends_on": "eval: doc.purpose=='Material Transfer' && !doc.outgoing_stock_entry",
"fieldname": "add_to_transit",
"fieldtype": "Check",
"label": "Add to Transit",
"no_copy": 1
} }
], ],
"icon": "fa fa-file-text", "icon": "fa fa-file-text",
"idx": 1, "idx": 1,
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2020-04-23 12:56:52.881752", "modified": "2020-08-11 19:10:07.954981",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Stock Entry", "name": "Stock Entry",

View File

@ -96,6 +96,11 @@ class StockEntry(StockController):
self.update_quality_inspection() self.update_quality_inspection()
if self.work_order and self.purpose == "Manufacture": if self.work_order and self.purpose == "Manufacture":
self.update_so_in_serial_number() self.update_so_in_serial_number()
if self.purpose == 'Material Transfer' and self.add_to_transit:
self.set_material_request_transfer_status('In Transit')
if self.purpose == 'Material Transfer' and self.outgoing_stock_entry:
self.set_material_request_transfer_status('Completed')
def on_cancel(self): def on_cancel(self):
@ -116,6 +121,11 @@ class StockEntry(StockController):
self.update_quality_inspection() self.update_quality_inspection()
self.delete_auto_created_batches() self.delete_auto_created_batches()
if self.purpose == 'Material Transfer' and self.add_to_transit:
self.set_material_request_transfer_status('Not Started')
if self.purpose == 'Material Transfer' and self.outgoing_stock_entry:
self.set_material_request_transfer_status('In Transit')
def set_job_card_data(self): def set_job_card_data(self):
if self.job_card and not self.work_order: if self.job_card and not self.work_order:
data = frappe.db.get_value('Job Card', data = frappe.db.get_value('Job Card',
@ -133,7 +143,7 @@ class StockEntry(StockController):
def validate_purpose(self): def validate_purpose(self):
valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer", valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer",
"Material Transfer for Manufacture", "Manufacture", "Repack", "Send to Subcontractor", "Material Transfer for Manufacture", "Manufacture", "Repack", "Send to Subcontractor",
"Material Consumption for Manufacture", "Send to Warehouse", "Receive at Warehouse"] "Material Consumption for Manufacture"]
if self.purpose not in valid_purposes: if self.purpose not in valid_purposes:
frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes))) frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes)))
@ -259,10 +269,10 @@ class StockEntry(StockController):
"""perform various (sometimes conditional) validations on warehouse""" """perform various (sometimes conditional) validations on warehouse"""
source_mandatory = ["Material Issue", "Material Transfer", "Send to Subcontractor", "Material Transfer for Manufacture", source_mandatory = ["Material Issue", "Material Transfer", "Send to Subcontractor", "Material Transfer for Manufacture",
"Material Consumption for Manufacture", "Send to Warehouse", "Receive at Warehouse"] "Material Consumption for Manufacture"]
target_mandatory = ["Material Receipt", "Material Transfer", "Send to Subcontractor", target_mandatory = ["Material Receipt", "Material Transfer", "Send to Subcontractor",
"Material Transfer for Manufacture", "Send to Warehouse", "Receive at Warehouse"] "Material Transfer for Manufacture"]
validate_for_manufacture = any([d.bom_no for d in self.get("items")]) validate_for_manufacture = any([d.bom_no for d in self.get("items")])
@ -810,7 +820,7 @@ class StockEntry(StockController):
def set_items_for_stock_in(self): def set_items_for_stock_in(self):
self.items = [] self.items = []
if self.outgoing_stock_entry and self.purpose == 'Receive at Warehouse': if self.outgoing_stock_entry and self.purpose == 'Material Transfer':
doc = frappe.get_doc('Stock Entry', self.outgoing_stock_entry) doc = frappe.get_doc('Stock Entry', self.outgoing_stock_entry)
if doc.per_transferred == 100: if doc.per_transferred == 100:
@ -1211,13 +1221,25 @@ class StockEntry(StockController):
def validate_with_material_request(self): def validate_with_material_request(self):
for item in self.get("items"): for item in self.get("items"):
if item.material_request: material_request = item.material_request or None
material_request_item = item.material_request_item or None
if self.purpose == 'Material Transfer' and self.outgoing_stock_entry:
parent_se = frappe.get_value("Stock Entry Detail", item.ste_detail, ['material_request','material_request_item'],as_dict=True)
if parent_se:
material_request = parent_se.material_request
material_request_item = parent_se.material_request_item
if material_request:
mreq_item = frappe.db.get_value("Material Request Item", mreq_item = frappe.db.get_value("Material Request Item",
{"name": item.material_request_item, "parent": item.material_request}, {"name": material_request_item, "parent": material_request},
["item_code", "warehouse", "idx"], as_dict=True) ["item_code", "warehouse", "idx"], as_dict=True)
if mreq_item.item_code != item.item_code or \ if mreq_item.item_code != item.item_code:
mreq_item.warehouse != (item.s_warehouse if self.purpose== "Material Issue" else item.t_warehouse): frappe.throw(_("Item for row {0} does not match Material Request").format(item.idx),
frappe.throw(_("Item or Warehouse for row {0} does not match Material Request").format(item.idx), frappe.MappingMismatchError)
elif self.purpose == "Material Transfer" and self.add_to_transit:
continue
elif mreq_item.warehouse != (item.s_warehouse if self.purpose == "Material Issue" else item.t_warehouse):
frappe.throw(_("Warehouse for row {0} does not match Material Request").format(item.idx),
frappe.MappingMismatchError) frappe.MappingMismatchError)
def validate_batch(self): def validate_batch(self):
@ -1285,7 +1307,7 @@ class StockEntry(StockController):
to fullfill Sales Order {2}.").format(item.item_code, sr, sales_order)) to fullfill Sales Order {2}.").format(item.item_code, sr, sales_order))
def update_transferred_qty(self): def update_transferred_qty(self):
if self.purpose == 'Receive at Warehouse': if self.purpose == 'Material Transfer' and self.outgoing_stock_entry:
stock_entries = {} stock_entries = {}
stock_entries_child_list = [] stock_entries_child_list = []
for d in self.items: for d in self.items:
@ -1343,6 +1365,20 @@ class StockEntry(StockController):
'reference_type': reference_type, 'reference_type': reference_type,
'reference_name': reference_name 'reference_name': reference_name
}) })
def set_material_request_transfer_status(self, status):
material_requests = []
if self.outgoing_stock_entry:
parent_se = frappe.get_value("Stock Entry", self.outgoing_stock_entry, 'add_to_transit')
for item in self.items:
material_request = item.material_request or None
if self.purpose == "Material Transfer" and material_request not in material_requests:
if self.outgoing_stock_entry and parent_se:
material_request = frappe.get_value("Stock Entry Detail", item.ste_detail, 'material_request')
if material_request and material_request not in material_requests:
material_requests.append(material_request)
frappe.db.set_value('Material Request', material_request, 'transfer_status', status)
@frappe.whitelist() @frappe.whitelist()
def move_sample_to_retention_warehouse(company, items): def move_sample_to_retention_warehouse(company, items):
@ -1382,12 +1418,19 @@ def move_sample_to_retention_warehouse(company, items):
@frappe.whitelist() @frappe.whitelist()
def make_stock_in_entry(source_name, target_doc=None): def make_stock_in_entry(source_name, target_doc=None):
def set_missing_values(source, target): def set_missing_values(source, target):
target.purpose = 'Receive at Warehouse'
target.set_stock_entry_type() target.set_stock_entry_type()
def update_item(source_doc, target_doc, source_parent): def update_item(source_doc, target_doc, source_parent):
target_doc.t_warehouse = '' target_doc.t_warehouse = ''
if source_doc.material_request_item and source_doc.material_request :
add_to_transit = frappe.db.get_value('Stock Entry', source_name, 'add_to_transit')
if add_to_transit:
warehouse = frappe.get_value('Material Request Item', source_doc.material_request_item, 'warehouse')
target_doc.t_warehouse = warehouse
target_doc.s_warehouse = source_doc.t_warehouse target_doc.s_warehouse = source_doc.t_warehouse
target_doc.qty = source_doc.qty - source_doc.transferred_qty target_doc.qty = source_doc.qty - source_doc.transferred_qty

View File

@ -737,34 +737,6 @@ class TestStockEntry(unittest.TestCase):
self.assertEqual(se.get("items")[0].allow_zero_valuation_rate, 1) self.assertEqual(se.get("items")[0].allow_zero_valuation_rate, 1)
self.assertEqual(se.get("items")[0].amount, 0) self.assertEqual(se.get("items")[0].amount, 0)
def test_goods_in_transit(self):
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
warehouse = "_Test Warehouse FG 1 - _TC"
if not frappe.db.exists('Warehouse', warehouse):
create_warehouse("_Test Warehouse FG 1")
outward_entry = make_stock_entry(item_code="_Test Item",
purpose="Send to Warehouse",
source="_Test Warehouse - _TC",
target="_Test Warehouse 1 - _TC", qty=50, basic_rate=100)
inward_entry1 = make_stock_in_entry(outward_entry.name)
inward_entry1.items[0].t_warehouse = warehouse
inward_entry1.items[0].qty = 25
inward_entry1.submit()
doc = frappe.get_doc('Stock Entry', outward_entry.name)
self.assertEqual(doc.per_transferred, 50)
inward_entry2 = make_stock_in_entry(outward_entry.name)
inward_entry2.items[0].t_warehouse = warehouse
inward_entry2.items[0].qty = 25
inward_entry2.submit()
doc = frappe.get_doc('Stock Entry', outward_entry.name)
self.assertEqual(doc.per_transferred, 100)
def test_gle_for_opening_stock_entry(self): def test_gle_for_opening_stock_entry(self):
mr = make_stock_entry(item_code="_Test Item", target="Stores - TCP1", company="_Test Company with perpetual inventory",qty=50, basic_rate=100, expense_account="Stock Adjustment - TCP1", is_opening="Yes", do_not_save=True) mr = make_stock_entry(item_code="_Test Item", target="Stores - TCP1", company="_Test Company with perpetual inventory",qty=50, basic_rate=100, expense_account="Stock Adjustment - TCP1", is_opening="Yes", do_not_save=True)

View File

@ -1,156 +1,83 @@
{ {
"allow_copy": 0, "actions": [],
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "Prompt", "autoname": "Prompt",
"beta": 0,
"creation": "2019-03-13 16:23:46.636769", "creation": "2019-03-13 16:23:46.636769",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"purpose"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Material Issue", "default": "Material Issue",
"fetch_if_empty": 0,
"fieldname": "purpose", "fieldname": "purpose",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Purpose", "label": "Purpose",
"length": 0, "options": "\nMaterial Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nMaterial Consumption for Manufacture\nManufacture\nRepack\nSend to Subcontractor",
"no_copy": 0,
"options": "\nMaterial Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nMaterial Consumption for Manufacture\nManufacture\nRepack\nSend to Subcontractor\nSend to Warehouse\nReceive at Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1, "reqd": 1,
"search_index": 0, "set_only_once": 1
"set_only_once": 1,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0, "links": [],
"hide_heading": 0, "modified": "2020-08-10 23:24:37.160817",
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-03-26 12:02:42.144377",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Stock Entry Type", "name": "Stock Entry Type",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "System Manager", "role": "System Manager",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Manufacturing Manager", "role": "Manufacturing Manager",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Stock Manager", "role": "Stock Manager",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
}, },
{ {
"amend": 0,
"cancel": 0,
"create": 1, "create": 1,
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "Stock User", "role": "Stock User",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 0,
"write": 1 "write": 1
} }
], ],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "ASC", "sort_order": "ASC",
"track_changes": 1, "track_changes": 1
"track_seen": 0,
"track_views": 0
} }