Merge pull request #1361 from trhura/develop
Pull request for issue #856
This commit is contained in:
commit
115dcc09d4
File diff suppressed because it is too large
Load Diff
@ -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)""")
|
@ -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)
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user