diff --git a/sandbox/__init__.py b/sandbox/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/sandbox/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/sandbox/test_leave.py b/sandbox/test_leave.py deleted file mode 100644 index 25601b7471..0000000000 --- a/sandbox/test_leave.py +++ /dev/null @@ -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 . - -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() diff --git a/sandbox/test_stock_entry.py b/sandbox/test_stock_entry.py deleted file mode 100644 index fe28880b93..0000000000 --- a/sandbox/test_stock_entry.py +++ /dev/null @@ -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 . - -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] diff --git a/sandbox/test_stock_reco.py b/sandbox/test_stock_reco.py deleted file mode 100644 index ada85b48db..0000000000 --- a/sandbox/test_stock_reco.py +++ /dev/null @@ -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 . - -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] diff --git a/sandbox/testdata/__init__.py b/sandbox/testdata/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/sandbox/testdata/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/sandbox/testdata/leaves.py b/sandbox/testdata/leaves.py deleted file mode 100644 index db8b431e5a..0000000000 --- a/sandbox/testdata/leaves.py +++ /dev/null @@ -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 . - -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 - } -) diff --git a/sandbox/testdata/masters.py b/sandbox/testdata/masters.py deleted file mode 100644 index c59253b3a9..0000000000 --- a/sandbox/testdata/masters.py +++ /dev/null @@ -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 . - -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) diff --git a/sandbox/testdata/sle_data.py b/sandbox/testdata/sle_data.py deleted file mode 100644 index 5cd6dc2665..0000000000 --- a/sandbox/testdata/sle_data.py +++ /dev/null @@ -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 . - -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, - } -) diff --git a/sandbox/testdata/stock_entry.py b/sandbox/testdata/stock_entry.py deleted file mode 100644 index e617c08313..0000000000 --- a/sandbox/testdata/stock_entry.py +++ /dev/null @@ -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 . - -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' - } - ) -] diff --git a/sandbox/testdata/stock_reco.py b/sandbox/testdata/stock_reco.py deleted file mode 100644 index 87e3eb2347..0000000000 --- a/sandbox/testdata/stock_reco.py +++ /dev/null @@ -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 . - -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] -] diff --git a/setup/doctype/authorization_rule/authorization_rule.txt b/setup/doctype/authorization_rule/authorization_rule.txt index 7061da37b1..a7d024a56e 100644 --- a/setup/doctype/authorization_rule/authorization_rule.txt +++ b/setup/doctype/authorization_rule/authorization_rule.txt @@ -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", diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js index 5805b2aa92..db418f0755 100644 --- a/stock/doctype/stock_entry/stock_entry.js +++ b/stock/doctype/stock_entry/stock_entry.js @@ -14,28 +14,33 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -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 diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index 45dcb805f5..cf646433a3 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -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 @@ -34,7 +34,161 @@ class DocType(TransactionBase): self.doclist = doclist 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 = self.doc.bom_no + fg_qty = self.doc.fg_completed_qty + + 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.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 + 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, use_multi_level_bom) + 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,10 +406,9 @@ 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 + '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 diff --git a/stock/doctype/stock_entry/stock_entry.txt b/stock/doctype/stock_entry/stock_entry.txt index bcba4cdb02..4426f103fa 100644 --- a/stock/doctype/stock_entry/stock_entry.txt +++ b/stock/doctype/stock_entry/stock_entry.txt @@ -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": "
Warehouse
", - "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": "Notes: 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, diff --git a/stock/doctype/stock_entry_detail/stock_entry_detail.txt b/stock/doctype/stock_entry_detail/stock_entry_detail.txt index c191797326..9e0e5df6a7 100644 --- a/stock/doctype/stock_entry_detail/stock_entry_detail.txt +++ b/stock/doctype/stock_entry_detail/stock_entry_detail.txt @@ -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 }, { diff --git a/stock/doctype/stock_ledger/stock_ledger.py b/stock/doctype/stock_ledger/stock_ledger.py index b9a47f53b3..8d39b26dbb 100644 --- a/stock/doctype/stock_ledger/stock_ledger.py +++ b/stock/doctype/stock_ledger/stock_ledger.py @@ -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) diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index e6c4deeec5..dadb4130bd 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -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)