Merge pull request #21367 from scmmishra/cal-report
fix: specify column width
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 100bb1d..b358f56 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -330,9 +330,9 @@
if pr_doc.mixed_conditions:
amt = args.get('qty') * args.get("price_list_rate")
if args.get("item_code") != row.get("item_code"):
- amt = row.get('qty') * (row.get("price_list_rate") or args.get("rate"))
+ amt = flt(row.get('qty')) * flt(row.get("price_list_rate") or args.get("rate"))
- sum_qty += row.get("stock_qty") or args.get("stock_qty") or args.get("qty")
+ sum_qty += flt(row.get("stock_qty")) or flt(args.get("stock_qty")) or flt(args.get("qty"))
sum_amt += amt
if pr_doc.is_cumulative:
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 3af236c..0e09454 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -13,23 +13,18 @@
"supplier_name",
"tax_id",
"due_date",
- "is_paid",
- "is_return",
- "apply_tds",
"column_break1",
"company",
"posting_date",
"posting_time",
"set_posting_time",
+ "is_paid",
+ "is_return",
+ "apply_tds",
"amended_from",
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
- "sb_14",
- "on_hold",
- "release_date",
- "cb_17",
- "hold_comment",
"supplier_invoice_details",
"bill_no",
"column_break_15",
@@ -137,10 +132,15 @@
"terms",
"printing_settings",
"letter_head",
- "group_same_items",
- "column_break_112",
"select_print_heading",
+ "column_break_112",
+ "group_same_items",
"language",
+ "sb_14",
+ "on_hold",
+ "release_date",
+ "cb_17",
+ "hold_comment",
"more_info",
"credit_to",
"party_account_currency",
@@ -190,6 +190,7 @@
"oldfieldtype": "Link",
"options": "Supplier",
"print_hide": 1,
+ "reqd": 1,
"search_index": 1
},
{
@@ -1232,6 +1233,7 @@
"print_hide": 1
},
{
+ "collapsible": 1,
"fieldname": "subscription_section",
"fieldtype": "Section Break",
"label": "Subscription Section",
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 db3f72a..52a5be0 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -12,15 +12,11 @@
"item_name",
"description_section",
"description",
- "item_group",
"brand",
- "image_section",
+ "col_break7",
+ "item_group",
"image",
"image_view",
- "manufacture_details",
- "manufacturer",
- "column_break_13",
- "manufacturer_part_no",
"quantity_and_rate",
"received_qty",
"qty",
@@ -55,20 +51,19 @@
"item_tax_amount",
"landed_cost_voucher_amount",
"rm_supp_cost",
- "item_weight_details",
- "weight_per_unit",
- "total_weight",
- "column_break_38",
- "weight_uom",
"warehouse_section",
"warehouse",
- "rejected_warehouse",
"from_warehouse",
"quality_inspection",
- "batch_no",
- "col_br_wh",
"serial_no",
+ "col_br_wh",
+ "rejected_warehouse",
+ "batch_no",
"rejected_serial_no",
+ "manufacture_details",
+ "manufacturer",
+ "column_break_13",
+ "manufacturer_part_no",
"accounting",
"expense_account",
"col_break5",
@@ -92,6 +87,11 @@
"po_detail",
"purchase_receipt",
"pr_detail",
+ "item_weight_details",
+ "weight_per_unit",
+ "total_weight",
+ "column_break_38",
+ "weight_uom",
"accounting_dimensions_section",
"project",
"dimension_col_break",
@@ -550,23 +550,21 @@
},
{
"fieldname": "brand",
- "fieldtype": "Data",
- "hidden": 1,
- "label": "Brand",
- "oldfieldname": "brand",
- "oldfieldtype": "Data",
- "print_hide": 1
- },
- {
- "fieldname": "item_group",
"fieldtype": "Link",
"hidden": 1,
- "label": "Item Group",
- "oldfieldname": "item_group",
- "oldfieldtype": "Link",
- "options": "Item Group",
+ "label": "Brand",
"print_hide": 1,
- "read_only": 1
+ "options": "Brand"
+ },
+ {
+ "fetch_from": "item_code.item_group",
+ "fetch_if_empty": 1,
+ "fieldname": "item_group",
+ "fieldtype": "Link",
+ "label": "Item Group",
+ "print_hide": 1,
+ "read_only": 1,
+ "options": "Item Group"
},
{
"description": "Tax detail table fetched from item master as a string and stored in this field.\nUsed for Taxes and Charges",
@@ -722,12 +720,6 @@
},
{
"collapsible": 1,
- "fieldname": "image_section",
- "fieldtype": "Section Break",
- "label": "Image"
- },
- {
- "collapsible": 1,
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions"
@@ -737,6 +729,7 @@
"fieldtype": "Column Break"
},
{
+ "collapsible": 1,
"fieldname": "manufacture_details",
"fieldtype": "Section Break",
"label": "Manufacture"
@@ -771,12 +764,17 @@
"ignore_user_permissions": 1,
"label": "Supplier Warehouse",
"options": "Warehouse"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "col_break7",
+ "fieldtype": "Column Break"
}
],
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2020-04-07 18:34:35.104178",
+ "modified": "2020-04-22 10:37:35.103176",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",
@@ -784,4 +782,4 @@
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC"
-}
\ No newline at end of file
+}
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js
index 3c135d4..001fc26 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js
@@ -24,26 +24,6 @@
return indicator;
}
);
-
- frm.set_query('select_serial_no', function(doc){
- return {
- asset: frm.doc.asset_name
- }
- })
- },
-
- select_serial_no: (frm) => {
- let serial_nos = frm.doc.serial_no || frm.doc.select_serial_no;
- if (serial_nos) {
- serial_nos = serial_nos.split('\n');
- serial_nos.push(frm.doc.select_serial_no);
-
- const unique_sn = serial_nos.filter(function(elem, index, self) {
- return index === self.indexOf(elem);
- });
-
- frm.set_value("serial_no", unique_sn.join('\n'));
- }
},
refresh: (frm) => {
@@ -93,25 +73,6 @@
},
end_date: (frm, cdt, cdn) => {
get_next_due_date(frm, cdt, cdn);
- },
- assign_to: (frm, cdt, cdn) => {
- var d = locals[cdt][cdn];
- if (frm.doc.__islocal) {
- frappe.model.set_value(cdt, cdn, "assign_to", "");
- frappe.model.set_value(cdt, cdn, "assign_to_name", "");
- frappe.throw(__("Please save before assigning task."));
- }
- if (d.assign_to) {
- return frappe.call({
- method: 'erpnext.assets.doctype.asset_maintenance.asset_maintenance.assign_tasks',
- args: {
- asset_maintenance_name: frm.doc.name,
- assign_to_member: d.assign_to,
- maintenance_task: d.maintenance_task,
- next_due_date: d.next_due_date
- }
- });
- }
}
});
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
index ecb55dd..3f04611 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
@@ -16,12 +16,11 @@
throw(_("Start date should be less than end date for task {0}").format(task.maintenance_task))
if getdate(task.next_due_date) < getdate(nowdate()):
task.maintenance_status = "Overdue"
+ if not task.assign_to and self.docstatus == 0:
+ throw(_("Row #{}: Please asign task to a member.").format(task.idx))
def on_update(self):
for task in self.get('asset_maintenance_tasks'):
- if not task.assign_to:
- task.db_set("assign_to", self.maintenance_manager)
- task.db_set("assign_to_name", self.maintenance_manager_name)
assign_tasks(self.name, task.assign_to, task.maintenance_task, task.next_due_date)
self.sync_maintenance_tasks()
@@ -108,7 +107,7 @@
@frappe.whitelist()
def get_team_members(doctype, txt, searchfield, start, page_len, filters):
- return frappe.db.get_values('Maintenance Team Member', {'parent':filters.get("maintenance_team")})
+ return frappe.db.get_values('Maintenance Team Member', { 'parent': filters.get("maintenance_team") })
@frappe.whitelist()
def get_maintenance_log(asset_name):
diff --git a/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py
index 6c2fd67..392fbdd 100644
--- a/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py
+++ b/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py
@@ -125,13 +125,15 @@
"start_date": nowdate(),
"periodicity": "Monthly",
"maintenance_type": "Preventive Maintenance",
- "maintenance_status": "Planned"
+ "maintenance_status": "Planned",
+ "assign_to": "marcus@abc.com"
},
{"maintenance_task": "Check Gears",
"start_date": nowdate(),
"periodicity": "Yearly",
"maintenance_type": "Calibration",
- "maintenance_status": "Planned"
+ "maintenance_status": "Planned",
+ "assign_to": "thalia@abc.com"
}
]
diff --git a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
index 6f2fbe5..ea58630 100644
--- a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
+++ b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
@@ -1,24 +1,31 @@
{
+ "actions": [],
"creation": "2013-02-22 01:27:42",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"main_item_code",
- "rm_item_code",
"description",
- "batch_no",
- "serial_no",
+ "bom_detail_no",
"col_break1",
- "required_qty",
- "consumed_qty",
+ "rm_item_code",
"stock_uom",
- "rate",
- "amount",
"conversion_factor",
- "current_stock",
"reference_name",
- "bom_detail_no"
+ "secbreak_1",
+ "rate",
+ "col_break2",
+ "amount",
+ "secbreak_2",
+ "required_qty",
+ "col_break3",
+ "consumed_qty",
+ "current_stock",
+ "secbreak_3",
+ "batch_no",
+ "col_break4",
+ "serial_no"
],
"fields": [
{
@@ -152,11 +159,36 @@
"oldfieldname": "bom_detail_no",
"oldfieldtype": "Data",
"read_only": 1
+ },
+ {
+ "fieldname": "secbreak_1",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "col_break2",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "secbreak_2",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "col_break3",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "secbreak_3",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "col_break4",
+ "fieldtype": "Column Break"
}
],
"idx": 1,
"istable": 1,
- "modified": "2019-11-21 16:25:29.909112",
+ "links": [],
+ "modified": "2020-04-10 18:09:33.997618",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Receipt Item Supplied",
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
index 3f295af..f32b7cf 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
@@ -79,6 +79,7 @@
if doc.is_billable and not doc.disabled:
disabled = 0
+ uom = frappe.db.exists('UOM', 'Unit') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
item = frappe.get_doc({
'doctype': 'Item',
'item_code': doc.template,
@@ -92,7 +93,7 @@
'show_in_website': 0,
'is_pro_applicable': 0,
'disabled': disabled,
- 'stock_uom': 'Unit'
+ 'stock_uom': uom
}).insert(ignore_permissions=True, ignore_mandatory=True)
make_item_price(item.name, doc.rate)
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
index 6bbb4f1..e2b47b4 100644
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
@@ -74,26 +74,27 @@
def create_item_from_template(doc):
- if doc.is_billable:
+ disabled = doc.disabled
+ if doc.is_billable and not doc.disabled:
disabled = 0
- else:
- disabled = 1
+
+ uom = frappe.db.exists('UOM', 'Unit') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
# insert item
item = frappe.get_doc({
- "doctype": "Item",
- "item_code": doc.lab_test_code,
- "item_name":doc.lab_test_name,
- "item_group": doc.lab_test_group,
- "description":doc.lab_test_description,
- "is_sales_item": 1,
- "is_service_item": 1,
- "is_purchase_item": 0,
- "is_stock_item": 0,
- "show_in_website": 0,
- "is_pro_applicable": 0,
- "disabled": disabled,
- "stock_uom": "Unit"
- }).insert(ignore_permissions=True)
+ "doctype": "Item",
+ "item_code": doc.lab_test_code,
+ "item_name":doc.lab_test_name,
+ "item_group": doc.lab_test_group,
+ "description":doc.lab_test_description,
+ "is_sales_item": 1,
+ "is_service_item": 1,
+ "is_purchase_item": 0,
+ "is_stock_item": 0,
+ "show_in_website": 0,
+ "is_pro_applicable": 0,
+ "disabled": disabled,
+ "stock_uom": uom
+ }).insert(ignore_permissions=True, ignore_mandatory=True)
# insert item price
# get item price list to insert item price
diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/desk_page/non_profit/non_profit.json
index a476857..ebe6194 100644
--- a/erpnext/non_profit/desk_page/non_profit/non_profit.json
+++ b/erpnext/non_profit/desk_page/non_profit/non_profit.json
@@ -42,7 +42,7 @@
"idx": 0,
"is_standard": 1,
"label": "Non Profit",
- "modified": "2020-04-01 11:28:51.430882",
+ "modified": "2020-04-13 13:41:52.373705",
"modified_by": "Administrator",
"module": "Non Profit",
"name": "Non Profit",
@@ -50,5 +50,31 @@
"pin_to_bottom": 0,
"pin_to_top": 0,
"restrict_to_domain": "Non Profit",
- "shortcuts": []
+ "shortcuts": [
+ {
+ "label": "Member",
+ "link_to": "Member",
+ "type": "DocType"
+ },
+ {
+ "label": "Membership Settings",
+ "link_to": "Membership Settings",
+ "type": "DocType"
+ },
+ {
+ "label": "Membership",
+ "link_to": "Membership",
+ "type": "DocType"
+ },
+ {
+ "label": "Chapter",
+ "link_to": "Chapter",
+ "type": "DocType"
+ },
+ {
+ "label": "Chapter Member",
+ "link_to": "Chapter Member",
+ "type": "DocType"
+ }
+ ]
}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/member/member.js b/erpnext/non_profit/doctype/member/member.js
index eb74dc1..3e9d0ba 100644
--- a/erpnext/non_profit/doctype/member/member.js
+++ b/erpnext/non_profit/doctype/member/member.js
@@ -2,6 +2,14 @@
// For license information, please see license.txt
frappe.ui.form.on('Member', {
+ setup: function(frm) {
+ frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => {
+ if (val && (frm.doc.subscription_id || frm.doc.customer_id)) {
+ frm.set_df_property('razorpay_details_section', 'hidden', false);
+ }
+ })
+ },
+
refresh: function(frm) {
frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Member'};
diff --git a/erpnext/non_profit/doctype/member/member.json b/erpnext/non_profit/doctype/member/member.json
index 9414974..bb73a84 100644
--- a/erpnext/non_profit/doctype/member/member.json
+++ b/erpnext/non_profit/doctype/member/member.json
@@ -1,604 +1,216 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 1,
- "autoname": "naming_series:",
- "beta": 0,
- "creation": "2017-09-11 09:24:52.898356",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "naming_series:",
+ "creation": "2017-09-11 09:24:52.898356",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "naming_series",
+ "member_name",
+ "membership_expiry_date",
+ "column_break_5",
+ "membership_type",
+ "email",
+ "email_id",
+ "image",
+ "customer_section",
+ "customer",
+ "customer_name",
+ "supplier_section",
+ "supplier",
+ "address_contacts",
+ "address_html",
+ "column_break_9",
+ "contact_html",
+ "razorpay_details_section",
+ "subscription_id",
+ "customer_id",
+ "subscription_activated",
+ "column_break_21",
+ "subscription_start",
+ "subscription_end"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "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": "Series",
- "length": 0,
- "no_copy": 0,
- "options": "NPO-MEM-.YYYY.-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "options": "NPO-MEM-.YYYY.-",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "member_name",
- "fieldtype": "Data",
- "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": "Member Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "member_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Member Name",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "membership_expiry_date",
- "fieldtype": "Date",
- "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": "Membership Expiry Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "membership_expiry_date",
+ "fieldtype": "Date",
+ "label": "Membership Expiry Date"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_5",
- "fieldtype": "Column Break",
- "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,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_5",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "membership_type",
- "fieldtype": "Link",
- "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": "Membership Type",
- "length": 0,
- "no_copy": 0,
- "options": "Membership Type",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "membership_type",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Membership Type",
+ "options": "Membership Type",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "email",
- "fieldtype": "Link",
- "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": "Email",
- "length": 0,
- "no_copy": 0,
- "options": "User",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "email",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "User",
+ "options": "User"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "image",
- "fieldtype": "Attach Image",
- "hidden": 1,
- "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",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "image",
+ "fieldtype": "Attach Image",
+ "hidden": 1,
+ "label": "Image",
+ "no_copy": 1,
+ "print_hide": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "customer_section",
- "fieldtype": "Section Break",
- "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": "Customer",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "collapsible": 1,
+ "fieldname": "customer_section",
+ "fieldtype": "Section Break",
+ "label": "Customer"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "customer",
- "fieldtype": "Link",
- "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": "Customer",
- "length": 0,
- "no_copy": 0,
- "options": "Customer",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "customer",
+ "fieldtype": "Link",
+ "label": "Customer",
+ "options": "Customer"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "customer.customer_name",
- "fieldname": "customer_name",
- "fieldtype": "Data",
- "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": "Customer Name",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fetch_from": "customer.customer_name",
+ "fieldname": "customer_name",
+ "fieldtype": "Data",
+ "label": "Customer Name",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "supplier_section",
- "fieldtype": "Section Break",
- "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": "Supplier",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "collapsible": 1,
+ "fieldname": "supplier_section",
+ "fieldtype": "Section Break",
+ "label": "Supplier"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "supplier",
- "fieldtype": "Link",
- "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": "Supplier",
- "length": 0,
- "no_copy": 0,
- "options": "Supplier",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "supplier",
+ "fieldtype": "Link",
+ "label": "Supplier",
+ "options": "Supplier"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "address_contacts",
- "fieldtype": "Section Break",
- "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": "Address and Contact",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-map-marker",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "address_contacts",
+ "fieldtype": "Section Break",
+ "label": "Address and Contact",
+ "options": "fa fa-map-marker"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "address_html",
- "fieldtype": "HTML",
- "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": "Address HTML",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "address_html",
+ "fieldtype": "HTML",
+ "label": "Address HTML"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_9",
- "fieldtype": "Column Break",
- "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,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_9",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "contact_html",
- "fieldtype": "HTML",
- "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": "Contact HTML",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "contact_html",
+ "fieldtype": "HTML",
+ "label": "Contact HTML"
+ },
+ {
+ "fieldname": "email_id",
+ "fieldtype": "Data",
+ "label": "Email Address"
+ },
+ {
+ "fieldname": "subscription_id",
+ "fieldtype": "Data",
+ "label": "Subscription ID",
+ "read_only": 1
+ },
+ {
+ "fieldname": "customer_id",
+ "fieldtype": "Data",
+ "label": "Customer ID",
+ "read_only": 1
+ },
+ {
+ "fieldname": "razorpay_details_section",
+ "fieldtype": "Section Break",
+ "hidden": 1,
+ "label": "Razorpay Details"
+ },
+ {
+ "fieldname": "column_break_21",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "fieldname": "subscription_activated",
+ "fieldtype": "Check",
+ "label": "Subscription Activated"
+ },
+ {
+ "fieldname": "subscription_start",
+ "fieldtype": "Date",
+ "label": "Subscription Start "
+ },
+ {
+ "fieldname": "subscription_end",
+ "fieldtype": "Date",
+ "label": "Subscription End"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_field": "image",
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-21 14:44:23.218109",
- "modified_by": "Administrator",
- "module": "Non Profit",
- "name": "Member",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "image_field": "image",
+ "links": [],
+ "modified": "2020-04-07 14:20:33.215700",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Member",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Non Profit Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Non Profit Manager",
+ "share": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Non Profit Member",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Non Profit Member",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Non Profit",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "member_name",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "quick_entry": 1,
+ "restrict_to_domain": "Non Profit",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "member_name",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/member/member.py b/erpnext/non_profit/doctype/member/member.py
index 9afaf90..571f87a 100644
--- a/erpnext/non_profit/doctype/member/member.py
+++ b/erpnext/non_profit/doctype/member/member.py
@@ -3,9 +3,12 @@
# For license information, please see license.txt
from __future__ import unicode_literals
+import frappe
+from frappe import _
from frappe.model.document import Document
from frappe.contacts.address_and_contact import load_address_and_contact
-
+from frappe.utils import cint
+from frappe.integrations.utils import get_payment_gateway_controller
class Member(Document):
def onload(self):
@@ -14,8 +17,114 @@
def validate(self):
- self.validate_email_type(self.email)
+ if self.email:
+ self.validate_email_type(self.email)
+ if self.email_id:
+ self.validate_email_type(self.email_id)
def validate_email_type(self, email):
from frappe.utils import validate_email_address
- validate_email_address(email.strip(), True)
\ No newline at end of file
+ validate_email_address(email.strip(), True)
+
+ def setup_subscription(self):
+ membership_settings = frappe.get_doc("Membership Settings")
+ if not membership_settings.enable_razorpay:
+ frappe.throw("Please enable Razorpay to setup subscription")
+
+ controller = get_payment_gateway_controller("Razorpay")
+ settings = controller.get_settings({})
+
+ plan_id = frappe.get_value("Membership Type", self.membership_type, "razorpay_plan_id")
+
+ if not plan_id:
+ frappe.throw(_("Please setup Razorpay Plan ID"))
+
+ subscription_details = {
+ "plan_id": plan_id,
+ "billing_frequency": cint(membership_settings.billing_frequency),
+ "customer_notify": 1
+ }
+
+ args = {
+ 'subscription_details': subscription_details
+ }
+
+ subscription = controller.setup_subscription(settings, **args)
+
+ return subscription
+
+def get_or_create_member(user_details):
+ member_list = frappe.get_all("Member", filters={'email': user_details.email, 'membership_type': user_details.plan_id})
+ if member_list and member_list[0]:
+ return member_list[0]['name']
+ else:
+ return create_member(user_details)
+
+def create_member(user_details):
+ member = frappe.new_doc("Member")
+ member.update({
+ "member_name": user_details.fullname,
+ "email_id": user_details.email,
+ "pan_number": user_details.pan,
+ "membership_type": user_details.plan_id,
+ "customer": create_customer(user_details)
+ })
+
+ member.insert(ignore_permissions=True)
+ return member
+
+def create_customer(user_details):
+ customer = frappe.new_doc("Customer")
+ customer.customer_name = user_details.fullname
+ customer.customer_type = "Individual"
+ customer.insert(ignore_permissions=True)
+
+ try:
+ contact = frappe.new_doc("Contact")
+ contact.first_name = user_details.fullname
+ contact.add_phone(user_details.mobile, is_primary_phone=1, is_primary_mobile_no=1)
+ contact.add_email(user_details.email, is_primary=1)
+ contact.insert(ignore_permissions=True)
+
+ contact.append("links", {
+ "link_doctype": "Customer",
+ "link_name": customer.name
+ })
+
+ contact.insert()
+ except Exception as e:
+ frappe.log_error(frappe.get_traceback(), _("Contact Creation Failed"))
+ pass
+
+ return customer.name
+
+@frappe.whitelist(allow_guest=True)
+def create_member_subscription_order(user_details):
+ """Create Member subscription and order for payment
+
+ Args:
+ user_details (TYPE): Description
+
+ Returns:
+ Dictionary: Dictionary with subscription details
+ {
+ 'subscription_details': {
+ 'plan_id': 'plan_EXwyxDYDCj3X4v',
+ 'billing_frequency': 24,
+ 'customer_notify': 1
+ },
+ 'subscription_id': 'sub_EZycCvXFvqnC6p'
+ }
+ """
+ # {"plan_id":"IFF Starter","fullname":"Shivam Mishra","mobile":"7506056962","email":"shivam@shivam.dev","pan":"Testing123"}
+ user_details = frappe._dict(user_details)
+ member = get_or_create_member(user_details)
+ if not member:
+ member = create_member(user_details)
+
+ subscription = member.setup_subscription()
+
+ member.subscription_id = subscription.get('subscription_id')
+ member.save(ignore_permissions=True)
+
+ return subscription
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership/membership.js b/erpnext/non_profit/doctype/membership/membership.js
index 4210879..554549a 100644
--- a/erpnext/non_profit/doctype/membership/membership.js
+++ b/erpnext/non_profit/doctype/membership/membership.js
@@ -2,7 +2,13 @@
// For license information, please see license.txt
frappe.ui.form.on('Membership', {
- onload:function(frm) {
+ setup: function(frm) {
+ frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => {
+ if (val) frm.set_df_property('razorpay_details_section', 'hidden', false);
+ })
+ },
+
+ onload: function(frm) {
frm.add_fetch('membership_type', 'amount', 'amount');
}
});
diff --git a/erpnext/non_profit/doctype/membership/membership.json b/erpnext/non_profit/doctype/membership/membership.json
index 9a204b1..9f10d0c 100644
--- a/erpnext/non_profit/doctype/membership/membership.json
+++ b/erpnext/non_profit/doctype/membership/membership.json
@@ -1,501 +1,164 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "NPO-MSH-.YYYY.-.#####",
- "beta": 0,
- "creation": "2017-09-11 11:39:18.492184",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "autoname": "NPO-MSH-.YYYY.-.#####",
+ "creation": "2017-09-11 11:39:18.492184",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "member",
+ "membership_type",
+ "column_break_3",
+ "membership_status",
+ "membership_validity_section",
+ "from_date",
+ "to_date",
+ "column_break_8",
+ "member_since_date",
+ "payment_details",
+ "paid",
+ "currency",
+ "amount",
+ "razorpay_details_section",
+ "subscription_id",
+ "payment_id",
+ "webhook_payload"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "member",
- "fieldtype": "Link",
- "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": "Member",
- "length": 0,
- "no_copy": 0,
- "options": "Member",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "member",
+ "fieldtype": "Link",
+ "label": "Member",
+ "options": "Member"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "membership_type",
- "fieldtype": "Link",
- "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": "Membership Type",
- "length": 0,
- "no_copy": 0,
- "options": "Membership Type",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "membership_type",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Membership Type",
+ "options": "Membership Type",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_3",
- "fieldtype": "Column Break",
- "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,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "membership_status",
- "fieldtype": "Select",
- "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": "Membership Status",
- "length": 0,
- "no_copy": 0,
- "options": "New\nCurrent\nExpired\nPending\nCancelled",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "membership_status",
+ "fieldtype": "Select",
+ "label": "Membership Status",
+ "options": "New\nCurrent\nExpired\nPending\nCancelled"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "membership_validity_section",
- "fieldtype": "Section Break",
- "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": "Validity",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "membership_validity_section",
+ "fieldtype": "Section Break",
+ "label": "Validity"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "from_date",
- "fieldtype": "Date",
- "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": "From",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "from_date",
+ "fieldtype": "Date",
+ "in_list_view": 1,
+ "label": "From",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "to_date",
- "fieldtype": "Date",
- "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": "To",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "to_date",
+ "fieldtype": "Date",
+ "in_list_view": 1,
+ "label": "To",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_8",
- "fieldtype": "Column Break",
- "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,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_8",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "member_since_date",
- "fieldtype": "Date",
- "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": "Member Since",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "member_since_date",
+ "fieldtype": "Date",
+ "label": "Member Since"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "payment_details",
- "fieldtype": "Section Break",
- "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": "Payment Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "payment_details",
+ "fieldtype": "Section Break",
+ "label": "Payment Details"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "paid",
- "fieldtype": "Check",
- "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": "Paid",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "0",
+ "fieldname": "paid",
+ "fieldtype": "Check",
+ "label": "Paid"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "currency",
- "fieldtype": "Select",
- "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": "Currency",
- "length": 0,
- "no_copy": 0,
- "options": "USD\nINR",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "currency",
+ "fieldtype": "Select",
+ "label": "Currency",
+ "options": "USD\nINR"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "amount",
- "fieldtype": "Float",
- "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": "Amount",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "amount",
+ "fieldtype": "Float",
+ "label": "Amount"
+ },
+ {
+ "fieldname": "razorpay_details_section",
+ "fieldtype": "Section Break",
+ "hidden": 1,
+ "label": "Razorpay Details"
+ },
+ {
+ "fieldname": "subscription_id",
+ "fieldtype": "Data",
+ "label": "Subscription ID",
+ "read_only": 1
+ },
+ {
+ "fieldname": "payment_id",
+ "fieldtype": "Data",
+ "label": "Payment ID",
+ "read_only": 1
+ },
+ {
+ "fieldname": "webhook_payload",
+ "fieldtype": "Code",
+ "label": "Webhook Payload",
+ "options": "JSON",
+ "read_only": 1
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-21 16:15:42.323446",
- "modified_by": "Administrator",
- "module": "Non Profit",
- "name": "Membership",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "links": [],
+ "modified": "2020-04-06 14:29:33.856060",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Membership",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Non Profit Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Non Profit Manager",
+ "share": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Non Profit Member",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Non Profit Member",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Non Profit",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "restrict_to_domain": "Non Profit",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py
index 98bee56..a523a23 100644
--- a/erpnext/non_profit/doctype/membership/membership.py
+++ b/erpnext/non_profit/doctype/membership/membership.py
@@ -3,9 +3,13 @@
# For license information, please see license.txt
from __future__ import unicode_literals
+import json
import frappe
+import six
+from datetime import datetime
from frappe.model.document import Document
-from frappe.utils import add_days, add_years, nowdate, getdate
+from frappe.email import sendmail_to_system_managers
+from frappe.utils import add_days, add_years, nowdate, getdate, add_months, get_link_to_form
from frappe import _
import erpnext
@@ -43,11 +47,80 @@
else:
self.from_date = nowdate()
- self.to_date = add_years(self.from_date, 1)
+ if frappe.db.get_single_value("Membership Settings", "billing_cycle") == "Yearly":
+ self.to_date = add_years(self.from_date, 1)
+ else:
+ self.to_date = add_months(self.from_date, 1)
def on_payment_authorized(self, status_changed_to=None):
if status_changed_to in ("Completed", "Authorized"):
self.load_from_db()
self.db_set('paid', 1)
+def get_member_based_on_subscription(subscription_id, email):
+ members = frappe.get_all("Member", filters={
+ 'subscription_id': subscription_id,
+ 'email_id': email
+ }, order_by="creation desc")
+ return frappe.get_doc("Member", members[0]['name'])
+
+
+@frappe.whitelist()
+def trigger_razorpay_subscription(data):
+ if isinstance(data, six.string_types):
+ data = json.loads(data)
+ data = frappe._dict(data)
+
+ subscription = data.payload.get("subscription", {}).get('entity', {})
+ subscription = frappe._dict(subscription)
+
+ payment = data.payload.get("payment", {}).get('entity', {})
+ payment = frappe._dict(payment)
+
+ try:
+ data_json = json.dumps(data, indent=4, sort_keys=True)
+ member = get_member_based_on_subscription(subscription.id, payment.email)
+ except Exception as e:
+ error_log = frappe.log_error(frappe.get_traceback() + '\n' + data_json , _("Membership Webhook Failed"))
+ notify_failure(error_log)
+ raise e
+
+ if data.event == "subscription.activated":
+ member.customer_id = payment.customer_id
+ member.subscription_start = datetime.fromtimestamp(subscription.start_at)
+ member.subscription_end = datetime.fromtimestamp(subscription.end_at)
+ member.subscription_activated = 1
+ member.save(ignore_permissions=True)
+ elif data.event == "subscription.charged":
+ membership = frappe.new_doc("Membership")
+ membership.update({
+ "member": member.name,
+ "membership_status": "Current",
+ "membership_type": member.membership_type,
+ "currency": "INR",
+ "paid": 1,
+ "payment_id": payment.id,
+ "webhook_payload": data_json,
+ "from_date": datetime.fromtimestamp(subscription.current_start),
+ "to_date": datetime.fromtimestamp(subscription.current_end),
+ "amount": payment.amount / 100 # Convert to rupees from paise
+ })
+ membership.insert(ignore_permissions=True)
+
+ return True
+
+
+
+def notify_failure(log):
+ try:
+ content = """Dear System Manager,
+Razorpay webhook for creating renewing membership subscription failed due to some reason. Please check the following error log linked below
+
+Error Log: {0}
+
+Regards,
+Administrator""".format(get_link_to_form("Error Log", log.name))
+ sendmail_to_system_managers("[Important] [ERPNext] Razorpay membership webhook failed , please check.", content)
+ except:
+ pass
diff --git a/erpnext/non_profit/doctype/membership_settings/__init__.py b/erpnext/non_profit/doctype/membership_settings/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_settings/__init__.py
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.js b/erpnext/non_profit/doctype/membership_settings/membership_settings.js
new file mode 100644
index 0000000..c01a0b2
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Membership Settings', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.json b/erpnext/non_profit/doctype/membership_settings/membership_settings.json
new file mode 100644
index 0000000..56b8eac
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.json
@@ -0,0 +1,62 @@
+{
+ "actions": [],
+ "creation": "2020-03-29 12:57:03.005120",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "enable_razorpay",
+ "razorpay_settings_section",
+ "billing_cycle",
+ "billing_frequency"
+ ],
+ "fields": [
+ {
+ "fieldname": "billing_cycle",
+ "fieldtype": "Select",
+ "label": "Billing Cycle",
+ "options": "Monthly\nYearly"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_razorpay",
+ "fieldtype": "Check",
+ "label": "Enable RazorPay For Memberships"
+ },
+ {
+ "depends_on": "eval:doc.enable_razorpay",
+ "fieldname": "razorpay_settings_section",
+ "fieldtype": "Section Break",
+ "label": "RazorPay Settings"
+ },
+ {
+ "description": "The number of billing cycles for which the customer should be charged. For example, if a customer is buying a 1-year membership that should be billed on a monthly basis, this value should be 12.",
+ "fieldname": "billing_frequency",
+ "fieldtype": "Int",
+ "label": "Billing Frequency"
+ }
+ ],
+ "issingle": 1,
+ "links": [],
+ "modified": "2020-04-07 18:42:51.496807",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Membership Settings",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "System Manager",
+ "share": 1,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.py b/erpnext/non_profit/doctype/membership_settings/membership_settings.py
new file mode 100644
index 0000000..2b8e37f
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.integrations.utils import get_payment_gateway_controller
+from frappe.model.document import Document
+
+class MembershipSettings(Document):
+ pass
+
+@frappe.whitelist()
+def get_plans_for_membership(*args, **kwargs):
+ controller = get_payment_gateway_controller("Razorpay")
+ plans = controller.get_plans()
+ return [plan.get("item") for plan in plans.get("items")]
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership_settings/test_membership_settings.py b/erpnext/non_profit/doctype/membership_settings/test_membership_settings.py
new file mode 100644
index 0000000..2ad7984
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_settings/test_membership_settings.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestMembershipSettings(unittest.TestCase):
+ pass
diff --git a/erpnext/non_profit/doctype/membership_type/membership_type.js b/erpnext/non_profit/doctype/membership_type/membership_type.js
index 3ef39ae..226981d 100644
--- a/erpnext/non_profit/doctype/membership_type/membership_type.js
+++ b/erpnext/non_profit/doctype/membership_type/membership_type.js
@@ -2,7 +2,9 @@
// For license information, please see license.txt
frappe.ui.form.on('Membership Type', {
- refresh: function() {
-
+ refresh: function(frm) {
+ frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => {
+ if (val) frm.set_df_property('razorpay_plan_id', 'hidden', false);
+ })
}
});
diff --git a/erpnext/non_profit/doctype/membership_type/membership_type.json b/erpnext/non_profit/doctype/membership_type/membership_type.json
index 35a7902..319078f 100644
--- a/erpnext/non_profit/doctype/membership_type/membership_type.json
+++ b/erpnext/non_profit/doctype/membership_type/membership_type.json
@@ -1,124 +1,63 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "field:membership_type",
- "beta": 0,
- "creation": "2017-09-18 12:56:56.343999",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "autoname": "field:membership_type",
+ "creation": "2017-09-18 12:56:56.343999",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "membership_type",
+ "amount",
+ "razorpay_plan_id"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "membership_type",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Membership Type",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "membership_type",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Membership Type",
+ "reqd": 1,
+ "unique": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "amount",
- "fieldtype": "Float",
- "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": "Amount",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
+ "fieldname": "amount",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "Amount",
+ "reqd": 1
+ },
+ {
+ "fieldname": "razorpay_plan_id",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Razorpay Plan ID",
+ "unique": 1
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2017-12-05 07:03:45.860757",
- "modified_by": "Administrator",
- "module": "Non Profit",
- "name": "Membership Type",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "links": [],
+ "modified": "2020-03-30 12:54:07.850857",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Membership Type",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Non Profit Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Non Profit Manager",
+ "share": 1,
"write": 1
}
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Non Profit",
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0
+ ],
+ "quick_entry": 1,
+ "restrict_to_domain": "Non Profit",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/set_permission_einvoicing.py b/erpnext/patches/v12_0/set_permission_einvoicing.py
index 1095c8c..e223510 100644
--- a/erpnext/patches/v12_0/set_permission_einvoicing.py
+++ b/erpnext/patches/v12_0/set_permission_einvoicing.py
@@ -10,6 +10,8 @@
make_custom_fields()
+ frappe.reload_doc("regional", "doctype", "import_supplier_invoice")
+
add_permission('Import Supplier Invoice', 'Accounts Manager', 0)
update_permission_property('Import Supplier Invoice', 'Accounts Manager', 0, 'write', 1)
- update_permission_property('Import Supplier Invoice', 'Accounts Manager', 0, 'create', 1)
\ No newline at end of file
+ update_permission_property('Import Supplier Invoice', 'Accounts Manager', 0, 'create', 1)
diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json
index 49abab1..f3cecd9 100644
--- a/erpnext/projects/doctype/project/project.json
+++ b/erpnext/projects/doctype/project/project.json
@@ -83,7 +83,6 @@
"oldfieldname": "status",
"oldfieldtype": "Select",
"options": "Open\nCompleted\nCancelled",
- "reqd": 1,
"search_index": 1
},
{
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index afbdbc6..d5dc412 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -444,75 +444,69 @@
"fieldname": "quantity",
"reqd": 1,
"default": 1
- },
- {
- "fieldtype": "Button",
- "label": __("Get Items"),
- "fieldname": "get_items",
- "cssClass": "btn-primary"
}
- ]
- });
-
- dialog.fields_dict.get_items.$input.click(function() {
- var args = dialog.get_values();
- if(!args) return;
- dialog.hide();
- return frappe.call({
- type: "GET",
- method: "erpnext.stock.doctype.packed_item.packed_item.get_items_from_product_bundle",
- args: {
+ ],
+ primary_action_label: 'Get Items',
+ primary_action(args){
+ if(!args) return;
+ dialog.hide();
+ return frappe.call({
+ type: "GET",
+ method: "erpnext.stock.doctype.packed_item.packed_item.get_items_from_product_bundle",
args: {
- item_code: args.product_bundle,
- quantity: args.quantity,
- parenttype: frm.doc.doctype,
- parent: frm.doc.name,
- supplier: frm.doc.supplier,
- currency: frm.doc.currency,
- conversion_rate: frm.doc.conversion_rate,
- price_list: frm.doc.buying_price_list,
- price_list_currency: frm.doc.price_list_currency,
- plc_conversion_rate: frm.doc.plc_conversion_rate,
- company: frm.doc.company,
- is_subcontracted: frm.doc.is_subcontracted,
- transaction_date: frm.doc.transaction_date || frm.doc.posting_date,
- ignore_pricing_rule: frm.doc.ignore_pricing_rule,
- doctype: frm.doc.doctype
- }
- },
- freeze: true,
- callback: function(r) {
- const first_row_is_empty = function(child_table){
- if($.isArray(child_table) && child_table.length > 0) {
- return !child_table[0].item_code;
+ args: {
+ item_code: args.product_bundle,
+ quantity: args.quantity,
+ parenttype: frm.doc.doctype,
+ parent: frm.doc.name,
+ supplier: frm.doc.supplier,
+ currency: frm.doc.currency,
+ conversion_rate: frm.doc.conversion_rate,
+ price_list: frm.doc.buying_price_list,
+ price_list_currency: frm.doc.price_list_currency,
+ plc_conversion_rate: frm.doc.plc_conversion_rate,
+ company: frm.doc.company,
+ is_subcontracted: frm.doc.is_subcontracted,
+ transaction_date: frm.doc.transaction_date || frm.doc.posting_date,
+ ignore_pricing_rule: frm.doc.ignore_pricing_rule,
+ doctype: frm.doc.doctype
}
- return false;
- };
+ },
+ freeze: true,
+ callback: function(r) {
+ const first_row_is_empty = function(child_table){
+ if($.isArray(child_table) && child_table.length > 0) {
+ return !child_table[0].item_code;
+ }
+ return false;
+ };
- const remove_empty_first_row = function(frm){
- if (first_row_is_empty(frm.doc.items)){
- frm.doc.items = frm.doc.items.splice(1);
- }
- };
+ const remove_empty_first_row = function(frm){
+ if (first_row_is_empty(frm.doc.items)){
+ frm.doc.items = frm.doc.items.splice(1);
+ }
+ };
- if(!r.exc && r.message) {
- remove_empty_first_row(frm);
- for ( var i=0; i< r.message.length; i++ ) {
- var d = frm.add_child("items");
- var item = r.message[i];
- for ( var key in item) {
- if ( !is_null(item[key]) ) {
- d[key] = item[key];
+ if(!r.exc && r.message) {
+ remove_empty_first_row(frm);
+ for ( var i=0; i< r.message.length; i++ ) {
+ var d = frm.add_child("items");
+ var item = r.message[i];
+ for ( var key in item) {
+ if ( !is_null(item[key]) ) {
+ d[key] = item[key];
+ }
+ }
+ if(frappe.meta.get_docfield(d.doctype, "price_list_rate", d.name)) {
+ frm.script_manager.trigger("price_list_rate", d.doctype, d.name);
}
}
- if(frappe.meta.get_docfield(d.doctype, "price_list_rate", d.name)) {
- frm.script_manager.trigger("price_list_rate", d.doctype, d.name);
- }
+ frm.refresh_field("items");
}
- frm.refresh_field("items");
}
- }
- })
+ })
+ }
});
+
dialog.show();
}
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index f126f6a..3443abc 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -499,7 +499,6 @@
conversion_factor: item.conversion_factor,
weight_per_unit: item.weight_per_unit,
weight_uom: item.weight_uom,
- uom : item.uom,
manufacturer: item.manufacturer,
stock_uom: item.stock_uom,
pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '',
@@ -1434,6 +1433,8 @@
for (let key in free_item_data) {
row_to_modify[key] = free_item_data[key];
}
+ } if (items && items.length && free_item_data) {
+ items[0].qty = free_item_data.qty
}
},
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 28b1f8f..4be6804 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -85,7 +85,7 @@
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
fieldtype='Data', fetch_from='item_code.gst_hsn_code', insert_after='description',
allow_on_submit=1, print_hide=1, fetch_if_empty=1)
- nil_rated_exempt = dict(fieldname='is_nil_exempt', label='Is nil rated or exempted',
+ nil_rated_exempt = dict(fieldname='is_nil_exempt', label='Is Nil Rated or Exempted',
fieldtype='Check', fetch_from='item_code.is_nil_exempt', insert_after='gst_hsn_code',
print_hide=1)
is_non_gst = dict(fieldname='is_non_gst', label='Is Non GST',
@@ -388,7 +388,7 @@
'Item': [
dict(fieldname='gst_hsn_code', label='HSN/SAC',
fieldtype='Link', options='GST HSN Code', insert_after='item_group'),
- dict(fieldname='is_nil_exempt', label='Is nil rated or exempted',
+ dict(fieldname='is_nil_exempt', label='Is Nil Rated or Exempted',
fieldtype='Check', insert_after='gst_hsn_code'),
dict(fieldname='is_non_gst', label='Is Non GST ',
fieldtype='Check', insert_after='is_nil_exempt')
@@ -497,6 +497,14 @@
'depends_on':'eval:in_list(["SEZ", "Overseas", "Deemed Export"], doc.gst_category)',
'options': '\nWith Payment of Tax\nWithout Payment of Tax'
}
+ ],
+ "Member": [
+ {
+ 'fieldname': 'pan_number',
+ 'label': 'PAN Details',
+ 'fieldtype': 'Data',
+ 'insert_after': 'email'
+ }
]
}
create_custom_fields(custom_fields, update=update)
@@ -718,4 +726,4 @@
doctype="Tax Withholding Category", accounts=accounts,
rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
"single_threshold": 2500, "cumulative_threshold": 0}])
- ]
+ ]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index 6110ea8..b97da69 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -12,7 +12,8 @@
'Purchase Order': 'Purchase Order',
'Request for Quotation': 'Request for Quotation',
'Supplier Quotation': 'Supplier Quotation',
- 'Work Order': 'Work Order'
+ 'Work Order': 'Work Order',
+ 'Purchase Receipt': 'Purchase Receipt'
};
// formatter for material request item
@@ -27,11 +28,20 @@
// set schedule_date
set_schedule_date(frm);
- frm.fields_dict["items"].grid.get_field("warehouse").get_query = function(doc) {
+
+ let filters = {'company': frm.doc.company}
+
+ frm.set_query("warehouse", "items", function() {
return {
- filters: {'company': doc.company}
+ filters: filters
};
- };
+ });
+
+ frm.set_query("set_warehouse", function(){
+ return {
+ filters: filters
+ };
+ });
},
onload_post_render: function(frm) {
@@ -129,12 +139,13 @@
source_doctype: "Sales Order",
target: frm,
setters: {
- company: frm.doc.company
+ customer: frm.doc.customer || undefined
},
get_query_filters: {
docstatus: 1,
status: ["not in", ["Closed", "On Hold"]],
per_delivered: ["<", 99.99],
+ company: frm.doc.company
}
});
},
@@ -182,46 +193,46 @@
options:"BOM", reqd: 1, get_query: function() {
return {filters: { docstatus:1 }};
}},
- {"fieldname":"warehouse", "fieldtype":"Link", "label":__("Warehouse"),
+ {"fieldname":"warehouse", "fieldtype":"Link", "label":__("For Warehouse"),
options:"Warehouse", reqd: 1},
{"fieldname":"qty", "fieldtype":"Float", "label":__("Quantity"),
reqd: 1, "default": 1},
{"fieldname":"fetch_exploded", "fieldtype":"Check",
- "label":__("Fetch exploded BOM (including sub-assemblies)"), "default":1},
- {fieldname:"fetch", "label":__("Get Items from BOM"), "fieldtype":"Button"}
- ]
- });
- d.get_input("fetch").on("click", function() {
- var values = d.get_values();
- if(!values) return;
- values["company"] = frm.doc.company;
- if(!frm.doc.company) frappe.throw(__("Company field is required"));
- frappe.call({
- method: "erpnext.manufacturing.doctype.bom.bom.get_bom_items",
- args: values,
- callback: function(r) {
- if (!r.message) {
- frappe.throw(__("BOM does not contain any stock item"));
- } else {
- erpnext.utils.remove_empty_first_row(frm, "items");
- $.each(r.message, function(i, item) {
- var d = frappe.model.add_child(cur_frm.doc, "Material Request Item", "items");
- d.item_code = item.item_code;
- d.item_name = item.item_name;
- d.description = item.description;
- d.warehouse = values.warehouse;
- d.uom = item.stock_uom;
- d.stock_uom = item.stock_uom;
- d.conversion_factor = 1;
- d.qty = item.qty;
- d.project = item.project;
- });
+ "label":__("Fetch exploded BOM (including sub-assemblies)"), "default":1}
+ ],
+ primary_action_label: 'Get Items',
+ primary_action(values) {
+ if(!values) return;
+ values["company"] = frm.doc.company;
+ if(!frm.doc.company) frappe.throw(__("Company field is required"));
+ frappe.call({
+ method: "erpnext.manufacturing.doctype.bom.bom.get_bom_items",
+ args: values,
+ callback: function(r) {
+ if (!r.message) {
+ frappe.throw(__("BOM does not contain any stock item"));
+ } else {
+ erpnext.utils.remove_empty_first_row(frm, "items");
+ $.each(r.message, function(i, item) {
+ var d = frappe.model.add_child(cur_frm.doc, "Material Request Item", "items");
+ d.item_code = item.item_code;
+ d.item_name = item.item_name;
+ d.description = item.description;
+ d.warehouse = values.warehouse;
+ d.uom = item.stock_uom;
+ d.stock_uom = item.stock_uom;
+ d.conversion_factor = 1;
+ d.qty = item.qty;
+ d.project = item.project;
+ });
+ }
+ d.hide();
+ refresh_field("items");
}
- d.hide();
- refresh_field("items");
- }
- });
+ });
+ }
});
+
d.show();
},
@@ -248,7 +259,8 @@
run_link_triggers: true
});
},
- __('Enter Supplier')
+ __('Enter Supplier'),
+ __('Create')
)
},
diff --git a/erpnext/stock/doctype/material_request/material_request.json b/erpnext/stock/doctype/material_request/material_request.json
index d0025d1..536f5fa 100644
--- a/erpnext/stock/doctype/material_request/material_request.json
+++ b/erpnext/stock/doctype/material_request/material_request.json
@@ -1,9 +1,11 @@
{
+ "actions": [],
"allow_import": 1,
"autoname": "naming_series:",
"creation": "2013-03-07 14:48:38",
"doctype": "DocType",
"document_type": "Document",
+ "engine": "InnoDB",
"field_order": [
"type_section",
"naming_series",
@@ -14,6 +16,8 @@
"schedule_date",
"company",
"amended_from",
+ "warehouse_section",
+ "set_warehouse",
"items_section",
"scan_barcode",
"items",
@@ -66,7 +70,7 @@
"fieldtype": "Select",
"in_list_view": 1,
"in_standard_filter": 1,
- "label": "Type",
+ "label": "Purpose",
"options": "Purchase\nMaterial Transfer\nMaterial Issue\nManufacture\nCustomer Provided",
"reqd": 1
},
@@ -85,7 +89,7 @@
"allow_on_submit": 1,
"fieldname": "schedule_date",
"fieldtype": "Date",
- "label": "Required Date"
+ "label": "Required By"
},
{
"fieldname": "company",
@@ -190,6 +194,7 @@
"width": "100px"
},
{
+ "depends_on": "eval:doc.docstatus==1",
"fieldname": "per_ordered",
"fieldtype": "Percent",
"label": "% Ordered",
@@ -200,6 +205,7 @@
"read_only": 1
},
{
+ "depends_on": "eval:doc.docstatus==1",
"fieldname": "per_received",
"fieldtype": "Percent",
"label": "% Received",
@@ -270,12 +276,24 @@
"options": "Job Card",
"print_hide": 1,
"read_only": 1
+ },
+ {
+ "fieldname": "warehouse_section",
+ "fieldtype": "Section Break"
+ },
+ {
+ "description": "Sets 'For Warehouse' in each row of the Items table.",
+ "fieldname": "set_warehouse",
+ "fieldtype": "Link",
+ "label": "Set Warehouse",
+ "options": "Warehouse"
}
],
"icon": "fa fa-ticket",
"idx": 70,
"is_submittable": 1,
- "modified": "2019-04-29 11:45:07.570292",
+ "links": [],
+ "modified": "2020-03-02 20:21:09.990867",
"modified_by": "Administrator",
"module": "Stock",
"name": "Material Request",
diff --git a/erpnext/stock/doctype/material_request/material_request_dashboard.py b/erpnext/stock/doctype/material_request/material_request_dashboard.py
index cbd6478..0e4fb7a 100644
--- a/erpnext/stock/doctype/material_request/material_request_dashboard.py
+++ b/erpnext/stock/doctype/material_request/material_request_dashboard.py
@@ -8,7 +8,12 @@
'transactions': [
{
'label': _('Related'),
- 'items': ['Request for Quotation', 'Supplier Quotation', 'Purchase Order', 'Stock Entry', 'Pick List']
+ 'items': ['Request for Quotation', 'Supplier Quotation', 'Purchase Order']
+ },
+ {
+ 'label': _('Stock'),
+ 'items': ['Stock Entry', 'Purchase Receipt', 'Pick List']
+
},
{
'label': _('Manufacturing'),
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index 5604913..2bdc268 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -7,36 +7,38 @@
"engine": "InnoDB",
"field_order": [
"item_code",
- "col_break1",
"item_name",
+ "col_break1",
+ "schedule_date",
"section_break_4",
"description",
"item_group",
"brand",
"image_section",
"image",
- "manufacture_details",
- "manufacturer",
"column_break_12",
"manufacturer_part_no",
"quantity_and_warehouse",
"qty",
- "uom",
- "conversion_factor",
"stock_uom",
"warehouse",
"col_break2",
- "schedule_date",
- "rate",
- "amount",
+ "uom",
+ "conversion_factor",
"stock_qty",
+ "rate_and_amount_section_break",
+ "rate",
+ "col_break3",
+ "amount",
+ "manufacture_details",
+ "manufacturer",
"more_info",
"lead_time_date",
"sales_order",
"sales_order_item",
"production_plan",
"material_request_plan_item",
- "col_break3",
+ "col_break4",
"min_order_qty",
"projected_qty",
"actual_qty",
@@ -175,7 +177,7 @@
"fieldname": "schedule_date",
"fieldtype": "Date",
"in_list_view": 1,
- "label": "Required Date",
+ "label": "Required By",
"oldfieldname": "schedule_date",
"oldfieldtype": "Date",
"print_width": "100px",
@@ -185,14 +187,12 @@
{
"fieldname": "rate",
"fieldtype": "Currency",
- "label": "Rate",
- "no_copy": 1
+ "label": "Rate"
},
{
"fieldname": "amount",
"fieldtype": "Currency",
"label": "Amount",
- "no_copy": 1,
"read_only": 1
},
{
@@ -204,6 +204,7 @@
"read_only": 1
},
{
+ "collapsible": 1,
"fieldname": "more_info",
"fieldtype": "Section Break",
"label": "More Information"
@@ -331,6 +332,7 @@
"read_only": 1
},
{
+ "collapsible": 1,
"fieldname": "accounting_details",
"fieldtype": "Section Break",
"label": "Accounting Details"
@@ -389,6 +391,7 @@
"fieldtype": "Column Break"
},
{
+ "collapsible": 1,
"fieldname": "manufacture_details",
"fieldtype": "Section Break",
"label": "Manufacture"
@@ -406,7 +409,16 @@
{
"fieldname": "manufacturer_part_no",
"fieldtype": "Data",
- "label": "Manufacturer Part Number"
+ "label": "Manufacturer Part Number",
+ "read_only": 1
+ },
+ {
+ "fieldname": "rate_and_amount_section_break",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "col_break4",
+ "fieldtype": "Column Break"
}
],
"idx": 1,
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index eed5749..467a206 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -16,10 +16,10 @@
"supplier_name",
"supplier_delivery_note",
"column_break1",
+ "company",
"posting_date",
"posting_time",
"set_posting_time",
- "company",
"is_return",
"return_against",
"section_addresses",
@@ -49,11 +49,6 @@
"items_section",
"scan_barcode",
"items",
- "pricing_rule_details",
- "pricing_rules",
- "get_current_stock",
- "raw_material_details",
- "supplied_items",
"section_break0",
"total_qty",
"base_total",
@@ -62,6 +57,11 @@
"total_net_weight",
"total",
"net_total",
+ "pricing_rule_details",
+ "pricing_rules",
+ "raw_material_details",
+ "get_current_stock",
+ "supplied_items",
"taxes_charges_section",
"tax_category",
"shipping_col",
@@ -113,13 +113,13 @@
"auto_repeat",
"printing_settings",
"letter_head",
- "select_print_heading",
"language",
- "group_same_items",
- "column_break_97",
- "other_details",
"instructions",
+ "column_break_97",
+ "select_print_heading",
+ "other_details",
"remarks",
+ "group_same_items",
"transporter_info",
"transporter_name",
"column_break5",
@@ -404,6 +404,7 @@
"fieldtype": "Section Break"
},
{
+ "description": "Sets 'Accepted Warehouse' in each row of the items table.",
"fieldname": "set_warehouse",
"fieldtype": "Link",
"label": "Accepted Warehouse",
@@ -411,7 +412,7 @@
"print_hide": 1
},
{
- "description": "Warehouse where you are maintaining stock of rejected items",
+ "description": "Sets 'Rejected Warehouse' in each row of the items table.",
"fieldname": "rejected_warehouse",
"fieldtype": "Link",
"label": "Rejected Warehouse",
@@ -429,7 +430,7 @@
"default": "No",
"fieldname": "is_subcontracted",
"fieldtype": "Select",
- "label": "Raw Materials Supplied",
+ "label": "Raw Materials Consumed",
"oldfieldname": "is_subcontracted",
"oldfieldtype": "Select",
"options": "No\nYes",
@@ -465,6 +466,7 @@
"reqd": 1
},
{
+ "collapsible": 1,
"fieldname": "pricing_rule_details",
"fieldtype": "Section Break",
"label": "Pricing Rules"
@@ -477,9 +479,10 @@
"read_only": 1
},
{
+ "depends_on": "supplied_items",
"fieldname": "get_current_stock",
"fieldtype": "Button",
- "label": "Get current stock",
+ "label": "Get Current Stock",
"oldfieldtype": "Button",
"options": "get_current_stock",
"print_hide": 1
@@ -489,7 +492,7 @@
"collapsible_depends_on": "supplied_items",
"fieldname": "raw_material_details",
"fieldtype": "Section Break",
- "label": "Raw Materials Supplied",
+ "label": "Raw Materials Consumed",
"oldfieldtype": "Section Break",
"options": "fa fa-table",
"print_hide": 1,
@@ -498,7 +501,7 @@
{
"fieldname": "supplied_items",
"fieldtype": "Table",
- "label": "Supplied Items",
+ "label": "Consumed Items",
"no_copy": 1,
"oldfieldname": "pr_raw_material_details",
"oldfieldtype": "Table",
@@ -1082,7 +1085,7 @@
"idx": 261,
"is_submittable": 1,
"links": [],
- "modified": "2020-04-17 13:06:26.970288",
+ "modified": "2020-04-18 18:02:18.020763",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt",
@@ -1149,4 +1152,4 @@
"timeline_field": "supplier",
"title_field": "title",
"track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index b15f23c..bc6bce9 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -15,15 +15,11 @@
"item_name",
"section_break_4",
"description",
- "item_group",
"brand",
- "image_section",
+ "image_column",
+ "item_group",
"image",
"image_view",
- "manufacture_details",
- "manufacturer",
- "column_break_16",
- "manufacturer_part_no",
"received_and_accepted",
"received_qty",
"qty",
@@ -32,6 +28,7 @@
"uom",
"stock_uom",
"conversion_factor",
+ "stock_qty",
"retain_sample",
"sample_quantity",
"rate_and_amount",
@@ -60,11 +57,6 @@
"rm_supp_cost",
"landed_cost_voucher_amount",
"billed_amt",
- "item_weight_details",
- "weight_per_unit",
- "total_weight",
- "column_break_41",
- "weight_uom",
"warehouse_and_reference",
"warehouse",
"rejected_warehouse",
@@ -77,20 +69,27 @@
"asset_category",
"schedule_date",
"quality_inspection",
- "stock_qty",
"purchase_order_item",
"material_request_item",
"section_break_45",
"allow_zero_valuation_rate",
"bom",
- "col_break5",
"serial_no",
+ "col_break5",
+ "include_exploded_items",
"batch_no",
- "column_break_48",
"rejected_serial_no",
"expense_account",
- "include_exploded_items",
"item_tax_rate",
+ "item_weight_details",
+ "weight_per_unit",
+ "total_weight",
+ "column_break_41",
+ "weight_uom",
+ "manufacture_details",
+ "manufacturer",
+ "column_break_16",
+ "manufacturer_part_no",
"accounting_dimensions_section",
"project",
"dimension_col_break",
@@ -526,7 +525,7 @@
{
"fieldname": "stock_qty",
"fieldtype": "Float",
- "label": "Qty as per Stock UOM",
+ "label": "Accepted Qty as per Stock UOM",
"oldfieldname": "stock_qty",
"oldfieldtype": "Currency",
"print_hide": 1,
@@ -553,7 +552,7 @@
"fieldname": "batch_no",
"fieldtype": "Link",
"in_list_view": 1,
- "label": "Batch No!",
+ "label": "Batch No",
"no_copy": 1,
"oldfieldname": "batch_no",
"oldfieldtype": "Link",
@@ -561,10 +560,6 @@
"print_hide": 1
},
{
- "fieldname": "column_break_48",
- "fieldtype": "Column Break"
- },
- {
"depends_on": "eval:!doc.is_fixed_asset",
"fieldname": "rejected_serial_no",
"fieldtype": "Small Text",
@@ -658,6 +653,7 @@
"read_only": 1
},
{
+ "fetch_from": "item_code.brand",
"fieldname": "brand",
"fieldtype": "Link",
"hidden": 1,
@@ -669,9 +665,9 @@
"read_only": 1
},
{
+ "fetch_from": "item_code.item_group",
"fieldname": "item_group",
"fieldtype": "Link",
- "hidden": 1,
"label": "Item Group",
"oldfieldname": "item_group",
"oldfieldtype": "Link",
@@ -749,21 +745,18 @@
"fieldtype": "Section Break"
},
{
- "collapsible": 1,
- "fieldname": "image_section",
- "fieldtype": "Section Break",
- "label": "Image"
- },
- {
"fieldname": "material_request",
"fieldtype": "Link",
"label": "Material Request",
- "options": "Material Request"
+ "options": "Material Request",
+ "read_only": 1
},
{
"fieldname": "material_request_item",
"fieldtype": "Data",
- "label": "Material Request Item"
+ "hidden": 1,
+ "label": "Material Request Item",
+ "read_only": 1
},
{
"fieldname": "expense_account",
@@ -826,12 +819,17 @@
"ignore_user_permissions": 1,
"label": "Supplier Warehouse",
"options": "Warehouse"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "image_column",
+ "fieldtype": "Column Break"
}
],
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2020-04-07 18:38:21.141558",
+ "modified": "2020-04-10 19:01:21.154963",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 7cf822b..95f9d46 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -865,14 +865,6 @@
self.add_to_stock_entry_detail(item_dict)
- if self.purpose != "Send to Subcontractor" and self.purpose in ["Manufacture", "Repack"]:
- scrap_item_dict = self.get_bom_scrap_material(self.fg_completed_qty)
- for item in itervalues(scrap_item_dict):
- if self.pro_doc and self.pro_doc.scrap_warehouse:
- item["to_warehouse"] = self.pro_doc.scrap_warehouse
-
- self.add_to_stock_entry_detail(scrap_item_dict, bom_no=self.bom_no)
-
# fetch the serial_no of the first stock entry for the second stock entry
if self.work_order and self.purpose == "Manufacture":
self.set_serial_nos(self.work_order)
@@ -883,9 +875,20 @@
if self.purpose in ("Manufacture", "Repack"):
self.load_items_from_bom()
+ self.set_scrap_items()
self.set_actual_qty()
self.calculate_rate_and_amount(raise_error_if_no_rate=False)
+ def set_scrap_items(self):
+ if self.purpose != "Send to Subcontractor" and self.purpose in ["Manufacture", "Repack"]:
+ scrap_item_dict = self.get_bom_scrap_material(self.fg_completed_qty)
+ for item in itervalues(scrap_item_dict):
+ item.idx = ''
+ if self.pro_doc and self.pro_doc.scrap_warehouse:
+ item["to_warehouse"] = self.pro_doc.scrap_warehouse
+
+ self.add_to_stock_entry_detail(scrap_item_dict, bom_no=self.bom_no)
+
def set_work_order_details(self):
if not getattr(self, "pro_doc", None):
self.pro_doc = frappe._dict()
diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py
index 9777673..4c721ac 100644
--- a/erpnext/stock/reorder_item.py
+++ b/erpnext/stock/reorder_item.py
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
import erpnext
+import json
from frappe.utils import flt, nowdate, add_days, cint
from frappe import _
@@ -198,19 +199,16 @@
subject=_('Auto Material Requests Generated'), message = msg)
def notify_errors(exceptions_list):
- subject = "[Important] [ERPNext] Auto Reorder Errors"
- content = """Dear System Manager,
+ subject = _("[Important] [ERPNext] Auto Reorder Errors")
+ content = _("Dear System Manager,") + "<br>" + _("An error occured for certain Items while creating Material Requests based on Re-order level. \
+ Please rectify these issues :") + "<br>"
-An error occured for certain Items while creating Material Requests based on Re-order level.
+ for exception in exceptions_list:
+ exception = json.loads(exception)
+ error_message = """<div class='small text-muted'>{0}</div><br>""".format(_(exception.get("message")))
+ content += error_message
-Please rectify these issues:
----
-<pre>
-%s
-</pre>
----
-Regards,
-Administrator""" % ("\n\n".join(exceptions_list),)
+ content += _("Regards,") + "<br>" + _("Administrator")
from frappe.email import sendmail_to_system_managers
sendmail_to_system_managers(subject, content)
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index fd72807..117267f 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -335,8 +335,13 @@
ignore_permissions = False
if is_website_user():
- if not filters: filters = []
- filters.append(("Issue", "customer", "=", customer)) if customer else filters.append(("Issue", "raised_by", "=", user))
+ if not filters: filters = {}
+
+ if customer:
+ filters["customer"] = customer
+ else:
+ filters["raised_by"] = user
+
ignore_permissions = True
return get_list(doctype, txt, filters, limit_start, limit_page_length, ignore_permissions=ignore_permissions)
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index f88ffd4..14674c0 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -126,7 +126,7 @@
frappe.msgprint(_("Row #{0}: Rate must be same as {1}: {2} ({3} / {4}) ")
.format(d.idx, ref_dt, d.get(ref_dn_field), d.rate, ref_rate))
frappe.throw(_("To allow different rates, disable the {0} checkbox in {1}.")
- .format(frappe.bold("Maintain Same Rate Throughout Sales Cycle"),
+ .format(frappe.bold(_("Maintain Same Rate Throughout Sales Cycle")),
get_link_to_form("Selling Settings", "Selling Settings", frappe.bold("Selling Settings"))))
def get_link_filters(self, for_doctype):
@@ -179,4 +179,6 @@
qty = d.get(f)
if qty:
if abs(cint(qty) - flt(qty)) > 0.0000001:
- frappe.throw(_("Quantity ({0}) cannot be a fraction in row {1}").format(qty, d.idx), UOMMustBeIntegerError)
+ frappe.throw(_("Row {1}: Quantity ({0}) cannot be a fraction. To allow this, disable '{2}' in UOM {3}.") \
+ .format(qty, d.idx, frappe.bold(_("Must be Whole Number")), frappe.bold(d.get(uom_field))),
+ UOMMustBeIntegerError)