Merge pull request #3549 from neilLasrado/item-varients
Validation changed for Item Template cannot have Stock
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index 1280cc0..ce6ac7a 100755
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -50,6 +50,23 @@
"width": "300px"
},
{
+ "fieldname": "image",
+ "fieldtype": "Attach",
+ "hidden": 1,
+ "label": "Image",
+ "permlevel": 0,
+ "precision": ""
+ },
+ {
+ "fieldname": "image_view",
+ "fieldtype": "Image",
+ "label": "Image View",
+ "options": "image",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1
+ },
+ {
"fieldname": "quantity_and_rate",
"fieldtype": "Section Break",
"label": "Quantity and Rate",
@@ -452,7 +469,7 @@
],
"idx": 1,
"istable": 1,
- "modified": "2015-06-02 14:18:56.294949",
+ "modified": "2015-07-02 03:00:44.496683",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
index 4ace40a..6dcd591 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
@@ -69,6 +69,23 @@
"width": "200px"
},
{
+ "fieldname": "image",
+ "fieldtype": "Attach",
+ "hidden": 1,
+ "label": "Image",
+ "permlevel": 0,
+ "precision": ""
+ },
+ {
+ "fieldname": "image_view",
+ "fieldtype": "Image",
+ "label": "Image View",
+ "options": "image",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1
+ },
+ {
"fieldname": "quantity_and_rate",
"fieldtype": "Section Break",
"label": "Quantity and Rate",
@@ -505,7 +522,7 @@
],
"idx": 1,
"istable": 1,
- "modified": "2015-06-02 14:18:45.176726",
+ "modified": "2015-07-02 02:59:08.413213",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index 716cc3d..9b68810 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -175,16 +175,15 @@
else:
if row.update_stock or row.dn_detail:
+ parenttype, parent, item_row = row.parenttype, row.parent, row.item_row
if row.dn_detail:
- row.parenttype = "Delivery Note"
- row.parent = row.delivery_note
- row.item_row = row.dn_detail
+ parenttype, parent, item_row = "Delivery Note", row.delivery_note, row.dn_detail
my_sle = self.sle.get((item_code, row.warehouse))
for i, sle in enumerate(my_sle):
# find the stock valution rate from stock ledger entry
- if sle.voucher_type == row.parenttype and row.parent == sle.voucher_no and \
- sle.voucher_detail_no == row.item_row:
+ if sle.voucher_type == parenttype and parent == sle.voucher_no and \
+ sle.voucher_detail_no == item_row:
previous_stock_value = len(my_sle) > i+1 and \
flt(my_sle[i+1].stock_value) or 0.0
return previous_stock_value - flt(sle.stock_value)
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 65ecfd8..f0eebb1 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -61,7 +61,7 @@
var d = locals[cdt][cdn];
if (d.item_code) {
return frappe.call({
- doc: cur_frm.doc,
+ doc: doc,
method: "get_bom_material_detail",
args: {
'item_code': d.item_code,
@@ -234,5 +234,3 @@
cur_frm.cscript.image = function() {
refresh_field("image_view");
}
-
-
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 80965ec..725e020 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -169,3 +169,4 @@
erpnext.patches.v5_0.index_on_account_and_gl_entry
execute:frappe.db.sql("""delete from `tabProject Task`""")
erpnext.patches.v5_0.item_variants
+erpnext.patches.v5_0.update_item_desc_in_invoice
\ No newline at end of file
diff --git a/erpnext/patches/v5_0/update_item_desc_in_invoice.py b/erpnext/patches/v5_0/update_item_desc_in_invoice.py
new file mode 100644
index 0000000..b7a071c
--- /dev/null
+++ b/erpnext/patches/v5_0/update_item_desc_in_invoice.py
@@ -0,0 +1,50 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe
+from frappe.website.utils import find_first_image
+from frappe.utils import cstr
+import re
+
+def execute():
+ item_details = frappe._dict()
+ for d in frappe.db.sql("select name, description, image from `tabItem`", as_dict=1):
+ description = cstr(d.description).strip()
+ item_details.setdefault(d.name, frappe._dict({
+ "description": description,
+ "image": d.image
+ }))
+
+
+ dt_list= ["Sales Invoice Item","Purchase Invoice Item"]
+ for dt in dt_list:
+ frappe.reload_doctype(dt)
+ records = frappe.db.sql("""select name, item_code, description from `tab{0}`
+ where description is not null """.format(dt), as_dict=1)
+
+ count = 1
+ for d in records:
+ if d.item_code and item_details.get(d.item_code) \
+ and cstr(d.description) == item_details.get(d.item_code).description:
+ desc = item_details.get(d.item_code).description
+ image = item_details.get(d.item_code).image
+ else:
+ desc, image = extract_image_and_description(cstr(d.description))
+
+ if not image:
+ image = item_details.get(d.item_code).image
+
+ frappe.db.sql("""update `tab{0}` set description = %s, image = %s
+ where name = %s """.format(dt), (desc, image, d.name))
+
+ count += 1
+ if count % 500 == 0:
+ frappe.db.commit()
+
+
+def extract_image_and_description(data):
+ image_url = find_first_image(data)
+ desc = data
+ for tag in ("img", "table", "tr", "td"):
+ desc = re.sub("\</*{0}[^>]*\>".format(tag), "", desc)
+ return desc, image_url
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 0ba368d..6ebafdb 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -46,6 +46,8 @@
"""sync tasks and remove table"""
if self.flags.dont_sync_tasks: return
+
+ task_added_or_deleted = False
task_names = []
for t in self.tasks:
if t.task_id:
@@ -53,6 +55,7 @@
else:
task = frappe.new_doc("Task")
task.project = self.name
+ task_added_or_deleted = True
task.update({
"subject": t.title,
@@ -70,15 +73,22 @@
# delete
for t in frappe.get_all("Task", ["name"], {"project": self.name, "name": ("not in", task_names)}):
frappe.delete_doc("Task", t.name)
+ task_added_or_deleted = True
+
+ if task_added_or_deleted:
+ self.update_project()
+
+ def update_project(self):
+ self.update_percent_complete()
+ self.update_costing()
def update_percent_complete(self):
- total = frappe.db.sql("""select count(*) from tabTask where project=%s""",
- self.name)[0][0]
+ total = frappe.db.sql("""select count(*) from tabTask where project=%s""", self.name)[0][0]
if total:
completed = frappe.db.sql("""select count(*) from tabTask where
project=%s and status in ('Closed', 'Cancelled')""", self.name)[0][0]
- frappe.db.set_value("Project", self.name, "percent_complete",
- int(float(completed) / total * 100))
+
+ self.percent_complete = flt(completed) / total * 100
def update_costing(self):
total_cost = frappe.db.sql("""select sum(total_costing_amount) as costing_amount,
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index f5541cc..7229203 100644
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -43,15 +43,8 @@
def on_update(self):
self.check_recursion()
self.reschedule_dependent_tasks()
- self.update_percentage()
self.update_project()
- def update_percentage(self):
- """update percent complete in project"""
- if self.project and not self.flags.from_project:
- project = frappe.get_doc("Project", self.project)
- project.run_method("update_percent_complete")
-
def update_total_expense_claim(self):
self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim`
where project = %s and task = %s and approval_status = "Approved" and docstatus=1""",(self.project, self.name))
@@ -70,10 +63,10 @@
self.act_end_date= tl.end_date
def update_project(self):
- if self.project and frappe.db.exists("Project", self.project):
+ if self.project and not self.flags.from_project:
project = frappe.get_doc("Project", self.project)
project.flags.dont_sync_tasks = True
- project.update_costing()
+ project.update_project()
project.save()
def check_recursion(self):
diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py
index 2398950..0ecc9c0 100644
--- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py
+++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import add_days, getdate, cint
+from frappe.utils import add_days, getdate, cint, cstr
from frappe import throw, _
from erpnext.utilities.transaction_base import TransactionBase, delete_events
@@ -73,7 +73,7 @@
"owner": email_map[d.sales_person] or self.owner,
"subject": description,
"description": description,
- "starts_on": key["scheduled_date"] + " 10:00:00",
+ "starts_on": cstr(key["scheduled_date"]) + " 10:00:00",
"event_type": "Private",
"ref_type": self.doctype,
"ref_name": self.name