diff --git a/accounts/doctype/journal_voucher/test_journal_voucher.py b/accounts/doctype/journal_voucher/test_journal_voucher.py
index 7cfeb595d81..feb1e2ca5a6 100644
--- a/accounts/doctype/journal_voucher/test_journal_voucher.py
+++ b/accounts/doctype/journal_voucher/test_journal_voucher.py
@@ -122,119 +122,4 @@ test_records = [
"parentfield": "entries",
"cost_center": "_Test Cost Center - _TC"
}],
-]
-
-
-
-
-
-
-#
-#
-# import webnotes.model
-# from webnotes.utils import nowdate, flt, add_days
-# from accounts.utils import get_fiscal_year, get_balance_on
-#
-# company = webnotes.conn.get_default("company")
-# abbr = webnotes.conn.get_value("Company", company, "abbr")
-#
-# data = {
-# "expense_account": {
-# "doctype": "Account",
-# "account_name": "Test Expense",
-# "parent_account": "Direct Expenses - %s" % abbr,
-# "company": company,
-# "debit_or_credit": "Debit",
-# "is_pl_account": "Yes",
-# "group_or_ledger": "Ledger"
-# },
-# "supplier_account": {
-# "doctype": "Account",
-# "account_name": "Test Supplier",
-# "parent_account": "Accounts Payable - %s" % abbr,
-# "company": company,
-# "debit_or_credit": "Credit",
-# "is_pl_account": "No",
-# "group_or_ledger": "Ledger"
-# },
-# "test_cost_center": {
-# "doctype": "Cost Center",
-# "cost_center_name": "Test Cost Center",
-# "parent_cost_center": "Root - %s" % abbr,
-# "company_name": company,
-# "group_or_ledger": "Ledger",
-# "company_abbr": abbr
-# },
-# "journal_voucher": [
-# {
-# "doctype": "Journal Voucher",
-# "voucher_type": "Journal Entry",
-# "naming_series": "JV",
-# "posting_date": nowdate(),
-# "remark": "Test Journal Voucher",
-# "fiscal_year": get_fiscal_year(nowdate())[0],
-# "company": company
-# },
-# {
-# "doctype": "Journal Voucher Detail",
-# "parentfield": "entries",
-# "account": "Test Expense - %s" % abbr,
-# "debit": 5000,
-# "cost_center": "Test Cost Center - %s" % abbr,
-# },
-# {
-# "doctype": "Journal Voucher Detail",
-# "parentfield": "entries",
-# "account": "Test Supplier - %s" % abbr,
-# "credit": 5000,
-# },
-# ]
-# }
-#
-# def get_name(s):
-# return s + " - " + abbr
-#
-# class TestJournalVoucher(unittest.TestCase):
-# def setUp(self):
-# webnotes.conn.begin()
-#
-# # create a dummy account
-# webnotes.model.insert([data["expense_account"]])
-# webnotes.model.insert([data["supplier_account"]])
-# webnotes.model.insert([data["test_cost_center"]])
-#
-# def tearDown(self):
-# webnotes.conn.rollback()
-#
-# def test_save_journal_voucher(self):
-# expense_ac_balance = get_balance_on(get_name("Test Expense"), nowdate())
-# supplier_ac_balance = get_balance_on(get_name("Test Supplier"), nowdate())
-#
-# dl = webnotes.model.insert(data["journal_voucher"])
-# dl.submit()
-# dl.load_from_db()
-#
-# # test submitted jv
-# self.assertTrue(webnotes.conn.exists("Journal Voucher", dl.doclist[0].name))
-# for d in dl.doclist[1:]:
-# self.assertEquals(webnotes.conn.get_value("Journal Voucher Detail",
-# d.name, "parent"), dl.doclist[0].name)
-#
-# # test gl entry
-# gle = webnotes.conn.sql("""select account, debit, credit
-# from `tabGL Entry` where voucher_no = %s order by account""",
-# dl.doclist[0].name)
-#
-# self.assertEquals((gle[0][0], flt(gle[0][1]), flt(gle[0][2])),
-# ('Test Expense - %s' % abbr, 5000.0, 0.0))
-# self.assertEquals((gle[1][0], flt(gle[1][1]), flt(gle[1][2])),
-# ('Test Supplier - %s' % abbr, 0.0, 5000.0))
-#
-# # check balance as on today
-# self.assertEqual(get_balance_on(get_name("Test Expense"), nowdate()),
-# expense_ac_balance + 5000)
-# self.assertEqual(get_balance_on(get_name("Test Supplier"), nowdate()),
-# supplier_ac_balance + 5000)
-#
-# # check previous balance
-# self.assertEqual(get_balance_on(get_name("Test Expense"), add_days(nowdate(), -1)), 0)
\ No newline at end of file
+]
\ No newline at end of file
diff --git a/accounts/doctype/pos_setting/pos_setting.txt b/accounts/doctype/pos_setting/pos_setting.txt
index 80cb1ecdc9c..788af9ee067 100755
--- a/accounts/doctype/pos_setting/pos_setting.txt
+++ b/accounts/doctype/pos_setting/pos_setting.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-04-30 12:58:25",
+ "creation": "2013-05-09 13:16:11",
"docstatus": 0,
- "modified": "2013-05-03 14:36:24",
+ "modified": "2013-05-23 12:52:09",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -213,6 +213,14 @@
"options": "link:Print Heading"
},
{
+ "cancel": 1,
+ "create": 1,
+ "doctype": "DocPerm",
+ "role": "System Manager",
+ "write": 1
+ },
+ {
+ "cancel": 1,
"create": 1,
"doctype": "DocPerm",
"role": "Accounts Manager",
diff --git a/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt b/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
index e33ab7c5698..8df4306f57b 100755
--- a/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
+++ b/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-04-10 08:35:38",
+ "creation": "2013-04-19 11:00:07",
"docstatus": 0,
- "modified": "2013-04-17 14:05:20",
+ "modified": "2013-05-22 12:01:56",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -224,6 +224,7 @@
"fieldtype": "Link",
"in_filter": 1,
"label": "Pur Order",
+ "no_copy": 1,
"oldfieldname": "purchase_order",
"oldfieldtype": "Link",
"options": "Purchase Order",
@@ -238,6 +239,7 @@
"hidden": 1,
"in_filter": 1,
"label": "Purchase Order Item",
+ "no_copy": 1,
"oldfieldname": "po_detail",
"oldfieldtype": "Data",
"print_hide": 1,
@@ -250,6 +252,7 @@
"fieldtype": "Link",
"in_filter": 1,
"label": "Pur Receipt",
+ "no_copy": 1,
"oldfieldname": "purchase_receipt",
"oldfieldtype": "Link",
"options": "Purchase Receipt",
@@ -264,6 +267,7 @@
"hidden": 1,
"in_filter": 1,
"label": "PR Detail",
+ "no_copy": 1,
"oldfieldname": "pr_detail",
"oldfieldtype": "Data",
"print_hide": 1,
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index e58b4000f2e..25dd29a9967 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -72,9 +72,11 @@ class DocType(SellingController):
self.set_aging_date()
self.set_against_income_account()
self.validate_c_form()
+ self.validate_rate_with_refdoc()
self.validate_time_logs_are_submitted()
self.validate_recurring_invoice()
+
def on_submit(self):
if cint(self.doc.is_pos) == 1:
if cint(self.doc.update_stock) == 1:
@@ -203,8 +205,9 @@ class DocType(SellingController):
if self.doc.customer:
acc_head = webnotes.conn.sql("""select name from `tabAccount`
where (name = %s or (master_name = %s and master_type = 'customer'))
- and docstatus != 2""",
- (cstr(self.doc.customer) + " - " + self.get_company_abbr(), self.doc.customer))
+ and docstatus != 2 and company = %s""",
+ (cstr(self.doc.customer) + " - " + self.get_company_abbr(),
+ self.doc.customer, self.doc.company))
if acc_head and acc_head[0][0]:
return acc_head[0][0]
@@ -461,6 +464,19 @@ class DocType(SellingController):
webnotes.conn.set(self.doc, 'c_form_no', '')
+ def validate_rate_with_refdoc(self):
+ """Validate values with reference document with previous document"""
+ for d in self.doclist.get({"parentfield": "entries"}):
+ if d.so_detail:
+ self.check_value("Sales Order", d.so_detail, d.export_rate, d.item_code)
+ if d.dn_detail:
+ self.check_value("Delivery Note", d.dn_detail, d.export_rate, d.item_code)
+
+ def check_value(self, ref_dt, ref_dn, val, item_code):
+ ref_val = webnotes.conn.get_value(ref_dt + "Item", ref_dn, "export_rate")
+ if flt(ref_val) != val:
+ msgprint(_("Rate is not matching with ") + ref_dt + ": " + ref_dn +
+ _(" for item: ") + item_code, raise_exception=True)
def update_current_stock(self):
for d in getlist(self.doclist, 'entries'):
diff --git a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
index 4dcd901f284..014a9f453cc 100644
--- a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
+++ b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-04-19 13:30:26",
+ "creation": "2013-04-19 11:00:07",
"docstatus": 0,
- "modified": "2013-05-21 16:43:21",
+ "modified": "2013-05-22 12:07:00",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -305,6 +305,7 @@
"fieldtype": "Link",
"in_filter": 1,
"label": "Sales Order",
+ "no_copy": 1,
"oldfieldname": "sales_order",
"oldfieldtype": "Link",
"options": "Sales Order",
@@ -319,6 +320,7 @@
"hidden": 1,
"in_filter": 1,
"label": "SO Detail ",
+ "no_copy": 1,
"oldfieldname": "so_detail",
"oldfieldtype": "Data",
"print_hide": 1,
@@ -331,6 +333,7 @@
"fieldtype": "Link",
"in_filter": 1,
"label": "Delivery Note",
+ "no_copy": 1,
"oldfieldname": "delivery_note",
"oldfieldtype": "Link",
"options": "Delivery Note",
@@ -345,6 +348,7 @@
"hidden": 1,
"in_filter": 1,
"label": "DN Detail",
+ "no_copy": 1,
"oldfieldname": "dn_detail",
"oldfieldtype": "Data",
"print_hide": 1,
diff --git a/buying/doctype/purchase_order_item/purchase_order_item.txt b/buying/doctype/purchase_order_item/purchase_order_item.txt
index cd00f872534..01a144a1433 100755
--- a/buying/doctype/purchase_order_item/purchase_order_item.txt
+++ b/buying/doctype/purchase_order_item/purchase_order_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-22 01:27:42",
+ "creation": "2013-03-07 11:42:55",
"docstatus": 0,
- "modified": "2013-03-07 07:03:27",
+ "modified": "2013-05-22 11:59:52",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -36,6 +36,7 @@
"oldfieldname": "schedule_date",
"oldfieldtype": "Date",
"print_hide": 1,
+ "read_only": 0,
"reqd": 1,
"search_index": 1
},
@@ -49,6 +50,7 @@
"oldfieldtype": "Link",
"options": "Item",
"print_hide": 0,
+ "read_only": 0,
"reqd": 1,
"search_index": 1
},
@@ -72,6 +74,7 @@
"oldfieldname": "item_name",
"oldfieldtype": "Data",
"print_hide": 1,
+ "read_only": 0,
"reqd": 1,
"search_index": 1
},
@@ -83,6 +86,7 @@
"oldfieldname": "description",
"oldfieldtype": "Small Text",
"print_width": "300px",
+ "read_only": 0,
"reqd": 1,
"width": "300px"
},
@@ -95,6 +99,7 @@
"oldfieldname": "qty",
"oldfieldtype": "Currency",
"print_width": "60px",
+ "read_only": 0,
"reqd": 1,
"width": "60px"
},
@@ -108,6 +113,7 @@
"options": "UOM",
"print_hide": 0,
"print_width": "100px",
+ "read_only": 0,
"reqd": 1,
"width": "100px"
},
@@ -117,14 +123,16 @@
"fieldtype": "Currency",
"label": "Ref Rate ",
"options": "currency",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"doctype": "DocField",
"fieldname": "discount_rate",
"fieldtype": "Float",
"label": "Discount %",
- "print_hide": 0
+ "print_hide": 0,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -135,7 +143,8 @@
"oldfieldname": "import_rate",
"oldfieldtype": "Currency",
"options": "currency",
- "print_hide": 0
+ "print_hide": 0,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -153,7 +162,8 @@
"fieldtype": "Currency",
"label": "Ref Rate*",
"options": "Company:company:default_currency",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"default": "0.00",
@@ -166,6 +176,7 @@
"options": "Company:company:default_currency",
"print_hide": 1,
"print_width": "100px",
+ "read_only": 0,
"reqd": 1,
"width": "100px"
},
@@ -192,6 +203,7 @@
"oldfieldtype": "Link",
"options": "Warehouse",
"print_hide": 1,
+ "read_only": 0,
"reqd": 0
},
{
@@ -202,6 +214,7 @@
"label": "Project Name",
"options": "Project",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0
},
{
@@ -214,6 +227,7 @@
"oldfieldtype": "Currency",
"print_hide": 1,
"print_width": "100px",
+ "read_only": 0,
"reqd": 1,
"width": "100px"
},
@@ -237,7 +251,7 @@
"fieldtype": "Data",
"hidden": 1,
"label": "Prevdoc DocType",
- "no_copy": 0,
+ "no_copy": 1,
"oldfieldname": "prevdoc_doctype",
"oldfieldtype": "Data",
"print_hide": 1,
@@ -250,7 +264,7 @@
"hidden": 0,
"in_filter": 1,
"label": "Material Request No",
- "no_copy": 0,
+ "no_copy": 1,
"oldfieldname": "prevdoc_docname",
"oldfieldtype": "Link",
"options": "Material Request",
@@ -267,6 +281,7 @@
"hidden": 1,
"in_filter": 1,
"label": "Material Request Date",
+ "no_copy": 1,
"oldfieldname": "prevdoc_date",
"oldfieldtype": "Date",
"print_hide": 1,
@@ -280,7 +295,7 @@
"hidden": 1,
"in_filter": 1,
"label": "Material Request Detail No",
- "no_copy": 0,
+ "no_copy": 1,
"oldfieldname": "prevdoc_detail_docname",
"oldfieldtype": "Data",
"print_hide": 1,
@@ -294,6 +309,7 @@
"hidden": 1,
"in_filter": 0,
"label": "Supplier Quotation",
+ "no_copy": 1,
"options": "Supplier Quotation",
"read_only": 1,
"search_index": 0
@@ -304,6 +320,7 @@
"fieldtype": "Link",
"hidden": 1,
"label": "Supplier Quotation Item",
+ "no_copy": 1,
"options": "Supplier Quotation Item",
"read_only": 1
},
@@ -395,6 +412,7 @@
"no_copy": 1,
"oldfieldname": "page_break",
"oldfieldtype": "Check",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
}
]
\ No newline at end of file
diff --git a/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt b/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt
index 53fa9f8d953..6b24d2f86f9 100644
--- a/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt
+++ b/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-02-22 01:27:43",
+ "creation": "2013-03-07 11:42:56",
"docstatus": 0,
- "modified": "2013-03-07 07:03:32",
+ "modified": "2013-05-22 12:02:28",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -35,6 +35,7 @@
"oldfieldtype": "Link",
"options": "Item",
"print_hide": 0,
+ "read_only": 0,
"reqd": 1,
"search_index": 1
},
@@ -58,6 +59,7 @@
"oldfieldname": "item_name",
"oldfieldtype": "Data",
"print_hide": 1,
+ "read_only": 0,
"reqd": 1,
"search_index": 1
},
@@ -69,6 +71,7 @@
"oldfieldname": "description",
"oldfieldtype": "Small Text",
"print_width": "300px",
+ "read_only": 0,
"reqd": 1,
"width": "300px"
},
@@ -81,6 +84,7 @@
"oldfieldname": "qty",
"oldfieldtype": "Currency",
"print_width": "60px",
+ "read_only": 0,
"reqd": 1,
"width": "60px"
},
@@ -94,6 +98,7 @@
"options": "UOM",
"print_hide": 0,
"print_width": "100px",
+ "read_only": 0,
"reqd": 1,
"width": "100px"
},
@@ -103,14 +108,16 @@
"fieldtype": "Currency",
"label": "Ref Rate ",
"options": "currency",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"doctype": "DocField",
"fieldname": "discount_rate",
"fieldtype": "Float",
"label": "Discount %",
- "print_hide": 0
+ "print_hide": 0,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -121,7 +128,8 @@
"oldfieldname": "import_rate",
"oldfieldtype": "Currency",
"options": "currency",
- "print_hide": 0
+ "print_hide": 0,
+ "read_only": 0
},
{
"doctype": "DocField",
@@ -139,7 +147,8 @@
"fieldtype": "Currency",
"label": "Ref Rate*",
"options": "Company:company:default_currency",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"default": "0.00",
@@ -152,6 +161,7 @@
"options": "Company:company:default_currency",
"print_hide": 1,
"print_width": "100px",
+ "read_only": 0,
"reqd": 1,
"width": "100px"
},
@@ -178,6 +188,7 @@
"oldfieldtype": "Link",
"options": "Warehouse",
"print_hide": 1,
+ "read_only": 0,
"reqd": 0
},
{
@@ -188,6 +199,7 @@
"label": "Project Name",
"options": "Project",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0
},
{
@@ -196,7 +208,7 @@
"fieldtype": "Data",
"hidden": 1,
"label": "Prevdoc DocType",
- "no_copy": 0,
+ "no_copy": 1,
"oldfieldname": "prevdoc_doctype",
"oldfieldtype": "Data",
"print_hide": 1,
@@ -209,7 +221,7 @@
"hidden": 0,
"in_filter": 1,
"label": "Material Request No",
- "no_copy": 0,
+ "no_copy": 1,
"oldfieldname": "prevdoc_docname",
"oldfieldtype": "Link",
"options": "Material Request",
@@ -226,6 +238,7 @@
"hidden": 1,
"in_filter": 1,
"label": "Material Request Date",
+ "no_copy": 1,
"oldfieldname": "prevdoc_date",
"oldfieldtype": "Date",
"print_hide": 1,
@@ -239,7 +252,7 @@
"hidden": 1,
"in_filter": 1,
"label": "Material Request Detail No",
- "no_copy": 0,
+ "no_copy": 1,
"oldfieldname": "prevdoc_detail_docname",
"oldfieldtype": "Data",
"print_hide": 1,
@@ -295,6 +308,7 @@
"no_copy": 1,
"oldfieldname": "page_break",
"oldfieldtype": "Check",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
}
]
\ No newline at end of file
diff --git a/hr/doctype/leave_application/leave_application.py b/hr/doctype/leave_application/leave_application.py
index 6e39751b716..7c47d6a09eb 100755
--- a/hr/doctype/leave_application/leave_application.py
+++ b/hr/doctype/leave_application/leave_application.py
@@ -335,15 +335,22 @@ def add_holidays(events, start, end, employee, company):
def query_for_permitted_employees(doctype, txt, searchfield, start, page_len, filters):
txt = "%" + cstr(txt) + "%"
- return webnotes.conn.sql("""select name, employee_name from `tabEmployee` emp
+ if "Leave Approver" in webnotes.user.get_roles():
+ condition = """and (exists(select ela.name from `tabEmployee Leave Approver` ela
+ where ela.parent=`tabEmployee`.name and ela.leave_approver= "%s") or
+ not exists(select ela.name from `tabEmployee Leave Approver` ela
+ where ela.parent=`tabEmployee`.name)
+ or user_id = "%s")""" % (webnotes.session.user, webnotes.session.user)
+ else:
+ from webnotes.widgets.reportview import build_match_conditions
+ condition = build_match_conditions("Employee")
+ condition = ("and " + condition) if condition else ""
+
+ return webnotes.conn.sql("""select name, employee_name from `tabEmployee`
where status = 'Active' and docstatus < 2 and
- (`%s` like %s or employee_name like %s) and
- (exists(select ela.name from `tabEmployee Leave Approver` ela
- where ela.parent=emp.name and ela.leave_approver=%s) or
- not exists(select ela.name from `tabEmployee Leave Approver` ela where ela.parent=emp.name)
- or user_id = %s)
+ (`%s` like %s or employee_name like %s) %s
order by
case when name like %s then 0 else 1 end,
case when employee_name like %s then 0 else 1 end,
- name limit %s, %s""" % tuple([searchfield] + ["%s"]*8),
- (txt, txt, webnotes.session.user, webnotes.session.user, txt, txt, start, page_len))
+ name limit %s, %s""" % tuple([searchfield] + ["%s"]*2 + [condition] + ["%s"]*4),
+ (txt, txt, txt, txt, start, page_len))
diff --git a/patches/may_2013/p03_update_support_ticket.py b/patches/may_2013/p03_update_support_ticket.py
new file mode 100644
index 00000000000..7dc5854b44e
--- /dev/null
+++ b/patches/may_2013/p03_update_support_ticket.py
@@ -0,0 +1,27 @@
+# ERPNext - web based ERP (http://erpnext.com)
+# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units
", "doctype": "DocField", @@ -274,7 +292,8 @@ "fieldtype": "Check", "label": "Auto Inventory Accounting", "no_copy": 0, - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "description": "Accounting entry frozen up to this date, nobody can do / modify entry except authorized person", @@ -507,11 +526,6 @@ "label": "SMS Sender Name", "read_only": 0 }, - { - "amend": 0, - "cancel": 0, - "doctype": "DocPerm" - }, { "doctype": "DocPerm" } diff --git a/setup/doctype/item_group/item_group.py b/setup/doctype/item_group/item_group.py index 1445f3999fc..1ff3d4a9397 100644 --- a/setup/doctype/item_group/item_group.py +++ b/setup/doctype/item_group/item_group.py @@ -81,3 +81,4 @@ class DocType(DocTypeNestedSet): if self.doc.slideshow: from website.helpers.slideshow import get_slideshow get_slideshow(self) + \ No newline at end of file diff --git a/startup/schedule_handlers.py b/startup/schedule_handlers.py index 0799817206b..cc0d1f4fead 100644 --- a/startup/schedule_handlers.py +++ b/startup/schedule_handlers.py @@ -55,6 +55,10 @@ def execute_daily(): from setup.doctype.backup_manager.backup_manager import take_backups_daily take_backups_daily() + # check reorder level + from stock.utils import reorder_item + run_fn(reorder_item) + def execute_weekly(): from setup.doctype.backup_manager.backup_manager import take_backups_weekly take_backups_weekly() diff --git a/startup/website.py b/startup/website.py index be8eba6def1..5e6c3118c2e 100644 --- a/startup/website.py +++ b/startup/website.py @@ -1,5 +1,5 @@ import webnotes, conf, os -from webnotes.utils import cint, cstr +from webnotes.utils import cint, cstr, encode def get_templates_path(): return os.path.join(os.path.dirname(conf.__file__), "app", "website", "templates") @@ -72,7 +72,7 @@ def update_template_args(page_name, args): args[k] = cint(args.get(k) or 0) args.url = quote(str(get_request_site_address(full_address=True)), str("")) - args.encoded_title = quote(str(args.title or ""), str("")) + args.encoded_title = quote(encode(args.title or ""), str("")) return args \ No newline at end of file diff --git a/stock/doctype/bin/bin.py b/stock/doctype/bin/bin.py index 2d98c2634f7..61baafafa2e 100644 --- a/stock/doctype/bin/bin.py +++ b/stock/doctype/bin/bin.py @@ -77,10 +77,6 @@ class DocType: self.doc.save() - if (flt(args.get("actual_qty")) < 0 or flt(args.get("reserved_qty")) > 0) \ - and args.get("is_cancelled") == 'No' and args.get("is_amended")=='No': - self.reorder_item(args.get("voucher_type"), args.get("voucher_no"), args.get("company")) - def get_first_sle(self): sle = sql(""" select * from `tabStock Ledger Entry` @@ -90,82 +86,4 @@ class DocType: order by timestamp(posting_date, posting_time) asc, name asc limit 1 """, (self.doc.item_code, self.doc.warehouse), as_dict=1) - return sle and sle[0] or None - - def reorder_item(self,doc_type,doc_name, company): - """ Reorder item if stock reaches reorder level""" - if not hasattr(webnotes, "auto_indent"): - webnotes.auto_indent = webnotes.conn.get_value('Global Defaults', None, 'auto_indent') - - if webnotes.auto_indent: - #check if re-order is required - item_reorder = webnotes.conn.get("Item Reorder", - {"parent": self.doc.item_code, "warehouse": self.doc.warehouse}) - if item_reorder: - reorder_level = item_reorder.warehouse_reorder_level - reorder_qty = item_reorder.warehouse_reorder_qty - material_request_type = item_reorder.material_request_type or "Purchase" - else: - reorder_level, reorder_qty = webnotes.conn.get_value("Item", self.doc.item_code, - ["re_order_level", "re_order_qty"]) - material_request_type = "Purchase" - - if flt(reorder_qty) and flt(self.doc.projected_qty) < flt(reorder_level): - self.create_material_request(doc_type, doc_name, reorder_level, reorder_qty, - company, material_request_type) - - def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty, company, - material_request_type="Purchase"): - """ Create indent on reaching reorder level """ - defaults = webnotes.defaults.get_defaults() - item = webnotes.doc("Item", self.doc.item_code) - - mr = webnotes.bean([{ - "doctype": "Material Request", - "company": company or defaults.company, - "fiscal_year": defaults.fiscal_year, - "transaction_date": nowdate(), - "material_request_type": material_request_type, - "remark": _("This is an auto generated Material Request.") + \ - _("It was raised because the (actual + ordered + indented - reserved) quantity reaches re-order level when the following record was created") + \ - ": " + _(doc_type) + " " + doc_name - }, { - "doctype": "Material Request Item", - "parenttype": "Material Request", - "parentfield": "indent_details", - "item_code": self.doc.item_code, - "schedule_date": add_days(nowdate(),cint(item.lead_time_days)), - "uom": self.doc.stock_uom, - "warehouse": self.doc.warehouse, - "item_name": item.item_name, - "description": item.description, - "item_group": item.item_group, - "qty": reorder_qty, - "brand": item.brand, - }]) - mr.insert() - mr.submit() - - msgprint("""Item: %s is to be re-ordered. Material Request %s raised. - It was generated from %s: %s""" % - (self.doc.item_code, mr.doc.name, doc_type, doc_name)) - - if(item.email_notify): - self.send_email_notification(doc_type, doc_name, mr) - - def send_email_notification(self, doc_type, doc_name, bean): - """ Notify user about auto creation of indent""" - - from webnotes.utils.email_lib import sendmail - email_list=[d[0] for d in sql("""select distinct r.parent from tabUserRole r, tabProfile p - where p.name = r.parent and p.enabled = 1 and p.docstatus < 2 - and r.role in ('Purchase Manager','Material Manager') - and p.name not in ('Administrator', 'All', 'Guest')""")] - - msg="""A new Material Request has been raised for Item: %s and Warehouse: %s \ - on %s due to %s: %s. See %s: %s """ % (self.doc.item_code, self.doc.warehouse, - formatdate(), doc_type, doc_name, bean.doc.doctype, - get_url_to_form(bean.doc.doctype, bean.doc.name)) - - sendmail(email_list, subject='Auto Material Request Generation Notification', msg = msg) - + return sle and sle[0] or None \ No newline at end of file diff --git a/stock/doctype/delivery_note_item/delivery_note_item.txt b/stock/doctype/delivery_note_item/delivery_note_item.txt index c758fb56043..a8eda202a05 100644 --- a/stock/doctype/delivery_note_item/delivery_note_item.txt +++ b/stock/doctype/delivery_note_item/delivery_note_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-04-19 13:31:02", + "creation": "2013-04-22 13:15:44", "docstatus": 0, - "modified": "2013-05-21 16:47:16", + "modified": "2013-05-22 12:15:32", "modified_by": "Administrator", "owner": "Administrator" }, @@ -340,6 +340,7 @@ "hidden": 1, "in_filter": 1, "label": "Document Type", + "no_copy": 1, "oldfieldname": "prevdoc_doctype", "oldfieldtype": "Data", "print_hide": 1, @@ -371,6 +372,7 @@ "hidden": 1, "in_filter": 1, "label": "Against Document Date", + "no_copy": 1, "oldfieldname": "prevdoc_date", "oldfieldtype": "Date", "print_hide": 1, @@ -383,6 +385,7 @@ "hidden": 1, "in_filter": 1, "label": "Against Document Detail No", + "no_copy": 1, "oldfieldname": "prevdoc_detail_docname", "oldfieldtype": "Data", "print_hide": 1, diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py index bc438a877ac..d743a980057 100644 --- a/stock/doctype/item/item.py +++ b/stock/doctype/item/item.py @@ -51,6 +51,7 @@ class DocType(DocListController): self.validate_barcode() self.check_non_asset_warehouse() self.cant_change() + self.validate_item_type_for_reorder() if self.doc.name: self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name') @@ -201,6 +202,13 @@ class DocType(DocListController): webnotes.msgprint(_("As there are existing stock transactions for this \ item, you can not change the values of 'Has Serial No', \ 'Is Stock Item' and 'Valuation Method'"), raise_exception=1) + + def validate_item_type_for_reorder(self): + if self.doc.re_order_level or len(self.doclist.get({"parentfield": "item_reorder", + "material_request_type": "Purchase"})): + if not self.doc.is_purchase_item: + webnotes.msgprint(_("""To set reorder level, item must be Purchase Item"""), + raise_exception=1) def check_if_sle_exists(self): sle = webnotes.conn.sql("""select name from `tabStock Ledger Entry` diff --git a/stock/doctype/item/item.txt b/stock/doctype/item/item.txt index 5f6c760ad10..611ae5e937e 100644 --- a/stock/doctype/item/item.txt +++ b/stock/doctype/item/item.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-03 10:45:46", "docstatus": 0, - "modified": "2013-05-07 16:00:00", + "modified": "2013-05-22 15:49:27", "modified_by": "Administrator", "owner": "Administrator" }, @@ -363,21 +363,6 @@ "label": "Re-Order Qty", "read_only": 0 }, - { - "doctype": "DocField", - "fieldname": "column_break_31", - "fieldtype": "Column Break", - "read_only": 0 - }, - { - "depends_on": "eval:doc.is_stock_item==\"Yes\"", - "description": "Send an email to users of role \"Material Manager\" and \"Purchase Manager\" when re-order level is crossed.", - "doctype": "DocField", - "fieldname": "email_notify", - "fieldtype": "Check", - "label": "Notify by Email on Re-order", - "read_only": 0 - }, { "doctype": "DocField", "fieldname": "section_break_31", diff --git a/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt b/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt index 7f4e827aa30..8cef6a35340 100755 --- a/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt +++ b/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-02-22 01:28:03", + "creation": "2013-03-07 11:42:59", "docstatus": 0, - "modified": "2013-03-07 07:03:28", + "modified": "2013-05-22 12:01:08", "modified_by": "Administrator", "owner": "Administrator" }, @@ -35,6 +35,7 @@ "oldfieldtype": "Link", "options": "Item", "print_width": "100px", + "read_only": 0, "reqd": 1, "search_index": 1, "width": "100px" @@ -48,6 +49,7 @@ "oldfieldname": "item_name", "oldfieldtype": "Data", "print_hide": 1, + "read_only": 0, "reqd": 1, "search_index": 0 }, @@ -59,6 +61,7 @@ "oldfieldname": "description", "oldfieldtype": "Text", "print_width": "300px", + "read_only": 0, "reqd": 1, "width": "300px" }, @@ -72,6 +75,7 @@ "oldfieldtype": "Currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -84,6 +88,7 @@ "oldfieldname": "qty", "oldfieldtype": "Currency", "print_width": "100px", + "read_only": 0, "width": "100px" }, { @@ -97,6 +102,7 @@ "oldfieldtype": "Currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "search_index": 0, "width": "100px" }, @@ -110,6 +116,7 @@ "options": "UOM", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -119,14 +126,16 @@ "fieldtype": "Currency", "label": "Ref Rate ", "options": "currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "discount_rate", "fieldtype": "Float", "label": "Discount %", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "default": "0.00", @@ -139,6 +148,7 @@ "options": "currency", "print_hide": 0, "print_width": "100px", + "read_only": 0, "width": "100px" }, { @@ -157,7 +167,8 @@ "fieldtype": "Currency", "label": "Ref Rate*", "options": "Company:company:default_currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "default": "0.00", @@ -170,6 +181,7 @@ "options": "Company:company:default_currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -184,6 +196,7 @@ "options": "Company:company:default_currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 0, "width": "100px" }, @@ -198,6 +211,7 @@ "options": "Warehouse", "print_hide": 1, "print_width": "100px", + "read_only": 0, "width": "100px" }, { @@ -209,6 +223,7 @@ "oldfieldtype": "Currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -235,6 +250,7 @@ "oldfieldname": "serial_no", "oldfieldtype": "Text", "print_hide": 0, + "read_only": 0, "report_hide": 0 }, { @@ -242,7 +258,8 @@ "fieldname": "rejected_serial_no", "fieldtype": "Text", "label": "Rejected Serial No", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -252,7 +269,8 @@ "oldfieldname": "batch_no", "oldfieldtype": "Link", "options": "Batch", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -278,6 +296,7 @@ "oldfieldname": "schedule_date", "oldfieldtype": "Date", "print_hide": 1, + "read_only": 0, "report_hide": 0, "reqd": 0 }, @@ -288,7 +307,8 @@ "in_filter": 1, "label": "Project Name", "options": "Project", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -299,7 +319,8 @@ "oldfieldname": "qa_no", "oldfieldtype": "Link", "options": "Quality Inspection", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -336,6 +357,7 @@ "oldfieldtype": "Currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "width": "100px" }, { @@ -344,9 +366,11 @@ "fieldtype": "Data", "hidden": 1, "label": "Prevdoc Doctype", + "no_copy": 1, "oldfieldname": "prevdoc_doctype", "oldfieldtype": "Data", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -355,7 +379,7 @@ "hidden": 0, "in_filter": 1, "label": "PO No", - "no_copy": 0, + "no_copy": 1, "oldfieldname": "prevdoc_docname", "oldfieldtype": "Link", "options": "Purchase Order", @@ -373,6 +397,7 @@ "hidden": 1, "in_filter": 1, "label": "PO Date", + "no_copy": 1, "oldfieldname": "prevdoc_date", "oldfieldtype": "Date", "print_hide": 1, @@ -418,7 +443,7 @@ "hidden": 1, "in_filter": 1, "label": "Purchase Order Item No", - "no_copy": 0, + "no_copy": 1, "oldfieldname": "prevdoc_detail_docname", "oldfieldtype": "Data", "print_hide": 1, @@ -479,6 +504,7 @@ "label": "Page Break", "oldfieldname": "page_break", "oldfieldtype": "Check", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 } ] \ No newline at end of file diff --git a/stock/utils.py b/stock/utils.py index a2541dc69e9..5e7e53bb014 100644 --- a/stock/utils.py +++ b/stock/utils.py @@ -17,7 +17,7 @@ import webnotes from webnotes import msgprint, _ import json -from webnotes.utils import flt, cstr +from webnotes.utils import flt, cstr, nowdate, add_days, cint from webnotes.defaults import get_global_default def validate_end_of_life(item_code, end_of_life=None, verbose=1): @@ -194,4 +194,117 @@ def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse, buying_amount = previous_stock_value - flt(sle.stock_value) return buying_amount - return 0.0 \ No newline at end of file + return 0.0 + + +def reorder_item(): + """ Reorder item if stock reaches reorder level""" + if not hasattr(webnotes, "auto_indent"): + webnotes.auto_indent = webnotes.conn.get_value('Global Defaults', None, 'auto_indent') + + if webnotes.auto_indent: + material_requests = {} + bin_list = webnotes.conn.sql("""select item_code, warehouse, projected_qty + from tabBin where ifnull(item_code, '') != '' and ifnull(warehouse, '') != ''""", + as_dict=True) + for bin in bin_list: + #check if re-order is required + item_reorder = webnotes.conn.get("Item Reorder", + {"parent": bin.item_code, "warehouse": bin.warehouse}) + if item_reorder: + reorder_level = item_reorder.warehouse_reorder_level + reorder_qty = item_reorder.warehouse_reorder_qty + material_request_type = item_reorder.material_request_type or "Purchase" + else: + reorder_level, reorder_qty = webnotes.conn.get_value("Item", bin.item_code, + ["re_order_level", "re_order_qty"]) + material_request_type = "Purchase" + + if reorder_level and flt(bin.projected_qty) < flt(reorder_level): + if flt(reorder_level) - flt(bin.projected_qty) > flt(reorder_qty): + reorder_qty = flt(reorder_level) - flt(bin.projected_qty) + + company = webnotes.conn.get_value("Warehouse", bin.warehouse, "company") or \ + webnotes.defaults.get_defaults()["company"] or \ + webnotes.conn.sql("""select name from tabCompany limit 1""")[0][0] + + material_requests.setdefault(material_request_type, webnotes._dict()).setdefault( + company, []).append(webnotes._dict({ + "item_code": bin.item_code, + "warehouse": bin.warehouse, + "reorder_qty": reorder_qty + }) + ) + + create_material_request(material_requests) + +def create_material_request(material_requests): + """ Create indent on reaching reorder level """ + mr_list = [] + defaults = webnotes.defaults.get_defaults() + for request_type in material_requests: + for company in material_requests[request_type]: + items = material_requests[request_type][company] + if items: + mr = [{ + "doctype": "Material Request", + "company": company, + "fiscal_year": defaults.fiscal_year, + "transaction_date": nowdate(), + "material_request_type": request_type, + "remark": _("This is an auto generated Material Request.") + \ + _("""It was raised because the (actual + ordered + indented - reserved) + quantity reaches re-order level when the following record was created""") + }] + + for d in items: + item = webnotes.doc("Item", d.item_code) + mr.append({ + "doctype": "Material Request Item", + "parenttype": "Material Request", + "parentfield": "indent_details", + "item_code": d.item_code, + "schedule_date": add_days(nowdate(),cint(item.lead_time_days)), + "uom": item.stock_uom, + "warehouse": d.warehouse, + "item_name": item.item_name, + "description": item.description, + "item_group": item.item_group, + "qty": d.reorder_qty, + "brand": item.brand, + }) + + mr_bean = webnotes.bean(mr) + mr_bean.insert() + mr_bean.submit() + mr_list.append(mr_bean) + + if mr_list: + if not hasattr(webnotes, "reorder_email_notify"): + webnotes.reorder_email_notify = webnotes.conn.get_value('Global Defaults', None, + 'reorder_email_notify') + + if(webnotes.reorder_email_notify): + send_email_notification(mr_list) + +def send_email_notification(mr_list): + """ Notify user about auto creation of indent""" + + from webnotes.utils.email_lib import sendmail + email_list = webnotes.conn.sql_list("""select distinct r.parent + from tabUserRole r, tabProfile p + where p.name = r.parent and p.enabled = 1 and p.docstatus < 2 + and r.role in ('Purchase Manager','Material Manager') + and p.name not in ('Administrator', 'All', 'Guest')""") + + msg="""" + mr.doc.name + """
| Item Code | Warehouse | Qty | UOM |
|---|---|---|---|
| " + item.item_code + " | " + item.warehouse + " | " + \ + cstr(item.qty) + " | " + cstr(item.uom) + " |
{{ slide.description }}
{% endif %} + {% if slide.description %}{{ slide.description }}
{% endif %}