Merge branch 'master' of github.com:webnotes/erpnext
diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py
index db0ddd8..f1c5758 100644
--- a/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -423,7 +423,7 @@
self.get_gl_dict({
"account": self.doc.credit_to,
"against": self.doc.against_expense_account,
- "credit": self.doc.grand_total,
+ "credit": self.doc.total_amount_to_pay,
"remarks": self.doc.remarks,
"against_voucher": self.doc.name,
"against_voucher_type": self.doc.doctype,
diff --git a/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js b/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js
index 6158e26..53588e0 100644
--- a/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js
+++ b/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js
@@ -76,8 +76,9 @@
alert("Please select Category first");
d.add_deduct_tax = '';
}
- else if(d.category != 'Total' && d.add_deduct_tax == 'Deduct'){
- alert("You cannot Deduct when category is for valuation or for both(i.e total and valuation)");
+ else if(d.category != 'Total' && d.add_deduct_tax == 'Deduct') {
+ console.log([d.category, d.add_deduct_tax]);
+ msgprint("You cannot deduct when category is for 'Valuation' or 'Valuation and Total'");
d.add_deduct_tax = '';
}
diff --git a/accounts/general_ledger.py b/accounts/general_ledger.py
index f7932bf..06c101b 100644
--- a/accounts/general_ledger.py
+++ b/accounts/general_ledger.py
@@ -70,6 +70,10 @@
for entry in gl_map:
gle = Document('GL Entry', fielddata=entry)
+ # round off upto 2 decimal
+ gle.debit = flt(gle.debit, 2)
+ gle.credit = flt(gle.credit, 2)
+
# toggle debit, credit if negative entry
if flt(gle.debit) < 0 or flt(gle.credit) < 0:
_swap(gle)
diff --git a/buying/doctype/purchase_common/purchase_common.js b/buying/doctype/purchase_common/purchase_common.js
index 3a9d891..b3f62d5 100644
--- a/buying/doctype/purchase_common/purchase_common.js
+++ b/buying/doctype/purchase_common/purchase_common.js
@@ -778,10 +778,10 @@
var calculate_outstanding = function(doc) {
// total amount to pay
- doc.total_amount_to_pay = flt(flt(doc.net_total) + flt(doc.other_charges_added) - flt(doc.other_charges_deducted));
+ doc.total_amount_to_pay = flt(doc.grand_total) - flt(doc.write_off_amount);
// outstanding amount
- if(doc.docstatus==0) doc.outstanding_amount = flt(doc.net_total) + flt(doc.other_charges_added) - flt(doc.other_charges_deducted) - flt(doc.total_advance);
+ if(doc.docstatus==0) doc.outstanding_amount = doc.total_amount_to_pay - flt(doc.total_advance);
refresh_many(['total_amount_to_pay', 'outstanding_amount']);
}
diff --git a/home/page/latest_updates/latest_updates.js b/home/page/latest_updates/latest_updates.js
index 7e28824..dea571d 100644
--- a/home/page/latest_updates/latest_updates.js
+++ b/home/page/latest_updates/latest_updates.js
@@ -1,4 +1,9 @@
erpnext.updates = [
+ ["13th February, 2013", [
+ "Employee: If Employee is linked to a Profile, copy Full Name, Date of Birth, \
+ Image and Gender to Profile",
+ "Leave Application: Select Leave Approver by their Full Name",
+ ]],
["6th February, 2013", [
"Bookmarks: Add bookmarks via toolbar by clicking on the <i class='icon-star'></i> sign.",
]],
diff --git a/hr/doctype/employee/employee.py b/hr/doctype/employee/employee.py
index 6846c5e..cef6fdc 100644
--- a/hr/doctype/employee/employee.py
+++ b/hr/doctype/employee/employee.py
@@ -63,19 +63,56 @@
return ret_sal_struct and ret_sal_struct[0][0] or ''
def on_update(self):
- self.update_user_default()
+ if self.doc.user_id:
+ self.update_user_default()
+ self.update_profile()
def update_user_default(self):
- if self.doc.user_id:
- webnotes.conn.set_default("employee", self.doc.name, self.doc.user_id)
- webnotes.conn.set_default("employee_name", self.doc.employee_name, self.doc.user_id)
- webnotes.conn.set_default("company", self.doc.company, self.doc.user_id)
-
- # add employee role if missing
- if not "Employee" in webnotes.conn.sql_list("""select role from tabUserRole
+ webnotes.conn.set_default("employee", self.doc.name, self.doc.user_id)
+ webnotes.conn.set_default("employee_name", self.doc.employee_name, self.doc.user_id)
+ webnotes.conn.set_default("company", self.doc.company, self.doc.user_id)
+
+ def update_profile(self):
+ # add employee role if missing
+ if not "Employee" in webnotes.conn.sql_list("""select role from tabUserRole
where parent=%s""", self.doc.user_id):
- webnotes.get_obj("Profile", self.doc.user_id).add_role("Employee")
-
+ from webnotes.profile import add_role
+ add_role(self.doc.user_id, "HR User")
+
+ profile_wrapper = webnotes.model_wrapper("Profile", self.doc.user_id)
+
+ # copy details like Fullname, DOB and Image to Profile
+ if self.doc.employee_name:
+ employee_name = self.doc.employee_name.split(" ")
+ if len(employee_name) >= 3:
+ profile_wrapper.doc.last_name = " ".join(employee_name[2:])
+ profile_wrapper.doc.middle_name = employee_name[1]
+ elif len(employee_name) == 2:
+ profile_wrapper.doc.last_name = employee_name[1]
+
+ profile_wrapper.doc.first_name = employee_name[0]
+
+ if self.doc.date_of_birth:
+ profile_wrapper.doc.birth_date = self.doc.date_of_birth
+
+ if self.doc.gender:
+ profile_wrapper.doc.gender = self.doc.gender
+
+ if self.doc.image and self.doc.file_list:
+ # add to file list and user_image
+ for file_args in self.doc.file_list.split("\n"):
+ fname, fid = file_args.split(",")
+ if self.doc.image == fname:
+ new_file_args = fname + "," + fid
+ file_list = profile_wrapper.doc.file_list.split("\n")
+ if new_file_args not in file_list:
+ file_list += [new_file_args]
+ profile_wrapper.doc.file_list = "\n".join(file_list)
+ profile_wrapper.doc.user_image = fname
+ break
+
+ profile_wrapper.save()
+
def validate_date(self):
import datetime
if self.doc.date_of_birth and self.doc.date_of_joining and getdate(self.doc.date_of_birth) >= getdate(self.doc.date_of_joining):
diff --git a/hr/doctype/employee/test_employee.py b/hr/doctype/employee/test_employee.py
index a9c715b..01c2087 100644
--- a/hr/doctype/employee/test_employee.py
+++ b/hr/doctype/employee/test_employee.py
@@ -7,7 +7,7 @@
"gender": "Female",
"status": "Active",
"company": "_Test Company",
- "user_id": "test@erpnext.com"
+ "user_id": "test@example.com"
}],
[{
"doctype":"Employee",
@@ -18,5 +18,17 @@
"gender": "Male",
"status": "Active",
"company": "_Test Company",
- "user_id": "test1@erpnext.com"
-}]]
\ No newline at end of file
+ "user_id": "test1@example.com"
+}],
+[{
+ "doctype":"Employee",
+ "employee_name": "_Test Employee 2",
+ "naming_series": "_T-Employee-",
+ "date_of_joining": "2010-01-01",
+ "date_of_birth": "1980-01-01",
+ "gender": "Male",
+ "status": "Active",
+ "company": "_Test Company",
+ "user_id": "test2@example.com"
+}]
+]
\ No newline at end of file
diff --git a/hr/doctype/holiday_block_list/test_holiday_block_list.py b/hr/doctype/holiday_block_list/test_holiday_block_list.py
index 5ec4dd1..e9f3b78 100644
--- a/hr/doctype/holiday_block_list/test_holiday_block_list.py
+++ b/hr/doctype/holiday_block_list/test_holiday_block_list.py
@@ -15,6 +15,6 @@
"parent": "_Test Holiday Block List",
"parenttype": "Holiday Block List",
"parentfield": "holiday_block_list_allowed",
- "allow_user": "test1@erpnext.com",
+ "allow_user": "test1@example.com",
}
]]
\ No newline at end of file
diff --git a/hr/doctype/leave_application/leave_application.js b/hr/doctype/leave_application/leave_application.js
index 3c26a51..9df348a 100755
--- a/hr/doctype/leave_application/leave_application.js
+++ b/hr/doctype/leave_application/leave_application.js
@@ -23,10 +23,14 @@
if(doc.__islocal) {
cur_frm.set_value("status", "Open")
}
+ cur_frm.set_df_property("leave_approver", "options", "");
cur_frm.call({
method:"get_approver_list",
callback: function(r) {
- cur_frm.set_df_property("leave_approver", "options", r.message);
+ cur_frm.set_df_property("leave_approver", "options", $.map(r.message,
+ function(profile) {
+ return {value: profile, label: wn.user_info(profile).fullname};
+ }));
cur_frm.cscript.get_leave_balance(cur_frm.doc);
}
});
diff --git a/hr/doctype/leave_application/leave_application.py b/hr/doctype/leave_application/leave_application.py
index 2045147..bc685df 100755
--- a/hr/doctype/leave_application/leave_application.py
+++ b/hr/doctype/leave_application/leave_application.py
@@ -78,7 +78,9 @@
if block_date > from_date and block_date < to_date:
webnotes.msgprint(_("You cannot apply for a leave on the following date because it is blocked")
+ ": " + formatdate(d.block_date) + _(" Reason: ") + d.reason)
- raise LeaveDayBlockedError
+ if self.doc.docstatus == 1:
+ # throw exception only when submitting
+ raise LeaveDayBlockedError
def is_user_in_allow_list(self, block_list):
return webnotes.session.user in webnotes.conn.sql_list("""select allow_user
diff --git a/hr/doctype/leave_application/test_leave_application.py b/hr/doctype/leave_application/test_leave_application.py
index 7195826..cd74d01 100644
--- a/hr/doctype/leave_application/test_leave_application.py
+++ b/hr/doctype/leave_application/test_leave_application.py
@@ -4,8 +4,8 @@
from hr.doctype.leave_application.leave_application import LeaveDayBlockedError
class TestLeaveApplication(unittest.TestCase):
- def get_application(self):
- application = webnotes.model_wrapper(test_records[1])
+ def get_application(self, doclist):
+ application = webnotes.model_wrapper(doclist)
application.doc.from_date = "2013-01-01"
application.doc.to_date = "2013-01-05"
return application
@@ -15,22 +15,37 @@
webnotes.conn.set_value("Employee", "_T-Employee-0001", "department",
"_Test Department with Block List")
- application = self.get_application()
- self.assertRaises(LeaveDayBlockedError, application.insert)
+ application = self.get_application(test_records[1])
+ application.insert()
+ self.assertRaises(LeaveDayBlockedError, application.submit)
- webnotes.session.user = "test1@erpnext.com"
- webnotes.get_obj("Profile", "test1@erpnext.com").add_role("HR User")
+ webnotes.session.user = "test1@example.com"
+
+ from webnotes.profile import add_role
+ add_role("test1@example.com", "HR User")
+
+ application = self.get_application(test_records[1])
self.assertTrue(application.insert())
def test_global_block_list(self):
- application = self.get_application()
+ application = self.get_application(test_records[3])
+ application.doc.leave_approver = "test@example.com"
webnotes.conn.set_value("Holiday Block List", "_Test Holiday Block List",
"applies_to_all_departments", 1)
- webnotes.conn.set_value("Employee", "_T-Employee-0001", "department",
+ webnotes.conn.set_value("Employee", "_T-Employee-0002", "department",
"_Test Department")
- webnotes.session.user = "test@erpnext.com"
+
+ webnotes.session.user = "test2@example.com"
+ from webnotes.profile import add_role
+ add_role("test2@example.com", "Employee")
- self.assertRaises(LeaveDayBlockedError, application.insert)
+ application.insert()
+
+ webnotes.session.user = "test@example.com"
+ from webnotes.profile import add_role
+ add_role("test@example.com", "Leave Approver")
+
+ self.assertRaises(LeaveDayBlockedError, application.submit)
test_records = [
[{
@@ -50,4 +65,23 @@
"fiscal_year": "_Test Fiscal Year 2013",
"employee": "_T-Employee-0001",
"company": "_Test Company"
- }]]
+ }],
+ [{
+ "doctype": "Leave Allocation",
+ "leave_type": "_Test Leave Type",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "employee":"_T-Employee-0002",
+ "new_leaves_allocated": 15,
+ "docstatus": 1
+ }],
+ [{
+ "doctype": "Leave Application",
+ "leave_type": "_Test Leave Type",
+ "from_date": "2013-05-01",
+ "to_date": "2013-05-05",
+ "posting_date": "2013-01-02",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "employee": "_T-Employee-0002",
+ "company": "_Test Company"
+ }]
+]
diff --git a/patches/february_2013/fix_outstanding.py b/patches/february_2013/fix_outstanding.py
new file mode 100644
index 0000000..226b360
--- /dev/null
+++ b/patches/february_2013/fix_outstanding.py
@@ -0,0 +1,15 @@
+def execute():
+ import webnotes
+ from webnotes.utils import flt
+ for dt in ["Sales Invoice", "Purchase Invoice"]:
+ records = webnotes.conn.sql("""select name, outstanding_amount from `tab%s`
+ where docstatus = 1""" % dt)
+ for r in records:
+ outstanding = webnotes.conn.sql("""
+ select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) from `tabGL Entry`
+ where against_voucher = %s and against_voucher_type = %s
+ and ifnull(is_cancelled, 'No') = 'No'""", (r[0], dt))
+ if flt(r[1]) != abs(flt(outstanding[0][0])):
+ # print r, outstanding
+ webnotes.conn.sql("update `tab%s` set outstanding_amount = %s where name = %s" %
+ (dt, '%s', '%s'), (abs(flt(outstanding[0][0])), si[0]))
\ No newline at end of file
diff --git a/patches/february_2013/gle_floating_point_issue_revisited.py b/patches/february_2013/gle_floating_point_issue_revisited.py
new file mode 100644
index 0000000..3fc57bd
--- /dev/null
+++ b/patches/february_2013/gle_floating_point_issue_revisited.py
@@ -0,0 +1,22 @@
+def execute():
+ import webnotes
+ from webnotes.utils import flt
+
+ records = webnotes.conn.sql("""select name, grand_total, debit_to from `tabSales Invoice`
+ where docstatus = 1""", as_dict=1)
+
+ for r in records:
+ gle = webnotes.conn.sql("""select name, debit from `tabGL Entry`
+ where account = %s and voucher_type = 'Sales Invoice' and voucher_no = %s
+ and ifnull(is_cancelled, 'No') = 'No' limit 1""", (r.debit_to, r.name), as_dict=1)
+ if gle:
+ diff = round((flt(r.grand_total) - flt(gle[0]['debit'])), 2)
+
+ if abs(diff) == 0.01:
+ # print r.name, r.grand_total, gle[0]['debit']
+ webnotes.conn.sql("""update `tabGL Entry` set debit = debit + %s
+ where name = %s""", (diff, gle[0]['name']))
+
+ webnotes.conn.sql("""update `tabGL Entry` set credit = credit - %s
+ where voucher_type = 'Sales Invoice' and voucher_no = %s
+ and credit > 0 limit 1""", (diff, r.name))
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index c1fa08f..c00744e 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -167,5 +167,6 @@
"patches.february_2013.account_negative_balance",
"patches.february_2013.remove_account_utils_folder",
"patches.february_2013.update_company_in_leave_application",
- "execute:webnotes.conn.sql_ddl('alter table tabSeries change `name` `name` varchar(100)')"
+ "execute:webnotes.conn.sql_ddl('alter table tabSeries change `name` `name` varchar(100)')",
+ "execute:webnotes.conn.sql('update tabUserRole set parentfield=\"user_roles\" where parentfield=\"userroles\"')",
]
\ No newline at end of file