mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-25 07:54:46 +00:00
[merge] [minor] merged with master
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-05-03 10:45:46",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-08-14 11:46:49",
|
||||
"modified": "2013-08-30 16:21:38",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -35,7 +35,9 @@
|
||||
"parentfield": "permissions",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0,
|
||||
"read": 1
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"submit": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocType",
|
||||
@@ -557,20 +559,6 @@
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "No",
|
||||
"depends_on": "eval:doc.is_sales_item==\"Yes\"",
|
||||
"description": "Select \"Yes\" if this item is to be sent to a customer or received from a supplier as a sample. Delivery notes and Purchase Receipts will update stock levels but there will be no invoice against this item.",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "is_sample_item",
|
||||
"fieldtype": "Select",
|
||||
"label": "Allow Samples",
|
||||
"oldfieldname": "is_sample_item",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Yes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_sales_item==\"Yes\"",
|
||||
"doctype": "DocField",
|
||||
@@ -878,9 +866,7 @@
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"report": 1,
|
||||
"role": "Material Master Manager",
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
@@ -888,9 +874,7 @@
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"report": 1,
|
||||
"role": "Material Manager",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
@@ -898,21 +882,7 @@
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"report": 1,
|
||||
"role": "Material User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"role": "Purchase User"
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"role": "Accounts User"
|
||||
}
|
||||
]
|
||||
@@ -44,7 +44,6 @@ test_records = [
|
||||
"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",
|
||||
@@ -82,7 +81,6 @@ test_records = [
|
||||
"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",
|
||||
@@ -108,7 +106,6 @@ test_records = [
|
||||
"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",
|
||||
@@ -128,7 +125,6 @@ test_records = [
|
||||
"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",
|
||||
@@ -149,7 +145,6 @@ test_records = [
|
||||
"is_purchase_item": "Yes",
|
||||
"is_sales_item": "Yes",
|
||||
"is_service_item": "No",
|
||||
"is_sample_item": "No",
|
||||
"inspection_required": "No",
|
||||
"is_pro_applicable": "Yes",
|
||||
"is_sub_contracted_item": "Yes",
|
||||
@@ -168,7 +163,6 @@ test_records = [
|
||||
"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",
|
||||
@@ -188,7 +182,6 @@ test_records = [
|
||||
"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",
|
||||
@@ -209,7 +202,6 @@ test_records = [
|
||||
"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",
|
||||
|
||||
@@ -42,11 +42,42 @@ class TestStockEntry(unittest.TestCase):
|
||||
|
||||
def test_warehouse_company_validation(self):
|
||||
self._clear_stock_account_balance()
|
||||
webnotes.session.user = "test2@example.com"
|
||||
webnotes.bean("Profile", "test2@example.com").get_controller()\
|
||||
.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
|
||||
|
||||
from stock.doctype.stock_ledger_entry.stock_ledger_entry import InvalidWarehouseCompany
|
||||
st1 = webnotes.bean(copy=test_records[0])
|
||||
st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
|
||||
st1.insert()
|
||||
self.assertRaises(InvalidWarehouseCompany, st1.submit)
|
||||
|
||||
webnotes.session.user = "Administrator"
|
||||
|
||||
def test_warehouse_user(self):
|
||||
from stock.utils import UserNotAllowedForWarehouse
|
||||
|
||||
webnotes.session.user = "test@example.com"
|
||||
webnotes.bean("Profile", "test@example.com").get_controller()\
|
||||
.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
|
||||
|
||||
webnotes.bean("Profile", "test2@example.com").get_controller()\
|
||||
.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
|
||||
|
||||
st1 = webnotes.bean(copy=test_records[0])
|
||||
st1.doc.company = "_Test Company 1"
|
||||
st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
|
||||
st1.insert()
|
||||
self.assertRaises(UserNotAllowedForWarehouse, st1.submit)
|
||||
|
||||
webnotes.session.user = "test2@example.com"
|
||||
st1 = webnotes.bean(copy=test_records[0])
|
||||
st1.doc.company = "_Test Company 1"
|
||||
st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
|
||||
st1.insert()
|
||||
st1.submit()
|
||||
|
||||
webnotes.session.user = "Administrator"
|
||||
|
||||
def test_material_receipt_gl_entry(self):
|
||||
self._clear_stock_account_balance()
|
||||
|
||||
@@ -25,12 +25,14 @@ class DocType(DocListController):
|
||||
self.doclist = doclist
|
||||
|
||||
def validate(self):
|
||||
from stock.utils import validate_warehouse_user
|
||||
if not hasattr(webnotes, "new_stock_ledger_entries"):
|
||||
webnotes.new_stock_ledger_entries = []
|
||||
|
||||
webnotes.new_stock_ledger_entries.append(self.doc)
|
||||
self.validate_mandatory()
|
||||
self.validate_item()
|
||||
self.validate_warehouse_user()
|
||||
validate_warehouse_user(self.doc.warehouse)
|
||||
self.validate_warehouse_company()
|
||||
self.actual_amt_check()
|
||||
self.check_stock_frozen_date()
|
||||
@@ -55,16 +57,6 @@ class DocType(DocListController):
|
||||
|
||||
self.doc.fields.pop('batch_bal')
|
||||
|
||||
def validate_warehouse_user(self):
|
||||
if webnotes.session.user=="Administrator":
|
||||
return
|
||||
warehouse_users = [p[0] for p in webnotes.conn.sql("""select user from `tabWarehouse User`
|
||||
where parent=%s""", self.doc.warehouse)]
|
||||
|
||||
if warehouse_users and not webnotes.session.user in warehouse_users:
|
||||
webnotes.msgprint(_("User not allowed entry in the Warehouse") \
|
||||
+ ": " + webnotes.session.user + " / " + self.doc.warehouse, raise_exception = 1)
|
||||
|
||||
def validate_warehouse_company(self):
|
||||
warehouse_company = webnotes.conn.get_value("Warehouse", self.doc.warehouse, "company")
|
||||
if warehouse_company and warehouse_company != self.doc.company:
|
||||
|
||||
@@ -287,8 +287,8 @@ class DocType(StockController):
|
||||
|
||||
stock_value_difference = {}
|
||||
for d in self.entries:
|
||||
diff = get_buying_amount(d.item_code, self.doc.doctype, self.doc.name,
|
||||
d.voucher_detail_no, stock_ledger_entries.get((d.item_code, d.warehouse), []))
|
||||
diff = get_buying_amount(self.doc.doctype, self.doc.name, d.voucher_detail_no,
|
||||
stock_ledger_entries.get((d.item_code, d.warehouse), []))
|
||||
stock_value_difference.setdefault(d.warehouse, 0.0)
|
||||
stock_value_difference[d.warehouse] -= diff
|
||||
|
||||
|
||||
@@ -17,7 +17,11 @@ test_records = [
|
||||
[{
|
||||
"doctype": "Warehouse",
|
||||
"warehouse_name": "_Test Warehouse 2",
|
||||
"company": "_Test Company 1",
|
||||
"account": "_Test Account Stock In Hand - _TC1"
|
||||
"account": "_Test Account Stock In Hand - _TC1",
|
||||
"company": "_Test Company 1"
|
||||
}, {
|
||||
"doctype": "Warehouse User",
|
||||
"parentfield": "warehouse_users",
|
||||
"user": "test2@example.com"
|
||||
}]
|
||||
]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-08-20 15:08:10",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-08-20 15:10:43",
|
||||
"modified": "2013-08-20 15:10:45",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -10,7 +10,7 @@
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"query": "SELECT\n tabBin.item_code as \"Item:Link/Item:120\",\n tabBin.warehouse as \"Item:Link/Warehouse:120\",\n tabBin.actual_qty as \"Actual:Float:90\",\n tabBin.indented_qty as \"Requested:Float:90\",\n tabBin.reserved_qty as \"Reserved:Float:90\",\n tabBin.ordered_qty as \"Ordered:Float:90\",\n tabBin.projected_qty as \"Projected:Float:90\"\nFROM\n tabBin, tabItem\nWHERE\n tabBin.item_code = tabItem.name\n AND tabItem.is_purchase_item = \"Yes\"\n AND tabBin.projected_qty < 0\nORDER BY\n tabBin.projected_qty ASC",
|
||||
"query": "SELECT\n tabBin.item_code as \"Item:Link/Item:120\",\n tabBin.warehouse as \"Warehouse:Link/Warehouse:120\",\n tabBin.actual_qty as \"Actual:Float:90\",\n tabBin.indented_qty as \"Requested:Float:90\",\n tabBin.reserved_qty as \"Reserved:Float:90\",\n tabBin.ordered_qty as \"Ordered:Float:90\",\n tabBin.projected_qty as \"Projected:Float:90\"\nFROM\n tabBin, tabItem\nWHERE\n tabBin.item_code = tabItem.name\n AND tabItem.is_purchase_item = \"Yes\"\n AND tabBin.projected_qty < 0\nORDER BY\n tabBin.projected_qty ASC",
|
||||
"ref_doctype": "Item",
|
||||
"report_name": "Items To Be Requested",
|
||||
"report_type": "Query Report"
|
||||
|
||||
@@ -8,6 +8,7 @@ from webnotes.utils import flt, cstr, nowdate, add_days, cint
|
||||
from webnotes.defaults import get_global_default
|
||||
from webnotes.utils.email_lib import sendmail
|
||||
|
||||
class UserNotAllowedForWarehouse(webnotes.ValidationError): pass
|
||||
|
||||
def get_stock_balance_on(warehouse_list, posting_date=None):
|
||||
if not posting_date: posting_date = nowdate()
|
||||
@@ -208,20 +209,28 @@ def get_warehouse_list(doctype, txt, searchfield, start, page_len, filters):
|
||||
wlist.append([w])
|
||||
return wlist
|
||||
|
||||
def get_buying_amount(item_code, voucher_type, voucher_no, voucher_detail_no,
|
||||
stock_ledger_entries, item_sales_bom=None):
|
||||
if item_sales_bom and item_sales_bom.get(item_code):
|
||||
# sales bom item
|
||||
buying_amount = 0.0
|
||||
for bom_item in item_sales_bom[item_code]:
|
||||
if bom_item.get("parent_detail_docname")==voucher_detail_no:
|
||||
buying_amount += _get_buying_amount(voucher_type, voucher_no, voucher_detail_no, stock_ledger_entries)
|
||||
return buying_amount
|
||||
else:
|
||||
# doesn't have sales bom
|
||||
return _get_buying_amount(voucher_type, voucher_no, voucher_detail_no, stock_ledger_entries)
|
||||
def validate_warehouse_user(warehouse):
|
||||
if webnotes.session.user=="Administrator":
|
||||
return
|
||||
warehouse_users = [p[0] for p in webnotes.conn.sql("""select user from `tabWarehouse User`
|
||||
where parent=%s""", warehouse)]
|
||||
|
||||
if warehouse_users and not (webnotes.session.user in warehouse_users):
|
||||
webnotes.throw(_("Not allowed entry in Warehouse") \
|
||||
+ ": " + warehouse, UserNotAllowedForWarehouse)
|
||||
|
||||
def get_sales_bom_buying_amount(item_code, warehouse, voucher_type, voucher_no, voucher_detail_no,
|
||||
stock_ledger_entries, item_sales_bom):
|
||||
# sales bom item
|
||||
buying_amount = 0.0
|
||||
for bom_item in item_sales_bom[item_code]:
|
||||
if bom_item.get("parent_detail_docname")==voucher_detail_no:
|
||||
buying_amount += get_buying_amount(voucher_type, voucher_no, voucher_detail_no,
|
||||
stock_ledger_entries.get((bom_item.item_code, warehouse), []))
|
||||
|
||||
return buying_amount
|
||||
|
||||
def _get_buying_amount(voucher_type, voucher_no, item_row, stock_ledger_entries):
|
||||
def get_buying_amount(voucher_type, voucher_no, item_row, stock_ledger_entries):
|
||||
# IMP NOTE
|
||||
# stock_ledger_entries should already be filtered by item_code and warehouse and
|
||||
# sorted by posting_date desc, posting_time desc
|
||||
|
||||
Reference in New Issue
Block a user