Merge branch 'develop' into set_defualt_mode_payment

This commit is contained in:
Nabin Hait 2017-07-28 21:09:42 +05:30 committed by GitHub
commit 1fcd2b0676
37 changed files with 160 additions and 59 deletions

View File

@ -4,7 +4,7 @@ import inspect
import frappe import frappe
from erpnext.hooks import regional_overrides from erpnext.hooks import regional_overrides
__version__ = '8.6.3' __version__ = '8.6.4'
def get_default_company(user=None): def get_default_company(user=None):
'''Get default company for user''' '''Get default company for user'''

View File

@ -147,8 +147,9 @@ class Asset(Document):
accumulated_depreciation_after_full_schedule = \ accumulated_depreciation_after_full_schedule = \
max([d.accumulated_depreciation_amount for d in self.get("schedules")]) max([d.accumulated_depreciation_amount for d in self.get("schedules")])
asset_value_after_full_schedule = (flt(self.gross_purchase_amount) - asset_value_after_full_schedule = flt(flt(self.gross_purchase_amount) -
flt(accumulated_depreciation_after_full_schedule)) flt(accumulated_depreciation_after_full_schedule),
self.precision('expected_value_after_useful_life'))
if self.expected_value_after_useful_life < asset_value_after_full_schedule: if self.expected_value_after_useful_life < asset_value_after_full_schedule:
frappe.throw(_("Expected value after useful life must be greater than or equal to {0}") frappe.throw(_("Expected value after useful life must be greater than or equal to {0}")

View File

@ -65,6 +65,13 @@ QUnit.test("test: item", function (assert) {
{item_group: "Products"} {item_group: "Products"}
] ]
), ),
() => frappe.tests.make(
"Item", [
{item_code: "Computer"},
{item_group: "Products"},
{is_stock_item: 0},
]
),
// Create a scrap item // Create a scrap item
() => frappe.tests.make( () => frappe.tests.make(

View File

@ -1,5 +1,5 @@
This form allows you to enroll a student to a program. A student can be enrolled to multiple programs. This form allows you to enroll a student to a program. A student can be enrolled to multiple programs.
<img class="screenshot" alt="Student Applicant Enrollment" src="{{url_prefix}}/assets/img/schools/admission/program-enrollment.png"> <img class="screenshot" alt="Student Applicant Enrollment" src="{{docs_base_url}}/assets/img/schools/admission/program-enrollment.png">
{next} {next}

View File

@ -3,7 +3,7 @@
A Student Applicant record needs to be created when a student applies for a program at your institute. A Student Applicant record needs to be created when a student applies for a program at your institute.
You can Approve or Reject a student applicant. By accepting a student applicant you can add them to the student master. You can Approve or Reject a student applicant. By accepting a student applicant you can add them to the student master.
<img class="screenshot" alt="Student Applicant" src="{{url_prefix}}/assets/img/schools/admission/student-applicant.png"> <img class="screenshot" alt="Student Applicant" src="{{docs_base_url}}/assets/img/schools/admission/student-applicant.png">
### Application Status ### Application Status
@ -23,6 +23,6 @@ You can Approve or Reject a student applicant. By accepting a student applicant
Once you approve a Student Applicant you can enroll them to a program. When you click the 'Enroll' buttom, Once you approve a Student Applicant you can enroll them to a program. When you click the 'Enroll' buttom,
the system shall create a student against that applicant and redirect you to the [Program Enrollment form]({{docs_base_url}}/user/manual/en/schools/student/program-enrollment.html). the system shall create a student against that applicant and redirect you to the [Program Enrollment form]({{docs_base_url}}/user/manual/en/schools/student/program-enrollment.html).
<img class="screenshot" alt="Student Applicant Enrollment" src="{{url_prefix}}/assets/img/schools/admission/student-applicant-enroll.png"> <img class="screenshot" alt="Student Applicant Enrollment" src="{{docs_base_url}}/assets/img/schools/admission/student-applicant-enroll.png">
{next} {next}

View File

@ -2,6 +2,6 @@
List of all different type of fees collected. List of all different type of fees collected.
<img class="screenshot" alt="Fees Category" src="{{url_prefix}}/assets/img/schools/fees/fee-category.png"> <img class="screenshot" alt="Fees Category" src="{{docs_base_url}}/assets/img/schools/fees/fee-category.png">
{next} {next}

View File

@ -2,6 +2,6 @@
A Fee Structure is a template that can be used while making fee records. A Fee Structure is a template that can be used while making fee records.
<img class="screenshot" alt="Fees Structure" src="{{url_prefix}}/assets/img/schools/fees/fee-structure.png"> <img class="screenshot" alt="Fees Structure" src="{{docs_base_url}}/assets/img/schools/fees/fee-structure.png">
{next} {next}

View File

@ -3,6 +3,6 @@
Maintain a record of fees collected from students. Maintain a record of fees collected from students.
The [Fee Structure]({{docs_base_url}}/user/manual/en/schools/fees/fee-structure.html) is fetched based on the selected Program and Academic Term. The [Fee Structure]({{docs_base_url}}/user/manual/en/schools/fees/fee-structure.html) is fetched based on the selected Program and Academic Term.
<img class="screenshot" alt="Fees" src="{{url_prefix}}/assets/img/schools/fees/fees.png"> <img class="screenshot" alt="Fees" src="{{docs_base_url}}/assets/img/schools/fees/fees.png">
{next} {next}

View File

@ -2,7 +2,7 @@
This section contains 'Fee' related documents. This section contains 'Fee' related documents.
<img class="screenshot" alt="Fees Section" src="{{url_prefix}}/assets/img/schools/fees/fees-section.png"> <img class="screenshot" alt="Fees Section" src="{{docs_base_url}}/assets/img/schools/fees/fees-section.png">
### Topics ### Topics

View File

@ -1,6 +1,6 @@
The School Modules is designed to meet requirements of Schools, Colleges & Educational Institutes. The School Modules is designed to meet requirements of Schools, Colleges & Educational Institutes.
<img class="screenshot" alt="Fees Section" src="{{url_prefix}}/assets/img/schools/module.png"> <img class="screenshot" alt="Fees Section" src="{{docs_base_url}}/assets/img/schools/module.png">
{index} {index}

View File

@ -3,13 +3,13 @@
Course Schedule is the schedule of a session conducted by an Instructor for a particular Course. Course Schedule is the schedule of a session conducted by an Instructor for a particular Course.
You can see the overall course schedule in the Calendar view. You can see the overall course schedule in the Calendar view.
<img class="screenshot" alt="Course Schedule" src="{{url_prefix}}/assets/img/schools/schedule/course-schedule.png"> <img class="screenshot" alt="Course Schedule" src="{{docs_base_url}}/assets/img/schools/schedule/course-schedule.png">
### Marking Attendance ### Marking Attendance
You can mark attendance for a Student Group against a Course Schedule. You can mark attendance for a Student Group against a Course Schedule.
<img class="screenshot" alt="Course Schedule Attendance" src="{{url_prefix}}/assets/img/schools/schedule/course-schedule-att.png"> <img class="screenshot" alt="Course Schedule Attendance" src="{{docs_base_url}}/assets/img/schools/schedule/course-schedule-att.png">
- To make attendance, expand the attendance section. - To make attendance, expand the attendance section.
- Check the students who were present for that session. - Check the students who were present for that session.
@ -20,6 +20,6 @@ You can mark attendance for a Student Group against a Course Schedule.
Once you have marked Attendance against a Course Schedule the Attendance section in the Course Schedule shall be hidden. Once you have marked Attendance against a Course Schedule the Attendance section in the Course Schedule shall be hidden.
A View Attendance button shall appear. Click on that button to view all attendance records created against that Course Schedule. A View Attendance button shall appear. Click on that button to view all attendance records created against that Course Schedule.
<img class="screenshot" alt="Course Schedule Attendance" src="{{url_prefix}}/assets/img/schools/schedule/course-schedule-att-1.png"> <img class="screenshot" alt="Course Schedule Attendance" src="{{docs_base_url}}/assets/img/schools/schedule/course-schedule-att-1.png">
{next} {next}

View File

@ -2,7 +2,7 @@
The Examination record can be used to track the exam schedule and the results of that exam. The Examination record can be used to track the exam schedule and the results of that exam.
<img class="screenshot" alt="Examination" src="{{url_prefix}}/assets/img/schools/schedule/examination.png"> <img class="screenshot" alt="Examination" src="{{docs_base_url}}/assets/img/schools/schedule/examination.png">
{next} {next}

View File

@ -1,6 +1,6 @@
# Schedule # Schedule
<img class="screenshot" alt="Schedule Section" src="{{url_prefix}}/assets/img/schools/schedule/schedule-section.png"> <img class="screenshot" alt="Schedule Section" src="{{docs_base_url}}/assets/img/schools/schedule/schedule-section.png">
### Topics ### Topics

View File

@ -2,7 +2,7 @@
This tool can be used to create 'Course Schedules'. This tool can be used to create 'Course Schedules'.
<img class="screenshot" alt="Scheduling Tool" src="{{url_prefix}}/assets/img/schools/schedule/scheduling-tool.png"> <img class="screenshot" alt="Scheduling Tool" src="{{docs_base_url}}/assets/img/schools/schedule/scheduling-tool.png">
### Creating Course Schedules ### Creating Course Schedules

View File

@ -2,6 +2,6 @@
Maintains attendance record of the student. Attendance Records can be created against Course Schedules. Maintains attendance record of the student. Attendance Records can be created against Course Schedules.
<img class="screenshot" alt="Student Attendance" src="{{url_prefix}}/assets/img/schools/schedule/student-attendance.png"> <img class="screenshot" alt="Student Attendance" src="{{docs_base_url}}/assets/img/schools/schedule/student-attendance.png">
{next} {next}

View File

@ -1,6 +1,6 @@
# Academic Term # Academic Term
<img class="screenshot" alt="Academic Term" src="{{url_prefix}}/assets/img/schools/setup/academic-term.png"> <img class="screenshot" alt="Academic Term" src="{{docs_base_url}}/assets/img/schools/setup/academic-term.png">
{next} {next}

View File

@ -1,5 +1,5 @@
# Academic Year # Academic Year
<img class="screenshot" alt="Academic Year" src="{{url_prefix}}/assets/img/schools/setup/academic-year.png"> <img class="screenshot" alt="Academic Year" src="{{docs_base_url}}/assets/img/schools/setup/academic-year.png">
{next} {next}

View File

@ -1,5 +1,5 @@
# Course # Course
<img class="screenshot" alt="Course" src="{{url_prefix}}/assets/img/schools/setup/course.png"> <img class="screenshot" alt="Course" src="{{docs_base_url}}/assets/img/schools/setup/course.png">
{next} {next}

View File

@ -1,6 +1,6 @@
# Setup # Setup
<img class="screenshot" alt="Setup Section" src="{{url_prefix}}/assets/img/schools/setup/setup-section.png"> <img class="screenshot" alt="Setup Section" src="{{docs_base_url}}/assets/img/schools/setup/setup-section.png">
### Topics ### Topics

View File

@ -1,5 +1,5 @@
# Instructor # Instructor
<img class="screenshot" alt="Instructor" src="{{url_prefix}}/assets/img/schools/setup/instructor.png"> <img class="screenshot" alt="Instructor" src="{{docs_base_url}}/assets/img/schools/setup/instructor.png">
{next} {next}

View File

@ -1,5 +1,5 @@
# Program # Program
<img class="screenshot" alt="Program" src="{{url_prefix}}/assets/img/schools/setup/program.png"> <img class="screenshot" alt="Program" src="{{docs_base_url}}/assets/img/schools/setup/program.png">
{next} {next}

View File

@ -1,6 +1,6 @@
# Room # Room
<img class="screenshot" alt="Room" src="{{url_prefix}}/assets/img/schools/setup/room.png"> <img class="screenshot" alt="Room" src="{{docs_base_url}}/assets/img/schools/setup/room.png">
{next} {next}

View File

@ -2,6 +2,6 @@
Student batch is a collection of students from Student Groups. Student batch is a collection of students from Student Groups.
<img class="screenshot" alt="Student" src="{{url_prefix}}/assets/img/schools/student/student-batch.png"> <img class="screenshot" alt="Student" src="{{docs_base_url}}/assets/img/schools/student/student-batch.png">
{next} {next}

View File

@ -1,6 +1,6 @@
This tool allows you to create student groups in bulk. You can specify multiple parameters to create them. This tool allows you to create student groups in bulk. You can specify multiple parameters to create them.
<img class="screenshot" alt="Student Group Creation Tool" src="{{url_prefix}}/assets/img/schools/student/student-group-creation-tool.png"> <img class="screenshot" alt="Student Group Creation Tool" src="{{docs_base_url}}/assets/img/schools/student/student-group-creation-tool.png">
{next} {next}

View File

@ -3,6 +3,6 @@
A student group is a collection of students taking a same course. You can create Course Schedules and Examinations against a Student Group. A student group is a collection of students taking a same course. You can create Course Schedules and Examinations against a Student Group.
A student group needs to be created for every course in a particular academic term and academic year. A student group needs to be created for every course in a particular academic term and academic year.
<img class="screenshot" alt="Student Group" src="{{url_prefix}}/assets/img/schools/student/student-group.png"> <img class="screenshot" alt="Student Group" src="{{docs_base_url}}/assets/img/schools/student/student-group.png">
{next} {next}

View File

@ -3,6 +3,6 @@
You can make a note of student activities using student log. You can make a note of student activities using student log.
Logs can be categorised as 'General', 'Academic', 'Medical' or 'Achievement' Logs can be categorised as 'General', 'Academic', 'Medical' or 'Achievement'
<img class="screenshot" alt="Student" src="{{url_prefix}}/assets/img/schools/student/student-log.png"> <img class="screenshot" alt="Student" src="{{docs_base_url}}/assets/img/schools/student/student-log.png">
{next} {next}

View File

@ -5,6 +5,6 @@ The student doctype maintains personal details of the student.
You can view everything related to a particular student on this page. Eg : Fees, Student Group, etc You can view everything related to a particular student on this page. Eg : Fees, Student Group, etc
<img class="screenshot" alt="Student" src="{{url_prefix}}/assets/img/schools/student/student.png"> <img class="screenshot" alt="Student" src="{{docs_base_url}}/assets/img/schools/student/student.png">
{next} {next}

View File

@ -62,49 +62,49 @@ website_route_rules = [
{"from_route": "/orders/<path:name>", "to_route": "order", {"from_route": "/orders/<path:name>", "to_route": "order",
"defaults": { "defaults": {
"doctype": "Sales Order", "doctype": "Sales Order",
"parents": [{"title": _("Orders"), "name": "orders"}] "parents": [{"label": _("Orders"), "route": "orders"}]
} }
}, },
{"from_route": "/invoices", "to_route": "Sales Invoice"}, {"from_route": "/invoices", "to_route": "Sales Invoice"},
{"from_route": "/invoices/<path:name>", "to_route": "order", {"from_route": "/invoices/<path:name>", "to_route": "order",
"defaults": { "defaults": {
"doctype": "Sales Invoice", "doctype": "Sales Invoice",
"parents": [{"title": _("Invoices"), "name": "invoices"}] "parents": [{"label": _("Invoices"), "route": "invoices"}]
} }
}, },
{"from_route": "/supplier-quotations", "to_route": "Supplier Quotation"}, {"from_route": "/supplier-quotations", "to_route": "Supplier Quotation"},
{"from_route": "/supplier-quotations/<path:name>", "to_route": "order", {"from_route": "/supplier-quotations/<path:name>", "to_route": "order",
"defaults": { "defaults": {
"doctype": "Supplier Quotation", "doctype": "Supplier Quotation",
"parents": [{"title": _("Supplier Quotation"), "name": "quotations"}] "parents": [{"label": _("Supplier Quotation"), "route": "quotations"}]
} }
}, },
{"from_route": "/quotations", "to_route": "Quotation"}, {"from_route": "/quotations", "to_route": "Quotation"},
{"from_route": "/quotations/<path:name>", "to_route": "order", {"from_route": "/quotations/<path:name>", "to_route": "order",
"defaults": { "defaults": {
"doctype": "Quotation", "doctype": "Quotation",
"parents": [{"title": _("Quotations"), "name": "quotation"}] "parents": [{"label": _("Quotations"), "route": "quotation"}]
} }
}, },
{"from_route": "/shipments", "to_route": "Delivery Note"}, {"from_route": "/shipments", "to_route": "Delivery Note"},
{"from_route": "/shipments/<path:name>", "to_route": "order", {"from_route": "/shipments/<path:name>", "to_route": "order",
"defaults": { "defaults": {
"doctype": "Delivery Note", "doctype": "Delivery Note",
"parents": [{"title": _("Shipments"), "name": "shipments"}] "parents": [{"label": _("Shipments"), "route": "shipments"}]
} }
}, },
{"from_route": "/rfq", "to_route": "Request for Quotation"}, {"from_route": "/rfq", "to_route": "Request for Quotation"},
{"from_route": "/rfq/<path:name>", "to_route": "rfq", {"from_route": "/rfq/<path:name>", "to_route": "rfq",
"defaults": { "defaults": {
"doctype": "Request for Quotation", "doctype": "Request for Quotation",
"parents": [{"title": _("Request for Quotation"), "name": "rfq"}] "parents": [{"label": _("Request for Quotation"), "route": "rfq"}]
} }
}, },
{"from_route": "/addresses", "to_route": "Address"}, {"from_route": "/addresses", "to_route": "Address"},
{"from_route": "/addresses/<path:name>", "to_route": "addresses", {"from_route": "/addresses/<path:name>", "to_route": "addresses",
"defaults": { "defaults": {
"doctype": "Address", "doctype": "Address",
"parents": [{"title": _("Addresses"), "name": "addresses"}] "parents": [{"label": _("Addresses"), "route": "addresses"}]
} }
}, },
{"from_route": "/jobs", "to_route": "Job Opening"}, {"from_route": "/jobs", "to_route": "Job Opening"},

View File

@ -0,0 +1,50 @@
QUnit.module('hr');
QUnit.test("Test: Leave application [HR]", function (assert) {
assert.expect(5);
let done = assert.async();
let today_date = frappe.datetime.nowdate();
let leave_date = frappe.datetime.add_days(today_date, 1); // leave for tomorrow
frappe.run_serially([
// test creating leave application
() => frappe.db.get_value('Employee', {'employee_name':'Test Employee 1'}, 'name'),
(employee) => {
return frappe.tests.make('Leave Application', [
{leave_type: "Test Leave type"},
{from_date: leave_date}, // for today
{to_date: leave_date},
{half_day: 1},
{employee: employee.message.name},
{leave_approver: "Administrator"},
{follow_via_email: 0}
]);
},
() => frappe.timeout(1),
// check calculated total leave days
() => assert.equal("0.5", cur_frm.doc.total_leave_days,
"leave application for half day"),
() => assert.ok(!cur_frm.doc.docstatus,
"leave application not submitted with status as open"),
() => cur_frm.set_value("status", "Approved"), // approve the application [as administrator]
() => frappe.timeout(0.5),
// save form
() => cur_frm.save(),
() => frappe.timeout(1),
() => cur_frm.savesubmit(),
() => frappe.timeout(1),
() => frappe.click_button('Yes'),
() => frappe.timeout(1),
() => assert.ok(cur_frm.doc.docstatus,
"leave application submitted after approval"),
// check auto filled posting date [today]
() => assert.equal(today_date, cur_frm.doc.posting_date,
"posting date correctly set"),
() => frappe.set_route("List", "Leave Application", "List"),
() => frappe.timeout(1),
// check approved application in list
() => assert.deepEqual(["Test Employee 1", "Approved"], [cur_list.data[0].employee_name, cur_list.data[0].status],
"leave for correct employee is approved"),
() => done()
]);
});

View File

@ -0,0 +1,36 @@
QUnit.test("test sales order", function(assert) {
assert.expect(4);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Product Bundle', [
{new_item_code: 'Computer'},
{items: [
[
{item_code:'CPU'},
{qty:1}
],
[
{item_code:'Screen'},
{qty:1}
],
[
{item_code:'Keyboard'},
{qty:1}
]
]},
]);
},
() => cur_frm.save(),
() => {
// get_item_details
assert.ok(cur_frm.doc.items[0].item_code=='CPU', "Item Code correct");
assert.ok(cur_frm.doc.items[1].item_code=='Screen', "Item Code correct");
assert.ok(cur_frm.doc.items[2].item_code=='Keyboard', "Item Code correct");
assert.ok(cur_frm.doc.new_item_code == "Computer", "Parent Item correct");
},
() => frappe.timeout(0.3),
() => done()
]);
});

View File

@ -16,7 +16,7 @@ class TestSalesOrder(unittest.TestCase):
frappe.set_user("Administrator") frappe.set_user("Administrator")
for role in ("Stock User", "Sales User"): for role in ("Stock User", "Sales User"):
set_user_permission_doctypes(doctype="Sales Order", role=role, set_user_permission_doctypes(doctypes="Sales Order", role=role,
apply_user_permissions=0, user_permission_doctypes=None) apply_user_permissions=0, user_permission_doctypes=None)
def test_make_material_request(self): def test_make_material_request(self):
@ -137,10 +137,10 @@ class TestSalesOrder(unittest.TestCase):
total_projected_qty = get_total_projected_qty('_Test Item') total_projected_qty = get_total_projected_qty('_Test Item')
item_doc_after_cancel = frappe.get_doc('Item', '_Test Item') item_doc_after_cancel = frappe.get_doc('Item', '_Test Item')
self.assertEqual(total_projected_qty, item_doc_after_cancel.total_projected_qty) self.assertEqual(total_projected_qty, item_doc_after_cancel.total_projected_qty)
def test_reserved_qty_for_over_delivery_via_sales_invoice(self): def test_reserved_qty_for_over_delivery_via_sales_invoice(self):
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100) make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
# set over-delivery tolerance # set over-delivery tolerance
frappe.db.set_value('Item', "_Test Item", 'tolerance', 50) frappe.db.set_value('Item', "_Test Item", 'tolerance', 50)
@ -158,9 +158,9 @@ class TestSalesOrder(unittest.TestCase):
total_projected_qty = get_total_projected_qty('_Test Item') total_projected_qty = get_total_projected_qty('_Test Item')
item_doc = frappe.get_doc('Item', '_Test Item') item_doc = frappe.get_doc('Item', '_Test Item')
self.assertEqual(total_projected_qty, item_doc.total_projected_qty) self.assertEqual(total_projected_qty, item_doc.total_projected_qty)
self.assertEqual(get_reserved_qty(), existing_reserved_qty) self.assertEqual(get_reserved_qty(), existing_reserved_qty)
so.load_from_db() so.load_from_db()
self.assertEqual(so.get("items")[0].delivered_qty, 12) self.assertEqual(so.get("items")[0].delivered_qty, 12)
self.assertEqual(so.per_delivered, 100) self.assertEqual(so.per_delivered, 100)
@ -170,7 +170,7 @@ class TestSalesOrder(unittest.TestCase):
total_projected_qty = get_total_projected_qty('_Test Item') total_projected_qty = get_total_projected_qty('_Test Item')
item_doc = frappe.get_doc('Item', '_Test Item') item_doc = frappe.get_doc('Item', '_Test Item')
self.assertEqual(total_projected_qty, item_doc.total_projected_qty) self.assertEqual(total_projected_qty, item_doc.total_projected_qty)
so.load_from_db() so.load_from_db()
self.assertEqual(so.get("items")[0].delivered_qty, 0) self.assertEqual(so.get("items")[0].delivered_qty, 0)
self.assertEqual(so.per_delivered, 0) self.assertEqual(so.per_delivered, 0)
@ -178,8 +178,8 @@ class TestSalesOrder(unittest.TestCase):
def test_reserved_qty_for_partial_delivery_with_packing_list(self): def test_reserved_qty_for_partial_delivery_with_packing_list(self):
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100) make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
make_stock_entry(item="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=10, rate=100) make_stock_entry(item="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=10, rate=100)
existing_reserved_qty_item1 = get_reserved_qty("_Test Item") existing_reserved_qty_item1 = get_reserved_qty("_Test Item")
existing_reserved_qty_item2 = get_reserved_qty("_Test Item Home Desktop 100") existing_reserved_qty_item2 = get_reserved_qty("_Test Item Home Desktop 100")
@ -227,7 +227,7 @@ class TestSalesOrder(unittest.TestCase):
def test_reserved_qty_for_over_delivery_with_packing_list(self): def test_reserved_qty_for_over_delivery_with_packing_list(self):
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100) make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
make_stock_entry(item="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=10, rate=100) make_stock_entry(item="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=10, rate=100)
# set over-delivery tolerance # set over-delivery tolerance
frappe.db.set_value('Item', "_Test Product Bundle Item", 'tolerance', 50) frappe.db.set_value('Item', "_Test Product Bundle Item", 'tolerance', 50)
@ -257,7 +257,7 @@ class TestSalesOrder(unittest.TestCase):
def test_warehouse_user(self): def test_warehouse_user(self):
for role in ("Stock User", "Sales User"): for role in ("Stock User", "Sales User"):
set_user_permission_doctypes(doctype="Sales Order", role=role, set_user_permission_doctypes(doctypes="Sales Order", role=role,
apply_user_permissions=1, user_permission_doctypes=["Warehouse"]) apply_user_permissions=1, user_permission_doctypes=["Warehouse"])
frappe.permissions.add_user_permission("Warehouse", "_Test Warehouse 1 - _TC", "test@example.com") frappe.permissions.add_user_permission("Warehouse", "_Test Warehouse 1 - _TC", "test@example.com")
@ -283,6 +283,7 @@ class TestSalesOrder(unittest.TestCase):
frappe.set_user("test2@example.com") frappe.set_user("test2@example.com")
so.insert() so.insert()
frappe.set_user("Administrator")
frappe.permissions.remove_user_permission("Warehouse", "_Test Warehouse 1 - _TC", "test@example.com") frappe.permissions.remove_user_permission("Warehouse", "_Test Warehouse 1 - _TC", "test@example.com")
frappe.permissions.remove_user_permission("Warehouse", "_Test Warehouse 2 - _TC1", "test2@example.com") frappe.permissions.remove_user_permission("Warehouse", "_Test Warehouse 2 - _TC1", "test2@example.com")
frappe.permissions.remove_user_permission("Company", "_Test Company 1", "test2@example.com") frappe.permissions.remove_user_permission("Company", "_Test Company 1", "test2@example.com")
@ -363,7 +364,7 @@ class TestSalesOrder(unittest.TestCase):
from erpnext.buying.doctype.purchase_order.purchase_order import update_status from erpnext.buying.doctype.purchase_order.purchase_order import update_status
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100) make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
po_item = make_item("_Test Item for Drop Shipping", {"is_stock_item": 1, "delivered_by_supplier": 1, po_item = make_item("_Test Item for Drop Shipping", {"is_stock_item": 1, "delivered_by_supplier": 1,
'default_supplier': '_Test Supplier', 'default_supplier': '_Test Supplier',
"expense_account": "_Test Account Cost for Goods Sold - _TC", "expense_account": "_Test Account Cost for Goods Sold - _TC",

View File

@ -132,7 +132,8 @@ class Item(WebsiteGenerator):
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
# default warehouse, or Stores # default warehouse, or Stores
default_warehouse = (frappe.db.get_single_value('Stock Settings', 'default_warehouse') default_warehouse = (self.default_warehouse
or frappe.db.get_single_value('Stock Settings', 'default_warehouse')
or frappe.db.get_value('Warehouse', {'warehouse_name': _('Stores')})) or frappe.db.get_value('Warehouse', {'warehouse_name': _('Stores')}))
if default_warehouse: if default_warehouse:

View File

@ -32,7 +32,7 @@ class TestStockEntry(unittest.TestCase):
set_perpetual_inventory(0) set_perpetual_inventory(0)
for role in ("Stock User", "Sales User"): for role in ("Stock User", "Sales User"):
set_user_permission_doctypes(doctype="Stock Entry", role=role, set_user_permission_doctypes(doctypes="Stock Entry", role=role,
apply_user_permissions=0, user_permission_doctypes=None) apply_user_permissions=0, user_permission_doctypes=None)
def test_fifo(self): def test_fifo(self):
@ -188,18 +188,18 @@ class TestStockEntry(unittest.TestCase):
[["_Test Item", "_Test Warehouse - _TC", -45.0], ["_Test Item", "_Test Warehouse 1 - _TC", 45.0]]) [["_Test Item", "_Test Warehouse - _TC", -45.0], ["_Test Item", "_Test Warehouse 1 - _TC", 45.0]])
stock_in_hand_account = get_inventory_account(mtn.company, mtn.get("items")[0].s_warehouse) stock_in_hand_account = get_inventory_account(mtn.company, mtn.get("items")[0].s_warehouse)
fixed_asset_account = get_inventory_account(mtn.company, mtn.get("items")[0].t_warehouse) fixed_asset_account = get_inventory_account(mtn.company, mtn.get("items")[0].t_warehouse)
if stock_in_hand_account == fixed_asset_account: if stock_in_hand_account == fixed_asset_account:
# no gl entry as both source and target warehouse has linked to same account. # no gl entry as both source and target warehouse has linked to same account.
self.assertFalse(frappe.db.sql("""select * from `tabGL Entry` self.assertFalse(frappe.db.sql("""select * from `tabGL Entry`
where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name)) where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name))
else: else:
stock_value_diff = abs(frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Stock Entry", stock_value_diff = abs(frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Stock Entry",
"voucher_no": mtn.name, "warehouse": "_Test Warehouse - _TC"}, "stock_value_difference")) "voucher_no": mtn.name, "warehouse": "_Test Warehouse - _TC"}, "stock_value_difference"))
self.check_gl_entries("Stock Entry", mtn.name, self.check_gl_entries("Stock Entry", mtn.name,
sorted([ sorted([
[stock_in_hand_account, 0.0, stock_value_diff], [stock_in_hand_account, 0.0, stock_value_diff],
@ -467,7 +467,7 @@ class TestStockEntry(unittest.TestCase):
# permission tests # permission tests
def test_warehouse_user(self): def test_warehouse_user(self):
for role in ("Stock User", "Sales User"): for role in ("Stock User", "Sales User"):
set_user_permission_doctypes(doctype="Stock Entry", role=role, set_user_permission_doctypes(doctypes="Stock Entry", role=role,
apply_user_permissions=1, user_permission_doctypes=["Warehouse"]) apply_user_permissions=1, user_permission_doctypes=["Warehouse"])
frappe.defaults.add_default("Warehouse", "_Test Warehouse 1 - _TC", "test@example.com", "User Permission") frappe.defaults.add_default("Warehouse", "_Test Warehouse 1 - _TC", "test@example.com", "User Permission")

View File

@ -7,16 +7,18 @@
"allow_multiple": 1, "allow_multiple": 1,
"allow_print": 0, "allow_print": 0,
"amount": 0.0, "amount": 0.0,
"breadcrumbs": "[{\"title\":\"Issues\", \"name\":\"issues\"}]", "amount_based_on_field": 0,
"breadcrumbs": "[{\"label\":_(\"Issues\"), \"route\":\"issues\"}]",
"creation": "2016-06-24 15:50:33.186483", "creation": "2016-06-24 15:50:33.186483",
"doc_type": "Issue", "doc_type": "Issue",
"docstatus": 0, "docstatus": 0,
"doctype": "Web Form", "doctype": "Web Form",
"idx": 0, "idx": 0,
"introduction_text": "",
"is_standard": 1, "is_standard": 1,
"login_required": 1, "login_required": 1,
"max_attachment_size": 0, "max_attachment_size": 0,
"modified": "2016-12-07 04:26:13.917693", "modified": "2017-07-25 22:49:10.762704",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Support", "module": "Support",
"name": "issues", "name": "issues",

View File

@ -80,7 +80,7 @@
<div class="page-header-actions-block" data-html-block="header-actions"> <div class="page-header-actions-block" data-html-block="header-actions">
<p> <p>
<a href="/api/method/erpnext.accounts.doctype.payment_request.payment_request.make_payment_request?dn={{ doc.name }}&dt={{ doc.doctype }}&submit_doc=1" <a href="/api/method/erpnext.accounts.doctype.payment_request.payment_request.make_payment_request?dn={{ doc.name }}&dt={{ doc.doctype }}&submit_doc=1"
class="btn btn-primary btn-sm">Pay {{ doc.get_formatted("grand_total") }} </a> class="btn btn-primary btn-sm">{{ _("Pay") }} {{ doc.get_formatted("grand_total") }} </a>
</p> </p>
</div> </div>
{% endif %} {% endif %}

View File

@ -18,6 +18,7 @@ def get_context(context):
context.attachments = get_attachments(frappe.form_dict.doctype, frappe.form_dict.name) context.attachments = get_attachments(frappe.form_dict.doctype, frappe.form_dict.name)
context.parents = frappe.form_dict.parents context.parents = frappe.form_dict.parents
context.title = frappe.form_dict.name
context.payment_ref = frappe.db.get_value("Payment Request", context.payment_ref = frappe.db.get_value("Payment Request",
{"reference_name": frappe.form_dict.name}, "name") {"reference_name": frappe.form_dict.name}, "name")

View File

@ -23,6 +23,7 @@ erpnext/hr/doctype/attendance/test_attendance.js
erpnext/hr/doctype/leave_type/test_leave_type.js erpnext/hr/doctype/leave_type/test_leave_type.js
erpnext/hr/doctype/leave_control_panel/test_leave_control_panel.js erpnext/hr/doctype/leave_control_panel/test_leave_control_panel.js
erpnext/hr/doctype/leave_allocation/test_leave_allocation.js erpnext/hr/doctype/leave_allocation/test_leave_allocation.js
erpnext/hr/doctype/leave_application/test_leave_application.js
erpnext/schools/doctype/academic_year/test_academic_year.js erpnext/schools/doctype/academic_year/test_academic_year.js
erpnext/schools/doctype/academic_term/test_academic_term.js erpnext/schools/doctype/academic_term/test_academic_term.js
erpnext/schools/doctype/school_settings/test_school_settings.js erpnext/schools/doctype/school_settings/test_school_settings.js
@ -30,4 +31,5 @@ erpnext/schools/doctype/student_batch_name/test_student_batch_name.js
erpnext/schools/doctype/student_category/test_student_category.js erpnext/schools/doctype/student_category/test_student_category.js
erpnext/schools/doctype/room/test_room.js erpnext/schools/doctype/room/test_room.js
erpnext/schools/doctype/instructor/test_instructor.js erpnext/schools/doctype/instructor/test_instructor.js
erpnext/accounts/page/pos/test_pos.js erpnext/accounts/page/pos/test_pos.js
erpnext/selling/doctype/product_bundle/test_product_bundle.js