Merge branch 'staging-fixes' into company_address
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 4197d54..b9b5347 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
-__version__ = '10.1.76'
+__version__ = '10.1.77'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js
index c18057e..779cd61 100644
--- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js
+++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js
@@ -39,6 +39,8 @@
});
frm.events.get_total_gain_loss(frm);
refresh_field("accounts");
+ } else {
+ frappe.msgprint(__("No records found"));
}
}
});
diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
index ae77516..cdfe34b 100644
--- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
+++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
@@ -67,17 +67,19 @@
and account_currency != %s
order by name""",(self.company, company_currency))
- account_details = frappe.db.sql("""
- select
- account, party_type, party, account_currency,
- sum(debit_in_account_currency) - sum(credit_in_account_currency) as balance_in_account_currency,
- sum(debit) - sum(credit) as balance
- from `tabGL Entry`
- where account in (%s)
- group by account, party_type, party
- having sum(debit) != sum(credit)
- order by account
- """ % ', '.join(['%s']*len(accounts)), tuple(accounts), as_dict=1)
+ account_details = []
+ if accounts:
+ account_details = frappe.db.sql("""
+ select
+ account, party_type, party, account_currency,
+ sum(debit_in_account_currency) - sum(credit_in_account_currency) as balance_in_account_currency,
+ sum(debit) - sum(credit) as balance
+ from `tabGL Entry`
+ where account in (%s)
+ group by account, party_type, party
+ having sum(debit) != sum(credit)
+ order by account
+ """ % ', '.join(['%s']*len(accounts)), tuple(accounts), as_dict=1)
return account_details
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index e6fe6ca..810b6f7 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -18,15 +18,14 @@
self.flags.ignore_submit_comment = True
self.check_mandatory()
self.validate_and_set_fiscal_year()
+ self.pl_must_have_cost_center()
+ self.validate_cost_center()
if not self.flags.from_repost:
- self.pl_must_have_cost_center()
self.check_pl_account()
- self.validate_cost_center()
self.validate_party()
self.validate_currency()
-
def on_update_with_args(self, adv_adj, update_outstanding = 'Yes', from_repost=False):
if not from_repost:
self.validate_account_details(adv_adj)
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index 2ed664c..7ecc695 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -200,7 +200,7 @@
def skip_row(self, row, product_bundles):
if self.filters.get("group_by") != "Invoice":
- if not row.get(scrub(self.filters.get("group_by"))):
+ if not row.get(scrub(self.filters.get("group_by", ""))):
return True
elif row.get("is_return") == 1:
return True
@@ -316,7 +316,7 @@
on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
{sales_team_table}
where
- `tabSales Invoice`.docstatus=1 {conditions} {match_cond}
+ `tabSales Invoice`.docstatus=1 and `tabSales Invoice`.is_opening!='Yes' {conditions} {match_cond}
order by
`tabSales Invoice`.posting_date desc, `tabSales Invoice`.posting_time desc"""
.format(conditions=conditions, sales_person_cols=sales_person_cols,
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index 5296e22..6b3c3cc73 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
@@ -154,7 +155,7 @@
"columns": 0,
"fetch_from": "item_code.asset_category",
"fieldname": "asset_category",
- "fieldtype": "Read Only",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -165,12 +166,12 @@
"label": "Asset Category",
"length": 0,
"no_copy": 0,
- "options": "",
+ "options": "Asset Category",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -1881,7 +1882,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-21 14:44:24.507215",
+ "modified": "2019-01-15 16:12:48.314196",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 24ce7d4..9bf3858 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -499,7 +499,8 @@
conditions = ""
warehouse = row.source_warehouse or row.default_warehouse or row.warehouse
if warehouse:
- conditions = " and warehouse='{0}'".format(frappe.db.escape(warehouse))
+ lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
+ conditions = " and exists(select name from `tabWarehouse` where lft >= {0} and rgt <= {1} and name=`tabBin`.warehouse)".format(lft, rgt)
item_projected_qty = frappe.db.sql(""" select ifnull(sum(projected_qty),0) as projected_qty,
ifnull(sum(actual_qty),0) as actual_qty from `tabBin`
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index af2463f..082f887 100755
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -1,9 +1,9 @@
execute:import unidecode # new requirement
erpnext.patches.v8_0.move_perpetual_inventory_setting
+erpnext.patches.v11_0.rename_production_order_to_work_order
erpnext.patches.v11_0.refactor_naming_series
erpnext.patches.v11_0.refactor_autoname_naming
erpnext.patches.v10_0.rename_schools_to_education
-erpnext.patches.v11_0.rename_production_order_to_work_order
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
diff --git a/erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py b/erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py
index 8313096..52d4621 100644
--- a/erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py
+++ b/erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py
@@ -1,3 +1,4 @@
+from __future__ import unicode_literals
import frappe
from frappe.model.rename_doc import rename_doc
from frappe.model.utils.rename_field import rename_field
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 649d73a..371fc5c 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -12,6 +12,7 @@
class CircularReferenceError(frappe.ValidationError): pass
+class EndDateCannotBeGreaterThanProjectEndDateError(frappe.ValidationError): pass
class Task(NestedSet):
nsm_parent_field = 'parent_task'
@@ -43,6 +44,12 @@
if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date):
frappe.throw(_("'Actual Start Date' can not be greater than 'Actual End Date'"))
+ if(self.project):
+ if frappe.db.exists("Project", self.project):
+ expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date")
+ if self.exp_end_date and expected_end_date and getdate(self.exp_end_date) > getdate(expected_end_date) :
+ frappe.throw(_("Expected end date cannot be after Project: <b>'{0}'</b> Expected end date").format(self.project), EndDateCannotBeGreaterThanProjectEndDateError)
+
def validate_status(self):
if self.status!=self.get_db_value("status") and self.status == "Closed":
for d in self.depends_on:
diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py
index 0966b76..6fb5412 100644
--- a/erpnext/projects/doctype/task/test_task.py
+++ b/erpnext/projects/doctype/task/test_task.py
@@ -5,11 +5,11 @@
import unittest
from frappe.utils import getdate, nowdate, add_days
-from erpnext.projects.doctype.task.task import CircularReferenceError
+from erpnext.projects.doctype.task.task import CircularReferenceError, EndDateCannotBeGreaterThanProjectEndDateError
class TestTask(unittest.TestCase):
def test_circular_reference(self):
- task1 = create_task("_Test Task 1", nowdate(), add_days(nowdate(), 10))
+ task1 = create_task("_Test Task 1", add_days(nowdate(), -15), add_days(nowdate(), -10))
task2 = create_task("_Test Task 2", add_days(nowdate(), 11), add_days(nowdate(), 15), task1.name)
task3 = create_task("_Test Task 3", add_days(nowdate(), 11), add_days(nowdate(), 15), task2.name)
@@ -97,7 +97,16 @@
self.assertEqual(frappe.db.get_value("Task", task.name, "status"), "Overdue")
-def create_task(subject, start=None, end=None, depends_on=None, project=None):
+ def test_end_date_validation(self):
+ task_end = create_task("Testing_Enddate_validation", add_days(nowdate(), 35), add_days(nowdate(), 45), save=False)
+ pro = frappe.get_doc("Project", task_end.project)
+ pro.expected_end_date = add_days(nowdate(), 40)
+ pro.save()
+ self.assertRaises(EndDateCannotBeGreaterThanProjectEndDateError, task_end.save)
+
+
+
+def create_task(subject, start=None, end=None, depends_on=None, project=None, save=True):
if not frappe.db.exists("Task", subject):
task = frappe.new_doc('Task')
task.status = "Open"
@@ -105,7 +114,8 @@
task.exp_start_date = start or nowdate()
task.exp_end_date = end or nowdate()
task.project = project or "_Test Project"
- task.save()
+ if save:
+ task.save()
else:
task = frappe.get_doc("Task", subject)
@@ -113,6 +123,7 @@
task.append("depends_on", {
"task": depends_on
})
- task.save()
+ if save:
+ task.save()
return task
\ No newline at end of file
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 035c58d..9dd9beb 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -416,6 +416,7 @@
item_code: item.item_code,
barcode: item.barcode,
serial_no: item.serial_no,
+ set_warehouse: me.frm.doc.set_warehouse,
warehouse: item.warehouse,
customer: me.frm.doc.customer,
supplier: me.frm.doc.supplier,
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index ea600e4..78aeee7 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -11,22 +11,49 @@
if not hasattr(doc, 'gstin'):
return
- if doc.gstin:
- doc.gstin = doc.gstin.upper()
- if doc.gstin not in ["NA", "na"]:
- p = re.compile("[0-9]{2}[a-zA-Z]{5}[0-9]{4}[a-zA-Z]{1}[1-9A-Za-z]{1}[Z]{1}[0-9a-zA-Z]{1}")
- if not p.match(doc.gstin):
- frappe.throw(_("Invalid GSTIN or Enter NA for Unregistered"))
+ doc.gstin = doc.gstin.upper().strip()
+ if not doc.gstin or doc.gstin == 'NA':
+ return
+
+ if len(doc.gstin) != 15:
+ frappe.throw(_("Invalid GSTIN! A GSTIN must have 15 characters."))
+
+ p = re.compile("^[0-9]{2}[A-Z]{4}[0-9A-Z]{1}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}[1-9A-Z]{1}[0-9A-Z]{1}$")
+ if not p.match(doc.gstin):
+ frappe.throw(_("Invalid GSTIN! The input you've entered doesn't match the format of GSTIN."))
+
+ validate_gstin_check_digit(doc.gstin)
if not doc.gst_state:
- if doc.state in states:
- doc.gst_state = doc.state
+ if not doc.state:
+ return
+ state = doc.state.lower()
+ states_lowercase = {s.lower():s for s in states}
+ if state in states_lowercase:
+ doc.gst_state = states_lowercase[state]
+ else:
+ return
- if doc.gst_state:
- doc.gst_state_number = state_numbers[doc.gst_state]
- if doc.gstin and doc.gstin != "NA" and doc.gst_state_number != doc.gstin[:2]:
- frappe.throw(_("First 2 digits of GSTIN should match with State number {0}")
- .format(doc.gst_state_number))
+ doc.gst_state_number = state_numbers[doc.gst_state]
+ if doc.gst_state_number != doc.gstin[:2]:
+ frappe.throw(_("Invalid GSTIN! First 2 digits of GSTIN should match with State number {0}.")
+ .format(doc.gst_state_number))
+
+def validate_gstin_check_digit(gstin):
+ ''' Function to validate the check digit of the GSTIN.'''
+ factor = 1
+ total = 0
+ code_point_chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ mod = len(code_point_chars)
+ input_chars = gstin[:-1]
+ for char in input_chars:
+ digit = factor * code_point_chars.find(char)
+ digit = (digit // mod) + (digit % mod)
+ total += digit
+ factor = 2 if factor == 1 else 1
+ if gstin[-1] != code_point_chars[((mod - (total % mod)) % mod)]:
+ frappe.throw(_("Invalid GSTIN! The check digit validation has failed. " +
+ "Please ensure you've typed the GSTIN correctly."))
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
if frappe.get_meta(item_doctype).has_field('gst_hsn_code'):
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 0da8272..2970d7a 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -177,6 +177,11 @@
frappe.throw(_("""New credit limit is less than current outstanding amount for the customer. Credit limit has to be atleast {0}""").format(outstanding_amt))
def on_trash(self):
+ if self.customer_primary_contact:
+ frappe.db.sql("""update `tabCustomer`
+ set customer_primary_contact=null, mobile_no=null, email_id=null
+ where name=%s""", self.name)
+
delete_contact_and_address('Customer', self.name)
if self.lead_name:
frappe.db.sql("update `tabLead` set status='Interested' where name=%s", self.lead_name)
diff --git a/erpnext/selling/doctype/customer/test_customer.py b/erpnext/selling/doctype/customer/test_customer.py
index cc2fc59..fa4f835 100644
--- a/erpnext/selling/doctype/customer/test_customer.py
+++ b/erpnext/selling/doctype/customer/test_customer.py
@@ -98,6 +98,15 @@
so.save()
+ def test_delete_customer_contact(self):
+ customer = frappe.get_doc(
+ get_customer_dict('_Test Customer for delete')).insert(ignore_permissions=True)
+
+ customer.mobile_no = "8989889890"
+ customer.save()
+ self.assertTrue(customer.customer_primary_contact)
+ frappe.delete_doc('Customer', customer.name)
+
def test_disabled_customer(self):
make_test_records("Item")
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py
index c078a08..3239fc6 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.py
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _, scrub
-from frappe.utils import getdate, flt
+from frappe.utils import getdate, flt, add_to_date, add_days
from six import iteritems
from erpnext.accounts.utils import get_fiscal_year
@@ -40,7 +40,7 @@
"fieldtype": "Data",
"width": 140
})
- for dummy, end_date in self.periodic_daterange:
+ for end_date in self.periodic_daterange:
period = self.get_period(end_date)
self.columns.append({
"label": _(period),
@@ -169,7 +169,7 @@
"entity_name": self.entity_names.get(entity)
}
total = 0
- for dummy, end_date in self.periodic_daterange:
+ for end_date in self.periodic_daterange:
period = self.get_period(end_date)
amount = flt(period_data.get(period, 0.0))
row[scrub(period)] = amount
@@ -188,7 +188,7 @@
"indent": self.depth_map.get(d.name)
}
total = 0
- for dummy, end_date in self.periodic_daterange:
+ for end_date in self.periodic_daterange:
period = self.get_period(end_date)
amount = flt(self.entity_periodic_data.get(d.name, {}).get(period, 0.0))
row[scrub(period)] = amount
@@ -219,12 +219,11 @@
period = "Quarter " + str(((posting_date.month-1)//3)+1) +" " + str(posting_date.year)
else:
year = get_fiscal_year(posting_date, company=self.filters.company)
- period = str(year[2])
-
+ period = str(year[0])
return period
def get_period_date_ranges(self):
- from dateutil.relativedelta import relativedelta
+ from dateutil.relativedelta import relativedelta, MO
from_date, to_date = getdate(self.filters.from_date), getdate(self.filters.to_date)
increment = {
@@ -234,18 +233,26 @@
"Yearly": 12
}.get(self.filters.range, 1)
+ if self.filters.range in ['Monthly', 'Quarterly']:
+ from_date = from_date.replace(day = 1)
+ elif self.filters.range == "Yearly":
+ from_date = get_fiscal_year(from_date)[1]
+ else:
+ from_date = from_date + relativedelta(from_date, weekday=MO(-1))
+
self.periodic_daterange = []
- for dummy in range(1, 53, increment):
+ for dummy in range(1, 53):
if self.filters.range == "Weekly":
- period_end_date = from_date + relativedelta(days=6)
+ period_end_date = add_days(from_date, 6)
else:
- period_end_date = from_date + relativedelta(months=increment, days=-1)
+ period_end_date = add_to_date(from_date, months=increment, days=-1)
if period_end_date > to_date:
period_end_date = to_date
- self.periodic_daterange.append([from_date, period_end_date])
- from_date = period_end_date + relativedelta(days=1)
+ self.periodic_daterange.append(period_end_date)
+
+ from_date = add_days(period_end_date, 1)
if period_end_date == to_date:
break
diff --git a/erpnext/setup/default_success_action.py b/erpnext/setup/default_success_action.py
index e8494a1..6c2a97a 100644
--- a/erpnext/setup/default_success_action.py
+++ b/erpnext/setup/default_success_action.py
@@ -1,3 +1,4 @@
+from __future__ import unicode_literals
from frappe import _
doctype_list = [
diff --git a/erpnext/setup/doctype/company/company_dashboard.py b/erpnext/setup/doctype/company/company_dashboard.py
index 6133226..5efcf38 100644
--- a/erpnext/setup/doctype/company/company_dashboard.py
+++ b/erpnext/setup/doctype/company/company_dashboard.py
@@ -13,7 +13,7 @@
'goal_doctype_link': 'company',
'goal_field': 'base_grand_total',
'date_field': 'posting_date',
- 'filter_str': 'docstatus = 1',
+ 'filter_str': "docstatus = 1 and is_opening != 'Yes'",
'aggregation': 'sum'
},
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 6bc9036..f258f7d 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -136,7 +136,10 @@
rgt = ('<', item_group.rgt),
),
or_filters = search_filters,
- order_by = 'weightage desc, name asc')
+ order_by = 'weightage desc, name asc',
+ start = start,
+ limit = limit
+ )
return [get_item_for_list_in_html(r) for r in data]
diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
index 212bb51..bc991b4 100644
--- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
@@ -10,7 +10,9 @@
from erpnext.accounts.utils import get_stock_and_account_difference
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
from erpnext.stock.stock_ledger import get_previous_sle, update_entries_after
-from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import EmptyStockReconciliationItemsError
+from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import EmptyStockReconciliationItemsError, get_items
+from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
+from erpnext.stock.doctype.item.test_item import make_item
class TestStockReconciliation(unittest.TestCase):
def setUp(self):
@@ -79,6 +81,17 @@
set_perpetual_inventory(0)
+ def test_get_items(self):
+ create_warehouse("_Test Warehouse Group 1", {"is_group": 1})
+ create_warehouse("_Test Warehouse Ledger 1", {"is_group": 0, "parent_warehouse": "_Test Warehouse Group 1 - _TC"})
+ make_item("_Test Stock Reco Item", {"default_warehouse": "_Test Warehouse Ledger 1 - _TC",
+ "is_stock_item": 1, "opening_stock": 100, "valuation_rate": 100})
+
+ items = get_items("_Test Warehouse Group 1 - _TC", nowdate(), nowtime())
+
+ self.assertEqual(["_Test Stock Reco Item", "_Test Warehouse Ledger 1 - _TC", 100],
+ [items[0]["item_code"], items[0]["warehouse"], items[0]["qty"]])
+
def insert_existing_sle(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
diff --git a/erpnext/stock/doctype/warehouse/test_warehouse.py b/erpnext/stock/doctype/warehouse/test_warehouse.py
index 006945e..b033f86 100644
--- a/erpnext/stock/doctype/warehouse/test_warehouse.py
+++ b/erpnext/stock/doctype/warehouse/test_warehouse.py
@@ -90,7 +90,7 @@
self.assertTrue(frappe.db.get_value("Warehouse",
filters={"account": "Test Warehouse for Merging 2 - _TC"}))
-def create_warehouse(warehouse_name):
+def create_warehouse(warehouse_name, properties=None):
if not frappe.db.exists("Warehouse", warehouse_name + " - _TC"):
w = frappe.new_doc("Warehouse")
w.warehouse_name = warehouse_name
@@ -98,11 +98,13 @@
w.company = "_Test Company"
make_account_for_warehouse(warehouse_name, w)
w.account = warehouse_name + " - _TC"
+ if properties:
+ w.update(properties)
w.save()
def make_account_for_warehouse(warehouse_name, warehouse_obj):
if not frappe.db.exists("Account", warehouse_name + " - _TC"):
- parent_account = frappe.db.get_value('Account',
+ parent_account = frappe.db.get_value('Account',
{'company': warehouse_obj.company, 'is_group':1, 'account_type': 'Stock'},'name')
account = create_account(account_name=warehouse_name, \
account_type="Stock", parent_account= parent_account, company=warehouse_obj.company)
\ No newline at end of file
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 692fe5d..bbea904 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -36,6 +36,7 @@
"is_subcontracted": "Yes" / "No",
"ignore_pricing_rule": 0/1
"project": ""
+ "set_warehouse": ""
}
"""
args = process_args(args)
@@ -189,7 +190,6 @@
"project": "",
barcode: "",
serial_no: "",
- warehouse: "",
currency: "",
update_stock: "",
price_list: "",
@@ -219,7 +219,7 @@
item_defaults = get_item_defaults(item.name, args.company)
item_group_defaults = get_item_group_defaults(item.name, args.company)
- warehouse = user_default_warehouse or item_defaults.get("default_warehouse") or\
+ warehouse = args.get("set_warehouse") or user_default_warehouse or item_defaults.get("default_warehouse") or\
item_group_defaults.get("default_warehouse") or args.warehouse
if args.get('doctype') == "Material Request" and not args.get('material_request_type'):
@@ -273,7 +273,7 @@
"transaction_date": args.get("transaction_date")
})
- if item.enable_deferred_revenue:
+ if item.get("enable_deferred_revenue") or item.get("enable_deferred_expense"):
out.update(calculate_service_end_date(args, item))
# calculate conversion factor
@@ -310,9 +310,15 @@
if not item:
item = frappe.get_cached_doc("Item", args.item_code)
- enable_deferred = "enable_deferred_revenue" if args.doctype=="Sales Invoice" else "enable_deferred_expense"
- no_of_months = "no_of_months" if args.doctype=="Sales Invoice" else "no_of_months_exp"
- account = "deferred_revenue_account" if args.doctype=="Sales Invoice" else "deferred_expense_account"
+ doctype = args.get("parenttype") or args.get("doctype")
+ if doctype == "Sales Invoice":
+ enable_deferred = "enable_deferred_revenue"
+ no_of_months = "no_of_months"
+ account = "deferred_revenue_account"
+ else:
+ enable_deferred = "enable_deferred_expense"
+ no_of_months = "no_of_months_exp"
+ account = "deferred_expense_account"
service_start_date = args.service_start_date if args.service_start_date else args.transaction_date
service_end_date = add_months(service_start_date, item.get(no_of_months))
@@ -336,7 +342,7 @@
or args.expense_account)
def get_default_deferred_account(args, item, fieldname=None):
- if item.enable_deferred_revenue:
+ if item.get("enable_deferred_revenue") or item.get("enable_deferred_expense"):
return (item.get(fieldname)
or args.get(fieldname)
or frappe.get_cached_value('Company', args.company, "default_"+fieldname))
@@ -370,16 +376,16 @@
price_list_rate = get_price_list_rate_for(args, item_doc.name) or 0
+ # variant
+ if not price_list_rate and item_doc.variant_of:
+ price_list_rate = get_price_list_rate_for(args, item_doc.variant_of)
+
# insert in database
if not price_list_rate:
if args.price_list and args.rate:
insert_item_price(args)
return {}
- # variant
- if not price_list_rate and item_doc.variant_of:
- price_list_rate = get_price_list_rate_for(args, item_doc.variant_of)
-
out.price_list_rate = flt(price_list_rate) * flt(args.plc_conversion_rate) \
/ flt(args.conversion_rate)