Merge branch 'hotfix'

This commit is contained in:
Nabin Hait 2018-03-27 14:22:28 +05:30
commit 745292ce98
19 changed files with 145 additions and 38 deletions

View File

@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
__version__ = '10.1.14'
__version__ = '10.1.15'
def get_default_company(user=None):
'''Get default company for user'''

View File

@ -61,7 +61,10 @@ frappe.query_reports["General Ledger"] = {
"label": __("Party Type"),
"fieldtype": "Link",
"options": "Party Type",
"default": ""
"default": "",
on_change: function() {
frappe.query_report_filters_by_name.party.set_value("");
}
},
{
"fieldname":"party",
@ -82,8 +85,7 @@ frappe.query_reports["General Ledger"] = {
frappe.query_report_filters_by_name.party_name.set_value("");
return;
}
var fieldname = frappe.scrub(party_type) + "_name";
var fieldname = erpnext.utils.get_party_name(party_type) || "name";
frappe.db.get_value(party_type, party, fieldname, function(value) {
frappe.query_report_filters_by_name.party_name.set_value(value[fieldname]);
});

View File

@ -71,7 +71,7 @@ def set_account_currency(filters):
if gle_currency:
account_currency = gle_currency
else:
account_currency = None if filters.party_type == "Employee" else \
account_currency = None if filters.party_type in ["Employee", "Student", "Shareholder"] else \
frappe.db.get_value(filters.party_type, filters.party, "default_currency")
filters["account_currency"] = account_currency or filters.company_currency

View File

@ -217,7 +217,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
me.frm.doc['supplied_items'].forEach((item, index) => {
if (item.rm_item_code && item.main_item_code) {
me.raw_material_data.push ({
'name':index,
'name':item.name,
'item_code': item.main_item_code,
'rm_item_code': item.rm_item_code,
'item_name': item.rm_item_code,

View File

@ -285,7 +285,7 @@ class StatusUpdater(Document):
ifnull((select
ifnull(sum(if(%(target_ref_field)s > %(target_field)s, abs(%(target_field)s), abs(%(target_ref_field)s))), 0)
/ sum(abs(%(target_ref_field)s)) * 100
from `tab%(target_dt)s` where parent="%(name)s" having sum(abs(%(target_ref_field)s)) > 0), 0), 2)
from `tab%(target_dt)s` where parent="%(name)s" having sum(abs(%(target_ref_field)s)) > 0), 0), 6)
%(update_modified)s
where name='%(name)s'""" % args)
@ -293,7 +293,7 @@ class StatusUpdater(Document):
if args.get('status_field'):
frappe.db.sql("""update `tab%(target_parent_dt)s`
set %(status_field)s = if(%(target_parent_field)s<0.001,
'Not %(keyword)s', if(%(target_parent_field)s>=99.99,
'Not %(keyword)s', if(%(target_parent_field)s>=99.999999,
'Fully %(keyword)s', 'Partly %(keyword)s'))
where name='%(name)s'""" % args)

View File

@ -16,6 +16,12 @@ frappe.ui.form.on("Program Enrollment Tool", {
});
},
get_students_from: function(frm) {
if (frm.doc.get_students_from == "Student Applicant") {
frm.dashboard.add_comment(__('Only the Student Applicant with the status "Approved" will be selected in the table below.'));
}
},
"get_students": function(frm) {
frm.set_value("students",[]);
frappe.call({

View File

@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
@ -12,6 +13,7 @@
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -21,6 +23,8 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Operation",
@ -38,9 +42,11 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -50,6 +56,8 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Workstation",
@ -67,9 +75,11 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -79,6 +89,8 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Description",
@ -95,9 +107,11 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -107,6 +121,8 @@
"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,
"length": 0,
@ -120,9 +136,11 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -132,6 +150,8 @@
"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": "Hour Rate",
@ -149,9 +169,11 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -162,7 +184,9 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Operation Time ",
"length": 0,
@ -179,9 +203,11 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -191,6 +217,8 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Operating Cost",
@ -208,9 +236,11 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -220,6 +250,8 @@
"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": "Base Hour Rate(Company Currency)",
@ -236,9 +268,11 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -249,6 +283,8 @@
"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": "Operating Cost(Company Currency)",
@ -265,9 +301,11 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -277,6 +315,8 @@
"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": "Image",
@ -292,20 +332,21 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-02-10 07:12:41.255544",
"modified": "2018-03-26 09:55:28.107451",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Operation",
@ -314,6 +355,7 @@
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"track_changes": 0,
"track_seen": 0
}

View File

@ -497,4 +497,5 @@ erpnext.patches.v10_0.update_warehouse_address_details
erpnext.patches.v10_0.update_reserved_qty_for_purchase_order
erpnext.patches.v10_0.update_hub_connector_domain
erpnext.patches.v10_0.set_student_party_type
erpnext.patches.v10_0.update_project_in_sle
erpnext.patches.v10_0.update_project_in_sle
erpnext.patches.v10_0.fix_reserved_qty_for_sub_contract

View File

@ -0,0 +1,29 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from erpnext.stock.utils import get_bin
def execute():
for d in frappe.db.sql("""
select distinct rm_item_code, reserve_warehouse
from `tabPurchase Order Item Supplied`
where docstatus=1 and reserve_warehouse is not null and reserve_warehouse != ''"""):
try:
bin_doc = get_bin(d[0], d[1])
bin_doc.update_reserved_qty_for_sub_contracting()
except:
pass
for d in frappe.db.sql("""select distinct item_code, source_warehouse
from `tabProduction Order Item`
where docstatus=1 and transferred_qty > required_qty
and source_warehouse is not null and source_warehouse != ''""", as_list=1):
try:
bin_doc = get_bin(d[0], d[1])
bin_doc.update_reserved_qty_for_production()
except:
pass

View File

@ -105,6 +105,12 @@ $.extend(erpnext.utils, {
}
},
get_party_name: function(party_type) {
var dict = {'Customer': 'customer_name', 'Supplier': 'supplier_name', 'Employee': 'employee_name',
'Member': 'member_name'};
return dict[party_type];
},
copy_value_in_all_row: function(doc, dt, dn, table_fieldname, fieldname) {
var d = locals[dt][dn];
if(d[fieldname]){

View File

@ -109,8 +109,8 @@ class Gstr1Report(object):
customers = frappe.get_all("Customer", filters={"customer_type": self.customer_type})
if self.filters.get("type_of_business") == "B2B":
conditions += " and invoice_type != 'Export' and is_return != 1 and customer in ('{0}')".\
format("', '".join([frappe.db.escape(c.name) for c in customers]))
conditions += """ and ifnull(invoice_type, '') != 'Export' and is_return != 1
and customer in ('{0}')""".format("', '".join([frappe.db.escape(c.name) for c in customers]))
if self.filters.get("type_of_business") in ("B2C Large", "B2C Small"):
b2c_limit = frappe.db.get_single_value('GSt Settings', 'b2c_limit')

View File

@ -84,7 +84,7 @@ class Gstr2Report(Gstr1Report):
conditions += opts[1]
if self.filters.get("type_of_business") == "B2B":
conditions += "and invoice_type != 'Export' and is_return != 1 "
conditions += "and ifnull(invoice_type, '') != 'Export' and is_return != 1 "
elif self.filters.get("type_of_business") == "CDNR":
conditions += """ and is_return = 1 """

View File

@ -96,14 +96,14 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
if (this.frm.has_perm("submit")) {
// close
if(flt(doc.per_delivered, 2) < 100 || flt(doc.per_billed) < 100) {
if(flt(doc.per_delivered, 6) < 100 || flt(doc.per_billed) < 100) {
this.frm.add_custom_button(__('Close'),
function() { me.close_sales_order() }, __("Status"))
}
}
// delivery note
if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && allow_delivery) {
if(flt(doc.per_delivered, 6) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && allow_delivery) {
this.frm.add_custom_button(__('Delivery'),
function() { me.make_delivery_note_based_on_delivery_date(); }, __("Make"));
this.frm.add_custom_button(__('Production Order'),
@ -113,20 +113,20 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
}
// sales invoice
if(flt(doc.per_billed, 2) < 100) {
if(flt(doc.per_billed, 6) < 100) {
this.frm.add_custom_button(__('Invoice'),
function() { me.make_sales_invoice() }, __("Make"));
}
// material request
if(!doc.order_type || ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1
&& flt(doc.per_delivered, 2) < 100) {
&& flt(doc.per_delivered, 6) < 100) {
this.frm.add_custom_button(__('Material Request'),
function() { me.make_material_request() }, __("Make"));
}
// make purchase order
if(flt(doc.per_delivered, 2) < 100 && allow_purchase) {
if(flt(doc.per_delivered, 6) < 100 && allow_purchase) {
this.frm.add_custom_button(__('Purchase Order'),
function() { me.make_purchase_order() }, __("Make"));
}
@ -229,6 +229,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
{fieldtype:'Data', fieldname:'sales_order_item', reqd: 1,
label: __('Sales Order Item'), hidden:1}
],
data: r.message,
get_data: function() {
return r.message
}

View File

@ -360,6 +360,7 @@ class SalesOrder(SellingController):
where production_item=%s and sales_order=%s and sales_order_item = %s and docstatus<2''', (i.item_code, self.name, i.name))[0][0])
if pending_qty:
items.append(dict(
name= i.name,
item_code= i.item_code,
bom = bom,
warehouse = i.warehouse,

View File

@ -6,15 +6,15 @@ frappe.listview_settings['Sales Order'] = {
return [__("Closed"), "green", "status,=,Closed"];
} else if (doc.order_type !== "Maintenance"
&& flt(doc.per_delivered, 2) < 100 && frappe.datetime.get_diff(doc.delivery_date) < 0) {
&& flt(doc.per_delivered, 6) < 100 && frappe.datetime.get_diff(doc.delivery_date) < 0) {
// to bill & overdue
return [__("Overdue"), "red", "per_delivered,<,100|delivery_date,<,Today|status,!=,Closed"];
} else if (doc.order_type !== "Maintenance"
&& flt(doc.per_delivered, 2) < 100 && doc.status!=="Closed") {
&& flt(doc.per_delivered, 6) < 100 && doc.status!=="Closed") {
// not delivered
if(flt(doc.per_billed, 2) < 100) {
if(flt(doc.per_billed, 6) < 100) {
// not delivered & not billed
return [__("To Deliver and Bill"), "orange",
@ -26,14 +26,14 @@ frappe.listview_settings['Sales Order'] = {
"per_delivered,<,100|per_billed,=,100|status,!=,Closed"];
}
} else if ((doc.order_type === "Maintenance" || flt(doc.per_delivered, 2) == 100)
&& flt(doc.per_billed, 2) < 100 && doc.status!=="Closed") {
} else if ((doc.order_type === "Maintenance" || flt(doc.per_delivered, 6) == 100)
&& flt(doc.per_billed, 6) < 100 && doc.status!=="Closed") {
// to bill
return [__("To Bill"), "orange", "per_delivered,=,100|per_billed,<,100|status,!=,Closed"];
} else if((doc.order_type === "Maintenance" || flt(doc.per_delivered, 2) == 100)
&& flt(doc.per_billed, 2) == 100 && doc.status!=="Closed") {
} else if((doc.order_type === "Maintenance" || flt(doc.per_delivered, 6) == 100)
&& flt(doc.per_billed, 6) == 100 && doc.status!=="Closed") {
return [__("Completed"), "green", "per_delivered,=,100|per_billed,=,100|status,!=,Closed"];
}

View File

@ -76,14 +76,16 @@ class Bin(Document):
def update_reserved_qty_for_production(self):
'''Update qty reserved for production from Production Item tables
in open production orders'''
self.reserved_qty_for_production = frappe.db.sql('''select sum(required_qty - transferred_qty)
self.reserved_qty_for_production = frappe.db.sql('''
select sum(item.required_qty - item.transferred_qty)
from `tabProduction Order` pro, `tabProduction Order Item` item
where
item.item_code = %s
and item.parent = pro.name
and pro.docstatus = 1
and item.source_warehouse = %s
and pro.status not in ("Stopped", "Completed")''', (self.item_code, self.warehouse))[0][0]
and pro.status not in ("Stopped", "Completed")
and item.required_qty > item.transferred_qty''', (self.item_code, self.warehouse))[0][0]
self.set_projected_qty()
@ -123,7 +125,12 @@ class Bin(Document):
and po.per_received < 100
""", (self.item_code))[0][0]
self.db_set('reserved_qty_for_sub_contract', (reserved_qty_for_sub_contract - materials_transferred))
if reserved_qty_for_sub_contract > materials_transferred:
reserved_qty_for_sub_contract = reserved_qty_for_sub_contract - materials_transferred
else:
reserved_qty_for_sub_contract = 0
self.db_set('reserved_qty_for_sub_contract', reserved_qty_for_sub_contract)
self.set_projected_qty()
self.db_set('projected_qty', self.projected_qty)

View File

@ -19,7 +19,7 @@ def get_product_bundle_items(item_code):
where t2.new_item_code=%s and t1.parent = t2.name order by t1.idx""", item_code, as_dict=1)
def get_packing_item_details(item):
return frappe.db.sql("""select item_name, description, stock_uom from `tabItem`
return frappe.db.sql("""select item_name, description, stock_uom, default_warehouse from `tabItem`
where name = %s""", item, as_dict = 1)[0]
def get_bin_qty(item, warehouse):
@ -28,7 +28,6 @@ def get_bin_qty(item, warehouse):
return det and det[0] or frappe._dict()
def update_packing_list_item(doc, packing_item_code, qty, main_item_row, description):
bin = get_bin_qty(packing_item_code, main_item_row.warehouse)
item = get_packing_item_details(packing_item_code)
# check if exists
@ -48,15 +47,16 @@ def update_packing_list_item(doc, packing_item_code, qty, main_item_row, descrip
pi.description = item.description
pi.uom = item.stock_uom
pi.qty = flt(qty)
pi.actual_qty = flt(bin.get("actual_qty"))
pi.projected_qty = flt(bin.get("projected_qty"))
pi.description = description
if not pi.warehouse:
pi.warehouse = main_item_row.warehouse
pi.warehouse = item.default_warehouse or main_item_row.warehouse
if not pi.batch_no:
pi.batch_no = cstr(main_item_row.get("batch_no"))
if not pi.target_warehouse:
pi.target_warehouse = main_item_row.get("target_warehouse")
bin = get_bin_qty(packing_item_code, pi.warehouse)
pi.actual_qty = flt(bin.get("actual_qty"))
pi.projected_qty = flt(bin.get("projected_qty"))
def make_packing_list(doc):
"""make packing list for Product Bundle item"""

View File

@ -217,6 +217,12 @@ def validate_serial_no(sle, item_det):
frappe.throw(_("Serial No {0} has already been received").format(serial_no),
SerialNoDuplicateError)
if (sr.delivery_document_no and sle.voucher_type != 'Stock Entry'
and sle.voucher_type == sr.delivery_document_type):
return_against = frappe.db.get_value(sle.voucher_type, sle.voucher_no, 'return_against')
if return_against and return_against != sr.delivery_document_no:
frappe.throw(_("Serial no {0} has been already returned").format(sr.name))
if sle.actual_qty < 0:
if sr.warehouse!=sle.warehouse:
frappe.throw(_("Serial No {0} does not belong to Warehouse {1}").format(serial_no,

View File

@ -106,8 +106,8 @@ frappe.ui.form.on('Stock Entry', {
frm.trigger("toggle_display_account_head");
}
if(frm.doc.docstatus==1 && frm.doc.purpose == "Material Receipt") {
frm.add_custom_button(__('Make Retention Stock Entry'), function () {
if(frm.doc.docstatus==1 && frm.doc.purpose == "Material Receipt" && frm.get_sum('items', 'sample_quantity')) {
frm.add_custom_button(__('Make Sample Retention Stock Entry'), function () {
frm.trigger("make_retention_stock_entry");
});
}
@ -465,7 +465,13 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
}
this.frm.set_indicator_formatter('item_code',
function(doc) { return (doc.qty<=doc.actual_qty) ? "green" : "orange" })
function(doc) {
if (!doc.s_warehouse) {
return 'blue';
} else {
return (doc.qty<=doc.actual_qty) ? "green" : "orange"
}
})
this.frm.add_fetch("purchase_order", "supplier", "supplier");