started with Auto Inventory Accounting - test case for purchase receipt

This commit is contained in:
Anand Doshi 2013-02-26 18:09:47 +05:30
parent 29786e38df
commit a1d4b78fbe
9 changed files with 341 additions and 315 deletions

View File

@ -1,27 +1,41 @@
from __future__ import unicode_literals
import webnotes
def make_test_records(verbose): def make_test_records(verbose):
from webnotes.test_runner import make_test_objects from webnotes.test_runner import make_test_objects
accounts = [ accounts = [
# [account_name, parent_account, group_or_ledger] # [account_name, parent_account, group_or_ledger]
["_Test Account Bank Account", "Bank Accounts - _TC", "Ledger"], ["_Test Account Bank Account", "Bank Accounts - _TC", "Ledger"],
["_Test Account Stock Expenses", "Direct Expenses - _TC", "Group"], ["_Test Account Stock Expenses", "Direct Expenses - _TC", "Group"],
["_Test Account Shipping Charges", "_Test Account Stock Expenses - _TC", "Ledger"], ["_Test Account Shipping Charges", "_Test Account Stock Expenses - _TC", "Ledger"],
["_Test Account Customs Duty", "_Test Account Stock Expenses - _TC", "Ledger"], ["_Test Account Customs Duty", "_Test Account Stock Expenses - _TC", "Ledger"],
["_Test Account Tax Assets", "Current Assets - _TC", "Group"], ["_Test Account Tax Assets", "Current Assets - _TC", "Group"],
["_Test Account VAT", "_Test Account Tax Assets - _TC", "Ledger"], ["_Test Account VAT", "_Test Account Tax Assets - _TC", "Ledger"],
["_Test Account Service Tax", "_Test Account Tax Assets - _TC", "Ledger"], ["_Test Account Service Tax", "_Test Account Tax Assets - _TC", "Ledger"],
["_Test Account Cost for Goods Sold", "Expenses - _TC", "Ledger"], ["_Test Account Cost for Goods Sold", "Expenses - _TC", "Ledger"],
["_Test Account Excise Duty", "_Test Account Tax Assets - _TC", "Ledger"], ["_Test Account Excise Duty", "_Test Account Tax Assets - _TC", "Ledger"],
["_Test Account Education Cess", "_Test Account Tax Assets - _TC", "Ledger"], ["_Test Account Education Cess", "_Test Account Tax Assets - _TC", "Ledger"],
["_Test Account S&H Education Cess", "_Test Account Tax Assets - _TC", "Ledger"], ["_Test Account S&H Education Cess", "_Test Account Tax Assets - _TC", "Ledger"],
["_Test Account CST", "Direct Expenses - _TC", "Ledger"], ["_Test Account CST", "Direct Expenses - _TC", "Ledger"],
["_Test Account Discount", "Direct Expenses - _TC", "Ledger"], ["_Test Account Discount", "Direct Expenses - _TC", "Ledger"],
# related to Account Inventory Integration
["_Test Account Stock In Hand", "Current Assets - _TC", "Ledger"],
] ]
return make_test_objects("Account", [[{ test_objects = make_test_objects("Account", [[{
"doctype": "Account", "doctype": "Account",
"account_name": account_name, "account_name": account_name,
"parent_account": parent_account, "parent_account": parent_account,
"company": "_Test Company", "company": "_Test Company",
"group_or_ledger": group_or_ledger "group_or_ledger": group_or_ledger
}] for account_name, parent_account, group_or_ledger in accounts]) }] for account_name, parent_account, group_or_ledger in accounts])
webnotes.conn.set_value("Company", "_Test Company", "stock_in_hand_account",
"_Test Account Stock In Hand - _TC")
return test_objects

View File

@ -385,7 +385,7 @@ class DocType(BuyingController):
gl_entries = [] gl_entries = []
valuation_tax = 0 valuation_tax = 0
auto_inventory_accounting = webnotes.conn.get_value("Global Defaults", None, auto_inventory_accounting = webnotes.conn.get_value("Global Defaults", None,
"automatic_inventory_accounting") "auto_inventory_accounting")
abbr = self.get_company_abbr() abbr = self.get_company_abbr()
# parent's gl entry # parent's gl entry

View File

@ -16,6 +16,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes import msgprint, _
from webnotes.utils import flt from webnotes.utils import flt
from utilities.transaction_base import TransactionBase from utilities.transaction_base import TransactionBase
@ -38,14 +39,6 @@ class AccountsController(TransactionBase):
gl_dict.update(args) gl_dict.update(args)
return gl_dict return gl_dict
def get_stock_in_hand_account(self):
stock_in_hand = webnotes.conn.get_value("Company", self.doc.company, "stock_in_hand")
if not stock_in_hand:
webnotes.msgprint("""Please specify "Stock In Hand" account
for company: %s""" % (self.doc.company,), raise_exception=1)
return stock_in_hand
def clear_unallocated_advances(self, childtype, parentfield): def clear_unallocated_advances(self, childtype, parentfield):
self.doclist.remove_items({"parentfield": parentfield, "allocated_amount": ["in", [0, None, ""]]}) self.doclist.remove_items({"parentfield": parentfield, "allocated_amount": ["in", [0, None, ""]]})
@ -74,3 +67,23 @@ class AccountsController(TransactionBase):
"advance_amount": flt(d.amount), "advance_amount": flt(d.amount),
"allocate_amount": 0 "allocate_amount": 0
}) })
def get_stock_in_hand_account(self):
stock_in_hand_account = webnotes.conn.get_value("Company", self.doc.company, "stock_in_hand_account")
if not stock_in_hand_account:
msgprint(_("Missing") + ": "
+ _(webnotes.get_doctype("company").get_label("stock_in_hand_account")
+ " " + _("for Company") + " " + self.doc.company), raise_exception=True)
return stock_in_hand_account
@property
def stock_items(self):
if not hasattr(self, "_stock_items"):
item_codes = list(set(item.item_code for item in self.doclist.get({"parentfield": self.fname})))
self._stock_items = [r[0] for r in webnotes.conn.sql("""select name
from `tabItem` where name in (%s) and is_stock_item='Yes'""" % \
(", ".join((["%s"]*len(item_codes))),), item_codes)]
return self._stock_items

View File

@ -114,6 +114,14 @@ class BuyingController(AccountsController):
for item in self.item_doclist: for item in self.item_doclist:
round_floats_in_doc(item, self.precision.item) round_floats_in_doc(item, self.precision.item)
# hack! - cleaned up in _cleanup()
if self.doc.doctype != "Purchase Invoice":
item.rate = item.purchase_rate
self.precision.item.rate = self.precision.item.purchase_rate
item.discount = item.discount_rate
self.precision.item.discount = self.precision.item.discount_rate
if item.discount == 100: if item.discount == 100:
if not item.import_ref_rate: if not item.import_ref_rate:
item.import_ref_rate = item.import_rate item.import_ref_rate = item.import_rate
@ -257,6 +265,9 @@ class BuyingController(AccountsController):
item.purchase_rate = item.rate item.purchase_rate = item.rate
del item.fields["rate"] del item.fields["rate"]
item.discount_rate = item.discount
del item.fields["discount"]
def validate_on_previous_row(self, tax): def validate_on_previous_row(self, tax):
""" """
validate if a valid row id is mentioned in case of validate if a valid row id is mentioned in case of
@ -315,16 +326,6 @@ class BuyingController(AccountsController):
item.item_tax_amount += flt(current_tax_amount, item.item_tax_amount += flt(current_tax_amount,
self.precision.item.item_tax_amount) self.precision.item.item_tax_amount)
@property
def stock_items(self):
if not hasattr(self, "_stock_items"):
item_codes = list(set(item.item_code for item in self.item_doclist))
self._stock_items = [r[0] for r in webnotes.conn.sql("""select name
from `tabItem` where name in (%s) and is_stock_item='Yes'""" % \
(", ".join((["%s"]*len(item_codes))),), item_codes)]
return self._stock_items
@property @property
def precision(self): def precision(self):
if not hasattr(self, "_precision"): if not hasattr(self, "_precision"):

View File

@ -37,7 +37,8 @@ class DocType:
# --------------------------------------------------- # ---------------------------------------------------
def create_default_accounts(self): def create_default_accounts(self):
self.fld_dict = {'account_name':0,'parent_account':1,'group_or_ledger':2,'is_pl_account':3,'account_type':4,'debit_or_credit':5,'company':6,'tax_rate':7} self.fld_dict = {'account_name':0,'parent_account':1,'group_or_ledger':2,'is_pl_account':3,'account_type':4,'debit_or_credit':5,'company':6,'tax_rate':7}
acc_list_common = [['Application of Funds (Assets)','','Group','No','','Debit',self.doc.name,''], acc_list_common = [
['Application of Funds (Assets)','','Group','No','','Debit',self.doc.name,''],
['Current Assets','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''], ['Current Assets','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''],
['Accounts Receivable','Current Assets','Group','No','','Debit',self.doc.name,''], ['Accounts Receivable','Current Assets','Group','No','','Debit',self.doc.name,''],
['Bank Accounts','Current Assets','Group','No','Bank or Cash','Debit',self.doc.name,''], ['Bank Accounts','Current Assets','Group','No','Bank or Cash','Debit',self.doc.name,''],
@ -49,6 +50,7 @@ class DocType:
['Stock In Hand','Current Assets','Group','No','','Debit',self.doc.name,''], ['Stock In Hand','Current Assets','Group','No','','Debit',self.doc.name,''],
['Stock','Stock In Hand','Ledger','No','','Debit',self.doc.name,''], ['Stock','Stock In Hand','Ledger','No','','Debit',self.doc.name,''],
['Tax Assets','Current Assets','Group','No','','Debit',self.doc.name,''], ['Tax Assets','Current Assets','Group','No','','Debit',self.doc.name,''],
['Stock Delivered But Not Billed','Current Assets','Ledger','No','','Debit',self.doc.name,''],
['Fixed Assets','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''], ['Fixed Assets','Application of Funds (Assets)','Group','No','','Debit',self.doc.name,''],
['Capital Equipments','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], ['Capital Equipments','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''],
['Computers','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''], ['Computers','Fixed Assets','Ledger','No','Fixed Asset Account','Debit',self.doc.name,''],
@ -61,6 +63,8 @@ class DocType:
['Expenses','','Group','Yes','Expense Account','Debit',self.doc.name,''], ['Expenses','','Group','Yes','Expense Account','Debit',self.doc.name,''],
['Direct Expenses','Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''], ['Direct Expenses','Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''],
['Cost of Goods Sold','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], ['Cost of Goods Sold','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
['Expenses Included In Valuation','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
['Stock Adjustment','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
['Indirect Expenses','Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''], ['Indirect Expenses','Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''],
['Advertising and Publicity','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''], ['Advertising and Publicity','Indirect Expenses','Ledger','Yes','Chargeable','Debit',self.doc.name,''],
['Bad Debts Written Off','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''], ['Bad Debts Written Off','Indirect Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
@ -102,6 +106,7 @@ class DocType:
['Secured Loans','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''], ['Secured Loans','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''],
['Unsecured Loans','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''], ['Unsecured Loans','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''],
['Bank Overdraft Account','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''], ['Bank Overdraft Account','Loans (Liabilities)','Group','No','','Credit',self.doc.name,''],
['Stock Received But Not Billed','Current Liabilities','Ledger','No','','Credit',self.doc.name,''],
['Temporary Accounts (Liabilities)','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''], ['Temporary Accounts (Liabilities)','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''],
['Temporary Account (Liabilities)','Temporary Accounts (Liabilities)','Ledger','No','','Credit',self.doc.name,''] ['Temporary Account (Liabilities)','Temporary Accounts (Liabilities)','Ledger','No','','Credit',self.doc.name,'']
] ]

View File

@ -1,8 +1,8 @@
[ [
{ {
"creation": "2013-01-22 16:50:36", "creation": "2013-02-22 01:27:54",
"docstatus": 0, "docstatus": 0,
"modified": "2013-01-23 16:51:54", "modified": "2013-02-26 10:57:39",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@ -51,12 +51,13 @@
"oldfieldtype": "Section Break" "oldfieldtype": "Section Break"
}, },
{ {
"description": "Please Enter Abbreviation or Short Name properly as it will be added as Suffix to all Account Heads.",
"doctype": "DocField", "doctype": "DocField",
"fieldname": "company_name", "fieldname": "abbr",
"fieldtype": "Data", "fieldtype": "Data",
"label": "Company", "label": "Abbr",
"no_copy": 0, "no_copy": 0,
"oldfieldname": "company_name", "oldfieldname": "abbr",
"oldfieldtype": "Data", "oldfieldtype": "Data",
"reqd": 1 "reqd": 1
}, },
@ -66,13 +67,12 @@
"fieldtype": "Column Break" "fieldtype": "Column Break"
}, },
{ {
"description": "Please Enter Abbreviation or Short Name properly as it will be added as Suffix to all Account Heads.",
"doctype": "DocField", "doctype": "DocField",
"fieldname": "abbr", "fieldname": "company_name",
"fieldtype": "Data", "fieldtype": "Data",
"label": "Abbr", "label": "Company",
"no_copy": 0, "no_copy": 0,
"oldfieldname": "abbr", "oldfieldname": "company_name",
"oldfieldtype": "Data", "oldfieldtype": "Data",
"reqd": 1 "reqd": 1
}, },
@ -124,6 +124,17 @@
"oldfieldtype": "Link", "oldfieldtype": "Link",
"options": "Account" "options": "Account"
}, },
{
"depends_on": "eval:!doc.__islocal",
"description": "This account will be used to maintain value of available stock",
"doctype": "DocField",
"fieldname": "stock_in_hand_account",
"fieldtype": "Link",
"label": "Stock In Hand Account",
"no_copy": 1,
"options": "Account",
"read_only": 0
},
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "column_break0", "fieldname": "column_break0",

View File

@ -174,7 +174,12 @@ class DocType(SellingController):
def validate_reference_value(self): def validate_reference_value(self):
"""Validate values with reference document with previous document""" """Validate values with reference document with previous document"""
get_obj('DocType Mapper', 'Sales Order-Delivery Note', with_children = 1).validate_reference_value(self, self.doc.name) validate_ref = any([d.prevdoc_docname for d in self.doclist.get({"parentfield": self.fname})
if d.prevdoc_doctype == "Sales Order"])
if validate_ref:
get_obj('DocType Mapper', 'Sales Order-Delivery Note',
with_children = 1).validate_reference_value(self, self.doc.name)
def validate_for_items(self): def validate_for_items(self):

View File

@ -17,7 +17,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes.utils import cstr, flt from webnotes.utils import cstr, flt, cint
from webnotes.model.doc import addchild from webnotes.model.doc import addchild
from webnotes.model.bean import getlist from webnotes.model.bean import getlist
from webnotes.model.code import get_obj from webnotes.model.code import get_obj
@ -92,11 +92,12 @@ class DocType(BuyingController):
# update valuation rate # update valuation rate
def update_valuation_rate(self): def update_valuation_rate(self):
total_b_cost = flt(self.doc.buying_cost_transport) + flt(self.doc.buying_cost_taxes) + flt(self.doc.buying_cost_other) for d in self.doclist.get({"parentfield": "purchase_receipt_details"}):
for d in getlist(self.doclist, 'purchase_receipt_details'): if d.qty:
if flt(self.doc.net_total) and flt(d.qty): d.valuation_rate = (flt(d.purchase_rate) + flt(d.item_tax_amount)/flt(d.qty)
#d.valuation_rate = (flt(d.purchase_rate) + ((flt(d.amount) * (total_b_cost)) / (self.doc.net_total * flt(d.qty))) + (flt(d.rm_supp_cost) / flt(d.qty))) / flt(d.conversion_factor) + flt(d.rm_supp_cost) / flt(d.qty)) / flt(d.conversion_factor)
d.valuation_rate = (flt(d.purchase_rate) + ((flt(d.amount) * (total_b_cost)) / (self.doc.net_total * flt(d.qty))) + (flt(d.rm_supp_cost) / flt(d.qty)) + (flt(d.item_tax_amount)/flt(d.qty))) / flt(d.conversion_factor) else:
d.valuation_rate = 0.0
#check in manage account if purchase order required or not. #check in manage account if purchase order required or not.
# ==================================================================================== # ====================================================================================
@ -264,10 +265,8 @@ class DocType(BuyingController):
# Update last purchase rate # Update last purchase rate
purchase_controller.update_last_purchase_rate(self, 1) purchase_controller.update_last_purchase_rate(self, 1)
self.make_gl_entries()
#On Cancel
#----------------------------------------------------------------------------------------------------
def check_next_docstatus(self): def check_next_docstatus(self):
submit_rv = sql("select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_receipt = '%s' and t1.docstatus = 1" % (self.doc.name)) submit_rv = sql("select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_receipt = '%s' and t1.docstatus = 1" % (self.doc.name))
if submit_rv: if submit_rv:
@ -302,9 +301,9 @@ class DocType(BuyingController):
# 6. Update last purchase rate # 6. Update last purchase rate
pc_obj.update_last_purchase_rate(self, 0) pc_obj.update_last_purchase_rate(self, 0)
self.make_gl_entries()
#----------- code for Sub-contracted Items -------------------
#--------check for sub-contracted items and accordingly update PR raw material detail table--------
def update_rw_material_detail(self): def update_rw_material_detail(self):
for d in getlist(self.doclist,'purchase_receipt_details'): for d in getlist(self.doclist,'purchase_receipt_details'):
@ -431,3 +430,44 @@ class DocType(BuyingController):
def get_purchase_tax_details(self): def get_purchase_tax_details(self):
self.doclist = get_obj('Purchase Common').get_purchase_tax_details(self) self.doclist = get_obj('Purchase Common').get_purchase_tax_details(self)
def make_gl_entries(self):
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
return
abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
stock_received_account = "Stock Received But Not Billed - %s" % (abbr,)
stock_in_hand_account = self.get_stock_in_hand_account()
total_valuation_amount = self.get_total_valuation_amount()
if total_valuation_amount:
gl_entries = [
# debit stock in hand account
self.get_gl_dict({
"account": stock_in_hand_account,
"against": stock_received_account,
"debit": total_valuation_amount,
"remarks": self.doc.remarks or "Accounting Entry for Stock",
}, self.doc.docstatus == 2),
# credit stock received but not billed account
self.get_gl_dict({
"account": stock_received_account,
"against": stock_in_hand_account,
"credit": total_valuation_amount,
"remarks": self.doc.remarks or "Accounting Entry for Stock",
}, self.doc.docstatus == 2),
]
from accounts.general_ledger import make_gl_entries
make_gl_entries(gl_entries, cancel=self.doc.docstatus == 2)
def get_total_valuation_amount(self):
total_valuation_amount = 0.0
for item in self.doclist.get({"parentfield": "purchase_receipt_details"}):
if item.item_code in self.stock_items:
total_valuation_amount += flt(item.valuation_rate) * \
flt(item.qty) * flt(item.conversion_factor)
return total_valuation_amount

View File

@ -18,178 +18,115 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import unittest import unittest
import webnotes import webnotes
import webnotes.model import webnotes.defaults
from webnotes.model.doclist import DocList from webnotes.utils import cint
from webnotes.utils import nowdate
company = webnotes.conn.get_default("company")
abbr = webnotes.conn.get_value("Company", company, "abbr")
def load_data():
insert_accounts()
# 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"})
from webnotes.tests import insert_test_data
# 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")
# create supplier type
webnotes.insert({"doctype": "Supplier Type", "supplier_type": "Manufacturing"})
# create supplier
webnotes.insert({"doctype": "Supplier", "supplier_name": "East Wind Inc.",
"supplier_type": "Manufacturing", "company": company})
# create default cost center if not exists
if not webnotes.conn.exists("Cost Center", "Default Cost Center - %s" % abbr):
webnotes.insert({"doctype": "Cost Center", "group_or_ledger": "Ledger",
"cost_center_name": "Default Cost Center",
"parent_cost_center": "Root - %s" % abbr,
"company_name": company})
# create account heads for taxes
webnotes.insert({"doctype": "Account", "account_name": "Shipping Charges",
"parent_account": "Stock Expenses - %s" % abbr, "company": company,
"group_or_ledger": "Ledger"})
webnotes.insert({"doctype": "Account", "account_name": "Customs Duty",
"parent_account": "Stock Expenses - %s" % abbr, "company": company,
"group_or_ledger": "Ledger"})
webnotes.insert({"doctype": "Account", "account_name": "_Test Tax Assets",
"parent_account": "Current Assets - %s" % abbr, "company": company,
"group_or_ledger": "Group"})
webnotes.insert({"doctype": "Account", "account_name": "VAT - Test",
"parent_account": "_Test Tax Assets - %s" % abbr, "company": company,
"group_or_ledger": "Ledger"})
# create BOM
# webnotes.insert(DocList([
# {"doctype": "BOM", "item": "Nebula 7", "quantity": 1,
# "is_active": "Yes", "is_default": 1, "uom": "Nos"},
# {"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
# "opn_description": "Development"},
# {"doctype": "BOM Item", "item_code": "Android Jack D", "operation_no": 1, "qty": 5,
# "rate": 20, "amount": 100, "stock_uom": "Nos", "parentfield": "bom_materials"}
# ]))
base_purchase_receipt = [
{
"doctype": "Purchase Receipt", "supplier": "East Wind Inc.",
"naming_series": "PR", "posting_date": nowdate(), "posting_time": "12:05",
"company": company, "fiscal_year": webnotes.conn.get_default("fiscal_year"),
"currency": webnotes.conn.get_default("currency"), "conversion_rate": 1
},
{
"doctype": "Purchase Receipt Item",
"item_code": "Home Desktop 100",
"qty": 10, "received_qty": 10, "rejected_qty": 0, "purchase_rate": 50,
"amount": 500, "warehouse": "Default Warehouse",
"parentfield": "purchase_receipt_details",
"conversion_factor": 1, "uom": "Nos", "stock_uom": "Nos"
},
{
"doctype": "Purchase Taxes and Charges", "charge_type": "Actual",
"account_head": "Shipping Charges - %s" % abbr, "rate": 100, "tax_amount": 100,
"category": "Valuation and Total", "parentfield": "purchase_tax_details",
"cost_center": "Default Cost Center - %s" % abbr
},
{
"doctype": "Purchase Taxes and Charges", "charge_type": "Actual",
"account_head": "VAT - Test - %s" % abbr, "rate": 120, "tax_amount": 120,
"category": "Total", "parentfield": "purchase_tax_details"
},
{
"doctype": "Purchase Taxes and Charges", "charge_type": "Actual",
"account_head": "Customs Duty - %s" % abbr, "rate": 150, "tax_amount": 150,
"category": "Valuation", "parentfield": "purchase_tax_details",
"cost_center": "Default Cost Center - %s" % abbr
}
]
def insert_accounts():
for d in webnotes.conn.sql("""select name, abbr from tabCompany""", as_dict=1):
acc_list = [
make_account_dict('Stock Assets', 'Current Assets', d, 'Group'),
make_account_dict('Stock In Hand', 'Stock Assets', d, 'Ledger'),
make_account_dict('Stock Delivered But Not Billed', 'Stock Assets',
d, 'Ledger'),
make_account_dict('Stock Liabilities', 'Current Liabilities', d, 'Group'),
make_account_dict('Stock Received But Not Billed', 'Stock Liabilities',
d, 'Ledger'),
make_account_dict('Stock Expenses', 'Direct Expenses', d, 'Group'),
make_account_dict('Stock Variance', 'Stock Expenses', d, 'Ledger'),
make_account_dict('Expenses Included In Valuation', 'Stock Expenses',
d, 'Ledger'),
]
for acc in acc_list:
acc_name = "%s - %s" % (acc['account_name'], d['abbr'])
if not webnotes.conn.exists('Account', acc_name):
webnotes.insert(acc)
def make_account_dict(account, parent, company_detail, group_or_ledger):
return {
"doctype": "Account",
"account_name": account,
"parent_account": "%s - %s" % (parent, company_detail['abbr']),
"company": company_detail['name'],
"group_or_ledger": group_or_ledger
}
class TestPurchaseReceipt(unittest.TestCase): class TestPurchaseReceipt(unittest.TestCase):
def setUp(self): def test_purchase_receipt_no_gl_entry(self):
webnotes.conn.begin() pr = webnotes.bean(copy=test_records[0])
load_data() pr.run_method("calculate_taxes_and_totals")
webnotes.conn.set_value("Global Defaults", None, "automatic_inventory_accounting", 1) pr.insert()
pr.submit()
def test_purchase_receipt(self): gl_entries = webnotes.conn.sql("""select account, debit, credit
# warehouse does not have stock in hand specified from `tabGL Entry` where voucher_type='Purchase Receipt' and voucher_no=%s
self.run_purchase_receipt_test(base_purchase_receipt, order by account desc""", pr.doc.name, as_dict=1)
"Stock In Hand - %s" % (abbr,),
"Stock Received But Not Billed - %s" % (abbr,), 750.0)
def run_purchase_receipt_test(self, purchase_receipt, debit_account, self.assertTrue(not gl_entries)
credit_account, stock_value):
dl = webnotes.insert(DocList(purchase_receipt))
from controllers.tax_controller import TaxController def test_purchase_receipt_gl_entry(self):
tax_controller = TaxController(dl.doc, dl.doclist) webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
tax_controller.item_table_field = "purchase_receipt_details"
tax_controller.calculate_taxes_and_totals()
dl.doc = tax_controller.doc
dl.doclist = tax_controller.doclist
dl.submit() self.assertEqual(cint(webnotes.defaults.get_global_default("auto_inventory_accounting")), 1)
dl.load_from_db()
gle = webnotes.conn.sql("""select account, ifnull(debit, 0), ifnull(credit, 0) pr = webnotes.bean(copy=test_records[0])
from `tabGL Entry` where voucher_no = %s""", dl.doclist[0].name) pr.run_method("calculate_taxes_and_totals")
pr.insert()
pr.submit()
gle_map = dict(((entry[0], entry) for entry in gle)) gl_entries = webnotes.conn.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type='Purchase Receipt' and voucher_no=%s
order by account desc""", pr.doc.name, as_dict=1)
self.assertEquals(gle_map[debit_account], (debit_account, stock_value, 0.0)) self.assertTrue(gl_entries)
self.assertEquals(gle_map[credit_account], (credit_account, 0.0, stock_value))
def atest_subcontracting(self): stock_in_hand_account = webnotes.conn.get_value("Company", pr.doc.company,
pr = base_purchase_receipt.copy() "stock_in_hand_account")
pr[1].update({"item_code": "Nebula 7"})
self.run_purchase_receipt_test(pr, expected_values = [
"Stock In Hand - %s" % (abbr,), [stock_in_hand_account, 750.0, 0.0],
"Stock Received But Not Billed - %s" % (abbr,), 1750.0) ["Stock Received But Not Billed - _TC", 0.0, 750.0]
]
def tearDown(self): for i, gle in enumerate(gl_entries):
webnotes.conn.rollback() self.assertEquals(expected_values[i][0], gle.account)
self.assertEquals(expected_values[i][1], gle.debit)
self.assertEquals(expected_values[i][2], gle.credit)
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
test_records = [
[
{
"company": "_Test Company",
"conversion_rate": 1.0,
"currency": "INR",
"doctype": "Purchase Receipt",
"fiscal_year": "_Test Fiscal Year 2013",
"posting_date": "2013-02-12",
"posting_time": "15:33:30",
"supplier": "_Test Supplier",
"net_total": 500.0,
"grand_total": 720.0,
},
{
"conversion_factor": 1.0,
"description": "_Test Item",
"doctype": "Purchase Receipt Item",
"item_code": "_Test Item",
"item_name": "_Test Item",
"parentfield": "purchase_receipt_details",
"received_qty": 10.0,
"qty": 10.0,
"rejected_qty": 0.0,
"import_rate": 50.0,
"amount": 500.0,
"warehouse": "_Test Warehouse",
"stock_uom": "Nos",
"uom": "_Test UOM",
},
{
"account_head": "_Test Account Shipping Charges - _TC",
"add_deduct_tax": "Add",
"category": "Valuation and Total",
"charge_type": "Actual",
"description": "Shipping Charges",
"doctype": "Purchase Taxes and Charges",
"parentfield": "purchase_tax_details",
"rate": 100.0,
"tax_amount": 100.0,
},
{
"account_head": "_Test Account VAT - _TC",
"add_deduct_tax": "Add",
"category": "Total",
"charge_type": "Actual",
"description": "VAT",
"doctype": "Purchase Taxes and Charges",
"parentfield": "purchase_tax_details",
"rate": 120.0,
"tax_amount": 120.0,
},
{
"account_head": "_Test Account Customs Duty - _TC",
"add_deduct_tax": "Add",
"category": "Valuation",
"charge_type": "Actual",
"description": "Customs Duty",
"doctype": "Purchase Taxes and Charges",
"parentfield": "purchase_tax_details",
"rate": 150.0,
"tax_amount": 150.0,
},
],
]