Merge branch 'master' of https://github.com/webnotes/erpnext
Conflicts: controllers/buying_controller.py
This commit is contained in:
commit
076535d979
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-01-10 16:34:06",
|
"creation": "2013-01-22 16:50:25",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-01-22 14:46:59",
|
"modified": "2013-03-13 12:29:40",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -23,7 +23,6 @@
|
|||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"doctype": "DocPerm",
|
"doctype": "DocPerm",
|
||||||
@ -42,22 +41,6 @@
|
|||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"name": "Fiscal Year"
|
"name": "Fiscal Year"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "year_details",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Fiscal Year Details",
|
|
||||||
"oldfieldtype": "Section Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "trash_reason",
|
|
||||||
"fieldtype": "Small Text",
|
|
||||||
"label": "Trash Reason",
|
|
||||||
"oldfieldname": "trash_reason",
|
|
||||||
"oldfieldtype": "Small Text",
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "For e.g. 2012, 2012-13",
|
"description": "For e.g. 2012, 2012-13",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@ -73,6 +56,7 @@
|
|||||||
"fieldname": "year_start_date",
|
"fieldname": "year_start_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Year Start Date",
|
"label": "Year Start Date",
|
||||||
|
"no_copy": 1,
|
||||||
"oldfieldname": "year_start_date",
|
"oldfieldname": "year_start_date",
|
||||||
"oldfieldtype": "Date",
|
"oldfieldtype": "Date",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
@ -84,6 +68,7 @@
|
|||||||
"fieldname": "is_fiscal_year_closed",
|
"fieldname": "is_fiscal_year_closed",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Year Closed",
|
"label": "Year Closed",
|
||||||
|
"no_copy": 1,
|
||||||
"oldfieldname": "is_fiscal_year_closed",
|
"oldfieldname": "is_fiscal_year_closed",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "\nNo\nYes",
|
"options": "\nNo\nYes",
|
||||||
|
@ -238,8 +238,11 @@ cur_frm.cscript.expense_head = function(doc, cdt, cdn){
|
|||||||
refresh_field('entries');
|
refresh_field('entries');
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.fields_dict['entries'].grid.get_field("cost_center").get_query = function(doc) {
|
cur_frm.fields_dict["entries"].grid.get_field("cost_center").get_query = function(doc) {
|
||||||
return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.`company_name` = "' +doc.company+'" AND `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.docstatus != 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50';
|
return {
|
||||||
|
query: "accounts.utils.get_cost_center_list",
|
||||||
|
filters: { company_name: doc.company}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.cost_center = function(doc, cdt, cdn){
|
cur_frm.cscript.cost_center = function(doc, cdt, cdn){
|
||||||
|
@ -444,6 +444,9 @@ class DocType(BuyingController):
|
|||||||
|
|
||||||
# item gl entries
|
# item gl entries
|
||||||
stock_item_and_auto_inventory_accounting = False
|
stock_item_and_auto_inventory_accounting = False
|
||||||
|
if auto_inventory_accounting:
|
||||||
|
stock_acocunt = self.get_default_account("stock_received_but_not_billed")
|
||||||
|
|
||||||
for item in self.doclist.get({"parentfield": "entries"}):
|
for item in self.doclist.get({"parentfield": "entries"}):
|
||||||
if auto_inventory_accounting and item.item_code in self.stock_items:
|
if auto_inventory_accounting and item.item_code in self.stock_items:
|
||||||
if flt(item.valuation_rate):
|
if flt(item.valuation_rate):
|
||||||
@ -455,7 +458,7 @@ class DocType(BuyingController):
|
|||||||
|
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": "Stock Received But Not Billed - %s" % (self.company_abbr,),
|
"account": stock_acocunt,
|
||||||
"against": self.doc.credit_to,
|
"against": self.doc.credit_to,
|
||||||
"debit": flt(item.valuation_rate) * flt(item.conversion_factor) \
|
"debit": flt(item.valuation_rate) * flt(item.conversion_factor) \
|
||||||
* flt(item.qty),
|
* flt(item.qty),
|
||||||
@ -480,7 +483,7 @@ class DocType(BuyingController):
|
|||||||
# this will balance out valuation amount included in cost of goods sold
|
# this will balance out valuation amount included in cost of goods sold
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": "Expenses Included In Valuation - %s" % (self.company_abbr,),
|
"account": self.get_default_account("expenses_included_in_valuation"),
|
||||||
"cost_center": "Auto Inventory Accounting - %s" % self.company_abbr,
|
"cost_center": "Auto Inventory Accounting - %s" % self.company_abbr,
|
||||||
"against": self.doc.credit_to,
|
"against": self.doc.credit_to,
|
||||||
"credit": valuation_tax,
|
"credit": valuation_tax,
|
||||||
|
@ -271,8 +271,6 @@ cur_frm.cscript.is_opening = function(doc, dt, dn) {
|
|||||||
if (doc.is_opening == 'Yes') unhide_field('aging_date');
|
if (doc.is_opening == 'Yes') unhide_field('aging_date');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* **************************** TRIGGERS ********************************** */
|
|
||||||
|
|
||||||
// Get Items based on SO or DN Selected
|
// Get Items based on SO or DN Selected
|
||||||
cur_frm.cscript.get_items = function(doc, dt, dn) {
|
cur_frm.cscript.get_items = function(doc, dt, dn) {
|
||||||
var callback = function(r,rt) {
|
var callback = function(r,rt) {
|
||||||
@ -371,6 +369,18 @@ cur_frm.set_query("income_account", "entries", function(doc) {
|
|||||||
return 'SELECT tabAccount.name FROM tabAccount WHERE (tabAccount.debit_or_credit="Credit" OR tabAccount.account_type = "Income Account") AND tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus!=2 AND tabAccount.company="'+doc.company+'" AND tabAccount.%(key)s LIKE "%s"';
|
return 'SELECT tabAccount.name FROM tabAccount WHERE (tabAccount.debit_or_credit="Credit" OR tabAccount.account_type = "Income Account") AND tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus!=2 AND tabAccount.company="'+doc.company+'" AND tabAccount.%(key)s LIKE "%s"';
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// expense account
|
||||||
|
cur_frm.fields_dict['entries'].grid.get_field('expense_account').get_query = function(doc) {
|
||||||
|
return {
|
||||||
|
"query": "accounts.utils.get_account_list",
|
||||||
|
"filters": {
|
||||||
|
"is_pl_account": "Yes",
|
||||||
|
"debit_or_credit": "Debit",
|
||||||
|
"company": doc.company
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// warehouse in detail table
|
// warehouse in detail table
|
||||||
//----------------------------
|
//----------------------------
|
||||||
cur_frm.fields_dict['entries'].grid.get_field('warehouse').get_query= function(doc, cdt, cdn) {
|
cur_frm.fields_dict['entries'].grid.get_field('warehouse').get_query= function(doc, cdt, cdn) {
|
||||||
@ -380,8 +390,11 @@ cur_frm.fields_dict['entries'].grid.get_field('warehouse').get_query= function(d
|
|||||||
|
|
||||||
// Cost Center in Details Table
|
// Cost Center in Details Table
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
cur_frm.fields_dict.entries.grid.get_field("cost_center").get_query = function(doc) {
|
cur_frm.fields_dict["entries"].grid.get_field("cost_center").get_query = function(doc) {
|
||||||
return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.`company_name` = "' +doc.company+'" AND `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.`docstatus`!= 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50';
|
return {
|
||||||
|
query: "accounts.utils.get_cost_center_list",
|
||||||
|
filters: { company_name: doc.company}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sales Order
|
// Sales Order
|
||||||
|
@ -704,9 +704,9 @@ class DocType(SellingController):
|
|||||||
|
|
||||||
if auto_inventory_accounting:
|
if auto_inventory_accounting:
|
||||||
if cint(self.doc.is_pos) and cint(self.doc.update_stock):
|
if cint(self.doc.is_pos) and cint(self.doc.update_stock):
|
||||||
stock_account = self.get_stock_in_hand_account()
|
stock_account = self.get_default_account("stock_in_hand_account")
|
||||||
else:
|
else:
|
||||||
stock_account = "Stock Delivered But Not Billed - %s" % (self.company_abbr,)
|
stock_account = self.get_default_account("stock_delivered_but_not_billed")
|
||||||
|
|
||||||
for item in self.doclist.get({"parentfield": "entries"}):
|
for item in self.doclist.get({"parentfield": "entries"}):
|
||||||
# income account gl entries
|
# income account gl entries
|
||||||
@ -794,7 +794,8 @@ class DocType(SellingController):
|
|||||||
stock_ledger_entries = item_sales_bom = None
|
stock_ledger_entries = item_sales_bom = None
|
||||||
|
|
||||||
for item in self.doclist.get({"parentfield": "entries"}):
|
for item in self.doclist.get({"parentfield": "entries"}):
|
||||||
if item.item_code in self.stock_items:
|
if item.item_code in self.stock_items or \
|
||||||
|
(item_sales_bom and item_sales_bom.get(item.item_code)):
|
||||||
item.buying_amount = self.get_item_buying_amount(item, stock_ledger_entries,
|
item.buying_amount = self.get_item_buying_amount(item, stock_ledger_entries,
|
||||||
item_sales_bom)
|
item_sales_bom)
|
||||||
webnotes.conn.set_value("Sales Invoice Item", item.name,
|
webnotes.conn.set_value("Sales Invoice Item", item.name,
|
||||||
@ -804,8 +805,9 @@ class DocType(SellingController):
|
|||||||
item_buying_amount = 0
|
item_buying_amount = 0
|
||||||
if stock_ledger_entries:
|
if stock_ledger_entries:
|
||||||
# is pos and update stock
|
# is pos and update stock
|
||||||
item_buying_amount = get_buying_amount(item.item_code, item.warehouse, item.qty,
|
item_buying_amount = get_buying_amount(item.item_code, item.warehouse, -1*item.qty,
|
||||||
self.doc.doctype, self.doc.name, item.name, stock_ledger_entries, item_sales_bom)
|
self.doc.doctype, self.doc.name, item.name, stock_ledger_entries, item_sales_bom)
|
||||||
|
item.buying_amount = item_buying_amount > 0 and item_buying_amount or 0
|
||||||
elif item.delivery_note and item.dn_detail:
|
elif item.delivery_note and item.dn_detail:
|
||||||
# against delivery note
|
# against delivery note
|
||||||
dn_item = webnotes.conn.get_value("Delivery Note Item", item.dn_detail,
|
dn_item = webnotes.conn.get_value("Delivery Note Item", item.dn_detail,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-03-07 11:42:55",
|
"creation": "2013-03-07 11:42:55",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-03-11 14:58:50",
|
"modified": "2013-03-18 15:41:19",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -207,14 +207,16 @@
|
|||||||
"width": "120px"
|
"width": "120px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:sys_defaults.auto_inventory_accounting",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "expense_account",
|
"fieldname": "expense_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 1,
|
"hidden": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
"label": "Expense Account",
|
"label": "Expense Account",
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
"print_hide": 1
|
"print_hide": 1,
|
||||||
|
"width": "120px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
|
@ -24,8 +24,10 @@ def execute(filters=None):
|
|||||||
data = []
|
data = []
|
||||||
for row in delivery_note_items:
|
for row in delivery_note_items:
|
||||||
selling_amount = flt(row.amount)
|
selling_amount = flt(row.amount)
|
||||||
buying_amount = get_buying_amount(row.item_code, row.warehouse,
|
buying_amount = get_buying_amount(row.item_code, row.warehouse, -1*row.qty,
|
||||||
row.qty, "Delivery Note", row.name, row.item_row, stock_ledger_entries, item_sales_bom)
|
"Delivery Note", row.name, row.item_row, stock_ledger_entries, item_sales_bom)
|
||||||
|
buying_amount = buying_amount > 0 and buying_amount or 0
|
||||||
|
|
||||||
if selling_amount:
|
if selling_amount:
|
||||||
gross_profit = selling_amount - buying_amount
|
gross_profit = selling_amount - buying_amount
|
||||||
gross_profit_percent = (gross_profit / selling_amount) * 100.0
|
gross_profit_percent = (gross_profit / selling_amount) * 100.0
|
||||||
|
@ -18,6 +18,7 @@ from __future__ import unicode_literals
|
|||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import msgprint, _
|
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
|
||||||
|
|
||||||
class AccountsController(TransactionBase):
|
class AccountsController(TransactionBase):
|
||||||
@ -75,15 +76,14 @@ class AccountsController(TransactionBase):
|
|||||||
"allocate_amount": 0
|
"allocate_amount": 0
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_stock_in_hand_account(self):
|
def get_default_account(self, account_for):
|
||||||
stock_in_hand_account = webnotes.conn.get_value("Company", self.doc.company, "stock_in_hand_account")
|
account = webnotes.conn.get_value("Company", self.doc.company, account_for)
|
||||||
|
if not account:
|
||||||
|
msgprint(_("Please mention default account for '") +
|
||||||
|
_(webnotes.get_doctype("company").get_label(account_for) +
|
||||||
|
_("' in Company: ") + self.doc.company), raise_exception=True)
|
||||||
|
|
||||||
if not stock_in_hand_account:
|
return 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
|
@property
|
||||||
def stock_items(self):
|
def stock_items(self):
|
||||||
@ -101,3 +101,8 @@ class AccountsController(TransactionBase):
|
|||||||
self._abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
|
self._abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
|
||||||
|
|
||||||
return self._abbr
|
return self._abbr
|
||||||
|
|
||||||
|
|
||||||
|
@webnotes.whitelist()
|
||||||
|
def get_default_account(account_for, company):
|
||||||
|
return webnotes.conn.get_value("Company", company, account_for)
|
||||||
|
@ -24,9 +24,9 @@ from buying.utils import get_item_details
|
|||||||
from setup.utils import get_company_currency
|
from setup.utils import get_company_currency
|
||||||
from webnotes.model.utils import round_floats_in_doc
|
from webnotes.model.utils import round_floats_in_doc
|
||||||
|
|
||||||
from controllers.accounts_controller import AccountsController
|
from controllers.stock_controller import StockController
|
||||||
|
|
||||||
class BuyingController(AccountsController):
|
class BuyingController(StockController):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
super(BuyingController, self).validate()
|
super(BuyingController, self).validate()
|
||||||
if self.meta.get_field("currency"):
|
if self.meta.get_field("currency"):
|
||||||
|
@ -19,9 +19,9 @@ import webnotes
|
|||||||
from webnotes.utils import cint
|
from webnotes.utils import cint
|
||||||
from setup.utils import get_company_currency
|
from setup.utils import get_company_currency
|
||||||
|
|
||||||
from controllers.accounts_controller import AccountsController
|
from controllers.stock_controller import StockController
|
||||||
|
|
||||||
class SellingController(AccountsController):
|
class SellingController(StockController):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
super(SellingController, self).validate()
|
super(SellingController, self).validate()
|
||||||
self.set_total_in_words()
|
self.set_total_in_words()
|
||||||
@ -39,26 +39,3 @@ class SellingController(AccountsController):
|
|||||||
if self.meta.get_field("in_words_export"):
|
if self.meta.get_field("in_words_export"):
|
||||||
self.doc.in_words_export = money_in_words(disable_rounded_total and
|
self.doc.in_words_export = money_in_words(disable_rounded_total and
|
||||||
self.doc.grand_total_export or self.doc.rounded_total_export, self.doc.currency)
|
self.doc.grand_total_export or self.doc.rounded_total_export, self.doc.currency)
|
||||||
|
|
||||||
def get_stock_ledger_entries(self):
|
|
||||||
item_list, warehouse_list = self.get_distinct_item_warehouse()
|
|
||||||
if item_list and warehouse_list:
|
|
||||||
return webnotes.conn.sql("""select item_code, voucher_type, voucher_no,
|
|
||||||
voucher_detail_no, posting_date, posting_time, stock_value,
|
|
||||||
warehouse, actual_qty as qty from `tabStock Ledger Entry`
|
|
||||||
where ifnull(`is_cancelled`, "No") = "No" and company = %s
|
|
||||||
and item_code in (%s) and warehouse in (%s)
|
|
||||||
order by item_code desc, warehouse desc, posting_date desc,
|
|
||||||
posting_time desc, name desc""" %
|
|
||||||
('%s', ', '.join(['%s']*len(item_list)), ', '.join(['%s']*len(warehouse_list))),
|
|
||||||
tuple([self.doc.company] + item_list + warehouse_list), as_dict=1)
|
|
||||||
|
|
||||||
def get_distinct_item_warehouse(self):
|
|
||||||
item_list = []
|
|
||||||
warehouse_list = []
|
|
||||||
for item in self.doclist.get({"parentfield": self.fname}) \
|
|
||||||
+ self.doclist.get({"parentfield": "packing_details"}):
|
|
||||||
item_list.append(item.item_code)
|
|
||||||
warehouse_list.append(item.warehouse)
|
|
||||||
|
|
||||||
return list(set(item_list)), list(set(warehouse_list))
|
|
71
controllers/stock_controller.py
Normal file
71
controllers/stock_controller.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# ERPNext - web based ERP (http://erpnext.com)
|
||||||
|
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import webnotes
|
||||||
|
from controllers.accounts_controller import AccountsController
|
||||||
|
|
||||||
|
class StockController(AccountsController):
|
||||||
|
def make_gl_entries(self, against_stock_account, amount, cost_center=None):
|
||||||
|
stock_in_hand_account = self.get_default_account("stock_in_hand_account")
|
||||||
|
|
||||||
|
if amount:
|
||||||
|
gl_entries = [
|
||||||
|
# stock in hand account
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": stock_in_hand_account,
|
||||||
|
"against": against_stock_account,
|
||||||
|
"debit": amount,
|
||||||
|
"remarks": self.doc.remarks or "Accounting Entry for Stock",
|
||||||
|
}, self.doc.docstatus == 2),
|
||||||
|
|
||||||
|
# account against stock in hand
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": against_stock_account,
|
||||||
|
"against": stock_in_hand_account,
|
||||||
|
"credit": amount,
|
||||||
|
"cost_center": cost_center or None,
|
||||||
|
"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_stock_ledger_entries(self, item_list=None, warehouse_list=None):
|
||||||
|
if not (item_list and warehouse_list):
|
||||||
|
item_list, warehouse_list = self.get_distinct_item_warehouse()
|
||||||
|
|
||||||
|
if item_list and warehouse_list:
|
||||||
|
return webnotes.conn.sql("""select item_code, voucher_type, voucher_no,
|
||||||
|
voucher_detail_no, posting_date, posting_time, stock_value,
|
||||||
|
warehouse, actual_qty as qty from `tabStock Ledger Entry`
|
||||||
|
where ifnull(`is_cancelled`, "No") = "No" and company = %s
|
||||||
|
and item_code in (%s) and warehouse in (%s)
|
||||||
|
order by item_code desc, warehouse desc, posting_date desc,
|
||||||
|
posting_time desc, name desc""" %
|
||||||
|
('%s', ', '.join(['%s']*len(item_list)), ', '.join(['%s']*len(warehouse_list))),
|
||||||
|
tuple([self.doc.company] + item_list + warehouse_list), as_dict=1)
|
||||||
|
|
||||||
|
def get_distinct_item_warehouse(self):
|
||||||
|
item_list = []
|
||||||
|
warehouse_list = []
|
||||||
|
for item in self.doclist.get({"parentfield": self.fname}) \
|
||||||
|
+ self.doclist.get({"parentfield": "packing_details"}):
|
||||||
|
item_list.append(item.item_code)
|
||||||
|
warehouse_list.append(item.warehouse)
|
||||||
|
|
||||||
|
return list(set(item_list)), list(set(warehouse_list))
|
@ -58,3 +58,43 @@ cur_frm.fields_dict.receivables_group.get_query = function(doc) {
|
|||||||
cur_frm.fields_dict.payables_group.get_query = function(doc) {
|
cur_frm.fields_dict.payables_group.get_query = function(doc) {
|
||||||
return 'SELECT `tabAccount`.name FROM `tabAccount` WHERE `tabAccount`.company = "'+doc.name+'" AND `tabAccount`.group_or_ledger = "Group" AND `tabAccount`.docstatus != 2 AND `tabAccount`.%(key)s LIKE "%s" ORDER BY `tabAccount`.name LIMIT 50';
|
return 'SELECT `tabAccount`.name FROM `tabAccount` WHERE `tabAccount`.company = "'+doc.name+'" AND `tabAccount`.group_or_ledger = "Group" AND `tabAccount`.docstatus != 2 AND `tabAccount`.%(key)s LIKE "%s" ORDER BY `tabAccount`.name LIMIT 50';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cur_frm.fields_dict["stock_in_hand_account"].get_query = function(doc) {
|
||||||
|
return {
|
||||||
|
"query": "accounts.utils.get_account_list",
|
||||||
|
"filters": {
|
||||||
|
"is_pl_account": "No",
|
||||||
|
"debit_or_credit": "Debit",
|
||||||
|
"company": doc.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_frm.fields_dict["stock_adjustment_account"].get_query = function(doc) {
|
||||||
|
return {
|
||||||
|
"query": "accounts.utils.get_account_list",
|
||||||
|
"filters": {
|
||||||
|
"is_pl_account": "Yes",
|
||||||
|
"debit_or_credit": "Debit",
|
||||||
|
"company": doc.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_frm.fields_dict["expenses_included_in_valuation"].get_query =
|
||||||
|
cur_frm.fields_dict["stock_adjustment_account"].get_query;
|
||||||
|
|
||||||
|
cur_frm.fields_dict["stock_delivered_but_not_billed"].get_query =
|
||||||
|
cur_frm.fields_dict["stock_in_hand_account"].get_query;
|
||||||
|
|
||||||
|
cur_frm.fields_dict["stock_received_but_not_billed"].get_query = function(doc) {
|
||||||
|
return {
|
||||||
|
"query": "accounts.utils.get_account_list",
|
||||||
|
"filters": {
|
||||||
|
"is_pl_account": "No",
|
||||||
|
"debit_or_credit": "Credit",
|
||||||
|
"company": doc.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
|
|
||||||
from webnotes.utils import cstr, set_default
|
from webnotes.utils import cstr
|
||||||
from webnotes.model.doc import Document
|
from webnotes.model.doc import Document
|
||||||
from webnotes.model.code import get_obj
|
from webnotes.model.code import get_obj
|
||||||
import webnotes.defaults
|
import webnotes.defaults
|
||||||
@ -47,10 +47,11 @@ class DocType:
|
|||||||
['Loans and Advances (Assets)','Current Assets','Group','No','','Debit',self.doc.name,''],
|
['Loans and Advances (Assets)','Current Assets','Group','No','','Debit',self.doc.name,''],
|
||||||
['Securities and Deposits','Current Assets','Group','No','','Debit',self.doc.name,''],
|
['Securities and Deposits','Current Assets','Group','No','','Debit',self.doc.name,''],
|
||||||
['Earnest Money','Securities and Deposits','Ledger','No','','Debit',self.doc.name,''],
|
['Earnest Money','Securities and Deposits','Ledger','No','','Debit',self.doc.name,''],
|
||||||
['Stock In Hand','Current Assets','Group','No','','Debit',self.doc.name,''],
|
['Stock Assets','Current Assets','Group','No','','Debit',self.doc.name,''],
|
||||||
['Stock','Stock In Hand','Ledger','No','','Debit',self.doc.name,''],
|
['Stock In Hand','Stock Assets','Ledger','No','','Debit',self.doc.name,''],
|
||||||
|
['Stock Delivered But Not Billed', 'Stock Assets', '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,''],
|
||||||
@ -62,9 +63,10 @@ class DocType:
|
|||||||
['Temporary Account (Assets)','Temporary Accounts (Assets)','Ledger','No','','Debit',self.doc.name,''],
|
['Temporary Account (Assets)','Temporary Accounts (Assets)','Ledger','No','','Debit',self.doc.name,''],
|
||||||
['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,''],
|
['Stock Expenses','Direct Expenses','Group','Yes','Expense Account','Debit',self.doc.name,''],
|
||||||
['Expenses Included In Valuation','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
|
['Cost of Goods Sold','Stock Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
|
||||||
['Stock Adjustment','Direct Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
|
['Stock Adjustment','Stock Expenses','Ledger','Yes','Expense Account','Debit',self.doc.name,''],
|
||||||
|
['Expenses Included In Valuation', "Stock 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,''],
|
||||||
@ -101,12 +103,14 @@ class DocType:
|
|||||||
['Shareholders Funds','Capital Account','Group','No','','Credit',self.doc.name,''],
|
['Shareholders Funds','Capital Account','Group','No','','Credit',self.doc.name,''],
|
||||||
['Current Liabilities','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''],
|
['Current Liabilities','Source of Funds (Liabilities)','Group','No','','Credit',self.doc.name,''],
|
||||||
['Accounts Payable','Current Liabilities','Group','No','','Credit',self.doc.name,''],
|
['Accounts Payable','Current Liabilities','Group','No','','Credit',self.doc.name,''],
|
||||||
|
['Stock Liabilities','Current Liabilities','Group','No','','Credit',self.doc.name,''],
|
||||||
|
['Stock Received But Not Billed', 'Stock Liabilities', 'Ledger',
|
||||||
|
'No', '', 'Credit', self.doc.name, ''],
|
||||||
['Duties and Taxes','Current Liabilities','Group','No','','Credit',self.doc.name,''],
|
['Duties and Taxes','Current Liabilities','Group','No','','Credit',self.doc.name,''],
|
||||||
['Loans (Liabilities)','Current Liabilities','Group','No','','Credit',self.doc.name,''],
|
['Loans (Liabilities)','Current Liabilities','Group','No','','Credit',self.doc.name,''],
|
||||||
['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,'']
|
||||||
]
|
]
|
||||||
@ -186,14 +190,35 @@ class DocType:
|
|||||||
|
|
||||||
self.doc.letter_head = header
|
self.doc.letter_head = header
|
||||||
|
|
||||||
# Set default AR and AP group
|
def set_default_accounts(self):
|
||||||
# ---------------------------------------------------
|
if not self.doc.receivables_group and webnotes.conn.exists('Account',
|
||||||
def set_default_groups(self):
|
'Accounts Receivable - ' + self.doc.abbr):
|
||||||
if not self.doc.receivables_group:
|
webnotes.conn.set(self.doc, 'receivables_group', 'Accounts Receivable - ' +
|
||||||
webnotes.conn.set(self.doc, 'receivables_group', 'Accounts Receivable - '+self.doc.abbr)
|
self.doc.abbr)
|
||||||
if not self.doc.payables_group:
|
|
||||||
webnotes.conn.set(self.doc, 'payables_group', 'Accounts Payable - '+self.doc.abbr)
|
|
||||||
|
|
||||||
|
if not self.doc.payables_group and webnotes.conn.exists('Account',
|
||||||
|
'Accounts Payable - ' + self.doc.abbr):
|
||||||
|
webnotes.conn.set(self.doc, 'payables_group', 'Accounts Payable - ' + self.doc.abbr)
|
||||||
|
|
||||||
|
if not self.doc.stock_delivered_but_not_billed and webnotes.conn.exists("Account",
|
||||||
|
"Stock Delivered But Not Billed - " + self.doc.abbr):
|
||||||
|
webnotes.conn.set(self.doc, "stock_delivered_but_not_billed",
|
||||||
|
"Stock Delivered But Not Billed - " + self.doc.abbr)
|
||||||
|
|
||||||
|
if not self.doc.stock_received_but_not_billed and webnotes.conn.exists("Account",
|
||||||
|
"Stock Received But Not Billed - " + self.doc.abbr):
|
||||||
|
webnotes.conn.set(self.doc, "stock_received_but_not_billed",
|
||||||
|
"Stock Received But Not Billed - " + self.doc.abbr)
|
||||||
|
|
||||||
|
if not self.doc.stock_adjustment_account and webnotes.conn.exists("Account",
|
||||||
|
"Stock Adjustment - " + self.doc.abbr):
|
||||||
|
webnotes.conn.set(self.doc, "stock_adjustment_account", "Stock Adjustment - " +
|
||||||
|
self.doc.abbr)
|
||||||
|
|
||||||
|
if not self.doc.expenses_included_in_valuation and webnotes.conn.exists("Account",
|
||||||
|
"Expenses Included In Valuation - " + self.doc.abbr):
|
||||||
|
webnotes.conn.set(self.doc, "expenses_included_in_valuation",
|
||||||
|
"Expenses Included In Valuation - " + self.doc.abbr)
|
||||||
|
|
||||||
# Create default cost center
|
# Create default cost center
|
||||||
# ---------------------------------------------------
|
# ---------------------------------------------------
|
||||||
@ -228,7 +253,7 @@ class DocType:
|
|||||||
self.doc.name)
|
self.doc.name)
|
||||||
if not ac:
|
if not ac:
|
||||||
self.create_default_accounts()
|
self.create_default_accounts()
|
||||||
self.set_default_groups()
|
self.set_default_accounts()
|
||||||
cc = sql("select name from `tabCost Center` where cost_center_name = 'Root' and company_name = '%s'"%(self.doc.name))
|
cc = sql("select name from `tabCost Center` where cost_center_name = 'Root' and company_name = '%s'"%(self.doc.name))
|
||||||
if not cc:
|
if not cc:
|
||||||
self.create_default_cost_center()
|
self.create_default_cost_center()
|
||||||
@ -258,9 +283,6 @@ class DocType:
|
|||||||
#update value as blank for tabSingles Global Defaults
|
#update value as blank for tabSingles Global Defaults
|
||||||
sql("update `tabSingles` set value = '' where doctype='Global Defaults' and field = 'default_company' and value = %s", self.doc.name)
|
sql("update `tabSingles` set value = '' where doctype='Global Defaults' and field = 'default_company' and value = %s", self.doc.name)
|
||||||
|
|
||||||
|
|
||||||
# on rename
|
|
||||||
# ---------
|
|
||||||
def on_rename(self,newdn,olddn):
|
def on_rename(self,newdn,olddn):
|
||||||
sql("update `tabCompany` set company_name = '%s' where name = '%s'" %(newdn,olddn))
|
sql("update `tabCompany` set company_name = '%s' where name = '%s'" %(newdn,olddn))
|
||||||
sql("update `tabSingles` set value = %s where doctype='Global Defaults' and field = 'default_company' and value = %s", (newdn, olddn))
|
sql("update `tabSingles` set value = %s where doctype='Global Defaults' and field = 'default_company' and value = %s", (newdn, olddn))
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-02-22 01:27:54",
|
"creation": "2013-02-27 09:38:05",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-02-26 10:57:39",
|
"modified": "2013-03-19 12:52:00",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -124,17 +124,6 @@
|
|||||||
"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",
|
||||||
@ -181,6 +170,57 @@
|
|||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "\nWarn\nIgnore\nStop"
|
"options": "\nWarn\nIgnore\nStop"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:!doc.__islocal && sys_defaults.auto_inventory_accounting",
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "auto_inventory_accounting_settings",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Auto Inventory Accounting Settings"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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",
|
||||||
|
"fieldname": "stock_adjustment_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Stock Adjustment Account",
|
||||||
|
"options": "Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "expenses_included_in_valuation",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Expenses Included In Valuation",
|
||||||
|
"options": "Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "col_break23",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"width": "50%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "stock_delivered_but_not_billed",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Stock Delivered But Not Billed",
|
||||||
|
"options": "Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "stock_received_but_not_billed",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Stock Received But Not Billed",
|
||||||
|
"options": "Account"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "For reference only.",
|
"description": "For reference only.",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-03-08 15:37:09",
|
"creation": "2013-02-21 14:54:43",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-03-12 18:48:53",
|
"modified": "2013-03-19 14:46:49",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -410,7 +410,7 @@
|
|||||||
"fieldname": "emp_created_by",
|
"fieldname": "emp_created_by",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Employee Records to be created by ",
|
"label": "Employee Records to be created by ",
|
||||||
"options": "\nNaming Series\nEmployee Number"
|
"options": "Naming Series\nEmployee Number"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
|
@ -16,15 +16,8 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import _
|
from webnotes.utils import add_days, cint,flt, nowdate, get_url_to_form, formatdate
|
||||||
|
from webnotes import msgprint, _
|
||||||
from webnotes.utils import add_days, cint, cstr, flt, now, nowdate, \
|
|
||||||
get_url_to_form, formatdate
|
|
||||||
from webnotes.model import db_exists
|
|
||||||
from webnotes.model.doc import Document, addchild
|
|
||||||
from webnotes.model.bean import copy_doclist
|
|
||||||
from webnotes.model.code import get_obj
|
|
||||||
from webnotes import msgprint
|
|
||||||
sql = webnotes.conn.sql
|
sql = webnotes.conn.sql
|
||||||
|
|
||||||
import webnotes.defaults
|
import webnotes.defaults
|
||||||
@ -61,7 +54,7 @@ class DocType:
|
|||||||
from stock.stock_ledger import update_entries_after
|
from stock.stock_ledger import update_entries_after
|
||||||
|
|
||||||
if not args.get("posting_date"):
|
if not args.get("posting_date"):
|
||||||
posting_date = nowdate()
|
args["posting_date"] = nowdate()
|
||||||
|
|
||||||
# update valuation and qty after transaction for post dated entry
|
# update valuation and qty after transaction for post dated entry
|
||||||
update_entries_after({
|
update_entries_after({
|
||||||
@ -108,11 +101,10 @@ class DocType:
|
|||||||
#check if re-order is required
|
#check if re-order is required
|
||||||
item_reorder = webnotes.conn.get("Item Reorder",
|
item_reorder = webnotes.conn.get("Item Reorder",
|
||||||
{"parent": self.doc.item_code, "warehouse": self.doc.warehouse})
|
{"parent": self.doc.item_code, "warehouse": self.doc.warehouse})
|
||||||
|
|
||||||
if item_reorder:
|
if item_reorder:
|
||||||
reorder_level = item_reorder.warehouse_reorder_level
|
reorder_level = item_reorder.warehouse_reorder_level
|
||||||
reorder_qty = item_reorder.warehouse_reorder_qty
|
reorder_qty = item_reorder.warehouse_reorder_qty
|
||||||
material_request_type = item_reorder.material_request_type
|
material_request_type = item_reorder.material_request_type or "Purchase"
|
||||||
else:
|
else:
|
||||||
reorder_level, reorder_qty = webnotes.conn.get_value("Item", self.doc.item_code,
|
reorder_level, reorder_qty = webnotes.conn.get_value("Item", self.doc.item_code,
|
||||||
["re_order_level", "re_order_qty"])
|
["re_order_level", "re_order_qty"])
|
||||||
@ -123,7 +115,7 @@ class DocType:
|
|||||||
material_request_type)
|
material_request_type)
|
||||||
|
|
||||||
def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty,
|
def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty,
|
||||||
material_request_type):
|
material_request_type="Purchase"):
|
||||||
""" Create indent on reaching reorder level """
|
""" Create indent on reaching reorder level """
|
||||||
defaults = webnotes.defaults.get_defaults()
|
defaults = webnotes.defaults.get_defaults()
|
||||||
item = webnotes.doc("Item", self.doc.item_code)
|
item = webnotes.doc("Item", self.doc.item_code)
|
||||||
@ -151,7 +143,6 @@ class DocType:
|
|||||||
"qty": reorder_qty,
|
"qty": reorder_qty,
|
||||||
"brand": item.brand,
|
"brand": item.brand,
|
||||||
}])
|
}])
|
||||||
|
|
||||||
mr.insert()
|
mr.insert()
|
||||||
mr.submit()
|
mr.submit()
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ from webnotes import msgprint
|
|||||||
|
|
||||||
sql = webnotes.conn.sql
|
sql = webnotes.conn.sql
|
||||||
|
|
||||||
|
|
||||||
from controllers.selling_controller import SellingController
|
from controllers.selling_controller import SellingController
|
||||||
|
|
||||||
class DocType(SellingController):
|
class DocType(SellingController):
|
||||||
@ -401,9 +400,12 @@ class DocType(SellingController):
|
|||||||
|
|
||||||
if stock_ledger_entries:
|
if stock_ledger_entries:
|
||||||
for item in self.doclist.get({"parentfield": "delivery_note_details"}):
|
for item in self.doclist.get({"parentfield": "delivery_note_details"}):
|
||||||
item.buying_amount = get_buying_amount(item.item_code, item.warehouse, item.qty,
|
if item.item_code in self.stock_items or \
|
||||||
|
(item_sales_bom and item_sales_bom.get(item.item_code)):
|
||||||
|
buying_amount = get_buying_amount(item.item_code, item.warehouse, -1*item.qty,
|
||||||
self.doc.doctype, self.doc.name, item.name, stock_ledger_entries,
|
self.doc.doctype, self.doc.name, item.name, stock_ledger_entries,
|
||||||
item_sales_bom)
|
item_sales_bom)
|
||||||
|
item.buying_amount = buying_amount > 0 and buying_amount or 0
|
||||||
webnotes.conn.set_value("Delivery Note Item", item.name, "buying_amount",
|
webnotes.conn.set_value("Delivery Note Item", item.name, "buying_amount",
|
||||||
item.buying_amount)
|
item.buying_amount)
|
||||||
|
|
||||||
@ -420,31 +422,10 @@ class DocType(SellingController):
|
|||||||
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
|
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
|
||||||
return
|
return
|
||||||
|
|
||||||
abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
|
against_stock_account = self.get_default_account("stock_delivered_but_not_billed")
|
||||||
stock_delivered_account = "Stock Delivered But Not Billed - %s" % (abbr,)
|
|
||||||
stock_in_hand_account = self.get_stock_in_hand_account()
|
|
||||||
|
|
||||||
total_buying_amount = self.get_total_buying_amount()
|
total_buying_amount = self.get_total_buying_amount()
|
||||||
if total_buying_amount:
|
|
||||||
gl_entries = [
|
|
||||||
# credit stock in hand account
|
|
||||||
self.get_gl_dict({
|
|
||||||
"account": stock_in_hand_account,
|
|
||||||
"against": stock_delivered_account,
|
|
||||||
"credit": total_buying_amount,
|
|
||||||
"remarks": self.doc.remarks or "Accounting Entry for Stock",
|
|
||||||
}, self.doc.docstatus == 2),
|
|
||||||
|
|
||||||
# debit stock received but not billed account
|
super(DocType, self).make_gl_entries(against_stock_account, -1*total_buying_amount)
|
||||||
self.get_gl_dict({
|
|
||||||
"account": stock_delivered_account,
|
|
||||||
"against": stock_in_hand_account,
|
|
||||||
"debit": total_buying_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_buying_amount(self):
|
def get_total_buying_amount(self):
|
||||||
total_buying_amount = sum([item.buying_amount for item in
|
total_buying_amount = sum([item.buying_amount for item in
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-02-22 01:28:01",
|
"creation": "2013-03-07 11:42:59",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-03-07 07:03:22",
|
"modified": "2013-03-19 12:22:44",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -20,7 +20,8 @@
|
|||||||
"parent": "Item Reorder",
|
"parent": "Item Reorder",
|
||||||
"parentfield": "fields",
|
"parentfield": "fields",
|
||||||
"parenttype": "DocType",
|
"parenttype": "DocType",
|
||||||
"permlevel": 0
|
"permlevel": 0,
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -38,7 +39,8 @@
|
|||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "warehouse_reorder_level",
|
"fieldname": "warehouse_reorder_level",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Re-order Level"
|
"label": "Re-order Level",
|
||||||
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@ -51,6 +53,7 @@
|
|||||||
"fieldname": "material_request_type",
|
"fieldname": "material_request_type",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Material Request Type",
|
"label": "Material Request Type",
|
||||||
"options": "Purchase\nTransfer"
|
"options": "Purchase\nTransfer",
|
||||||
|
"reqd": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -28,18 +28,10 @@ cur_frm.fields_dict['item_details'].grid.get_field('item_code').get_query = func
|
|||||||
|
|
||||||
|
|
||||||
// Fetch item details
|
// Fetch item details
|
||||||
cur_frm.cscript.item_code = function(doc, cdt, cdn) {
|
cur_frm.add_fetch("item_code", "item_name", "item_name");
|
||||||
if(locals[cdt][cdn].item_code) {
|
cur_frm.add_fetch("item_code", "stock_uom", "stock_uom");
|
||||||
$c_obj(make_doclist(cdt, cdn), 'get_item_details', doc.delivery_note, function(r, rt) {
|
cur_frm.add_fetch("item_code", "net_weight", "net_weight");
|
||||||
if(r.exc) {
|
cur_frm.add_fetch("item_code", "weight_uom", "weight_uom");
|
||||||
msgprint(r.exc);
|
|
||||||
} else {
|
|
||||||
refresh_field('item_details');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
|
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
|
||||||
if(doc.delivery_note && doc.__islocal) {
|
if(doc.delivery_note && doc.__islocal) {
|
||||||
|
@ -20,8 +20,7 @@ import webnotes
|
|||||||
from webnotes.utils import cstr, flt, cint
|
from webnotes.utils import cstr, flt, cint
|
||||||
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
|
||||||
from webnotes.model.doc import Document
|
from webnotes import msgprint
|
||||||
from webnotes import msgprint, _
|
|
||||||
|
|
||||||
sql = webnotes.conn.sql
|
sql = webnotes.conn.sql
|
||||||
|
|
||||||
@ -319,32 +318,10 @@ class DocType(BuyingController):
|
|||||||
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
|
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
|
||||||
return
|
return
|
||||||
|
|
||||||
abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
|
against_stock_account = self.get_default_account("stock_received_but_not_billed")
|
||||||
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()
|
total_valuation_amount = self.get_total_valuation_amount()
|
||||||
|
|
||||||
if total_valuation_amount:
|
super(DocType, self).make_gl_entries(against_stock_account, 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):
|
def get_total_valuation_amount(self):
|
||||||
total_valuation_amount = 0.0
|
total_valuation_amount = 0.0
|
||||||
|
@ -18,6 +18,33 @@ wn.require("public/app/js/controllers/stock_controller.js");
|
|||||||
wn.provide("erpnext.stock");
|
wn.provide("erpnext.stock");
|
||||||
|
|
||||||
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||||
|
onload: function() {
|
||||||
|
this.set_default_account();
|
||||||
|
},
|
||||||
|
|
||||||
|
set_default_account: function() {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if (sys_defaults.auto_inventory_accounting && !this.frm.doc.expense_adjustment_account) {
|
||||||
|
if (this.frm.doc.purpose == "Sales Return")
|
||||||
|
account_for = "stock_delivered_but_not_billed";
|
||||||
|
else if (this.frm.doc.purpose == "Purchase Return")
|
||||||
|
account_for = "stock_received_but_not_billed";
|
||||||
|
else account_for = "stock_adjustment_account";
|
||||||
|
|
||||||
|
this.frm.call({
|
||||||
|
method: "controllers.accounts_controller.get_default_account",
|
||||||
|
args: {
|
||||||
|
"account_for": account_for,
|
||||||
|
"company": this.frm.doc.company
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if (!r.exc) me.frm.set_value("expense_adjustment_account", r.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
setup: function() {
|
setup: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
@ -49,6 +76,16 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (sys_defaults.auto_inventory_accounting) {
|
||||||
|
this.frm.add_fetch("company", "expense_adjustment_account", "stock_adjustment_account");
|
||||||
|
|
||||||
|
this.frm.fields_dict["expense_adjustment_account"].get_query = function() {
|
||||||
|
return {
|
||||||
|
"query": "accounts.utils.get_account_list",
|
||||||
|
"filters": { "company": me.frm.doc.company }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onload_post_render: function() {
|
onload_post_render: function() {
|
||||||
|
@ -31,9 +31,9 @@ sql = webnotes.conn.sql
|
|||||||
class NotUpdateStockError(webnotes.ValidationError): pass
|
class NotUpdateStockError(webnotes.ValidationError): pass
|
||||||
class StockOverReturnError(webnotes.ValidationError): pass
|
class StockOverReturnError(webnotes.ValidationError): pass
|
||||||
|
|
||||||
from controllers.accounts_controller import AccountsController
|
from controllers.stock_controller import StockController
|
||||||
|
|
||||||
class DocType(AccountsController):
|
class DocType(StockController):
|
||||||
def __init__(self, doc, doclist=[]):
|
def __init__(self, doc, doclist=[]):
|
||||||
self.doc = doc
|
self.doc = doc
|
||||||
self.doclist = doclist
|
self.doclist = doclist
|
||||||
@ -171,31 +171,14 @@ class DocType(AccountsController):
|
|||||||
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
|
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
|
||||||
return
|
return
|
||||||
|
|
||||||
abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
|
if not self.doc.expense_adjustment_account:
|
||||||
stock_in_hand_account = self.get_stock_in_hand_account()
|
webnotes.msgprint(_("Please enter Expense/Adjustment Account"), raise_exception=1)
|
||||||
|
|
||||||
|
cost_center = "Auto Inventory Accounting - %s" % (self.company_abbr,)
|
||||||
total_valuation_amount = self.get_total_valuation_amount()
|
total_valuation_amount = self.get_total_valuation_amount()
|
||||||
|
|
||||||
if total_valuation_amount:
|
super(DocType, self).make_gl_entries(self.doc.expense_adjustment_account,
|
||||||
gl_entries = [
|
total_valuation_amount, cost_center)
|
||||||
# debit stock in hand account
|
|
||||||
self.get_gl_dict({
|
|
||||||
"account": stock_in_hand_account,
|
|
||||||
"against": "Stock Adjustment - %s" % abbr,
|
|
||||||
"debit": total_valuation_amount,
|
|
||||||
"remarks": self.doc.remarks or "Accounting Entry for Stock",
|
|
||||||
}, self.doc.docstatus == 2),
|
|
||||||
|
|
||||||
# debit stock received but not billed account
|
|
||||||
self.get_gl_dict({
|
|
||||||
"account": "Stock Adjustment - %s" % abbr,
|
|
||||||
"against": stock_in_hand_account,
|
|
||||||
"credit": total_valuation_amount,
|
|
||||||
"cost_center": "Auto Inventory Accounting - %s" % abbr,
|
|
||||||
"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):
|
def get_total_valuation_amount(self):
|
||||||
total_valuation_amount = 0
|
total_valuation_amount = 0
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"oldfieldtype": "Column Break",
|
"oldfieldtype": "Column Break",
|
||||||
"print_width": "50%",
|
"print_width": "50%",
|
||||||
|
"read_only": 0,
|
||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -76,6 +77,7 @@
|
|||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "\nSTE",
|
"options": "\nSTE",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -95,6 +97,7 @@
|
|||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nManufacture/Repack\nSubcontract\nSales Return\nPurchase Return",
|
"options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nManufacture/Repack\nSubcontract\nSales Return\nPurchase Return",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -152,6 +155,7 @@
|
|||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"oldfieldtype": "Column Break",
|
"oldfieldtype": "Column Break",
|
||||||
"print_width": "50%",
|
"print_width": "50%",
|
||||||
|
"read_only": 0,
|
||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -169,6 +173,7 @@
|
|||||||
"oldfieldname": "posting_date",
|
"oldfieldname": "posting_date",
|
||||||
"oldfieldtype": "Date",
|
"oldfieldtype": "Date",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
@ -185,16 +190,26 @@
|
|||||||
"oldfieldname": "posting_time",
|
"oldfieldname": "posting_time",
|
||||||
"oldfieldtype": "Time",
|
"oldfieldtype": "Time",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:sys_defaults.auto_inventory_accounting",
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "expense_adjustment_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Expense/Adjustment Account",
|
||||||
|
"options": "Account"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "items_section",
|
"fieldname": "items_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Items",
|
"label": "Items",
|
||||||
"oldfieldtype": "Section Break"
|
"oldfieldtype": "Section Break",
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -210,6 +225,7 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -217,7 +233,8 @@
|
|||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "cb0",
|
"fieldname": "cb0",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break",
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -233,6 +250,7 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -241,7 +259,8 @@
|
|||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "sb0",
|
"fieldname": "sb0",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"options": "Simple"
|
"options": "Simple",
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -256,6 +275,7 @@
|
|||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"options": "Stock Entry Detail",
|
"options": "Stock Entry Detail",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -268,14 +288,16 @@
|
|||||||
"label": "Get Stock and Rate",
|
"label": "Get Stock and Rate",
|
||||||
"oldfieldtype": "Button",
|
"oldfieldtype": "Button",
|
||||||
"options": "get_stock_and_rate",
|
"options": "get_stock_and_rate",
|
||||||
"print_hide": 1
|
"print_hide": 1,
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:(doc.purpose!==\"Sales Return\" || doc.purpose!==\"Purchase Return\")",
|
"depends_on": "eval:(doc.purpose!==\"Sales Return\" || doc.purpose!==\"Purchase Return\")",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "sb1",
|
"fieldname": "sb1",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Reference"
|
"label": "Reference",
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -291,6 +313,7 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Production Order",
|
"options": "Production Order",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
@ -301,7 +324,8 @@
|
|||||||
"fieldname": "bom_no",
|
"fieldname": "bom_no",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "BOM No",
|
"label": "BOM No",
|
||||||
"options": "BOM"
|
"options": "BOM",
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -317,6 +341,7 @@
|
|||||||
"oldfieldname": "fg_completed_qty",
|
"oldfieldname": "fg_completed_qty",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -324,7 +349,8 @@
|
|||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "cb1",
|
"fieldname": "cb1",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break",
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
@ -333,7 +359,8 @@
|
|||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "use_multi_level_bom",
|
"fieldname": "use_multi_level_bom",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Use Multi-Level BOM"
|
"label": "Use Multi-Level BOM",
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -347,6 +374,7 @@
|
|||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"oldfieldtype": "Button",
|
"oldfieldtype": "Button",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -356,7 +384,8 @@
|
|||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "contact_section",
|
"fieldname": "contact_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Contact Info"
|
"label": "Contact Info",
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -372,6 +401,7 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Supplier",
|
"options": "Supplier",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -407,6 +437,7 @@
|
|||||||
"oldfieldname": "supplier_address",
|
"oldfieldname": "supplier_address",
|
||||||
"oldfieldtype": "Small Text",
|
"oldfieldtype": "Small Text",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -425,6 +456,7 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Customer",
|
"options": "Customer",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -460,6 +492,7 @@
|
|||||||
"oldfieldname": "customer_address",
|
"oldfieldname": "customer_address",
|
||||||
"oldfieldtype": "Small Text",
|
"oldfieldtype": "Small Text",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -469,13 +502,15 @@
|
|||||||
"fieldname": "more_info",
|
"fieldname": "more_info",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "More Info",
|
"label": "More Info",
|
||||||
"oldfieldtype": "Section Break"
|
"oldfieldtype": "Section Break",
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "col4",
|
"fieldname": "col4",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"print_width": "50%",
|
"print_width": "50%",
|
||||||
|
"read_only": 0,
|
||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -486,7 +521,8 @@
|
|||||||
"label": "Project Name",
|
"label": "Project Name",
|
||||||
"oldfieldname": "project_name",
|
"oldfieldname": "project_name",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Project"
|
"options": "Project",
|
||||||
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -501,6 +537,7 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Print Heading",
|
"options": "Print Heading",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -518,6 +555,7 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -527,6 +565,7 @@
|
|||||||
"fieldname": "col5",
|
"fieldname": "col5",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"print_width": "50%",
|
"print_width": "50%",
|
||||||
|
"read_only": 0,
|
||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -559,6 +598,7 @@
|
|||||||
"oldfieldname": "remarks",
|
"oldfieldname": "remarks",
|
||||||
"oldfieldtype": "Text",
|
"oldfieldtype": "Text",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
@ -570,5 +610,13 @@
|
|||||||
{
|
{
|
||||||
"doctype": "DocPerm",
|
"doctype": "DocPerm",
|
||||||
"role": "Manufacturing User"
|
"role": "Manufacturing User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"role": "Manufacturing Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"role": "Material Manager"
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -560,6 +560,7 @@ test_records = [
|
|||||||
"posting_time": "17:14:24",
|
"posting_time": "17:14:24",
|
||||||
"purpose": "Material Receipt",
|
"purpose": "Material Receipt",
|
||||||
"fiscal_year": "_Test Fiscal Year 2013",
|
"fiscal_year": "_Test Fiscal Year 2013",
|
||||||
|
"expense_adjustment_account": "Stock Adjustment - _TC"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"conversion_factor": 1.0,
|
"conversion_factor": 1.0,
|
||||||
@ -582,6 +583,7 @@ test_records = [
|
|||||||
"posting_time": "17:15",
|
"posting_time": "17:15",
|
||||||
"purpose": "Material Issue",
|
"purpose": "Material Issue",
|
||||||
"fiscal_year": "_Test Fiscal Year 2013",
|
"fiscal_year": "_Test Fiscal Year 2013",
|
||||||
|
"expense_adjustment_account": "Stock Adjustment - _TC"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"conversion_factor": 1.0,
|
"conversion_factor": 1.0,
|
||||||
@ -604,6 +606,7 @@ test_records = [
|
|||||||
"posting_time": "17:14:24",
|
"posting_time": "17:14:24",
|
||||||
"purpose": "Material Transfer",
|
"purpose": "Material Transfer",
|
||||||
"fiscal_year": "_Test Fiscal Year 2013",
|
"fiscal_year": "_Test Fiscal Year 2013",
|
||||||
|
"expense_adjustment_account": "Stock Adjustment - _TC"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"conversion_factor": 1.0,
|
"conversion_factor": 1.0,
|
||||||
|
@ -18,6 +18,44 @@ wn.require("public/app/js/controllers/stock_controller.js");
|
|||||||
wn.provide("erpnext.stock");
|
wn.provide("erpnext.stock");
|
||||||
|
|
||||||
erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({
|
erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({
|
||||||
|
onload: function() {
|
||||||
|
this.set_default_expense_account();
|
||||||
|
},
|
||||||
|
|
||||||
|
set_default_expense_account: function() {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if (sys_defaults.auto_inventory_accounting && !this.frm.doc.expense_account) {
|
||||||
|
this.frm.call({
|
||||||
|
method: "controllers.accounts_controller.get_default_account",
|
||||||
|
args: {
|
||||||
|
"account_for": "stock_adjustment_account",
|
||||||
|
"company": this.frm.doc.company
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if (!r.exc) me.frm.set_value("expense_account", r.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setup: function() {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
this.frm.add_fetch("company", "expense_account", "stock_adjustment_account");
|
||||||
|
|
||||||
|
this.frm.fields_dict["expense_account"].get_query = function() {
|
||||||
|
return {
|
||||||
|
"query": "accounts.utils.get_account_list",
|
||||||
|
"filters": {
|
||||||
|
"is_pl_account": "Yes",
|
||||||
|
"debit_or_credit": "Debit",
|
||||||
|
"company": me.frm.doc.company
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
if(this.frm.doc.docstatus===0) {
|
if(this.frm.doc.docstatus===0) {
|
||||||
this.show_download_template();
|
this.show_download_template();
|
||||||
|
@ -18,22 +18,26 @@ from __future__ import unicode_literals
|
|||||||
import webnotes
|
import webnotes
|
||||||
import json
|
import json
|
||||||
from webnotes import msgprint, _
|
from webnotes import msgprint, _
|
||||||
from webnotes.utils import cstr, flt
|
from webnotes.utils import cstr, flt, cint
|
||||||
from webnotes.model.controller import DocListController
|
|
||||||
from stock.stock_ledger import update_entries_after
|
from stock.stock_ledger import update_entries_after
|
||||||
|
from controllers.stock_controller import StockController
|
||||||
|
|
||||||
class DocType(DocListController):
|
class DocType(StockController):
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]
|
self.head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]
|
||||||
|
self.entries = []
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_data()
|
self.validate_data()
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.insert_stock_ledger_entries()
|
self.insert_stock_ledger_entries()
|
||||||
|
self.set_stock_value_difference()
|
||||||
|
self.make_gl_entries()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.delete_stock_ledger_entries()
|
self.delete_stock_ledger_entries()
|
||||||
|
self.make_gl_entries()
|
||||||
|
|
||||||
def validate_data(self):
|
def validate_data(self):
|
||||||
if not self.doc.reconciliation_json:
|
if not self.doc.reconciliation_json:
|
||||||
@ -134,6 +138,7 @@ class DocType(DocListController):
|
|||||||
data = json.loads(self.doc.reconciliation_json)
|
data = json.loads(self.doc.reconciliation_json)
|
||||||
for row_num, row in enumerate(data[data.index(self.head_row)+1:]):
|
for row_num, row in enumerate(data[data.index(self.head_row)+1:]):
|
||||||
row = webnotes._dict(zip(row_template, row))
|
row = webnotes._dict(zip(row_template, row))
|
||||||
|
row["row_num"] = row_num
|
||||||
previous_sle = get_previous_sle({
|
previous_sle = get_previous_sle({
|
||||||
"item_code": row.item_code,
|
"item_code": row.item_code,
|
||||||
"warehouse": row.warehouse,
|
"warehouse": row.warehouse,
|
||||||
@ -162,8 +167,7 @@ class DocType(DocListController):
|
|||||||
|
|
||||||
def sle_for_moving_avg(self, row, previous_sle, change_in_qty, change_in_rate):
|
def sle_for_moving_avg(self, row, previous_sle, change_in_qty, change_in_rate):
|
||||||
"""Insert Stock Ledger Entries for Moving Average valuation"""
|
"""Insert Stock Ledger Entries for Moving Average valuation"""
|
||||||
def _get_incoming_rate(qty, valuation_rate, previous_qty,
|
def _get_incoming_rate(qty, valuation_rate, previous_qty, previous_valuation_rate):
|
||||||
previous_valuation_rate):
|
|
||||||
if previous_valuation_rate == 0:
|
if previous_valuation_rate == 0:
|
||||||
return flt(valuation_rate)
|
return flt(valuation_rate)
|
||||||
else:
|
else:
|
||||||
@ -178,8 +182,8 @@ class DocType(DocListController):
|
|||||||
flt(previous_sle.get("qty_after_transaction")),
|
flt(previous_sle.get("qty_after_transaction")),
|
||||||
flt(previous_sle.get("valuation_rate")))
|
flt(previous_sle.get("valuation_rate")))
|
||||||
|
|
||||||
self.insert_entries({"actual_qty": change_in_qty,
|
row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Actual Entry"
|
||||||
"incoming_rate": incoming_rate}, row)
|
self.insert_entries({"actual_qty": change_in_qty, "incoming_rate": incoming_rate}, row)
|
||||||
|
|
||||||
elif change_in_rate and flt(previous_sle.get("qty_after_transaction")) > 0:
|
elif change_in_rate and flt(previous_sle.get("qty_after_transaction")) > 0:
|
||||||
# if no change in qty, but change in rate
|
# if no change in qty, but change in rate
|
||||||
@ -190,9 +194,11 @@ class DocType(DocListController):
|
|||||||
flt(previous_sle.get("valuation_rate")))
|
flt(previous_sle.get("valuation_rate")))
|
||||||
|
|
||||||
# +1 entry
|
# +1 entry
|
||||||
|
row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Valuation Adjustment +1"
|
||||||
self.insert_entries({"actual_qty": 1, "incoming_rate": incoming_rate}, row)
|
self.insert_entries({"actual_qty": 1, "incoming_rate": incoming_rate}, row)
|
||||||
|
|
||||||
# -1 entry
|
# -1 entry
|
||||||
|
row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Valuation Adjustment -1"
|
||||||
self.insert_entries({"actual_qty": -1}, row)
|
self.insert_entries({"actual_qty": -1}, row)
|
||||||
|
|
||||||
def sle_for_fifo(self, row, previous_sle, change_in_qty, change_in_rate):
|
def sle_for_fifo(self, row, previous_sle, change_in_qty, change_in_rate):
|
||||||
@ -206,13 +212,15 @@ class DocType(DocListController):
|
|||||||
if previous_stock_queue != [[row.qty, row.valuation_rate]]:
|
if previous_stock_queue != [[row.qty, row.valuation_rate]]:
|
||||||
# make entry as per attachment
|
# make entry as per attachment
|
||||||
if row.qty:
|
if row.qty:
|
||||||
|
row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Actual Entry"
|
||||||
self.insert_entries({"actual_qty": row.qty,
|
self.insert_entries({"actual_qty": row.qty,
|
||||||
"incoming_rate": flt(row.valuation_rate)}, row)
|
"incoming_rate": flt(row.valuation_rate)}, row)
|
||||||
|
|
||||||
# Make reverse entry
|
# Make reverse entry
|
||||||
if previous_stock_qty:
|
if previous_stock_qty:
|
||||||
|
row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Reverse Entry"
|
||||||
self.insert_entries({"actual_qty": -1 * previous_stock_qty,
|
self.insert_entries({"actual_qty": -1 * previous_stock_qty,
|
||||||
"incoming_rate": previous_stock_qty < 0 and \
|
"incoming_rate": previous_stock_qty < 0 and
|
||||||
flt(row.valuation_rate) or 0}, row)
|
flt(row.valuation_rate) or 0}, row)
|
||||||
|
|
||||||
|
|
||||||
@ -221,8 +229,7 @@ class DocType(DocListController):
|
|||||||
# dont want change in valuation
|
# dont want change in valuation
|
||||||
if previous_stock_qty > 0:
|
if previous_stock_qty > 0:
|
||||||
# set valuation_rate as previous valuation_rate
|
# set valuation_rate as previous valuation_rate
|
||||||
row.valuation_rate = \
|
row.valuation_rate = previous_stock_value / flt(previous_stock_qty)
|
||||||
previous_stock_value / flt(previous_stock_qty)
|
|
||||||
|
|
||||||
_insert_entries()
|
_insert_entries()
|
||||||
|
|
||||||
@ -235,7 +242,7 @@ class DocType(DocListController):
|
|||||||
|
|
||||||
def insert_entries(self, opts, row):
|
def insert_entries(self, opts, row):
|
||||||
"""Insert Stock Ledger Entries"""
|
"""Insert Stock Ledger Entries"""
|
||||||
args = {
|
args = webnotes._dict({
|
||||||
"doctype": "Stock Ledger Entry",
|
"doctype": "Stock Ledger Entry",
|
||||||
"item_code": row.item_code,
|
"item_code": row.item_code,
|
||||||
"warehouse": row.warehouse,
|
"warehouse": row.warehouse,
|
||||||
@ -243,9 +250,10 @@ class DocType(DocListController):
|
|||||||
"posting_time": self.doc.posting_time,
|
"posting_time": self.doc.posting_time,
|
||||||
"voucher_type": self.doc.doctype,
|
"voucher_type": self.doc.doctype,
|
||||||
"voucher_no": self.doc.name,
|
"voucher_no": self.doc.name,
|
||||||
"company": webnotes.conn.get_default("company"),
|
"company": self.doc.company,
|
||||||
"is_cancelled": "No",
|
"is_cancelled": "No",
|
||||||
}
|
"voucher_detail_no": row.voucher_detail_no
|
||||||
|
})
|
||||||
args.update(opts)
|
args.update(opts)
|
||||||
# create stock ledger entry
|
# create stock ledger entry
|
||||||
sle_wrapper = webnotes.bean([args])
|
sle_wrapper = webnotes.bean([args])
|
||||||
@ -255,7 +263,8 @@ class DocType(DocListController):
|
|||||||
# update bin
|
# update bin
|
||||||
webnotes.get_obj('Warehouse', row.warehouse).update_bin(args)
|
webnotes.get_obj('Warehouse', row.warehouse).update_bin(args)
|
||||||
|
|
||||||
return sle_wrapper
|
# append to entries
|
||||||
|
self.entries.append(args)
|
||||||
|
|
||||||
def delete_stock_ledger_entries(self):
|
def delete_stock_ledger_entries(self):
|
||||||
""" Delete Stock Ledger Entries related to this Stock Reconciliation
|
""" Delete Stock Ledger Entries related to this Stock Reconciliation
|
||||||
@ -278,6 +287,32 @@ class DocType(DocListController):
|
|||||||
"posting_time": self.doc.posting_time
|
"posting_time": self.doc.posting_time
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def set_stock_value_difference(self):
|
||||||
|
"""stock_value_difference is the increment in the stock value"""
|
||||||
|
from stock.utils import get_buying_amount
|
||||||
|
|
||||||
|
item_list = [d.item_code for d in self.entries]
|
||||||
|
warehouse_list = [d.warehouse for d in self.entries]
|
||||||
|
stock_ledger_entries = self.get_stock_ledger_entries(item_list, warehouse_list)
|
||||||
|
|
||||||
|
self.doc.stock_value_difference = 0.0
|
||||||
|
for d in self.entries:
|
||||||
|
self.doc.stock_value_difference -= get_buying_amount(d.item_code, d.warehouse,
|
||||||
|
d.actual_qty, self.doc.doctype, self.doc.name, d.voucher_detail_no,
|
||||||
|
stock_ledger_entries)
|
||||||
|
webnotes.conn.set(self.doc, "stock_value_difference", self.doc.stock_value_difference)
|
||||||
|
|
||||||
|
def make_gl_entries(self):
|
||||||
|
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
|
||||||
|
return
|
||||||
|
|
||||||
|
if not self.doc.expense_account:
|
||||||
|
msgprint(_("Please enter Expense Account"), raise_exception=1)
|
||||||
|
|
||||||
|
cost_center = "Auto Inventory Accounting - %s" % (self.company_abbr,)
|
||||||
|
|
||||||
|
super(DocType, self).make_gl_entries(self.doc.expense_account,
|
||||||
|
self.doc.stock_value_difference, cost_center)
|
||||||
|
|
||||||
@webnotes.whitelist()
|
@webnotes.whitelist()
|
||||||
def upload():
|
def upload():
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-01-19 10:23:35",
|
"creation": "2013-01-22 16:50:41",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-01-22 14:57:24",
|
"modified": "2013-03-18 12:48:42",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -30,6 +30,7 @@
|
|||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"amend": 1,
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"doctype": "DocPerm",
|
"doctype": "DocPerm",
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
|
"role": "Material Manager",
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
@ -79,6 +81,22 @@
|
|||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Company",
|
||||||
|
"options": "Company",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:sys_defaults.auto_inventory_accounting",
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "expense_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Expense Account",
|
||||||
|
"options": "Account"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "col1",
|
"fieldname": "col1",
|
||||||
@ -119,12 +137,14 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"doctype": "DocField",
|
||||||
"doctype": "DocPerm",
|
"fieldname": "stock_value_difference",
|
||||||
"role": "Material Manager"
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Stock Value Difference",
|
||||||
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocPerm",
|
"doctype": "DocPerm"
|
||||||
"role": "System Manager"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -1,40 +1,15 @@
|
|||||||
# ERPNext - web based ERP (http://erpnext.com)
|
# ERPNext - web based ERP (http://erpnext.com)
|
||||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
# For license information, please see license.txt
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import unittest
|
import webnotes, unittest
|
||||||
import webnotes
|
|
||||||
from webnotes.tests import insert_test_data
|
|
||||||
from webnotes.utils import flt
|
from webnotes.utils import flt
|
||||||
import json
|
import json
|
||||||
|
from accounts.utils import get_fiscal_year
|
||||||
company = webnotes.conn.get_default("company")
|
|
||||||
|
|
||||||
class TestStockReconciliation(unittest.TestCase):
|
class TestStockReconciliation(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_reco_for_fifo(self):
|
def test_reco_for_fifo(self):
|
||||||
|
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||||
# [[qty, valuation_rate, posting_date,
|
# [[qty, valuation_rate, posting_date,
|
||||||
# posting_time, expected_stock_value, bin_qty, bin_valuation]]
|
# posting_time, expected_stock_value, bin_qty, bin_valuation]]
|
||||||
input_data = [
|
input_data = [
|
||||||
@ -53,28 +28,32 @@ class TestStockReconciliation(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
for d in input_data:
|
for d in input_data:
|
||||||
|
self.cleanup_data()
|
||||||
self.insert_existing_sle("FIFO")
|
self.insert_existing_sle("FIFO")
|
||||||
|
stock_reco = self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
|
||||||
|
|
||||||
self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
|
# check stock value
|
||||||
|
|
||||||
res = webnotes.conn.sql("""select stock_value from `tabStock Ledger Entry`
|
res = webnotes.conn.sql("""select stock_value from `tabStock Ledger Entry`
|
||||||
where item_code = 'Android Jack D' and warehouse = 'Default Warehouse'
|
where item_code = '_Test Item' and warehouse = '_Test Warehouse'
|
||||||
and posting_date = %s and posting_time = %s order by name desc limit 1""",
|
and posting_date = %s and posting_time = %s order by name desc limit 1""",
|
||||||
(d[2], d[3]))
|
(d[2], d[3]))
|
||||||
|
|
||||||
self.assertEqual(res and flt(res[0][0]) or 0, d[4])
|
self.assertEqual(res and flt(res[0][0]) or 0, d[4])
|
||||||
|
|
||||||
|
# check bin qty and stock value
|
||||||
bin = webnotes.conn.sql("""select actual_qty, stock_value from `tabBin`
|
bin = webnotes.conn.sql("""select actual_qty, stock_value from `tabBin`
|
||||||
where item_code = 'Android Jack D' and warehouse = 'Default Warehouse'""")
|
where item_code = '_Test Item' and warehouse = '_Test Warehouse'""")
|
||||||
|
|
||||||
self.assertEqual(bin and [flt(bin[0][0]), flt(bin[0][1])] or [], [d[5], d[6]])
|
self.assertEqual(bin and [flt(bin[0][0]), flt(bin[0][1])] or [], [d[5], d[6]])
|
||||||
|
|
||||||
|
# no gl entries
|
||||||
self.tearDown()
|
gl_entries = webnotes.conn.sql("""select name from `tabGL Entry`
|
||||||
self.setUp()
|
where voucher_type = 'Stock Reconciliation' and voucher_no = %s""",
|
||||||
|
stock_reco.doc.name)
|
||||||
|
self.assertFalse(gl_entries)
|
||||||
|
|
||||||
|
|
||||||
def test_reco_for_moving_average(self):
|
def test_reco_for_moving_average(self):
|
||||||
|
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||||
# [[qty, valuation_rate, posting_date,
|
# [[qty, valuation_rate, posting_date,
|
||||||
# posting_time, expected_stock_value, bin_qty, bin_valuation]]
|
# posting_time, expected_stock_value, bin_qty, bin_valuation]]
|
||||||
input_data = [
|
input_data = [
|
||||||
@ -94,95 +73,194 @@ class TestStockReconciliation(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
for d in input_data:
|
for d in input_data:
|
||||||
|
self.cleanup_data()
|
||||||
self.insert_existing_sle("Moving Average")
|
self.insert_existing_sle("Moving Average")
|
||||||
|
stock_reco = self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
|
||||||
|
|
||||||
self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
|
# check stock value in sle
|
||||||
|
|
||||||
res = webnotes.conn.sql("""select stock_value from `tabStock Ledger Entry`
|
res = webnotes.conn.sql("""select stock_value from `tabStock Ledger Entry`
|
||||||
where item_code = 'Android Jack D' and warehouse = 'Default Warehouse'
|
where item_code = '_Test Item' and warehouse = '_Test Warehouse'
|
||||||
and posting_date = %s and posting_time = %s order by name desc limit 1""",
|
and posting_date = %s and posting_time = %s order by name desc limit 1""",
|
||||||
(d[2], d[3]))
|
(d[2], d[3]))
|
||||||
|
|
||||||
self.assertEqual(res and flt(res[0][0], 4) or 0, d[4])
|
self.assertEqual(res and flt(res[0][0], 4) or 0, d[4])
|
||||||
|
|
||||||
|
# bin qty and stock value
|
||||||
bin = webnotes.conn.sql("""select actual_qty, stock_value from `tabBin`
|
bin = webnotes.conn.sql("""select actual_qty, stock_value from `tabBin`
|
||||||
where item_code = 'Android Jack D' and warehouse = 'Default Warehouse'""")
|
where item_code = '_Test Item' and warehouse = '_Test Warehouse'""")
|
||||||
|
|
||||||
self.assertEqual(bin and [flt(bin[0][0]), flt(bin[0][1], 4)] or [],
|
self.assertEqual(bin and [flt(bin[0][0]), flt(bin[0][1], 4)] or [],
|
||||||
[flt(d[5]), flt(d[6])])
|
[flt(d[5]), flt(d[6])])
|
||||||
|
|
||||||
self.tearDown()
|
# no gl entries
|
||||||
self.setUp()
|
gl_entries = webnotes.conn.sql("""select name from `tabGL Entry`
|
||||||
|
where voucher_type = 'Stock Reconciliation' and voucher_no = %s""",
|
||||||
|
stock_reco.doc.name)
|
||||||
|
self.assertFalse(gl_entries)
|
||||||
|
|
||||||
|
def test_reco_fifo_gl_entries(self):
|
||||||
|
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||||
|
|
||||||
|
# [[qty, valuation_rate, posting_date,
|
||||||
|
# posting_time, stock_in_hand_debit]]
|
||||||
|
input_data = [
|
||||||
|
[50, 1000, "2012-12-26", "12:00", 38000],
|
||||||
|
[5, 1000, "2012-12-26", "12:00", -7000],
|
||||||
|
[15, 1000, "2012-12-26", "12:00", 3000],
|
||||||
|
[25, 900, "2012-12-26", "12:00", 10500],
|
||||||
|
[20, 500, "2012-12-26", "12:00", -2000],
|
||||||
|
["", 1000, "2012-12-26", "12:05", 3000],
|
||||||
|
[20, "", "2012-12-26", "12:05", 4000],
|
||||||
|
[10, 2000, "2012-12-26", "12:10", 8000],
|
||||||
|
[0, "", "2012-12-26", "12:10", -12000],
|
||||||
|
[50, 1000, "2013-01-01", "12:00", 50000],
|
||||||
|
[5, 1000, "2013-01-01", "12:00", 5000],
|
||||||
|
[1, 1000, "2012-12-01", "00:00", 1000],
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
for d in input_data:
|
||||||
|
self.cleanup_data()
|
||||||
|
self.insert_existing_sle("FIFO")
|
||||||
|
stock_reco = self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
|
||||||
|
|
||||||
|
# check gl_entries
|
||||||
|
self.check_gl_entries(stock_reco.doc.name, d[4])
|
||||||
|
|
||||||
|
# cancel
|
||||||
|
stock_reco.cancel()
|
||||||
|
self.check_gl_entries(stock_reco.doc.name, -d[4], True)
|
||||||
|
|
||||||
|
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||||
|
|
||||||
|
def test_reco_moving_average_gl_entries(self):
|
||||||
|
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||||
|
|
||||||
|
# [[qty, valuation_rate, posting_date,
|
||||||
|
# posting_time, stock_in_hand_debit]]
|
||||||
|
input_data = [
|
||||||
|
[50, 1000, "2012-12-26", "12:00", 36500],
|
||||||
|
[5, 1000, "2012-12-26", "12:00", -8500],
|
||||||
|
[15, 1000, "2012-12-26", "12:00", 1500],
|
||||||
|
[25, 900, "2012-12-26", "12:00", 9000],
|
||||||
|
[20, 500, "2012-12-26", "12:00", -3500],
|
||||||
|
["", 1000, "2012-12-26", "12:05", 1500],
|
||||||
|
[20, "", "2012-12-26", "12:05", 4500],
|
||||||
|
[10, 2000, "2012-12-26", "12:10", 6500],
|
||||||
|
[0, "", "2012-12-26", "12:10", -13500],
|
||||||
|
[50, 1000, "2013-01-01", "12:00", 50000],
|
||||||
|
[5, 1000, "2013-01-01", "12:00", 5000],
|
||||||
|
[1, 1000, "2012-12-01", "00:00", 1000],
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
for d in input_data:
|
||||||
|
self.cleanup_data()
|
||||||
|
self.insert_existing_sle("Moving Average")
|
||||||
|
stock_reco = self.submit_stock_reconciliation(d[0], d[1], d[2], d[3])
|
||||||
|
|
||||||
|
# check gl_entries
|
||||||
|
self.check_gl_entries(stock_reco.doc.name, d[4])
|
||||||
|
|
||||||
|
# cancel
|
||||||
|
stock_reco.cancel()
|
||||||
|
self.check_gl_entries(stock_reco.doc.name, -d[4], True)
|
||||||
|
|
||||||
|
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup_data(self):
|
||||||
|
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
||||||
|
webnotes.conn.sql("delete from tabBin")
|
||||||
|
|
||||||
def submit_stock_reconciliation(self, qty, rate, posting_date, posting_time):
|
def submit_stock_reconciliation(self, qty, rate, posting_date, posting_time):
|
||||||
return webnotes.bean([{
|
stock_reco = webnotes.bean([{
|
||||||
"doctype": "Stock Reconciliation",
|
"doctype": "Stock Reconciliation",
|
||||||
"name": "RECO-001",
|
|
||||||
"__islocal": 1,
|
|
||||||
"posting_date": posting_date,
|
"posting_date": posting_date,
|
||||||
"posting_time": posting_time,
|
"posting_time": posting_time,
|
||||||
|
"fiscal_year": get_fiscal_year(posting_date)[0],
|
||||||
|
"company": "_Test Company",
|
||||||
|
"expense_account": "Stock Adjustment - _TC",
|
||||||
"reconciliation_json": json.dumps([
|
"reconciliation_json": json.dumps([
|
||||||
["Item Code", "Warehouse", "Quantity", "Valuation Rate"],
|
["Item Code", "Warehouse", "Quantity", "Valuation Rate"],
|
||||||
["Android Jack D", "Default Warehouse", qty, rate]
|
["_Test Item", "_Test Warehouse", qty, rate]
|
||||||
]),
|
]),
|
||||||
}]).submit()
|
}])
|
||||||
|
stock_reco.insert()
|
||||||
|
stock_reco.submit()
|
||||||
|
return stock_reco
|
||||||
|
|
||||||
def insert_test_data(self):
|
def check_gl_entries(self, voucher_no, stock_value_diff, cancel=None):
|
||||||
# create default warehouse
|
stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company",
|
||||||
if not webnotes.conn.exists("Warehouse", "Default Warehouse"):
|
"stock_in_hand_account")
|
||||||
webnotes.insert({"doctype": "Warehouse",
|
debit_amount = stock_value_diff > 0 and stock_value_diff or 0.0
|
||||||
"warehouse_name": "Default Warehouse",
|
credit_amount = stock_value_diff < 0 and abs(stock_value_diff) or 0.0
|
||||||
"warehouse_type": "Stores"})
|
|
||||||
|
|
||||||
# create UOM: Nos.
|
expected_gl_entries = sorted([
|
||||||
if not webnotes.conn.exists("UOM", "Nos"):
|
[stock_in_hand_account, debit_amount, credit_amount],
|
||||||
webnotes.insert({"doctype": "UOM", "uom_name": "Nos"})
|
["Stock Adjustment - _TC", credit_amount, debit_amount]
|
||||||
|
])
|
||||||
|
if cancel:
|
||||||
|
expected_gl_entries = sorted([
|
||||||
|
[stock_in_hand_account, debit_amount, credit_amount],
|
||||||
|
["Stock Adjustment - _TC", credit_amount, debit_amount],
|
||||||
|
[stock_in_hand_account, credit_amount, debit_amount],
|
||||||
|
["Stock Adjustment - _TC", debit_amount, credit_amount]
|
||||||
|
])
|
||||||
|
|
||||||
# create item groups and items
|
gl_entries = webnotes.conn.sql("""select account, debit, credit
|
||||||
insert_test_data("Item Group",
|
from `tabGL Entry` where voucher_type='Stock Reconciliation' and voucher_no=%s
|
||||||
sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name')))
|
order by account asc, debit asc""", voucher_no, as_dict=1)
|
||||||
insert_test_data("Item")
|
self.assertTrue(gl_entries)
|
||||||
|
|
||||||
|
for i, gle in enumerate(gl_entries):
|
||||||
|
self.assertEquals(expected_gl_entries[i][0], gle.account)
|
||||||
|
self.assertEquals(expected_gl_entries[i][1], gle.debit)
|
||||||
|
self.assertEquals(expected_gl_entries[i][2], gle.credit)
|
||||||
|
|
||||||
def insert_existing_sle(self, valuation_method):
|
def insert_existing_sle(self, valuation_method):
|
||||||
webnotes.conn.set_value("Item", "Android Jack D", "valuation_method", valuation_method)
|
webnotes.conn.set_value("Item", "_Test Item", "valuation_method", valuation_method)
|
||||||
webnotes.conn.set_default("allow_negative_stock", 1)
|
webnotes.conn.set_default("allow_negative_stock", 1)
|
||||||
|
|
||||||
existing_ledgers = [
|
existing_ledgers = [
|
||||||
{
|
{
|
||||||
"doctype": "Stock Ledger Entry", "__islocal": 1,
|
"doctype": "Stock Ledger Entry", "__islocal": 1,
|
||||||
"voucher_type": "Stock Entry", "voucher_no": "TEST",
|
"voucher_type": "Stock Entry", "voucher_no": "TEST",
|
||||||
"item_code": "Android Jack D", "warehouse": "Default Warehouse",
|
"item_code": "_Test Item", "warehouse": "_Test Warehouse",
|
||||||
"posting_date": "2012-12-12", "posting_time": "01:00",
|
"posting_date": "2012-12-12", "posting_time": "01:00",
|
||||||
"actual_qty": 20, "incoming_rate": 1000, "company": company
|
"actual_qty": 20, "incoming_rate": 1000, "company": "_Test Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Stock Ledger Entry", "__islocal": 1,
|
"doctype": "Stock Ledger Entry", "__islocal": 1,
|
||||||
"voucher_type": "Stock Entry", "voucher_no": "TEST",
|
"voucher_type": "Stock Entry", "voucher_no": "TEST",
|
||||||
"item_code": "Android Jack D", "warehouse": "Default Warehouse",
|
"item_code": "_Test Item", "warehouse": "_Test Warehouse",
|
||||||
"posting_date": "2012-12-15", "posting_time": "02:00",
|
"posting_date": "2012-12-15", "posting_time": "02:00",
|
||||||
"actual_qty": 10, "incoming_rate": 700, "company": company
|
"actual_qty": 10, "incoming_rate": 700, "company": "_Test Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Stock Ledger Entry", "__islocal": 1,
|
"doctype": "Stock Ledger Entry", "__islocal": 1,
|
||||||
"voucher_type": "Stock Entry", "voucher_no": "TEST",
|
"voucher_type": "Stock Entry", "voucher_no": "TEST",
|
||||||
"item_code": "Android Jack D", "warehouse": "Default Warehouse",
|
"item_code": "_Test Item", "warehouse": "_Test Warehouse",
|
||||||
"posting_date": "2012-12-25", "posting_time": "03:00",
|
"posting_date": "2012-12-25", "posting_time": "03:00",
|
||||||
"actual_qty": -15, "company": company
|
"actual_qty": -15, "company": "_Test Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Stock Ledger Entry", "__islocal": 1,
|
"doctype": "Stock Ledger Entry", "__islocal": 1,
|
||||||
"voucher_type": "Stock Entry", "voucher_no": "TEST",
|
"voucher_type": "Stock Entry", "voucher_no": "TEST",
|
||||||
"item_code": "Android Jack D", "warehouse": "Default Warehouse",
|
"item_code": "_Test Item", "warehouse": "_Test Warehouse",
|
||||||
"posting_date": "2012-12-31", "posting_time": "08:00",
|
"posting_date": "2012-12-31", "posting_time": "08:00",
|
||||||
"actual_qty": -20, "company": company
|
"actual_qty": -20, "company": "_Test Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Stock Ledger Entry", "__islocal": 1,
|
"doctype": "Stock Ledger Entry", "__islocal": 1,
|
||||||
"voucher_type": "Stock Entry", "voucher_no": "TEST",
|
"voucher_type": "Stock Entry", "voucher_no": "TEST",
|
||||||
"item_code": "Android Jack D", "warehouse": "Default Warehouse",
|
"item_code": "_Test Item", "warehouse": "_Test Warehouse",
|
||||||
"posting_date": "2013-01-05", "posting_time": "07:00",
|
"posting_date": "2013-01-05", "posting_time": "07:00",
|
||||||
"actual_qty": 15, "incoming_rate": 1200, "company": company
|
"actual_qty": 15, "incoming_rate": 1200, "company": "_Test Company"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
webnotes.get_obj("Stock Ledger").update_stock(existing_ledgers)
|
webnotes.get_obj("Stock Ledger").update_stock(existing_ledgers)
|
||||||
|
|
||||||
|
|
||||||
|
test_dependencies = ["Item", "Warehouse"]
|
@ -72,7 +72,7 @@ def update_entries_after(args, verbose=1):
|
|||||||
(qty_after_transaction * valuation_rate) or 0
|
(qty_after_transaction * valuation_rate) or 0
|
||||||
else:
|
else:
|
||||||
stock_value = sum((flt(batch[0]) * flt(batch[1]) for batch in stock_queue))
|
stock_value = sum((flt(batch[0]) * flt(batch[1]) for batch in stock_queue))
|
||||||
|
# print sle.posting_date, sle.actual_qty, sle.incoming_rate, stock_queue, stock_value
|
||||||
# update current sle
|
# update current sle
|
||||||
webnotes.conn.sql("""update `tabStock Ledger Entry`
|
webnotes.conn.sql("""update `tabStock Ledger Entry`
|
||||||
set qty_after_transaction=%s, valuation_rate=%s, stock_queue=%s,
|
set qty_after_transaction=%s, valuation_rate=%s, stock_queue=%s,
|
||||||
|
@ -165,8 +165,8 @@ def get_warehouse_list(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
return wlist
|
return wlist
|
||||||
|
|
||||||
def get_buying_amount(item_code, warehouse, qty, voucher_type, voucher_no, voucher_detail_no,
|
def get_buying_amount(item_code, warehouse, qty, voucher_type, voucher_no, voucher_detail_no,
|
||||||
stock_ledger_entries, item_sales_bom):
|
stock_ledger_entries, item_sales_bom=None):
|
||||||
if item_sales_bom.get(item_code):
|
if item_sales_bom and item_sales_bom.get(item_code):
|
||||||
# sales bom item
|
# sales bom item
|
||||||
buying_amount = 0.0
|
buying_amount = 0.0
|
||||||
for bom_item in item_sales_bom[item_code]:
|
for bom_item in item_sales_bom[item_code]:
|
||||||
@ -182,12 +182,14 @@ def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse,
|
|||||||
stock_ledger_entries):
|
stock_ledger_entries):
|
||||||
for i, sle in enumerate(stock_ledger_entries):
|
for i, sle in enumerate(stock_ledger_entries):
|
||||||
if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no and \
|
if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no and \
|
||||||
len(stock_ledger_entries) > i+1:
|
(sle.voucher_detail_no == item_row or (sle.voucher_type != "Stock Reconciliation"
|
||||||
if (sle.voucher_detail_no == item_row) or \
|
and sle.item_code == item_code and sle.warehouse == warehouse and flt(sle.qty) == qty)):
|
||||||
(sle.item_code == item_code and sle.warehouse == warehouse and \
|
# print "previous_sle", stock_ledger_entries[i+1]
|
||||||
abs(flt(sle.qty)) == qty):
|
# print "current sle", sle
|
||||||
buying_amount = flt(stock_ledger_entries[i+1].stock_value) - \
|
previous_stock_value = len(stock_ledger_entries) > i+1 and \
|
||||||
flt(sle.stock_value)
|
flt(stock_ledger_entries[i+1].stock_value) or 0.0
|
||||||
|
|
||||||
|
buying_amount = previous_stock_value - flt(sle.stock_value)
|
||||||
return buying_amount
|
return buying_amount
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user