stock entry cleanp
This commit is contained in:
parent
9ea22b75bd
commit
7c59c68434
@ -1 +0,0 @@
|
||||
from __future__ import unicode_literals
|
@ -1,69 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
|
||||
import webnotes
|
||||
import webnotes.profile
|
||||
webnotes.user = webnotes.profile.Profile()
|
||||
|
||||
|
||||
from webnotes.model.code import get_obj
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
from sandbox.testdata import leaves
|
||||
#----------------------------------------------------------
|
||||
|
||||
|
||||
class TestStockEntry(unittest.TestCase):
|
||||
#===========================================================================
|
||||
def setUp(self):
|
||||
webnotes.conn.begin()
|
||||
leaves.emp.save(new = 1, make_autoname = 0)
|
||||
|
||||
def test_leave_bal(self):
|
||||
leaves.l_all.save(1)
|
||||
leaves.l_app1.save(1)
|
||||
leaves.l_app2.save(1)
|
||||
|
||||
la1 = get_obj('Leave Application', leaves.l_app1.name, with_children=1)
|
||||
la1.validate()
|
||||
la1.doc.docstatus = 1
|
||||
la1.doc.save()
|
||||
|
||||
self.assertTrue(la1.doc.total_leave_days == 2)
|
||||
|
||||
la1.doc.half_day = 1
|
||||
la1.validate()
|
||||
la1.doc.save()
|
||||
|
||||
self.assertTrue(la1.doc.total_leave_days == .5)
|
||||
|
||||
print "Test case for leave applied no of days"
|
||||
|
||||
|
||||
la2 = get_obj('Leave Application', leaves.l_app2.name, with_children=1)
|
||||
la2.validate()
|
||||
bal = la2.get_leave_balance()
|
||||
self.assertTrue(bal, 18)
|
||||
print "Test case for leave balance"
|
||||
|
||||
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
webnotes.conn.rollback()
|
@ -1,490 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
|
||||
import webnotes
|
||||
import webnotes.profile
|
||||
webnotes.user = webnotes.profile.Profile()
|
||||
|
||||
|
||||
from webnotes.model.code import get_obj
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
from sandbox.testdata.masters import *
|
||||
from sandbox.testdata import stock_entry
|
||||
#----------------------------------------------------------
|
||||
|
||||
|
||||
class TestStockEntry(unittest.TestCase):
|
||||
#===========================================================================
|
||||
def assertDoc(self, lst):
|
||||
"""assert all values"""
|
||||
for d in lst:
|
||||
cl, vl = [], []
|
||||
for k in d.keys():
|
||||
if k!='doctype':
|
||||
cl.append('%s=%s' % (k, '%s'))
|
||||
vl.append(d[k])
|
||||
|
||||
self.assertTrue(sql("select name from `tab%s` where %s limit 1" % (d['doctype'], ' and '.join(cl)), vl))
|
||||
|
||||
#===========================================================================
|
||||
def assertCount(self, lst):
|
||||
"""assert all values"""
|
||||
for d in lst:
|
||||
cl, vl = [], []
|
||||
for k in d[0].keys():
|
||||
if k!='doctype':
|
||||
cl.append('%s=%s' % (k, '%s'))
|
||||
vl.append(d[0][k])
|
||||
|
||||
self.assertTrue(sql("select count(name) from `tab%s` where %s limit 1" % (d[0]['doctype'], ' and '.join(cl)), vl)[0][0] == d[1])
|
||||
|
||||
#===========================================================================
|
||||
def setUp(self):
|
||||
print "====================================="
|
||||
webnotes.conn.begin()
|
||||
create_master_records()
|
||||
print 'Master Data Created'
|
||||
|
||||
#===========================================================================
|
||||
# Purpose: Material Receipt
|
||||
#===========================================================================
|
||||
def test_mr_onsubmit(self):
|
||||
print "Test Case: Material Receipt submission"
|
||||
self.save_stock_entry('Material Receipt')
|
||||
|
||||
mr = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
|
||||
self.submit_stock_entry(mr)
|
||||
|
||||
# stock ledger entry
|
||||
print "Checking stock ledger entry........."
|
||||
self.assertDoc(self.get_expected_sle('mr_submit'))
|
||||
|
||||
# bin qty
|
||||
print "Checking Bin qty........."
|
||||
self.assertDoc([{'doctype':'Bin', 'actual_qty':10, 'item_code':'it', 'warehouse':'wh1'}])
|
||||
|
||||
# serial no
|
||||
self.assertCount([[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh1', 'status': 'In Store', 'docstatus': 0}, 10]])
|
||||
|
||||
|
||||
#===========================================================================
|
||||
def test_mr_oncancel(self):
|
||||
print "Test Case: Material Receipt Cancellation"
|
||||
self.save_stock_entry('Material Receipt')
|
||||
|
||||
mr = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
|
||||
self.cancel_stock_entry(mr)
|
||||
|
||||
# stock ledger entry
|
||||
print "Checking stock ledger entry........."
|
||||
self.assertDoc(self.get_expected_sle('mr_cancel'))
|
||||
|
||||
# bin qty
|
||||
print "Checking Bin qty........."
|
||||
self.assertDoc([{'doctype':'Bin', 'actual_qty':0, 'item_code':'it', 'warehouse':'wh1'}])
|
||||
|
||||
# serial no
|
||||
self.assertCount([[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': '', 'status': 'Not in Use', 'docstatus': 2}, 10]])
|
||||
|
||||
#===========================================================================
|
||||
# Purpose: Material Transafer
|
||||
#===========================================================================
|
||||
def test_mtn_onsubmit(self):
|
||||
print "Test Case: Material Transfer Note submission"
|
||||
|
||||
self.save_stock_entry('Material Receipt')
|
||||
mr = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
|
||||
mr = self.submit_stock_entry(mr)
|
||||
|
||||
self.save_stock_entry('Material Transfer')
|
||||
mtn = get_obj('Stock Entry', stock_entry.mtn[0].name, with_children=1)
|
||||
mtn = self.submit_stock_entry(mtn)
|
||||
|
||||
# stock ledger entry
|
||||
print "Checking stock ledger entry........."
|
||||
self.assertDoc(self.get_expected_sle('mtn_submit'))
|
||||
|
||||
# bin qty
|
||||
print "Checking Bin qty........."
|
||||
self.assertDoc([
|
||||
{'doctype':'Bin', 'actual_qty':5, 'item_code':'it', 'warehouse':'wh1'},
|
||||
{'doctype':'Bin', 'actual_qty':5, 'item_code':'it', 'warehouse':'wh2'}
|
||||
])
|
||||
|
||||
# serial no
|
||||
self.assertCount([
|
||||
[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh1', 'status': 'In Store', 'docstatus': 0}, 5],
|
||||
[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh2', 'status': 'In Store', 'docstatus': 0}, 5]
|
||||
])
|
||||
|
||||
#===========================================================================
|
||||
def test_mtn_oncancel(self):
|
||||
print "Test Case: Material Transfer Note Cancellation"
|
||||
|
||||
self.save_stock_entry('Material Receipt')
|
||||
mr = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
|
||||
mr = self.submit_stock_entry(mr)
|
||||
|
||||
self.save_stock_entry('Material Transfer')
|
||||
mtn = get_obj('Stock Entry', stock_entry.mtn[0].name, with_children=1)
|
||||
self.cancel_stock_entry(mtn)
|
||||
|
||||
# stock ledger entry
|
||||
print "Checking stock ledger entry........."
|
||||
self.assertDoc(self.get_expected_sle('mtn_cancel'))
|
||||
|
||||
# bin qty
|
||||
print "Checking Bin qty........."
|
||||
self.assertDoc([
|
||||
{'doctype':'Bin', 'actual_qty':10, 'item_code':'it', 'warehouse':'wh1'},
|
||||
{'doctype':'Bin', 'actual_qty':0, 'item_code':'it', 'warehouse':'wh2'}
|
||||
])
|
||||
|
||||
# serial no
|
||||
self.assertCount([[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh1', 'status': 'In Store', 'docstatus': 0}, 10]])
|
||||
|
||||
#===========================================================================
|
||||
# Purpose: Material Issue
|
||||
#===========================================================================
|
||||
def test_mi_onsubmit(self):
|
||||
print "Test Case: Material Issue submission"
|
||||
|
||||
self.save_stock_entry('Material Receipt')
|
||||
mr = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
|
||||
mr = self.submit_stock_entry(mr)
|
||||
|
||||
self.save_stock_entry('Material Issue')
|
||||
mi = get_obj('Stock Entry', stock_entry.mi[0].name, with_children=1)
|
||||
mi = self.submit_stock_entry(mi)
|
||||
|
||||
# stock ledger entry
|
||||
print "Checking stock ledger entry........."
|
||||
self.assertDoc(self.get_expected_sle('mi_submit'))
|
||||
|
||||
# bin qty
|
||||
print "Checking Bin qty........."
|
||||
self.assertDoc([
|
||||
{'doctype':'Bin', 'actual_qty':6, 'item_code':'it', 'warehouse':'wh1'}
|
||||
])
|
||||
|
||||
# serial no
|
||||
self.assertCount([
|
||||
[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh1', 'status': 'In Store', 'docstatus': 0}, 6]
|
||||
])
|
||||
|
||||
#===========================================================================
|
||||
def test_mi_oncancel(self):
|
||||
print "Test Case: Material Issue Cancellation"
|
||||
|
||||
self.save_stock_entry('Material Receipt')
|
||||
mr = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
|
||||
mr = self.submit_stock_entry(mr)
|
||||
|
||||
self.save_stock_entry('Material Issue')
|
||||
mi = get_obj('Stock Entry', stock_entry.mi[0].name, with_children=1)
|
||||
self.cancel_stock_entry(mi)
|
||||
|
||||
# stock ledger entry
|
||||
print "Checking stock ledger entry........."
|
||||
self.assertDoc(self.get_expected_sle('mi_cancel'))
|
||||
|
||||
# bin qty
|
||||
print "Checking Bin qty........."
|
||||
self.assertDoc([
|
||||
{'doctype':'Bin', 'actual_qty':10, 'item_code':'it', 'warehouse':'wh1'}
|
||||
])
|
||||
|
||||
# serial no
|
||||
self.assertCount([
|
||||
[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh1', 'status': 'In Store', 'docstatus': 0}, 10]
|
||||
])
|
||||
|
||||
#===========================================================================
|
||||
def test_entries_on_same_datetime(self):
|
||||
print "Test Case: Multiple entries on same datetime, cancel first one"
|
||||
|
||||
# submitted 1st MR
|
||||
self.save_stock_entry('Material Receipt')
|
||||
mr = get_obj('Stock Entry', stock_entry.mr[0].name, with_children=1)
|
||||
mr = self.submit_stock_entry(mr)
|
||||
|
||||
# submitted 2nd MR
|
||||
for each in stock_entry.mr1:
|
||||
each.save(1)
|
||||
for t in stock_entry.mr1[1:]:
|
||||
sql("update `tabStock Entry Detail` set parent = '%s' where name = '%s'" % (stock_entry.mr1[0].name, t.name))
|
||||
|
||||
mr1 = get_obj('Stock Entry', stock_entry.mr1[0].name, with_children=1)
|
||||
mr1 = self.submit_stock_entry(mr1)
|
||||
|
||||
|
||||
# submitted MTN
|
||||
self.save_stock_entry('Material Transfer')
|
||||
mtn = get_obj('Stock Entry', stock_entry.mtn[0].name, with_children=1)
|
||||
mtn = self.submit_stock_entry(mtn)
|
||||
|
||||
# cancel prev MR
|
||||
mr.on_cancel()
|
||||
mr.doc.cancel_reason = "testing"
|
||||
mr.doc.docstatus = 2
|
||||
mr.doc.save()
|
||||
|
||||
|
||||
# stock ledger entry
|
||||
print "Checking stock ledger entry........."
|
||||
self.assertDoc(self.get_expected_sle('entries_on_same_datetime'))
|
||||
|
||||
# bin qty
|
||||
print "Checking Bin qty........."
|
||||
self.assertDoc([
|
||||
{'doctype':'Bin', 'actual_qty':0, 'item_code':'it', 'warehouse':'wh1'},
|
||||
{'doctype':'Bin', 'actual_qty':5, 'item_code':'it', 'warehouse':'wh2'}
|
||||
])
|
||||
|
||||
# serial no
|
||||
self.assertCount([
|
||||
[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh1', 'status': 'In Store', 'docstatus': 0}, 0],
|
||||
[{'doctype': 'Serial No', 'item_code': 'it', 'warehouse': 'wh2', 'status': 'In Store', 'docstatus': 0}, 5]
|
||||
])
|
||||
|
||||
#===========================================================================
|
||||
def save_stock_entry(self, t):
|
||||
if t == 'Material Receipt':
|
||||
data = stock_entry.mr
|
||||
elif t == 'Material Transfer':
|
||||
data = stock_entry.mtn
|
||||
elif t == 'Material Issue':
|
||||
data = stock_entry.mi
|
||||
|
||||
for each in data:
|
||||
each.save(1)
|
||||
|
||||
for t in data[1:]:
|
||||
sql("update `tabStock Entry Detail` set parent = '%s' where name = '%s'" % (data[0].name, t.name))
|
||||
print "Stock Entry Created"
|
||||
|
||||
|
||||
#===========================================================================
|
||||
def submit_stock_entry(self, ste):
|
||||
ste.validate()
|
||||
ste.on_submit()
|
||||
|
||||
ste.doc.docstatus = 1
|
||||
ste.doc.save()
|
||||
|
||||
print "Stock Entry Submitted"
|
||||
return ste
|
||||
|
||||
#===========================================================================
|
||||
def cancel_stock_entry(self, ste):
|
||||
ste = self.submit_stock_entry(ste)
|
||||
|
||||
ste.on_cancel()
|
||||
|
||||
ste.doc.cancel_reason = "testing"
|
||||
ste.doc.docstatus = 2
|
||||
ste.doc.save()
|
||||
|
||||
print "Stock Entry Cancelled"
|
||||
return ste
|
||||
|
||||
#===========================================================================
|
||||
def tearDown(self):
|
||||
webnotes.conn.rollback()
|
||||
|
||||
|
||||
# Expected Result Set
|
||||
#===================================================================================================
|
||||
def get_expected_sle(self, action):
|
||||
expected_sle = {
|
||||
'mr_submit': [{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mr[0].name,
|
||||
'actual_qty': 10,
|
||||
'bin_aqat': 10,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'No'
|
||||
}],
|
||||
'mr_cancel': [{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mr[0].name,
|
||||
'actual_qty': 10,
|
||||
'bin_aqat': 10,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'Yes'
|
||||
},{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mr[0].name,
|
||||
'actual_qty': -10,
|
||||
'ifnull(bin_aqat, 0)': 0,
|
||||
'ifnull(valuation_rate, 0)': 0,
|
||||
"ifnull(is_cancelled, 'No')": 'Yes'
|
||||
}],
|
||||
'mtn_submit': [{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mtn[0].name,
|
||||
'actual_qty': -5,
|
||||
'bin_aqat': 5,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'No'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh2',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mtn[0].name,
|
||||
'actual_qty': 5,
|
||||
'bin_aqat': 5,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'No'
|
||||
}],
|
||||
'mtn_cancel': [{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mtn[0].name,
|
||||
'actual_qty': -5,
|
||||
'bin_aqat': 5,
|
||||
'is_cancelled': 'Yes'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh2',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mtn[0].name,
|
||||
'actual_qty': 5,
|
||||
'bin_aqat': 5,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'Yes'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mtn[0].name,
|
||||
'actual_qty': 5,
|
||||
'is_cancelled': 'Yes'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh2',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mtn[0].name,
|
||||
'actual_qty': -5,
|
||||
'is_cancelled': 'Yes'
|
||||
}],
|
||||
'mi_submit': [{'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mi[0].name,
|
||||
'actual_qty': -4,
|
||||
'bin_aqat': 6,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'No'
|
||||
}],
|
||||
'mi_cancel': [{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mi[0].name,
|
||||
'actual_qty': -4,
|
||||
'bin_aqat': 6,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'Yes'
|
||||
},{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mi[0].name,
|
||||
'actual_qty': 4,
|
||||
'ifnull(bin_aqat, 0)': 0,
|
||||
'ifnull(valuation_rate, 0)': 0,
|
||||
"ifnull(is_cancelled, 'No')": 'Yes'
|
||||
}],
|
||||
'entries_on_same_datetime': [{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mr[0].name,
|
||||
'actual_qty': 10,
|
||||
'bin_aqat': 10,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'Yes'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mr[0].name,
|
||||
'actual_qty': -10,
|
||||
'ifnull(bin_aqat, 0)': 0,
|
||||
'ifnull(valuation_rate, 0)': 0,
|
||||
"ifnull(is_cancelled, 'No')": 'Yes'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mr1[0].name,
|
||||
'actual_qty': 5,
|
||||
'bin_aqat': 5,
|
||||
'valuation_rate': 400,
|
||||
'is_cancelled': 'No'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mtn[0].name,
|
||||
'actual_qty': -5,
|
||||
'bin_aqat': 0,
|
||||
'valuation_rate': 400,
|
||||
'is_cancelled': 'No'
|
||||
}, {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh2',
|
||||
'voucher_type': 'Stock Entry',
|
||||
'voucher_no': stock_entry.mtn[0].name,
|
||||
'actual_qty': 5,
|
||||
'bin_aqat': 5,
|
||||
'valuation_rate': 100,
|
||||
'is_cancelled': 'No'
|
||||
}]
|
||||
}
|
||||
|
||||
return expected_sle[action]
|
@ -1,108 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
|
||||
import webnotes
|
||||
import webnotes.profile
|
||||
webnotes.user = webnotes.profile.Profile()
|
||||
|
||||
|
||||
from webnotes.model.code import get_obj
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
from sandbox.testdata.masters import *
|
||||
from sandbox.testdata.sle_data import sle, bin
|
||||
from sandbox.testdata.stock_reco import *
|
||||
#----------------------------------------------------------
|
||||
|
||||
|
||||
class TestStockEntry(unittest.TestCase):
|
||||
def assertDoc(self, lst):
|
||||
"""assert all values"""
|
||||
for d in lst:
|
||||
cl, vl = [], []
|
||||
for k in d.keys():
|
||||
if k!='doctype':
|
||||
cl.append('%s=%s' % (k, '%s'))
|
||||
vl.append(d[k])
|
||||
|
||||
self.assertTrue(sql("select name from `tab%s` where %s limit 1" % (d['doctype'], ' and '.join(cl)), vl))
|
||||
|
||||
#===========================================================================
|
||||
def setUp(self):
|
||||
print "====================================="
|
||||
webnotes.conn.begin()
|
||||
create_master_records()
|
||||
print 'Master Data Created'
|
||||
|
||||
for d in sle:
|
||||
d.save(1)
|
||||
print "Existing SLE created"
|
||||
|
||||
bin.save(1)
|
||||
|
||||
sreco.save(1)
|
||||
print "Stock Reco saved"
|
||||
|
||||
#===========================================================================
|
||||
def test_diff_in_both(self):
|
||||
reco = get_obj('Stock Reconciliation', sreco.name)
|
||||
reco.doc.docstatus = 1
|
||||
reco.doc.save()
|
||||
reco.validate()
|
||||
reco.on_submit()
|
||||
print "Stock Reco submitted"
|
||||
|
||||
print "Checking stock ledger entry........."
|
||||
self.assertDoc(self.get_expected_sle('diff_in_both'))
|
||||
|
||||
#===========================================================================
|
||||
def tearDown(self):
|
||||
webnotes.conn.rollback()
|
||||
|
||||
# Expected Result Set
|
||||
#===================================================================================================
|
||||
def get_expected_sle(self, action):
|
||||
expected_sle = {
|
||||
'diff_in_both': [{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'item_code':'it',
|
||||
'warehouse':'wh1',
|
||||
'voucher_type': 'Stock Reconciliation',
|
||||
'voucher_no': sreco.name,
|
||||
'actual_qty': 15,
|
||||
'bin_aqat': 20,
|
||||
'valuation_rate': 150,
|
||||
#'stock_value': 3000,
|
||||
'is_cancelled': 'No'
|
||||
},{
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'posting_date': '2011-09-10',
|
||||
'posting_time': '15:00',
|
||||
'item_code': 'it',
|
||||
'warehouse': 'wh1',
|
||||
'actual_qty': 20,
|
||||
'incoming_rate': 200,
|
||||
'bin_aqat': 40,
|
||||
'valuation_rate': 175,
|
||||
#'stock_value': 4500,
|
||||
'is_cancelled': 'No'
|
||||
}
|
||||
]
|
||||
}
|
||||
return expected_sle[action]
|
1
sandbox/testdata/__init__.py
vendored
1
sandbox/testdata/__init__.py
vendored
@ -1 +0,0 @@
|
||||
from __future__ import unicode_literals
|
71
sandbox/testdata/leaves.py
vendored
71
sandbox/testdata/leaves.py
vendored
@ -1,71 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
emp = Document(
|
||||
fielddata = {
|
||||
'doctype': 'Employee',
|
||||
'name': 'emp1',
|
||||
'employee_name': 'Nijil',
|
||||
'status': 'Active',
|
||||
'date_of_joining': '2011-01-01'
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
l_all = Document(
|
||||
fielddata = {
|
||||
'doctype' : 'Leave Allocation',
|
||||
'name': 'l_all',
|
||||
'employee' : 'emp1',
|
||||
'leave_type' : 'Casual Leave',
|
||||
'posting_date': '2011-03-01',
|
||||
'fiscal_year': '2011-2012',
|
||||
'total_leaves_allocated': 20,
|
||||
'docstatus': 1
|
||||
}
|
||||
)
|
||||
|
||||
l_app1 = Document(
|
||||
fielddata = {
|
||||
'doctype' : 'Leave Application',
|
||||
'name': 'l_app1',
|
||||
'employee' : 'emp1',
|
||||
'leave_type' : 'Casual Leave',
|
||||
'posting_date': '2011-03-01',
|
||||
'fiscal_year': '2011-2012',
|
||||
'from_date': '2011-08-01',
|
||||
'to_date': '2011-08-02',
|
||||
'total_leave_days': 2
|
||||
}
|
||||
)
|
||||
|
||||
l_app2 = Document(
|
||||
fielddata = {
|
||||
'doctype' : 'Leave Application',
|
||||
'name': 'l_app2',
|
||||
'employee' : 'emp1',
|
||||
'leave_type' : 'Casual Leave',
|
||||
'posting_date': '2011-03-01',
|
||||
'fiscal_year': '2011-2012',
|
||||
'from_date': '2011-08-15',
|
||||
'to_date': '2011-08-17',
|
||||
'total_leave_days': 3
|
||||
}
|
||||
)
|
299
sandbox/testdata/masters.py
vendored
299
sandbox/testdata/masters.py
vendored
@ -1,299 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
All master data in one place, can be created by 1 function call
|
||||
|
||||
"""
|
||||
|
||||
import webnotes
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
|
||||
master_groups = {
|
||||
# Company
|
||||
#----------------------------------
|
||||
'company': Document(
|
||||
fielddata={
|
||||
'doctype':'Company',
|
||||
'abbr': 'co',
|
||||
'company_name' : 'comp',
|
||||
'name': 'comp'
|
||||
}
|
||||
),
|
||||
|
||||
# Customer Group
|
||||
#----------------------------------
|
||||
'customer_group': Document(
|
||||
fielddata={
|
||||
'doctype':'Customer Group',
|
||||
'customer_group_name' : 'cg',
|
||||
'name': 'cg',
|
||||
'is_group': 'No',
|
||||
'parent_customer_group':'',
|
||||
'lft' : 1,
|
||||
'rgt': 2
|
||||
}
|
||||
),
|
||||
|
||||
# Item Group
|
||||
#----------------------------------
|
||||
'item_group': Document(
|
||||
fielddata = {
|
||||
'doctype': 'Item Group',
|
||||
'item_group_name': 'ig',
|
||||
'lft': 1,
|
||||
'rgt': 2,
|
||||
'parent_item_group' : '',
|
||||
'is_group': 'No',
|
||||
'name': 'ig'
|
||||
}
|
||||
),
|
||||
|
||||
# Warehouse Type
|
||||
#-----------------------------
|
||||
'warehouse_type' : Document(
|
||||
fielddata = {
|
||||
'doctype' : 'Warehouse Type',
|
||||
'name': 'normal',
|
||||
'warehouse_type' : 'normal'
|
||||
}
|
||||
),
|
||||
|
||||
# Supplier Type
|
||||
#-----------------------------
|
||||
'supplier_type' : Document(
|
||||
fielddata = {
|
||||
'doctype': 'Supplier Type',
|
||||
'supplier_type': 'stype'
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
main_masters = {
|
||||
# Customer
|
||||
#----------------------------------
|
||||
'customer': Document(
|
||||
fielddata={
|
||||
'doctype':'Customer',
|
||||
'docstatus':0,
|
||||
'customer_name' : 'cust',
|
||||
'company' : 'comp',
|
||||
'customer_group' : '',
|
||||
'name': 'cust'
|
||||
}
|
||||
),
|
||||
|
||||
|
||||
# Supplier
|
||||
#----------------------------------
|
||||
'supplier': Document(
|
||||
fielddata = {
|
||||
'doctype': 'Supplier',
|
||||
'supplier_name': 'supp',
|
||||
'name': 'supp',
|
||||
'supplier_type' : 'stype'
|
||||
}
|
||||
),
|
||||
|
||||
# Customer Account
|
||||
#----------------------------------
|
||||
'customer_acc': Document(
|
||||
fielddata={
|
||||
'doctype':'Account',
|
||||
'docstatus':0,
|
||||
'account_name' : 'cust',
|
||||
'debit_or_credit': 'Debit',
|
||||
'company' : 'comp',
|
||||
'lft': 1,
|
||||
'rgt': 2,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'is_pl_account': 'No',
|
||||
'name' : 'cust - co'
|
||||
}
|
||||
),
|
||||
|
||||
# Customer Account
|
||||
#----------------------------------
|
||||
'supplier_acc': Document(
|
||||
fielddata={
|
||||
'doctype':'Account',
|
||||
'docstatus':0,
|
||||
'account_name' : 'supp',
|
||||
'debit_or_credit': 'Credit',
|
||||
'company' : 'comp',
|
||||
'lft': 5,
|
||||
'rgt': 6,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'is_pl_account': 'No',
|
||||
'name' : 'supp - co'
|
||||
}
|
||||
),
|
||||
|
||||
# Bank Account
|
||||
#----------------------------------
|
||||
'bank_acc': Document(
|
||||
fielddata={
|
||||
'doctype':'Account',
|
||||
'docstatus':0,
|
||||
'account_name' : 'icici',
|
||||
'parent_account': '',
|
||||
'debit_or_credit': 'Debit',
|
||||
'company' : 'comp',
|
||||
'lft': 3,
|
||||
'rgt': 4,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'is_pl_account': 'No',
|
||||
'name' : 'icici - co'
|
||||
}
|
||||
),
|
||||
|
||||
# Income Account
|
||||
#----------------------------------
|
||||
'income_acc': Document(
|
||||
fielddata={
|
||||
'doctype':'Account',
|
||||
'docstatus':0,
|
||||
'account_name' : 'income',
|
||||
'debit_or_credit': 'Credit',
|
||||
'company' : 'comp',
|
||||
'lft': 7,
|
||||
'rgt': 8,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'is_pl_account': 'Yes',
|
||||
'name' : 'income - co'
|
||||
}
|
||||
),
|
||||
|
||||
# Expense Account
|
||||
#----------------------------------
|
||||
'expense_acc': Document(
|
||||
fielddata={
|
||||
'doctype':'Account',
|
||||
'docstatus':0,
|
||||
'account_name' : 'expense',
|
||||
'debit_or_credit': 'Debit',
|
||||
'company' : 'comp',
|
||||
'lft': 9,
|
||||
'rgt': 10,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'is_pl_account': 'Yes',
|
||||
'name' : 'expense - co'
|
||||
}
|
||||
),
|
||||
|
||||
# Cost Center
|
||||
#----------------------------------
|
||||
'cost_center': Document(
|
||||
fielddata={
|
||||
'doctype':'Cost Center',
|
||||
'docstatus':0,
|
||||
'cost_center_name' : 'cc',
|
||||
'lft': 1,
|
||||
'rgt': 2,
|
||||
'group_or_ledger' : 'Ledger',
|
||||
'name' : 'cc'
|
||||
}
|
||||
),
|
||||
|
||||
# Item
|
||||
#----------------------------------
|
||||
# Stock item / non-serialized
|
||||
|
||||
'item': [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Item',
|
||||
'docstatus': 0,
|
||||
'name': 'it',
|
||||
'item_name': 'it',
|
||||
'item_code': 'it',
|
||||
'item_group': 'ig',
|
||||
'is_stock_item': 'Yes',
|
||||
'has_serial_no': 'Yes',
|
||||
'stock_uom': 'Nos',
|
||||
'is_sales_item': 'Yes',
|
||||
'is_purchase_item': 'Yes',
|
||||
'is_service_item': 'No',
|
||||
'is_sub_contracted_item': 'No',
|
||||
'is_pro_applicable': 'Yes',
|
||||
'is_manufactured_item': 'Yes'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Item Price',
|
||||
'parentfield': 'ref_rate_details',
|
||||
'parenttype': 'Item',
|
||||
'parent' : 'it',
|
||||
'price_list_name': 'pl',
|
||||
'ref_currency': 'INR',
|
||||
'ref_rate': 100
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Item Tax',
|
||||
'parentfield': 'item_tax',
|
||||
'parenttype': 'Item',
|
||||
'parent' : 'it',
|
||||
'tax_type' : 'Tax1',
|
||||
'tax_rate': 10
|
||||
}
|
||||
)
|
||||
],
|
||||
|
||||
# Warehouse
|
||||
#-----------------------------
|
||||
'warehouse': [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Warehouse',
|
||||
'name' : 'wh1',
|
||||
'warehouse_name' : 'wh1',
|
||||
'warehouse_type': 'normal',
|
||||
'company': 'comp'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Warehouse',
|
||||
'name' : 'wh2',
|
||||
'warehouse_name' : 'wh2',
|
||||
'warehouse_type': 'normal',
|
||||
'company': 'comp'
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Save all master records
|
||||
#----------------------------------
|
||||
def create_master_records():
|
||||
for m in master_groups.keys():
|
||||
master_groups[m].save(1)
|
||||
|
||||
for m in main_masters.keys():
|
||||
if type(main_masters[m]) == list:
|
||||
for each in main_masters[m]:
|
||||
each.save(1)
|
||||
else:
|
||||
main_masters[m].save(1)
|
102
sandbox/testdata/sle_data.py
vendored
102
sandbox/testdata/sle_data.py
vendored
@ -1,102 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
# Existing SLE data
|
||||
#---------------------------
|
||||
|
||||
sle = [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'name': 'sle1',
|
||||
'posting_date': '2011-09-01',
|
||||
'posting_time': '12:00',
|
||||
'item_code': 'it',
|
||||
'warehouse': 'wh1',
|
||||
'actual_qty': 10,
|
||||
'incoming_rate': 100,
|
||||
'bin_aqat': 10,
|
||||
'valuation_rate': 100,
|
||||
'fcfs_stack': '',
|
||||
'stock_value': 1000,
|
||||
'is_cancelled': 'No'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'name': 'sle2',
|
||||
'posting_date': '2011-09-01',
|
||||
'posting_time': '12:00',
|
||||
'item_code': 'it',
|
||||
'warehouse': 'wh1',
|
||||
'actual_qty': -5,
|
||||
'incoming_rate': 100,
|
||||
'bin_aqat': 5,
|
||||
'valuation_rate': 100,
|
||||
'fcfs_stack': '',
|
||||
'stock_value': 500,
|
||||
'is_cancelled': 'No'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'name': 'sle3',
|
||||
'posting_date': '2011-09-10',
|
||||
'posting_time': '15:00',
|
||||
'item_code': 'it',
|
||||
'warehouse': 'wh1',
|
||||
'actual_qty': 20,
|
||||
'incoming_rate': 200,
|
||||
'bin_aqat': 25,
|
||||
'valuation_rate': 180,
|
||||
'fcfs_stack': '',
|
||||
'stock_value': 4500,
|
||||
'is_cancelled': 'No'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Ledger Entry',
|
||||
'name': 'sle4',
|
||||
'posting_date': '2011-09-15',
|
||||
'posting_time': '09:30',
|
||||
'item_code': 'it',
|
||||
'warehouse': 'wh1',
|
||||
'actual_qty': -5,
|
||||
'incoming_rate': 180,
|
||||
'bin_aqat': 20,
|
||||
'valuation_rate': 180,
|
||||
'fcfs_stack': '',
|
||||
'stock_value': 3600,
|
||||
'is_cancelled': 'No'
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
bin = Document(
|
||||
fielddata = {
|
||||
'doctype': 'Bin',
|
||||
'name': 'bin01',
|
||||
'item_code': 'it',
|
||||
'warehouse': 'wh1',
|
||||
'actual_qty': 20,
|
||||
}
|
||||
)
|
153
sandbox/testdata/stock_entry.py
vendored
153
sandbox/testdata/stock_entry.py
vendored
@ -1,153 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
# Material Receipt
|
||||
#-----------------------
|
||||
|
||||
mr = [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Entry',
|
||||
'posting_date': '2011-09-01',
|
||||
'transfer_date': '2011-09-01',
|
||||
'posting_time': '12:00',
|
||||
'company': 'comp',
|
||||
'fiscal_year' : '2011-2012',
|
||||
'purpose': 'Material Receipt',
|
||||
'name': 'mr'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata ={
|
||||
'doctype': 'Stock Entry Detail',
|
||||
'parenttype': 'Stock Entry',
|
||||
'parentfield' : 'mtn_details',
|
||||
'parent' : 'mr',
|
||||
'item_code' : 'it',
|
||||
't_warehouse' : 'wh1',
|
||||
'qty' : 10,
|
||||
'transfer_qty' : 10,
|
||||
'incoming_rate': 100,
|
||||
'stock_uom': 'Nos',
|
||||
'conversion_factor': 1,
|
||||
'serial_no': 'srno1, srno2, srno3, srno4, srno5, srno6, srno7, srno8, srno9, srno10'
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
mr1 = [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Entry',
|
||||
'posting_date': '2011-09-01',
|
||||
'transfer_date': '2011-09-01',
|
||||
'posting_time': '12:00',
|
||||
'company': 'comp',
|
||||
'fiscal_year' : '2011-2012',
|
||||
'purpose': 'Material Receipt',
|
||||
'name': 'mr1'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata ={
|
||||
'doctype': 'Stock Entry Detail',
|
||||
'parenttype': 'Stock Entry',
|
||||
'parentfield' : 'mtn_details',
|
||||
'parent' : 'mr1',
|
||||
'item_code' : 'it',
|
||||
't_warehouse' : 'wh1',
|
||||
'qty' : 5,
|
||||
'transfer_qty' : 5,
|
||||
'incoming_rate': 400,
|
||||
'stock_uom': 'Nos',
|
||||
'conversion_factor': 1,
|
||||
'serial_no': 'srno11, srno12, srno13, srno14, srno15'
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
# Material Transfer
|
||||
#--------------------
|
||||
|
||||
mtn = [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Entry',
|
||||
'posting_date': '2011-09-01',
|
||||
'transfer_date': '2011-09-01',
|
||||
'posting_time': '12:00',
|
||||
'company': 'comp',
|
||||
'fiscal_year' : '2011-2012',
|
||||
'purpose': 'Material Transfer',
|
||||
'name': 'mtn'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata ={
|
||||
'doctype': 'Stock Entry Detail',
|
||||
'parenttype': 'Stock Entry',
|
||||
'parentfield' : 'mtn_details',
|
||||
'parent' : 'mtn',
|
||||
'item_code' : 'it',
|
||||
's_warehouse' : 'wh1',
|
||||
't_warehouse' : 'wh2',
|
||||
'qty' : 5,
|
||||
'transfer_qty' : 5,
|
||||
'incoming_rate': 100,
|
||||
'stock_uom': 'Nos',
|
||||
'conversion_factor': 1,
|
||||
'serial_no': 'srno1, srno2, srno3, srno4, srno5'
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
# Material Issue
|
||||
#--------------------
|
||||
|
||||
mi = [
|
||||
Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Entry',
|
||||
'posting_date': '2011-09-01',
|
||||
'transfer_date': '2011-09-01',
|
||||
'posting_time': '14:00',
|
||||
'company': 'comp',
|
||||
'fiscal_year' : '2011-2012',
|
||||
'purpose': 'Material Issue',
|
||||
'name': 'mi'
|
||||
}
|
||||
),
|
||||
Document(
|
||||
fielddata ={
|
||||
'doctype': 'Stock Entry Detail',
|
||||
'parenttype': 'Stock Entry',
|
||||
'parentfield' : 'mtn_details',
|
||||
'parent' : 'mi',
|
||||
'item_code' : 'it',
|
||||
's_warehouse' : 'wh1',
|
||||
'qty' : 4,
|
||||
'transfer_qty' : 4,
|
||||
'incoming_rate': 100,
|
||||
'stock_uom': 'Nos',
|
||||
'conversion_factor': 1,
|
||||
'serial_no': 'srno1, srno2, srno3, srno4'
|
||||
}
|
||||
)
|
||||
]
|
60
sandbox/testdata/stock_reco.py
vendored
60
sandbox/testdata/stock_reco.py
vendored
@ -1,60 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from webnotes.model.doc import Document
|
||||
|
||||
# Stock Reconciliation
|
||||
#---------------------------
|
||||
|
||||
sreco = Document(
|
||||
fielddata = {
|
||||
'doctype': 'Stock Reconciliation',
|
||||
'name': 'sreco',
|
||||
'reconciliation_date': '2011-09-08',
|
||||
'reconciliation_time': '20:00',
|
||||
}
|
||||
)
|
||||
|
||||
# diff in both
|
||||
csv_data1 = [
|
||||
['Item', 'Warehouse', 'Quantity', 'Rate'],
|
||||
['it', 'wh1', 20, 150]
|
||||
]
|
||||
|
||||
# diff in qty, no rate
|
||||
csv_data2 = [
|
||||
['Item', 'Warehouse', 'Quantity'],
|
||||
['it', 'wh1', 20]
|
||||
]
|
||||
|
||||
# diff in rate, no qty
|
||||
csv_data3 = [
|
||||
['Item', 'Warehouse', 'Rate'],
|
||||
['it', 'wh1', 200]
|
||||
]
|
||||
|
||||
# diff in rate, same qty
|
||||
csv_data4 = [
|
||||
['Item', 'Warehouse', 'Quantity', 'Rate'],
|
||||
['it', 'wh1', 5, 200]
|
||||
]
|
||||
|
||||
# no diff
|
||||
csv_data1 = [
|
||||
['Item', 'Warehouse', 'Quantity', 'Rate'],
|
||||
['it', 'wh1', 5, 100]
|
||||
]
|
@ -2,9 +2,9 @@
|
||||
{
|
||||
"owner": "Administrator",
|
||||
"docstatus": 0,
|
||||
"creation": "2012-07-03 13:30:00",
|
||||
"creation": "2012-12-14 14:27:06",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2012-12-12 10:42:42"
|
||||
"modified": "2012-12-17 17:59:54"
|
||||
},
|
||||
{
|
||||
"autoname": "AR.####",
|
||||
@ -58,7 +58,7 @@
|
||||
"fieldname": "transaction",
|
||||
"fieldtype": "Select",
|
||||
"reqd": 1,
|
||||
"options": "\nDelivery Note\nPurchase Invoice\nPurchase Order\nPurchase Receipt\nQuotation\nSales Invoice\nSales Order\nStock Entry\nAppraisal"
|
||||
"options": "\nDelivery Note\nPurchase Invoice\nPurchase Order\nPurchase Receipt\nQuotation\nSales Invoice\nSales Order\nAppraisal"
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Select",
|
||||
|
@ -14,28 +14,33 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
if (!doc.posting_date) doc.posting_date = dateutil.obj_to_str(new Date());
|
||||
if (!doc.transfer_date) doc.transfer_date = dateutil.obj_to_str(new Date());
|
||||
if(!doc.purpose) set_multiple(cdt, cdn, {purpose:'Material Issue'});
|
||||
cfn_set_fields(doc, cdt, cdn);
|
||||
cur_frm.cscript.refresh = function(doc) {
|
||||
erpnext.hide_naming_series();
|
||||
cur_frm.cscript.toggle_related_fields(doc);
|
||||
}
|
||||
|
||||
|
||||
var cfn_set_fields = function(doc, cdt, cdn) {
|
||||
lst = ['supplier', 'supplier_name', 'supplier_address',
|
||||
'customer', 'customer_name', 'customer_address'];
|
||||
if (in_list(['Material Issue', 'Material Transfer', 'Material Receipt', 'Sales Return',
|
||||
'Purchase Return', 'Production Order', 'Subcontracting', 'Other'], doc.purpose)) {
|
||||
hide_field(lst);
|
||||
$(cur_frm.fields_dict.contact_section.row.wrapper).toggle(false);
|
||||
} else unhide_field(lst);
|
||||
|
||||
cur_frm.cscript.toggle_related_fields = function(doc) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(doc.purpose.startswith("Production Order") || doc.purpose == "Other") {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (doc.purpose == 'Production Order' || doc.purpose == 'Other') {
|
||||
unhide_field('get_items');
|
||||
hide_field(['from_warehouse', 'to_warehouse','purchase_receipt_no',
|
||||
'delivery_note_no', 'sales_invoice_no','warehouse_html',
|
||||
'transporter', 'is_excisable_goods', 'excisable_goods']);
|
||||
'delivery_note_no', 'sales_invoice_no','warehouse_html']);
|
||||
if (doc.purpose=='Production Order') unhide_field(['production_order', 'process']);
|
||||
else {
|
||||
doc.production_order = doc.process = '';
|
||||
@ -81,16 +86,6 @@ var cfn_set_fields = function(doc, cdt, cdn) {
|
||||
refresh_many(lst);
|
||||
}
|
||||
|
||||
//Refresh
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
//India related
|
||||
excise_flds = ['is_excisable_goods', 'excisable_goods', 'under_rule'];
|
||||
if(wn.control_panel.country == 'India') unhide_field(excise_flds);
|
||||
else hide_field(excise_flds);
|
||||
}
|
||||
|
||||
cur_frm.cscript.delivery_note_no = function(doc,cdt,cdn){
|
||||
if(doc.delivery_note_no) get_server_fields('get_cust_values','','',doc,cdt,cdn,1);
|
||||
}
|
||||
@ -117,11 +112,11 @@ cur_frm.fields_dict['production_order'].get_query = function(doc) {
|
||||
}
|
||||
|
||||
cur_frm.cscript.purpose = function(doc, cdt, cdn) {
|
||||
cfn_set_fields(doc, cdt, cdn);
|
||||
cur_frm.cscript.toggle_related_fields(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.process = function(doc, cdt, cdn) {
|
||||
cfn_set_fields(doc, cdt, cdn);
|
||||
cur_frm.cscript.toggle_related_fields(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
// item code - only if quantity present in source warehosue
|
||||
|
@ -22,7 +22,7 @@ from webnotes.model import db_exists, delete_doc
|
||||
from webnotes.model.doc import Document, addchild
|
||||
from webnotes.model.wrapper import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj
|
||||
from webnotes import msgprint
|
||||
from webnotes import msgprint, _
|
||||
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
@ -35,6 +35,160 @@ class DocType(TransactionBase):
|
||||
self.item_dict = {}
|
||||
self.fname = 'mtn_details'
|
||||
|
||||
def validate(self):
|
||||
self.validate_serial_nos()
|
||||
|
||||
pro_obj = self.doc.production_order and \
|
||||
get_obj('Production Order', self.doc.production_order) or None
|
||||
|
||||
self.validate_warehouse(pro_obj)
|
||||
self.validate_production_order(pro_obj)
|
||||
self.get_stock_and_rate()
|
||||
self.validate_incoming_rate()
|
||||
self.validate_bom()
|
||||
self.validate_finished_goods()
|
||||
|
||||
def validate_serial_nos(self):
|
||||
sl_obj = get_obj("Stock Ledger")
|
||||
sl_obj.scrub_serial_nos(self)
|
||||
sl_obj.validate_serial_no(self, 'mtn_details')
|
||||
|
||||
def validate_warehouse(self, pro_obj):
|
||||
"""perform various (sometimes conditional) validations on warehouse"""
|
||||
|
||||
source_mandatory = ["Material Issue", "Material Transfer",
|
||||
"Production Order - Material Transfer", "Purchase Return"]
|
||||
target_mandatory = ["Material Receipt", "Material Transfer",
|
||||
"Production Order - Material Transfer", "Sales Return"]
|
||||
|
||||
fg_qty = 0
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if not d.s_warehouse and not d.t_warehouse:
|
||||
d.s_warehouse = self.doc.from_warehouse
|
||||
d.t_warehouse = self.doc.to_warehouse
|
||||
|
||||
if not (d.s_warehouse or d.t_warehouse):
|
||||
msgprint(_("Atleast one warehouse is mandatory"), raise_exception=1)
|
||||
|
||||
if d.s_warehouse == d.t_warehouse:
|
||||
msgprint(_("Source and Target Warehouse cannot be same"), raise_exception=1)
|
||||
|
||||
if self.doc.purpose in source_mandatory:
|
||||
if not d.s_warehouse:
|
||||
msgprint(_("Row # ") + "%s: " % cint(d.idx)
|
||||
+ _("Source Warehouse") + _(" is mandatory"), raise_exception=1)
|
||||
|
||||
if self.doc.purpose not in target_mandatory:
|
||||
d.t_warehouse = None
|
||||
|
||||
if self.doc.purpose in target_mandatory:
|
||||
if not d.t_warehouse:
|
||||
msgprint(_("Row # ") + "%s: " % cint(d.idx)
|
||||
+ _("Target Warehouse") + _(" is mandatory"), raise_exception=1)
|
||||
|
||||
if self.doc.purpose not in source_mandatory:
|
||||
d.s_warehouse = None
|
||||
|
||||
if self.doc.purpose == "Production Order - Update Finished Goods":
|
||||
if d.item_code == pro_obj.doc.item:
|
||||
d.s_warehouse = None
|
||||
|
||||
if cstr(d.t_warehouse) != pro_obj.doc.fg_warehouse:
|
||||
msgprint(_("Row # ") + "%s: " % cint(d.idx)
|
||||
+ _("Target Warehouse") + _(" should be same as that in ")
|
||||
+ _("Production Order"), raise_exception=1)
|
||||
|
||||
else:
|
||||
d.t_warehouse = None
|
||||
if not d.s_warehouse:
|
||||
msgprint(_("Row # ") + "%s: " % cint(d.idx)
|
||||
+ _("Source Warehouse") + _(" is mandatory"), raise_exception=1)
|
||||
|
||||
# if self.doc.fg_completed_qty and flt(self.doc.fg_completed_qty) != flt(fg_qty):
|
||||
# msgprint("The Total of FG Qty %s in Stock Entry Detail do not match with FG Completed Qty %s" % (flt(fg_qty), flt(self.doc.fg_completed_qty)))
|
||||
# raise Exception
|
||||
|
||||
def validate_production_order(self, pro_obj=None):
|
||||
if not pro_obj:
|
||||
pro_obj = get_obj('Production Order', self.doc.production_order)
|
||||
|
||||
if self.doc.purpose == "Production Order - Material Transfer":
|
||||
self.doc.fg_completed_qty = 0
|
||||
|
||||
elif self.doc.purpose == "Production Order - Update Finished Goods":
|
||||
if not flt(self.doc.fg_completed_qty):
|
||||
msgprint(_("Manufacturing Quantity") + _(" is mandatory"), raise_exception=1)
|
||||
|
||||
if flt(pro_obj.doc.qty) < (flt(pro_obj.doc.produced_qty)
|
||||
+ flt(self.doc.fg_completed_qty)):
|
||||
# do not allow manufacture of qty > production order qty
|
||||
msgprint(_("For Item ") + pro_obj.doc.production_item
|
||||
+ _("Quantity already manufactured")
|
||||
+ " = %s." % flt(pro_obj.doc.produced_qty)
|
||||
+ _("Hence, maximum allowed Manufacturing Quantity")
|
||||
+ " = %s." % flt(pro_obj.doc.qty) - flt(pro_obj.doc.produced_qty),
|
||||
raise_exception=1)
|
||||
else:
|
||||
self.doc.production_order = None
|
||||
|
||||
def get_stock_and_rate(self):
|
||||
"""get stock and incoming rate on posting date"""
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
# get actual stock at source warehouse
|
||||
d.actual_qty = self.get_as_on_stock(d.item_code, d.s_warehouse or d.t_warehouse,
|
||||
self.doc.posting_date, self.doc.posting_time)
|
||||
|
||||
# get incoming rate
|
||||
if not flt(d.incoming_rate):
|
||||
d.incoming_rate = self.get_incoming_rate(d.item_code,
|
||||
d.s_warehouse or d.t_warehouse, self.doc.posting_date,
|
||||
self.doc.posting_time, d.transfer_qty, d.serial_no, d.bom_no)
|
||||
|
||||
def get_as_on_stock(self, item_code, warehouse, posting_date, posting_time):
|
||||
"""Get stock qty on any date"""
|
||||
bin = sql("select name from tabBin where item_code = %s and warehouse = %s",
|
||||
(item_code, warehouse))
|
||||
if bin:
|
||||
prev_sle = get_obj('Bin', bin[0][0]).get_prev_sle(posting_date, posting_time)
|
||||
return flt(prev_sle["bin_aqat"])
|
||||
else:
|
||||
return 0
|
||||
|
||||
def get_incoming_rate(self, item_code=None, warehouse=None,
|
||||
posting_date=None, posting_time=None, qty=0, serial_no=None, bom_no=None):
|
||||
in_rate = 0
|
||||
|
||||
if bom_no:
|
||||
result = flt(webnotes.conn.sql("""select ifnull(total_cost, 0) / ifnull(quantity, 1)
|
||||
from `tabBOM` where name = %s and docstatus=1""", bom_no))
|
||||
in_rate = result and result[0][0] or 0
|
||||
elif warehouse:
|
||||
in_rate = get_obj("Valuation Control").get_incoming_rate(posting_date, posting_time,
|
||||
item_code, warehouse, qty, serial_no)
|
||||
|
||||
return in_rate
|
||||
|
||||
def validate_incoming_rate(self):
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if not flt(d.incoming_rate) and d.t_warehouse:
|
||||
msgprint("Rate is mandatory for Item: %s at row %s" % (d.item_code, d.idx),
|
||||
raise_exception=1)
|
||||
|
||||
def validate_bom(self):
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if d.bom_no and not webnotes.conn.sql("""select name from `tabBOM`
|
||||
where item = %s and name = %s and docstatus = 1 and is_active = 1""",
|
||||
(d.item_code, d.bom_no)):
|
||||
msgprint(_("Item") + " %s: " % cstr(d.item_code)
|
||||
+ _("does not belong to BOM: ") + cstr(d.bom_no)
|
||||
+ _(" or the BOM is cancelled or inactive"), raise_exception=1)
|
||||
|
||||
def validate_finished_goods(self):
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if d.bom_no and flt(d.transfer_qty) != flt(self.doc.fg_completed_qty):
|
||||
|
||||
|
||||
|
||||
def get_item_details(self, arg):
|
||||
import json
|
||||
arg, actual_qty, in_rate = json.loads(arg), 0, 0
|
||||
@ -87,50 +241,6 @@ class DocType(TransactionBase):
|
||||
return ret
|
||||
|
||||
|
||||
def get_stock_and_rate(self, bom_no = ''):
|
||||
""" get stock and incoming rate on posting date"""
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
# assign parent warehouse
|
||||
d.s_warehouse = cstr(d.s_warehouse) or self.doc.purpose != 'Production Order' \
|
||||
and self.doc.from_warehouse or ''
|
||||
d.t_warehouse = cstr(d.t_warehouse) or self.doc.purpose != 'Production Order' \
|
||||
and self.doc.to_warehouse or ''
|
||||
|
||||
# get current stock at source warehouse
|
||||
d.actual_qty = self.get_as_on_stock(d.item_code, d.s_warehouse or d.t_warehouse,
|
||||
self.doc.posting_date, self.doc.posting_time) or 0
|
||||
|
||||
# get incoming rate
|
||||
if not flt(d.incoming_rate):
|
||||
d.incoming_rate = self.get_incoming_rate(d.item_code,
|
||||
d.s_warehouse or d.t_warehouse, self.doc.posting_date,
|
||||
self.doc.posting_time, d.transfer_qty, d.serial_no,
|
||||
d.fg_item, d.bom_no or bom_no)
|
||||
|
||||
|
||||
def get_as_on_stock(self, item, wh, dt, tm):
|
||||
"""Get stock qty on any date"""
|
||||
bin = sql("select name from tabBin where item_code = %s and warehouse = %s", (item, wh))
|
||||
bin_id = bin and bin[0][0] or ''
|
||||
prev_sle = bin_id and get_obj('Bin', bin_id).get_prev_sle(dt, tm) or {}
|
||||
qty = flt(prev_sle.get('bin_aqat', 0))
|
||||
return qty
|
||||
|
||||
|
||||
def get_incoming_rate(self, item, wh, dt, tm, qty=0, serial_no='', fg_item=0, bom_no=''):
|
||||
in_rate = 0
|
||||
if fg_item and bom_no:
|
||||
in_rate = webnotes.conn.sql("""select ifnull(total_cost, 0) / ifnull(quantity, 1)
|
||||
from `tabBOM` where name = %s and docstatus=1""", bom_no, debug=1)
|
||||
in_rate = in_rate and in_rate[0][0] or 0
|
||||
elif wh:
|
||||
in_rate = get_obj('Valuation Control').get_incoming_rate(dt, tm,
|
||||
item, wh, qty, serial_no)
|
||||
|
||||
return in_rate
|
||||
|
||||
|
||||
|
||||
def make_items_dict(self, items_list):
|
||||
"""makes dict of unique items with it's qty"""
|
||||
for i in items_list:
|
||||
@ -144,9 +254,12 @@ class DocType(TransactionBase):
|
||||
def update_only_remaining_qty(self):
|
||||
""" Only pending raw material to be issued to shop floor """
|
||||
already_issued_item = {}
|
||||
for t in sql("""select t1.item_code, sum(t1.qty) from `tabStock Entry Detail` t1, `tabStock Entry` t2
|
||||
where t1.parent = t2.name and t2.production_order = %s and t2.process = 'Material Transfer'
|
||||
and t2.docstatus = 1 group by t1.item_code""", self.doc.production_order):
|
||||
result = sql("""select t1.item_code, sum(t1.qty)
|
||||
from `tabStock Entry Detail` t1, `tabStock Entry` t2
|
||||
where t1.parent = t2.name and t2.production_order = %s
|
||||
and t2.purpose = 'Production Order - Material Transfer'
|
||||
and t2.docstatus = 1 group by t1.item_code""", self.doc.production_order)
|
||||
for t in result:
|
||||
already_issued_item[t[0]] = flt(t[1])
|
||||
|
||||
for d in self.item_dict.keys():
|
||||
@ -190,7 +303,7 @@ class DocType(TransactionBase):
|
||||
self.make_items_dict(fl_bom_sa_items)
|
||||
|
||||
# Update only qty remaining to be issued for production
|
||||
if self.doc.process == 'Material Transfer':
|
||||
if self.doc.purpose == 'Production Order - Material Transfer':
|
||||
self.update_only_remaining_qty()
|
||||
|
||||
|
||||
@ -211,40 +324,49 @@ class DocType(TransactionBase):
|
||||
se_child.conversion_factor = 1.00
|
||||
if fg_item: se_child.bom_no = bom_no
|
||||
|
||||
def validate_bom_no(self):
|
||||
if self.doc.bom_no:
|
||||
if not webnotes.conn.sql("""select name from tabBOM where name = %s and docstatus = 1
|
||||
and is_active = 1""", self.doc.bom_no):
|
||||
msgprint("""BOM: %s not found, may be it has been cancelled or inactivated""" %
|
||||
self.doc.bom_no, raise_exception=1)
|
||||
if not self.doc.fg_completed_qty:
|
||||
msgprint("Please enter FG Completed Qty", raise_exception=1)
|
||||
|
||||
|
||||
def get_items(self):
|
||||
if self.doc.purpose == 'Production Order':
|
||||
pro_obj = self.doc.production_order and get_obj('Production Order', self.doc.production_order) or ''
|
||||
self.validate_for_production_order(pro_obj)
|
||||
|
||||
bom_no = pro_obj.doc.bom_no
|
||||
fg_qty = (self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) \
|
||||
or flt(pro_obj.doc.qty)
|
||||
use_multi_level_bom = pro_obj.doc.use_multi_level_bom
|
||||
elif self.doc.purpose == 'Other':
|
||||
self.validate_bom_no()
|
||||
bom_no = self.doc.bom_no
|
||||
fg_qty = self.doc.fg_completed_qty
|
||||
use_multi_level_bom = self.doc.use_multi_level_bom
|
||||
|
||||
self.get_raw_materials(bom_no, fg_qty, use_multi_level_bom)
|
||||
if self.doc.purpose.startswith('Production Order'):
|
||||
if not self.doc.production_order:
|
||||
webnotes.msgprint(_("Please specify Production Order"), raise_exception=1)
|
||||
|
||||
# common validations
|
||||
pro_obj = get_obj('Production Order', self.doc.production_order)
|
||||
if pro_obj:
|
||||
self.validate_production_order(pro_obj)
|
||||
|
||||
bom_no = pro_obj.doc.bom_no
|
||||
fg_qty = (self.doc.purpose == 'Production Order - Update Finished Goods') \
|
||||
and flt(self.doc.fg_completed_qty) or flt(pro_obj.doc.qty)
|
||||
|
||||
self.get_raw_materials(bom_no, fg_qty, self.doc.use_multi_level_bom)
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'mtn_details', 1)
|
||||
|
||||
sw = (self.doc.process == 'Backflush') and cstr(pro_obj.doc.wip_warehouse) or ''
|
||||
tw = (self.doc.process == 'Material Transfer') and cstr(pro_obj.doc.wip_warehouse) or ''
|
||||
self.add_to_stock_entry_detail(sw, tw, self.item_dict)
|
||||
# add raw materials to Stock Entry Detail table
|
||||
self.add_to_stock_entry_detail(self.doc.from_warehouse, self.doc.to_warehouse,
|
||||
self.item_dict)
|
||||
|
||||
# add finished good item to Stock Entry Detail table
|
||||
if self.doc.production_order:
|
||||
self.add_to_stock_entry_detail(None, pro_obj.doc.fg_warehouse, {
|
||||
cstr(pro_obj.doc.production_item):
|
||||
[self.doc.fg_completed_qty, pro_obj.doc.description, pro_obj.doc.stock_uom]
|
||||
})
|
||||
elif self.doc.bom_no:
|
||||
item = webnotes.conn.sql("""select item, description, uom from `tabBOM`
|
||||
where name=%s""", (self.doc.bom_no,), as_dict=1)
|
||||
self.add_to_stock_entry_detail(None, None, {
|
||||
item[0]["item"] :
|
||||
[self.doc.fg_completed_qty, item[0]["description"], item[0]["uom"]]
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
fg_item_dict = {}
|
||||
if self.doc.process == 'Backflush':
|
||||
if self.doc.purpose == 'Production Order - Update Finished Goods':
|
||||
sw = ''
|
||||
tw = cstr(pro_obj.doc.fg_warehouse)
|
||||
fg_item_dict = {
|
||||
@ -264,28 +386,17 @@ class DocType(TransactionBase):
|
||||
|
||||
self.get_stock_and_rate()
|
||||
|
||||
|
||||
|
||||
def validate_transfer_qty(self):
|
||||
def validate_qty_as_per_stock_uom(self):
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if flt(d.transfer_qty) <= 0:
|
||||
msgprint("Transfer Quantity can not be less than or equal to zero \
|
||||
at Row No " + cstr(d.idx), raise_exception=1)
|
||||
|
||||
|
||||
def calc_amount(self):
|
||||
total_amount = 0
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
d.amount = flt(d.transfer_qty) * flt(d.incoming_rate)
|
||||
total_amount += flt(d.amount)
|
||||
self.doc.total_amount = flt(total_amount)
|
||||
msgprint("Row No #%s: Qty as per Stock UOM can not be less than \
|
||||
or equal to zero" % cint(d.idx), raise_exception=1)
|
||||
|
||||
|
||||
def add_to_values(self, d, wh, qty, is_cancelled):
|
||||
self.values.append({
|
||||
'item_code' : d.item_code,
|
||||
'warehouse' : wh,
|
||||
'transaction_date' : self.doc.transfer_date,
|
||||
'posting_date' : self.doc.posting_date,
|
||||
'posting_time' : self.doc.posting_time,
|
||||
'voucher_type' : 'Stock Entry',
|
||||
@ -295,7 +406,6 @@ class DocType(TransactionBase):
|
||||
'incoming_rate' : flt(d.incoming_rate) or 0,
|
||||
'stock_uom' : d.stock_uom,
|
||||
'company' : self.doc.company,
|
||||
'fiscal_year' : self.doc.fiscal_year,
|
||||
'is_cancelled' : (is_cancelled ==1) and 'Yes' or 'No',
|
||||
'batch_no' : d.batch_no,
|
||||
'serial_no' : d.serial_no
|
||||
@ -311,139 +421,6 @@ class DocType(TransactionBase):
|
||||
self.add_to_values(d, cstr(d.t_warehouse), flt(d.transfer_qty), is_cancelled)
|
||||
get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values, self.doc.amended_from and 'Yes' or 'No')
|
||||
|
||||
|
||||
def validate_for_production_order(self, pro_obj):
|
||||
if self.doc.purpose == 'Production Order' or self.doc.process or self.doc.production_order:
|
||||
if self.doc.purpose != 'Production Order':
|
||||
msgprint("Purpose should be 'Production Order'.")
|
||||
raise Exception
|
||||
if not self.doc.process:
|
||||
msgprint("Process Field is mandatory.")
|
||||
raise Exception
|
||||
if self.doc.process == 'Backflush' and not flt(self.doc.fg_completed_qty):
|
||||
msgprint("FG Completed Qty is mandatory as the process selected is 'Backflush'")
|
||||
raise Exception
|
||||
if self.doc.process == 'Material Transfer' and flt(self.doc.fg_completed_qty):
|
||||
msgprint("FG Completed Qty should be zero. As the Process selected is 'Material Transfer'.")
|
||||
raise Exception
|
||||
if not self.doc.production_order:
|
||||
msgprint("Production Order field is mandatory")
|
||||
raise Exception
|
||||
if flt(pro_obj.doc.qty) < flt(pro_obj.doc.produced_qty) + flt(self.doc.fg_completed_qty) :
|
||||
msgprint("error:Already Produced Qty for %s is %s and maximum allowed Qty is %s" % (pro_obj.doc.production_item, cstr(pro_obj.doc.produced_qty) or 0.00 , cstr(pro_obj.doc.qty)))
|
||||
raise Exception
|
||||
|
||||
|
||||
def validate(self):
|
||||
sl_obj = get_obj("Stock Ledger", "Stock Ledger")
|
||||
sl_obj.scrub_serial_nos(self)
|
||||
sl_obj.validate_serial_no(self, 'mtn_details')
|
||||
pro_obj = ''
|
||||
if self.doc.production_order:
|
||||
pro_obj = get_obj('Production Order', self.doc.production_order)
|
||||
self.validate_for_production_order(pro_obj)
|
||||
self.get_stock_and_rate(pro_obj and pro_obj.doc.bom_no or '')
|
||||
self.validate_warehouse(pro_obj)
|
||||
self.validate_incoming_rate()
|
||||
self.validate_bom_belongs_to_item()
|
||||
self.calc_amount()
|
||||
get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,
|
||||
self.doc.posting_date, 'Posting Date')
|
||||
if self.doc.purpose == 'Other':
|
||||
self.validate_bom_no()
|
||||
|
||||
# If target warehouse exists, incoming rate is mandatory
|
||||
# --------------------------------------------------------
|
||||
def validate_incoming_rate(self):
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if not flt(d.incoming_rate) and d.t_warehouse:
|
||||
msgprint("Rate is mandatory for Item: %s at row %s" % (d.item_code, d.idx), raise_exception=1)
|
||||
|
||||
|
||||
def validate_bom_belongs_to_item(self):
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if d.bom_no and not webnotes.conn.sql("""\
|
||||
SELECT name FROM `tabBOM`
|
||||
WHERE item = %s and name = %s
|
||||
""", (d.item_code, d.bom_no)):
|
||||
msgprint("BOM %s does not belong to Item: %s at row %s" % (d.bom_no, d.item_code, d.idx), raise_exception=1)
|
||||
|
||||
|
||||
# Validate warehouse
|
||||
# -----------------------------------
|
||||
def validate_warehouse(self, pro_obj):
|
||||
fg_qty = 0
|
||||
for d in getlist(self.doclist, 'mtn_details'):
|
||||
if not d.s_warehouse and not d.t_warehouse:
|
||||
d.s_warehouse = self.doc.from_warehouse
|
||||
d.t_warehouse = self.doc.to_warehouse
|
||||
|
||||
if not (d.s_warehouse or d.t_warehouse):
|
||||
msgprint("Atleast one warehouse is mandatory for Stock Entry")
|
||||
raise Exception
|
||||
if d.s_warehouse and not sql("select name from tabWarehouse where name = '%s'" % d.s_warehouse):
|
||||
msgprint("Invalid Warehouse: %s" % self.doc.s_warehouse)
|
||||
raise Exception
|
||||
if d.t_warehouse and not sql("select name from tabWarehouse where name = '%s'" % d.t_warehouse):
|
||||
msgprint("Invalid Warehouse: %s" % self.doc.t_warehouse)
|
||||
raise Exception
|
||||
if d.s_warehouse == d.t_warehouse:
|
||||
msgprint("Source and Target Warehouse Cannot be Same.")
|
||||
raise Exception
|
||||
|
||||
if self.doc.purpose == 'Material Issue':
|
||||
if not cstr(d.s_warehouse):
|
||||
msgprint("Source Warehouse is Mandatory for Purpose => 'Material Issue'")
|
||||
raise Exception
|
||||
if cstr(d.t_warehouse):
|
||||
msgprint("Target Warehouse is not Required for Purpose => 'Material Issue'")
|
||||
raise Exception
|
||||
if self.doc.purpose == 'Material Transfer':
|
||||
if not cstr(d.s_warehouse) or not cstr(d.t_warehouse):
|
||||
msgprint("Source Warehouse and Target Warehouse both are Mandatory for Purpose => 'Material Transfer'")
|
||||
raise Exception
|
||||
if self.doc.purpose == 'Material Receipt':
|
||||
if not cstr(d.t_warehouse):
|
||||
msgprint("Target Warehouse is Mandatory for Purpose => 'Material Receipt'")
|
||||
raise Exception
|
||||
if cstr(d.s_warehouse):
|
||||
msgprint("Source Warehouse is not Required for Purpose => 'Material Receipt'")
|
||||
raise Exception
|
||||
if self.doc.process == 'Material Transfer':
|
||||
if cstr(d.t_warehouse) != (pro_obj.doc.wip_warehouse):
|
||||
msgprint(" Target Warehouse should be same as WIP Warehouse %s in Production Order %s at Row No %s" % (cstr(pro_obj.doc.wip_warehouse), cstr(pro_obj.doc.name), cstr(d.idx)) )
|
||||
raise Exception
|
||||
if not cstr(d.s_warehouse):
|
||||
msgprint("Please Enter Source Warehouse at Row No %s." % (cstr(d.idx)))
|
||||
raise Exception
|
||||
|
||||
if self.doc.process == 'Backflush':
|
||||
if flt(d.fg_item):
|
||||
if cstr(pro_obj.doc.production_item) != cstr(d.item_code):
|
||||
msgprint("Item %s in Stock Entry Detail as Row No %s do not match with Item %s in Production Order %s" % (cstr(d.item_code), cstr(d.idx), cstr(pro_obj.doc.production_item), cstr(pro_obj.doc.name)))
|
||||
raise Exception
|
||||
if cstr(d.t_warehouse) != cstr(pro_obj.doc.fg_warehouse):
|
||||
msgprint("As Item %s is FG Item. Target Warehouse should be same as FG Warehouse %s in Production Order %s, at Row No %s. " % ( cstr(d.item_code), cstr(pro_obj.doc.fg_warehouse), cstr(pro_obj.doc.name), cstr(d.idx)))
|
||||
raise Exception
|
||||
if cstr(d.s_warehouse):
|
||||
msgprint("As Item %s is a FG Item. There should be no Source Warehouse at Row No %s" % (cstr(d.item_code), cstr(d.idx)))
|
||||
raise Exception
|
||||
if not flt(d.fg_item):
|
||||
if cstr(d.t_warehouse):
|
||||
msgprint("As Item %s is not a FG Item. There should no Tareget Warehouse at Row No %s" % (cstr(d.item_code), cstr(d.idx)))
|
||||
raise Exception
|
||||
if cstr(d.s_warehouse) != cstr(pro_obj.doc.wip_warehouse):
|
||||
msgprint("As Item %s is Raw Material. Source Warehouse should be same as WIP Warehouse %s in Production Order %s, at Row No %s. " % ( cstr(d.item_code), cstr(pro_obj.doc.wip_warehouse), cstr(pro_obj.doc.name), cstr(d.idx)))
|
||||
raise Exception
|
||||
if d.fg_item and (self.doc.purpose == 'Other' or self.doc.process == 'Backflush'):
|
||||
fg_qty = flt(fg_qty) + flt(d.transfer_qty)
|
||||
|
||||
d.save()
|
||||
if self.doc.fg_completed_qty and flt(self.doc.fg_completed_qty) != flt(fg_qty):
|
||||
msgprint("The Total of FG Qty %s in Stock Entry Detail do not match with FG Completed Qty %s" % (flt(fg_qty), flt(self.doc.fg_completed_qty)))
|
||||
raise Exception
|
||||
|
||||
|
||||
def update_production_order(self, is_submit):
|
||||
if self.doc.production_order:
|
||||
pro_obj = get_obj("Production Order", self.doc.production_order)
|
||||
@ -460,7 +437,7 @@ class DocType(TransactionBase):
|
||||
msgprint("""Posting Date of Stock Entry cannot be before Posting Date of
|
||||
Production Order: %s"""% cstr(self.doc.production_order), raise_exception=1)
|
||||
|
||||
if self.doc.process == 'Backflush':
|
||||
if self.doc.purpose == "Production Order - Update Finished Goods":
|
||||
pro_obj.doc.produced_qty = flt(pro_obj.doc.produced_qty) + \
|
||||
(is_submit and 1 or -1 ) * flt(self.doc.fg_completed_qty)
|
||||
args = {
|
||||
@ -469,8 +446,6 @@ class DocType(TransactionBase):
|
||||
"planned_qty": (is_submit and -1 or 1 ) * flt(self.doc.fg_completed_qty)
|
||||
}
|
||||
get_obj('Warehouse', pro_obj.doc.fg_warehouse).update_bin(args)
|
||||
elif self.doc.process == 'Material Transfer':
|
||||
pass
|
||||
|
||||
pro_obj.doc.status = (flt(pro_obj.doc.qty)==flt(pro_obj.doc.produced_qty)) \
|
||||
and 'Completed' or 'In Process'
|
||||
@ -503,9 +478,7 @@ class DocType(TransactionBase):
|
||||
|
||||
|
||||
def on_submit(self):
|
||||
self.validate_transfer_qty()
|
||||
# Check for Approving Authority
|
||||
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.total_amount)
|
||||
self.validate_qty_as_per_stock_uom()
|
||||
self.update_serial_no(1)
|
||||
self.update_stock_ledger(0)
|
||||
# update Production Order
|
||||
|
@ -2,9 +2,9 @@
|
||||
{
|
||||
"owner": "Administrator",
|
||||
"docstatus": 0,
|
||||
"creation": "2012-11-28 11:26:22",
|
||||
"creation": "2012-12-17 11:42:09",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2012-12-10 18:30:00"
|
||||
"modified": "2012-12-17 18:19:44"
|
||||
},
|
||||
{
|
||||
"is_submittable": 1,
|
||||
@ -59,7 +59,6 @@
|
||||
"description": "To manage multiple series please go to Setup > Manage Series",
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "Select",
|
||||
"colour": "White:FFF",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Series",
|
||||
@ -75,223 +74,24 @@
|
||||
"report_hide": 0
|
||||
},
|
||||
{
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Select",
|
||||
"colour": "White:FFF",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Purpose",
|
||||
"oldfieldname": "purpose",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"default": "Material Issue",
|
||||
"fieldname": "purpose",
|
||||
"fieldtype": "Select",
|
||||
"search_index": 0,
|
||||
"reqd": 1,
|
||||
"hidden": 0,
|
||||
"options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nSales Return\nPurchase Return\nSubcontracting\nProduction Order\nOther",
|
||||
"options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nSales Return\nPurchase Return\nSubcontracting\nProduction Order - Material Transfer\nProduction Order - Update Finished Goods\nOther",
|
||||
"report_hide": 0,
|
||||
"in_filter": 1
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Delivery Note No",
|
||||
"oldfieldname": "delivery_note_no",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"fieldname": "delivery_note_no",
|
||||
"fieldtype": "Link",
|
||||
"search_index": 1,
|
||||
"reqd": 0,
|
||||
"hidden": 1,
|
||||
"options": "Delivery Note",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Purchase Receipt No",
|
||||
"oldfieldname": "purchase_receipt_no",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"fieldname": "purchase_receipt_no",
|
||||
"fieldtype": "Link",
|
||||
"search_index": 1,
|
||||
"reqd": 0,
|
||||
"hidden": 1,
|
||||
"options": "Purchase Receipt",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"doctype": "DocField",
|
||||
"label": "Sales Invoice No",
|
||||
"options": "Sales Invoice",
|
||||
"fieldname": "sales_invoice_no",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Select",
|
||||
"colour": "White:FFF",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Process",
|
||||
"oldfieldname": "process",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"fieldname": "process",
|
||||
"fieldtype": "Select",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 1,
|
||||
"options": "\nMaterial Transfer\nBackflush",
|
||||
"report_hide": 0,
|
||||
"in_filter": 1
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Production Order",
|
||||
"oldfieldname": "production_order",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"fieldname": "production_order",
|
||||
"fieldtype": "Link",
|
||||
"search_index": 1,
|
||||
"reqd": 0,
|
||||
"hidden": 1,
|
||||
"options": "Production Order",
|
||||
"report_hide": 0,
|
||||
"in_filter": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.purpose == 'Other'",
|
||||
"doctype": "DocField",
|
||||
"label": "BOM No",
|
||||
"options": "BOM",
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
|
||||
"depends_on": "eval:doc.purpose == 'Other'",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Currency",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "FG Completed Qty",
|
||||
"oldfieldname": "fg_completed_qty",
|
||||
"trigger": "Client",
|
||||
"fieldname": "fg_completed_qty",
|
||||
"fieldtype": "Currency",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"permlevel": 0,
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Button",
|
||||
"colour": "White:FFF",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Get Items",
|
||||
"permlevel": 0,
|
||||
"fieldname": "get_items",
|
||||
"fieldtype": "Button",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"options": "get_items",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "HTML",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "Warehouse HTML",
|
||||
"options": "<div class='columnHeading'>Warehouse</div>",
|
||||
"fieldname": "warehouse_html",
|
||||
"fieldtype": "HTML",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Source Warehouse",
|
||||
"oldfieldname": "from_warehouse",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"fieldname": "from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"options": "Warehouse",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"oldfieldname": "to_warehouse",
|
||||
"reqd": 0,
|
||||
"in_filter": 0,
|
||||
"print_hide": 1,
|
||||
"label": "Target Warehouse",
|
||||
"trigger": "Client",
|
||||
"hidden": 0,
|
||||
"permlevel": 0,
|
||||
"description": "<b>Notes:</b> Either Source or Target is Mandatory",
|
||||
"search_index": 0,
|
||||
"allow_on_submit": 0,
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "to_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"report_hide": 0
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Column Break",
|
||||
"doctype": "DocField",
|
||||
@ -303,12 +103,13 @@
|
||||
{
|
||||
"print_hide": 1,
|
||||
"description": "The date at which current entry will get or has actually executed.",
|
||||
"no_copy": 1,
|
||||
"default": "Today",
|
||||
"oldfieldtype": "Date",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Posting Date",
|
||||
"oldfieldname": "posting_date",
|
||||
"no_copy": 1,
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"search_index": 1,
|
||||
@ -335,23 +136,6 @@
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "Text",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Remarks",
|
||||
"oldfieldname": "remarks",
|
||||
"fieldname": "remarks",
|
||||
"fieldtype": "Text",
|
||||
"search_index": 0,
|
||||
"reqd": 1,
|
||||
"hidden": 0,
|
||||
"permlevel": 0,
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Section Break",
|
||||
"doctype": "DocField",
|
||||
@ -360,11 +144,59 @@
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Default Source Warehouse",
|
||||
"oldfieldname": "from_warehouse",
|
||||
"permlevel": 0,
|
||||
"fieldname": "from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"options": "Warehouse",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "cb0",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Default Target Warehouse",
|
||||
"oldfieldname": "to_warehouse",
|
||||
"permlevel": 0,
|
||||
"fieldname": "to_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"options": "Warehouse",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"options": "Simple",
|
||||
"fieldname": "sb0",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Table",
|
||||
"colour": "White:FFF",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "MTN Details",
|
||||
@ -379,43 +211,10 @@
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Section Break",
|
||||
"doctype": "DocField",
|
||||
"options": "Simple",
|
||||
"fieldname": "item_section",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Currency",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Total Amount",
|
||||
"oldfieldname": "total_amount",
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Currency",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"permlevel": 1,
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Column Break",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "col3",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"description": "Get valuation rate and available stock at source/target warehouse on mentioned posting date-time. If serialized item, please press this button after entering serial nos.",
|
||||
"oldfieldtype": "Button",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "Get Stock and Rate",
|
||||
"options": "get_stock_and_rate",
|
||||
@ -424,6 +223,139 @@
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"label": "Reference",
|
||||
"fieldname": "sb1",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"depends_on": "eval:doc.purpose.startsWith(\"Production Order\")",
|
||||
"no_copy": 0,
|
||||
"search_index": 1,
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Production Order",
|
||||
"oldfieldname": "production_order",
|
||||
"permlevel": 0,
|
||||
"fieldname": "production_order",
|
||||
"fieldtype": "Link",
|
||||
"oldfieldtype": "Link",
|
||||
"reqd": 0,
|
||||
"hidden": 1,
|
||||
"options": "Production Order",
|
||||
"report_hide": 0,
|
||||
"in_filter": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.purpose.startsWith(\"Production Order\")",
|
||||
"doctype": "DocField",
|
||||
"label": "BOM No",
|
||||
"options": "BOM",
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Currency",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Manufacturing Quantity",
|
||||
"oldfieldname": "fg_completed_qty",
|
||||
"fieldname": "fg_completed_qty",
|
||||
"fieldtype": "Currency",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"permlevel": 0,
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
|
||||
"doctype": "DocField",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Button",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Get Items",
|
||||
"permlevel": 0,
|
||||
"fieldname": "get_items",
|
||||
"fieldtype": "Button",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"options": "get_items",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "cb1",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"depends_on": "eval:doc.purpose==\"Sales Return\"",
|
||||
"no_copy": 0,
|
||||
"search_index": 1,
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Delivery Note No",
|
||||
"oldfieldname": "delivery_note_no",
|
||||
"permlevel": 0,
|
||||
"fieldname": "delivery_note_no",
|
||||
"fieldtype": "Link",
|
||||
"oldfieldtype": "Link",
|
||||
"reqd": 0,
|
||||
"hidden": 1,
|
||||
"options": "Delivery Note",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"depends_on": "eval:doc.purpose==\"Sales Return\"",
|
||||
"doctype": "DocField",
|
||||
"label": "Sales Invoice No",
|
||||
"options": "Sales Invoice",
|
||||
"fieldname": "sales_invoice_no",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"depends_on": "eval:doc.purpose==\"Purchase Return\"",
|
||||
"no_copy": 0,
|
||||
"search_index": 1,
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Purchase Receipt No",
|
||||
"oldfieldname": "purchase_receipt_no",
|
||||
"permlevel": 0,
|
||||
"fieldname": "purchase_receipt_no",
|
||||
"fieldtype": "Link",
|
||||
"oldfieldtype": "Link",
|
||||
"reqd": 0,
|
||||
"hidden": 1,
|
||||
"options": "Purchase Receipt",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:(doc.purpose==\"Sales Return\" || doc.purpose==\"Purchase Return\")",
|
||||
"doctype": "DocField",
|
||||
"label": "Contact Info",
|
||||
"fieldname": "contact_section",
|
||||
@ -432,18 +364,17 @@
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"depends_on": "eval:doc.purpose==\"Purchase Return\"",
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"search_index": 0,
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Supplier",
|
||||
"oldfieldname": "supplier",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"fieldname": "supplier",
|
||||
"fieldtype": "Link",
|
||||
"search_index": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"options": "Supplier",
|
||||
@ -452,15 +383,16 @@
|
||||
},
|
||||
{
|
||||
"print_hide": 0,
|
||||
"depends_on": "eval:doc.purpose==\"Purchase Return\"",
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Data",
|
||||
"search_index": 0,
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Supplier Name",
|
||||
"oldfieldname": "supplier_name",
|
||||
"fieldname": "supplier_name",
|
||||
"fieldtype": "Data",
|
||||
"search_index": 0,
|
||||
"oldfieldtype": "Data",
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"permlevel": 1,
|
||||
@ -469,17 +401,16 @@
|
||||
},
|
||||
{
|
||||
"print_hide": 0,
|
||||
"depends_on": "eval:doc.purpose==\"Purchase Return\"",
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Small Text",
|
||||
"colour": "White:FFF",
|
||||
"search_index": 0,
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Supplier Address",
|
||||
"oldfieldname": "supplier_address",
|
||||
"trigger": "Client",
|
||||
"fieldname": "supplier_address",
|
||||
"fieldtype": "Small Text",
|
||||
"search_index": 0,
|
||||
"oldfieldtype": "Small Text",
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"permlevel": 0,
|
||||
@ -488,18 +419,17 @@
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"depends_on": "eval:doc.purpose==\"Sales Return\"",
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"search_index": 0,
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Customer",
|
||||
"oldfieldname": "customer",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"search_index": 0,
|
||||
"oldfieldtype": "Link",
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"options": "Customer",
|
||||
@ -508,15 +438,16 @@
|
||||
},
|
||||
{
|
||||
"print_hide": 0,
|
||||
"depends_on": "eval:doc.purpose==\"Sales Return\"",
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Data",
|
||||
"search_index": 0,
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Customer Name",
|
||||
"oldfieldname": "customer_name",
|
||||
"fieldname": "customer_name",
|
||||
"fieldtype": "Data",
|
||||
"search_index": 0,
|
||||
"oldfieldtype": "Data",
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"permlevel": 1,
|
||||
@ -525,15 +456,16 @@
|
||||
},
|
||||
{
|
||||
"print_hide": 0,
|
||||
"depends_on": "eval:doc.purpose==\"Sales Return\"",
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Small Text",
|
||||
"search_index": 0,
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Customer Address",
|
||||
"oldfieldname": "customer_address",
|
||||
"fieldname": "customer_address",
|
||||
"fieldtype": "Small Text",
|
||||
"search_index": 0,
|
||||
"oldfieldtype": "Small Text",
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"permlevel": 0,
|
||||
@ -584,119 +516,6 @@
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "Data",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Cancel Reason",
|
||||
"oldfieldname": "cancel_reason",
|
||||
"fieldname": "cancel_reason",
|
||||
"fieldtype": "Data",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 1,
|
||||
"permlevel": 1,
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 0,
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "Date",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Transfer Date",
|
||||
"oldfieldname": "transfer_date",
|
||||
"default": "Today",
|
||||
"fieldname": "transfer_date",
|
||||
"fieldtype": "Date",
|
||||
"search_index": 0,
|
||||
"reqd": 1,
|
||||
"hidden": 0,
|
||||
"permlevel": 0,
|
||||
"report_hide": 0,
|
||||
"in_filter": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"width": "50%",
|
||||
"fieldname": "col5",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Select",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Is Excisable Goods",
|
||||
"oldfieldname": "is_excisable_goods",
|
||||
"permlevel": 0,
|
||||
"fieldname": "is_excisable_goods",
|
||||
"fieldtype": "Select",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"options": "\nYes\nNo",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Select",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Excisable Goods",
|
||||
"oldfieldname": "excisable_goods",
|
||||
"permlevel": 0,
|
||||
"fieldname": "excisable_goods",
|
||||
"fieldtype": "Select",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"options": "\nReturnable\nNon-Returnable",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Select",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Under Rule",
|
||||
"oldfieldname": "under_rule",
|
||||
"permlevel": 0,
|
||||
"fieldname": "under_rule",
|
||||
"fieldtype": "Select",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 1,
|
||||
"options": "\nOrdinary\n57 AC (5) a\n57 F (2) Non-Exc.",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Data",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Transporter",
|
||||
"oldfieldname": "transporter",
|
||||
"fieldname": "transporter",
|
||||
"fieldtype": "Data",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"permlevel": 0,
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
@ -716,22 +535,11 @@
|
||||
"in_filter": 1
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Select",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Fiscal Year",
|
||||
"oldfieldname": "fiscal_year",
|
||||
"permlevel": 0,
|
||||
"fieldname": "fiscal_year",
|
||||
"fieldtype": "Select",
|
||||
"search_index": 0,
|
||||
"reqd": 1,
|
||||
"hidden": 0,
|
||||
"options": "link:Fiscal Year",
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
"width": "50%",
|
||||
"fieldname": "col5",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
@ -753,21 +561,20 @@
|
||||
},
|
||||
{
|
||||
"print_hide": 1,
|
||||
"description": "The date at which current entry is corrected in the system.",
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "Date",
|
||||
"oldfieldtype": "Text",
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
"label": "Amendment Date",
|
||||
"oldfieldname": "amendment_date",
|
||||
"fieldname": "amendment_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Remarks",
|
||||
"oldfieldname": "remarks",
|
||||
"fieldname": "remarks",
|
||||
"fieldtype": "Text",
|
||||
"search_index": 0,
|
||||
"reqd": 0,
|
||||
"hidden": 0,
|
||||
"in_filter": 0,
|
||||
"permlevel": 0,
|
||||
"report_hide": 0
|
||||
"report_hide": 0,
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
|
@ -4,7 +4,7 @@
|
||||
"docstatus": 0,
|
||||
"creation": "2012-07-03 13:29:47",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2012-12-03 11:37:17"
|
||||
"modified": "2012-12-17 16:12:42"
|
||||
},
|
||||
{
|
||||
"istable": 1,
|
||||
@ -14,6 +14,7 @@
|
||||
"module": "Stock"
|
||||
},
|
||||
{
|
||||
"read_only": 0,
|
||||
"name": "__common__",
|
||||
"parent": "Stock Entry Detail",
|
||||
"doctype": "DocField",
|
||||
@ -52,7 +53,6 @@
|
||||
"label": "Item Code",
|
||||
"oldfieldname": "item_code",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"search_index": 1,
|
||||
@ -75,7 +75,6 @@
|
||||
"doctype": "DocField",
|
||||
"label": "Qty",
|
||||
"oldfieldname": "qty",
|
||||
"trigger": "Client",
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Currency",
|
||||
"reqd": 1,
|
||||
@ -83,15 +82,13 @@
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "UOM",
|
||||
"oldfieldname": "uom",
|
||||
"trigger": "Client",
|
||||
"options": "UOM",
|
||||
"fieldname": "uom",
|
||||
"fieldtype": "Link",
|
||||
"reqd": 1,
|
||||
"options": "UOM",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
@ -130,10 +127,9 @@
|
||||
"doctype": "DocField",
|
||||
"label": "Batch No",
|
||||
"oldfieldname": "batch_no",
|
||||
"trigger": "Client",
|
||||
"options": "Batch",
|
||||
"fieldname": "batch_no",
|
||||
"fieldtype": "Link",
|
||||
"options": "Batch",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
@ -174,7 +170,7 @@
|
||||
{
|
||||
"oldfieldtype": "Currency",
|
||||
"doctype": "DocField",
|
||||
"label": "Stock Qty",
|
||||
"label": "Qty as per Stock UOM",
|
||||
"oldfieldname": "transfer_qty",
|
||||
"fieldname": "transfer_qty",
|
||||
"fieldtype": "Currency",
|
||||
@ -186,12 +182,12 @@
|
||||
"doctype": "DocField",
|
||||
"label": "Stock UOM",
|
||||
"oldfieldname": "stock_uom",
|
||||
"options": "UOM",
|
||||
"permlevel": 1,
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"search_index": 0,
|
||||
"reqd": 1,
|
||||
"permlevel": 1,
|
||||
"options": "UOM",
|
||||
"in_filter": 0
|
||||
},
|
||||
{
|
||||
|
@ -125,7 +125,6 @@ class DocType:
|
||||
s.modified_by = session['user']
|
||||
s.serial_no = serial_no
|
||||
s.sle_exists = 1
|
||||
s.fiscal_year = obj.doc.fiscal_year
|
||||
s.company = obj.doc.company
|
||||
s.save(new_rec)
|
||||
|
||||
|
@ -44,7 +44,7 @@ class DocType:
|
||||
|
||||
|
||||
def validate_mandatory(self):
|
||||
mandatory = ['warehouse','transaction_date','posting_date','voucher_type','voucher_no','actual_qty','company','fiscal_year']
|
||||
mandatory = ['warehouse','transaction_date','posting_date','voucher_type','voucher_no','actual_qty','company']
|
||||
for k in mandatory:
|
||||
if self.doc.fields.get(k)==None:
|
||||
msgprint("Stock Ledger Entry: '%s' is mandatory" % k, raise_exception = 1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user