Merge branch 'develop' into issue-9424
This commit is contained in:
commit
c1d22adb9f
@ -1,5 +1,6 @@
|
||||
language: python
|
||||
dist: trusty
|
||||
group: deprecated-2017Q2
|
||||
|
||||
python:
|
||||
- "2.7"
|
||||
|
@ -2,7 +2,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
__version__ = '8.0.51'
|
||||
__version__ = '8.1.1'
|
||||
|
||||
|
||||
def get_default_company(user=None):
|
||||
@ -36,12 +36,13 @@ def get_company_currency(company):
|
||||
frappe.flags.company_currency[company] = frappe.db.get_value('Company', company, 'default_currency')
|
||||
return frappe.flags.company_currency[company]
|
||||
|
||||
def set_perpetual_inventory(enable=1, company=None):
|
||||
if not company:
|
||||
company = "_Test Company" if frappe.flags.in_test else get_default_company()
|
||||
|
||||
def set_perpetual_inventory(enable=1):
|
||||
accounts_settings = frappe.get_doc("Accounts Settings")
|
||||
accounts_settings.auto_accounting_for_stock = enable
|
||||
accounts_settings.save()
|
||||
|
||||
company = frappe.get_doc("Company", company)
|
||||
company.enable_perpetual_inventory = enable
|
||||
company.save()
|
||||
|
||||
def encode_company_abbr(name, company):
|
||||
'''Returns name encoded with company abbreviation'''
|
||||
@ -53,4 +54,15 @@ def encode_company_abbr(name, company):
|
||||
|
||||
return " - ".join(parts)
|
||||
|
||||
def is_perpetual_inventory_enabled(company):
|
||||
if not company:
|
||||
company = "_Test Company" if frappe.flags.in_test else get_default_company()
|
||||
|
||||
if not hasattr(frappe.local, 'enable_perpetual_inventory'):
|
||||
frappe.local.enable_perpetual_inventory = {}
|
||||
|
||||
if not company in frappe.local.enable_perpetual_inventory:
|
||||
frappe.local.enable_perpetual_inventory[company] = frappe.db.get_value("Company",
|
||||
company, "enable_perpetual_inventory") or 0
|
||||
|
||||
return frappe.local.enable_perpetual_inventory[company]
|
||||
|
@ -14,6 +14,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -22,7 +23,7 @@
|
||||
"description": "If enabled, the system will post accounting entries for inventory automatically.",
|
||||
"fieldname": "auto_accounting_for_stock",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
@ -44,6 +45,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -73,6 +75,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -103,6 +106,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -131,6 +135,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -161,6 +166,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -190,6 +196,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -219,6 +226,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -249,6 +257,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -290,7 +299,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-04-18 13:35:59.166250",
|
||||
"modified": "2017-06-16 17:39:50.614522",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounts Settings",
|
||||
|
@ -11,18 +11,4 @@ from frappe.model.document import Document
|
||||
|
||||
class AccountsSettings(Document):
|
||||
def on_update(self):
|
||||
frappe.db.set_default("auto_accounting_for_stock", self.auto_accounting_for_stock)
|
||||
|
||||
if cint(self.auto_accounting_for_stock):
|
||||
# set default perpetual account in company
|
||||
for company in frappe.db.sql("select name from tabCompany"):
|
||||
company = frappe.get_doc("Company", company[0])
|
||||
company.flags.ignore_permissions = True
|
||||
company.save()
|
||||
|
||||
# validate warehouse linked to company
|
||||
warehouse_with_no_company = frappe.db.sql_list("""select name from tabWarehouse
|
||||
where disabled=0 and company is null or company = ''""")
|
||||
if warehouse_with_no_company:
|
||||
frappe.throw(_("Company is missing in warehouses {0}")
|
||||
.format(comma_and(warehouse_with_no_company)))
|
||||
pass
|
@ -26,6 +26,23 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
|
||||
});
|
||||
});
|
||||
|
||||
frappe.ui.form.on('POS Profile', {
|
||||
refresh: function(frm) {
|
||||
if(frm.doc.company) {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
}
|
||||
},
|
||||
|
||||
company: function(frm) {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
},
|
||||
|
||||
toggle_display_account_head: function(frm) {
|
||||
frm.toggle_display('expense_account',
|
||||
erpnext.is_perpetual_inventory_enabled(frm.doc.company));
|
||||
}
|
||||
})
|
||||
|
||||
// Income Account
|
||||
// --------------------------------
|
||||
cur_frm.fields_dict['income_account'].get_query = function(doc,cdt,cdn) {
|
||||
|
@ -1132,7 +1132,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||
"depends_on": "",
|
||||
"fieldname": "expense_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -1201,7 +1201,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-06-15 20:07:55.682137",
|
||||
"modified": "2017-06-16 17:04:33.165676",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Profile",
|
||||
|
@ -164,7 +164,7 @@ class PurchaseInvoice(BuyingController):
|
||||
frappe.msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
|
||||
|
||||
def set_expense_account(self, for_validate=False):
|
||||
auto_accounting_for_stock = cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
|
||||
auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company)
|
||||
|
||||
if auto_accounting_for_stock:
|
||||
stock_not_billed_account = self.get_company_default("stock_received_but_not_billed")
|
||||
@ -335,9 +335,7 @@ class PurchaseInvoice(BuyingController):
|
||||
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||
|
||||
def get_gl_entries(self, warehouse_account=None):
|
||||
self.auto_accounting_for_stock = \
|
||||
cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
|
||||
|
||||
self.auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company)
|
||||
self.stock_received_but_not_billed = self.get_company_default("stock_received_but_not_billed")
|
||||
self.expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
|
||||
self.negative_expense_to_be_booked = 0.0
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
import frappe.model
|
||||
from frappe.utils import cint, flt, today, nowdate
|
||||
import frappe.defaults
|
||||
@ -25,11 +25,10 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
def tearDown(self):
|
||||
unlink_payment_on_cancel_of_invoice(0)
|
||||
|
||||
def test_gl_entries_without_auto_accounting_for_stock(self):
|
||||
set_perpetual_inventory(0)
|
||||
self.assertTrue(not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")))
|
||||
|
||||
def test_gl_entries_without_perpetual_inventory(self):
|
||||
wrapper = frappe.copy_doc(test_records[0])
|
||||
set_perpetual_inventory(0, wrapper.company)
|
||||
self.assertTrue(not cint(erpnext.is_perpetual_inventory_enabled(wrapper.company)))
|
||||
wrapper.insert()
|
||||
wrapper.submit()
|
||||
wrapper.load_from_db()
|
||||
@ -51,17 +50,16 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
for d in gl_entries:
|
||||
self.assertEqual([d.debit, d.credit], expected_gl_entries.get(d.account))
|
||||
|
||||
def test_gl_entries_with_auto_accounting_for_stock(self):
|
||||
set_perpetual_inventory(1)
|
||||
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
||||
|
||||
def test_gl_entries_with_perpetual_inventory(self):
|
||||
pi = frappe.copy_doc(test_records[1])
|
||||
set_perpetual_inventory(1, pi.company)
|
||||
self.assertTrue(cint(erpnext.is_perpetual_inventory_enabled(pi.company)), 1)
|
||||
pi.insert()
|
||||
pi.submit()
|
||||
|
||||
self.check_gle_for_pi(pi.name)
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, pi.company)
|
||||
|
||||
def test_payment_entry_unlink_against_purchase_invoice(self):
|
||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
||||
@ -84,11 +82,10 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
|
||||
self.assertRaises(frappe.LinkExistsError, pi_doc.cancel)
|
||||
|
||||
def test_gl_entries_with_auto_accounting_for_stock_against_pr(self):
|
||||
set_perpetual_inventory(1)
|
||||
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
||||
|
||||
def test_gl_entries_with_perpetual_inventory_against_pr(self):
|
||||
pr = frappe.copy_doc(pr_test_records[0])
|
||||
set_perpetual_inventory(1, pr.company)
|
||||
self.assertTrue(cint(erpnext.is_perpetual_inventory_enabled(pr.company)), 1)
|
||||
pr.submit()
|
||||
|
||||
pi = frappe.copy_doc(test_records[1])
|
||||
@ -99,7 +96,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
|
||||
self.check_gle_for_pi(pi.name)
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, pr.company)
|
||||
|
||||
def check_gle_for_pi(self, pi):
|
||||
gl_entries = frappe.db.sql("""select account, debit, credit
|
||||
@ -133,10 +130,9 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
self.assertRaises(frappe.CannotChangeConstantError, pi.save)
|
||||
|
||||
def test_gl_entries_with_aia_for_non_stock_items(self):
|
||||
set_perpetual_inventory()
|
||||
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
||||
|
||||
pi = frappe.copy_doc(test_records[1])
|
||||
set_perpetual_inventory(1, pi.company)
|
||||
self.assertTrue(cint(erpnext.is_perpetual_inventory_enabled(pi.company)), 1)
|
||||
pi.get("items")[0].item_code = "_Test Non Stock Item"
|
||||
pi.get("items")[0].expense_account = "_Test Account Cost for Goods Sold - _TC"
|
||||
pi.get("taxes").pop(0)
|
||||
@ -159,7 +155,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
self.assertEquals(expected_values[i][0], gle.account)
|
||||
self.assertEquals(expected_values[i][1], gle.debit)
|
||||
self.assertEquals(expected_values[i][2], gle.credit)
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, pi.company)
|
||||
|
||||
def test_purchase_invoice_calculation(self):
|
||||
pi = frappe.copy_doc(test_records[0])
|
||||
|
@ -400,19 +400,6 @@ cur_frm.set_query("income_account", "items", function(doc) {
|
||||
}
|
||||
});
|
||||
|
||||
// expense account
|
||||
if (frappe.sys_defaults.auto_accounting_for_stock) {
|
||||
cur_frm.fields_dict['items'].grid.get_field('expense_account').get_query = function(doc) {
|
||||
return {
|
||||
filters: {
|
||||
'report_type': 'Profit and Loss',
|
||||
'company': doc.company,
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Cost Center in Details Table
|
||||
// -----------------------------
|
||||
@ -502,6 +489,21 @@ frappe.ui.form.on('Sales Invoice', {
|
||||
filters: {'project': doc.project}
|
||||
}
|
||||
}
|
||||
|
||||
// expense account
|
||||
frm.fields_dict['items'].grid.get_field('expense_account').get_query = function(doc) {
|
||||
if (erpnext.is_perpetual_inventory_enabled(doc.company)) {
|
||||
return {
|
||||
filters: {
|
||||
'report_type': 'Profit and Loss',
|
||||
'company': doc.company,
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
project: function(frm){
|
||||
|
@ -2,7 +2,7 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
import frappe.defaults
|
||||
from frappe.utils import cint, flt
|
||||
from frappe import _, msgprint, throw
|
||||
@ -559,6 +559,8 @@ class SalesInvoice(SellingController):
|
||||
throw(_("Delivery Note {0} is not submitted").format(d.delivery_note))
|
||||
|
||||
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
|
||||
auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company)
|
||||
|
||||
if not self.grand_total:
|
||||
return
|
||||
|
||||
@ -580,11 +582,11 @@ class SalesInvoice(SellingController):
|
||||
self.doctype, self.return_against if cint(self.is_return) else self.name)
|
||||
|
||||
if repost_future_gle and cint(self.update_stock) \
|
||||
and cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
and cint(auto_accounting_for_stock):
|
||||
items, warehouses = self.get_items_and_warehouses()
|
||||
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items)
|
||||
elif self.docstatus == 2 and cint(self.update_stock) \
|
||||
and cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
and cint(auto_accounting_for_stock):
|
||||
from erpnext.accounts.general_ledger import delete_gl_entries
|
||||
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||
|
||||
@ -672,8 +674,8 @@ class SalesInvoice(SellingController):
|
||||
)
|
||||
|
||||
# expense account gl entries
|
||||
if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \
|
||||
and cint(self.update_stock):
|
||||
if cint(self.update_stock) and \
|
||||
erpnext.is_perpetual_inventory_enabled(self.company):
|
||||
gl_entries += super(SalesInvoice, self).get_gl_entries()
|
||||
|
||||
def make_pos_gl_entries(self, gl_entries):
|
||||
|
@ -488,8 +488,8 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 561.8)
|
||||
|
||||
def test_sales_invoice_gl_entry_without_perpetual_inventory(self):
|
||||
set_perpetual_inventory(0)
|
||||
si = frappe.copy_doc(test_records[1])
|
||||
set_perpetual_inventory(0, si.company)
|
||||
si.insert()
|
||||
si.submit()
|
||||
|
||||
@ -617,6 +617,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertEquals(expected_gl_entries[i][2], gle.credit)
|
||||
|
||||
si.cancel()
|
||||
frappe.delete_doc('Sales Invoice', si.name)
|
||||
gle = frappe.db.sql("""select * from `tabGL Entry`
|
||||
where voucher_type='Sales Invoice' and voucher_no=%s""", si.name)
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
from frappe.utils import flt, cstr, cint
|
||||
from frappe import _
|
||||
from frappe.model.meta import get_field_precision
|
||||
@ -80,7 +80,7 @@ def check_if_in_list(gle, gl_map):
|
||||
|
||||
def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
|
||||
if not from_repost:
|
||||
validate_account_for_auto_accounting_for_stock(gl_map)
|
||||
validate_account_for_perpetual_inventory(gl_map)
|
||||
|
||||
round_off_debit_credit(gl_map)
|
||||
|
||||
@ -100,8 +100,8 @@ def make_entry(args, adv_adj, update_outstanding, from_repost=False):
|
||||
gle.run_method("on_update_with_args", adv_adj, update_outstanding, from_repost)
|
||||
gle.submit()
|
||||
|
||||
def validate_account_for_auto_accounting_for_stock(gl_map):
|
||||
if cint(frappe.db.get_single_value("Accounts Settings", "auto_accounting_for_stock")) \
|
||||
def validate_account_for_perpetual_inventory(gl_map):
|
||||
if cint(erpnext.is_perpetual_inventory_enabled(gl_map[0].company)) \
|
||||
and gl_map[0].voucher_type=="Journal Entry":
|
||||
aii_accounts = [d[0] for d in frappe.db.sql("""select name from tabAccount
|
||||
where account_type = 'Stock' and is_group=0""")]
|
||||
|
@ -1484,7 +1484,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
print_dialog: function () {
|
||||
var me = this;
|
||||
|
||||
this.frappe.msgprint = frappe.msgprint(
|
||||
this.msgprint = frappe.msgprint(
|
||||
`<a class="btn btn-primary print_doc"
|
||||
style="margin-right: 5px;">${__('Print')}</a>
|
||||
<a class="btn btn-default new_doc">${__('New')}</a>`);
|
||||
@ -1495,7 +1495,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
})
|
||||
|
||||
$('.new_doc').click(function () {
|
||||
me.frappe.msgprint.hide()
|
||||
me.msgprint.hide()
|
||||
me.make_new_cart()
|
||||
})
|
||||
},
|
||||
|
@ -227,7 +227,7 @@ class GrossProfitGenerator(object):
|
||||
if not average_buying_rate:
|
||||
average_buying_rate = get_valuation_rate(item_code, row.warehouse,
|
||||
row.parenttype, row.parent, allow_zero_rate=True,
|
||||
currency=self.filters.currency)
|
||||
currency=self.filters.currency, company=self.filters.company)
|
||||
|
||||
self.average_buying_rate[item_code] = flt(average_buying_rate)
|
||||
|
||||
|
@ -227,7 +227,7 @@ class BuyingController(StockController):
|
||||
})
|
||||
if not rm.rate:
|
||||
rm.rate = get_valuation_rate(bom_item.item_code, self.supplier_warehouse,
|
||||
self.doctype, self.name, currency=self.company_currency)
|
||||
self.doctype, self.name, currency=self.company_currency, company = self.company)
|
||||
else:
|
||||
rm.rate = bom_item.rate
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
from frappe.utils import cint, flt, cstr
|
||||
from frappe import msgprint, _
|
||||
import frappe.defaults
|
||||
@ -21,7 +21,7 @@ class StockController(AccountsController):
|
||||
if self.docstatus == 2:
|
||||
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||
|
||||
if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
if cint(erpnext.is_perpetual_inventory_enabled(self.company)):
|
||||
warehouse_account = get_warehouse_account_map()
|
||||
|
||||
if self.docstatus==1:
|
||||
@ -95,7 +95,7 @@ class StockController(AccountsController):
|
||||
|
||||
def update_stock_ledger_entries(self, sle):
|
||||
sle.valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse,
|
||||
self.doctype, self.name, currency=self.company_currency)
|
||||
self.doctype, self.name, currency=self.company_currency, company=self.company)
|
||||
|
||||
sle.stock_value = flt(sle.qty_after_transaction) * flt(sle.valuation_rate)
|
||||
sle.stock_value_difference = flt(sle.actual_qty) * flt(sle.valuation_rate)
|
||||
|
@ -1144,7 +1144,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-06-13 14:29:12.567700",
|
||||
"modified": "2017-06-22 14:29:12.700000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "CRM",
|
||||
"name": "Lead",
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 59 KiB |
@ -8,7 +8,7 @@ On receipt of items in a particular warehouse, the balance in the Warehouse Acco
|
||||
|
||||
* Activate Perpetual Inventory
|
||||
|
||||
> Explore > Accounts > Accounts Settings > "Make Accounting Entry For Every Stock Movement"
|
||||
> Setup > Company > Stock Settings > "Enable Perpetual Inventory"
|
||||
|
||||
<img class="screenshot" alt="Perpetual Inventory" src="{{docs_base_url}}/assets/img/accounts/perpetual-1.png">
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
execute:import unidecode # new requirement
|
||||
|
||||
erpnext.patches.v8_0.move_perpetual_inventory_setting
|
||||
erpnext.patches.v4_0.validate_v3_patch
|
||||
erpnext.patches.v4_0.fix_employee_user_id
|
||||
erpnext.patches.v4_0.remove_employee_role_if_no_employee
|
||||
@ -404,4 +404,6 @@ erpnext.patches.v8_0.delete_bin_indexes
|
||||
erpnext.patches.v8_0.move_account_head_from_account_to_warehouse_for_inventory
|
||||
erpnext.patches.v8_0.change_in_words_varchar_length
|
||||
erpnext.patches.v8_0.create_domain_docs #16-05-2017
|
||||
erpnext.patches.v8_0.update_sales_cost_in_project
|
||||
erpnext.patches.v8_0.update_sales_cost_in_project
|
||||
erpnext.patches.v8_0.save_system_settings
|
||||
erpnext.patches.v8_1.delete_deprecated_reports
|
@ -1,6 +1,6 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import cint
|
||||
from frappe.utils.nestedset import rebuild_tree
|
||||
@ -51,7 +51,8 @@ def check_is_warehouse_associated_with_company():
|
||||
def make_warehouse_nestedset(company=None):
|
||||
validate_parent_account_for_warehouse(company)
|
||||
stock_account_group = get_stock_account_group(company.name)
|
||||
if not stock_account_group and cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
enable_perpetual_inventory = cint(erpnext.is_perpetual_inventory_enabled(company)) or 0
|
||||
if not stock_account_group and enable_perpetual_inventory:
|
||||
return
|
||||
|
||||
if company:
|
||||
@ -65,14 +66,14 @@ def make_warehouse_nestedset(company=None):
|
||||
create_default_warehouse_group(company, stock_account_group, ignore_mandatory)
|
||||
|
||||
set_parent_to_warehouse(warehouse_group, company)
|
||||
if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
if enable_perpetual_inventory:
|
||||
set_parent_to_warehouse_account(company)
|
||||
|
||||
def validate_parent_account_for_warehouse(company=None):
|
||||
if not company:
|
||||
return
|
||||
|
||||
if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
if cint(erpnext.is_perpetual_inventory_enabled(company)):
|
||||
parent_account = frappe.db.sql("""select name from tabAccount
|
||||
where account_type='Stock' and company=%s and is_group=1
|
||||
and (warehouse is null or warehouse = '')""", company.name)
|
||||
|
@ -2,18 +2,16 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
|
||||
def execute():
|
||||
if not frappe.db.get_single_value("Accounts Settings", "auto_accounting_for_stock"):
|
||||
return
|
||||
|
||||
frappe.reload_doctype("Account")
|
||||
|
||||
warehouses = frappe.db.sql_list("""select name from tabAccount
|
||||
warehouses = frappe.db.sql_list("""select name, company from tabAccount
|
||||
where account_type = 'Stock' and is_group = 0
|
||||
and (warehouse is null or warehouse = '')""")
|
||||
if warehouses:
|
||||
and (warehouse is null or warehouse = '')""", as_dict)
|
||||
warehouses = [d.name for d in warehouses if erpnext.is_perpetual_inventory_enabled(d.company)]
|
||||
if len(warehouses) > 0:
|
||||
warehouses = set_warehouse_for_stock_account(warehouses)
|
||||
if not warehouses:
|
||||
return
|
||||
|
@ -8,17 +8,16 @@ from erpnext.stock import get_warehouse_account_map
|
||||
from erpnext.controllers.stock_controller import update_gl_entries_after
|
||||
|
||||
def execute():
|
||||
if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
return
|
||||
|
||||
company_list = frappe.db.sql_list("""Select name from tabCompany where enable_perpetual_inventory = 1""")
|
||||
frappe.reload_doc('accounts', 'doctype', 'sales_invoice')
|
||||
|
||||
frappe.reload_doctype("Purchase Invoice")
|
||||
wh_account = get_warehouse_account_map()
|
||||
|
||||
for pi in frappe.get_all("Purchase Invoice", filters={"docstatus": 1, "update_stock": 1}):
|
||||
pi_doc = frappe.get_doc("Purchase Invoice", pi.name)
|
||||
items, warehouses = pi_doc.get_items_and_warehouses()
|
||||
update_gl_entries_after(pi_doc.posting_date, pi_doc.posting_time, warehouses, items, wh_account)
|
||||
for pi in frappe.get_all("Purchase Invoice", fields=["name", "company"], filters={"docstatus": 1, "update_stock": 1}):
|
||||
if pi.company in company_list:
|
||||
pi_doc = frappe.get_doc("Purchase Invoice", pi.name)
|
||||
items, warehouses = pi_doc.get_items_and_warehouses()
|
||||
update_gl_entries_after(pi_doc.posting_date, pi_doc.posting_time, warehouses, items, wh_account)
|
||||
|
||||
frappe.db.commit()
|
||||
frappe.db.commit()
|
@ -6,13 +6,11 @@ import frappe
|
||||
from frappe.utils import cint
|
||||
|
||||
def execute():
|
||||
if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
return
|
||||
|
||||
frappe.reload_doctype("Purchase Invoice")
|
||||
|
||||
for pi in frappe.db.sql("""select name from `tabPurchase Invoice`
|
||||
where update_stock=1 and docstatus=1 order by posting_date asc""", as_dict=1):
|
||||
where company in(select name from tabCompany where enable_perpetual_inventory = 1) and
|
||||
update_stock=1 and docstatus=1 order by posting_date asc""", as_dict=1):
|
||||
|
||||
frappe.db.sql("""delete from `tabGL Entry`
|
||||
where voucher_type = 'Purchase Invoice' and voucher_no = %s""", pi.name)
|
||||
|
13
erpnext/patches/v8_0/move_perpetual_inventory_setting.py
Normal file
13
erpnext/patches/v8_0/move_perpetual_inventory_setting.py
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doctype('Company')
|
||||
enabled = frappe.db.get_single_value("Accounts Settings", "auto_accounting_for_stock") or 0
|
||||
for data in frappe.get_all('Company', fields = ["name"]):
|
||||
doc = frappe.get_doc('Company', data.name)
|
||||
doc.enable_perpetual_inventory = enabled
|
||||
doc.save(ignore_permissions=True)
|
15
erpnext/patches/v8_0/save_system_settings.py
Normal file
15
erpnext/patches/v8_0/save_system_settings.py
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2017, Frappe and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
"""
|
||||
save system settings document
|
||||
"""
|
||||
|
||||
frappe.reload_doc("core", "doctype", "system_settings")
|
||||
doc = frappe.get_doc("System Settings", "System Settings")
|
||||
doc.flags.ignore_mandatory = True
|
||||
doc.save(ignore_permissions=True)
|
0
erpnext/patches/v8_1/__init__.py
Normal file
0
erpnext/patches/v8_1/__init__.py
Normal file
15
erpnext/patches/v8_1/delete_deprecated_reports.py
Normal file
15
erpnext/patches/v8_1/delete_deprecated_reports.py
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2017, Frappe and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
""" delete deprecated reports """
|
||||
|
||||
reports = ["Monthly Salary Register", "Customer Addresses And Contacts",
|
||||
"Supplier Addresses And Contacts"]
|
||||
|
||||
for report in reports:
|
||||
if frappe.db.exists("Report", report):
|
||||
frappe.delete_doc("Report", report, ignore_permissions=True)
|
@ -31,6 +31,12 @@ $.extend(erpnext, {
|
||||
}
|
||||
},
|
||||
|
||||
is_perpetual_inventory_enabled: function(company) {
|
||||
if(company) {
|
||||
return frappe.get_doc(":Company", company).enable_perpetual_inventory
|
||||
}
|
||||
},
|
||||
|
||||
setup_serial_no: function() {
|
||||
var grid_row = cur_frm.open_grid_row();
|
||||
if(!grid_row || !grid_row.grid_form.fields_dict.serial_no ||
|
||||
|
@ -156,7 +156,7 @@ erpnext.company.setup_queries = function(frm) {
|
||||
erpnext.company.set_custom_query(frm, v);
|
||||
});
|
||||
|
||||
if (frappe.sys_defaults.auto_accounting_for_stock) {
|
||||
if (frm.doc.enable_perpetual_inventory) {
|
||||
$.each([
|
||||
["stock_adjustment_account",
|
||||
{"root_type": "Expense", "account_type": "Stock Adjustment"}],
|
||||
|
@ -1122,6 +1122,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"fieldname": "enable_perpetual_inventory",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Enable Perpetual Inventory",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@ -1243,6 +1274,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -1777,7 +1809,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-06-14 11:06:33.629948",
|
||||
"modified": "2017-06-15 19:46:10.875108",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Company",
|
||||
|
@ -33,6 +33,7 @@ class Company(Document):
|
||||
self.validate_default_accounts()
|
||||
self.validate_currency()
|
||||
self.validate_coa_input()
|
||||
self.validate_perpetual_inventory()
|
||||
|
||||
def validate_abbr(self):
|
||||
if not self.abbr:
|
||||
@ -88,6 +89,10 @@ class Company(Document):
|
||||
if self.default_currency:
|
||||
frappe.db.set_value("Currency", self.default_currency, "enabled", 1)
|
||||
|
||||
if hasattr(frappe.local, 'enable_perpetual_inventory') and \
|
||||
self.name in frappe.local.enable_perpetual_inventory:
|
||||
frappe.local.enable_perpetual_inventory[self.name] = self.enable_perpetual_inventory
|
||||
|
||||
frappe.clear_cache()
|
||||
|
||||
def install_country_fixtures(self):
|
||||
@ -139,6 +144,12 @@ class Company(Document):
|
||||
if not self.chart_of_accounts:
|
||||
self.chart_of_accounts = "Standard"
|
||||
|
||||
def validate_perpetual_inventory(self):
|
||||
if not self.get("__islocal"):
|
||||
if cint(self.enable_perpetual_inventory) == 1 and not self.default_inventory_account:
|
||||
frappe.msgprint(_("Set default inventory account for perpetual inventory"),
|
||||
alert=True, indicator='orange')
|
||||
|
||||
def set_default_accounts(self):
|
||||
self._set_default_account("default_cash_account", "Cash")
|
||||
self._set_default_account("default_bank_account", "Bank")
|
||||
@ -146,7 +157,7 @@ class Company(Document):
|
||||
self._set_default_account("accumulated_depreciation_account", "Accumulated Depreciation")
|
||||
self._set_default_account("depreciation_expense_account", "Depreciation")
|
||||
|
||||
if cint(frappe.db.get_single_value("Accounts Settings", "auto_accounting_for_stock")):
|
||||
if self.enable_perpetual_inventory:
|
||||
self._set_default_account("stock_received_but_not_billed", "Stock Received But Not Billed")
|
||||
self._set_default_account("default_inventory_account", "Stock")
|
||||
self._set_default_account("stock_adjustment_account", "Stock Adjustment")
|
||||
|
@ -85,6 +85,7 @@ def create_fiscal_year_and_company(args):
|
||||
frappe.get_doc({
|
||||
"doctype":"Company",
|
||||
'company_name':args.get('company_name').strip(),
|
||||
'enable_perpetual_inventory': 1,
|
||||
'abbr':args.get('company_abbr'),
|
||||
'default_currency':args.get('currency'),
|
||||
'country': args.get('country'),
|
||||
@ -159,10 +160,6 @@ def set_defaults(args):
|
||||
|
||||
frappe.db.set_value("System Settings", None, "email_footer_address", args.get("company"))
|
||||
|
||||
accounts_settings = frappe.get_doc("Accounts Settings")
|
||||
accounts_settings.auto_accounting_for_stock = 1
|
||||
accounts_settings.save()
|
||||
|
||||
stock_settings = frappe.get_doc("Stock Settings")
|
||||
stock_settings.item_naming_by = "Item Code"
|
||||
stock_settings.valuation_method = "FIFO"
|
||||
|
@ -27,8 +27,8 @@ def boot_session(bootinfo):
|
||||
bootinfo.setup_complete = frappe.db.sql("""select name from
|
||||
tabCompany limit 1""") and 'Yes' or 'No'
|
||||
|
||||
bootinfo.docs += frappe.db.sql("""select name, default_currency, cost_center,
|
||||
default_terms, default_letter_head, default_bank_account from `tabCompany`""",
|
||||
bootinfo.docs += frappe.db.sql("""select name, default_currency, cost_center, default_terms,
|
||||
default_letter_head, default_bank_account, enable_perpetual_inventory from `tabCompany`""",
|
||||
as_dict=1, update={"doctype":":Company"})
|
||||
|
||||
def load_country_and_currency(bootinfo):
|
||||
|
@ -38,8 +38,9 @@ frappe.ui.form.on("Delivery Note", {
|
||||
}
|
||||
});
|
||||
|
||||
if (frappe.sys_defaults.auto_accounting_for_stock) {
|
||||
frm.set_query('expense_account', 'items', function(doc, cdt, cdn) {
|
||||
|
||||
frm.set_query('expense_account', 'items', function(doc, cdt, cdn) {
|
||||
if (erpnext.is_perpetual_inventory_enabled(doc.company)) {
|
||||
return {
|
||||
filters: {
|
||||
"report_type": "Profit and Loss",
|
||||
@ -47,17 +48,20 @@ frappe.ui.form.on("Delivery Note", {
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query('cost_center', 'items', function(doc, cdt, cdn) {
|
||||
frm.set_query('cost_center', 'items', function(doc, cdt, cdn) {
|
||||
if (erpnext.is_perpetual_inventory_enabled(doc.company)) {
|
||||
return {
|
||||
filters: {
|
||||
'company': doc.company,
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$.extend(frm.cscript, new erpnext.stock.DeliveryNoteController({frm: frm}));
|
||||
},
|
||||
@ -137,7 +141,7 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
|
||||
|
||||
if (doc.docstatus==1) {
|
||||
this.show_stock_ledger();
|
||||
if (cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
|
||||
if (erpnext.is_perpetual_inventory_enabled(doc.company)) {
|
||||
this.show_general_ledger();
|
||||
}
|
||||
if (this.frm.has_perm("submit") && doc.status !== "Closed") {
|
||||
@ -164,10 +168,6 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
|
||||
__("Status"))
|
||||
}
|
||||
erpnext.stock.delivery_note.set_print_hide(doc, dt, dn);
|
||||
|
||||
// unhide expense_account and cost_center is auto_accounting_for_stock enabled
|
||||
var aii_enabled = cint(frappe.sys_defaults.auto_accounting_for_stock)
|
||||
this.frm.fields_dict["items"].grid.set_column_disp(["expense_account", "cost_center"], aii_enabled);
|
||||
},
|
||||
|
||||
make_sales_invoice: function() {
|
||||
@ -225,6 +225,24 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
|
||||
|
||||
});
|
||||
|
||||
frappe.ui.form.on('Delivery Note', {
|
||||
setup: function(frm) {
|
||||
if(frm.doc.company) {
|
||||
frm.trigger("unhide_account_head");
|
||||
}
|
||||
},
|
||||
|
||||
company: function(frm) {
|
||||
frm.trigger("unhide_account_head");
|
||||
},
|
||||
|
||||
unhide_account_head: function(frm) {
|
||||
// unhide expense_account and cost_center if perpetual inventory is enabled in the company
|
||||
var aii_enabled = erpnext.is_perpetual_inventory_enabled(frm.doc.company)
|
||||
frm.fields_dict["items"].grid.set_column_disp(["expense_account", "cost_center"], aii_enabled);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){
|
||||
var dn_fields = frappe.meta.docfield_map['Delivery Note'];
|
||||
|
@ -47,9 +47,8 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
self.assertRaises(frappe.ValidationError, frappe.get_doc(si).insert)
|
||||
|
||||
def test_delivery_note_no_gl_entry(self):
|
||||
set_perpetual_inventory(0)
|
||||
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 0)
|
||||
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(0, company)
|
||||
make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100)
|
||||
|
||||
stock_queue = json.loads(get_previous_sle({
|
||||
@ -68,8 +67,9 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
self.assertFalse(get_gl_entries("Delivery Note", dn.name))
|
||||
|
||||
def test_delivery_note_gl_entry(self):
|
||||
set_perpetual_inventory()
|
||||
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(1, company)
|
||||
|
||||
set_valuation_method("_Test Item", "FIFO")
|
||||
|
||||
make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100)
|
||||
@ -115,10 +115,11 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
|
||||
dn.cancel()
|
||||
self.assertFalse(get_gl_entries("Delivery Note", dn.name))
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, company)
|
||||
|
||||
def test_delivery_note_gl_entry_packing_item(self):
|
||||
set_perpetual_inventory()
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(1, company)
|
||||
|
||||
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=10, basic_rate=100)
|
||||
make_stock_entry(item_code="_Test Item Home Desktop 100",
|
||||
@ -156,7 +157,7 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
dn.cancel()
|
||||
self.assertFalse(get_gl_entries("Delivery Note", dn.name))
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, company)
|
||||
|
||||
def test_serialized(self):
|
||||
se = make_serialized_item()
|
||||
@ -196,7 +197,8 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
self.assertEquals(cstr(serial_no.get(field)), value)
|
||||
|
||||
def test_sales_return_for_non_bundled_items(self):
|
||||
set_perpetual_inventory()
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(1, company)
|
||||
|
||||
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100)
|
||||
|
||||
@ -230,10 +232,11 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
|
||||
self.assertEquals(gle_warehouse_amount, stock_value_difference)
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, company)
|
||||
|
||||
def test_return_single_item_from_bundled_items(self):
|
||||
set_perpetual_inventory()
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(1, company)
|
||||
|
||||
create_stock_reconciliation(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, rate=100)
|
||||
create_stock_reconciliation(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC",
|
||||
@ -270,10 +273,11 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
|
||||
self.assertEquals(gle_warehouse_amount, stock_value_difference)
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, company)
|
||||
|
||||
def test_return_entire_bundled_items(self):
|
||||
set_perpetual_inventory()
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(1, company)
|
||||
|
||||
create_stock_reconciliation(item_code="_Test Item",
|
||||
target="_Test Warehouse - _TC", qty=50, rate=100)
|
||||
@ -312,7 +316,7 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
|
||||
self.assertEquals(gle_warehouse_amount, 1400)
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, company)
|
||||
|
||||
def test_return_for_serialized_items(self):
|
||||
se = make_serialized_item()
|
||||
@ -350,7 +354,8 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
})
|
||||
|
||||
def test_delivery_of_bundled_items_to_target_warehouse(self):
|
||||
set_perpetual_inventory()
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(1, company)
|
||||
|
||||
set_valuation_method("_Test Item", "FIFO")
|
||||
set_valuation_method("_Test Item Home Desktop 100", "FIFO")
|
||||
@ -418,7 +423,7 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account))
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, company)
|
||||
|
||||
def test_closed_delivery_note(self):
|
||||
from erpnext.stock.doctype.delivery_note.delivery_note import update_delivery_note_status
|
||||
|
@ -5,13 +5,13 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, unittest
|
||||
import frappe, unittest, erpnext
|
||||
from frappe.utils import flt
|
||||
from erpnext.stock.doctype.material_request.material_request import raise_production_orders
|
||||
|
||||
class TestMaterialRequest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
frappe.defaults.set_global_default("auto_accounting_for_stock", 0)
|
||||
erpnext.set_perpetual_inventory(0)
|
||||
|
||||
def test_make_purchase_order(self):
|
||||
from erpnext.stock.doctype.material_request.material_request import make_purchase_order
|
||||
|
@ -33,6 +33,21 @@ frappe.ui.form.on("Purchase Receipt", {
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if(frm.doc.company) {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
}
|
||||
},
|
||||
|
||||
company: function(frm) {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
},
|
||||
|
||||
toggle_display_account_head: function(frm) {
|
||||
var enabled = erpnext.is_perpetual_inventory_enabled(frm.doc.company)
|
||||
frm.fields_dict["items"].grid.set_column_disp(["cost_center"], enabled);
|
||||
}
|
||||
});
|
||||
|
||||
@ -47,7 +62,7 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend
|
||||
this._super();
|
||||
if(this.frm.doc.docstatus===1) {
|
||||
this.show_stock_ledger();
|
||||
if (cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
|
||||
if (erpnext.is_perpetual_inventory_enabled(this.frm.doc.company)) {
|
||||
this.show_general_ledger();
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
import frappe.defaults
|
||||
from frappe.utils import cint, flt, cstr, today
|
||||
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
|
||||
@ -30,7 +30,8 @@ class TestPurchaseReceipt(unittest.TestCase):
|
||||
self.assertRaises(frappe.ValidationError, frappe.get_doc(pi).submit)
|
||||
|
||||
def test_purchase_receipt_no_gl_entry(self):
|
||||
set_perpetual_inventory(0)
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(0, company)
|
||||
|
||||
existing_bin_stock_value = frappe.db.get_value("Bin", {"item_code": "_Test Item",
|
||||
"warehouse": "_Test Warehouse - _TC"}, "stock_value")
|
||||
@ -50,9 +51,9 @@ class TestPurchaseReceipt(unittest.TestCase):
|
||||
self.assertFalse(get_gl_entries("Purchase Receipt", pr.name))
|
||||
|
||||
def test_purchase_receipt_gl_entry(self):
|
||||
set_perpetual_inventory()
|
||||
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
||||
pr = frappe.copy_doc(test_records[0])
|
||||
set_perpetual_inventory(1, pr.company)
|
||||
self.assertEqual(cint(erpnext.is_perpetual_inventory_enabled(pr.company)), 1)
|
||||
pr.insert()
|
||||
pr.submit()
|
||||
|
||||
@ -84,7 +85,7 @@ class TestPurchaseReceipt(unittest.TestCase):
|
||||
pr.cancel()
|
||||
self.assertFalse(get_gl_entries("Purchase Receipt", pr.name))
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, pr.company)
|
||||
|
||||
def test_subcontracting(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -67,6 +67,10 @@ frappe.ui.form.on('Stock Entry', {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if(frm.doc.company) {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
}
|
||||
},
|
||||
purpose: function(frm) {
|
||||
frm.fields_dict.items.grid.refresh();
|
||||
@ -78,6 +82,7 @@ frappe.ui.form.on('Stock Entry', {
|
||||
if(company_doc.default_letter_head) {
|
||||
frm.set_value("letter_head", company_doc.default_letter_head);
|
||||
}
|
||||
frm.trigger("toggle_display_account_head");
|
||||
}
|
||||
},
|
||||
set_serial_no: function(frm, cdt, cdn) {
|
||||
@ -98,6 +103,10 @@ frappe.ui.form.on('Stock Entry', {
|
||||
}
|
||||
});
|
||||
},
|
||||
toggle_display_account_head: function(frm) {
|
||||
var enabled = erpnext.is_perpetual_inventory_enabled(frm.doc.company);
|
||||
frm.fields_dict["items"].grid.set_column_disp(["cost_center", "expense_account"], enabled);
|
||||
}
|
||||
})
|
||||
|
||||
frappe.ui.form.on('Stock Entry Detail', {
|
||||
@ -213,17 +222,19 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
};
|
||||
});
|
||||
|
||||
if(cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
|
||||
if(me.frm.doc.company && erpnext.is_perpetual_inventory_enabled(me.frm.doc.company)) {
|
||||
this.frm.add_fetch("company", "stock_adjustment_account", "expense_account");
|
||||
this.frm.fields_dict.items.grid.get_field('expense_account').get_query =
|
||||
function() {
|
||||
return {
|
||||
filters: {
|
||||
"company": me.frm.doc.company,
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
|
||||
this.frm.fields_dict.items.grid.get_field('expense_account').get_query = function() {
|
||||
if (erpnext.is_perpetual_inventory_enabled(me.frm.doc.company)) {
|
||||
return {
|
||||
filters: {
|
||||
"company": me.frm.doc.company,
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.frm.set_indicator_formatter('item_code',
|
||||
@ -254,7 +265,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
this.toggle_related_fields(this.frm.doc);
|
||||
this.toggle_enable_bom();
|
||||
this.show_stock_ledger();
|
||||
if (cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
|
||||
if (this.frm.doc.docstatus===1 && erpnext.is_perpetual_inventory_enabled(this.frm.doc.company)) {
|
||||
this.show_general_ledger();
|
||||
}
|
||||
erpnext.hide_company();
|
||||
@ -272,7 +283,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
set_default_account: function(callback) {
|
||||
var me = this;
|
||||
|
||||
if(cint(frappe.defaults.get_default("auto_accounting_for_stock")) && this.frm.doc.company) {
|
||||
if(this.frm.doc.company && erpnext.is_perpetual_inventory_enabled(this.frm.doc.company)) {
|
||||
return this.frm.call({
|
||||
method: "erpnext.accounts.utils.get_company_default",
|
||||
args: {
|
||||
|
@ -123,7 +123,8 @@ class TestStockEntry(unittest.TestCase):
|
||||
self.assertTrue(item_code in items)
|
||||
|
||||
def test_material_receipt_gl_entry(self):
|
||||
set_perpetual_inventory()
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(1, company)
|
||||
|
||||
mr = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
||||
qty=50, basic_rate=100, expense_account="Stock Adjustment - _TC")
|
||||
@ -148,7 +149,8 @@ class TestStockEntry(unittest.TestCase):
|
||||
where voucher_type='Stock Entry' and voucher_no=%s""", mr.name))
|
||||
|
||||
def test_material_issue_gl_entry(self):
|
||||
set_perpetual_inventory()
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(1, company)
|
||||
|
||||
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
||||
qty=50, basic_rate=100, expense_account="Stock Adjustment - _TC")
|
||||
@ -179,7 +181,8 @@ class TestStockEntry(unittest.TestCase):
|
||||
where voucher_type='Stock Entry' and voucher_no=%s""", mi.name))
|
||||
|
||||
def test_material_transfer_gl_entry(self):
|
||||
set_perpetual_inventory()
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(1, company)
|
||||
|
||||
create_stock_reconciliation(qty=100, rate=100)
|
||||
|
||||
@ -217,7 +220,8 @@ class TestStockEntry(unittest.TestCase):
|
||||
where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name))
|
||||
|
||||
def test_repack_no_change_in_valuation(self):
|
||||
set_perpetual_inventory(0)
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(0, company)
|
||||
|
||||
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100)
|
||||
make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC",
|
||||
@ -238,10 +242,11 @@ class TestStockEntry(unittest.TestCase):
|
||||
order by account desc""", repack.name, as_dict=1)
|
||||
self.assertFalse(gl_entries)
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, repack.company)
|
||||
|
||||
def test_repack_with_additional_costs(self):
|
||||
set_perpetual_inventory()
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
|
||||
set_perpetual_inventory(1, company)
|
||||
|
||||
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100)
|
||||
repack = frappe.copy_doc(test_records[3])
|
||||
@ -278,7 +283,7 @@ class TestStockEntry(unittest.TestCase):
|
||||
["Expenses Included In Valuation - _TC", 0.0, 1200.0]
|
||||
])
|
||||
)
|
||||
set_perpetual_inventory(0)
|
||||
set_perpetual_inventory(0, repack.company)
|
||||
|
||||
def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle):
|
||||
expected_sle.sort(key=lambda x: x[0])
|
||||
@ -452,7 +457,8 @@ class TestStockEntry(unittest.TestCase):
|
||||
self.assertFalse(frappe.db.get_value("Serial No", serial_no, "warehouse"))
|
||||
|
||||
def test_warehouse_company_validation(self):
|
||||
set_perpetual_inventory(0)
|
||||
company = frappe.db.get_value('Warehouse', '_Test Warehouse 2 - _TC1', 'company')
|
||||
set_perpetual_inventory(0, company)
|
||||
frappe.get_doc("User", "test2@example.com")\
|
||||
.add_roles("Sales User", "Sales Manager", "Stock User", "Stock Manager")
|
||||
frappe.set_user("test2@example.com")
|
||||
@ -465,8 +471,6 @@ class TestStockEntry(unittest.TestCase):
|
||||
|
||||
# permission tests
|
||||
def test_warehouse_user(self):
|
||||
set_perpetual_inventory(0)
|
||||
|
||||
for role in ("Stock User", "Sales User"):
|
||||
set_user_permission_doctypes(doctype="Stock Entry", role=role,
|
||||
apply_user_permissions=1, user_permission_doctypes=["Warehouse"])
|
||||
@ -483,6 +487,7 @@ class TestStockEntry(unittest.TestCase):
|
||||
frappe.set_user("test@example.com")
|
||||
st1 = frappe.copy_doc(test_records[0])
|
||||
st1.company = "_Test Company 1"
|
||||
set_perpetual_inventory(0, st1.company)
|
||||
st1.get("items")[0].t_warehouse="_Test Warehouse 2 - _TC1"
|
||||
self.assertRaises(frappe.PermissionError, st1.insert)
|
||||
|
||||
@ -490,6 +495,8 @@ class TestStockEntry(unittest.TestCase):
|
||||
st1 = frappe.copy_doc(test_records[0])
|
||||
st1.company = "_Test Company 1"
|
||||
st1.get("items")[0].t_warehouse="_Test Warehouse 2 - _TC1"
|
||||
st1.get("items")[0].expense_account = "Stock Adjustment - _TC1"
|
||||
st1.get("items")[0].cost_center = "Main - _TC1"
|
||||
st1.insert()
|
||||
st1.submit()
|
||||
|
||||
|
@ -960,7 +960,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:cint(frappe.sys_defaults.auto_accounting_for_stock)",
|
||||
"depends_on": "",
|
||||
"fieldname": "expense_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -1020,7 +1020,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": ":Company",
|
||||
"depends_on": "eval:cint(frappe.sys_defaults.auto_accounting_for_stock)",
|
||||
"depends_on": "",
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -1266,8 +1266,8 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-06-08 10:38:10.914780",
|
||||
"modified_by": "prateeksha@erpnext.com",
|
||||
"modified": "2017-06-16 17:32:56.989049",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Entry Detail",
|
||||
"owner": "Administrator",
|
||||
|
@ -31,6 +31,10 @@ frappe.ui.form.on("Stock Reconciliation", {
|
||||
frm.events.get_items(frm);
|
||||
});
|
||||
}
|
||||
|
||||
if(frm.doc.company) {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
}
|
||||
},
|
||||
|
||||
get_items: function(frm) {
|
||||
@ -103,6 +107,13 @@ frappe.ui.form.on("Stock Reconciliation", {
|
||||
frappe.model.set_value(cdt, cdn, "quantity_difference", flt(d.qty) - flt(d.current_qty));
|
||||
frappe.model.set_value(cdt, cdn, "amount_difference", flt(d.amount) - flt(d.current_amount));
|
||||
}
|
||||
},
|
||||
company: function(frm) {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
},
|
||||
toggle_display_account_head: function(frm) {
|
||||
frm.toggle_display(['expense_account', 'cost_center'],
|
||||
erpnext.is_perpetual_inventory_enabled(frm.doc.company));
|
||||
}
|
||||
});
|
||||
|
||||
@ -133,7 +144,7 @@ erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({
|
||||
set_default_expense_account: function() {
|
||||
var me = this;
|
||||
if(this.frm.doc.company) {
|
||||
if (frappe.sys_defaults.auto_accounting_for_stock && !this.frm.doc.expense_account) {
|
||||
if (erpnext.is_perpetual_inventory_enabled(this.frm.doc.company) && !this.frm.doc.expense_account) {
|
||||
return this.frm.call({
|
||||
method: "erpnext.accounts.utils.get_company_default",
|
||||
args: {
|
||||
@ -155,11 +166,12 @@ erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({
|
||||
|
||||
this.setup_posting_date_time_check();
|
||||
|
||||
if (frappe.sys_defaults.auto_accounting_for_stock) {
|
||||
if (me.frm.doc.company && erpnext.is_perpetual_inventory_enabled(me.frm.doc.company)) {
|
||||
this.frm.add_fetch("company", "stock_adjustment_account", "expense_account");
|
||||
this.frm.add_fetch("company", "cost_center", "cost_center");
|
||||
|
||||
this.frm.fields_dict["expense_account"].get_query = function() {
|
||||
}
|
||||
this.frm.fields_dict["expense_account"].get_query = function() {
|
||||
if(erpnext.is_perpetual_inventory_enabled(me.frm.doc.company)) {
|
||||
return {
|
||||
"filters": {
|
||||
'company': me.frm.doc.company,
|
||||
@ -167,7 +179,9 @@ erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({
|
||||
}
|
||||
}
|
||||
}
|
||||
this.frm.fields_dict["cost_center"].get_query = function() {
|
||||
}
|
||||
this.frm.fields_dict["cost_center"].get_query = function() {
|
||||
if(erpnext.is_perpetual_inventory_enabled(me.frm.doc.company)) {
|
||||
return {
|
||||
"filters": {
|
||||
'company': me.frm.doc.company,
|
||||
@ -181,7 +195,7 @@ erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({
|
||||
refresh: function() {
|
||||
if(this.frm.doc.docstatus==1) {
|
||||
this.show_stock_ledger();
|
||||
if (cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
|
||||
if (erpnext.is_perpetual_inventory_enabled(this.frm.doc.company)) {
|
||||
this.show_general_ledger();
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +320,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||
"depends_on": "",
|
||||
"fieldname": "expense_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -351,7 +351,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
|
||||
"depends_on": "",
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -477,7 +477,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 1,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-06-13 14:28:56.013804",
|
||||
"modified": "2017-06-16 17:35:54.811500",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Reconciliation",
|
||||
|
@ -2,7 +2,7 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
import frappe.defaults
|
||||
from frappe import msgprint, _
|
||||
from frappe.utils import cstr, flt, cint
|
||||
@ -231,7 +231,7 @@ class StockReconciliation(StockController):
|
||||
self.expense_account, self.cost_center)
|
||||
|
||||
def validate_expense_account(self):
|
||||
if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
if not cint(erpnext.is_perpetual_inventory_enabled(self.company)):
|
||||
return
|
||||
|
||||
if not self.expense_account:
|
||||
|
@ -423,8 +423,11 @@ def get_stock_ledger_entries(previous_sle, operator=None, order="desc", limit=No
|
||||
}, previous_sle, as_dict=1, debug=debug)
|
||||
|
||||
def get_valuation_rate(item_code, warehouse, voucher_type, voucher_no,
|
||||
allow_zero_rate=False, currency=None):
|
||||
allow_zero_rate=False, currency=None, company=None):
|
||||
# Get valuation rate from last sle for the same item and warehouse
|
||||
if not company:
|
||||
company = erpnext.get_default_company()
|
||||
|
||||
last_valuation_rate = frappe.db.sql("""select valuation_rate
|
||||
from `tabStock Ledger Entry`
|
||||
where item_code = %s and warehouse = %s
|
||||
@ -451,7 +454,7 @@ def get_valuation_rate(item_code, warehouse, voucher_type, voucher_no,
|
||||
dict(item_code=item_code, buying=1, currency=currency), 'price_list_rate')
|
||||
|
||||
if not allow_zero_rate and not valuation_rate \
|
||||
and cint(frappe.db.get_value("Accounts Settings", None, "auto_accounting_for_stock")):
|
||||
and cint(erpnext.is_perpetual_inventory_enabled(company)):
|
||||
frappe.local.message_log = []
|
||||
frappe.throw(_("Valuation rate not found for the Item {0}, which is required to do accounting entries for {1} {2}. If the item is transacting as a sample item in the {1}, please mention that in the {1} Item table. Otherwise, please create an incoming stock transaction for the item or mention valuation rate in the Item record, and then try submiting/cancelling this entry").format(item_code, voucher_type, voucher_no))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user