Merge pull request #1361 from trhura/develop

Pull request for issue #856
This commit is contained in:
Nabin Hait 2014-01-29 00:30:07 -08:00
commit 115dcc09d4
4 changed files with 399 additions and 359 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,15 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt # License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes import msgprint from webnotes import msgprint
from webnotes.utils import flt, getdate from webnotes.utils import flt, getdate, add_days
from webnotes.model.controller import DocListController from webnotes.model.controller import DocListController
from datetime import date
class StockFreezeError(webnotes.ValidationError): pass
class DocType(DocListController): class DocType(DocListController):
def __init__(self, doc, doclist=[]): def __init__(self, doc, doclist=[]):
@ -19,30 +23,30 @@ class DocType(DocListController):
validate_warehouse_user(self.doc.warehouse) validate_warehouse_user(self.doc.warehouse)
validate_warehouse_company(self.doc.warehouse, self.doc.company) validate_warehouse_company(self.doc.warehouse, self.doc.company)
self.scrub_posting_time() self.scrub_posting_time()
from accounts.utils import validate_fiscal_year from accounts.utils import validate_fiscal_year
validate_fiscal_year(self.doc.posting_date, self.doc.fiscal_year, self.meta.get_label("posting_date")) validate_fiscal_year(self.doc.posting_date, self.doc.fiscal_year, self.meta.get_label("posting_date"))
def on_submit(self): def on_submit(self):
self.check_stock_frozen_date() self.check_stock_frozen_date()
self.actual_amt_check() self.actual_amt_check()
from stock.doctype.serial_no.serial_no import process_serial_no from stock.doctype.serial_no.serial_no import process_serial_no
process_serial_no(self.doc) process_serial_no(self.doc)
#check for item quantity available in stock #check for item quantity available in stock
def actual_amt_check(self): def actual_amt_check(self):
if self.doc.batch_no: if self.doc.batch_no:
batch_bal_after_transaction = flt(webnotes.conn.sql("""select sum(actual_qty) batch_bal_after_transaction = flt(webnotes.conn.sql("""select sum(actual_qty)
from `tabStock Ledger Entry` from `tabStock Ledger Entry`
where warehouse=%s and item_code=%s and batch_no=%s""", where warehouse=%s and item_code=%s and batch_no=%s""",
(self.doc.warehouse, self.doc.item_code, self.doc.batch_no))[0][0]) (self.doc.warehouse, self.doc.item_code, self.doc.batch_no))[0][0])
if batch_bal_after_transaction < 0: if batch_bal_after_transaction < 0:
self.doc.fields.update({ self.doc.fields.update({
'batch_bal': batch_bal_after_transaction - self.doc.actual_qty 'batch_bal': batch_bal_after_transaction - self.doc.actual_qty
}) })
webnotes.throw("""Not enough quantity (requested: %(actual_qty)s, \ webnotes.throw("""Not enough quantity (requested: %(actual_qty)s, \
current: %(batch_bal)s in Batch <b>%(batch_no)s</b> for Item \ current: %(batch_bal)s in Batch <b>%(batch_no)s</b> for Item \
<b>%(item_code)s</b> at Warehouse <b>%(warehouse)s</b> \ <b>%(item_code)s</b> at Warehouse <b>%(warehouse)s</b> \
@ -60,41 +64,49 @@ class DocType(DocListController):
msgprint("Warehouse: '%s' does not exist in the system. Please check." % self.doc.fields.get(k), raise_exception = 1) msgprint("Warehouse: '%s' does not exist in the system. Please check." % self.doc.fields.get(k), raise_exception = 1)
def validate_item(self): def validate_item(self):
item_det = webnotes.conn.sql("""select name, has_batch_no, docstatus, item_det = webnotes.conn.sql("""select name, has_batch_no, docstatus,
is_stock_item, has_serial_no, serial_no_series is_stock_item, has_serial_no, serial_no_series
from tabItem where name=%s""", from tabItem where name=%s""",
self.doc.item_code, as_dict=True)[0] self.doc.item_code, as_dict=True)[0]
if item_det.is_stock_item != 'Yes': if item_det.is_stock_item != 'Yes':
webnotes.throw("""Item: "%s" is not a Stock Item.""" % self.doc.item_code) webnotes.throw("""Item: "%s" is not a Stock Item.""" % self.doc.item_code)
# check if batch number is required # check if batch number is required
if item_det.has_batch_no =='Yes' and self.doc.voucher_type != 'Stock Reconciliation': if item_det.has_batch_no =='Yes' and self.doc.voucher_type != 'Stock Reconciliation':
if not self.doc.batch_no: if not self.doc.batch_no:
webnotes.throw("Batch number is mandatory for Item '%s'" % self.doc.item_code) webnotes.throw("Batch number is mandatory for Item '%s'" % self.doc.item_code)
# check if batch belongs to item # check if batch belongs to item
if not webnotes.conn.sql("""select name from `tabBatch` if not webnotes.conn.sql("""select name from `tabBatch`
where item='%s' and name ='%s' and docstatus != 2""" % (self.doc.item_code, self.doc.batch_no)): where item='%s' and name ='%s' and docstatus != 2""" % (self.doc.item_code, self.doc.batch_no)):
webnotes.throw("'%s' is not a valid Batch Number for Item '%s'" % (self.doc.batch_no, self.doc.item_code)) webnotes.throw("'%s' is not a valid Batch Number for Item '%s'" % (self.doc.batch_no, self.doc.item_code))
if not self.doc.stock_uom: if not self.doc.stock_uom:
self.doc.stock_uom = item_det.stock_uom self.doc.stock_uom = item_det.stock_uom
def check_stock_frozen_date(self): def check_stock_frozen_date(self):
stock_frozen_upto = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto') or '' stock_frozen_upto = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto') or ''
if stock_frozen_upto: if stock_frozen_upto:
stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role')
if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles(): if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles():
msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=1) msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=StockFreezeError)
stock_frozen_upto_days = int(webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0)
if stock_frozen_upto_days:
stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role')
older_than_x_days_ago = (add_days(getdate(self.doc.posting_date), stock_frozen_upto_days) <= date.today())
if older_than_x_days_ago and not stock_auth_role in webnotes.user.get_roles():
msgprint("You are not authorized to do / modify back dated stock entries older than %d days ago" %stock_frozen_upto_days, raise_exception=StockFreezeError)
def scrub_posting_time(self): def scrub_posting_time(self):
if not self.doc.posting_time or self.doc.posting_time == '00:0': if not self.doc.posting_time or self.doc.posting_time == '00:0':
self.doc.posting_time = '00:00' self.doc.posting_time = '00:00'
def on_doctype_update(): def on_doctype_update():
if not webnotes.conn.sql("""show index from `tabStock Ledger Entry` if not webnotes.conn.sql("""show index from `tabStock Ledger Entry`
where Key_name="posting_sort_index" """): where Key_name="posting_sort_index" """):
webnotes.conn.commit() webnotes.conn.commit()
webnotes.conn.sql("""alter table `tabStock Ledger Entry` webnotes.conn.sql("""alter table `tabStock Ledger Entry`
add index posting_sort_index(posting_date, posting_time, name)""") add index posting_sort_index(posting_date, posting_time, name)""")

View File

@ -5,18 +5,23 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes import _
class DocType: class DocType:
def __init__(self, d, dl): def __init__(self, d, dl):
self.doc, self.doclist = d, dl self.doc, self.doclist = d, dl
def validate(self): def validate(self):
for key in ["item_naming_by", "item_group", "stock_uom", for key in ["item_naming_by", "item_group", "stock_uom",
"allow_negative_stock"]: "allow_negative_stock"]:
webnotes.conn.set_default(key, self.doc.fields.get(key, "")) webnotes.conn.set_default(key, self.doc.fields.get(key, ""))
from setup.doctype.naming_series.naming_series import set_by_naming_series from setup.doctype.naming_series.naming_series import set_by_naming_series
set_by_naming_series("Item", "item_code", set_by_naming_series("Item", "item_code",
self.doc.get("item_naming_by")=="Naming Series", hide_name_field=True) self.doc.get("item_naming_by")=="Naming Series", hide_name_field=True)
stock_frozen_limit = 356
submitted_stock_frozen = self.doc.stock_frozen_upto_days
if submitted_stock_frozen > stock_frozen_limit:
self.doc.stock_frozen_upto_days = stock_frozen_limit
webnotes.msgprint (_("`Freeze Stocks Older Than` should be smaller than %d days.") %stock_frozen_limit)

View File

@ -1,128 +1,134 @@
[ [
{ {
"creation": "2013-06-24 16:37:54", "creation": "2013-06-24 16:37:54",
"docstatus": 0, "docstatus": 0,
"modified": "2013-11-02 19:41:56", "modified": "2014-01-27 20:00:56",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
{ {
"description": "Settings", "description": "Settings",
"doctype": "DocType", "doctype": "DocType",
"icon": "icon-cog", "icon": "icon-cog",
"issingle": 1, "issingle": 1,
"module": "Stock", "module": "Stock",
"name": "__common__" "name": "__common__"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"name": "__common__", "name": "__common__",
"parent": "Stock Settings", "parent": "Stock Settings",
"parentfield": "fields", "parentfield": "fields",
"parenttype": "DocType", "parenttype": "DocType",
"permlevel": 0 "permlevel": 0
}, },
{ {
"create": 1, "create": 1,
"doctype": "DocPerm", "doctype": "DocPerm",
"name": "__common__", "name": "__common__",
"parent": "Stock Settings", "parent": "Stock Settings",
"parentfield": "permissions", "parentfield": "permissions",
"parenttype": "DocType", "parenttype": "DocType",
"permlevel": 0, "permlevel": 0,
"read": 1, "read": 1,
"role": "Material Manager", "role": "Material Manager",
"write": 1 "write": 1
}, },
{ {
"doctype": "DocType", "doctype": "DocType",
"name": "Stock Settings" "name": "Stock Settings"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "item_naming_by", "fieldname": "item_naming_by",
"fieldtype": "Select", "fieldtype": "Select",
"label": "Item Naming By", "label": "Item Naming By",
"options": "Item Code\nNaming Series" "options": "Item Code\nNaming Series"
}, },
{ {
"description": "<a href=\"#Sales Browser/Item Group\">Add / Edit</a>", "description": "<a href=\"#Sales Browser/Item Group\">Add / Edit</a>",
"doctype": "DocField", "doctype": "DocField",
"fieldname": "item_group", "fieldname": "item_group",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Default Item Group", "label": "Default Item Group",
"options": "Item Group" "options": "Item Group"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "stock_uom", "fieldname": "stock_uom",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Default Stock UOM", "label": "Default Stock UOM",
"options": "UOM" "options": "UOM"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "column_break_4", "fieldname": "column_break_4",
"fieldtype": "Column Break" "fieldtype": "Column Break"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "allow_negative_stock", "fieldname": "allow_negative_stock",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Allow Negative Stock" "label": "Allow Negative Stock"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "valuation_method", "fieldname": "valuation_method",
"fieldtype": "Select", "fieldtype": "Select",
"label": "Default Valuation Method", "label": "Default Valuation Method",
"options": "FIFO\nMoving Average" "options": "FIFO\nMoving Average"
}, },
{ {
"description": "Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.", "description": "Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.",
"doctype": "DocField", "doctype": "DocField",
"fieldname": "tolerance", "fieldname": "tolerance",
"fieldtype": "Float", "fieldtype": "Float",
"label": "Allowance Percent" "label": "Allowance Percent"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "auto_material_request", "fieldname": "auto_material_request",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Auto Material Request" "label": "Auto Material Request"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "auto_indent", "fieldname": "auto_indent",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Raise Material Request when stock reaches re-order level" "label": "Raise Material Request when stock reaches re-order level"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "reorder_email_notify", "fieldname": "reorder_email_notify",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Notify by Email on creation of automatic Material Request" "label": "Notify by Email on creation of automatic Material Request"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "freeze_stock_entries", "fieldname": "freeze_stock_entries",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Freeze Stock Entries" "label": "Freeze Stock Entries"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "stock_frozen_upto", "fieldname": "stock_frozen_upto",
"fieldtype": "Date", "fieldtype": "Date",
"label": "Stock Frozen Upto" "label": "Stock Frozen Upto"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "stock_auth_role", "fieldname": "stock_frozen_upto_days",
"fieldtype": "Link", "fieldtype": "Int",
"label": "Role Allowed to edit frozen stock", "label": "Freeze Stocks Older Than [Days]"
},
{
"doctype": "DocField",
"fieldname": "stock_auth_role",
"fieldtype": "Link",
"label": "Role Allowed to edit frozen stock",
"options": "Role" "options": "Role"
}, },
{ {
"doctype": "DocPerm" "doctype": "DocPerm"
} }
] ]