Merge branch 'develop' into enrollment-fixes
This commit is contained in:
commit
9ed208364d
@ -16,7 +16,7 @@
|
|||||||
ERPNext as a monolith includes the following areas for managing businesses:
|
ERPNext as a monolith includes the following areas for managing businesses:
|
||||||
|
|
||||||
1. [Accounting](https://erpnext.com/open-source-accounting)
|
1. [Accounting](https://erpnext.com/open-source-accounting)
|
||||||
1. [Inventory](https://erpnext.com/distribution/inventory-management-system)
|
1. [Warehouse Management](https://erpnext.com/distribution/warehouse-management-system)
|
||||||
1. [CRM](https://erpnext.com/open-source-crm)
|
1. [CRM](https://erpnext.com/open-source-crm)
|
||||||
1. [Sales](https://erpnext.com/open-source-sales-purchase)
|
1. [Sales](https://erpnext.com/open-source-sales-purchase)
|
||||||
1. [Purchase](https://erpnext.com/open-source-sales-purchase)
|
1. [Purchase](https://erpnext.com/open-source-sales-purchase)
|
||||||
|
@ -38,8 +38,8 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2020-06-18 20:27:42.615842",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "ahmad@havenir.com",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Item Tax Template",
|
"name": "Item Tax Template",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
|
@ -45,11 +45,11 @@
|
|||||||
],
|
],
|
||||||
"icon": "fa fa-credit-card",
|
"icon": "fa fa-credit-card",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2019-08-14 14:58:42.079115",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "sammish.thundiyil@gmail.com",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Mode of Payment",
|
"name": "Mode of Payment",
|
||||||
"owner": "harshada@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"create": 1,
|
"create": 1,
|
||||||
|
@ -12,9 +12,10 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
|
|
||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
frm.set_query("paid_from", function() {
|
frm.set_query("paid_from", function() {
|
||||||
|
frm.events.validate_company(frm);
|
||||||
|
|
||||||
var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ?
|
var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ?
|
||||||
["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
|
["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"account_type": ["in", account_types],
|
"account_type": ["in", account_types],
|
||||||
@ -23,13 +24,16 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.set_query("party_type", function() {
|
frm.set_query("party_type", function() {
|
||||||
|
frm.events.validate_company(frm);
|
||||||
return{
|
return{
|
||||||
filters: {
|
filters: {
|
||||||
"name": ["in", Object.keys(frappe.boot.party_account_types)],
|
"name": ["in", Object.keys(frappe.boot.party_account_types)],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.set_query("party_bank_account", function() {
|
frm.set_query("party_bank_account", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
@ -39,6 +43,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.set_query("bank_account", function() {
|
frm.set_query("bank_account", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
@ -47,6 +52,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.set_query("contact_person", function() {
|
frm.set_query("contact_person", function() {
|
||||||
if (frm.doc.party) {
|
if (frm.doc.party) {
|
||||||
return {
|
return {
|
||||||
@ -58,10 +64,12 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.set_query("paid_to", function() {
|
frm.set_query("paid_to", function() {
|
||||||
|
frm.events.validate_company(frm);
|
||||||
|
|
||||||
var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ?
|
var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ?
|
||||||
["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
|
["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"account_type": ["in", account_types],
|
"account_type": ["in", account_types],
|
||||||
@ -150,6 +158,12 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
frm.events.show_general_ledger(frm);
|
frm.events.show_general_ledger(frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
validate_company: (frm) => {
|
||||||
|
if (!frm.doc.company){
|
||||||
|
frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
company: function(frm) {
|
company: function(frm) {
|
||||||
frm.events.hide_unhide_fields(frm);
|
frm.events.hide_unhide_fields(frm);
|
||||||
frm.events.set_dynamic_labels(frm);
|
frm.events.set_dynamic_labels(frm);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2016-06-01 14:38:51.012597",
|
"creation": "2016-06-01 14:38:51.012597",
|
||||||
@ -63,6 +64,7 @@
|
|||||||
"cost_center",
|
"cost_center",
|
||||||
"section_break_12",
|
"section_break_12",
|
||||||
"status",
|
"status",
|
||||||
|
"custom_remarks",
|
||||||
"remarks",
|
"remarks",
|
||||||
"column_break_16",
|
"column_break_16",
|
||||||
"letter_head",
|
"letter_head",
|
||||||
@ -462,7 +464,8 @@
|
|||||||
"fieldname": "remarks",
|
"fieldname": "remarks",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Remarks",
|
"label": "Remarks",
|
||||||
"no_copy": 1
|
"no_copy": 1,
|
||||||
|
"read_only_depends_on": "eval:doc.custom_remarks == 0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_16",
|
"fieldname": "column_break_16",
|
||||||
@ -573,10 +576,18 @@
|
|||||||
"label": "Status",
|
"label": "Status",
|
||||||
"options": "\nDraft\nSubmitted\nCancelled",
|
"options": "\nDraft\nSubmitted\nCancelled",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "custom_remarks",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Custom Remarks"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-12-08 13:02:30.016610",
|
"links": [],
|
||||||
|
"modified": "2020-09-02 13:39:43.383705",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
@ -453,7 +453,7 @@ class PaymentEntry(AccountsController):
|
|||||||
frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
|
frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
|
||||||
|
|
||||||
def set_remarks(self):
|
def set_remarks(self):
|
||||||
if self.remarks: return
|
if self.custom_remarks: return
|
||||||
|
|
||||||
if self.payment_type=="Internal Transfer":
|
if self.payment_type=="Internal Transfer":
|
||||||
remarks = [_("Amount {0} {1} transferred from {2} to {3}")
|
remarks = [_("Amount {0} {1} transferred from {2} to {3}")
|
||||||
|
@ -291,11 +291,11 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-08-21 16:15:49.089450",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Period Closing Voucher",
|
"name": "Period Closing Voucher",
|
||||||
"owner": "jai@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
|
@ -5,13 +5,14 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import cint
|
from frappe.utils import cint, get_link_to_form
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.controllers.status_updater import StatusUpdater
|
from erpnext.controllers.status_updater import StatusUpdater
|
||||||
|
|
||||||
class POSOpeningEntry(StatusUpdater):
|
class POSOpeningEntry(StatusUpdater):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_pos_profile_and_cashier()
|
self.validate_pos_profile_and_cashier()
|
||||||
|
self.validate_payment_method_account()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
def validate_pos_profile_and_cashier(self):
|
def validate_pos_profile_and_cashier(self):
|
||||||
@ -21,5 +22,13 @@ class POSOpeningEntry(StatusUpdater):
|
|||||||
if not cint(frappe.db.get_value("User", self.user, "enabled")):
|
if not cint(frappe.db.get_value("User", self.user, "enabled")):
|
||||||
frappe.throw(_("User {} has been disabled. Please select valid user/cashier".format(self.user)))
|
frappe.throw(_("User {} has been disabled. Please select valid user/cashier".format(self.user)))
|
||||||
|
|
||||||
|
def validate_payment_method_account(self):
|
||||||
|
for d in self.balance_details:
|
||||||
|
account = frappe.db.get_value("Mode of Payment Account",
|
||||||
|
{"parent": d.mode_of_payment, "company": self.company}, "default_account")
|
||||||
|
if not account:
|
||||||
|
frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}")
|
||||||
|
.format(get_link_to_form("Mode of Payment", mode_of_payment)), title=_("Missing Account"))
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.set_status(update=True)
|
self.set_status(update=True)
|
@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import msgprint, _
|
from frappe import msgprint, _
|
||||||
from frappe.utils import cint, now
|
from frappe.utils import cint, now, get_link_to_form
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ class POSProfile(Document):
|
|||||||
self.validate_default_profile()
|
self.validate_default_profile()
|
||||||
self.validate_all_link_fields()
|
self.validate_all_link_fields()
|
||||||
self.validate_duplicate_groups()
|
self.validate_duplicate_groups()
|
||||||
self.check_default_payment()
|
self.validate_payment_methods()
|
||||||
|
|
||||||
def validate_default_profile(self):
|
def validate_default_profile(self):
|
||||||
for row in self.applicable_for_users:
|
for row in self.applicable_for_users:
|
||||||
@ -52,14 +52,23 @@ class POSProfile(Document):
|
|||||||
if len(customer_groups) != len(set(customer_groups)):
|
if len(customer_groups) != len(set(customer_groups)):
|
||||||
frappe.throw(_("Duplicate customer group found in the cutomer group table"), title = "Duplicate Customer Group")
|
frappe.throw(_("Duplicate customer group found in the cutomer group table"), title = "Duplicate Customer Group")
|
||||||
|
|
||||||
def check_default_payment(self):
|
def validate_payment_methods(self):
|
||||||
if self.payments:
|
if not self.payments:
|
||||||
|
frappe.throw(_("Payment methods are mandatory. Please add at least one payment method."))
|
||||||
|
|
||||||
default_mode_of_payment = [d.default for d in self.payments if d.default]
|
default_mode_of_payment = [d.default for d in self.payments if d.default]
|
||||||
if not default_mode_of_payment:
|
if not default_mode_of_payment:
|
||||||
frappe.throw(_("Set default mode of payment"))
|
frappe.throw(_("Please select a default mode of payment"))
|
||||||
|
|
||||||
if len(default_mode_of_payment) > 1:
|
if len(default_mode_of_payment) > 1:
|
||||||
frappe.throw(_("Multiple default mode of payment is not allowed"))
|
frappe.throw(_("You can only select one mode of payment as default"))
|
||||||
|
|
||||||
|
for d in self.payments:
|
||||||
|
account = frappe.db.get_value("Mode of Payment Account",
|
||||||
|
{"parent": d.mode_of_payment, "company": self.company}, "default_account")
|
||||||
|
if not account:
|
||||||
|
frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}")
|
||||||
|
.format(get_link_to_form("Mode of Payment", mode_of_payment)), title=_("Missing Account"))
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
self.set_defaults()
|
self.set_defaults()
|
||||||
|
@ -7,10 +7,10 @@ frappe.ui.form.on('POS Settings', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
get_invoice_fields: function(frm) {
|
get_invoice_fields: function(frm) {
|
||||||
frappe.model.with_doctype("Sales Invoice", () => {
|
frappe.model.with_doctype("POS Invoice", () => {
|
||||||
var fields = $.map(frappe.get_doc("DocType", "Sales Invoice").fields, function(d) {
|
var fields = $.map(frappe.get_doc("DocType", "POS Invoice").fields, function(d) {
|
||||||
if (frappe.model.no_value_type.indexOf(d.fieldtype) === -1 ||
|
if (frappe.model.no_value_type.indexOf(d.fieldtype) === -1 ||
|
||||||
d.fieldtype === 'Table') {
|
['Table', 'Button'].includes(d.fieldtype)) {
|
||||||
return { label: d.label + ' (' + d.fieldtype + ')', value: d.fieldname };
|
return { label: d.label + ' (' + d.fieldtype + ')', value: d.fieldname };
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@ -25,7 +25,7 @@ frappe.ui.form.on('POS Settings', {
|
|||||||
frappe.ui.form.on("POS Field", {
|
frappe.ui.form.on("POS Field", {
|
||||||
fieldname: function(frm, doctype, name) {
|
fieldname: function(frm, doctype, name) {
|
||||||
var doc = frappe.get_doc(doctype, name);
|
var doc = frappe.get_doc(doctype, name);
|
||||||
var df = $.map(frappe.get_doc("DocType", "Sales Invoice").fields, function(d) {
|
var df = $.map(frappe.get_doc("DocType", "POS Invoice").fields, function(d) {
|
||||||
return doc.fieldname == d.fieldname ? d : null;
|
return doc.fieldname == d.fieldname ? d : null;
|
||||||
})[0];
|
})[0];
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-03-12 14:53:47.679439",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Taxes and Charges",
|
"name": "Purchase Taxes and Charges",
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Taxes and Charges Template",
|
"name": "Purchase Taxes and Charges Template",
|
||||||
"owner": "wasim@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"email": 1,
|
"email": 1,
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from frappe.utils import cint, flt, add_months, today, date_diff, getdate, add_days, cstr, nowdate
|
from frappe.utils import cint, flt, add_months, today, date_diff, getdate, add_days, cstr, nowdate, get_link_to_form
|
||||||
from frappe import _, msgprint, throw
|
from frappe import _, msgprint, throw
|
||||||
from erpnext.accounts.party import get_party_account, get_due_date
|
from erpnext.accounts.party import get_party_account, get_due_date
|
||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
@ -1372,7 +1372,7 @@ def get_bank_cash_account(mode_of_payment, company):
|
|||||||
{"parent": mode_of_payment, "company": company}, "default_account")
|
{"parent": mode_of_payment, "company": company}, "default_account")
|
||||||
if not account:
|
if not account:
|
||||||
frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}")
|
frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}")
|
||||||
.format(mode_of_payment))
|
.format(get_link_to_form("Mode of Payment", mode_of_payment)), title=_("Missing Account"))
|
||||||
return {
|
return {
|
||||||
"account": account
|
"account": account
|
||||||
}
|
}
|
||||||
@ -1612,16 +1612,14 @@ def update_multi_mode_option(doc, pos_profile):
|
|||||||
payment.type = payment_mode.type
|
payment.type = payment_mode.type
|
||||||
|
|
||||||
doc.set('payments', [])
|
doc.set('payments', [])
|
||||||
if not pos_profile or not pos_profile.get('payments'):
|
|
||||||
for payment_mode in get_all_mode_of_payments(doc):
|
|
||||||
append_payment(payment_mode)
|
|
||||||
return
|
|
||||||
|
|
||||||
for pos_payment_method in pos_profile.get('payments'):
|
for pos_payment_method in pos_profile.get('payments'):
|
||||||
pos_payment_method = pos_payment_method.as_dict()
|
pos_payment_method = pos_payment_method.as_dict()
|
||||||
|
|
||||||
payment_mode = get_mode_of_payment_info(pos_payment_method.mode_of_payment, doc.company)
|
payment_mode = get_mode_of_payment_info(pos_payment_method.mode_of_payment, doc.company)
|
||||||
if payment_mode:
|
if not payment_mode:
|
||||||
|
frappe.throw(_("Please set default Cash or Bank account in Mode of Payment {0}")
|
||||||
|
.format(get_link_to_form("Mode of Payment", pos_payment_method.mode_of_payment)), title=_("Missing Account"))
|
||||||
|
|
||||||
payment_mode[0].default = pos_payment_method.default
|
payment_mode[0].default = pos_payment_method.default
|
||||||
append_payment(payment_mode[0])
|
append_payment(payment_mode[0])
|
||||||
|
|
||||||
|
@ -320,7 +320,6 @@ def make_reverse_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
|||||||
|
|
||||||
entry['remarks'] = "On cancellation of " + entry['voucher_no']
|
entry['remarks'] = "On cancellation of " + entry['voucher_no']
|
||||||
entry['is_cancelled'] = 1
|
entry['is_cancelled'] = 1
|
||||||
entry['posting_date'] = today()
|
|
||||||
|
|
||||||
if entry['debit'] or entry['credit']:
|
if entry['debit'] or entry['credit']:
|
||||||
make_entry(entry, adv_adj, "Yes")
|
make_entry(entry, adv_adj, "Yes")
|
||||||
|
@ -72,7 +72,7 @@ erpnext.accounts.bankReconciliation = class BankReconciliation {
|
|||||||
check_plaid_status() {
|
check_plaid_status() {
|
||||||
const me = this;
|
const me = this;
|
||||||
frappe.db.get_value("Plaid Settings", "Plaid Settings", "enabled", (r) => {
|
frappe.db.get_value("Plaid Settings", "Plaid Settings", "enabled", (r) => {
|
||||||
if (r && r.enabled == "1") {
|
if (r && r.enabled === "1") {
|
||||||
me.plaid_status = "active"
|
me.plaid_status = "active"
|
||||||
} else {
|
} else {
|
||||||
me.plaid_status = "inactive"
|
me.plaid_status = "inactive"
|
||||||
@ -214,29 +214,33 @@ erpnext.accounts.bankTransactionSync = class bankTransactionSync {
|
|||||||
|
|
||||||
init_config() {
|
init_config() {
|
||||||
const me = this;
|
const me = this;
|
||||||
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.plaid_configuration')
|
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.get_plaid_configuration')
|
||||||
.then(result => {
|
.then(result => {
|
||||||
me.plaid_env = result.plaid_env;
|
me.plaid_env = result.plaid_env;
|
||||||
me.plaid_public_key = result.plaid_public_key;
|
|
||||||
me.client_name = result.client_name;
|
me.client_name = result.client_name;
|
||||||
me.sync_transactions()
|
me.link_token = result.link_token;
|
||||||
|
me.sync_transactions();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_transactions() {
|
sync_transactions() {
|
||||||
const me = this;
|
const me = this;
|
||||||
frappe.db.get_value("Bank Account", me.parent.bank_account, "bank", (v) => {
|
frappe.db.get_value("Bank Account", me.parent.bank_account, "bank", (r) => {
|
||||||
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions', {
|
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions', {
|
||||||
bank: v['bank'],
|
bank: r.bank,
|
||||||
bank_account: me.parent.bank_account,
|
bank_account: me.parent.bank_account,
|
||||||
freeze: true
|
freeze: true
|
||||||
})
|
})
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
let result_title = (result.length > 0) ? __("{0} bank transaction(s) created", [result.length]) : __("This bank account is already synchronized")
|
let result_title = (result && result.length > 0)
|
||||||
|
? __("{0} bank transaction(s) created", [result.length])
|
||||||
|
: __("This bank account is already synchronized");
|
||||||
|
|
||||||
let result_msg = `
|
let result_msg = `
|
||||||
<div class="flex justify-center align-center text-muted" style="height: 50vh; display: flex;">
|
<div class="flex justify-center align-center text-muted" style="height: 50vh; display: flex;">
|
||||||
<h5 class="text-muted">${result_title}</h5>
|
<h5 class="text-muted">${result_title}</h5>
|
||||||
</div>`
|
</div>`
|
||||||
|
|
||||||
this.parent.$main_section.append(result_msg)
|
this.parent.$main_section.append(result_msg)
|
||||||
frappe.show_alert({ message: __("Bank account '{0}' has been synchronized", [me.parent.bank_account]), indicator: 'green' });
|
frappe.show_alert({ message: __("Bank account '{0}' has been synchronized", [me.parent.bank_account]), indicator: 'green' });
|
||||||
})
|
})
|
||||||
|
@ -34,7 +34,7 @@ frappe.query_reports["Accounts Receivable"] = {
|
|||||||
filters: {
|
filters: {
|
||||||
'company': company
|
'company': company
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -617,9 +617,19 @@ class ReceivablePayableReport(object):
|
|||||||
elif party_type_field=="supplier":
|
elif party_type_field=="supplier":
|
||||||
self.add_supplier_filters(conditions, values)
|
self.add_supplier_filters(conditions, values)
|
||||||
|
|
||||||
|
if self.filters.cost_center:
|
||||||
|
self.get_cost_center_conditions(conditions)
|
||||||
|
|
||||||
self.add_accounting_dimensions_filters(conditions, values)
|
self.add_accounting_dimensions_filters(conditions, values)
|
||||||
return " and ".join(conditions), values
|
return " and ".join(conditions), values
|
||||||
|
|
||||||
|
def get_cost_center_conditions(self, conditions):
|
||||||
|
lft, rgt = frappe.db.get_value("Cost Center", self.filters.cost_center, ["lft", "rgt"])
|
||||||
|
cost_center_list = [center.name for center in frappe.get_list("Cost Center", filters = {'lft': (">=", lft), 'rgt': ("<=", rgt)})]
|
||||||
|
|
||||||
|
cost_center_string = '", "'.join(cost_center_list)
|
||||||
|
conditions.append('cost_center in ("{0}")'.format(cost_center_string))
|
||||||
|
|
||||||
def get_order_by_condition(self):
|
def get_order_by_condition(self):
|
||||||
if self.filters.get('group_by_party'):
|
if self.filters.get('group_by_party'):
|
||||||
return "order by party, posting_date"
|
return "order by party, posting_date"
|
||||||
|
@ -268,9 +268,9 @@ class GrossProfitGenerator(object):
|
|||||||
def get_last_purchase_rate(self, item_code, row):
|
def get_last_purchase_rate(self, item_code, row):
|
||||||
condition = ''
|
condition = ''
|
||||||
if row.project:
|
if row.project:
|
||||||
condition += " AND a.project='%s'" % (row.project)
|
condition += " AND a.project=%s" % (frappe.db.escape(row.project))
|
||||||
elif row.cost_center:
|
elif row.cost_center:
|
||||||
condition += " AND a.cost_center='%s'" % (row.cost_center)
|
condition += " AND a.cost_center=%s" % (frappe.db.escape(row.cost_center))
|
||||||
if self.filters.to_date:
|
if self.filters.to_date:
|
||||||
condition += " AND modified='%s'" % (self.filters.to_date)
|
condition += " AND modified='%s'" % (self.filters.to_date)
|
||||||
|
|
||||||
|
@ -252,13 +252,6 @@ frappe.ui.form.on('Asset', {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
available_for_use_date: function(frm) {
|
|
||||||
$.each(frm.doc.finance_books || [], function(i, d) {
|
|
||||||
if(!d.depreciation_start_date) d.depreciation_start_date = frm.doc.available_for_use_date;
|
|
||||||
});
|
|
||||||
refresh_field("finance_books");
|
|
||||||
},
|
|
||||||
|
|
||||||
is_existing_asset: function(frm) {
|
is_existing_asset: function(frm) {
|
||||||
frm.trigger("toggle_reference_doc");
|
frm.trigger("toggle_reference_doc");
|
||||||
// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
|
// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
|
||||||
@ -438,6 +431,15 @@ frappe.ui.form.on('Asset Finance Book', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frappe.flags.dont_change_rate = false;
|
frappe.flags.dont_change_rate = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
depreciation_start_date: function(frm, cdt, cdn) {
|
||||||
|
const book = locals[cdt][cdn];
|
||||||
|
if (frm.doc.available_for_use_date && book.depreciation_start_date == frm.doc.available_for_use_date) {
|
||||||
|
frappe.msgprint(__(`Depreciation Posting Date should not be equal to Available for Use Date.`));
|
||||||
|
book.depreciation_start_date = "";
|
||||||
|
frm.refresh_field("finance_books");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe, erpnext, math, json
|
import frappe, erpnext, math, json
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from six import string_types
|
from six import string_types
|
||||||
from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff, month_diff, add_days
|
from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff, month_diff, add_days, get_last_day
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
|
||||||
from erpnext.assets.doctype.asset.depreciation \
|
from erpnext.assets.doctype.asset.depreciation \
|
||||||
@ -83,6 +83,11 @@ class Asset(AccountsController):
|
|||||||
if not self.available_for_use_date:
|
if not self.available_for_use_date:
|
||||||
frappe.throw(_("Available for use date is required"))
|
frappe.throw(_("Available for use date is required"))
|
||||||
|
|
||||||
|
for d in self.finance_books:
|
||||||
|
if d.depreciation_start_date == self.available_for_use_date:
|
||||||
|
frappe.throw(_("Row #{}: Depreciation Posting Date should not be equal to Available for Use Date.").format(d.idx),
|
||||||
|
title=_("Incorrect Date"))
|
||||||
|
|
||||||
def set_missing_values(self):
|
def set_missing_values(self):
|
||||||
if not self.asset_category:
|
if not self.asset_category:
|
||||||
self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category")
|
self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category")
|
||||||
@ -294,7 +299,7 @@ class Asset(AccountsController):
|
|||||||
if not row.depreciation_start_date:
|
if not row.depreciation_start_date:
|
||||||
if not self.available_for_use_date:
|
if not self.available_for_use_date:
|
||||||
frappe.throw(_("Row {0}: Depreciation Start Date is required").format(row.idx))
|
frappe.throw(_("Row {0}: Depreciation Start Date is required").format(row.idx))
|
||||||
row.depreciation_start_date = self.available_for_use_date
|
row.depreciation_start_date = get_last_day(self.available_for_use_date)
|
||||||
|
|
||||||
if not self.is_existing_asset:
|
if not self.is_existing_asset:
|
||||||
self.opening_accumulated_depreciation = 0
|
self.opening_accumulated_depreciation = 0
|
||||||
|
@ -371,19 +371,18 @@ class TestAsset(unittest.TestCase):
|
|||||||
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
|
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
|
||||||
asset = frappe.get_doc('Asset', asset_name)
|
asset = frappe.get_doc('Asset', asset_name)
|
||||||
asset.calculate_depreciation = 1
|
asset.calculate_depreciation = 1
|
||||||
asset.available_for_use_date = nowdate()
|
asset.available_for_use_date = '2020-01-01'
|
||||||
asset.purchase_date = nowdate()
|
asset.purchase_date = '2020-01-01'
|
||||||
asset.append("finance_books", {
|
asset.append("finance_books", {
|
||||||
"expected_value_after_useful_life": 10000,
|
"expected_value_after_useful_life": 10000,
|
||||||
"depreciation_method": "Straight Line",
|
"depreciation_method": "Straight Line",
|
||||||
"total_number_of_depreciations": 3,
|
"total_number_of_depreciations": 10,
|
||||||
"frequency_of_depreciation": 10,
|
"frequency_of_depreciation": 1
|
||||||
"depreciation_start_date": nowdate()
|
|
||||||
})
|
})
|
||||||
asset.insert()
|
asset.insert()
|
||||||
asset.submit()
|
asset.submit()
|
||||||
|
|
||||||
post_depreciation_entries(date=add_months(nowdate(), 10))
|
post_depreciation_entries(date=add_months('2020-01-01', 4))
|
||||||
|
|
||||||
scrap_asset(asset.name)
|
scrap_asset(asset.name)
|
||||||
|
|
||||||
@ -392,9 +391,9 @@ class TestAsset(unittest.TestCase):
|
|||||||
self.assertTrue(asset.journal_entry_for_scrap)
|
self.assertTrue(asset.journal_entry_for_scrap)
|
||||||
|
|
||||||
expected_gle = (
|
expected_gle = (
|
||||||
("_Test Accumulated Depreciations - _TC", 30000.0, 0.0),
|
("_Test Accumulated Depreciations - _TC", 36000.0, 0.0),
|
||||||
("_Test Fixed Asset - _TC", 0.0, 100000.0),
|
("_Test Fixed Asset - _TC", 0.0, 100000.0),
|
||||||
("_Test Gain/Loss on Asset Disposal - _TC", 70000.0, 0.0)
|
("_Test Gain/Loss on Asset Disposal - _TC", 64000.0, 0.0)
|
||||||
)
|
)
|
||||||
|
|
||||||
gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
|
gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
|
||||||
@ -466,8 +465,7 @@ class TestAsset(unittest.TestCase):
|
|||||||
"expected_value_after_useful_life": 10000,
|
"expected_value_after_useful_life": 10000,
|
||||||
"depreciation_method": "Straight Line",
|
"depreciation_method": "Straight Line",
|
||||||
"total_number_of_depreciations": 3,
|
"total_number_of_depreciations": 3,
|
||||||
"frequency_of_depreciation": 10,
|
"frequency_of_depreciation": 10
|
||||||
"depreciation_start_date": "2020-06-06"
|
|
||||||
})
|
})
|
||||||
asset.insert()
|
asset.insert()
|
||||||
accumulated_depreciation_after_full_schedule = \
|
accumulated_depreciation_after_full_schedule = \
|
||||||
|
@ -1,347 +1,99 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2018-05-08 14:44:37.095570",
|
"creation": "2018-05-08 14:44:37.095570",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"finance_book",
|
||||||
|
"depreciation_method",
|
||||||
|
"total_number_of_depreciations",
|
||||||
|
"column_break_5",
|
||||||
|
"frequency_of_depreciation",
|
||||||
|
"depreciation_start_date",
|
||||||
|
"expected_value_after_useful_life",
|
||||||
|
"value_after_depreciation",
|
||||||
|
"rate_of_depreciation"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "",
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "finance_book",
|
"fieldname": "finance_book",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Finance Book",
|
"label": "Finance Book",
|
||||||
"length": 0,
|
"options": "Finance Book"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Finance Book",
|
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "depreciation_method",
|
"fieldname": "depreciation_method",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Depreciation Method",
|
"label": "Depreciation Method",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "\nStraight Line\nDouble Declining Balance\nWritten Down Value\nManual",
|
"options": "\nStraight Line\nDouble Declining Balance\nWritten Down Value\nManual",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "total_number_of_depreciations",
|
"fieldname": "total_number_of_depreciations",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Total Number of Depreciations",
|
"label": "Total Number of Depreciations",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "column_break_5",
|
"fieldname": "column_break_5",
|
||||||
"fieldtype": "Column Break",
|
"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,
|
|
||||||
"label": "",
|
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "frequency_of_depreciation",
|
"fieldname": "frequency_of_depreciation",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Frequency of Depreciation (Months)",
|
"label": "Frequency of Depreciation (Months)",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:parent.doctype == 'Asset'",
|
"depends_on": "eval:parent.doctype == 'Asset'",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "depreciation_start_date",
|
"fieldname": "depreciation_start_date",
|
||||||
"fieldtype": "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_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"label": "Depreciation Posting Date",
|
||||||
"label": "Depreciation Start Date",
|
"reqd": 1
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"depends_on": "eval:parent.doctype == 'Asset'",
|
"depends_on": "eval:parent.doctype == 'Asset'",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "expected_value_after_useful_life",
|
"fieldname": "expected_value_after_useful_life",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"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": "Expected Value After Useful Life",
|
"label": "Expected Value After Useful Life",
|
||||||
"length": 0,
|
"options": "Company:company:default_currency"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "value_after_depreciation",
|
"fieldname": "value_after_depreciation",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 1,
|
"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": "Value After Depreciation",
|
"label": "Value After Depreciation",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"print_hide_if_no_value": 0,
|
"read_only": 1
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:doc.depreciation_method == 'Written Down Value'",
|
"depends_on": "eval:doc.depreciation_method == 'Written Down Value'",
|
||||||
"description": "In Percentage",
|
"description": "In Percentage",
|
||||||
"fetch_if_empty": 0,
|
|
||||||
"fieldname": "rate_of_depreciation",
|
"fieldname": "rate_of_depreciation",
|
||||||
"fieldtype": "Percent",
|
"fieldtype": "Percent",
|
||||||
"hidden": 0,
|
"label": "Rate of Depreciation"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Rate of Depreciation",
|
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"index_web_pages_for_search": 1,
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"links": [],
|
||||||
"modified": "2019-04-09 19:45:14.523488",
|
"modified": "2020-09-16 12:11:30.631788",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Finance Book",
|
"name": "Asset Finance Book",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1,
|
"track_changes": 1
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -32,8 +32,7 @@ class TestAssetMovement(unittest.TestCase):
|
|||||||
"next_depreciation_date": "2020-12-31",
|
"next_depreciation_date": "2020-12-31",
|
||||||
"depreciation_method": "Straight Line",
|
"depreciation_method": "Straight Line",
|
||||||
"total_number_of_depreciations": 3,
|
"total_number_of_depreciations": 3,
|
||||||
"frequency_of_depreciation": 10,
|
"frequency_of_depreciation": 10
|
||||||
"depreciation_start_date": "2020-06-06"
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if asset.docstatus == 0:
|
if asset.docstatus == 0:
|
||||||
@ -82,8 +81,7 @@ class TestAssetMovement(unittest.TestCase):
|
|||||||
"next_depreciation_date": "2020-12-31",
|
"next_depreciation_date": "2020-12-31",
|
||||||
"depreciation_method": "Straight Line",
|
"depreciation_method": "Straight Line",
|
||||||
"total_number_of_depreciations": 3,
|
"total_number_of_depreciations": 3,
|
||||||
"frequency_of_depreciation": 10,
|
"frequency_of_depreciation": 10
|
||||||
"depreciation_start_date": "2020-06-06"
|
|
||||||
})
|
})
|
||||||
if asset.docstatus == 0:
|
if asset.docstatus == 0:
|
||||||
asset.submit()
|
asset.submit()
|
||||||
|
@ -202,6 +202,53 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Purchase Order', trans_item, po.name)
|
self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Purchase Order', trans_item, po.name)
|
||||||
frappe.set_user("Administrator")
|
frappe.set_user("Administrator")
|
||||||
|
|
||||||
|
def test_update_child_with_tax_template(self):
|
||||||
|
tax_template = "_Test Account Excise Duty @ 10"
|
||||||
|
item = "_Test Item Home Desktop 100"
|
||||||
|
|
||||||
|
if not frappe.db.exists("Item Tax", {"parent":item, "item_tax_template":tax_template}):
|
||||||
|
item_doc = frappe.get_doc("Item", item)
|
||||||
|
item_doc.append("taxes", {
|
||||||
|
"item_tax_template": tax_template,
|
||||||
|
"valid_from": nowdate()
|
||||||
|
})
|
||||||
|
item_doc.save()
|
||||||
|
else:
|
||||||
|
# update valid from
|
||||||
|
frappe.db.sql("""UPDATE `tabItem Tax` set valid_from = CURDATE()
|
||||||
|
where parent = %(item)s and item_tax_template = %(tax)s""",
|
||||||
|
{"item": item, "tax": tax_template})
|
||||||
|
|
||||||
|
po = create_purchase_order(item_code=item, qty=1, do_not_save=1)
|
||||||
|
|
||||||
|
po.append("taxes", {
|
||||||
|
"account_head": "_Test Account Excise Duty - _TC",
|
||||||
|
"charge_type": "On Net Total",
|
||||||
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
|
"description": "Excise Duty",
|
||||||
|
"doctype": "Purchase Taxes and Charges",
|
||||||
|
"rate": 10
|
||||||
|
})
|
||||||
|
po.insert()
|
||||||
|
po.submit()
|
||||||
|
|
||||||
|
self.assertEqual(po.taxes[0].tax_amount, 50)
|
||||||
|
self.assertEqual(po.taxes[0].total, 550)
|
||||||
|
|
||||||
|
items = json.dumps([
|
||||||
|
{'item_code' : item, 'rate' : 500, 'qty' : 1, 'docname': po.items[0].name},
|
||||||
|
{'item_code' : item, 'rate' : 100, 'qty' : 1} # added item
|
||||||
|
])
|
||||||
|
update_child_qty_rate('Purchase Order', items, po.name)
|
||||||
|
|
||||||
|
po.reload()
|
||||||
|
self.assertEqual(po.taxes[0].tax_amount, 60)
|
||||||
|
self.assertEqual(po.taxes[0].total, 660)
|
||||||
|
|
||||||
|
frappe.db.sql("""UPDATE `tabItem Tax` set valid_from = NULL
|
||||||
|
where parent = %(item)s and item_tax_template = %(tax)s""",
|
||||||
|
{"item": item, "tax": tax_template})
|
||||||
|
|
||||||
def test_update_child_uom_conv_factor_change(self):
|
def test_update_child_uom_conv_factor_change(self):
|
||||||
po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
|
po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
|
||||||
total_reqd_qty = sum([d.get("required_qty") for d in po.as_dict().get("supplied_items")])
|
total_reqd_qty = sum([d.get("required_qty") for d in po.as_dict().get("supplied_items")])
|
||||||
|
@ -148,11 +148,11 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-03-12 15:43:53.862897",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order Item Supplied",
|
"name": "Purchase Order Item Supplied",
|
||||||
"owner": "dhanalekshmi@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC"
|
"sort_order": "DESC"
|
||||||
|
@ -188,11 +188,11 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-10 18:09:33.997618",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Receipt Item Supplied",
|
"name": "Purchase Receipt Item Supplied",
|
||||||
"owner": "wasim@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
@ -178,6 +178,7 @@ def make_all_scorecards(docname):
|
|||||||
period_card = make_supplier_scorecard(docname, None)
|
period_card = make_supplier_scorecard(docname, None)
|
||||||
period_card.start_date = start_date
|
period_card.start_date = start_date
|
||||||
period_card.end_date = end_date
|
period_card.end_date = end_date
|
||||||
|
period_card.insert(ignore_permissions=True)
|
||||||
period_card.submit()
|
period_card.submit()
|
||||||
scp_count = scp_count + 1
|
scp_count = scp_count + 1
|
||||||
if start_date < first_start_date:
|
if start_date < first_start_date:
|
||||||
|
@ -106,7 +106,7 @@ def make_supplier_scorecard(source_name, target_doc=None):
|
|||||||
"doctype": "Supplier Scorecard Scoring Criteria",
|
"doctype": "Supplier Scorecard Scoring Criteria",
|
||||||
"postprocess": update_criteria_fields,
|
"postprocess": update_criteria_fields,
|
||||||
}
|
}
|
||||||
}, target_doc, post_process)
|
}, target_doc, post_process, ignore_permissions=True)
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ from erpnext.accounts.doctype.pricing_rule.utils import (apply_pricing_rule_on_t
|
|||||||
from erpnext.exceptions import InvalidCurrency
|
from erpnext.exceptions import InvalidCurrency
|
||||||
from six import text_type
|
from six import text_type
|
||||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||||
from erpnext.stock.get_item_details import get_item_warehouse
|
from erpnext.stock.get_item_details import get_item_warehouse, _get_item_tax_template, get_item_tax_map
|
||||||
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
|
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
|
||||||
|
|
||||||
force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules")
|
force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules")
|
||||||
@ -1158,6 +1158,18 @@ def get_supplier_block_status(party_name):
|
|||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
def set_child_tax_template_and_map(item, child_item, parent_doc):
|
||||||
|
args = {
|
||||||
|
'item_code': item.item_code,
|
||||||
|
'posting_date': parent_doc.transaction_date,
|
||||||
|
'tax_category': parent_doc.get('tax_category'),
|
||||||
|
'company': parent_doc.get('company')
|
||||||
|
}
|
||||||
|
|
||||||
|
child_item.item_tax_template = _get_item_tax_template(args, item.taxes)
|
||||||
|
if child_item.get("item_tax_template"):
|
||||||
|
child_item.item_tax_rate = get_item_tax_map(parent_doc.get('company'), child_item.item_tax_template, as_json=True)
|
||||||
|
|
||||||
def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
|
def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
|
||||||
"""
|
"""
|
||||||
Returns a Sales Order Item child item containing the default values
|
Returns a Sales Order Item child item containing the default values
|
||||||
@ -1172,6 +1184,7 @@ def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname,
|
|||||||
child_item.uom = trans_item.get("uom") or item.stock_uom
|
child_item.uom = trans_item.get("uom") or item.stock_uom
|
||||||
conversion_factor = flt(get_conversion_factor(item.item_code, child_item.uom).get("conversion_factor"))
|
conversion_factor = flt(get_conversion_factor(item.item_code, child_item.uom).get("conversion_factor"))
|
||||||
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or conversion_factor
|
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or conversion_factor
|
||||||
|
set_child_tax_template_and_map(item, child_item, p_doc)
|
||||||
child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
|
child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
|
||||||
if not child_item.warehouse:
|
if not child_item.warehouse:
|
||||||
frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
|
frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
|
||||||
@ -1195,6 +1208,7 @@ def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docna
|
|||||||
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or conversion_factor
|
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or conversion_factor
|
||||||
child_item.base_rate = 1 # Initiallize value will update in parent validation
|
child_item.base_rate = 1 # Initiallize value will update in parent validation
|
||||||
child_item.base_amount = 1 # Initiallize value will update in parent validation
|
child_item.base_amount = 1 # Initiallize value will update in parent validation
|
||||||
|
set_child_tax_template_and_map(item, child_item, p_doc)
|
||||||
return child_item
|
return child_item
|
||||||
|
|
||||||
def validate_and_delete_children(parent, data):
|
def validate_and_delete_children(parent, data):
|
||||||
@ -1250,7 +1264,10 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
transitions.append(transition.as_dict())
|
transitions.append(transition.as_dict())
|
||||||
|
|
||||||
if not transitions:
|
if not transitions:
|
||||||
frappe.throw(_("You do not have workflow access to update this document."), title=_("Insufficient Workflow Permissions"))
|
frappe.throw(
|
||||||
|
_("You are not allowed to update as per the conditions set in {} Workflow.").format(get_link_to_form("Workflow", workflow)),
|
||||||
|
title=_("Insufficient Permissions")
|
||||||
|
)
|
||||||
|
|
||||||
def get_new_child_item(item_row):
|
def get_new_child_item(item_row):
|
||||||
new_child_function = set_sales_order_defaults if parent_doctype == "Sales Order" else set_purchase_order_defaults
|
new_child_function = set_sales_order_defaults if parent_doctype == "Sales Order" else set_purchase_order_defaults
|
||||||
|
@ -165,9 +165,14 @@ def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
AND company = %(company)s
|
AND company = %(company)s
|
||||||
AND account_currency = %(currency)s
|
AND account_currency = %(currency)s
|
||||||
AND `{searchfield}` LIKE %(txt)s
|
AND `{searchfield}` LIKE %(txt)s
|
||||||
|
{mcond}
|
||||||
ORDER BY idx DESC, name
|
ORDER BY idx DESC, name
|
||||||
LIMIT %(offset)s, %(limit)s
|
LIMIT %(offset)s, %(limit)s
|
||||||
""".format(account_type_condition=account_type_condition, searchfield=searchfield),
|
""".format(
|
||||||
|
account_type_condition=account_type_condition,
|
||||||
|
searchfield=searchfield,
|
||||||
|
mcond=get_match_cond(doctype)
|
||||||
|
),
|
||||||
dict(
|
dict(
|
||||||
account_types=filters.get("account_type"),
|
account_types=filters.get("account_type"),
|
||||||
company=filters.get("company"),
|
company=filters.get("company"),
|
||||||
@ -359,9 +364,21 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
if filters.get("is_return"):
|
if filters.get("is_return"):
|
||||||
having_clause = ""
|
having_clause = ""
|
||||||
|
|
||||||
|
meta = frappe.get_meta("Batch", cached=True)
|
||||||
|
searchfields = meta.get_search_fields()
|
||||||
|
|
||||||
|
search_columns = ''
|
||||||
|
if searchfields:
|
||||||
|
search_columns = ", " + ", ".join(searchfields)
|
||||||
|
|
||||||
if args.get('warehouse'):
|
if args.get('warehouse'):
|
||||||
|
searchfields = ['batch.' + field for field in searchfields]
|
||||||
|
if searchfields:
|
||||||
|
search_columns = ", " + ", ".join(searchfields)
|
||||||
|
|
||||||
batch_nos = frappe.db.sql("""select sle.batch_no, round(sum(sle.actual_qty),2), sle.stock_uom,
|
batch_nos = frappe.db.sql("""select sle.batch_no, round(sum(sle.actual_qty),2), sle.stock_uom,
|
||||||
concat('MFG-',batch.manufacturing_date), concat('EXP-',batch.expiry_date)
|
concat('MFG-',batch.manufacturing_date), concat('EXP-',batch.expiry_date)
|
||||||
|
{search_columns}
|
||||||
from `tabStock Ledger Entry` sle
|
from `tabStock Ledger Entry` sle
|
||||||
INNER JOIN `tabBatch` batch on sle.batch_no = batch.name
|
INNER JOIN `tabBatch` batch on sle.batch_no = batch.name
|
||||||
where
|
where
|
||||||
@ -377,6 +394,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
group by batch_no {having_clause}
|
group by batch_no {having_clause}
|
||||||
order by batch.expiry_date, sle.batch_no desc
|
order by batch.expiry_date, sle.batch_no desc
|
||||||
limit %(start)s, %(page_len)s""".format(
|
limit %(start)s, %(page_len)s""".format(
|
||||||
|
search_columns = search_columns,
|
||||||
cond=cond,
|
cond=cond,
|
||||||
match_conditions=get_match_cond(doctype),
|
match_conditions=get_match_cond(doctype),
|
||||||
having_clause = having_clause
|
having_clause = having_clause
|
||||||
@ -384,7 +402,9 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
|
|
||||||
return batch_nos
|
return batch_nos
|
||||||
else:
|
else:
|
||||||
return frappe.db.sql("""select name, concat('MFG-', manufacturing_date), concat('EXP-',expiry_date) from `tabBatch` batch
|
return frappe.db.sql("""select name, concat('MFG-', manufacturing_date), concat('EXP-',expiry_date)
|
||||||
|
{search_columns}
|
||||||
|
from `tabBatch` batch
|
||||||
where batch.disabled = 0
|
where batch.disabled = 0
|
||||||
and item = %(item_code)s
|
and item = %(item_code)s
|
||||||
and (name like %(txt)s
|
and (name like %(txt)s
|
||||||
@ -394,7 +414,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
{0}
|
{0}
|
||||||
{match_conditions}
|
{match_conditions}
|
||||||
order by expiry_date, name desc
|
order by expiry_date, name desc
|
||||||
limit %(start)s, %(page_len)s""".format(cond, match_conditions=get_match_cond(doctype)), args)
|
limit %(start)s, %(page_len)s""".format(cond, search_columns = search_columns, match_conditions=get_match_cond(doctype)), args)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
@ -81,6 +81,7 @@ class SellingController(StockController):
|
|||||||
party_details = _get_party_details(customer,
|
party_details = _get_party_details(customer,
|
||||||
ignore_permissions=self.flags.ignore_permissions,
|
ignore_permissions=self.flags.ignore_permissions,
|
||||||
doctype=self.doctype, company=self.company,
|
doctype=self.doctype, company=self.company,
|
||||||
|
posting_date=self.get('posting_date'),
|
||||||
fetch_payment_terms_template=fetch_payment_terms_template,
|
fetch_payment_terms_template=fetch_payment_terms_template,
|
||||||
party_address=self.customer_address, shipping_address=self.shipping_address_name)
|
party_address=self.customer_address, shipping_address=self.shipping_address_name)
|
||||||
if not self.meta.get_field("sales_team"):
|
if not self.meta.get_field("sales_team"):
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Reports",
|
"label": "Reports",
|
||||||
"links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Prospects Engaged But Not Converted\",\n \"name\": \"Prospects Engaged But Not Converted\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Opportunity\"\n ],\n \"doctype\": \"Opportunity\",\n \"is_query_report\": true,\n \"label\": \"Minutes to First Response for Opportunity\",\n \"name\": \"Minutes to First Response for Opportunity\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Campaign Efficiency\",\n \"name\": \"Campaign Efficiency\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Owner Efficiency\",\n \"name\": \"Lead Owner Efficiency\",\n \"type\": \"report\"\n }\n]"
|
"links": "[\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Details\",\n \"name\": \"Lead Details\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"icon\": \"fa fa-bar-chart\",\n \"label\": \"Sales Funnel\",\n \"name\": \"sales-funnel\",\n \"onboard\": 1,\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Prospects Engaged But Not Converted\",\n \"name\": \"Prospects Engaged But Not Converted\",\n \"onboard\": 1,\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Opportunity\"\n ],\n \"doctype\": \"Opportunity\",\n \"is_query_report\": true,\n \"label\": \"First Response Time for Opportunity\",\n \"name\": \"First Response Time for Opportunity\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Order\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Inactive Customers\",\n \"name\": \"Inactive Customers\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Campaign Efficiency\",\n \"name\": \"Campaign Efficiency\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Lead\"\n ],\n \"doctype\": \"Lead\",\n \"is_query_report\": true,\n \"label\": \"Lead Owner Efficiency\",\n \"name\": \"Lead Owner Efficiency\",\n \"type\": \"report\"\n }\n]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -42,7 +42,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "CRM",
|
"label": "CRM",
|
||||||
"modified": "2020-05-28 13:33:52.906750",
|
"modified": "2020-08-11 18:55:18.238900",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "CRM",
|
"name": "CRM",
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
"converted_by",
|
"converted_by",
|
||||||
"sales_stage",
|
"sales_stage",
|
||||||
"order_lost_reason",
|
"order_lost_reason",
|
||||||
"mins_to_first_response",
|
"first_response_time",
|
||||||
"expected_closing",
|
"expected_closing",
|
||||||
"next_contact",
|
"next_contact",
|
||||||
"contact_by",
|
"contact_by",
|
||||||
@ -152,13 +152,6 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"bold": 1,
|
|
||||||
"fieldname": "mins_to_first_response",
|
|
||||||
"fieldtype": "Float",
|
|
||||||
"label": "Mins to first response",
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "expected_closing",
|
"fieldname": "expected_closing",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
@ -419,12 +412,19 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Converted By",
|
"label": "Converted By",
|
||||||
"options": "User"
|
"options": "User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bold": 1,
|
||||||
|
"fieldname": "first_response_time",
|
||||||
|
"fieldtype": "Duration",
|
||||||
|
"label": "First Response Time",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-info-sign",
|
"icon": "fa fa-info-sign",
|
||||||
"idx": 195,
|
"idx": 195,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-08-11 17:34:35.066961",
|
"modified": "2020-08-12 17:34:35.066961",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Opportunity",
|
"name": "Opportunity",
|
||||||
|
@ -1,33 +1,44 @@
|
|||||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
frappe.query_reports["Minutes to First Response for Opportunity"] = {
|
frappe.query_reports["First Response Time for Opportunity"] = {
|
||||||
"filters": [
|
"filters": [
|
||||||
{
|
{
|
||||||
"fieldname": "from_date",
|
"fieldname": "from_date",
|
||||||
"label": __("From Date"),
|
"label": __("From Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
'reqd': 1,
|
"reqd": 1,
|
||||||
"default": frappe.datetime.add_days(frappe.datetime.nowdate(), -30)
|
"default": frappe.datetime.add_days(frappe.datetime.nowdate(), -30)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "to_date",
|
"fieldname": "to_date",
|
||||||
"label": __("To Date"),
|
"label": __("To Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
'reqd': 1,
|
"reqd": 1,
|
||||||
"default": frappe.datetime.nowdate()
|
"default": frappe.datetime.nowdate()
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
get_chart_data: function (columns, result) {
|
get_chart_data: function (_columns, result) {
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
labels: result.map(d => d[0]),
|
labels: result.map(d => d[0]),
|
||||||
datasets: [{
|
datasets: [{
|
||||||
name: 'Mins to first response',
|
name: "First Response Time",
|
||||||
values: result.map(d => d[1])
|
values: result.map(d => d[1])
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
type: 'line',
|
type: "line",
|
||||||
|
tooltipOptions: {
|
||||||
|
formatTooltipY: d => {
|
||||||
|
let duration_options = {
|
||||||
|
hide_days: 0,
|
||||||
|
hide_seconds: 0
|
||||||
|
};
|
||||||
|
value = frappe.utils.get_formatted_duration(d, duration_options);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"add_total_row": 0,
|
||||||
|
"creation": "2020-08-10 18:34:19.083872",
|
||||||
|
"disable_prepared_report": 0,
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"letter_head": "Test 2",
|
||||||
|
"modified": "2020-08-10 18:34:19.083872",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "CRM",
|
||||||
|
"name": "First Response Time for Opportunity",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"prepared_report": 0,
|
||||||
|
"ref_doctype": "Opportunity",
|
||||||
|
"report_name": "First Response Time for Opportunity",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Sales User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Sales Manager"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
'fieldname': 'creation_date',
|
||||||
|
'label': 'Date',
|
||||||
|
'fieldtype': 'Date',
|
||||||
|
'width': 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'first_response_time',
|
||||||
|
'fieldtype': 'Duration',
|
||||||
|
'label': 'First Response Time',
|
||||||
|
'width': 300
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
data = frappe.db.sql('''
|
||||||
|
SELECT
|
||||||
|
date(creation) as creation_date,
|
||||||
|
avg(first_response_time) as avg_response_time
|
||||||
|
FROM tabOpportunity
|
||||||
|
WHERE
|
||||||
|
date(creation) between %s and %s
|
||||||
|
and first_response_time > 0
|
||||||
|
GROUP BY creation_date
|
||||||
|
ORDER BY creation_date desc
|
||||||
|
''', (filters.from_date, filters.to_date))
|
||||||
|
|
||||||
|
return columns, data
|
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"add_total_row": 0,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"creation": "2016-06-17 11:28:25.867258",
|
|
||||||
"disabled": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "Report",
|
|
||||||
"idx": 2,
|
|
||||||
"is_standard": "Yes",
|
|
||||||
"modified": "2017-02-24 20:06:08.801109",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "CRM",
|
|
||||||
"name": "Minutes to First Response for Opportunity",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"ref_doctype": "Opportunity",
|
|
||||||
"report_name": "Minutes to First Response for Opportunity",
|
|
||||||
"report_type": "Script Report",
|
|
||||||
"roles": [
|
|
||||||
{
|
|
||||||
"role": "Sales User"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "Sales Manager"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
|
|
||||||
def execute(filters=None):
|
|
||||||
columns = [
|
|
||||||
{
|
|
||||||
'fieldname': 'creation_date',
|
|
||||||
'label': 'Date',
|
|
||||||
'fieldtype': 'Date'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'mins',
|
|
||||||
'fieldtype': 'Float',
|
|
||||||
'label': 'Mins to First Response'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
data = frappe.db.sql('''select date(creation) as creation_date,
|
|
||||||
avg(mins_to_first_response) as mins
|
|
||||||
from tabOpportunity
|
|
||||||
where date(creation) between %s and %s
|
|
||||||
and mins_to_first_response > 0
|
|
||||||
group by creation_date order by creation_date desc''', (filters.from_date, filters.to_date))
|
|
||||||
|
|
||||||
return columns, data
|
|
@ -2,81 +2,90 @@
|
|||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
import plaid
|
||||||
from frappe import _
|
import requests
|
||||||
from frappe.utils.password import get_decrypted_password
|
from plaid.errors import APIError, ItemError, InvalidRequestError
|
||||||
from plaid import Client
|
|
||||||
from plaid.errors import APIError, ItemError
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import requests
|
from frappe import _
|
||||||
|
|
||||||
|
|
||||||
class PlaidConnector():
|
class PlaidConnector():
|
||||||
def __init__(self, access_token=None):
|
def __init__(self, access_token=None):
|
||||||
|
|
||||||
plaid_settings = frappe.get_single("Plaid Settings")
|
|
||||||
|
|
||||||
self.config = {
|
|
||||||
"plaid_client_id": plaid_settings.plaid_client_id,
|
|
||||||
"plaid_secret": get_decrypted_password("Plaid Settings", "Plaid Settings", 'plaid_secret'),
|
|
||||||
"plaid_public_key": plaid_settings.plaid_public_key,
|
|
||||||
"plaid_env": plaid_settings.plaid_env
|
|
||||||
}
|
|
||||||
|
|
||||||
self.client = Client(client_id=self.config.get("plaid_client_id"),
|
|
||||||
secret=self.config.get("plaid_secret"),
|
|
||||||
public_key=self.config.get("plaid_public_key"),
|
|
||||||
environment=self.config.get("plaid_env")
|
|
||||||
)
|
|
||||||
|
|
||||||
self.access_token = access_token
|
self.access_token = access_token
|
||||||
|
self.settings = frappe.get_single("Plaid Settings")
|
||||||
|
self.products = ["auth", "transactions"]
|
||||||
|
self.client_name = frappe.local.site
|
||||||
|
self.client = plaid.Client(
|
||||||
|
client_id=self.settings.plaid_client_id,
|
||||||
|
secret=self.settings.get_password("plaid_secret"),
|
||||||
|
environment=self.settings.plaid_env,
|
||||||
|
api_version="2019-05-29"
|
||||||
|
)
|
||||||
|
|
||||||
def get_access_token(self, public_token):
|
def get_access_token(self, public_token):
|
||||||
if public_token is None:
|
if public_token is None:
|
||||||
frappe.log_error(_("Public token is missing for this bank"), _("Plaid public token error"))
|
frappe.log_error(_("Public token is missing for this bank"), _("Plaid public token error"))
|
||||||
|
|
||||||
response = self.client.Item.public_token.exchange(public_token)
|
response = self.client.Item.public_token.exchange(public_token)
|
||||||
access_token = response['access_token']
|
access_token = response["access_token"]
|
||||||
|
|
||||||
return access_token
|
return access_token
|
||||||
|
|
||||||
|
def get_link_token(self):
|
||||||
|
token_request = {
|
||||||
|
"client_name": self.client_name,
|
||||||
|
"client_id": self.settings.plaid_client_id,
|
||||||
|
"secret": self.settings.plaid_secret,
|
||||||
|
"products": self.products,
|
||||||
|
# only allow Plaid-supported languages and countries (LAST: Sep-19-2020)
|
||||||
|
"language": frappe.local.lang if frappe.local.lang in ["en", "fr", "es", "nl"] else "en",
|
||||||
|
"country_codes": ["US", "CA", "FR", "IE", "NL", "ES", "GB"],
|
||||||
|
"user": {
|
||||||
|
"client_user_id": frappe.generate_hash(frappe.session.user, length=32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = self.client.LinkToken.create(token_request)
|
||||||
|
except InvalidRequestError:
|
||||||
|
frappe.log_error(frappe.get_traceback(), _("Plaid invalid request error"))
|
||||||
|
frappe.msgprint(_("Please check your Plaid client ID and secret values"))
|
||||||
|
except APIError as e:
|
||||||
|
frappe.log_error(frappe.get_traceback(), _("Plaid authentication error"))
|
||||||
|
frappe.throw(_(str(e)), title=_("Authentication Failed"))
|
||||||
|
else:
|
||||||
|
return response["link_token"]
|
||||||
|
|
||||||
def auth(self):
|
def auth(self):
|
||||||
try:
|
try:
|
||||||
self.client.Auth.get(self.access_token)
|
self.client.Auth.get(self.access_token)
|
||||||
print("Authentication successful.....")
|
|
||||||
except ItemError as e:
|
except ItemError as e:
|
||||||
if e.code == 'ITEM_LOGIN_REQUIRED':
|
if e.code == "ITEM_LOGIN_REQUIRED":
|
||||||
pass
|
|
||||||
else:
|
|
||||||
pass
|
pass
|
||||||
except APIError as e:
|
except APIError as e:
|
||||||
if e.code == 'PLANNED_MAINTENANCE':
|
if e.code == "PLANNED_MAINTENANCE":
|
||||||
pass
|
|
||||||
else:
|
|
||||||
pass
|
pass
|
||||||
except requests.Timeout:
|
except requests.Timeout:
|
||||||
pass
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
|
||||||
frappe.log_error(frappe.get_traceback(), _("Plaid authentication error"))
|
frappe.log_error(frappe.get_traceback(), _("Plaid authentication error"))
|
||||||
frappe.msgprint({"title": _("Authentication Failed"), "message":e, "raise_exception":1, "indicator":'red'})
|
frappe.throw(_(str(e)), title=_("Authentication Failed"))
|
||||||
|
|
||||||
def get_transactions(self, start_date, end_date, account_id=None):
|
def get_transactions(self, start_date, end_date, account_id=None):
|
||||||
try:
|
|
||||||
self.auth()
|
self.auth()
|
||||||
|
kwargs = dict(
|
||||||
|
access_token=self.access_token,
|
||||||
|
start_date=start_date,
|
||||||
|
end_date=end_date
|
||||||
|
)
|
||||||
if account_id:
|
if account_id:
|
||||||
account_ids = [account_id]
|
kwargs.update(dict(account_ids=[account_id]))
|
||||||
|
|
||||||
response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, account_ids=account_ids)
|
try:
|
||||||
|
response = self.client.Transactions.get(**kwargs)
|
||||||
else:
|
transactions = response["transactions"]
|
||||||
response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date)
|
while len(transactions) < response["total_transactions"]:
|
||||||
|
|
||||||
transactions = response['transactions']
|
|
||||||
|
|
||||||
while len(transactions) < response['total_transactions']:
|
|
||||||
response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, offset=len(transactions))
|
response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, offset=len(transactions))
|
||||||
transactions.extend(response['transactions'])
|
transactions.extend(response["transactions"])
|
||||||
return transactions
|
return transactions
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
|
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
|
||||||
|
@ -7,9 +7,9 @@ frappe.ui.form.on('Plaid Settings', {
|
|||||||
enabled: function (frm) {
|
enabled: function (frm) {
|
||||||
frm.toggle_reqd('plaid_client_id', frm.doc.enabled);
|
frm.toggle_reqd('plaid_client_id', frm.doc.enabled);
|
||||||
frm.toggle_reqd('plaid_secret', frm.doc.enabled);
|
frm.toggle_reqd('plaid_secret', frm.doc.enabled);
|
||||||
frm.toggle_reqd('plaid_public_key', frm.doc.enabled);
|
|
||||||
frm.toggle_reqd('plaid_env', frm.doc.enabled);
|
frm.toggle_reqd('plaid_env', frm.doc.enabled);
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function (frm) {
|
refresh: function (frm) {
|
||||||
if (frm.doc.enabled) {
|
if (frm.doc.enabled) {
|
||||||
frm.add_custom_button('Link a new bank account', () => {
|
frm.add_custom_button('Link a new bank account', () => {
|
||||||
@ -22,17 +22,16 @@ frappe.ui.form.on('Plaid Settings', {
|
|||||||
erpnext.integrations.plaidLink = class plaidLink {
|
erpnext.integrations.plaidLink = class plaidLink {
|
||||||
constructor(parent) {
|
constructor(parent) {
|
||||||
this.frm = parent;
|
this.frm = parent;
|
||||||
this.product = ["transactions", "auth"];
|
|
||||||
this.plaidUrl = 'https://cdn.plaid.com/link/v2/stable/link-initialize.js';
|
this.plaidUrl = 'https://cdn.plaid.com/link/v2/stable/link-initialize.js';
|
||||||
this.init_config();
|
this.init_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
init_config() {
|
async init_config() {
|
||||||
const me = this;
|
this.product = ["auth", "transactions"];
|
||||||
me.plaid_env = me.frm.doc.plaid_env;
|
this.plaid_env = this.frm.doc.plaid_env;
|
||||||
me.plaid_public_key = me.frm.doc.plaid_public_key;
|
this.client_name = frappe.boot.sitename;
|
||||||
me.client_name = frappe.boot.sitename;
|
this.token = await this.frm.call("get_link_token").then(resp => resp.message);
|
||||||
me.init_plaid();
|
this.init_plaid();
|
||||||
}
|
}
|
||||||
|
|
||||||
init_plaid() {
|
init_plaid() {
|
||||||
@ -69,17 +68,17 @@ erpnext.integrations.plaidLink = class plaidLink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onScriptLoaded(me) {
|
onScriptLoaded(me) {
|
||||||
me.linkHandler = window.Plaid.create({
|
me.linkHandler = Plaid.create({
|
||||||
clientName: me.client_name,
|
clientName: me.client_name,
|
||||||
|
product: me.product,
|
||||||
env: me.plaid_env,
|
env: me.plaid_env,
|
||||||
key: me.plaid_public_key,
|
token: me.token,
|
||||||
onSuccess: me.plaid_success,
|
onSuccess: me.plaid_success
|
||||||
product: me.product
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onScriptError(error) {
|
onScriptError(error) {
|
||||||
frappe.msgprint('There was an issue loading the link-initialize.js script');
|
frappe.msgprint("There was an issue connecting to Plaid's authentication server");
|
||||||
frappe.msgprint(error);
|
frappe.msgprint(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,12 +93,16 @@ erpnext.integrations.plaidLink = class plaidLink {
|
|||||||
reqd: 1
|
reqd: 1
|
||||||
}, (data) => {
|
}, (data) => {
|
||||||
me.company = data.company;
|
me.company = data.company;
|
||||||
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_institution', {token: token, response: response})
|
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_institution', {
|
||||||
.then((result) => {
|
token: token,
|
||||||
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_bank_accounts', {response: response,
|
response: response
|
||||||
bank: result, company: me.company});
|
}).then((result) => {
|
||||||
})
|
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_bank_accounts', {
|
||||||
.then(() => {
|
response: response,
|
||||||
|
bank: result,
|
||||||
|
company: me.company
|
||||||
|
});
|
||||||
|
}).then(() => {
|
||||||
frappe.show_alert({ message: __("Bank accounts added"), indicator: 'green' });
|
frappe.show_alert({ message: __("Bank accounts added"), indicator: 'green' });
|
||||||
});
|
});
|
||||||
}, __("Select a company"), __("Continue"));
|
}, __("Select a company"), __("Continue"));
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"actions": [],
|
|
||||||
"creation": "2018-10-25 10:02:48.656165",
|
"creation": "2018-10-25 10:02:48.656165",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
@ -12,7 +11,6 @@
|
|||||||
"plaid_client_id",
|
"plaid_client_id",
|
||||||
"plaid_secret",
|
"plaid_secret",
|
||||||
"column_break_7",
|
"column_break_7",
|
||||||
"plaid_public_key",
|
|
||||||
"plaid_env"
|
"plaid_env"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
@ -41,12 +39,6 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Plaid Secret"
|
"label": "Plaid Secret"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "plaid_public_key",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Plaid Public Key"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "plaid_env",
|
"fieldname": "plaid_env",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
@ -69,8 +61,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"modified": "2020-09-12 02:31:44.542385",
|
||||||
"modified": "2020-02-07 15:21:11.616231",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "ERPNext Integrations",
|
"module": "ERPNext Integrations",
|
||||||
"name": "Plaid Settings",
|
"name": "Plaid Settings",
|
||||||
|
@ -2,37 +2,44 @@
|
|||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
import json
|
import json
|
||||||
from frappe import _
|
|
||||||
from frappe.model.document import Document
|
import frappe
|
||||||
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
|
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
|
||||||
from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_connector import PlaidConnector
|
from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_connector import PlaidConnector
|
||||||
from frappe.utils import getdate, formatdate, today, add_months
|
from frappe import _
|
||||||
from frappe.desk.doctype.tag.tag import add_tag
|
from frappe.desk.doctype.tag.tag import add_tag
|
||||||
|
from frappe.model.document import Document
|
||||||
|
from frappe.utils import add_months, formatdate, getdate, today
|
||||||
|
|
||||||
|
|
||||||
class PlaidSettings(Document):
|
class PlaidSettings(Document):
|
||||||
pass
|
@staticmethod
|
||||||
|
def get_link_token():
|
||||||
|
plaid = PlaidConnector()
|
||||||
|
return plaid.get_link_token()
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def plaid_configuration():
|
def get_plaid_configuration():
|
||||||
if frappe.db.get_single_value("Plaid Settings", "enabled"):
|
if frappe.db.get_single_value("Plaid Settings", "enabled"):
|
||||||
plaid_settings = frappe.get_single("Plaid Settings")
|
plaid_settings = frappe.get_single("Plaid Settings")
|
||||||
return {
|
return {
|
||||||
"plaid_public_key": plaid_settings.plaid_public_key,
|
|
||||||
"plaid_env": plaid_settings.plaid_env,
|
"plaid_env": plaid_settings.plaid_env,
|
||||||
|
"link_token": plaid_settings.get_link_token(),
|
||||||
"client_name": frappe.local.site
|
"client_name": frappe.local.site
|
||||||
}
|
}
|
||||||
else:
|
|
||||||
return "disabled"
|
return "disabled"
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def add_institution(token, response):
|
def add_institution(token, response):
|
||||||
response = json.loads(response)
|
response = json.loads(response)
|
||||||
|
|
||||||
plaid = PlaidConnector()
|
plaid = PlaidConnector()
|
||||||
access_token = plaid.get_access_token(token)
|
access_token = plaid.get_access_token(token)
|
||||||
|
bank = None
|
||||||
|
|
||||||
if not frappe.db.exists("Bank", response["institution"]["name"]):
|
if not frappe.db.exists("Bank", response["institution"]["name"]):
|
||||||
try:
|
try:
|
||||||
@ -44,7 +51,6 @@ def add_institution(token, response):
|
|||||||
bank.insert()
|
bank.insert()
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.throw(frappe.get_traceback())
|
frappe.throw(frappe.get_traceback())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
bank = frappe.get_doc("Bank", response["institution"]["name"])
|
bank = frappe.get_doc("Bank", response["institution"]["name"])
|
||||||
bank.plaid_access_token = access_token
|
bank.plaid_access_token = access_token
|
||||||
@ -52,6 +58,7 @@ def add_institution(token, response):
|
|||||||
|
|
||||||
return bank
|
return bank
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def add_bank_accounts(response, bank, company):
|
def add_bank_accounts(response, bank, company):
|
||||||
try:
|
try:
|
||||||
@ -92,9 +99,8 @@ def add_bank_accounts(response, bank, company):
|
|||||||
new_account.insert()
|
new_account.insert()
|
||||||
|
|
||||||
result.append(new_account.name)
|
result.append(new_account.name)
|
||||||
|
|
||||||
except frappe.UniqueValidationError:
|
except frappe.UniqueValidationError:
|
||||||
frappe.msgprint(_("Bank account {0} already exists and could not be created again").format(new_account.account_name))
|
frappe.msgprint(_("Bank account {0} already exists and could not be created again").format(account["name"]))
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.throw(frappe.get_traceback())
|
frappe.throw(frappe.get_traceback())
|
||||||
|
|
||||||
@ -103,6 +109,7 @@ def add_bank_accounts(response, bank, company):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def add_account_type(account_type):
|
def add_account_type(account_type):
|
||||||
try:
|
try:
|
||||||
frappe.get_doc({
|
frappe.get_doc({
|
||||||
@ -122,10 +129,11 @@ def add_account_subtype(account_subtype):
|
|||||||
except Exception:
|
except Exception:
|
||||||
frappe.throw(frappe.get_traceback())
|
frappe.throw(frappe.get_traceback())
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def sync_transactions(bank, bank_account):
|
def sync_transactions(bank, bank_account):
|
||||||
'''Sync transactions based on the last integration date as the start date, after the sync is completed
|
"""Sync transactions based on the last integration date as the start date, after sync is completed
|
||||||
add the transaction date of the oldest transaction as the last integration date'''
|
add the transaction date of the oldest transaction as the last integration date."""
|
||||||
last_transaction_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date")
|
last_transaction_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date")
|
||||||
if last_transaction_date:
|
if last_transaction_date:
|
||||||
start_date = formatdate(last_transaction_date, "YYYY-MM-dd")
|
start_date = formatdate(last_transaction_date, "YYYY-MM-dd")
|
||||||
@ -147,10 +155,10 @@ def sync_transactions(bank, bank_account):
|
|||||||
len(result), bank_account, start_date, end_date))
|
len(result), bank_account, start_date, end_date))
|
||||||
|
|
||||||
frappe.db.set_value("Bank Account", bank_account, "last_integration_date", last_transaction_date)
|
frappe.db.set_value("Bank Account", bank_account, "last_integration_date", last_transaction_date)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
|
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
|
||||||
|
|
||||||
|
|
||||||
def get_transactions(bank, bank_account=None, start_date=None, end_date=None):
|
def get_transactions(bank, bank_account=None, start_date=None, end_date=None):
|
||||||
access_token = None
|
access_token = None
|
||||||
|
|
||||||
@ -168,6 +176,7 @@ def get_transactions(bank, bank_account=None, start_date=None, end_date=None):
|
|||||||
|
|
||||||
return transactions
|
return transactions
|
||||||
|
|
||||||
|
|
||||||
def new_bank_transaction(transaction):
|
def new_bank_transaction(transaction):
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
@ -182,8 +191,8 @@ def new_bank_transaction(transaction):
|
|||||||
|
|
||||||
status = "Pending" if transaction["pending"] == "True" else "Settled"
|
status = "Pending" if transaction["pending"] == "True" else "Settled"
|
||||||
|
|
||||||
try:
|
|
||||||
tags = []
|
tags = []
|
||||||
|
try:
|
||||||
tags += transaction["category"]
|
tags += transaction["category"]
|
||||||
tags += ["Plaid Cat. {}".format(transaction["category_id"])]
|
tags += ["Plaid Cat. {}".format(transaction["category_id"])]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@ -216,6 +225,7 @@ def new_bank_transaction(transaction):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def automatic_synchronization():
|
def automatic_synchronization():
|
||||||
settings = frappe.get_doc("Plaid Settings", "Plaid Settings")
|
settings = frappe.get_doc("Plaid Settings", "Plaid Settings")
|
||||||
|
|
||||||
@ -223,4 +233,8 @@ def automatic_synchronization():
|
|||||||
plaid_accounts = frappe.get_all("Bank Account", filters={"integration_id": ["!=", ""]}, fields=["name", "bank"])
|
plaid_accounts = frappe.get_all("Bank Account", filters={"integration_id": ["!=", ""]}, fields=["name", "bank"])
|
||||||
|
|
||||||
for plaid_account in plaid_accounts:
|
for plaid_account in plaid_accounts:
|
||||||
frappe.enqueue("erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions", bank=plaid_account.bank, bank_account=plaid_account.name)
|
frappe.enqueue(
|
||||||
|
"erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions",
|
||||||
|
bank=plaid_account.bank,
|
||||||
|
bank_account=plaid_account.name
|
||||||
|
)
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
import frappe
|
|
||||||
from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings import plaid_configuration, add_account_type, add_account_subtype, new_bank_transaction, add_bank_accounts
|
|
||||||
import json
|
import json
|
||||||
from frappe.utils.response import json_handler
|
import unittest
|
||||||
|
|
||||||
|
import frappe
|
||||||
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
|
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
|
||||||
|
from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings import (
|
||||||
|
add_account_subtype, add_account_type, add_bank_accounts,
|
||||||
|
new_bank_transaction, get_plaid_configuration)
|
||||||
|
from frappe.utils.response import json_handler
|
||||||
|
|
||||||
|
|
||||||
class TestPlaidSettings(unittest.TestCase):
|
class TestPlaidSettings(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -31,7 +34,7 @@ class TestPlaidSettings(unittest.TestCase):
|
|||||||
|
|
||||||
def test_plaid_disabled(self):
|
def test_plaid_disabled(self):
|
||||||
frappe.db.set_value("Plaid Settings", None, "enabled", 0)
|
frappe.db.set_value("Plaid Settings", None, "enabled", 0)
|
||||||
self.assertTrue(plaid_configuration() == "disabled")
|
self.assertTrue(get_plaid_configuration() == "disabled")
|
||||||
|
|
||||||
def test_add_account_type(self):
|
def test_add_account_type(self):
|
||||||
add_account_type("brokerage")
|
add_account_type("brokerage")
|
||||||
|
@ -258,8 +258,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"modified": "2020-05-28 12:32:11.384757",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "umair@erpnext.com",
|
"modified_by": "Administrator",
|
||||||
"module": "ERPNext Integrations",
|
"module": "ERPNext Integrations",
|
||||||
"name": "Shopify Settings",
|
"name": "Shopify Settings",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
|
@ -117,12 +117,12 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-05-08 13:45:57.226530",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Healthcare",
|
"module": "Healthcare",
|
||||||
"name": "Healthcare Schedule Time Slot",
|
"name": "Healthcare Schedule Time Slot",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
"owner": "rmehta@gmail.com",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
|
@ -44,11 +44,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-01-31 12:21:45.975488",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Healthcare",
|
"module": "Healthcare",
|
||||||
"name": "Practitioner Schedule",
|
"name": "Practitioner Schedule",
|
||||||
"owner": "rmehta@gmail.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"create": 1,
|
"create": 1,
|
||||||
|
@ -282,6 +282,11 @@ auto_cancel_exempted_doctypes= [
|
|||||||
]
|
]
|
||||||
|
|
||||||
scheduler_events = {
|
scheduler_events = {
|
||||||
|
"cron": {
|
||||||
|
"0/30 * * * *": [
|
||||||
|
"erpnext.utilities.doctype.video.video.update_youtube_data",
|
||||||
|
]
|
||||||
|
},
|
||||||
"all": [
|
"all": [
|
||||||
"erpnext.projects.doctype.project.project.project_status_update_reminder",
|
"erpnext.projects.doctype.project.project.project_status_update_reminder",
|
||||||
"erpnext.healthcare.doctype.patient_appointment.patient_appointment.send_appointment_reminder",
|
"erpnext.healthcare.doctype.patient_appointment.patient_appointment.send_appointment_reminder",
|
||||||
|
@ -696,11 +696,11 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2019-01-30 11:28:08.401459",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Appraisal",
|
"name": "Appraisal",
|
||||||
"owner": "ashwini@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
|
@ -207,11 +207,11 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-07-11 03:27:57.897071",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Appraisal Goal",
|
"name": "Appraisal Goal",
|
||||||
"owner": "ashwini@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 0,
|
"quick_entry": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
|
@ -113,11 +113,11 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-12-13 12:37:56.937023",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Appraisal Template",
|
"name": "Appraisal Template",
|
||||||
"owner": "ashwini@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
|
@ -78,11 +78,11 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-07-11 03:27:57.979215",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Appraisal Template Goal",
|
"name": "Appraisal Template Goal",
|
||||||
"owner": "ashwini@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 0,
|
"quick_entry": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
|
@ -205,11 +205,11 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-05-29 13:51:37.177231",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Attendance",
|
"name": "Attendance",
|
||||||
"owner": "ashwini@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
|
@ -371,12 +371,12 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-06-15 12:43:04.099803",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Expense Claim",
|
"name": "Expense Claim",
|
||||||
"name_case": "Title Case",
|
"name_case": "Title Case",
|
||||||
"owner": "harshada@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
|
@ -120,11 +120,11 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-05-11 18:54:35.601592",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Expense Claim Detail",
|
"name": "Expense Claim Detail",
|
||||||
"owner": "harshada@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC"
|
"sort_order": "DESC"
|
||||||
|
@ -48,11 +48,11 @@
|
|||||||
"icon": "fa fa-flag",
|
"icon": "fa fa-flag",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2019-12-11 13:38:59.534034",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Expense Claim Type",
|
"name": "Expense Claim Type",
|
||||||
"owner": "harshada@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"create": 1,
|
"create": 1,
|
||||||
|
@ -229,11 +229,11 @@
|
|||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 1,
|
"max_attachments": 1,
|
||||||
"modified": "2017-11-14 12:51:34.980103",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Upload Attendance",
|
"name": "Upload Attendance",
|
||||||
"owner": "harshada@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
|
@ -40,8 +40,8 @@
|
|||||||
"mapping_name": "Company to Hub Company",
|
"mapping_name": "Company to Hub Company",
|
||||||
"mapping_type": "Push",
|
"mapping_type": "Push",
|
||||||
"migration_id_field": "hub_sync_id",
|
"migration_id_field": "hub_sync_id",
|
||||||
"modified": "2018-02-14 15:57:05.571142",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "achilles@erpnext.com",
|
"modified_by": "Administrator",
|
||||||
"name": "Company to Hub Company",
|
"name": "Company to Hub Company",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"page_length": 10,
|
"page_length": 10,
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
"mapping_name": "Hub Message to Lead",
|
"mapping_name": "Hub Message to Lead",
|
||||||
"mapping_type": "Pull",
|
"mapping_type": "Pull",
|
||||||
"migration_id_field": "hub_sync_id",
|
"migration_id_field": "hub_sync_id",
|
||||||
"modified": "2018-02-14 15:57:05.606597",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "achilles@erpnext.com",
|
"modified_by": "Administrator",
|
||||||
"name": "Hub Message to Lead",
|
"name": "Hub Message to Lead",
|
||||||
"owner": "frappetest@gmail.com",
|
"owner": "Administrator",
|
||||||
"page_length": 10,
|
"page_length": 10,
|
||||||
"remote_objectname": "Hub Message",
|
"remote_objectname": "Hub Message",
|
||||||
"remote_primary_key": "name"
|
"remote_primary_key": "name"
|
||||||
|
@ -121,8 +121,8 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-09-01 13:56:07.816894",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "netchamp@rawcoderz.com",
|
"modified_by": "Administrator",
|
||||||
"module": "Hub Node",
|
"module": "Hub Node",
|
||||||
"name": "Hub User",
|
"name": "Hub User",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
|
@ -54,12 +54,12 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-03-06 04:41:17.916243",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Hub Node",
|
"module": "Hub Node",
|
||||||
"name": "Hub Users",
|
"name": "Hub Users",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
"owner": "test1@example.com",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
|
@ -352,12 +352,12 @@
|
|||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2019-02-01 14:21:16.729848",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Hub Node",
|
"module": "Hub Node",
|
||||||
"name": "Marketplace Settings",
|
"name": "Marketplace Settings",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
"owner": "netchamp@rawcoderz.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
|
@ -813,7 +813,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-08-21 14:44:33.670332",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Maintenance",
|
"module": "Maintenance",
|
||||||
"name": "Maintenance Schedule",
|
"name": "Maintenance Schedule",
|
||||||
|
@ -1001,11 +1001,11 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2020-07-15 14:44:44.911402",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Maintenance",
|
"module": "Maintenance",
|
||||||
"name": "Maintenance Visit",
|
"name": "Maintenance Visit",
|
||||||
"owner": "ashwini@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
|
@ -125,11 +125,11 @@
|
|||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-10-03 14:55:52.786805",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Maintenance",
|
"module": "Maintenance",
|
||||||
"name": "Maintenance Visit Purpose",
|
"name": "Maintenance Visit Purpose",
|
||||||
"owner": "ashwini@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
@ -1,336 +1,105 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "field:email",
|
"autoname": "field:email",
|
||||||
"beta": 0,
|
|
||||||
"creation": "2017-09-19 16:20:27.510196",
|
"creation": "2017-09-19 16:20:27.510196",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"donor_name",
|
||||||
|
"column_break_5",
|
||||||
|
"donor_type",
|
||||||
|
"email",
|
||||||
|
"image",
|
||||||
|
"address_contacts",
|
||||||
|
"address_html",
|
||||||
|
"column_break_9",
|
||||||
|
"contact_html"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "donor_name",
|
"fieldname": "donor_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Donor Name",
|
"label": "Donor Name",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_5",
|
"fieldname": "column_break_5",
|
||||||
"fieldtype": "Column Break",
|
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "donor_type",
|
"fieldname": "donor_type",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Donor Type",
|
"label": "Donor Type",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Donor Type",
|
"options": "Donor Type",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "email",
|
"fieldname": "email",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Email",
|
"label": "Email",
|
||||||
"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,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"unique": 1
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "image",
|
"fieldname": "image",
|
||||||
"fieldtype": "Attach Image",
|
"fieldtype": "Attach Image",
|
||||||
"hidden": 1,
|
"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",
|
"label": "Image",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"permlevel": 0,
|
"print_hide": 1
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"depends_on": "eval:!doc.__islocal;",
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "address_contacts",
|
"fieldname": "address_contacts",
|
||||||
"fieldtype": "Section Break",
|
"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",
|
"label": "Address and Contact",
|
||||||
"length": 0,
|
"options": "fa fa-map-marker"
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "address_html",
|
"fieldname": "address_html",
|
||||||
"fieldtype": "HTML",
|
"fieldtype": "HTML",
|
||||||
"hidden": 0,
|
"label": "Address HTML"
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_9",
|
"fieldname": "column_break_9",
|
||||||
"fieldtype": "Column Break",
|
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "contact_html",
|
"fieldname": "contact_html",
|
||||||
"fieldtype": "HTML",
|
"fieldtype": "HTML",
|
||||||
"hidden": 0,
|
"label": "Contact HTML"
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"image_view": 0,
|
"links": [],
|
||||||
"in_create": 0,
|
"modified": "2020-09-16 23:46:04.083274",
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-01-22 15:53:35.059946",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Non Profit",
|
"module": "Non Profit",
|
||||||
"name": "Donor",
|
"name": "Donor",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Non Profit Manager",
|
"role": "Non Profit Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"restrict_to_domain": "Non Profit",
|
"restrict_to_domain": "Non Profit",
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "donor_name",
|
"title_field": "donor_name",
|
||||||
"track_changes": 1,
|
"track_changes": 1
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
@ -111,6 +111,7 @@
|
|||||||
"options": "Supplier"
|
"options": "Supplier"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:!doc.__islocal;",
|
||||||
"fieldname": "address_contacts",
|
"fieldname": "address_contacts",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Address and Contact",
|
"label": "Address and Contact",
|
||||||
@ -177,7 +178,7 @@
|
|||||||
],
|
],
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-08-06 10:06:01.153564",
|
"modified": "2020-09-16 23:44:13.596948",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Non Profit",
|
"module": "Non Profit",
|
||||||
"name": "Member",
|
"name": "Member",
|
||||||
|
@ -90,9 +90,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "currency",
|
"fieldname": "currency",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Link",
|
||||||
"label": "Currency",
|
"label": "Currency",
|
||||||
"options": "USD\nINR"
|
"options": "Currency"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "amount",
|
"fieldname": "amount",
|
||||||
@ -126,7 +126,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-07-31 13:57:02.328995",
|
"modified": "2020-09-19 14:28:11.532696",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Non Profit",
|
"module": "Non Profit",
|
||||||
"name": "Membership",
|
"name": "Membership",
|
||||||
|
@ -1,580 +1,148 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "field:email",
|
"autoname": "field:email",
|
||||||
"beta": 0,
|
|
||||||
"creation": "2017-09-19 16:16:45.676019",
|
"creation": "2017-09-19 16:16:45.676019",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"volunteer_name",
|
||||||
|
"column_break_5",
|
||||||
|
"volunteer_type",
|
||||||
|
"email",
|
||||||
|
"image",
|
||||||
|
"address_contacts",
|
||||||
|
"address_html",
|
||||||
|
"column_break_9",
|
||||||
|
"contact_html",
|
||||||
|
"volunteer_availability_and_skills_details",
|
||||||
|
"availability",
|
||||||
|
"availability_timeslot",
|
||||||
|
"column_break_12",
|
||||||
|
"volunteer_skills",
|
||||||
|
"section_break_15",
|
||||||
|
"note"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "volunteer_name",
|
"fieldname": "volunteer_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Volunteer Name",
|
"label": "Volunteer Name",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_5",
|
"fieldname": "column_break_5",
|
||||||
"fieldtype": "Column Break",
|
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "volunteer_type",
|
"fieldname": "volunteer_type",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Volunteer Type",
|
"label": "Volunteer Type",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Volunteer Type",
|
"options": "Volunteer Type",
|
||||||
"permlevel": 0,
|
"reqd": 1
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "email",
|
"fieldname": "email",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Email",
|
"label": "Email",
|
||||||
"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,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 1
|
"unique": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "image",
|
"fieldname": "image",
|
||||||
"fieldtype": "Attach Image",
|
"fieldtype": "Attach Image",
|
||||||
"hidden": 1,
|
"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",
|
"label": "Image",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"permlevel": 0,
|
"print_hide": 1
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"depends_on": "eval:!doc.__islocal;",
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "address_contacts",
|
"fieldname": "address_contacts",
|
||||||
"fieldtype": "Section Break",
|
"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",
|
"label": "Address and Contact",
|
||||||
"length": 0,
|
"options": "fa fa-map-marker"
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "address_html",
|
"fieldname": "address_html",
|
||||||
"fieldtype": "HTML",
|
"fieldtype": "HTML",
|
||||||
"hidden": 0,
|
"label": "Address HTML"
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_9",
|
"fieldname": "column_break_9",
|
||||||
"fieldtype": "Column Break",
|
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "contact_html",
|
"fieldname": "contact_html",
|
||||||
"fieldtype": "HTML",
|
"fieldtype": "HTML",
|
||||||
"hidden": 0,
|
"label": "Contact HTML"
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "volunteer_availability_and_skills_details",
|
"fieldname": "volunteer_availability_and_skills_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Availability and Skills"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Availability and Skills",
|
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "availability",
|
"fieldname": "availability",
|
||||||
"fieldtype": "Select",
|
"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": "Availability",
|
"label": "Availability",
|
||||||
"length": 0,
|
"options": "\nWeekly\nWeekdays\nWeekends"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "\nWeekly\nWeekdays\nWeekends",
|
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "availability_timeslot",
|
"fieldname": "availability_timeslot",
|
||||||
"fieldtype": "Select",
|
"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": "Availability Timeslot",
|
"label": "Availability Timeslot",
|
||||||
"length": 0,
|
"options": "\nMorning\nAfternoon\nEvening\nAnytime"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "\nMorning\nAfternoon\nEvening\nAnytime",
|
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_12",
|
"fieldname": "column_break_12",
|
||||||
"fieldtype": "Column Break",
|
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "volunteer_skills",
|
"fieldname": "volunteer_skills",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"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": "Volunteer Skills",
|
"label": "Volunteer Skills",
|
||||||
"length": 0,
|
"options": "Volunteer Skill"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Volunteer Skill",
|
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_15",
|
"fieldname": "section_break_15",
|
||||||
"fieldtype": "Section Break",
|
"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,
|
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "note",
|
"fieldname": "note",
|
||||||
"fieldtype": "Long Text",
|
"fieldtype": "Long Text",
|
||||||
"hidden": 0,
|
"label": "Note"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Note",
|
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"image_view": 0,
|
"links": [],
|
||||||
"in_create": 0,
|
"modified": "2020-09-16 23:45:15.595952",
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-11-04 03:36:25.776211",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Non Profit",
|
"module": "Non Profit",
|
||||||
"name": "Volunteer",
|
"name": "Volunteer",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Non Profit Manager",
|
"role": "Non Profit Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"restrict_to_domain": "Non Profit",
|
"restrict_to_domain": "Non Profit",
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "volunteer_name",
|
"title_field": "volunteer_name",
|
||||||
"track_changes": 1,
|
"track_changes": 1
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -690,6 +690,7 @@ erpnext.patches.v12_0.set_valid_till_date_in_supplier_quotation
|
|||||||
erpnext.patches.v13_0.update_old_loans
|
erpnext.patches.v13_0.update_old_loans
|
||||||
erpnext.patches.v12_0.set_serial_no_status #2020-05-21
|
erpnext.patches.v12_0.set_serial_no_status #2020-05-21
|
||||||
erpnext.patches.v12_0.update_price_list_currency_in_bom
|
erpnext.patches.v12_0.update_price_list_currency_in_bom
|
||||||
|
execute:frappe.reload_doctype('Dashboard')
|
||||||
execute:frappe.delete_doc_if_exists('Dashboard', 'Accounts')
|
execute:frappe.delete_doc_if_exists('Dashboard', 'Accounts')
|
||||||
erpnext.patches.v13_0.update_actual_start_and_end_date_in_wo
|
erpnext.patches.v13_0.update_actual_start_and_end_date_in_wo
|
||||||
erpnext.patches.v13_0.set_company_field_in_healthcare_doctypes #2020-05-25
|
erpnext.patches.v13_0.set_company_field_in_healthcare_doctypes #2020-05-25
|
||||||
@ -725,4 +726,6 @@ erpnext.patches.v12_0.rename_lost_reason_detail
|
|||||||
erpnext.patches.v13_0.drop_razorpay_payload_column
|
erpnext.patches.v13_0.drop_razorpay_payload_column
|
||||||
erpnext.patches.v13_0.update_start_end_date_for_old_shift_assignment
|
erpnext.patches.v13_0.update_start_end_date_for_old_shift_assignment
|
||||||
erpnext.patches.v13_0.setting_custom_roles_for_some_regional_reports
|
erpnext.patches.v13_0.setting_custom_roles_for_some_regional_reports
|
||||||
|
erpnext.patches.v13_0.rename_issue_doctype_fields
|
||||||
erpnext.patches.v13_0.change_default_pos_print_format
|
erpnext.patches.v13_0.change_default_pos_print_format
|
||||||
|
erpnext.patches.v13_0.set_youtube_video_id
|
||||||
|
@ -4,17 +4,16 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
frappe.reload_doc("erpnext_integrations", "doctype", "plaid_settings")
|
frappe.reload_doc("erpnext_integrations", "doctype", "plaid_settings")
|
||||||
plaid_settings = frappe.get_single("Plaid Settings")
|
plaid_settings = frappe.get_single("Plaid Settings")
|
||||||
if plaid_settings.enabled:
|
if plaid_settings.enabled:
|
||||||
if not (frappe.conf.plaid_client_id and frappe.conf.plaid_env \
|
if not (frappe.conf.plaid_client_id and frappe.conf.plaid_env and frappe.conf.plaid_secret):
|
||||||
and frappe.conf.plaid_public_key and frappe.conf.plaid_secret):
|
|
||||||
plaid_settings.enabled = 0
|
plaid_settings.enabled = 0
|
||||||
else:
|
else:
|
||||||
plaid_settings.update({
|
plaid_settings.update({
|
||||||
"plaid_client_id": frappe.conf.plaid_client_id,
|
"plaid_client_id": frappe.conf.plaid_client_id,
|
||||||
"plaid_public_key": frappe.conf.plaid_public_key,
|
|
||||||
"plaid_env": frappe.conf.plaid_env,
|
"plaid_env": frappe.conf.plaid_env,
|
||||||
"plaid_secret": frappe.conf.plaid_secret
|
"plaid_secret": frappe.conf.plaid_secret
|
||||||
})
|
})
|
||||||
|
65
erpnext/patches/v13_0/rename_issue_doctype_fields.py
Normal file
65
erpnext/patches/v13_0/rename_issue_doctype_fields.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
# Copyright (c) 2020, Frappe and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.model.utils.rename_field import rename_field
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
if frappe.db.exists('DocType', 'Issue'):
|
||||||
|
issues = frappe.db.get_all('Issue', fields=['name', 'response_by_variance', 'resolution_by_variance', 'mins_to_first_response'],
|
||||||
|
order_by='creation desc')
|
||||||
|
frappe.reload_doc('support', 'doctype', 'issue')
|
||||||
|
|
||||||
|
# rename fields
|
||||||
|
rename_map = {
|
||||||
|
'agreement_fulfilled': 'agreement_status',
|
||||||
|
'mins_to_first_response': 'first_response_time'
|
||||||
|
}
|
||||||
|
for old, new in rename_map.items():
|
||||||
|
rename_field('Issue', old, new)
|
||||||
|
|
||||||
|
# change fieldtype to duration
|
||||||
|
count = 0
|
||||||
|
for entry in issues:
|
||||||
|
response_by_variance = convert_to_seconds(entry.response_by_variance, 'Hours')
|
||||||
|
resolution_by_variance = convert_to_seconds(entry.resolution_by_variance, 'Hours')
|
||||||
|
mins_to_first_response = convert_to_seconds(entry.mins_to_first_response, 'Minutes')
|
||||||
|
frappe.db.set_value('Issue', entry.name, {
|
||||||
|
'response_by_variance': response_by_variance,
|
||||||
|
'resolution_by_variance': resolution_by_variance,
|
||||||
|
'first_response_time': mins_to_first_response
|
||||||
|
})
|
||||||
|
# commit after every 100 updates
|
||||||
|
count += 1
|
||||||
|
if count%100 == 0:
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
if frappe.db.exists('DocType', 'Opportunity'):
|
||||||
|
opportunities = frappe.db.get_all('Opportunity', fields=['name', 'mins_to_first_response'], order_by='creation desc')
|
||||||
|
frappe.reload_doc('crm', 'doctype', 'opportunity')
|
||||||
|
rename_field('Opportunity', 'mins_to_first_response', 'first_response_time')
|
||||||
|
|
||||||
|
# change fieldtype to duration
|
||||||
|
count = 0
|
||||||
|
for entry in opportunities:
|
||||||
|
mins_to_first_response = convert_to_seconds(entry.mins_to_first_response, 'Minutes')
|
||||||
|
frappe.db.set_value('Opportunity', entry.name, 'first_response_time', mins_to_first_response)
|
||||||
|
# commit after every 100 updates
|
||||||
|
count += 1
|
||||||
|
if count%100 == 0:
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
# renamed reports from "Minutes to First Response for Issues" to "First Response Time for Issues". Same for Opportunity
|
||||||
|
for report in ['Minutes to First Response for Issues', 'Minutes to First Response for Opportunity']:
|
||||||
|
if frappe.db.exists('Report', report):
|
||||||
|
frappe.delete_doc('Report', report)
|
||||||
|
|
||||||
|
|
||||||
|
def convert_to_seconds(value, unit):
|
||||||
|
seconds = 0
|
||||||
|
if unit == 'Hours':
|
||||||
|
seconds = value * 3600
|
||||||
|
if unit == 'Minutes':
|
||||||
|
seconds = value * 60
|
||||||
|
return seconds
|
10
erpnext/patches/v13_0/set_youtube_video_id.py
Normal file
10
erpnext/patches/v13_0/set_youtube_video_id.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from erpnext.utilities.doctype.video.video import get_id_from_url
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doc("utilities", "doctype","video")
|
||||||
|
|
||||||
|
for video in frappe.get_all("Video", fields=["name", "url", "youtube_video_id"]):
|
||||||
|
if video.url and not video.youtube_video_id:
|
||||||
|
frappe.db.set_value("Video", video.name, "youtube_video_id", get_id_from_url(video.url))
|
@ -48,8 +48,8 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-10-26 17:37:25.638190",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "rohitw1991@gmail.com",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Dependent Task",
|
"name": "Dependent Task",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
|
@ -11,7 +11,9 @@ $.extend(frappe.breadcrumbs.preferred, {
|
|||||||
"Territory": "Selling",
|
"Territory": "Selling",
|
||||||
"Sales Person": "Selling",
|
"Sales Person": "Selling",
|
||||||
"Sales Partner": "Selling",
|
"Sales Partner": "Selling",
|
||||||
"Brand": "Stock"
|
"Brand": "Stock",
|
||||||
|
"Maintenance Schedule": "Support",
|
||||||
|
"Maintenance Visit": "Support"
|
||||||
});
|
});
|
||||||
|
|
||||||
$.extend(frappe.breadcrumbs.module_map, {
|
$.extend(frappe.breadcrumbs.module_map, {
|
||||||
|
@ -120,7 +120,7 @@ frappe.ui.form.on('Salary Structure', {
|
|||||||
|
|
||||||
var get_payment_mode_account = function(frm, mode_of_payment, callback) {
|
var get_payment_mode_account = function(frm, mode_of_payment, callback) {
|
||||||
if(!frm.doc.company) {
|
if(!frm.doc.company) {
|
||||||
frappe.throw(__("Please select the Company first"));
|
frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!mode_of_payment) {
|
if(!mode_of_payment) {
|
||||||
|
@ -417,7 +417,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
var taxes_and_charges_field = frappe.meta.get_docfield(me.frm.doc.doctype, "taxes_and_charges",
|
var taxes_and_charges_field = frappe.meta.get_docfield(me.frm.doc.doctype, "taxes_and_charges",
|
||||||
me.frm.doc.name);
|
me.frm.doc.name);
|
||||||
|
|
||||||
if (!this.frm.doc.taxes_and_charges && this.frm.doc.taxes) {
|
if (!this.frm.doc.taxes_and_charges && this.frm.doc.taxes && this.frm.doc.taxes.length > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,6 +224,10 @@ erpnext.utils.set_taxes = function(frm, triggered_from_field) {
|
|||||||
party = frm.doc.party_name;
|
party = frm.doc.party_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!frm.doc.company) {
|
||||||
|
frappe.throw(__("Kindly select the company first"));
|
||||||
|
}
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.party.set_taxes",
|
method: "erpnext.accounts.party.set_taxes",
|
||||||
args: {
|
args: {
|
||||||
|
0
erpnext/regional/germany/utils/datev/__init__.py
Normal file
0
erpnext/regional/germany/utils/datev/__init__.py
Normal file
@ -460,80 +460,8 @@ ACCOUNT_NAME_COLUMNS = [
|
|||||||
"Sprach-ID"
|
"Sprach-ID"
|
||||||
]
|
]
|
||||||
|
|
||||||
QUERY_REPORT_COLUMNS = [
|
|
||||||
{
|
|
||||||
"label": "Umsatz (ohne Soll/Haben-Kz)",
|
|
||||||
"fieldname": "Umsatz (ohne Soll/Haben-Kz)",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"width": 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Soll/Haben-Kennzeichen",
|
|
||||||
"fieldname": "Soll/Haben-Kennzeichen",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"width": 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Konto",
|
|
||||||
"fieldname": "Konto",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"width": 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Gegenkonto (ohne BU-Schlüssel)",
|
|
||||||
"fieldname": "Gegenkonto (ohne BU-Schlüssel)",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"width": 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Belegdatum",
|
|
||||||
"fieldname": "Belegdatum",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"width": 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Belegfeld 1",
|
|
||||||
"fieldname": "Belegfeld 1",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"width": 150
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Buchungstext",
|
|
||||||
"fieldname": "Buchungstext",
|
|
||||||
"fieldtype": "Text",
|
|
||||||
"width": 300
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Beleginfo - Art 1",
|
|
||||||
"fieldname": "Beleginfo - Art 1",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "DocType",
|
|
||||||
"width": 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Beleginfo - Inhalt 1",
|
|
||||||
"fieldname": "Beleginfo - Inhalt 1",
|
|
||||||
"fieldtype": "Dynamic Link",
|
|
||||||
"options": "Beleginfo - Art 1",
|
|
||||||
"width": 150
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Beleginfo - Art 2",
|
|
||||||
"fieldname": "Beleginfo - Art 2",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": "DocType",
|
|
||||||
"width": 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Beleginfo - Inhalt 2",
|
|
||||||
"fieldname": "Beleginfo - Inhalt 2",
|
|
||||||
"fieldtype": "Dynamic Link",
|
|
||||||
"options": "Beleginfo - Art 2",
|
|
||||||
"width": 150
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
class DataCategory():
|
class DataCategory():
|
||||||
|
|
||||||
"""Field of the CSV Header."""
|
"""Field of the CSV Header."""
|
||||||
|
|
||||||
DEBTORS_CREDITORS = "16"
|
DEBTORS_CREDITORS = "16"
|
||||||
@ -542,6 +470,7 @@ class DataCategory():
|
|||||||
POSTING_TEXT_CONSTANTS = "67"
|
POSTING_TEXT_CONSTANTS = "67"
|
||||||
|
|
||||||
class FormatName():
|
class FormatName():
|
||||||
|
|
||||||
"""Field of the CSV Header, corresponds to DataCategory."""
|
"""Field of the CSV Header, corresponds to DataCategory."""
|
||||||
|
|
||||||
DEBTORS_CREDITORS = "Debitoren/Kreditoren"
|
DEBTORS_CREDITORS = "Debitoren/Kreditoren"
|
174
erpnext/regional/germany/utils/datev/datev_csv.py
Normal file
174
erpnext/regional/germany/utils/datev/datev_csv.py
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import zipfile
|
||||||
|
from csv import QUOTE_NONNUMERIC
|
||||||
|
from six import BytesIO
|
||||||
|
|
||||||
|
import six
|
||||||
|
import frappe
|
||||||
|
import pandas as pd
|
||||||
|
from frappe import _
|
||||||
|
from .datev_constants import DataCategory
|
||||||
|
|
||||||
|
|
||||||
|
def get_datev_csv(data, filters, csv_class):
|
||||||
|
"""
|
||||||
|
Fill in missing columns and return a CSV in DATEV Format.
|
||||||
|
|
||||||
|
For automatic processing, DATEV requires the first line of the CSV file to
|
||||||
|
hold meta data such as the length of account numbers oder the category of
|
||||||
|
the data.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
data -- array of dictionaries
|
||||||
|
filters -- dict
|
||||||
|
csv_class -- defines DATA_CATEGORY, FORMAT_NAME and COLUMNS
|
||||||
|
"""
|
||||||
|
empty_df = pd.DataFrame(columns=csv_class.COLUMNS)
|
||||||
|
data_df = pd.DataFrame.from_records(data)
|
||||||
|
result = empty_df.append(data_df, sort=True)
|
||||||
|
|
||||||
|
if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS:
|
||||||
|
result['Belegdatum'] = pd.to_datetime(result['Belegdatum'])
|
||||||
|
|
||||||
|
if csv_class.DATA_CATEGORY == DataCategory.ACCOUNT_NAMES:
|
||||||
|
result['Sprach-ID'] = 'de-DE'
|
||||||
|
|
||||||
|
data = result.to_csv(
|
||||||
|
# Reason for str(';'): https://github.com/pandas-dev/pandas/issues/6035
|
||||||
|
sep=str(';'),
|
||||||
|
# European decimal seperator
|
||||||
|
decimal=',',
|
||||||
|
# Windows "ANSI" encoding
|
||||||
|
encoding='latin_1',
|
||||||
|
# format date as DDMM
|
||||||
|
date_format='%d%m',
|
||||||
|
# Windows line terminator
|
||||||
|
line_terminator='\r\n',
|
||||||
|
# Do not number rows
|
||||||
|
index=False,
|
||||||
|
# Use all columns defined above
|
||||||
|
columns=csv_class.COLUMNS,
|
||||||
|
# Quote most fields, even currency values with "," separator
|
||||||
|
quoting=QUOTE_NONNUMERIC
|
||||||
|
)
|
||||||
|
|
||||||
|
if not six.PY2:
|
||||||
|
data = data.encode('latin_1')
|
||||||
|
|
||||||
|
header = get_header(filters, csv_class)
|
||||||
|
header = ';'.join(header).encode('latin_1')
|
||||||
|
|
||||||
|
# 1st Row: Header with meta data
|
||||||
|
# 2nd Row: Data heading (Überschrift der Nutzdaten), included in `data` here.
|
||||||
|
# 3rd - nth Row: Data (Nutzdaten)
|
||||||
|
return header + b'\r\n' + data
|
||||||
|
|
||||||
|
|
||||||
|
def get_header(filters, csv_class):
|
||||||
|
description = filters.get('voucher_type', csv_class.FORMAT_NAME)
|
||||||
|
company = filters.get('company')
|
||||||
|
datev_settings = frappe.get_doc('DATEV Settings', {'client': company})
|
||||||
|
default_currency = frappe.get_value('Company', company, 'default_currency')
|
||||||
|
coa = frappe.get_value('Company', company, 'chart_of_accounts')
|
||||||
|
coa_short_code = '04' if 'SKR04' in coa else ('03' if 'SKR03' in coa else '')
|
||||||
|
|
||||||
|
header = [
|
||||||
|
# DATEV format
|
||||||
|
# "DTVF" = created by DATEV software,
|
||||||
|
# "EXTF" = created by other software
|
||||||
|
'"EXTF"',
|
||||||
|
# version of the DATEV format
|
||||||
|
# 141 = 1.41,
|
||||||
|
# 510 = 5.10,
|
||||||
|
# 720 = 7.20
|
||||||
|
'700',
|
||||||
|
csv_class.DATA_CATEGORY,
|
||||||
|
'"%s"' % csv_class.FORMAT_NAME,
|
||||||
|
# Format version (regarding format name)
|
||||||
|
csv_class.FORMAT_VERSION,
|
||||||
|
# Generated on
|
||||||
|
datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '000',
|
||||||
|
# Imported on -- stays empty
|
||||||
|
'',
|
||||||
|
# Origin. Any two symbols, will be replaced by "SV" on import.
|
||||||
|
'"EN"',
|
||||||
|
# I = Exported by
|
||||||
|
'"%s"' % frappe.session.user,
|
||||||
|
# J = Imported by -- stays empty
|
||||||
|
'',
|
||||||
|
# K = Tax consultant number (Beraternummer)
|
||||||
|
datev_settings.get('consultant_number', '0000000'),
|
||||||
|
# L = Tax client number (Mandantennummer)
|
||||||
|
datev_settings.get('client_number', '00000'),
|
||||||
|
# M = Start of the fiscal year (Wirtschaftsjahresbeginn)
|
||||||
|
frappe.utils.formatdate(frappe.defaults.get_user_default('year_start_date'), 'yyyyMMdd'),
|
||||||
|
# N = Length of account numbers (Sachkontenlänge)
|
||||||
|
datev_settings.get('account_number_length', '4'),
|
||||||
|
# O = Transaction batch start date (YYYYMMDD)
|
||||||
|
frappe.utils.formatdate(filters.get('from_date'), 'yyyyMMdd') if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
||||||
|
# P = Transaction batch end date (YYYYMMDD)
|
||||||
|
frappe.utils.formatdate(filters.get('to_date'), 'yyyyMMdd') if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
||||||
|
# Q = Description (for example, "Sales Invoice") Max. 30 chars
|
||||||
|
'"{}"'.format(_(description)) if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
||||||
|
# R = Diktatkürzel
|
||||||
|
'',
|
||||||
|
# S = Buchungstyp
|
||||||
|
# 1 = Transaction batch (Finanzbuchführung),
|
||||||
|
# 2 = Annual financial statement (Jahresabschluss)
|
||||||
|
'1' if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
||||||
|
# T = Rechnungslegungszweck
|
||||||
|
# 0 oder leer = vom Rechnungslegungszweck unabhängig
|
||||||
|
# 50 = Handelsrecht
|
||||||
|
# 30 = Steuerrecht
|
||||||
|
# 64 = IFRS
|
||||||
|
# 40 = Kalkulatorik
|
||||||
|
# 11 = Reserviert
|
||||||
|
# 12 = Reserviert
|
||||||
|
'0' if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
||||||
|
# U = Festschreibung
|
||||||
|
# TODO: Filter by Accounting Period. In export for closed Accounting Period, this will be "1"
|
||||||
|
'0',
|
||||||
|
# V = Default currency, for example, "EUR"
|
||||||
|
'"%s"' % default_currency if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
||||||
|
# reserviert
|
||||||
|
'',
|
||||||
|
# Derivatskennzeichen
|
||||||
|
'',
|
||||||
|
# reserviert
|
||||||
|
'',
|
||||||
|
# reserviert
|
||||||
|
'',
|
||||||
|
# SKR
|
||||||
|
'"%s"' % coa_short_code,
|
||||||
|
# Branchen-Lösungs-ID
|
||||||
|
'',
|
||||||
|
# reserviert
|
||||||
|
'',
|
||||||
|
# reserviert
|
||||||
|
'',
|
||||||
|
# Anwendungsinformation (Verarbeitungskennzeichen der abgebenden Anwendung)
|
||||||
|
''
|
||||||
|
]
|
||||||
|
return header
|
||||||
|
|
||||||
|
|
||||||
|
def download_csv_files_as_zip(csv_data_list):
|
||||||
|
"""
|
||||||
|
Put CSV files in a zip archive and send that to the client.
|
||||||
|
|
||||||
|
Params:
|
||||||
|
csv_data_list -- list of dicts [{'file_name': 'EXTF_Buchunsstapel.zip', 'csv_data': get_datev_csv()}]
|
||||||
|
"""
|
||||||
|
zip_buffer = BytesIO()
|
||||||
|
|
||||||
|
datev_zip = zipfile.ZipFile(zip_buffer, mode='w', compression=zipfile.ZIP_DEFLATED)
|
||||||
|
for csv_file in csv_data_list:
|
||||||
|
datev_zip.writestr(csv_file.get('file_name'), csv_file.get('csv_data'))
|
||||||
|
datev_zip.close()
|
||||||
|
|
||||||
|
frappe.response['filecontent'] = zip_buffer.getvalue()
|
||||||
|
frappe.response['filename'] = 'DATEV.zip'
|
||||||
|
frappe.response['type'] = 'binary'
|
@ -9,31 +9,91 @@ Provide a report and downloadable CSV according to the German DATEV format.
|
|||||||
"""
|
"""
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import datetime
|
|
||||||
import json
|
import json
|
||||||
import zipfile
|
|
||||||
import six
|
|
||||||
import frappe
|
import frappe
|
||||||
import pandas as pd
|
|
||||||
|
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from csv import QUOTE_NONNUMERIC
|
|
||||||
from six import BytesIO
|
|
||||||
from six import string_types
|
from six import string_types
|
||||||
from .datev_constants import DataCategory
|
from erpnext.regional.germany.utils.datev.datev_csv import download_csv_files_as_zip, get_datev_csv
|
||||||
from .datev_constants import Transactions
|
from erpnext.regional.germany.utils.datev.datev_constants import Transactions, DebtorsCreditors, AccountNames
|
||||||
from .datev_constants import DebtorsCreditors
|
|
||||||
from .datev_constants import AccountNames
|
COLUMNS = [
|
||||||
from .datev_constants import QUERY_REPORT_COLUMNS
|
{
|
||||||
|
"label": "Umsatz (ohne Soll/Haben-Kz)",
|
||||||
|
"fieldname": "Umsatz (ohne Soll/Haben-Kz)",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Soll/Haben-Kennzeichen",
|
||||||
|
"fieldname": "Soll/Haben-Kennzeichen",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Konto",
|
||||||
|
"fieldname": "Konto",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Gegenkonto (ohne BU-Schlüssel)",
|
||||||
|
"fieldname": "Gegenkonto (ohne BU-Schlüssel)",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Belegdatum",
|
||||||
|
"fieldname": "Belegdatum",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Belegfeld 1",
|
||||||
|
"fieldname": "Belegfeld 1",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Buchungstext",
|
||||||
|
"fieldname": "Buchungstext",
|
||||||
|
"fieldtype": "Text",
|
||||||
|
"width": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Beleginfo - Art 1",
|
||||||
|
"fieldname": "Beleginfo - Art 1",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "DocType",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Beleginfo - Inhalt 1",
|
||||||
|
"fieldname": "Beleginfo - Inhalt 1",
|
||||||
|
"fieldtype": "Dynamic Link",
|
||||||
|
"options": "Beleginfo - Art 1",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Beleginfo - Art 2",
|
||||||
|
"fieldname": "Beleginfo - Art 2",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "DocType",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Beleginfo - Inhalt 2",
|
||||||
|
"fieldname": "Beleginfo - Inhalt 2",
|
||||||
|
"fieldtype": "Dynamic Link",
|
||||||
|
"options": "Beleginfo - Art 2",
|
||||||
|
"width": 150
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
"""Entry point for frappe."""
|
"""Entry point for frappe."""
|
||||||
validate(filters)
|
validate(filters)
|
||||||
result = get_transactions(filters, as_dict=0)
|
return COLUMNS, get_transactions(filters, as_dict=0)
|
||||||
columns = QUERY_REPORT_COLUMNS
|
|
||||||
|
|
||||||
return columns, result
|
|
||||||
|
|
||||||
|
|
||||||
def validate(filters):
|
def validate(filters):
|
||||||
@ -240,146 +300,8 @@ def get_account_names(filters):
|
|||||||
""", filters, as_dict=1)
|
""", filters, as_dict=1)
|
||||||
|
|
||||||
|
|
||||||
def get_datev_csv(data, filters, csv_class):
|
|
||||||
"""
|
|
||||||
Fill in missing columns and return a CSV in DATEV Format.
|
|
||||||
|
|
||||||
For automatic processing, DATEV requires the first line of the CSV file to
|
|
||||||
hold meta data such as the length of account numbers oder the category of
|
|
||||||
the data.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
data -- array of dictionaries
|
|
||||||
filters -- dict
|
|
||||||
csv_class -- defines DATA_CATEGORY, FORMAT_NAME and COLUMNS
|
|
||||||
"""
|
|
||||||
empty_df = pd.DataFrame(columns=csv_class.COLUMNS)
|
|
||||||
data_df = pd.DataFrame.from_records(data)
|
|
||||||
|
|
||||||
result = empty_df.append(data_df, sort=True)
|
|
||||||
|
|
||||||
if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS:
|
|
||||||
result['Belegdatum'] = pd.to_datetime(result['Belegdatum'])
|
|
||||||
|
|
||||||
if csv_class.DATA_CATEGORY == DataCategory.ACCOUNT_NAMES:
|
|
||||||
result['Sprach-ID'] = 'de-DE'
|
|
||||||
|
|
||||||
data = result.to_csv(
|
|
||||||
# Reason for str(';'): https://github.com/pandas-dev/pandas/issues/6035
|
|
||||||
sep=str(';'),
|
|
||||||
# European decimal seperator
|
|
||||||
decimal=',',
|
|
||||||
# Windows "ANSI" encoding
|
|
||||||
encoding='latin_1',
|
|
||||||
# format date as DDMM
|
|
||||||
date_format='%d%m',
|
|
||||||
# Windows line terminator
|
|
||||||
line_terminator='\r\n',
|
|
||||||
# Do not number rows
|
|
||||||
index=False,
|
|
||||||
# Use all columns defined above
|
|
||||||
columns=csv_class.COLUMNS,
|
|
||||||
# Quote most fields, even currency values with "," separator
|
|
||||||
quoting=QUOTE_NONNUMERIC
|
|
||||||
)
|
|
||||||
|
|
||||||
if not six.PY2:
|
|
||||||
data = data.encode('latin_1')
|
|
||||||
|
|
||||||
header = get_header(filters, csv_class)
|
|
||||||
header = ';'.join(header).encode('latin_1')
|
|
||||||
|
|
||||||
# 1st Row: Header with meta data
|
|
||||||
# 2nd Row: Data heading (Überschrift der Nutzdaten), included in `data` here.
|
|
||||||
# 3rd - nth Row: Data (Nutzdaten)
|
|
||||||
return header + b'\r\n' + data
|
|
||||||
|
|
||||||
|
|
||||||
def get_header(filters, csv_class):
|
|
||||||
description = filters.get('voucher_type', csv_class.FORMAT_NAME)
|
|
||||||
|
|
||||||
header = [
|
|
||||||
# DATEV format
|
|
||||||
# "DTVF" = created by DATEV software,
|
|
||||||
# "EXTF" = created by other software
|
|
||||||
'"EXTF"',
|
|
||||||
# version of the DATEV format
|
|
||||||
# 141 = 1.41,
|
|
||||||
# 510 = 5.10,
|
|
||||||
# 720 = 7.20
|
|
||||||
'700',
|
|
||||||
csv_class.DATA_CATEGORY,
|
|
||||||
'"%s"' % csv_class.FORMAT_NAME,
|
|
||||||
# Format version (regarding format name)
|
|
||||||
csv_class.FORMAT_VERSION,
|
|
||||||
# Generated on
|
|
||||||
datetime.datetime.now().strftime("%Y%m%d%H%M%S") + '000',
|
|
||||||
# Imported on -- stays empty
|
|
||||||
'',
|
|
||||||
# Origin. Any two symbols, will be replaced by "SV" on import.
|
|
||||||
'"EN"',
|
|
||||||
# I = Exported by
|
|
||||||
'"%s"' % frappe.session.user,
|
|
||||||
# J = Imported by -- stays empty
|
|
||||||
'',
|
|
||||||
# K = Tax consultant number (Beraternummer)
|
|
||||||
filters.get('consultant_number', '0000000'),
|
|
||||||
# L = Tax client number (Mandantennummer)
|
|
||||||
filters.get('client_number', '00000'),
|
|
||||||
# M = Start of the fiscal year (Wirtschaftsjahresbeginn)
|
|
||||||
frappe.utils.formatdate(frappe.defaults.get_user_default("year_start_date"), "yyyyMMdd"),
|
|
||||||
# N = Length of account numbers (Sachkontenlänge)
|
|
||||||
'%d' % filters.get('acc_len', 4),
|
|
||||||
# O = Transaction batch start date (YYYYMMDD)
|
|
||||||
frappe.utils.formatdate(filters.get('from_date'), "yyyyMMdd") if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
|
||||||
# P = Transaction batch end date (YYYYMMDD)
|
|
||||||
frappe.utils.formatdate(filters.get('to_date'), "yyyyMMdd") if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
|
||||||
# Q = Description (for example, "Sales Invoice") Max. 30 chars
|
|
||||||
'"{}"'.format(_(description)) if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
|
||||||
# R = Diktatkürzel
|
|
||||||
'',
|
|
||||||
# S = Buchungstyp
|
|
||||||
# 1 = Transaction batch (Finanzbuchführung),
|
|
||||||
# 2 = Annual financial statement (Jahresabschluss)
|
|
||||||
'1' if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
|
||||||
# T = Rechnungslegungszweck
|
|
||||||
# 0 oder leer = vom Rechnungslegungszweck unabhängig
|
|
||||||
# 50 = Handelsrecht
|
|
||||||
# 30 = Steuerrecht
|
|
||||||
# 64 = IFRS
|
|
||||||
# 40 = Kalkulatorik
|
|
||||||
# 11 = Reserviert
|
|
||||||
# 12 = Reserviert
|
|
||||||
'0' if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
|
||||||
# U = Festschreibung
|
|
||||||
# TODO: Filter by Accounting Period. In export for closed Accounting Period, this will be "1"
|
|
||||||
'0',
|
|
||||||
# V = Default currency, for example, "EUR"
|
|
||||||
'"%s"' % filters.get('default_currency', 'EUR') if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
|
||||||
# reserviert
|
|
||||||
'',
|
|
||||||
# Derivatskennzeichen
|
|
||||||
'',
|
|
||||||
# reserviert
|
|
||||||
'',
|
|
||||||
# reserviert
|
|
||||||
'',
|
|
||||||
# SKR
|
|
||||||
'"%s"' % filters.get('skr', '04'),
|
|
||||||
# Branchen-Lösungs-ID
|
|
||||||
'',
|
|
||||||
# reserviert
|
|
||||||
'',
|
|
||||||
# reserviert
|
|
||||||
'',
|
|
||||||
# Anwendungsinformation (Verarbeitungskennzeichen der abgebenden Anwendung)
|
|
||||||
''
|
|
||||||
]
|
|
||||||
return header
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def download_datev_csv(filters=None):
|
def download_datev_csv(filters):
|
||||||
"""
|
"""
|
||||||
Provide accounting entries for download in DATEV format.
|
Provide accounting entries for download in DATEV format.
|
||||||
|
|
||||||
@ -400,38 +322,26 @@ def download_datev_csv(filters=None):
|
|||||||
coa = frappe.get_value('Company', filters.get('company'), 'chart_of_accounts')
|
coa = frappe.get_value('Company', filters.get('company'), 'chart_of_accounts')
|
||||||
filters['skr'] = '04' if 'SKR04' in coa else ('03' if 'SKR03' in coa else '')
|
filters['skr'] = '04' if 'SKR04' in coa else ('03' if 'SKR03' in coa else '')
|
||||||
|
|
||||||
# set account number length
|
|
||||||
account_numbers = frappe.get_list('Account', fields=['account_number'], filters={'is_group': 0, 'account_number': ('!=', '')})
|
|
||||||
filters['acc_len'] = max([len(a.account_number) for a in account_numbers])
|
|
||||||
|
|
||||||
filters['consultant_number'] = frappe.get_value('DATEV Settings', filters.get('company'), 'consultant_number')
|
|
||||||
filters['client_number'] = frappe.get_value('DATEV Settings', filters.get('company'), 'client_number')
|
|
||||||
filters['default_currency'] = frappe.get_value('Company', filters.get('company'), 'default_currency')
|
|
||||||
|
|
||||||
# This is where my zip will be written
|
|
||||||
zip_buffer = BytesIO()
|
|
||||||
# This is my zip file
|
|
||||||
datev_zip = zipfile.ZipFile(zip_buffer, mode='w', compression=zipfile.ZIP_DEFLATED)
|
|
||||||
|
|
||||||
transactions = get_transactions(filters)
|
transactions = get_transactions(filters)
|
||||||
transactions_csv = get_datev_csv(transactions, filters, csv_class=Transactions)
|
|
||||||
datev_zip.writestr('EXTF_Buchungsstapel.csv', transactions_csv)
|
|
||||||
|
|
||||||
account_names = get_account_names(filters)
|
account_names = get_account_names(filters)
|
||||||
account_names_csv = get_datev_csv(account_names, filters, csv_class=AccountNames)
|
|
||||||
datev_zip.writestr('EXTF_Kontenbeschriftungen.csv', account_names_csv)
|
|
||||||
|
|
||||||
customers = get_customers(filters)
|
customers = get_customers(filters)
|
||||||
customers_csv = get_datev_csv(customers, filters, csv_class=DebtorsCreditors)
|
|
||||||
datev_zip.writestr('EXTF_Kunden.csv', customers_csv)
|
|
||||||
|
|
||||||
suppliers = get_suppliers(filters)
|
suppliers = get_suppliers(filters)
|
||||||
suppliers_csv = get_datev_csv(suppliers, filters, csv_class=DebtorsCreditors)
|
|
||||||
datev_zip.writestr('EXTF_Lieferanten.csv', suppliers_csv)
|
|
||||||
|
|
||||||
# You must call close() before exiting your program or essential records will not be written.
|
download_csv_files_as_zip([
|
||||||
datev_zip.close()
|
{
|
||||||
|
'file_name': 'EXTF_Buchungsstapel.csv',
|
||||||
frappe.response['filecontent'] = zip_buffer.getvalue()
|
'csv_data': get_datev_csv(transactions, filters, csv_class=Transactions)
|
||||||
frappe.response['filename'] = 'DATEV.zip'
|
},
|
||||||
frappe.response['type'] = 'binary'
|
{
|
||||||
|
'file_name': 'EXTF_Kontenbeschriftungen.csv',
|
||||||
|
'csv_data': get_datev_csv(account_names, filters, csv_class=AccountNames)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'file_name': 'EXTF_Kunden.csv',
|
||||||
|
'csv_data': get_datev_csv(customers, filters, csv_class=DebtorsCreditors)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'file_name': 'EXTF_Lieferanten.csv',
|
||||||
|
'csv_data': get_datev_csv(suppliers, filters, csv_class=DebtorsCreditors)
|
||||||
|
},
|
||||||
|
])
|
||||||
|
@ -1,32 +1,22 @@
|
|||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
import zipfile
|
import zipfile
|
||||||
|
import frappe
|
||||||
from six import BytesIO
|
from six import BytesIO
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
from frappe.utils import today, now_datetime, cstr
|
||||||
import frappe
|
|
||||||
from frappe.utils import getdate, today, now_datetime, cstr
|
|
||||||
from frappe.test_runner import make_test_objects
|
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts
|
|
||||||
|
|
||||||
from erpnext.regional.report.datev.datev import validate
|
from erpnext.regional.report.datev.datev import validate
|
||||||
from erpnext.regional.report.datev.datev import get_transactions
|
from erpnext.regional.report.datev.datev import get_transactions
|
||||||
from erpnext.regional.report.datev.datev import get_customers
|
from erpnext.regional.report.datev.datev import get_customers
|
||||||
from erpnext.regional.report.datev.datev import get_suppliers
|
from erpnext.regional.report.datev.datev import get_suppliers
|
||||||
from erpnext.regional.report.datev.datev import get_account_names
|
from erpnext.regional.report.datev.datev import get_account_names
|
||||||
from erpnext.regional.report.datev.datev import get_datev_csv
|
|
||||||
from erpnext.regional.report.datev.datev import get_header
|
|
||||||
from erpnext.regional.report.datev.datev import download_datev_csv
|
from erpnext.regional.report.datev.datev import download_datev_csv
|
||||||
|
|
||||||
from erpnext.regional.report.datev.datev_constants import DataCategory
|
from erpnext.regional.germany.utils.datev.datev_csv import get_datev_csv, get_header
|
||||||
from erpnext.regional.report.datev.datev_constants import Transactions
|
from erpnext.regional.germany.utils.datev.datev_constants import Transactions, DebtorsCreditors, AccountNames
|
||||||
from erpnext.regional.report.datev.datev_constants import DebtorsCreditors
|
|
||||||
from erpnext.regional.report.datev.datev_constants import AccountNames
|
|
||||||
from erpnext.regional.report.datev.datev_constants import QUERY_REPORT_COLUMNS
|
|
||||||
|
|
||||||
def make_company(company_name, abbr):
|
def make_company(company_name, abbr):
|
||||||
if not frappe.db.exists("Company", company_name):
|
if not frappe.db.exists("Company", company_name):
|
||||||
|
@ -49,11 +49,11 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-07-25 05:24:25.881361",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Industry Type",
|
"name": "Industry Type",
|
||||||
"owner": "harshada@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
|
@ -238,8 +238,8 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-10-18 14:23:06.538568",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "tundebabzy@gmail.com",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Product Bundle",
|
"name": "Product Bundle",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
|
@ -70,13 +70,23 @@ erpnext.PointOfSale.Payment = class {
|
|||||||
this.$invoice_fields.append(
|
this.$invoice_fields.append(
|
||||||
`<div class="invoice_detail_field ${df.fieldname}-field" data-fieldname="${df.fieldname}"></div>`
|
`<div class="invoice_detail_field ${df.fieldname}-field" data-fieldname="${df.fieldname}"></div>`
|
||||||
);
|
);
|
||||||
|
let df_events = {
|
||||||
|
onchange: function() { frm.set_value(this.df.fieldname, this.value); }
|
||||||
|
}
|
||||||
|
if (df.fieldtype == "Button") {
|
||||||
|
df_events = {
|
||||||
|
click: function() {
|
||||||
|
if (frm.script_manager.has_handlers(df.fieldname, frm.doc.doctype)) {
|
||||||
|
frm.script_manager.trigger(df.fieldname, frm.doc.doctype, frm.doc.docname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this[`${df.fieldname}_field`] = frappe.ui.form.make_control({
|
this[`${df.fieldname}_field`] = frappe.ui.form.make_control({
|
||||||
df: {
|
df: {
|
||||||
...df,
|
...df,
|
||||||
onchange: function() {
|
...df_events
|
||||||
frm.set_value(this.df.fieldname, this.value);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
parent: this.$invoice_fields.find(`.${df.fieldname}-field`),
|
parent: this.$invoice_fields.find(`.${df.fieldname}-field`),
|
||||||
render_input: true,
|
render_input: true,
|
||||||
|
@ -188,7 +188,7 @@ def get_conditions(filters):
|
|||||||
conditions += "AND so.transaction_date <= '%s'" %filters.to_date
|
conditions += "AND so.transaction_date <= '%s'" %filters.to_date
|
||||||
|
|
||||||
if filters.get("item_code"):
|
if filters.get("item_code"):
|
||||||
conditions += "AND so_item.item_code = '%s'" %frappe.db.escape(filters.item_code)
|
conditions += "AND so_item.item_code = %s" %frappe.db.escape(filters.item_code)
|
||||||
|
|
||||||
if filters.get("customer"):
|
if filters.get("customer"):
|
||||||
conditions += "AND so.customer = %s" %frappe.db.escape(filters.customer)
|
conditions += "AND so.customer = %s" %frappe.db.escape(filters.customer)
|
||||||
|
@ -8,7 +8,7 @@ frappe.query_reports["Sales Analytics"] = {
|
|||||||
fieldname: "tree_type",
|
fieldname: "tree_type",
|
||||||
label: __("Tree Type"),
|
label: __("Tree Type"),
|
||||||
fieldtype: "Select",
|
fieldtype: "Select",
|
||||||
options: ["Customer Group","Customer","Item Group","Item","Territory","Order Type"],
|
options: ["Customer Group", "Customer", "Item Group", "Item", "Territory", "Order Type", "Project"],
|
||||||
default: "Customer",
|
default: "Customer",
|
||||||
reqd: 1
|
reqd: 1
|
||||||
},
|
},
|
||||||
|
@ -34,7 +34,7 @@ class Analytics(object):
|
|||||||
|
|
||||||
def get_columns(self):
|
def get_columns(self):
|
||||||
self.columns = [{
|
self.columns = [{
|
||||||
"label": _(self.filters.tree_type + " ID"),
|
"label": _(self.filters.tree_type),
|
||||||
"options": self.filters.tree_type if self.filters.tree_type != "Order Type" else "",
|
"options": self.filters.tree_type if self.filters.tree_type != "Order Type" else "",
|
||||||
"fieldname": "entity",
|
"fieldname": "entity",
|
||||||
"fieldtype": "Link" if self.filters.tree_type != "Order Type" else "Data",
|
"fieldtype": "Link" if self.filters.tree_type != "Order Type" else "Data",
|
||||||
@ -97,6 +97,10 @@ class Analytics(object):
|
|||||||
self.get_sales_transactions_based_on_order_type()
|
self.get_sales_transactions_based_on_order_type()
|
||||||
self.get_rows_by_group()
|
self.get_rows_by_group()
|
||||||
|
|
||||||
|
elif self.filters.tree_type == "Project":
|
||||||
|
self.get_sales_transactions_based_on_project()
|
||||||
|
self.get_rows()
|
||||||
|
|
||||||
def get_sales_transactions_based_on_order_type(self):
|
def get_sales_transactions_based_on_order_type(self):
|
||||||
if self.filters["value_quantity"] == 'Value':
|
if self.filters["value_quantity"] == 'Value':
|
||||||
value_field = "base_net_total"
|
value_field = "base_net_total"
|
||||||
@ -198,6 +202,24 @@ class Analytics(object):
|
|||||||
|
|
||||||
self.get_groups()
|
self.get_groups()
|
||||||
|
|
||||||
|
def get_sales_transactions_based_on_project(self):
|
||||||
|
if self.filters["value_quantity"] == 'Value':
|
||||||
|
value_field = "base_net_total as value_field"
|
||||||
|
else:
|
||||||
|
value_field = "total_qty as value_field"
|
||||||
|
|
||||||
|
entity = "project as entity"
|
||||||
|
|
||||||
|
self.entries = frappe.get_all(self.filters.doc_type,
|
||||||
|
fields=[entity, value_field, self.date_field],
|
||||||
|
filters={
|
||||||
|
"docstatus": 1,
|
||||||
|
"company": self.filters.company,
|
||||||
|
"project": ["!=", ""],
|
||||||
|
self.date_field: ('between', [self.filters.from_date, self.filters.to_date])
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def get_rows(self):
|
def get_rows(self):
|
||||||
self.data = []
|
self.data = []
|
||||||
self.get_periodic_data()
|
self.get_periodic_data()
|
||||||
@ -205,7 +227,7 @@ class Analytics(object):
|
|||||||
for entity, period_data in iteritems(self.entity_periodic_data):
|
for entity, period_data in iteritems(self.entity_periodic_data):
|
||||||
row = {
|
row = {
|
||||||
"entity": entity,
|
"entity": entity,
|
||||||
"entity_name": self.entity_names.get(entity)
|
"entity_name": self.entity_names.get(entity) if hasattr(self, 'entity_names') else None
|
||||||
}
|
}
|
||||||
total = 0
|
total = 0
|
||||||
for end_date in self.periodic_daterange:
|
for end_date in self.periodic_daterange:
|
||||||
|
@ -166,11 +166,11 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"max_attachments": 5,
|
"max_attachments": 5,
|
||||||
"modified": "2019-10-03 22:38:45.104056",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Batch",
|
"name": "Batch",
|
||||||
"owner": "harshada@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"create": 1,
|
"create": 1,
|
||||||
|
@ -26,19 +26,19 @@ frappe.ui.form.on("Item", {
|
|||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
if (frm.doc.is_stock_item) {
|
if (frm.doc.is_stock_item) {
|
||||||
frm.add_custom_button(__("Balance"), function() {
|
frm.add_custom_button(__("Stock Balance"), function() {
|
||||||
frappe.route_options = {
|
frappe.route_options = {
|
||||||
"item_code": frm.doc.name
|
"item_code": frm.doc.name
|
||||||
}
|
}
|
||||||
frappe.set_route("query-report", "Stock Balance");
|
frappe.set_route("query-report", "Stock Balance");
|
||||||
}, __("View"));
|
}, __("View"));
|
||||||
frm.add_custom_button(__("Ledger"), function() {
|
frm.add_custom_button(__("Stock Ledger"), function() {
|
||||||
frappe.route_options = {
|
frappe.route_options = {
|
||||||
"item_code": frm.doc.name
|
"item_code": frm.doc.name
|
||||||
}
|
}
|
||||||
frappe.set_route("query-report", "Stock Ledger");
|
frappe.set_route("query-report", "Stock Ledger");
|
||||||
}, __("View"));
|
}, __("View"));
|
||||||
frm.add_custom_button(__("Projected"), function() {
|
frm.add_custom_button(__("Stock Projected Qty"), function() {
|
||||||
frappe.route_options = {
|
frappe.route_options = {
|
||||||
"item_code": frm.doc.name
|
"item_code": frm.doc.name
|
||||||
}
|
}
|
||||||
|
@ -133,11 +133,11 @@
|
|||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-11-12 15:41:21.053462",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Landed Cost Item",
|
"name": "Landed Cost Item",
|
||||||
"owner": "wasim@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC"
|
"sort_order": "DESC"
|
||||||
|
@ -173,11 +173,11 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-07-20 10:49:34.228751",
|
"modified": "2020-09-18 17:26:09.703215",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Landed Cost Purchase Receipt",
|
"name": "Landed Cost Purchase Receipt",
|
||||||
"owner": "wasim@webnotestech.com",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 0,
|
"quick_entry": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
|
@ -494,8 +494,7 @@ class TestPurchaseReceipt(unittest.TestCase):
|
|||||||
"expected_value_after_useful_life": 10,
|
"expected_value_after_useful_life": 10,
|
||||||
"depreciation_method": "Straight Line",
|
"depreciation_method": "Straight Line",
|
||||||
"total_number_of_depreciations": 3,
|
"total_number_of_depreciations": 3,
|
||||||
"frequency_of_depreciation": 1,
|
"frequency_of_depreciation": 1
|
||||||
"depreciation_start_date": frappe.utils.nowdate()
|
|
||||||
})
|
})
|
||||||
asset.submit()
|
asset.submit()
|
||||||
|
|
||||||
|
@ -23,6 +23,24 @@ frappe.ui.form.on('Stock Entry', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.set_query('source_warehouse_address', function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
link_doctype: 'Warehouse',
|
||||||
|
link_name: frm.doc.from_warehouse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frm.set_query('target_warehouse_address', function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
link_doctype: 'Warehouse',
|
||||||
|
link_name: frm.doc.to_warehouse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
frappe.db.get_value('Stock Settings', {name: 'Stock Settings'}, 'sample_retention_warehouse', (r) => {
|
frappe.db.get_value('Stock Settings', {name: 'Stock Settings'}, 'sample_retention_warehouse', (r) => {
|
||||||
if (r.sample_retention_warehouse) {
|
if (r.sample_retention_warehouse) {
|
||||||
var filters = [
|
var filters = [
|
||||||
|
@ -9,13 +9,15 @@ frappe.query_reports["Batch-Wise Balance History"] = {
|
|||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"width": "80",
|
"width": "80",
|
||||||
"default": frappe.sys_defaults.year_start_date,
|
"default": frappe.sys_defaults.year_start_date,
|
||||||
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"to_date",
|
"fieldname":"to_date",
|
||||||
"label": __("To Date"),
|
"label": __("To Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"width": "80",
|
"width": "80",
|
||||||
"default": frappe.datetime.get_today()
|
"default": frappe.datetime.get_today(),
|
||||||
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "item",
|
"fieldname": "item",
|
||||||
|
@ -11,6 +11,9 @@ from frappe.utils import cint, flt, getdate
|
|||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
|
|
||||||
|
if filters.from_date > filters.to_date:
|
||||||
|
frappe.throw(_("From Date must be before To Date"))
|
||||||
|
|
||||||
float_precision = cint(frappe.db.get_default("float_precision")) or 3
|
float_precision = cint(frappe.db.get_default("float_precision")) or 3
|
||||||
|
|
||||||
columns = get_columns(filters)
|
columns = get_columns(filters)
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Reports",
|
"label": "Reports",
|
||||||
"links": "[\n {\n \"dependencies\": [\n \"Issue\"\n ],\n \"doctype\": \"Issue\",\n \"is_query_report\": true,\n \"label\": \"Minutes to First Response for Issues\",\n \"name\": \"Minutes to First Response for Issues\",\n \"type\": \"report\"\n }\n]"
|
"links": "[\n {\n \"dependencies\": [\n \"Issue\"\n ],\n \"doctype\": \"Issue\",\n \"is_query_report\": true,\n \"label\": \"First Response Time for Issues\",\n \"name\": \"First Response Time for Issues\",\n \"type\": \"report\"\n }\n]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"category": "Modules",
|
"category": "Modules",
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Support",
|
"label": "Support",
|
||||||
"modified": "2020-06-04 11:54:56.124219",
|
"modified": "2020-08-11 15:49:34.307341",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Support",
|
"module": "Support",
|
||||||
"name": "Support",
|
"name": "Support",
|
||||||
|
@ -2,8 +2,12 @@ frappe.ui.form.on("Issue", {
|
|||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
frm.email_field = "raised_by";
|
frm.email_field = "raised_by";
|
||||||
|
|
||||||
frappe.db.get_value("Support Settings", {name: "Support Settings"}, "allow_resetting_service_level_agreement", (r) => {
|
frappe.db.get_value("Support Settings", {name: "Support Settings"},
|
||||||
if (!r.allow_resetting_service_level_agreement) {
|
["allow_resetting_service_level_agreement", "track_service_level_agreement"], (r) => {
|
||||||
|
if (r && r.track_service_level_agreement == "0") {
|
||||||
|
frm.set_df_property("service_level_section", "hidden", 1);
|
||||||
|
}
|
||||||
|
if (r && r.allow_resetting_service_level_agreement == "0") {
|
||||||
frm.set_df_property("reset_service_level_agreement", "hidden", 1);
|
frm.set_df_property("reset_service_level_agreement", "hidden", 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -38,7 +42,7 @@ frappe.ui.form.on("Issue", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
refresh: function (frm) {
|
refresh: function (frm) {
|
||||||
if (frm.doc.status !== "Closed" && frm.doc.agreement_fulfilled === "Ongoing") {
|
if (frm.doc.status !== "Closed" && frm.doc.agreement_status === "Ongoing") {
|
||||||
if (frm.doc.service_level_agreement) {
|
if (frm.doc.service_level_agreement) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
'method': 'frappe.client.get',
|
'method': 'frappe.client.get',
|
||||||
@ -85,14 +89,14 @@ frappe.ui.form.on("Issue", {
|
|||||||
if (frm.doc.service_level_agreement) {
|
if (frm.doc.service_level_agreement) {
|
||||||
frm.dashboard.clear_headline();
|
frm.dashboard.clear_headline();
|
||||||
|
|
||||||
let agreement_fulfilled = (frm.doc.agreement_fulfilled == "Fulfilled") ?
|
let agreement_status = (frm.doc.agreement_status == "Fulfilled") ?
|
||||||
{"indicator": "green", "msg": "Service Level Agreement has been fulfilled"} :
|
{"indicator": "green", "msg": "Service Level Agreement has been fulfilled"} :
|
||||||
{"indicator": "red", "msg": "Service Level Agreement Failed"};
|
{"indicator": "red", "msg": "Service Level Agreement Failed"};
|
||||||
|
|
||||||
frm.dashboard.set_headline_alert(
|
frm.dashboard.set_headline_alert(
|
||||||
'<div class="row">' +
|
'<div class="row">' +
|
||||||
'<div class="col-xs-12">' +
|
'<div class="col-xs-12">' +
|
||||||
'<span class="indicator whitespace-nowrap '+ agreement_fulfilled.indicator +'"><span class="hidden-xs">'+ agreement_fulfilled.msg +'</span></span> ' +
|
'<span class="indicator whitespace-nowrap '+ agreement_status.indicator +'"><span class="hidden-xs">'+ agreement_status.msg +'</span></span> ' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>'
|
'</div>'
|
||||||
);
|
);
|
||||||
@ -198,13 +202,13 @@ function set_time_to_resolve_and_response(frm) {
|
|||||||
frm.dashboard.clear_headline();
|
frm.dashboard.clear_headline();
|
||||||
|
|
||||||
var time_to_respond = get_status(frm.doc.response_by_variance);
|
var time_to_respond = get_status(frm.doc.response_by_variance);
|
||||||
if (!frm.doc.first_responded_on && frm.doc.agreement_fulfilled === "Ongoing") {
|
if (!frm.doc.first_responded_on && frm.doc.agreement_status === "Ongoing") {
|
||||||
time_to_respond = get_time_left(frm.doc.response_by, frm.doc.agreement_fulfilled);
|
time_to_respond = get_time_left(frm.doc.response_by, frm.doc.agreement_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
var time_to_resolve = get_status(frm.doc.resolution_by_variance);
|
var time_to_resolve = get_status(frm.doc.resolution_by_variance);
|
||||||
if (!frm.doc.resolution_date && frm.doc.agreement_fulfilled === "Ongoing") {
|
if (!frm.doc.resolution_date && frm.doc.agreement_status === "Ongoing") {
|
||||||
time_to_resolve = get_time_left(frm.doc.resolution_by, frm.doc.agreement_fulfilled);
|
time_to_resolve = get_time_left(frm.doc.resolution_by, frm.doc.agreement_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
frm.dashboard.set_headline_alert(
|
frm.dashboard.set_headline_alert(
|
||||||
@ -219,10 +223,10 @@ function set_time_to_resolve_and_response(frm) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_time_left(timestamp, agreement_fulfilled) {
|
function get_time_left(timestamp, agreement_status) {
|
||||||
const diff = moment(timestamp).diff(moment());
|
const diff = moment(timestamp).diff(moment());
|
||||||
const diff_display = diff >= 44500 ? moment.duration(diff).humanize() : "Failed";
|
const diff_display = diff >= 44500 ? moment.duration(diff).humanize() : "Failed";
|
||||||
let indicator = (diff_display == 'Failed' && agreement_fulfilled != "Fulfilled") ? "red" : "green";
|
let indicator = (diff_display == 'Failed' && agreement_status != "Fulfilled") ? "red" : "green";
|
||||||
return {"diff_display": diff_display, "indicator": indicator};
|
return {"diff_display": diff_display, "indicator": indicator};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user