mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-05 05:09:11 +00:00
Merge branch 'develop' of https://github.com/frappe/erpnext into develop
This commit is contained in:
@@ -180,10 +180,20 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
get_items_from_open_material_requests: function() {
|
get_items_from_open_material_requests: function() {
|
||||||
erpnext.utils.map_current_doc({
|
erpnext.utils.map_current_doc({
|
||||||
method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order_based_on_supplier",
|
method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order_based_on_supplier",
|
||||||
|
args: {
|
||||||
|
supplier: this.frm.doc.supplier
|
||||||
|
},
|
||||||
|
source_doctype: "Material Request",
|
||||||
source_name: this.frm.doc.supplier,
|
source_name: this.frm.doc.supplier,
|
||||||
|
target: this.frm,
|
||||||
|
setters: {
|
||||||
|
company: me.frm.doc.company
|
||||||
|
},
|
||||||
get_query_filters: {
|
get_query_filters: {
|
||||||
docstatus: ["!=", 2],
|
docstatus: ["!=", 2],
|
||||||
}
|
supplier: this.frm.doc.supplier
|
||||||
|
},
|
||||||
|
get_query_method: "erpnext.stock.doctype.material_request.material_request.get_material_requests_based_on_supplier"
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
"supplier",
|
"supplier",
|
||||||
"get_items_from_open_material_requests",
|
"get_items_from_open_material_requests",
|
||||||
"supplier_name",
|
"supplier_name",
|
||||||
"company",
|
|
||||||
"column_break1",
|
"column_break1",
|
||||||
|
"company",
|
||||||
"transaction_date",
|
"transaction_date",
|
||||||
"schedule_date",
|
"schedule_date",
|
||||||
"order_confirmation_no",
|
"order_confirmation_no",
|
||||||
@@ -170,6 +170,7 @@
|
|||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "Fetch items based on Default Supplier.",
|
||||||
"depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))",
|
"depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))",
|
||||||
"fieldname": "get_items_from_open_material_requests",
|
"fieldname": "get_items_from_open_material_requests",
|
||||||
"fieldtype": "Button",
|
"fieldtype": "Button",
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ def get_data():
|
|||||||
'heatmap_message': _('This is based on transactions against this Supplier. See timeline below for details'),
|
'heatmap_message': _('This is based on transactions against this Supplier. See timeline below for details'),
|
||||||
'fieldname': 'supplier',
|
'fieldname': 'supplier',
|
||||||
'non_standard_fieldnames': {
|
'non_standard_fieldnames': {
|
||||||
'Payment Entry': 'party_name'
|
'Payment Entry': 'party_name',
|
||||||
|
'Bank Account': 'party'
|
||||||
},
|
},
|
||||||
'transactions': [
|
'transactions': [
|
||||||
{
|
{
|
||||||
@@ -24,6 +25,10 @@ def get_data():
|
|||||||
'label': _('Payments'),
|
'label': _('Payments'),
|
||||||
'items': ['Payment Entry']
|
'items': ['Payment Entry']
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'label': _('Bank'),
|
||||||
|
'items': ['Bank Account']
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'label': _('Pricing'),
|
'label': _('Pricing'),
|
||||||
'items': ['Pricing Rule']
|
'items': ['Pricing Rule']
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ class Student(Document):
|
|||||||
if self.date_of_birth and getdate(self.date_of_birth) >= getdate(today()):
|
if self.date_of_birth and getdate(self.date_of_birth) >= getdate(today()):
|
||||||
frappe.throw(_("Date of Birth cannot be greater than today."))
|
frappe.throw(_("Date of Birth cannot be greater than today."))
|
||||||
|
|
||||||
|
if self.date_of_birth and getdate(self.date_of_birth) >= getdate(self.joining_date):
|
||||||
|
frappe.throw(_("Date of Birth cannot be greater than Joining Date."))
|
||||||
|
|
||||||
if self.joining_date and self.date_of_leaving and getdate(self.joining_date) > getdate(self.date_of_leaving):
|
if self.joining_date and self.date_of_leaving and getdate(self.joining_date) > getdate(self.date_of_leaving):
|
||||||
frappe.throw(_("Joining Date can not be greater than Leaving Date"))
|
frappe.throw(_("Joining Date can not be greater than Leaving Date"))
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,16 @@ frappe.ui.form.on("Student Group", {
|
|||||||
group_based_on: function(frm) {
|
group_based_on: function(frm) {
|
||||||
if (frm.doc.group_based_on == "Batch") {
|
if (frm.doc.group_based_on == "Batch") {
|
||||||
frm.doc.course = null;
|
frm.doc.course = null;
|
||||||
|
frm.set_df_property('program', 'reqd', 1);
|
||||||
|
frm.set_df_property('course', 'reqd', 0);
|
||||||
|
}
|
||||||
|
else if (frm.doc.group_based_on == "Course") {
|
||||||
|
frm.set_df_property('program', 'reqd', 0);
|
||||||
|
frm.set_df_property('course', 'reqd', 1);
|
||||||
|
}
|
||||||
|
else if (frm.doc.group_based_on == "Activity") {
|
||||||
|
frm.set_df_property('program', 'reqd', 0);
|
||||||
|
frm.set_df_property('course', 'reqd', 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ import frappe
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import get_link_to_form
|
from frappe.utils import get_link_to_form
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe import throw, _
|
||||||
|
|
||||||
class StudentLeaveApplication(Document):
|
class StudentLeaveApplication(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
|
self.validate_dates()
|
||||||
self.validate_duplicate()
|
self.validate_duplicate()
|
||||||
|
|
||||||
def validate_duplicate(self):
|
def validate_duplicate(self):
|
||||||
@@ -30,3 +32,7 @@ class StudentLeaveApplication(Document):
|
|||||||
link = get_link_to_form("Student Leave Application", data[0].name)
|
link = get_link_to_form("Student Leave Application", data[0].name)
|
||||||
frappe.throw(_("Leave application {0} already exists against the student {1}")
|
frappe.throw(_("Leave application {0} already exists against the student {1}")
|
||||||
.format(link, self.student))
|
.format(link, self.student))
|
||||||
|
|
||||||
|
def validate_dates(self):
|
||||||
|
if self.to_date < self.from_date :
|
||||||
|
throw(_("To Date cannot be less than From Date"))
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2016-03-25 02:52:19.283003",
|
"creation": "2016-03-25 02:52:19.283003",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
"fetch_from": "user.full_name",
|
"fetch_from": "user.full_name",
|
||||||
"fieldname": "full_name",
|
"fieldname": "full_name",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "Full Name"
|
"label": "Full Name"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
"label": "Welcome email sent"
|
"label": "Welcome email sent"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 1,
|
"columns": 2,
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "view_attachments",
|
"fieldname": "view_attachments",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
@@ -74,7 +76,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-07-15 19:37:26.942294",
|
"links": [],
|
||||||
|
"modified": "2020-02-09 23:26:50.321417",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Project User",
|
"name": "Project User",
|
||||||
|
|||||||
@@ -514,9 +514,18 @@ erpnext.utils.update_child_items = function(opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
erpnext.utils.map_current_doc = function(opts) {
|
erpnext.utils.map_current_doc = function(opts) {
|
||||||
if(opts.get_query_filters) {
|
let query_args = {};
|
||||||
opts.get_query = function() {
|
if (opts.get_query_filters) {
|
||||||
return {filters: opts.get_query_filters};
|
query_args.filters = opts.get_query_filters;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.get_query_method) {
|
||||||
|
query_args.query = opts.get_query_method;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query_args.filters || query_args.query) {
|
||||||
|
opts.get_query = () => {
|
||||||
|
return query_args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var _map = function() {
|
var _map = function() {
|
||||||
@@ -582,7 +591,7 @@ erpnext.utils.map_current_doc = function(opts) {
|
|||||||
"method": opts.method,
|
"method": opts.method,
|
||||||
"source_names": opts.source_name,
|
"source_names": opts.source_name,
|
||||||
"target_doc": cur_frm.doc,
|
"target_doc": cur_frm.doc,
|
||||||
'args': opts.args
|
"args": opts.args
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(!r.exc) {
|
if(!r.exc) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
import json
|
||||||
|
|
||||||
from frappe.utils import cstr, flt, getdate, new_line_sep, nowdate, add_days
|
from frappe.utils import cstr, flt, getdate, new_line_sep, nowdate, add_days
|
||||||
from frappe import msgprint, _
|
from frappe import msgprint, _
|
||||||
@@ -329,17 +330,13 @@ def make_request_for_quotation(source_name, target_doc=None):
|
|||||||
return doclist
|
return doclist
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_purchase_order_based_on_supplier(source_name, target_doc=None):
|
def make_purchase_order_based_on_supplier(source_name, target_doc=None, args=None):
|
||||||
if target_doc:
|
mr = source_name
|
||||||
if isinstance(target_doc, string_types):
|
|
||||||
import json
|
|
||||||
target_doc = frappe.get_doc(json.loads(target_doc))
|
|
||||||
target_doc.set("items", [])
|
|
||||||
|
|
||||||
material_requests, supplier_items = get_material_requests_based_on_supplier(source_name)
|
supplier_items = get_items_based_on_default_supplier(args.get("supplier"))
|
||||||
|
|
||||||
def postprocess(source, target_doc):
|
def postprocess(source, target_doc):
|
||||||
target_doc.supplier = source_name
|
target_doc.supplier = args.get("supplier")
|
||||||
if getdate(target_doc.schedule_date) < getdate(nowdate()):
|
if getdate(target_doc.schedule_date) < getdate(nowdate()):
|
||||||
target_doc.schedule_date = None
|
target_doc.schedule_date = None
|
||||||
target_doc.set("items", [d for d in target_doc.get("items")
|
target_doc.set("items", [d for d in target_doc.get("items")
|
||||||
@@ -347,44 +344,64 @@ def make_purchase_order_based_on_supplier(source_name, target_doc=None):
|
|||||||
|
|
||||||
set_missing_values(source, target_doc)
|
set_missing_values(source, target_doc)
|
||||||
|
|
||||||
for mr in material_requests:
|
target_doc = get_mapped_doc("Material Request", mr, {
|
||||||
target_doc = get_mapped_doc("Material Request", mr, {
|
"Material Request": {
|
||||||
"Material Request": {
|
"doctype": "Purchase Order",
|
||||||
"doctype": "Purchase Order",
|
},
|
||||||
},
|
"Material Request Item": {
|
||||||
"Material Request Item": {
|
"doctype": "Purchase Order Item",
|
||||||
"doctype": "Purchase Order Item",
|
"field_map": [
|
||||||
"field_map": [
|
["name", "material_request_item"],
|
||||||
["name", "material_request_item"],
|
["parent", "material_request"],
|
||||||
["parent", "material_request"],
|
["uom", "stock_uom"],
|
||||||
["uom", "stock_uom"],
|
["uom", "uom"]
|
||||||
["uom", "uom"]
|
],
|
||||||
],
|
"postprocess": update_item,
|
||||||
"postprocess": update_item,
|
"condition": lambda doc: doc.ordered_qty < doc.qty
|
||||||
"condition": lambda doc: doc.ordered_qty < doc.qty
|
}
|
||||||
}
|
}, target_doc, postprocess)
|
||||||
}, target_doc, postprocess)
|
|
||||||
|
|
||||||
return target_doc
|
return target_doc
|
||||||
|
|
||||||
def get_material_requests_based_on_supplier(supplier):
|
@frappe.whitelist()
|
||||||
|
def get_items_based_on_default_supplier(supplier):
|
||||||
supplier_items = [d.parent for d in frappe.db.get_all("Item Default",
|
supplier_items = [d.parent for d in frappe.db.get_all("Item Default",
|
||||||
{"default_supplier": supplier}, 'parent')]
|
{"default_supplier": supplier, "parenttype": "Item"}, 'parent')]
|
||||||
|
|
||||||
|
return supplier_items
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_material_requests_based_on_supplier(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
conditions = ""
|
||||||
|
if txt:
|
||||||
|
conditions += "and mr.name like '%%"+txt+"%%' "
|
||||||
|
|
||||||
|
if filters.get("transaction_date"):
|
||||||
|
date = filters.get("transaction_date")[1]
|
||||||
|
conditions += "and mr.transaction_date between '{0}' and '{1}' ".format(date[0], date[1])
|
||||||
|
|
||||||
|
supplier = filters.get("supplier")
|
||||||
|
supplier_items = get_items_based_on_default_supplier(supplier)
|
||||||
|
|
||||||
if not supplier_items:
|
if not supplier_items:
|
||||||
frappe.throw(_("{0} is not the default supplier for any items.").format(supplier))
|
frappe.throw(_("{0} is not the default supplier for any items.").format(supplier))
|
||||||
|
|
||||||
material_requests = frappe.db.sql_list("""select distinct mr.name
|
material_requests = frappe.db.sql("""select distinct mr.name, transaction_date,company
|
||||||
from `tabMaterial Request` mr, `tabMaterial Request Item` mr_item
|
from `tabMaterial Request` mr, `tabMaterial Request Item` mr_item
|
||||||
where mr.name = mr_item.parent
|
where mr.name = mr_item.parent
|
||||||
and mr_item.item_code in (%s)
|
and mr_item.item_code in ({0})
|
||||||
and mr.material_request_type = 'Purchase'
|
and mr.material_request_type = 'Purchase'
|
||||||
and mr.per_ordered < 99.99
|
and mr.per_ordered < 99.99
|
||||||
and mr.docstatus = 1
|
and mr.docstatus = 1
|
||||||
and mr.status != 'Stopped'
|
and mr.status != 'Stopped'
|
||||||
order by mr_item.item_code ASC""" % ', '.join(['%s']*len(supplier_items)),
|
and mr.company = '{1}'
|
||||||
tuple(supplier_items))
|
{2}
|
||||||
|
order by mr_item.item_code ASC
|
||||||
|
limit {3} offset {4} """ \
|
||||||
|
.format(', '.join(['%s']*len(supplier_items)), filters.get("company"), conditions, page_len, start),
|
||||||
|
tuple(supplier_items), as_dict=1)
|
||||||
|
|
||||||
return material_requests, supplier_items
|
return material_requests
|
||||||
|
|
||||||
def get_default_supplier_query(doctype, txt, searchfield, start, page_len, filters):
|
def get_default_supplier_query(doctype, txt, searchfield, start, page_len, filters):
|
||||||
doc = frappe.get_doc("Material Request", filters.get("doc"))
|
doc = frappe.get_doc("Material Request", filters.get("doc"))
|
||||||
|
|||||||
16
package.json
16
package.json
@@ -1,7 +1,21 @@
|
|||||||
{
|
{
|
||||||
"devdependencies": {
|
"name": "erpnext",
|
||||||
|
"description": "Open Source ERP System powered by the Frappe Framework",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/frappe/erpnext.git"
|
||||||
|
},
|
||||||
|
"homepage": "https://erpnext.com",
|
||||||
|
"author": "Frappe Technologies Pvt. Ltd.",
|
||||||
|
"license": "GPL-3.0",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/frappe/erpnext/issues"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
"snyk": "^1.290.1"
|
"snyk": "^1.290.1"
|
||||||
},
|
},
|
||||||
|
"dependencies": {
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"snyk-protect": "snyk protect",
|
"snyk-protect": "snyk protect",
|
||||||
"prepare": "yarn run snyk-protect"
|
"prepare": "yarn run snyk-protect"
|
||||||
|
|||||||
Reference in New Issue
Block a user