Merge branch 'master' of github.com:webnotes/erpnext
This commit is contained in:
commit
2c3f35f557
@ -146,4 +146,23 @@ test_records = [
|
||||
"is_sub_contracted_item": "No",
|
||||
"stock_uom": "_Test UOM"
|
||||
}],
|
||||
[{
|
||||
"doctype": "Item",
|
||||
"item_code": "_Test Serialized Item",
|
||||
"item_name": "_Test Serialized Item",
|
||||
"description": "_Test Serialized Item",
|
||||
"item_group": "_Test Item Group Desktops",
|
||||
"is_stock_item": "Yes",
|
||||
"is_asset_item": "No",
|
||||
"has_batch_no": "No",
|
||||
"has_serial_no": "Yes",
|
||||
"is_purchase_item": "Yes",
|
||||
"is_sales_item": "Yes",
|
||||
"is_service_item": "No",
|
||||
"is_sample_item": "No",
|
||||
"inspection_required": "No",
|
||||
"is_pro_applicable": "No",
|
||||
"is_sub_contracted_item": "No",
|
||||
"stock_uom": "_Test UOM"
|
||||
}],
|
||||
]
|
@ -19,14 +19,11 @@ import webnotes
|
||||
|
||||
from webnotes.utils import cint, getdate, nowdate
|
||||
import datetime
|
||||
|
||||
sql = webnotes.conn.sql
|
||||
msgprint = webnotes.msgprint
|
||||
from webnotes import msgprint, _
|
||||
|
||||
from controllers.stock_controller import StockController
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
class DocType(StockController):
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
@ -54,21 +51,14 @@ class DocType(TransactionBase):
|
||||
"""
|
||||
Validate whether serial no is required for this item
|
||||
"""
|
||||
item = sql("select name, has_serial_no from tabItem where name = '%s'" % self.doc.item_code)
|
||||
item = webnotes.conn.sql("select name, has_serial_no from tabItem where name = '%s'" % self.doc.item_code)
|
||||
if not item:
|
||||
msgprint("Item is not exists in the system", raise_exception=1)
|
||||
elif item[0][1] == 'No':
|
||||
msgprint("To proceed please select 'Yes' in 'Has Serial No' in Item master: '%s'" % self.doc.item_code, raise_exception=1)
|
||||
|
||||
|
||||
# ---------
|
||||
# validate
|
||||
# ---------
|
||||
def validate(self):
|
||||
# import utilities
|
||||
# utilities.validate_status(self.doc.status, ["In Store", "Delivered",
|
||||
# "Not in Use", "Purchase Returned"])
|
||||
|
||||
self.validate_warranty_status()
|
||||
self.validate_amc_status()
|
||||
self.validate_warehouse()
|
||||
@ -77,10 +67,12 @@ class DocType(TransactionBase):
|
||||
def on_update(self):
|
||||
if self.doc.warehouse and self.doc.status == 'In Store' \
|
||||
and cint(self.doc.sle_exists) == 0 and \
|
||||
not sql("""select name from `tabStock Ledger Entry` where serial_no = %s and
|
||||
ifnull(is_cancelled, 'No') = 'No'""", self.doc.name):
|
||||
not webnotes.conn.sql("""select name from `tabStock Ledger Entry`
|
||||
where serial_no = %s and ifnull(is_cancelled, 'No') = 'No'""", self.doc.name):
|
||||
self.make_stock_ledger_entry(1)
|
||||
webnotes.conn.set(self.doc, 'sle_exists', 1)
|
||||
|
||||
self.make_gl_entries()
|
||||
|
||||
def make_stock_ledger_entry(self, qty):
|
||||
from webnotes.model.code import get_obj
|
||||
@ -105,15 +97,13 @@ class DocType(TransactionBase):
|
||||
get_obj('Stock Ledger').update_stock(values)
|
||||
|
||||
|
||||
# ---------
|
||||
# on trash
|
||||
# ---------
|
||||
def on_trash(self):
|
||||
if self.doc.status == 'Delivered':
|
||||
msgprint("Cannot trash Serial No : %s as it is already Delivered" % (self.doc.name), raise_exception = 1)
|
||||
elif self.doc.status == 'In Store':
|
||||
webnotes.conn.set(self.doc, 'status', 'Not in Use')
|
||||
self.make_stock_ledger_entry(-1)
|
||||
self.make_gl_entries(cancel=True)
|
||||
|
||||
|
||||
def on_cancel(self):
|
||||
@ -121,6 +111,7 @@ class DocType(TransactionBase):
|
||||
|
||||
def on_restore(self):
|
||||
self.make_stock_ledger_entry(1)
|
||||
self.make_gl_entries()
|
||||
|
||||
def on_rename(self, new, old):
|
||||
"""rename serial_no text fields"""
|
||||
@ -135,7 +126,16 @@ class DocType(TransactionBase):
|
||||
where name=%s""" % (dt[0], '%s', '%s'),
|
||||
('\n'.join(serial_nos), item[0]))
|
||||
|
||||
def make_gl_entries(self, cancel=False):
|
||||
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
|
||||
return
|
||||
|
||||
|
||||
from accounts.general_ledger import make_gl_entries
|
||||
against_stock_account = self.get_company_default("stock_adjustment_account")
|
||||
gl_entries = self.get_gl_entries_for_stock(against_stock_account, self.doc.purchase_rate)
|
||||
|
||||
for entry in gl_entries:
|
||||
entry["posting_date"] = self.doc.purchase_date
|
||||
|
||||
|
||||
if gl_entries:
|
||||
make_gl_entries(gl_entries, cancel)
|
@ -1,93 +1,102 @@
|
||||
# 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/>.
|
||||
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import webnotes
|
||||
from webnotes.tests import insert_test_data
|
||||
|
||||
company = webnotes.conn.get_default("company")
|
||||
import webnotes, unittest
|
||||
|
||||
class TestSerialNo(unittest.TestCase):
|
||||
def setUp(self):
|
||||
webnotes.conn.begin()
|
||||
self.insert_test_data()
|
||||
|
||||
def tearDown(self):
|
||||
# print "Message Log:", "\n--\n".join(webnotes.message_log)
|
||||
# print "Debug Log:", "\n--\n".join(webnotes.debug_log)
|
||||
webnotes.conn.rollback()
|
||||
def test_aii_gl_entries_for_serial_no_in_store(self):
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||
|
||||
def test_serialized_stock_entry(self):
|
||||
data = [["2012-01-01", "01:00", "10001", 400, 400],
|
||||
["2012-01-01", "03:00", "10002", 500, 700],
|
||||
["2012-01-01", "04:00", "10003", 700, 700],
|
||||
["2012-01-01", "05:00", "10004", 1200, 800],
|
||||
["2012-01-01", "05:00", "10005", 800, 800],
|
||||
["2012-01-01", "02:00", "10006", 1200, 800],
|
||||
["2012-01-01", "06:00", "10007", 1500, 900]]
|
||||
for d in data:
|
||||
webnotes.bean([{
|
||||
"doctype": "Serial No",
|
||||
"item_code": "Nebula 8",
|
||||
"warehouse": "Default Warehouse",
|
||||
"status": "In Store",
|
||||
"sle_exists": 0,
|
||||
"purchase_date": d[0],
|
||||
"purchase_time": d[1],
|
||||
"serial_no": d[2],
|
||||
"purchase_rate": d[3],
|
||||
"company": company,
|
||||
}]).insert()
|
||||
sr = webnotes.bean(copy=test_records[0])
|
||||
sr.doc.serial_no = "_Test Serial No 1"
|
||||
sr.insert()
|
||||
|
||||
stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company",
|
||||
"stock_in_hand_account")
|
||||
against_stock_account = webnotes.conn.get_value("Company", "_Test Company",
|
||||
"stock_adjustment_account")
|
||||
|
||||
# check stock ledger entries
|
||||
sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry`
|
||||
where voucher_type = 'Serial No' and voucher_no = %s""", sr.doc.name, as_dict=1)[0]
|
||||
self.assertTrue(sle)
|
||||
self.assertEquals([sle.item_code, sle.warehouse, sle.actual_qty],
|
||||
["_Test Serialized Item", "_Test Warehouse", 1.0])
|
||||
|
||||
for d in data:
|
||||
res = webnotes.conn.sql("""select valuation_rate from `tabStock Ledger Entry`
|
||||
where posting_date=%s and posting_time=%s and actual_qty=1 and serial_no=%s""",
|
||||
(d[0], d[1], d[2]))
|
||||
self.assertEquals(res[0][0], d[4])
|
||||
# check gl entries
|
||||
gl_entries = webnotes.conn.sql("""select account, debit, credit
|
||||
from `tabGL Entry` where voucher_type='Serial No' and voucher_no=%s
|
||||
order by account desc""", sr.doc.name, as_dict=1)
|
||||
self.assertTrue(gl_entries)
|
||||
|
||||
print "deleted"
|
||||
webnotes.delete_doc("Serial No", "10002")
|
||||
expected_values = [
|
||||
[stock_in_hand_account, 1000.0, 0.0],
|
||||
[against_stock_account, 0.0, 1000.0]
|
||||
]
|
||||
|
||||
test_data = [["10001", 400, 400],
|
||||
["10003", 700, 766.666667],
|
||||
["10004", 1200, 875],
|
||||
["10005", 800, 860],
|
||||
["10006", 1200, 800],
|
||||
["10007", 1500, 966.666667]]
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_values[i][0], gle.account)
|
||||
self.assertEquals(expected_values[i][1], gle.debit)
|
||||
self.assertEquals(expected_values[i][2], gle.credit)
|
||||
|
||||
for d in test_data:
|
||||
res = webnotes.conn.sql("""select valuation_rate from `tabStock Ledger Entry`
|
||||
where actual_qty=1 and serial_no=%s""", (d[0],))
|
||||
self.assertEquals(res[0][0], d[2])
|
||||
sr.load_from_db()
|
||||
self.assertEquals(sr.doc.sle_exists, 1)
|
||||
|
||||
# save again
|
||||
sr.save()
|
||||
gl_entries = webnotes.conn.sql("""select account, debit, credit
|
||||
from `tabGL Entry` where voucher_type='Serial No' and voucher_no=%s
|
||||
order by account desc""", sr.doc.name, as_dict=1)
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_values[i][0], gle.account)
|
||||
self.assertEquals(expected_values[i][1], gle.debit)
|
||||
self.assertEquals(expected_values[i][2], gle.credit)
|
||||
|
||||
# trash/cancel
|
||||
sr.submit()
|
||||
sr.cancel()
|
||||
|
||||
gl_count = webnotes.conn.sql("""select count(name) from `tabGL Entry`
|
||||
where voucher_type='Serial No' and voucher_no=%s and ifnull(is_cancelled, 'No') = 'Yes'
|
||||
order by account asc, name asc""", sr.doc.name)
|
||||
|
||||
self.assertEquals(gl_count[0][0], 4)
|
||||
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
|
||||
|
||||
def test_aii_gl_entries_for_serial_no_delivered(self):
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||
|
||||
sr = webnotes.bean(copy=test_records[0])
|
||||
sr.doc.serial_no = "_Test Serial No 2"
|
||||
sr.doc.status = "Delivered"
|
||||
sr.insert()
|
||||
|
||||
gl_entries = webnotes.conn.sql("""select account, debit, credit
|
||||
from `tabGL Entry` where voucher_type='Serial No' and voucher_no=%s
|
||||
order by account desc""", sr.doc.name, as_dict=1)
|
||||
self.assertFalse(gl_entries)
|
||||
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
|
||||
def insert_test_data(self):
|
||||
# create default warehouse
|
||||
if not webnotes.conn.exists("Warehouse", "Default Warehouse"):
|
||||
webnotes.insert({"doctype": "Warehouse",
|
||||
"warehouse_name": "Default Warehouse",
|
||||
"warehouse_type": "Stores"})
|
||||
|
||||
# create UOM: Nos.
|
||||
if not webnotes.conn.exists("UOM", "Nos"):
|
||||
webnotes.insert({"doctype": "UOM", "uom_name": "Nos"})
|
||||
|
||||
# create item groups and items
|
||||
insert_test_data("Item Group",
|
||||
sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name')))
|
||||
|
||||
insert_test_data("Item")
|
||||
|
||||
test_records = [
|
||||
[
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"doctype": "Serial No",
|
||||
"serial_no": "_Test Serial No",
|
||||
"status": "In Store",
|
||||
"item_code": "_Test Serialized Item",
|
||||
"item_group": "_Test Item Group",
|
||||
"warehouse": "_Test Warehouse",
|
||||
"purchase_rate": 1000.0,
|
||||
"purchase_time": "11:37:39",
|
||||
"purchase_date": "2013-02-26",
|
||||
'fiscal_year': "_Test Fiscal Year 2013"
|
||||
}
|
||||
]
|
||||
]
|
Loading…
x
Reference in New Issue
Block a user