mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-09 08:02:51 +00:00
Merge branch 'develop' into patch-1
This commit is contained in:
14
.github/workflows/docker-release.yml
vendored
Normal file
14
.github/workflows/docker-release.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
name: Trigger Docker build on release
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [released]
|
||||||
|
jobs:
|
||||||
|
curl:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: alpine:latest
|
||||||
|
steps:
|
||||||
|
- name: curl
|
||||||
|
run: |
|
||||||
|
apk add curl bash
|
||||||
|
curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token ${{ secrets.TRAVIS_CI_TOKEN }}" -d '{"request":{"branch":"master"}}' https://api.travis-ci.com/repo/frappe%2Ffrappe_docker/requests
|
||||||
21
CODEOWNERS
21
CODEOWNERS
@@ -3,17 +3,16 @@
|
|||||||
# These owners will be the default owners for everything in
|
# These owners will be the default owners for everything in
|
||||||
# the repo. Unless a later match takes precedence,
|
# the repo. Unless a later match takes precedence,
|
||||||
|
|
||||||
* @nabinhait
|
manufacturing/ @rohitwaghchaure @marination
|
||||||
manufacturing/ @rohitwaghchaure
|
|
||||||
accounts/ @deepeshgarg007 @nextchamp-saqib
|
accounts/ @deepeshgarg007 @nextchamp-saqib
|
||||||
loan_management/ @deepeshgarg007
|
loan_management/ @deepeshgarg007 @rohitwaghchaure
|
||||||
pos* @nextchamp-saqib
|
pos* @nextchamp-saqib @rohitwaghchaure
|
||||||
assets/ @nextchamp-saqib
|
assets/ @nextchamp-saqib @deepeshgarg007
|
||||||
stock/ @marination @rohitwaghchaure
|
stock/ @marination @rohitwaghchaure
|
||||||
buying/ @marination @rohitwaghchaure
|
buying/ @marination @deepeshgarg007
|
||||||
hr/ @Anurag810
|
hr/ @Anurag810 @rohitwaghchaure
|
||||||
projects/ @hrwX
|
projects/ @hrwX @nextchamp-saqib
|
||||||
support/ @hrwX
|
support/ @hrwX @marination
|
||||||
healthcare/ @ruchamahabal
|
healthcare/ @ruchamahabal @marination
|
||||||
erpnext_integrations/ @Mangesh-Khairnar
|
erpnext_integrations/ @Mangesh-Khairnar @nextchamp-saqib
|
||||||
requirements.txt @gavindsouza
|
requirements.txt @gavindsouza
|
||||||
|
|||||||
@@ -5,7 +5,22 @@ import frappe
|
|||||||
import json
|
import json
|
||||||
from frappe.utils import nowdate, add_months, get_date_str
|
from frappe.utils import nowdate, add_months, get_date_str
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from erpnext.accounts.utils import get_fiscal_year, get_account_name
|
from erpnext.accounts.utils import get_fiscal_year, get_account_name, FiscalYearError
|
||||||
|
|
||||||
|
def _get_fiscal_year(date=None):
|
||||||
|
try:
|
||||||
|
fiscal_year = get_fiscal_year(date=nowdate(), as_dict=True)
|
||||||
|
return fiscal_year
|
||||||
|
|
||||||
|
except FiscalYearError:
|
||||||
|
#if no fiscal year for current date then get default fiscal year
|
||||||
|
try:
|
||||||
|
fiscal_year = get_fiscal_year(as_dict=True)
|
||||||
|
return fiscal_year
|
||||||
|
|
||||||
|
except FiscalYearError:
|
||||||
|
#if still no fiscal year found then no accounting data created, return
|
||||||
|
return None
|
||||||
|
|
||||||
def get_company_for_dashboards():
|
def get_company_for_dashboards():
|
||||||
company = frappe.defaults.get_defaults().company
|
company = frappe.defaults.get_defaults().company
|
||||||
@@ -18,10 +33,16 @@ def get_company_for_dashboards():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
|
|
||||||
|
fiscal_year = _get_fiscal_year(nowdate())
|
||||||
|
|
||||||
|
if not fiscal_year:
|
||||||
|
return frappe._dict()
|
||||||
|
|
||||||
return frappe._dict({
|
return frappe._dict({
|
||||||
"dashboards": get_dashboards(),
|
"dashboards": get_dashboards(),
|
||||||
"charts": get_charts(),
|
"charts": get_charts(fiscal_year),
|
||||||
"number_cards": get_number_cards()
|
"number_cards": get_number_cards(fiscal_year)
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_dashboards():
|
def get_dashboards():
|
||||||
@@ -46,10 +67,9 @@ def get_dashboards():
|
|||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def get_charts():
|
def get_charts(fiscal_year):
|
||||||
company = frappe.get_doc("Company", get_company_for_dashboards())
|
company = frappe.get_doc("Company", get_company_for_dashboards())
|
||||||
bank_account = company.default_bank_account or get_account_name("Bank", company=company.name)
|
bank_account = company.default_bank_account or get_account_name("Bank", company=company.name)
|
||||||
fiscal_year = get_fiscal_year(date=nowdate())
|
|
||||||
default_cost_center = company.cost_center
|
default_cost_center = company.cost_center
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@@ -60,9 +80,9 @@ def get_charts():
|
|||||||
"report_name": "Profit and Loss Statement",
|
"report_name": "Profit and Loss Statement",
|
||||||
"filters_json": json.dumps({
|
"filters_json": json.dumps({
|
||||||
"company": company.name,
|
"company": company.name,
|
||||||
"filter_based_on": "Date Range",
|
"filter_based_on": "Fiscal Year",
|
||||||
"period_start_date": get_date_str(fiscal_year[1]),
|
"from_fiscal_year": fiscal_year.get('name'),
|
||||||
"period_end_date": get_date_str(fiscal_year[2]),
|
"to_fiscal_year": fiscal_year.get('name'),
|
||||||
"periodicity": "Monthly",
|
"periodicity": "Monthly",
|
||||||
"include_default_book_entries": 1
|
"include_default_book_entries": 1
|
||||||
}),
|
}),
|
||||||
@@ -158,8 +178,8 @@ def get_charts():
|
|||||||
"report_name": "Budget Variance Report",
|
"report_name": "Budget Variance Report",
|
||||||
"filters_json": json.dumps({
|
"filters_json": json.dumps({
|
||||||
"company": company.name,
|
"company": company.name,
|
||||||
"from_fiscal_year": fiscal_year[0],
|
"from_fiscal_year": fiscal_year.get('name'),
|
||||||
"to_fiscal_year": fiscal_year[0],
|
"to_fiscal_year": fiscal_year.get('name'),
|
||||||
"period": "Monthly",
|
"period": "Monthly",
|
||||||
"budget_against": "Cost Center"
|
"budget_against": "Cost Center"
|
||||||
}),
|
}),
|
||||||
@@ -190,10 +210,10 @@ def get_charts():
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_number_cards():
|
def get_number_cards(fiscal_year):
|
||||||
fiscal_year = get_fiscal_year(date=nowdate())
|
|
||||||
year_start_date = get_date_str(fiscal_year[1])
|
year_start_date = get_date_str(fiscal_year.get("year_start_date"))
|
||||||
year_end_date = get_date_str(fiscal_year[2])
|
year_end_date = get_date_str(fiscal_year.get("year_end_date"))
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"doctype": "Number Card",
|
"doctype": "Number Card",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Accounts Receivable",
|
"label": "Accounts Receivable",
|
||||||
"links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Ordered Items To Be Billed\",\n \"name\": \"Ordered Items To Be Billed\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]"
|
"links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Accounting",
|
"label": "Accounting",
|
||||||
"modified": "2020-05-27 20:34:50.949772",
|
"modified": "2020-06-19 12:42:44.054598",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounting",
|
"name": "Accounting",
|
||||||
@@ -122,11 +122,6 @@
|
|||||||
"link_to": "Purchase Invoice",
|
"link_to": "Purchase Invoice",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"label": "Dashboard",
|
|
||||||
"link_to": "Accounts",
|
|
||||||
"type": "Dashboard"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"label": "Journal Entry",
|
"label": "Journal Entry",
|
||||||
"link_to": "Journal Entry",
|
"link_to": "Journal Entry",
|
||||||
@@ -151,6 +146,11 @@
|
|||||||
"label": "Trial Balance",
|
"label": "Trial Balance",
|
||||||
"link_to": "Trial Balance",
|
"link_to": "Trial Balance",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Dashboard",
|
||||||
|
"link_to": "Accounts",
|
||||||
|
"type": "Dashboard"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,9 @@ frappe.treeview_settings["Account"] = {
|
|||||||
on_change: function() {
|
on_change: function() {
|
||||||
var me = frappe.treeview_settings['Account'].treeview;
|
var me = frappe.treeview_settings['Account'].treeview;
|
||||||
var company = me.page.fields_dict.company.get_value();
|
var company = me.page.fields_dict.company.get_value();
|
||||||
|
if (!company) {
|
||||||
|
frappe.throw(__("Please set a Company"));
|
||||||
|
}
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.account.account.get_root_company",
|
method: "erpnext.accounts.doctype.account.account.get_root_company",
|
||||||
args: {
|
args: {
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ def make_dimension_in_accounting_doctypes(doc):
|
|||||||
if doctype == "Budget":
|
if doctype == "Budget":
|
||||||
add_dimension_to_budget_doctype(df, doc)
|
add_dimension_to_budget_doctype(df, doc)
|
||||||
else:
|
else:
|
||||||
|
meta = frappe.get_meta(doctype, cached=False)
|
||||||
|
fieldnames = [d.fieldname for d in meta.get("fields")]
|
||||||
|
|
||||||
|
if df['fieldname'] not in fieldnames:
|
||||||
create_custom_field(doctype, df)
|
create_custom_field(doctype, df)
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
|
|||||||
@@ -14,7 +14,18 @@ frappe.ui.form.on('Cost Center', {
|
|||||||
is_group: 1
|
is_group: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
frm.set_query("cost_center", "distributed_cost_center", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
company: frm.doc.company,
|
||||||
|
is_group: 0,
|
||||||
|
enable_distributed_cost_center: 0,
|
||||||
|
name: ['!=', frm.doc.name]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
},
|
},
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
if (!frm.is_new()) {
|
if (!frm.is_new()) {
|
||||||
@@ -60,8 +71,13 @@ frappe.ui.form.on('Cost Center', {
|
|||||||
"label": "Cost Center Number",
|
"label": "Cost Center Number",
|
||||||
"fieldname": "cost_center_number",
|
"fieldname": "cost_center_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"reqd": 1,
|
|
||||||
"default": frm.doc.cost_center_number
|
"default": frm.doc.cost_center_number
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": __("Merge with existing"),
|
||||||
|
"fieldname": "merge",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"default": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
@@ -76,8 +92,9 @@ frappe.ui.form.on('Cost Center', {
|
|||||||
args: {
|
args: {
|
||||||
docname: frm.doc.name,
|
docname: frm.doc.name,
|
||||||
cost_center_name: data.cost_center_name,
|
cost_center_name: data.cost_center_name,
|
||||||
cost_center_number: data.cost_center_number,
|
cost_center_number: cstr(data.cost_center_number),
|
||||||
company: frm.doc.company
|
company: frm.doc.company,
|
||||||
|
merge: data.merge
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
frappe.dom.unfreeze();
|
frappe.dom.unfreeze();
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
"cb0",
|
"cb0",
|
||||||
"is_group",
|
"is_group",
|
||||||
"disabled",
|
"disabled",
|
||||||
|
"section_break_9",
|
||||||
|
"enable_distributed_cost_center",
|
||||||
|
"distributed_cost_center",
|
||||||
"lft",
|
"lft",
|
||||||
"rgt",
|
"rgt",
|
||||||
"old_parent"
|
"old_parent"
|
||||||
@@ -119,13 +122,31 @@
|
|||||||
"fieldname": "disabled",
|
"fieldname": "disabled",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Disabled"
|
"label": "Disabled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "enable_distributed_cost_center",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Enable Distributed Cost Center"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.is_group==0",
|
||||||
|
"fieldname": "section_break_9",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "enable_distributed_cost_center",
|
||||||
|
"fieldname": "distributed_cost_center",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"label": "Distributed Cost Center",
|
||||||
|
"options": "Distributed Cost Center"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-money",
|
"icon": "fa fa-money",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_tree": 1,
|
"is_tree": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-29 16:09:30.025214",
|
"modified": "2020-06-17 16:09:30.025214",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Cost Center",
|
"name": "Cost Center",
|
||||||
|
|||||||
@@ -19,6 +19,24 @@ class CostCenter(NestedSet):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_mandatory()
|
self.validate_mandatory()
|
||||||
self.validate_parent_cost_center()
|
self.validate_parent_cost_center()
|
||||||
|
self.validate_distributed_cost_center()
|
||||||
|
|
||||||
|
def validate_distributed_cost_center(self):
|
||||||
|
if cint(self.enable_distributed_cost_center):
|
||||||
|
if not self.distributed_cost_center:
|
||||||
|
frappe.throw(_("Please enter distributed cost center"))
|
||||||
|
if sum(x.percentage_allocation for x in self.distributed_cost_center) != 100:
|
||||||
|
frappe.throw(_("Total percentage allocation for distributed cost center should be equal to 100"))
|
||||||
|
if not self.get('__islocal'):
|
||||||
|
if not cint(frappe.get_cached_value("Cost Center", {"name": self.name}, "enable_distributed_cost_center")) \
|
||||||
|
and self.check_if_part_of_distributed_cost_center():
|
||||||
|
frappe.throw(_("Cannot enable Distributed Cost Center for a Cost Center already allocated in another Distributed Cost Center"))
|
||||||
|
if next((True for x in self.distributed_cost_center if x.cost_center == x.parent), False):
|
||||||
|
frappe.throw(_("Parent Cost Center cannot be added in Distributed Cost Center"))
|
||||||
|
if check_if_distributed_cost_center_enabled(list(x.cost_center for x in self.distributed_cost_center)):
|
||||||
|
frappe.throw(_("A Distributed Cost Center cannot be added in the Distributed Cost Center allocation table."))
|
||||||
|
else:
|
||||||
|
self.distributed_cost_center = []
|
||||||
|
|
||||||
def validate_mandatory(self):
|
def validate_mandatory(self):
|
||||||
if self.cost_center_name != self.company and not self.parent_cost_center:
|
if self.cost_center_name != self.company and not self.parent_cost_center:
|
||||||
@@ -43,9 +61,12 @@ class CostCenter(NestedSet):
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
def convert_ledger_to_group(self):
|
def convert_ledger_to_group(self):
|
||||||
|
if cint(self.enable_distributed_cost_center):
|
||||||
|
frappe.throw(_("Cost Center with enabled distributed cost center can not be converted to group"))
|
||||||
|
if self.check_if_part_of_distributed_cost_center():
|
||||||
|
frappe.throw(_("Cost Center Already Allocated in a Distributed Cost Center cannot be converted to group"))
|
||||||
if self.check_gle_exists():
|
if self.check_gle_exists():
|
||||||
frappe.throw(_("Cost Center with existing transactions can not be converted to group"))
|
frappe.throw(_("Cost Center with existing transactions can not be converted to group"))
|
||||||
else:
|
|
||||||
self.is_group = 1
|
self.is_group = 1
|
||||||
self.save()
|
self.save()
|
||||||
return 1
|
return 1
|
||||||
@@ -57,6 +78,9 @@ class CostCenter(NestedSet):
|
|||||||
return frappe.db.sql("select name from `tabCost Center` where \
|
return frappe.db.sql("select name from `tabCost Center` where \
|
||||||
parent_cost_center = %s and docstatus != 2", self.name)
|
parent_cost_center = %s and docstatus != 2", self.name)
|
||||||
|
|
||||||
|
def check_if_part_of_distributed_cost_center(self):
|
||||||
|
return frappe.db.get_value("Distributed Cost Center", {"cost_center": self.name})
|
||||||
|
|
||||||
def before_rename(self, olddn, newdn, merge=False):
|
def before_rename(self, olddn, newdn, merge=False):
|
||||||
# Add company abbr if not provided
|
# Add company abbr if not provided
|
||||||
from erpnext.setup.doctype.company.company import get_name_with_abbr
|
from erpnext.setup.doctype.company.company import get_name_with_abbr
|
||||||
@@ -100,3 +124,7 @@ def get_name_with_number(new_account, account_number):
|
|||||||
if account_number and not new_account[0].isdigit():
|
if account_number and not new_account[0].isdigit():
|
||||||
new_account = account_number + " - " + new_account
|
new_account = account_number + " - " + new_account
|
||||||
return new_account
|
return new_account
|
||||||
|
|
||||||
|
def check_if_distributed_cost_center_enabled(cost_center_list):
|
||||||
|
value_list = frappe.get_list("Cost Center", {"name": ["in", cost_center_list]}, "enable_distributed_cost_center", as_list=1)
|
||||||
|
return next((True for x in value_list if x[0]), False)
|
||||||
@@ -22,6 +22,33 @@ class TestCostCenter(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(frappe.ValidationError, cost_center.save)
|
self.assertRaises(frappe.ValidationError, cost_center.save)
|
||||||
|
|
||||||
|
def test_validate_distributed_cost_center(self):
|
||||||
|
|
||||||
|
if not frappe.db.get_value('Cost Center', {'name': '_Test Cost Center - _TC'}):
|
||||||
|
frappe.get_doc(test_records[0]).insert()
|
||||||
|
|
||||||
|
if not frappe.db.get_value('Cost Center', {'name': '_Test Cost Center 2 - _TC'}):
|
||||||
|
frappe.get_doc(test_records[1]).insert()
|
||||||
|
|
||||||
|
invalid_distributed_cost_center = frappe.get_doc({
|
||||||
|
"company": "_Test Company",
|
||||||
|
"cost_center_name": "_Test Distributed Cost Center",
|
||||||
|
"doctype": "Cost Center",
|
||||||
|
"is_group": 0,
|
||||||
|
"parent_cost_center": "_Test Company - _TC",
|
||||||
|
"enable_distributed_cost_center": 1,
|
||||||
|
"distributed_cost_center": [{
|
||||||
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
|
"percentage_allocation": 40
|
||||||
|
}, {
|
||||||
|
"cost_center": "_Test Cost Center 2 - _TC",
|
||||||
|
"percentage_allocation": 50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
self.assertRaises(frappe.ValidationError, invalid_distributed_cost_center.save)
|
||||||
|
|
||||||
def create_cost_center(**args):
|
def create_cost_center(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
if args.cost_center_name:
|
if args.cost_center_name:
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"creation": "2020-03-19 12:34:01.500390",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"cost_center",
|
||||||
|
"percentage_allocation"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "cost_center",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Cost Center",
|
||||||
|
"options": "Cost Center",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "percentage_allocation",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Percentage Allocation",
|
||||||
|
"reqd": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2020-03-19 12:54:43.674655",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Distributed Cost Center",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class DistributedCostCenter(Document):
|
||||||
|
pass
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt, fmt_money, getdate, formatdate
|
from frappe.utils import flt, fmt_money, getdate, formatdate, cint
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.model.naming import set_name_from_naming_options
|
from frappe.model.naming import set_name_from_naming_options
|
||||||
from frappe.model.meta import get_field_precision
|
from frappe.model.meta import get_field_precision
|
||||||
@@ -134,10 +134,17 @@ class GLEntry(Document):
|
|||||||
|
|
||||||
return self.cost_center_company[self.cost_center]
|
return self.cost_center_company[self.cost_center]
|
||||||
|
|
||||||
|
def _check_is_group():
|
||||||
|
return cint(frappe.get_cached_value('Cost Center', self.cost_center, 'is_group'))
|
||||||
|
|
||||||
if self.cost_center and _get_cost_center_company() != self.company:
|
if self.cost_center and _get_cost_center_company() != self.company:
|
||||||
frappe.throw(_("{0} {1}: Cost Center {2} does not belong to Company {3}")
|
frappe.throw(_("{0} {1}: Cost Center {2} does not belong to Company {3}")
|
||||||
.format(self.voucher_type, self.voucher_no, self.cost_center, self.company))
|
.format(self.voucher_type, self.voucher_no, self.cost_center, self.company))
|
||||||
|
|
||||||
|
if self.cost_center and _check_is_group():
|
||||||
|
frappe.throw(_("""{0} {1}: Cost Center {2} is a group cost center and group cost centers cannot
|
||||||
|
be used in transactions""").format(self.voucher_type, self.voucher_no, frappe.bold(self.cost_center)))
|
||||||
|
|
||||||
def validate_party(self):
|
def validate_party(self):
|
||||||
validate_party_frozen_disabled(self.party_type, self.party)
|
validate_party_frozen_disabled(self.party_type, self.party)
|
||||||
|
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
|
|||||||
// payroll entry
|
// payroll entry
|
||||||
if(jvd.reference_type==="Payroll Entry") {
|
if(jvd.reference_type==="Payroll Entry") {
|
||||||
return {
|
return {
|
||||||
query: "erpnext.hr.doctype.payroll_entry.payroll_entry.get_payroll_entries_for_jv",
|
query: "erpnext.payroll.doctype.payroll_entry.payroll_entry.get_payroll_entries_for_jv",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -191,6 +191,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "total_debit",
|
"fieldname": "total_debit",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "Total Debit",
|
"label": "Total Debit",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "total_debit",
|
"oldfieldname": "total_debit",
|
||||||
@@ -252,7 +253,6 @@
|
|||||||
"fieldname": "total_amount",
|
"fieldname": "total_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Total Amount",
|
"label": "Total Amount",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "total_amount_currency",
|
"options": "total_amount_currency",
|
||||||
@@ -503,7 +503,7 @@
|
|||||||
"idx": 176,
|
"idx": 176,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-29 10:55:28.240916",
|
"modified": "2020-06-02 18:15:46.955697",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Journal Entry",
|
"name": "Journal Entry",
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class JournalEntry(AccountsController):
|
|||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
||||||
from erpnext.hr.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip
|
from erpnext.payroll.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip
|
||||||
unlink_ref_doc_from_payment_entries(self)
|
unlink_ref_doc_from_payment_entries(self)
|
||||||
unlink_ref_doc_from_salary_slip(self.name)
|
unlink_ref_doc_from_salary_slip(self.name)
|
||||||
self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry')
|
self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry')
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
|
"project",
|
||||||
"currency_section",
|
"currency_section",
|
||||||
"account_currency",
|
"account_currency",
|
||||||
"column_break_10",
|
"column_break_10",
|
||||||
@@ -32,7 +33,6 @@
|
|||||||
"reference_type",
|
"reference_type",
|
||||||
"reference_name",
|
"reference_name",
|
||||||
"reference_due_date",
|
"reference_due_date",
|
||||||
"project",
|
|
||||||
"col_break3",
|
"col_break3",
|
||||||
"is_advance",
|
"is_advance",
|
||||||
"user_remark",
|
"user_remark",
|
||||||
@@ -273,7 +273,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-25 01:47:49.060128",
|
"modified": "2020-06-18 14:06:54.833738",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Journal Entry Account",
|
"name": "Journal Entry Account",
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ class PaymentEntry(AccountsController):
|
|||||||
invoice_payment_amount_map.setdefault(key, 0.0)
|
invoice_payment_amount_map.setdefault(key, 0.0)
|
||||||
invoice_payment_amount_map[key] += reference.allocated_amount
|
invoice_payment_amount_map[key] += reference.allocated_amount
|
||||||
|
|
||||||
if not invoice_paid_amount_map.get(reference.reference_name):
|
if not invoice_paid_amount_map.get(key):
|
||||||
payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': reference.reference_name},
|
payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': reference.reference_name},
|
||||||
fields=['paid_amount', 'payment_amount', 'payment_term'])
|
fields=['paid_amount', 'payment_amount', 'payment_term'])
|
||||||
for term in payment_schedule:
|
for term in payment_schedule:
|
||||||
@@ -332,10 +332,12 @@ class PaymentEntry(AccountsController):
|
|||||||
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` - %s
|
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` - %s
|
||||||
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
||||||
else:
|
else:
|
||||||
outstanding = invoice_paid_amount_map.get(key)['outstanding']
|
outstanding = flt(invoice_paid_amount_map.get(key, {}).get('outstanding'))
|
||||||
|
|
||||||
if amount > outstanding:
|
if amount > outstanding:
|
||||||
frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
|
frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
|
||||||
|
|
||||||
|
if amount and outstanding:
|
||||||
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` + %s
|
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` + %s
|
||||||
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
||||||
|
|
||||||
@@ -451,6 +453,8 @@ 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.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}")
|
||||||
.format(self.paid_from_account_currency, self.paid_amount, self.paid_from, self.paid_to)]
|
.format(self.paid_from_account_currency, self.paid_amount, self.paid_from, self.paid_to)]
|
||||||
@@ -1091,6 +1095,10 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
|
def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
|
||||||
references = []
|
references = []
|
||||||
for payment_term in payment_schedule:
|
for payment_term in payment_schedule:
|
||||||
|
payment_term_outstanding = flt(payment_term.payment_amount - payment_term.paid_amount,
|
||||||
|
payment_term.precision('payment_amount'))
|
||||||
|
|
||||||
|
if payment_term_outstanding:
|
||||||
references.append({
|
references.append({
|
||||||
'reference_doctype': dt,
|
'reference_doctype': dt,
|
||||||
'reference_name': dn,
|
'reference_name': dn,
|
||||||
@@ -1099,8 +1107,7 @@ def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_tota
|
|||||||
'total_amount': grand_total,
|
'total_amount': grand_total,
|
||||||
'outstanding_amount': outstanding_amount,
|
'outstanding_amount': outstanding_amount,
|
||||||
'payment_term': payment_term.payment_term,
|
'payment_term': payment_term.payment_term,
|
||||||
'allocated_amount': flt(payment_term.payment_amount - payment_term.paid_amount,
|
'allocated_amount': payment_term_outstanding
|
||||||
payment_term.precision('payment_amount'))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return references
|
return references
|
||||||
|
|||||||
@@ -349,9 +349,10 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"in_create": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-05-08 10:23:02.815237",
|
"modified": "2020-05-29 17:38:49.392713",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Request",
|
"name": "Payment Request",
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ from six import string_types
|
|||||||
apply_on_dict = {"Item Code": "items",
|
apply_on_dict = {"Item Code": "items",
|
||||||
"Item Group": "item_groups", "Brand": "brands"}
|
"Item Group": "item_groups", "Brand": "brands"}
|
||||||
|
|
||||||
|
other_fields = ["other_item_code", "other_item_group", "other_brand"]
|
||||||
|
|
||||||
class PricingRule(Document):
|
class PricingRule(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_mandatory()
|
self.validate_mandatory()
|
||||||
@@ -47,6 +49,13 @@ class PricingRule(Document):
|
|||||||
if tocheck and not self.get(tocheck):
|
if tocheck and not self.get(tocheck):
|
||||||
throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError)
|
throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError)
|
||||||
|
|
||||||
|
if self.apply_rule_on_other:
|
||||||
|
o_field = 'other_' + frappe.scrub(self.apply_rule_on_other)
|
||||||
|
if not self.get(o_field) and o_field in other_fields:
|
||||||
|
frappe.throw(_("For the 'Apply Rule On Other' condition the field {0} is mandatory")
|
||||||
|
.format(frappe.bold(self.apply_rule_on_other)))
|
||||||
|
|
||||||
|
|
||||||
if self.price_or_product_discount == 'Price' and not self.rate_or_discount:
|
if self.price_or_product_discount == 'Price' and not self.rate_or_discount:
|
||||||
throw(_("Rate or Discount is required for the price discount."), frappe.MandatoryError)
|
throw(_("Rate or Discount is required for the price discount."), frappe.MandatoryError)
|
||||||
|
|
||||||
@@ -80,13 +89,27 @@ class PricingRule(Document):
|
|||||||
for f in options:
|
for f in options:
|
||||||
if not f: continue
|
if not f: continue
|
||||||
|
|
||||||
f = frappe.scrub(f)
|
scrubbed_f = frappe.scrub(f)
|
||||||
if f!=fieldname:
|
|
||||||
self.set(f, None)
|
if logic_field == 'apply_on':
|
||||||
|
apply_on_f = apply_on_dict.get(f, f)
|
||||||
|
else:
|
||||||
|
apply_on_f = scrubbed_f
|
||||||
|
|
||||||
|
if scrubbed_f != fieldname:
|
||||||
|
self.set(apply_on_f, None)
|
||||||
|
|
||||||
if self.mixed_conditions and self.get("same_item"):
|
if self.mixed_conditions and self.get("same_item"):
|
||||||
self.same_item = 0
|
self.same_item = 0
|
||||||
|
|
||||||
|
apply_rule_on_other = frappe.scrub(self.apply_rule_on_other or "")
|
||||||
|
|
||||||
|
cleanup_other_fields = (other_fields if not apply_rule_on_other
|
||||||
|
else [o_field for o_field in other_fields if o_field != 'other_' + apply_rule_on_other])
|
||||||
|
|
||||||
|
for other_field in cleanup_other_fields:
|
||||||
|
self.set(other_field, None)
|
||||||
|
|
||||||
def validate_rate_or_discount(self):
|
def validate_rate_or_discount(self):
|
||||||
for field in ["Rate"]:
|
for field in ["Rate"]:
|
||||||
if flt(self.get(frappe.scrub(field))) < 0:
|
if flt(self.get(frappe.scrub(field))) < 0:
|
||||||
|
|||||||
@@ -386,6 +386,50 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
self.assertEqual(so.items[1].is_free_item, 1)
|
self.assertEqual(so.items[1].is_free_item, 1)
|
||||||
self.assertEqual(so.items[1].item_code, "_Test Item 2")
|
self.assertEqual(so.items[1].item_code, "_Test Item 2")
|
||||||
|
|
||||||
|
def test_cumulative_pricing_rule(self):
|
||||||
|
frappe.delete_doc_if_exists('Pricing Rule', '_Test Cumulative Pricing Rule')
|
||||||
|
test_record = {
|
||||||
|
"doctype": "Pricing Rule",
|
||||||
|
"title": "_Test Cumulative Pricing Rule",
|
||||||
|
"apply_on": "Item Code",
|
||||||
|
"currency": "USD",
|
||||||
|
"items": [{
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
}],
|
||||||
|
"is_cumulative": 1,
|
||||||
|
"selling": 1,
|
||||||
|
"applicable_for": "Customer",
|
||||||
|
"customer": "_Test Customer",
|
||||||
|
"rate_or_discount": "Discount Percentage",
|
||||||
|
"rate": 0,
|
||||||
|
"min_amt": 0,
|
||||||
|
"max_amt": 10000,
|
||||||
|
"discount_percentage": 17.5,
|
||||||
|
"price_or_product_discount": "Price",
|
||||||
|
"company": "_Test Company",
|
||||||
|
"valid_from": frappe.utils.nowdate(),
|
||||||
|
"valid_upto": frappe.utils.nowdate()
|
||||||
|
}
|
||||||
|
frappe.get_doc(test_record.copy()).insert()
|
||||||
|
|
||||||
|
args = frappe._dict({
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
"company": "_Test Company",
|
||||||
|
"price_list": "_Test Price List",
|
||||||
|
"currency": "_Test Currency",
|
||||||
|
"doctype": "Sales Invoice",
|
||||||
|
"conversion_rate": 1,
|
||||||
|
"price_list_currency": "_Test Currency",
|
||||||
|
"plc_conversion_rate": 1,
|
||||||
|
"order_type": "Sales",
|
||||||
|
"customer": "_Test Customer",
|
||||||
|
"name": None,
|
||||||
|
"transaction_date": frappe.utils.nowdate()
|
||||||
|
})
|
||||||
|
details = get_item_details(args)
|
||||||
|
|
||||||
|
self.assertTrue(details)
|
||||||
|
|
||||||
def make_pricing_rule(**args):
|
def make_pricing_rule(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|
||||||
|
|||||||
@@ -366,8 +366,7 @@ def get_qty_amount_data_for_cumulative(pr_doc, doc, items=[]):
|
|||||||
sum_qty, sum_amt = [0, 0]
|
sum_qty, sum_amt = [0, 0]
|
||||||
doctype = doc.get('parenttype') or doc.doctype
|
doctype = doc.get('parenttype') or doc.doctype
|
||||||
|
|
||||||
date_field = ('transaction_date'
|
date_field = 'transaction_date' if frappe.get_meta(doctype).has_field('transaction_date') else 'posting_date'
|
||||||
if doc.get('transaction_date') else 'posting_date')
|
|
||||||
|
|
||||||
child_doctype = '{0} Item'.format(doctype)
|
child_doctype = '{0} Item'.format(doctype)
|
||||||
apply_on = frappe.scrub(pr_doc.get('apply_on'))
|
apply_on = frappe.scrub(pr_doc.get('apply_on'))
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -238,6 +238,12 @@ class PurchaseInvoice(BuyingController):
|
|||||||
not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")):
|
not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")):
|
||||||
|
|
||||||
if self.update_stock and (not item.from_warehouse):
|
if self.update_stock and (not item.from_warehouse):
|
||||||
|
if for_validate and item.expense_account and item.expense_account != warehouse_account[item.warehouse]["account"]:
|
||||||
|
frappe.msgprint(_('''Row {0}: Expense Head changed to {1} because account {2}
|
||||||
|
is not linked to warehouse {3} or it is not the default inventory account'''.format(
|
||||||
|
item.idx, frappe.bold(warehouse_account[item.warehouse]["account"]),
|
||||||
|
frappe.bold(item.expense_account), frappe.bold(item.warehouse))))
|
||||||
|
|
||||||
item.expense_account = warehouse_account[item.warehouse]["account"]
|
item.expense_account = warehouse_account[item.warehouse]["account"]
|
||||||
else:
|
else:
|
||||||
# check if 'Stock Received But Not Billed' account is credited in Purchase receipt or not
|
# check if 'Stock Received But Not Billed' account is credited in Purchase receipt or not
|
||||||
@@ -247,10 +253,21 @@ class PurchaseInvoice(BuyingController):
|
|||||||
(item.purchase_receipt, stock_not_billed_account))
|
(item.purchase_receipt, stock_not_billed_account))
|
||||||
|
|
||||||
if negative_expense_booked_in_pr:
|
if negative_expense_booked_in_pr:
|
||||||
|
if for_validate and item.expense_account and item.expense_account != stock_not_billed_account:
|
||||||
|
frappe.msgprint(_('''Row {0}: Expense Head changed to {1} because
|
||||||
|
expense is booked against this account in Purchase Receipt {2}'''.format(
|
||||||
|
item.idx, frappe.bold(stock_not_billed_account), frappe.bold(item.purchase_receipt))))
|
||||||
|
|
||||||
item.expense_account = stock_not_billed_account
|
item.expense_account = stock_not_billed_account
|
||||||
else:
|
else:
|
||||||
# If no purchase receipt present then book expense in 'Stock Received But Not Billed'
|
# If no purchase receipt present then book expense in 'Stock Received But Not Billed'
|
||||||
# This is done in cases when Purchase Invoice is created before Purchase Receipt
|
# This is done in cases when Purchase Invoice is created before Purchase Receipt
|
||||||
|
if for_validate and item.expense_account and item.expense_account != stock_not_billed_account:
|
||||||
|
frappe.msgprint(_('''Row {0}: Expense Head changed to {1} as no Purchase
|
||||||
|
Receipt is created against Item {2}. This is done to handle accounting for cases
|
||||||
|
when Purchase Receipt is created after Purchase Invoice'''.format(
|
||||||
|
item.idx, frappe.bold(stock_not_billed_account), frappe.bold(item.item_code))))
|
||||||
|
|
||||||
item.expense_account = stock_not_billed_account
|
item.expense_account = stock_not_billed_account
|
||||||
|
|
||||||
elif item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category):
|
elif item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category):
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ frappe.listview_settings['Purchase Invoice'] = {
|
|||||||
} else if(frappe.datetime.get_diff(doc.due_date) < 0) {
|
} else if(frappe.datetime.get_diff(doc.due_date) < 0) {
|
||||||
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<,Today"];
|
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<,Today"];
|
||||||
} else {
|
} else {
|
||||||
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due,>=,Today"];
|
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>=,Today"];
|
||||||
}
|
}
|
||||||
} else if(cint(doc.is_return)) {
|
} else if(cint(doc.is_return)) {
|
||||||
return [__("Return"), "darkgrey", "is_return,=,Yes"];
|
return [__("Return"), "darkgrey", "is_return,=,Yes"];
|
||||||
|
|||||||
@@ -582,14 +582,14 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
def validate_item_code(self):
|
def validate_item_code(self):
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
if not d.item_code:
|
if not d.item_code and self.is_opening == "No":
|
||||||
msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
|
msgprint(_("Item Code required at Row No {0}").format(d.idx), raise_exception=True)
|
||||||
|
|
||||||
def validate_warehouse(self):
|
def validate_warehouse(self):
|
||||||
super(SalesInvoice, self).validate_warehouse()
|
super(SalesInvoice, self).validate_warehouse()
|
||||||
|
|
||||||
for d in self.get_item_list():
|
for d in self.get_item_list():
|
||||||
if not d.warehouse and frappe.get_cached_value("Item", d.item_code, "is_stock_item"):
|
if not d.warehouse and d.item_code and frappe.get_cached_value("Item", d.item_code, "is_stock_item"):
|
||||||
frappe.throw(_("Warehouse required for stock Item {0}").format(d.item_code))
|
frappe.throw(_("Warehouse required for stock Item {0}").format(d.item_code))
|
||||||
|
|
||||||
def validate_delivery_note(self):
|
def validate_delivery_note(self):
|
||||||
@@ -1450,11 +1450,17 @@ def get_inter_company_details(doc, doctype):
|
|||||||
parties = frappe.db.get_all("Supplier", fields=["name"], filters={"disabled": 0, "is_internal_supplier": 1, "represents_company": doc.company})
|
parties = frappe.db.get_all("Supplier", fields=["name"], filters={"disabled": 0, "is_internal_supplier": 1, "represents_company": doc.company})
|
||||||
company = frappe.get_cached_value("Customer", doc.customer, "represents_company")
|
company = frappe.get_cached_value("Customer", doc.customer, "represents_company")
|
||||||
|
|
||||||
|
if not parties:
|
||||||
|
frappe.throw(_('No Supplier found for Inter Company Transactions which represents company {0}').format(frappe.bold(doc.company)))
|
||||||
|
|
||||||
party = get_internal_party(parties, "Supplier", doc)
|
party = get_internal_party(parties, "Supplier", doc)
|
||||||
else:
|
else:
|
||||||
parties = frappe.db.get_all("Customer", fields=["name"], filters={"disabled": 0, "is_internal_customer": 1, "represents_company": doc.company})
|
parties = frappe.db.get_all("Customer", fields=["name"], filters={"disabled": 0, "is_internal_customer": 1, "represents_company": doc.company})
|
||||||
company = frappe.get_cached_value("Supplier", doc.supplier, "represents_company")
|
company = frappe.get_cached_value("Supplier", doc.supplier, "represents_company")
|
||||||
|
|
||||||
|
if not parties:
|
||||||
|
frappe.throw(_('No Customer found for Inter Company Transactions which represents company {0}').format(frappe.bold(doc.company)))
|
||||||
|
|
||||||
party = get_internal_party(parties, "Customer", doc)
|
party = get_internal_party(parties, "Customer", doc)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -1519,14 +1525,22 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
|
|||||||
def update_details(source_doc, target_doc, source_parent):
|
def update_details(source_doc, target_doc, source_parent):
|
||||||
target_doc.inter_company_invoice_reference = source_doc.name
|
target_doc.inter_company_invoice_reference = source_doc.name
|
||||||
if target_doc.doctype in ["Purchase Invoice", "Purchase Order"]:
|
if target_doc.doctype in ["Purchase Invoice", "Purchase Order"]:
|
||||||
|
currency = frappe.db.get_value('Supplier', details.get('party'), 'default_currency')
|
||||||
target_doc.company = details.get("company")
|
target_doc.company = details.get("company")
|
||||||
target_doc.supplier = details.get("party")
|
target_doc.supplier = details.get("party")
|
||||||
target_doc.buying_price_list = source_doc.selling_price_list
|
target_doc.buying_price_list = source_doc.selling_price_list
|
||||||
|
|
||||||
|
if currency:
|
||||||
|
target_doc.currency = currency
|
||||||
else:
|
else:
|
||||||
|
currency = frappe.db.get_value('Customer', details.get('party'), 'default_currency')
|
||||||
target_doc.company = details.get("company")
|
target_doc.company = details.get("company")
|
||||||
target_doc.customer = details.get("party")
|
target_doc.customer = details.get("party")
|
||||||
target_doc.selling_price_list = source_doc.buying_price_list
|
target_doc.selling_price_list = source_doc.buying_price_list
|
||||||
|
|
||||||
|
if currency:
|
||||||
|
target_doc.currency = currency
|
||||||
|
|
||||||
doclist = get_mapped_doc(doctype, source_name, {
|
doclist = get_mapped_doc(doctype, source_name, {
|
||||||
doctype: {
|
doctype: {
|
||||||
"doctype": target_doctype,
|
"doctype": target_doctype,
|
||||||
|
|||||||
@@ -1745,53 +1745,6 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
check_gl_entries(self, si.name, expected_gle, "2019-01-30")
|
check_gl_entries(self, si.name, expected_gle, "2019-01-30")
|
||||||
|
|
||||||
def test_deferred_error_email(self):
|
|
||||||
deferred_account = create_account(account_name="Deferred Revenue",
|
|
||||||
parent_account="Current Liabilities - _TC", company="_Test Company")
|
|
||||||
|
|
||||||
item = create_item("_Test Item for Deferred Accounting")
|
|
||||||
item.enable_deferred_revenue = 1
|
|
||||||
item.deferred_revenue_account = deferred_account
|
|
||||||
item.no_of_months = 12
|
|
||||||
item.save()
|
|
||||||
|
|
||||||
si = create_sales_invoice(item=item.name, posting_date="2019-01-10", do_not_submit=True)
|
|
||||||
si.items[0].enable_deferred_revenue = 1
|
|
||||||
si.items[0].service_start_date = "2019-01-10"
|
|
||||||
si.items[0].service_end_date = "2019-03-15"
|
|
||||||
si.items[0].deferred_revenue_account = deferred_account
|
|
||||||
si.save()
|
|
||||||
si.submit()
|
|
||||||
|
|
||||||
from erpnext.accounts.deferred_revenue import convert_deferred_revenue_to_income
|
|
||||||
|
|
||||||
acc_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
|
|
||||||
acc_settings.acc_frozen_upto = '2019-01-31'
|
|
||||||
acc_settings.save()
|
|
||||||
|
|
||||||
pda = frappe.get_doc(dict(
|
|
||||||
doctype='Process Deferred Accounting',
|
|
||||||
posting_date=nowdate(),
|
|
||||||
start_date="2019-01-01",
|
|
||||||
end_date="2019-03-31",
|
|
||||||
type="Income",
|
|
||||||
company="_Test Company"
|
|
||||||
))
|
|
||||||
|
|
||||||
pda.insert()
|
|
||||||
pda.submit()
|
|
||||||
|
|
||||||
email = frappe.db.sql(""" select name from `tabEmail Queue`
|
|
||||||
where message like %(txt)s """, {
|
|
||||||
'txt': "%%%s%%" % "Error while processing deferred accounting for {0}".format(pda.name)
|
|
||||||
})
|
|
||||||
|
|
||||||
self.assertTrue(email)
|
|
||||||
|
|
||||||
acc_settings.load_from_db()
|
|
||||||
acc_settings.acc_frozen_upto = None
|
|
||||||
acc_settings.save()
|
|
||||||
|
|
||||||
def test_inter_company_transaction(self):
|
def test_inter_company_transaction(self):
|
||||||
|
|
||||||
if not frappe.db.exists("Customer", "_Test Internal Customer"):
|
if not frappe.db.exists("Customer", "_Test Internal Customer"):
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ class ShippingRule(Document):
|
|||||||
shipping_amount = 0.0
|
shipping_amount = 0.0
|
||||||
by_value = False
|
by_value = False
|
||||||
|
|
||||||
|
if doc.get_shipping_address():
|
||||||
|
# validate country only if there is address
|
||||||
self.validate_countries(doc)
|
self.validate_countries(doc)
|
||||||
|
|
||||||
if self.calculate_based_on == 'Net Total':
|
if self.calculate_based_on == 'Net Total':
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ def make_sales_invoice():
|
|||||||
debit_to = 'Debtors - _TC2',
|
debit_to = 'Debtors - _TC2',
|
||||||
income_account = 'Sales - _TC2',
|
income_account = 'Sales - _TC2',
|
||||||
expense_account = 'Cost of Goods Sold - _TC2',
|
expense_account = 'Cost of Goods Sold - _TC2',
|
||||||
cost_center = '_Test Company 2 - _TC2')
|
cost_center = 'Main - _TC2')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,8 @@ class ReceivablePayableReport(object):
|
|||||||
|
|
||||||
def append_subtotal_row(self, party):
|
def append_subtotal_row(self, party):
|
||||||
sub_total_row = self.total_row_map.get(party)
|
sub_total_row = self.total_row_map.get(party)
|
||||||
|
|
||||||
|
if sub_total_row:
|
||||||
self.data.append(sub_total_row)
|
self.data.append(sub_total_row)
|
||||||
self.data.append({})
|
self.data.append({})
|
||||||
self.update_sub_total_row(sub_total_row, 'Total')
|
self.update_sub_total_row(sub_total_row, 'Total')
|
||||||
@@ -232,6 +234,7 @@ class ReceivablePayableReport(object):
|
|||||||
|
|
||||||
if self.filters.get('group_by_party'):
|
if self.filters.get('group_by_party'):
|
||||||
self.append_subtotal_row(self.previous_party)
|
self.append_subtotal_row(self.previous_party)
|
||||||
|
if self.data:
|
||||||
self.data.append(self.total_row_map.get('Total'))
|
self.data.append(self.total_row_map.get('Total'))
|
||||||
|
|
||||||
def append_row(self, row):
|
def append_row(self, row):
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ def make_sales_invoice():
|
|||||||
debit_to = 'Debtors - _TC2',
|
debit_to = 'Debtors - _TC2',
|
||||||
income_account = 'Sales - _TC2',
|
income_account = 'Sales - _TC2',
|
||||||
expense_account = 'Cost of Goods Sold - _TC2',
|
expense_account = 'Cost of Goods Sold - _TC2',
|
||||||
cost_center = '_Test Company 2 - _TC2',
|
cost_center = 'Main - _TC2',
|
||||||
do_not_save=1)
|
do_not_save=1)
|
||||||
|
|
||||||
si.append('payment_schedule', dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30))
|
si.append('payment_schedule', dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30))
|
||||||
@@ -90,7 +90,7 @@ def make_credit_note(docname):
|
|||||||
debit_to = 'Debtors - _TC2',
|
debit_to = 'Debtors - _TC2',
|
||||||
income_account = 'Sales - _TC2',
|
income_account = 'Sales - _TC2',
|
||||||
expense_account = 'Cost of Goods Sold - _TC2',
|
expense_account = 'Cost of Goods Sold - _TC2',
|
||||||
cost_center = '_Test Company 2 - _TC2',
|
cost_center = 'Main - _TC2',
|
||||||
is_return = 1,
|
is_return = 1,
|
||||||
return_against = docname)
|
return_against = docname)
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ def get_assets(filters):
|
|||||||
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
|
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
|
||||||
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
|
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
|
||||||
from (SELECT a.asset_category,
|
from (SELECT a.asset_category,
|
||||||
ifnull(sum(case when ds.schedule_date < %(from_date)s then
|
ifnull(sum(case when ds.schedule_date < %(from_date)s and (ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s) then
|
||||||
ds.depreciation_amount
|
ds.depreciation_amount
|
||||||
else
|
else
|
||||||
0
|
0
|
||||||
@@ -115,9 +115,7 @@ def get_assets(filters):
|
|||||||
group by a.asset_category
|
group by a.asset_category
|
||||||
union
|
union
|
||||||
SELECT a.asset_category,
|
SELECT a.asset_category,
|
||||||
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
|
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) then
|
||||||
and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s)
|
|
||||||
then
|
|
||||||
0
|
0
|
||||||
else
|
else
|
||||||
a.opening_accumulated_depreciation
|
a.opening_accumulated_depreciation
|
||||||
|
|||||||
@@ -29,6 +29,26 @@ def execute(filters=None):
|
|||||||
for dimension in dimensions:
|
for dimension in dimensions:
|
||||||
dimension_items = cam_map.get(dimension)
|
dimension_items = cam_map.get(dimension)
|
||||||
if dimension_items:
|
if dimension_items:
|
||||||
|
data = get_final_data(dimension, dimension_items, filters, period_month_ranges, data, 0)
|
||||||
|
else:
|
||||||
|
DCC_allocation = frappe.db.sql('''SELECT parent, sum(percentage_allocation) as percentage_allocation
|
||||||
|
FROM `tabDistributed Cost Center`
|
||||||
|
WHERE cost_center IN %(dimension)s
|
||||||
|
AND parent NOT IN %(dimension)s
|
||||||
|
GROUP BY parent''',{'dimension':[dimension]})
|
||||||
|
if DCC_allocation:
|
||||||
|
filters['budget_against_filter'] = [DCC_allocation[0][0]]
|
||||||
|
cam_map = get_dimension_account_month_map(filters)
|
||||||
|
dimension_items = cam_map.get(DCC_allocation[0][0])
|
||||||
|
if dimension_items:
|
||||||
|
data = get_final_data(dimension, dimension_items, filters, period_month_ranges, data, DCC_allocation[0][1])
|
||||||
|
|
||||||
|
chart = get_chart_data(filters, columns, data)
|
||||||
|
|
||||||
|
return columns, data, None, chart
|
||||||
|
|
||||||
|
def get_final_data(dimension, dimension_items, filters, period_month_ranges, data, DCC_allocation):
|
||||||
|
|
||||||
for account, monthwise_data in iteritems(dimension_items):
|
for account, monthwise_data in iteritems(dimension_items):
|
||||||
row = [dimension, account]
|
row = [dimension, account]
|
||||||
totals = [0, 0, 0]
|
totals = [0, 0, 0]
|
||||||
@@ -46,7 +66,11 @@ def execute(filters=None):
|
|||||||
|
|
||||||
period_data[0] += last_total
|
period_data[0] += last_total
|
||||||
|
|
||||||
if filters.get("show_cumulative"):
|
if DCC_allocation:
|
||||||
|
period_data[0] = period_data[0]*(DCC_allocation/100)
|
||||||
|
period_data[1] = period_data[1]*(DCC_allocation/100)
|
||||||
|
|
||||||
|
if(filters.get("show_cumulative")):
|
||||||
last_total = period_data[0] - period_data[1]
|
last_total = period_data[0] - period_data[1]
|
||||||
|
|
||||||
period_data[2] = period_data[0] - period_data[1]
|
period_data[2] = period_data[0] - period_data[1]
|
||||||
@@ -56,9 +80,8 @@ def execute(filters=None):
|
|||||||
row += totals
|
row += totals
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|
||||||
chart = get_chart_data(filters, columns, data)
|
return data
|
||||||
|
|
||||||
return columns, data, None, chart
|
|
||||||
|
|
||||||
def get_columns(filters):
|
def get_columns(filters):
|
||||||
columns = [
|
columns = [
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ frappe.query_reports["Consolidated Financial Statement"] = {
|
|||||||
"fieldname":"period_start_date",
|
"fieldname":"period_start_date",
|
||||||
"label": __("Start Date"),
|
"label": __("Start Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"default": frappe.datetime.nowdate(),
|
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
@@ -41,7 +40,6 @@ frappe.query_reports["Consolidated Financial Statement"] = {
|
|||||||
"fieldname":"period_end_date",
|
"fieldname":"period_end_date",
|
||||||
"label": __("End Date"),
|
"label": __("End Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"default": frappe.datetime.add_months(frappe.datetime.nowdate(), 12),
|
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
@@ -106,5 +104,16 @@ frappe.query_reports["Consolidated Financial Statement"] = {
|
|||||||
value = $value.wrap("<p></p>").parent().html();
|
value = $value.wrap("<p></p>").parent().html();
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
},
|
||||||
|
onload: function() {
|
||||||
|
let fiscal_year = frappe.defaults.get_user_default("fiscal_year")
|
||||||
|
|
||||||
|
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
|
||||||
|
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
|
||||||
|
frappe.query_report.set_filter_value({
|
||||||
|
period_start_date: fy.year_start_date,
|
||||||
|
period_end_date: fy.year_end_date
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,8 +56,7 @@ def get_period_list(from_fiscal_year, to_fiscal_year, period_start_date, period_
|
|||||||
to_date = add_months(start_date, months_to_add)
|
to_date = add_months(start_date, months_to_add)
|
||||||
start_date = to_date
|
start_date = to_date
|
||||||
|
|
||||||
if to_date == get_first_day(to_date):
|
# Subtract one day from to_date, as it may be first day in next fiscal year or month
|
||||||
# if to_date is the first day, get the last day of previous month
|
|
||||||
to_date = add_days(to_date, -1)
|
to_date = add_days(to_date, -1)
|
||||||
|
|
||||||
if to_date <= year_end_date:
|
if to_date <= year_end_date:
|
||||||
@@ -387,11 +386,43 @@ def set_gl_entries_by_account(
|
|||||||
key: value
|
key: value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
distributed_cost_center_query = ""
|
||||||
|
if filters and filters.get('cost_center'):
|
||||||
|
distributed_cost_center_query = """
|
||||||
|
UNION ALL
|
||||||
|
SELECT posting_date,
|
||||||
|
account,
|
||||||
|
debit*(DCC_allocation.percentage_allocation/100) as debit,
|
||||||
|
credit*(DCC_allocation.percentage_allocation/100) as credit,
|
||||||
|
is_opening,
|
||||||
|
fiscal_year,
|
||||||
|
debit_in_account_currency*(DCC_allocation.percentage_allocation/100) as debit_in_account_currency,
|
||||||
|
credit_in_account_currency*(DCC_allocation.percentage_allocation/100) as credit_in_account_currency,
|
||||||
|
account_currency
|
||||||
|
FROM `tabGL Entry`,
|
||||||
|
(
|
||||||
|
SELECT parent, sum(percentage_allocation) as percentage_allocation
|
||||||
|
FROM `tabDistributed Cost Center`
|
||||||
|
WHERE cost_center IN %(cost_center)s
|
||||||
|
AND parent NOT IN %(cost_center)s
|
||||||
|
AND is_cancelled = 0
|
||||||
|
GROUP BY parent
|
||||||
|
) as DCC_allocation
|
||||||
|
WHERE company=%(company)s
|
||||||
|
{additional_conditions}
|
||||||
|
AND posting_date <= %(to_date)s
|
||||||
|
AND cost_center = DCC_allocation.parent
|
||||||
|
""".format(additional_conditions=additional_conditions.replace("and cost_center in %(cost_center)s ", ''))
|
||||||
|
|
||||||
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry`
|
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry`
|
||||||
where company=%(company)s
|
where company=%(company)s
|
||||||
{additional_conditions}
|
{additional_conditions}
|
||||||
and posting_date <= %(to_date)s
|
and posting_date <= %(to_date)s
|
||||||
order by account, posting_date""".format(additional_conditions=additional_conditions), gl_filters, as_dict=True) #nosec
|
and is_cancelled = 0
|
||||||
|
{distributed_cost_center_query}
|
||||||
|
order by account, posting_date""".format(
|
||||||
|
additional_conditions=additional_conditions,
|
||||||
|
distributed_cost_center_query=distributed_cost_center_query), gl_filters, as_dict=True) #nosec
|
||||||
|
|
||||||
if filters and filters.get('presentation_currency'):
|
if filters and filters.get('presentation_currency'):
|
||||||
convert_to_presentation_currency(gl_entries, get_currency(filters))
|
convert_to_presentation_currency(gl_entries, get_currency(filters))
|
||||||
|
|||||||
@@ -128,18 +128,53 @@ def get_gl_entries(filters):
|
|||||||
filters['company_fb'] = frappe.db.get_value("Company",
|
filters['company_fb'] = frappe.db.get_value("Company",
|
||||||
filters.get("company"), 'default_finance_book')
|
filters.get("company"), 'default_finance_book')
|
||||||
|
|
||||||
|
distributed_cost_center_query = ""
|
||||||
|
if filters and filters.get('cost_center'):
|
||||||
|
select_fields_with_percentage = """, debit*(DCC_allocation.percentage_allocation/100) as debit, credit*(DCC_allocation.percentage_allocation/100) as credit, debit_in_account_currency*(DCC_allocation.percentage_allocation/100) as debit_in_account_currency,
|
||||||
|
credit_in_account_currency*(DCC_allocation.percentage_allocation/100) as credit_in_account_currency """
|
||||||
|
|
||||||
|
distributed_cost_center_query = """
|
||||||
|
UNION ALL
|
||||||
|
SELECT name as gl_entry,
|
||||||
|
posting_date,
|
||||||
|
account,
|
||||||
|
party_type,
|
||||||
|
party,
|
||||||
|
voucher_type,
|
||||||
|
voucher_no,
|
||||||
|
cost_center, project,
|
||||||
|
against_voucher_type,
|
||||||
|
against_voucher,
|
||||||
|
account_currency,
|
||||||
|
remarks, against,
|
||||||
|
is_opening, `tabGL Entry`.creation {select_fields_with_percentage}
|
||||||
|
FROM `tabGL Entry`,
|
||||||
|
(
|
||||||
|
SELECT parent, sum(percentage_allocation) as percentage_allocation
|
||||||
|
FROM `tabDistributed Cost Center`
|
||||||
|
WHERE cost_center IN %(cost_center)s
|
||||||
|
AND parent NOT IN %(cost_center)s
|
||||||
|
GROUP BY parent
|
||||||
|
) as DCC_allocation
|
||||||
|
WHERE company=%(company)s
|
||||||
|
{conditions}
|
||||||
|
AND posting_date <= %(to_date)s
|
||||||
|
AND cost_center = DCC_allocation.parent
|
||||||
|
""".format(select_fields_with_percentage=select_fields_with_percentage, conditions=get_conditions(filters).replace("and cost_center in %(cost_center)s ", ''))
|
||||||
|
|
||||||
gl_entries = frappe.db.sql(
|
gl_entries = frappe.db.sql(
|
||||||
"""
|
"""
|
||||||
select
|
select
|
||||||
name as gl_entry, posting_date, account, party_type, party,
|
name as gl_entry, posting_date, account, party_type, party,
|
||||||
voucher_type, voucher_no, cost_center, project,
|
voucher_type, voucher_no, cost_center, project,
|
||||||
against_voucher_type, against_voucher, account_currency,
|
against_voucher_type, against_voucher, account_currency,
|
||||||
remarks, against, is_opening {select_fields}
|
remarks, against, is_opening, creation {select_fields}
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where company=%(company)s {conditions}
|
where company=%(company)s {conditions}
|
||||||
|
{distributed_cost_center_query}
|
||||||
{order_by_statement}
|
{order_by_statement}
|
||||||
""".format(
|
""".format(
|
||||||
select_fields=select_fields, conditions=get_conditions(filters),
|
select_fields=select_fields, conditions=get_conditions(filters), distributed_cost_center_query=distributed_cost_center_query,
|
||||||
order_by_statement=order_by_statement
|
order_by_statement=order_by_statement
|
||||||
),
|
),
|
||||||
filters, as_dict=1)
|
filters, as_dict=1)
|
||||||
|
|||||||
@@ -265,13 +265,6 @@ def get_columns(additional_table_columns, filters):
|
|||||||
'fieldtype': 'Currency',
|
'fieldtype': 'Currency',
|
||||||
'options': 'currency',
|
'options': 'currency',
|
||||||
'width': 100
|
'width': 100
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'currency',
|
|
||||||
'label': _('Currency'),
|
|
||||||
'fieldtype': 'Currency',
|
|
||||||
'width': 80,
|
|
||||||
'hidden': 1
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ def get_columns(additional_table_columns, filters):
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
if filters.get('group_by') != 'Terriotory':
|
if filters.get('group_by') != 'Territory':
|
||||||
columns.extend([
|
columns.extend([
|
||||||
{
|
{
|
||||||
'label': _("Territory"),
|
'label': _("Territory"),
|
||||||
@@ -304,13 +304,6 @@ def get_columns(additional_table_columns, filters):
|
|||||||
'fieldtype': 'Currency',
|
'fieldtype': 'Currency',
|
||||||
'options': 'currency',
|
'options': 'currency',
|
||||||
'width': 100
|
'width': 100
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'currency',
|
|
||||||
'label': _('Currency'),
|
|
||||||
'fieldtype': 'Currency',
|
|
||||||
'width': 80,
|
|
||||||
'hidden': 1
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -536,6 +529,13 @@ def get_tax_accounts(item_list, columns, company_currency,
|
|||||||
'fieldtype': 'Currency',
|
'fieldtype': 'Currency',
|
||||||
'options': 'currency',
|
'options': 'currency',
|
||||||
'width': 100
|
'width': 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'currency',
|
||||||
|
'label': _('Currency'),
|
||||||
|
'fieldtype': 'Currency',
|
||||||
|
'width': 80,
|
||||||
|
'hidden': 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.query_reports["Ordered Items To Be Billed"] = {
|
|
||||||
"filters": [
|
|
||||||
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"add_total_row": 1,
|
|
||||||
"apply_user_permissions": 1,
|
|
||||||
"creation": "2013-02-21 14:26:44",
|
|
||||||
"disabled": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "Report",
|
|
||||||
"idx": 3,
|
|
||||||
"is_standard": "Yes",
|
|
||||||
"modified": "2017-11-06 13:04:51.559061",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Ordered Items To Be Billed",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`customer_name` as \"Customer Name:150\",\n`tabSales Order`.`status` as \"Status\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project` as \"Project\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.base_amount as \"Amount:Currency:110\",\n (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1)) as \"Billed Amount:Currency:110\",\n (`tabSales Order Item`.base_amount - (`tabSales Order Item`.billed_amt * ifnull(`tabSales Order`.conversion_rate, 1))) as \"Pending Amount:Currency:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order`.`company` as \"Company:Link/Company:\"\nfrom\n `tabSales Order`, `tabSales Order Item`\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status != \"Closed\"\n and `tabSales Order Item`.amount > 0\n and `tabSales Order Item`.billed_amt < `tabSales Order Item`.amount\norder by `tabSales Order`.transaction_date asc",
|
|
||||||
"ref_doctype": "Sales Invoice",
|
|
||||||
"report_name": "Ordered Items To Be Billed",
|
|
||||||
"report_type": "Script Report",
|
|
||||||
"roles": [
|
|
||||||
{
|
|
||||||
"role": "Accounts Manager"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "Accounts User"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,26 +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
|
|
||||||
from frappe import _
|
|
||||||
from erpnext.accounts.report.non_billed_report import get_ordered_to_be_billed_data
|
|
||||||
|
|
||||||
def execute(filters=None):
|
|
||||||
columns = get_column()
|
|
||||||
args = get_args()
|
|
||||||
data = get_ordered_to_be_billed_data(args)
|
|
||||||
return columns, data
|
|
||||||
|
|
||||||
def get_column():
|
|
||||||
return [
|
|
||||||
_("Sales Order") + ":Link/Sales Order:120", _("Status") + "::120", _("Date") + ":Date:100",
|
|
||||||
_("Suplier") + ":Link/Customer:120", _("Customer Name") + "::120",
|
|
||||||
_("Project") + ":Link/Project:120", _("Item Code") + ":Link/Item:120",
|
|
||||||
_("Amount") + ":Currency:100", _("Billed Amount") + ":Currency:100", _("Pending Amount") + ":Currency:100",
|
|
||||||
_("Item Name") + "::120", _("Description") + "::120", _("Company") + ":Link/Company:120",
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_args():
|
|
||||||
return {'doctype': 'Sales Order', 'party': 'customer',
|
|
||||||
'date': 'transaction_date', 'order': 'transaction_date', 'order_by': 'asc'}
|
|
||||||
@@ -105,6 +105,7 @@ def accumulate_values_into_parents(accounts, accounts_by_name):
|
|||||||
|
|
||||||
def prepare_data(accounts, filters, total_row, parent_children_map, based_on):
|
def prepare_data(accounts, filters, total_row, parent_children_map, based_on):
|
||||||
data = []
|
data = []
|
||||||
|
new_accounts = accounts
|
||||||
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
|
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
|
||||||
|
|
||||||
for d in accounts:
|
for d in accounts:
|
||||||
@@ -118,6 +119,19 @@ def prepare_data(accounts, filters, total_row, parent_children_map, based_on):
|
|||||||
"currency": company_currency,
|
"currency": company_currency,
|
||||||
"based_on": based_on
|
"based_on": based_on
|
||||||
}
|
}
|
||||||
|
if based_on == 'cost_center':
|
||||||
|
cost_center_doc = frappe.get_doc("Cost Center",d.name)
|
||||||
|
if not cost_center_doc.enable_distributed_cost_center:
|
||||||
|
DCC_allocation = frappe.db.sql("""SELECT parent, sum(percentage_allocation) as percentage_allocation
|
||||||
|
FROM `tabDistributed Cost Center`
|
||||||
|
WHERE cost_center IN %(cost_center)s
|
||||||
|
AND parent NOT IN %(cost_center)s
|
||||||
|
GROUP BY parent""",{'cost_center': [d.name]})
|
||||||
|
if DCC_allocation:
|
||||||
|
for account in new_accounts:
|
||||||
|
if account['name'] == DCC_allocation[0][0]:
|
||||||
|
for value in value_fields:
|
||||||
|
d[value] += account[value]*(DCC_allocation[0][1]/100)
|
||||||
|
|
||||||
for key in value_fields:
|
for key in value_fields:
|
||||||
row[key] = flt(d.get(key, 0.0), 3)
|
row[key] = flt(d.get(key, 0.0), 3)
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ def get_gle_map(filters):
|
|||||||
# {"purchase_invoice": list of dict of all gle created for this invoice}
|
# {"purchase_invoice": list of dict of all gle created for this invoice}
|
||||||
gle_map = {}
|
gle_map = {}
|
||||||
gle = frappe.db.get_all('GL Entry',\
|
gle = frappe.db.get_all('GL Entry',\
|
||||||
{"voucher_no": ["in", [d.get("name") for d in filters["invoices"]]]},
|
{"voucher_no": ["in", [d.get("name") for d in filters["invoices"]]], 'is_cancelled': 0},
|
||||||
["fiscal_year", "credit", "debit", "account", "voucher_no", "posting_date"])
|
["fiscal_year", "credit", "debit", "account", "voucher_no", "posting_date"])
|
||||||
|
|
||||||
for d in gle:
|
for d in gle:
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verb
|
|||||||
|
|
||||||
frappe.cache().hset("fiscal_years", company, fiscal_years)
|
frappe.cache().hset("fiscal_years", company, fiscal_years)
|
||||||
|
|
||||||
|
if not transaction_date and not fiscal_year:
|
||||||
|
return fiscal_years
|
||||||
|
|
||||||
if transaction_date:
|
if transaction_date:
|
||||||
transaction_date = getdate(transaction_date)
|
transaction_date = getdate(transaction_date)
|
||||||
|
|
||||||
@@ -79,6 +82,23 @@ def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verb
|
|||||||
if verbose==1: frappe.msgprint(error_msg)
|
if verbose==1: frappe.msgprint(error_msg)
|
||||||
raise FiscalYearError(error_msg)
|
raise FiscalYearError(error_msg)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_fiscal_year_filter_field(company=None):
|
||||||
|
field = {
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"options": [],
|
||||||
|
"operator": "Between",
|
||||||
|
"query_value": True
|
||||||
|
}
|
||||||
|
fiscal_years = get_fiscal_years(company=company)
|
||||||
|
for fiscal_year in fiscal_years:
|
||||||
|
field["options"].append({
|
||||||
|
"label": fiscal_year.name,
|
||||||
|
"value": fiscal_year.name,
|
||||||
|
"query_value": [fiscal_year.year_start_date.strftime("%Y-%m-%d"), fiscal_year.year_end_date.strftime("%Y-%m-%d")]
|
||||||
|
})
|
||||||
|
return field
|
||||||
|
|
||||||
def validate_fiscal_year(date, fiscal_year, company, label="Date", doc=None):
|
def validate_fiscal_year(date, fiscal_year, company, label="Date", doc=None):
|
||||||
years = [f[0] for f in get_fiscal_years(date, label=_(label), company=company)]
|
years = [f[0] for f in get_fiscal_years(date, label=_(label), company=company)]
|
||||||
if fiscal_year not in years:
|
if fiscal_year not in years:
|
||||||
@@ -817,7 +837,7 @@ def create_payment_gateway_account(gateway):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def update_cost_center(docname, cost_center_name, cost_center_number, company):
|
def update_cost_center(docname, cost_center_name, cost_center_number, company, merge):
|
||||||
'''
|
'''
|
||||||
Renames the document by adding the number as a prefix to the current name and updates
|
Renames the document by adding the number as a prefix to the current name and updates
|
||||||
all transaction where it was present.
|
all transaction where it was present.
|
||||||
@@ -833,7 +853,7 @@ def update_cost_center(docname, cost_center_name, cost_center_number, company):
|
|||||||
|
|
||||||
new_name = get_autoname_with_number(cost_center_number, cost_center_name, docname, company)
|
new_name = get_autoname_with_number(cost_center_number, cost_center_name, docname, company)
|
||||||
if docname != new_name:
|
if docname != new_name:
|
||||||
frappe.rename_doc("Cost Center", docname, new_name, force=1)
|
frappe.rename_doc("Cost Center", docname, new_name, force=1, merge=merge)
|
||||||
return new_name
|
return new_name
|
||||||
|
|
||||||
def validate_field_number(doctype_name, docname, number_value, company, field_name):
|
def validate_field_number(doctype_name, docname, number_value, company, field_name):
|
||||||
|
|||||||
@@ -5,14 +5,23 @@ import frappe
|
|||||||
import json
|
import json
|
||||||
from frappe.utils import nowdate, add_months, get_date_str
|
from frappe.utils import nowdate, add_months, get_date_str
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.dashboard_fixtures import _get_fiscal_year
|
||||||
|
from erpnext.buying.dashboard_fixtures import get_company_for_dashboards
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
|
|
||||||
|
fiscal_year = _get_fiscal_year(nowdate())
|
||||||
|
|
||||||
|
if not fiscal_year:
|
||||||
|
return frappe._dict()
|
||||||
|
|
||||||
|
year_start_date = get_date_str(fiscal_year.get('year_start_date'))
|
||||||
|
year_end_date = get_date_str(fiscal_year.get('year_end_date'))
|
||||||
|
|
||||||
return frappe._dict({
|
return frappe._dict({
|
||||||
"dashboards": get_dashboards(),
|
"dashboards": get_dashboards(),
|
||||||
"charts": get_charts(),
|
"charts": get_charts(fiscal_year, year_start_date, year_end_date),
|
||||||
"number_cards": get_number_cards(),
|
"number_cards": get_number_cards(fiscal_year, year_start_date, year_end_date),
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_dashboards():
|
def get_dashboards():
|
||||||
@@ -31,12 +40,7 @@ def get_dashboards():
|
|||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
fiscal_year = get_fiscal_year(date=nowdate())
|
def get_charts(fiscal_year, year_start_date, year_end_date):
|
||||||
year_start_date = get_date_str(fiscal_year[1])
|
|
||||||
year_end_date = get_date_str(fiscal_year[2])
|
|
||||||
|
|
||||||
|
|
||||||
def get_charts():
|
|
||||||
company = get_company_for_dashboards()
|
company = get_company_for_dashboards()
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -55,8 +59,8 @@ def get_charts():
|
|||||||
"company": company,
|
"company": company,
|
||||||
"status": "In Location",
|
"status": "In Location",
|
||||||
"filter_based_on": "Fiscal Year",
|
"filter_based_on": "Fiscal Year",
|
||||||
"from_fiscal_year": fiscal_year[0],
|
"from_fiscal_year": fiscal_year.get('name'),
|
||||||
"to_fiscal_year": fiscal_year[0],
|
"to_fiscal_year": fiscal_year.get('name'),
|
||||||
"period_start_date": year_start_date,
|
"period_start_date": year_start_date,
|
||||||
"period_end_date": year_end_date,
|
"period_end_date": year_end_date,
|
||||||
"date_based_on": "Purchase Date",
|
"date_based_on": "Purchase Date",
|
||||||
@@ -134,7 +138,7 @@ def get_charts():
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_number_cards():
|
def get_number_cards(fiscal_year, year_start_date, year_end_date):
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"name": "Total Assets",
|
"name": "Total Assets",
|
||||||
@@ -173,13 +177,3 @@ def get_number_cards():
|
|||||||
"doctype": "Number Card"
|
"doctype": "Number Card"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_company_for_dashboards():
|
|
||||||
company = frappe.defaults.get_defaults().company
|
|
||||||
if company:
|
|
||||||
return company
|
|
||||||
else:
|
|
||||||
company_list = frappe.get_list("Company")
|
|
||||||
if company_list:
|
|
||||||
return company_list[0].name
|
|
||||||
return None
|
|
||||||
@@ -1,559 +1,140 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"autoname": "field:asset_name",
|
"autoname": "field:asset_name",
|
||||||
"beta": 0,
|
|
||||||
"creation": "2017-10-19 16:50:22.879545",
|
"creation": "2017-10-19 16:50:22.879545",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"asset_name",
|
||||||
|
"asset_category",
|
||||||
|
"company",
|
||||||
|
"column_break_3",
|
||||||
|
"item_code",
|
||||||
|
"item_name",
|
||||||
|
"section_break_6",
|
||||||
|
"maintenance_team",
|
||||||
|
"column_break_9",
|
||||||
|
"maintenance_manager",
|
||||||
|
"maintenance_manager_name",
|
||||||
|
"section_break_8",
|
||||||
|
"asset_maintenance_tasks"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "asset_name",
|
"fieldname": "asset_name",
|
||||||
"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": "Asset Name",
|
"label": "Asset Name",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset",
|
"options": "Asset",
|
||||||
"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,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "asset_name.asset_category",
|
"fetch_from": "asset_name.asset_category",
|
||||||
"fieldname": "asset_category",
|
"fieldname": "asset_category",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Asset Category"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Asset Category",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "asset_name.item_code",
|
"fetch_from": "asset_name.item_code",
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Item Code"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Code",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "asset_name.item_name",
|
"fetch_from": "asset_name.item_name",
|
||||||
"fieldname": "item_name",
|
"fieldname": "item_name",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Item Name"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_3",
|
"fieldname": "column_break_3",
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Company",
|
"label": "Company",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "select_serial_no",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Select Serial No",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Serial No",
|
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "serial_no",
|
|
||||||
"fieldtype": "Small Text",
|
|
||||||
"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": "Serial No",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_6",
|
"fieldname": "section_break_6",
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "maintenance_team",
|
"fieldname": "maintenance_team",
|
||||||
"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": "Maintenance Team",
|
"label": "Maintenance Team",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset Maintenance Team",
|
"options": "Asset Maintenance Team",
|
||||||
"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_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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "maintenance_team.maintenance_manager",
|
"fetch_from": "maintenance_team.maintenance_manager",
|
||||||
"fieldname": "maintenance_manager",
|
"fieldname": "maintenance_manager",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"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": "Maintenance Manager",
|
"label": "Maintenance Manager",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "maintenance_team.maintenance_manager_name",
|
"fetch_from": "maintenance_team.maintenance_manager_name",
|
||||||
"fieldname": "maintenance_manager_name",
|
"fieldname": "maintenance_manager_name",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Maintenance Manager Name"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Maintenance Manager Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_8",
|
"fieldname": "section_break_8",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Tasks"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Tasks",
|
|
||||||
"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_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "asset_maintenance_tasks",
|
"fieldname": "asset_maintenance_tasks",
|
||||||
"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": "Maintenance Tasks",
|
"label": "Maintenance Tasks",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset Maintenance Task",
|
"options": "Asset Maintenance Task",
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"links": [],
|
||||||
"hide_heading": 0,
|
"modified": "2020-05-28 20:28:32.993823",
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-05-22 17:20:54.711885",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Maintenance",
|
"name": "Asset Maintenance",
|
||||||
"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": "Quality Manager",
|
"role": "Quality Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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": "Manufacturing User",
|
"role": "Manufacturing User",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 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
|
|
||||||
}
|
}
|
||||||
@@ -38,10 +38,10 @@ class AssetMaintenance(Document):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def assign_tasks(asset_maintenance_name, assign_to_member, maintenance_task, next_due_date):
|
def assign_tasks(asset_maintenance_name, assign_to_member, maintenance_task, next_due_date):
|
||||||
team_member = frappe.get_doc('User', assign_to_member).email
|
team_member = frappe.db.get_value('User', assign_to_member, "email")
|
||||||
args = {
|
args = {
|
||||||
'doctype' : 'Asset Maintenance',
|
'doctype' : 'Asset Maintenance',
|
||||||
'assign_to' : team_member,
|
'assign_to' : [team_member],
|
||||||
'name' : asset_maintenance_name,
|
'name' : asset_maintenance_name,
|
||||||
'description' : maintenance_task,
|
'description' : maintenance_task,
|
||||||
'date' : next_due_date
|
'date' : next_due_date
|
||||||
@@ -77,7 +77,7 @@ def calculate_next_due_date(periodicity, start_date = None, end_date = None, las
|
|||||||
|
|
||||||
def update_maintenance_log(asset_maintenance, item_code, item_name, task):
|
def update_maintenance_log(asset_maintenance, item_code, item_name, task):
|
||||||
asset_maintenance_log = frappe.get_value("Asset Maintenance Log", {"asset_maintenance": asset_maintenance,
|
asset_maintenance_log = frappe.get_value("Asset Maintenance Log", {"asset_maintenance": asset_maintenance,
|
||||||
"task": task.maintenance_task, "maintenance_status": ('in',['Planned','Overdue'])})
|
"task": task.name, "maintenance_status": ('in',['Planned','Overdue'])})
|
||||||
|
|
||||||
if not asset_maintenance_log:
|
if not asset_maintenance_log:
|
||||||
asset_maintenance_log = frappe.get_doc({
|
asset_maintenance_log = frappe.get_doc({
|
||||||
@@ -86,7 +86,7 @@ def update_maintenance_log(asset_maintenance, item_code, item_name, task):
|
|||||||
"asset_name": asset_maintenance,
|
"asset_name": asset_maintenance,
|
||||||
"item_code": item_code,
|
"item_code": item_code,
|
||||||
"item_name": item_name,
|
"item_name": item_name,
|
||||||
"task": task.maintenance_task,
|
"task": task.name,
|
||||||
"has_certificate": task.certificate_required,
|
"has_certificate": task.certificate_required,
|
||||||
"description": task.description,
|
"description": task.description,
|
||||||
"assign_to_name": task.assign_to_name,
|
"assign_to_name": task.assign_to_name,
|
||||||
|
|||||||
@@ -1,789 +1,190 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"beta": 0,
|
|
||||||
"creation": "2017-10-23 16:58:44.424309",
|
"creation": "2017-10-23 16:58:44.424309",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "Document",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"asset_maintenance",
|
||||||
|
"naming_series",
|
||||||
|
"asset_name",
|
||||||
|
"column_break_2",
|
||||||
|
"item_code",
|
||||||
|
"item_name",
|
||||||
|
"section_break_5",
|
||||||
|
"task",
|
||||||
|
"task_name",
|
||||||
|
"maintenance_type",
|
||||||
|
"periodicity",
|
||||||
|
"assign_to_name",
|
||||||
|
"column_break_6",
|
||||||
|
"due_date",
|
||||||
|
"completion_date",
|
||||||
|
"maintenance_status",
|
||||||
|
"section_break_12",
|
||||||
|
"has_certificate",
|
||||||
|
"certificate_attachement",
|
||||||
|
"section_break_6",
|
||||||
|
"description",
|
||||||
|
"column_break_9",
|
||||||
|
"actions_performed",
|
||||||
|
"amended_from"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "asset_maintenance",
|
"fieldname": "asset_maintenance",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Asset Maintenance",
|
"label": "Asset Maintenance",
|
||||||
"length": 0,
|
"options": "Asset Maintenance"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset Maintenance",
|
|
||||||
"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": "",
|
|
||||||
"fieldname": "naming_series",
|
"fieldname": "naming_series",
|
||||||
"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": "Series",
|
"label": "Series",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "ACC-AML-.YYYY.-",
|
"options": "ACC-AML-.YYYY.-",
|
||||||
"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_from": "asset_maintenance.asset_name",
|
"fetch_from": "asset_maintenance.asset_name",
|
||||||
"fieldname": "asset_name",
|
"fieldname": "asset_name",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Asset Name"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Asset Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_2",
|
"fieldname": "column_break_2",
|
||||||
"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,
|
|
||||||
"fetch_from": "asset_maintenance.item_code",
|
"fetch_from": "asset_maintenance.item_code",
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Item Code"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Code",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_from": "asset_maintenance.item_name",
|
"fetch_from": "asset_maintenance.item_name",
|
||||||
"fieldname": "item_name",
|
"fieldname": "item_name",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Item Name"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_5",
|
"fieldname": "section_break_5",
|
||||||
"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": "task",
|
"fieldname": "task",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Task",
|
"label": "Task",
|
||||||
"length": 0,
|
"options": "Asset Maintenance Task"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Asset Maintenance Task",
|
|
||||||
"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_from": "task.maintenance_type",
|
"fetch_from": "task.maintenance_type",
|
||||||
"fieldname": "maintenance_type",
|
"fieldname": "maintenance_type",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Maintenance Type"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Maintenance Type",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_from": "task.periodicity",
|
"fetch_from": "task.periodicity",
|
||||||
"fieldname": "periodicity",
|
"fieldname": "periodicity",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Periodicity",
|
"label": "Periodicity",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "task.assign_to_name",
|
"fetch_from": "task.assign_to_name",
|
||||||
"fieldname": "assign_to_name",
|
"fieldname": "assign_to_name",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"hidden": 0,
|
"label": "Assign To"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Assign To",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_6",
|
"fieldname": "column_break_6",
|
||||||
"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,
|
|
||||||
"fetch_from": "task.next_due_date",
|
"fetch_from": "task.next_due_date",
|
||||||
"fieldname": "due_date",
|
"fieldname": "due_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": "Due Date",
|
"label": "Due Date",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "completion_date",
|
"fieldname": "completion_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": "Completion Date"
|
||||||
"label": "Completion Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "maintenance_status",
|
"fieldname": "maintenance_status",
|
||||||
"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": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Maintenance Status",
|
"label": "Maintenance Status",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Planned\nCompleted\nCancelled\nOverdue",
|
"options": "Planned\nCompleted\nCancelled\nOverdue",
|
||||||
"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": "section_break_12",
|
"fieldname": "section_break_12",
|
||||||
"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,
|
"default": "0",
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fetch_from": "task.certificate_required",
|
"fetch_from": "task.certificate_required",
|
||||||
"fieldname": "has_certificate",
|
"fieldname": "has_certificate",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"label": "Has Certificate "
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Has Certificate ",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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,
|
|
||||||
"depends_on": "eval:doc.has_certificate",
|
"depends_on": "eval:doc.has_certificate",
|
||||||
"fieldname": "certificate_attachement",
|
"fieldname": "certificate_attachement",
|
||||||
"fieldtype": "Attach",
|
"fieldtype": "Attach",
|
||||||
"hidden": 0,
|
"label": "Certificate"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Certificate",
|
|
||||||
"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": "section_break_6",
|
"fieldname": "section_break_6",
|
||||||
"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,
|
|
||||||
"fetch_from": "task.description",
|
"fetch_from": "task.description",
|
||||||
"fieldname": "description",
|
"fieldname": "description",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"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": "Description",
|
"label": "Description",
|
||||||
"length": 0,
|
"read_only": 1
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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": "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": 1,
|
"allow_on_submit": 1,
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "actions_performed",
|
"fieldname": "actions_performed",
|
||||||
"fieldtype": "Text Editor",
|
"fieldtype": "Text Editor",
|
||||||
"hidden": 0,
|
"label": "Actions performed"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Actions performed",
|
|
||||||
"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": "amended_from",
|
"fieldname": "amended_from",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Amended From",
|
"label": "Amended From",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Asset Maintenance Log",
|
"options": "Asset Maintenance Log",
|
||||||
"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,
|
"fetch_from": "task.maintenance_task",
|
||||||
"reqd": 0,
|
"fieldname": "task_name",
|
||||||
"search_index": 0,
|
"fieldtype": "Data",
|
||||||
"set_only_once": 0,
|
"in_preview": 1,
|
||||||
"translatable": 0,
|
"label": "Task Name",
|
||||||
"unique": 0
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"issingle": 0,
|
"links": [],
|
||||||
"istable": 0,
|
"modified": "2020-05-28 20:51:48.238397",
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-08-21 14:44:51.457835",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Maintenance Log",
|
"name": "Asset Maintenance Log",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@@ -793,27 +194,17 @@
|
|||||||
"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": "Manufacturing User",
|
"role": "Manufacturing User",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "",
|
|
||||||
"track_changes": 1,
|
"track_changes": 1,
|
||||||
"track_seen": 1,
|
"track_seen": 1
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
||||||
@@ -7,5 +7,4 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class AssetMaintenanceTask(Document):
|
class AssetMaintenanceTask(Document):
|
||||||
def autoname(self):
|
pass
|
||||||
self.name = self.maintenance_task
|
|
||||||
|
|||||||
@@ -5,13 +5,24 @@ import frappe
|
|||||||
import json
|
import json
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.dashboard_fixtures import _get_fiscal_year
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
|
|
||||||
|
fiscal_year = _get_fiscal_year(nowdate())
|
||||||
|
|
||||||
|
if not fiscal_year:
|
||||||
|
return frappe._dict()
|
||||||
|
|
||||||
|
company = frappe.get_doc("Company", get_company_for_dashboards())
|
||||||
|
fiscal_year_name = fiscal_year.get("name")
|
||||||
|
start_date = str(fiscal_year.get("year_start_date"))
|
||||||
|
end_date = str(fiscal_year.get("year_end_date"))
|
||||||
|
|
||||||
return frappe._dict({
|
return frappe._dict({
|
||||||
"dashboards": get_dashboards(),
|
"dashboards": get_dashboards(),
|
||||||
"charts": get_charts(),
|
"charts": get_charts(company, fiscal_year_name, start_date, end_date),
|
||||||
"number_cards": get_number_cards(),
|
"number_cards": get_number_cards(company, fiscal_year_name, start_date, end_date),
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_company_for_dashboards():
|
def get_company_for_dashboards():
|
||||||
@@ -24,12 +35,6 @@ def get_company_for_dashboards():
|
|||||||
return company_list[0].name
|
return company_list[0].name
|
||||||
return None
|
return None
|
||||||
|
|
||||||
company = frappe.get_doc("Company", get_company_for_dashboards())
|
|
||||||
fiscal_year = get_fiscal_year(nowdate(), as_dict=1)
|
|
||||||
fiscal_year_name = fiscal_year.get("name")
|
|
||||||
start_date = str(fiscal_year.get("year_start_date"))
|
|
||||||
end_date = str(fiscal_year.get("year_end_date"))
|
|
||||||
|
|
||||||
def get_dashboards():
|
def get_dashboards():
|
||||||
return [{
|
return [{
|
||||||
"name": "Buying",
|
"name": "Buying",
|
||||||
@@ -48,7 +53,7 @@ def get_dashboards():
|
|||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def get_charts():
|
def get_charts(company, fiscal_year_name, start_date, end_date):
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"name": "Purchase Order Analysis",
|
"name": "Purchase Order Analysis",
|
||||||
@@ -139,7 +144,7 @@ def get_charts():
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_number_cards():
|
def get_number_cards(company, fiscal_year_name, start_date, end_date):
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"name": "Annual Purchase",
|
"name": "Annual Purchase",
|
||||||
@@ -150,8 +155,7 @@ def get_number_cards():
|
|||||||
["Purchase Order", "transaction_date", "Between", [start_date, end_date], False],
|
["Purchase Order", "transaction_date", "Between", [start_date, end_date], False],
|
||||||
["Purchase Order", "status", "not in", ["Draft", "Cancelled", "Closed", None], False],
|
["Purchase Order", "status", "not in", ["Draft", "Cancelled", "Closed", None], False],
|
||||||
["Purchase Order", "docstatus", "=", 1, False],
|
["Purchase Order", "docstatus", "=", 1, False],
|
||||||
["Purchase Order", "company", "=", company.name, False],
|
["Purchase Order", "company", "=", company.name, False]
|
||||||
["Purchase Order", "transaction_date", "Between", [start_date,end_date], False]
|
|
||||||
]),
|
]),
|
||||||
"function": "Sum",
|
"function": "Sum",
|
||||||
"is_public": 1,
|
"is_public": 1,
|
||||||
|
|||||||
@@ -34,9 +34,14 @@
|
|||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Other Reports",
|
"label": "Other Reports",
|
||||||
"links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Items To Be Requested\",\n \"name\": \"Items To Be Requested\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase History\",\n \"name\": \"Item-wise Purchase History\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Subcontracted Item To Be Received\",\n \"name\": \"Subcontracted Item To Be Received\",\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Quoted Item Comparison\",\n \"name\": \"Quoted Item Comparison\",\n \"onboard\": 1,\n \"reference_doctype\": \"Supplier Quotation\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Material Requests for which Supplier Quotations are not created\",\n \"name\": \"Material Requests for which Supplier Quotations are not created\",\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"reference_doctype\": \"Address\",\n \"route_options\": {\n \"party_type\": \"Supplier\"\n },\n \"type\": \"report\"\n }\n]"
|
"links": "[\n {\n \"is_query_report\": true,\n \"label\": \"Items To Be Requested\",\n \"name\": \"Items To Be Requested\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase History\",\n \"name\": \"Item-wise Purchase History\",\n \"onboard\": 1,\n \"reference_doctype\": \"Item\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Subcontracted Item To Be Received\",\n \"name\": \"Subcontracted Item To Be Received\",\n \"reference_doctype\": \"Purchase Order\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Quoted Item Comparison\",\n \"name\": \"Quoted Item Comparison\",\n \"onboard\": 1,\n \"reference_doctype\": \"Supplier Quotation\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Material Requests for which Supplier Quotations are not created\",\n \"name\": \"Material Requests for which Supplier Quotations are not created\",\n \"reference_doctype\": \"Material Request\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Supplier Addresses And Contacts\",\n \"name\": \"Address And Contacts\",\n \"reference_doctype\": \"Address\",\n \"route_options\": {\n \"party_type\": \"Supplier\"\n },\n \"type\": \"report\"\n }\n]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"label": "Regional",
|
||||||
|
"links": "[\n {\n \"description\": \"Import Italian Purchase Invoices\",\n \"label\": \"Import Supplier Invoice\",\n \"name\": \"Import Supplier Invoice\",\n \"type\": \"doctype\"\n } \n]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"cards_label": "Masters & Reports ",
|
"cards_label": "",
|
||||||
"category": "Modules",
|
"category": "Modules",
|
||||||
"charts": [
|
"charts": [
|
||||||
{
|
{
|
||||||
@@ -44,7 +49,7 @@
|
|||||||
"label": "Purchase Order Trends"
|
"label": "Purchase Order Trends"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"charts_label": "Buying Dashboard",
|
"charts_label": "",
|
||||||
"creation": "2020-01-28 11:50:26.195467",
|
"creation": "2020-01-28 11:50:26.195467",
|
||||||
"developer_mode_only": 0,
|
"developer_mode_only": 0,
|
||||||
"disable_user_customization": 0,
|
"disable_user_customization": 0,
|
||||||
@@ -55,7 +60,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Buying",
|
"label": "Buying",
|
||||||
"modified": "2020-05-27 19:55:22.407528",
|
"modified": "2020-05-28 13:32:49.960574",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Buying",
|
"name": "Buying",
|
||||||
@@ -104,5 +109,5 @@
|
|||||||
"type": "Dashboard"
|
"type": "Dashboard"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"shortcuts_label": "Quick Access"
|
"shortcuts_label": ""
|
||||||
}
|
}
|
||||||
@@ -11,21 +11,21 @@ frappe.tour['Buying Settings'] = [
|
|||||||
{
|
{
|
||||||
fieldname: "supp_master_name",
|
fieldname: "supp_master_name",
|
||||||
title: "Supplier Naming By",
|
title: "Supplier Naming By",
|
||||||
description: __("By default, the Item Name is set as per the Item Code entered. If you want Items to be named by a set ") + "<a href='https://docs.erpnext.com/docs/user/manual/en/setting-up/settings/naming-series' target='_blank'>Naming Series</a>" + __(" choose the 'Naming Series' option."),
|
description: __("By default, the Supplier Name is set as per the Supplier Name entered. If you want Suppliers to be named by a ") + "<a href='https://docs.erpnext.com/docs/user/manual/en/setting-up/settings/naming-series' target='_blank'>Naming Series</a>" + __(" choose the 'Naming Series' option."),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "buying_price_list",
|
fieldname: "buying_price_list",
|
||||||
title: "Default Buying Price List",
|
title: "Default Buying Price List",
|
||||||
description: __("Configure the default Price List when creating a new Buying transaction, the default is set as 'Standard Buying'. Item prices will be fetched from this Price List.")
|
description: __("Configure the default Price List when creating a new Purchase transaction. Item prices will be fetched from this Price List.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "po_required",
|
fieldname: "po_required",
|
||||||
title: "Purchase Order Required for Purchase Invoice & Receipt Creation",
|
title: "Purchase Order Required for Purchase Invoice & Receipt Creation",
|
||||||
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice or Receipt without creating a Purchase Order first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Order' checkbox in supplier master.")
|
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice or Receipt without creating a Purchase Order first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Order' checkbox in the Supplier master.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "pr_required",
|
fieldname: "pr_required",
|
||||||
title: "Purchase Receipt Required for Purchase Invoice Creation",
|
title: "Purchase Receipt Required for Purchase Invoice Creation",
|
||||||
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice without creating a Purchase Receipt first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Receipt' checkbox in supplier master.")
|
description: __("If this option is configured 'Yes', ERPNext will prevent you from creating a Purchase Invoice without creating a Purchase Receipt first. This configuration can be overridden for a particular supplier by enabling the 'Allow Purchase Invoice Creation Without Purchase Receipt' checkbox in the Supplier master.")
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -71,6 +71,15 @@ class PurchaseOrder(BuyingController):
|
|||||||
"compare_fields": [["project", "="], ["item_code", "="],
|
"compare_fields": [["project", "="], ["item_code", "="],
|
||||||
["uom", "="], ["conversion_factor", "="]],
|
["uom", "="], ["conversion_factor", "="]],
|
||||||
"is_child_table": True
|
"is_child_table": True
|
||||||
|
},
|
||||||
|
"Material Request": {
|
||||||
|
"ref_dn_field": "material_request",
|
||||||
|
"compare_fields": [["company", "="]],
|
||||||
|
},
|
||||||
|
"Material Request Item": {
|
||||||
|
"ref_dn_field": "material_request_item",
|
||||||
|
"compare_fields": [["project", "="], ["item_code", "="]],
|
||||||
|
"is_child_table": True
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -185,6 +185,23 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertEquals(len(po.get('items')), 1)
|
self.assertEquals(len(po.get('items')), 1)
|
||||||
self.assertEqual(po.status, 'To Receive and Bill')
|
self.assertEqual(po.status, 'To Receive and Bill')
|
||||||
|
|
||||||
|
def test_update_child_qty_rate_perm(self):
|
||||||
|
po = create_purchase_order(item_code= "_Test Item", qty=4)
|
||||||
|
|
||||||
|
user = 'test@example.com'
|
||||||
|
test_user = frappe.get_doc('User', user)
|
||||||
|
test_user.add_roles("Accounts User")
|
||||||
|
frappe.set_user(user)
|
||||||
|
|
||||||
|
# update qty
|
||||||
|
trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 200, 'qty' : 7, 'docname': po.items[0].name}])
|
||||||
|
self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Purchase Order', trans_item, po.name)
|
||||||
|
|
||||||
|
# add new item
|
||||||
|
trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 100, 'qty' : 2}])
|
||||||
|
self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Purchase Order', trans_item, po.name)
|
||||||
|
frappe.set_user("Administrator")
|
||||||
|
|
||||||
def test_update_qty(self):
|
def test_update_qty(self):
|
||||||
po = create_purchase_order()
|
po = create_purchase_order()
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class RequestforQuotation(BuyingController):
|
|||||||
self.validate_duplicate_supplier()
|
self.validate_duplicate_supplier()
|
||||||
self.validate_supplier_list()
|
self.validate_supplier_list()
|
||||||
validate_for_items(self)
|
validate_for_items(self)
|
||||||
|
super(RequestforQuotation, self).set_qty_as_per_stock_uom()
|
||||||
self.update_email_id()
|
self.update_email_id()
|
||||||
|
|
||||||
def validate_duplicate_supplier(self):
|
def validate_duplicate_supplier(self):
|
||||||
@@ -278,6 +279,7 @@ def create_rfq_items(sq_doc, supplier, data):
|
|||||||
"description": data.description,
|
"description": data.description,
|
||||||
"qty": data.qty,
|
"qty": data.qty,
|
||||||
"rate": data.rate,
|
"rate": data.rate,
|
||||||
|
"conversion_factor": data.conversion_factor if data.conversion_factor else None,
|
||||||
"supplier_part_no": frappe.db.get_value("Item Supplier", {'parent': data.item_code, 'supplier': supplier}, "supplier_part_no"),
|
"supplier_part_no": frappe.db.get_value("Item Supplier", {'parent': data.item_code, 'supplier': supplier}, "supplier_part_no"),
|
||||||
"warehouse": data.warehouse or '',
|
"warehouse": data.warehouse or '',
|
||||||
"request_for_quotation_item": data.name,
|
"request_for_quotation_item": data.name,
|
||||||
|
|||||||
@@ -6,12 +6,14 @@ from __future__ import unicode_literals
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
|
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
||||||
|
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
||||||
|
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import create_supplier_quotation
|
||||||
|
|
||||||
class TestRequestforQuotation(unittest.TestCase):
|
class TestRequestforQuotation(unittest.TestCase):
|
||||||
def test_quote_status(self):
|
def test_quote_status(self):
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
|
|
||||||
self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Pending')
|
self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Pending')
|
||||||
@@ -31,7 +33,6 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
self.assertEqual(rfq.get('suppliers')[1].quote_status, 'No Quote')
|
self.assertEqual(rfq.get('suppliers')[1].quote_status, 'No Quote')
|
||||||
|
|
||||||
def test_make_supplier_quotation(self):
|
def test_make_supplier_quotation(self):
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
|
|
||||||
sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
|
sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
|
||||||
@@ -51,15 +52,13 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
self.assertEqual(sq1.get('items')[0].qty, 5)
|
self.assertEqual(sq1.get('items')[0].qty, 5)
|
||||||
|
|
||||||
def test_make_supplier_quotation_with_special_characters(self):
|
def test_make_supplier_quotation_with_special_characters(self):
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
|
||||||
|
|
||||||
frappe.delete_doc_if_exists("Supplier", "_Test Supplier '1", force=1)
|
frappe.delete_doc_if_exists("Supplier", "_Test Supplier '1", force=1)
|
||||||
supplier = frappe.new_doc("Supplier")
|
supplier = frappe.new_doc("Supplier")
|
||||||
supplier.supplier_name = "_Test Supplier '1"
|
supplier.supplier_name = "_Test Supplier '1"
|
||||||
supplier.supplier_group = "_Test Supplier Group"
|
supplier.supplier_group = "_Test Supplier Group"
|
||||||
supplier.insert()
|
supplier.insert()
|
||||||
|
|
||||||
rfq = make_request_for_quotation(supplier_wt_appos)
|
rfq = make_request_for_quotation(supplier_data=supplier_wt_appos)
|
||||||
|
|
||||||
sq = make_supplier_quotation(rfq.name, supplier_wt_appos[0].get("supplier"))
|
sq = make_supplier_quotation(rfq.name, supplier_wt_appos[0].get("supplier"))
|
||||||
sq.submit()
|
sq.submit()
|
||||||
@@ -76,7 +75,6 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
frappe.form_dict.name = None
|
frappe.form_dict.name = None
|
||||||
|
|
||||||
def test_make_supplier_quotation_from_portal(self):
|
def test_make_supplier_quotation_from_portal(self):
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import create_supplier_quotation
|
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
rfq.get('items')[0].rate = 100
|
rfq.get('items')[0].rate = 100
|
||||||
rfq.supplier = rfq.suppliers[0].supplier
|
rfq.supplier = rfq.suppliers[0].supplier
|
||||||
@@ -90,12 +88,34 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
self.assertEqual(supplier_quotation_doc.get('items')[0].qty, 5)
|
self.assertEqual(supplier_quotation_doc.get('items')[0].qty, 5)
|
||||||
self.assertEqual(supplier_quotation_doc.get('items')[0].amount, 500)
|
self.assertEqual(supplier_quotation_doc.get('items')[0].amount, 500)
|
||||||
|
|
||||||
|
def test_make_multi_uom_supplier_quotation(self):
|
||||||
|
item_code = "_Test Multi UOM RFQ Item"
|
||||||
|
if not frappe.db.exists('Item', item_code):
|
||||||
|
item = make_item(item_code, {'stock_uom': '_Test UOM'})
|
||||||
|
row = item.append('uoms', {
|
||||||
|
'uom': 'Kg',
|
||||||
|
'conversion_factor': 2
|
||||||
|
})
|
||||||
|
row.db_update()
|
||||||
|
|
||||||
def make_request_for_quotation(supplier_data=None):
|
rfq = make_request_for_quotation(item_code="_Test Multi UOM RFQ Item", uom="Kg", conversion_factor=2)
|
||||||
|
rfq.get('items')[0].rate = 100
|
||||||
|
rfq.supplier = rfq.suppliers[0].supplier
|
||||||
|
|
||||||
|
self.assertEqual(rfq.items[0].stock_qty, 10)
|
||||||
|
|
||||||
|
supplier_quotation_name = create_supplier_quotation(rfq)
|
||||||
|
supplier_quotation = frappe.get_doc('Supplier Quotation', supplier_quotation_name)
|
||||||
|
|
||||||
|
self.assertEqual(supplier_quotation.items[0].qty, 5)
|
||||||
|
self.assertEqual(supplier_quotation.items[0].stock_qty, 10)
|
||||||
|
|
||||||
|
def make_request_for_quotation(**args):
|
||||||
"""
|
"""
|
||||||
:param supplier_data: List containing supplier data
|
:param supplier_data: List containing supplier data
|
||||||
"""
|
"""
|
||||||
supplier_data = supplier_data if supplier_data else get_supplier_data()
|
args = frappe._dict(args)
|
||||||
|
supplier_data = args.get("supplier_data") if args.get("supplier_data") else get_supplier_data()
|
||||||
rfq = frappe.new_doc('Request for Quotation')
|
rfq = frappe.new_doc('Request for Quotation')
|
||||||
rfq.transaction_date = nowdate()
|
rfq.transaction_date = nowdate()
|
||||||
rfq.status = 'Draft'
|
rfq.status = 'Draft'
|
||||||
@@ -106,11 +126,13 @@ def make_request_for_quotation(supplier_data=None):
|
|||||||
rfq.append('suppliers', data)
|
rfq.append('suppliers', data)
|
||||||
|
|
||||||
rfq.append("items", {
|
rfq.append("items", {
|
||||||
"item_code": "_Test Item",
|
"item_code": args.item_code or "_Test Item",
|
||||||
"description": "_Test Item",
|
"description": "_Test Item",
|
||||||
"uom": "_Test UOM",
|
"uom": args.uom or "_Test UOM",
|
||||||
"qty": 5,
|
"stock_uom": args.stock_uom or "_Test UOM",
|
||||||
"warehouse": "_Test Warehouse - _TC",
|
"qty": args.qty or 5,
|
||||||
|
"conversion_factor": args.conversion_factor or 1.0,
|
||||||
|
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
||||||
"schedule_date": nowdate()
|
"schedule_date": nowdate()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "hash",
|
"autoname": "hash",
|
||||||
"creation": "2016-02-25 08:04:02.452958",
|
"creation": "2016-02-25 08:04:02.452958",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@@ -9,6 +10,7 @@
|
|||||||
"supplier_part_no",
|
"supplier_part_no",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"item_name",
|
"item_name",
|
||||||
|
"schedule_date",
|
||||||
"section_break_5",
|
"section_break_5",
|
||||||
"description",
|
"description",
|
||||||
"item_group",
|
"item_group",
|
||||||
@@ -18,9 +20,11 @@
|
|||||||
"image_view",
|
"image_view",
|
||||||
"quantity",
|
"quantity",
|
||||||
"qty",
|
"qty",
|
||||||
|
"stock_uom",
|
||||||
"col_break2",
|
"col_break2",
|
||||||
"schedule_date",
|
|
||||||
"uom",
|
"uom",
|
||||||
|
"conversion_factor",
|
||||||
|
"stock_qty",
|
||||||
"warehouse_and_reference",
|
"warehouse_and_reference",
|
||||||
"warehouse",
|
"warehouse",
|
||||||
"project_name",
|
"project_name",
|
||||||
@@ -33,7 +37,7 @@
|
|||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"bold": 1,
|
"bold": 1,
|
||||||
"columns": 3,
|
"columns": 2,
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -98,7 +102,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "quantity",
|
"fieldname": "quantity",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Quantity"
|
"label": "Quantity & Stock"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bold": 1,
|
"bold": 1,
|
||||||
@@ -129,12 +133,12 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "uom",
|
"fieldname": "uom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "UOM",
|
"label": "UOM",
|
||||||
"oldfieldname": "uom",
|
"oldfieldname": "uom",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "UOM",
|
"options": "UOM",
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
"read_only": 1,
|
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
@@ -144,7 +148,7 @@
|
|||||||
"label": "Warehouse and Reference"
|
"label": "Warehouse and Reference"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 3,
|
"columns": 2,
|
||||||
"fieldname": "warehouse",
|
"fieldname": "warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -202,6 +206,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
|
"default": "0",
|
||||||
"fieldname": "page_break",
|
"fieldname": "page_break",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Page Break",
|
"label": "Page Break",
|
||||||
@@ -219,10 +224,36 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "section_break_23",
|
"fieldname": "section_break_23",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "stock_uom",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Stock UOM",
|
||||||
|
"options": "UOM",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1,
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "conversion_factor",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "UOM Conversion Factor",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1,
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "stock_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Qty as per Stock UOM",
|
||||||
|
"no_copy": 1,
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-05-01 17:50:23.703801",
|
"links": [],
|
||||||
|
"modified": "2020-06-12 19:10:36.333441",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Request for Quotation Item",
|
"name": "Request for Quotation Item",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/buying",
|
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/buying",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_complete": 0,
|
"is_complete": 0,
|
||||||
"modified": "2020-05-27 17:17:52.075947",
|
"modified": "2020-06-01 12:55:09.234944",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Buying",
|
"name": "Buying",
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
{
|
{
|
||||||
"action": "Update Settings",
|
"action": "Show Form Tour",
|
||||||
"creation": "2020-05-06 15:53:44.667414",
|
"creation": "2020-05-06 15:53:44.667414",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Onboarding Step",
|
"doctype": "Onboarding Step",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_complete": 0,
|
"is_complete": 0,
|
||||||
"is_mandatory": 0,
|
"is_mandatory": 1,
|
||||||
"is_single": 0,
|
"is_single": 1,
|
||||||
"is_skipped": 0,
|
"is_skipped": 0,
|
||||||
"modified": "2020-05-12 18:30:06.323797",
|
"modified": "2020-06-01 12:52:57.668870",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"name": "Buying Settings",
|
"name": "Buying Settings",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"reference_document": "Buying Settings",
|
"reference_document": "Buying Settings",
|
||||||
"show_full_form": 0,
|
"show_full_form": 0,
|
||||||
"title": "Configure Buying Settings.",
|
"title": "Configure Buying Settings.",
|
||||||
"validate_action": 1
|
"validate_action": 0
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
from frappe.utils import flt
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
columns = get_columns(filters)
|
columns = get_columns(filters)
|
||||||
@@ -54,15 +55,16 @@ def get_columns(filters):
|
|||||||
"width": 140
|
"width": 140
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": _("Description"),
|
"label": _("Item"),
|
||||||
"fieldname": "description",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Link",
|
||||||
"width": 200
|
"options": "Item",
|
||||||
|
"width": 150
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": _("Quantity"),
|
"label": _("Quantity"),
|
||||||
"fieldname": "quantity",
|
"fieldname": "quantity",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Float",
|
||||||
"width": 140
|
"width": 140
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -118,7 +120,7 @@ def get_columns(filters):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": _("Purchase Order Amount(Company Currency)"),
|
"label": _("Purchase Order Amount(Company Currency)"),
|
||||||
"fieldname": "purchase_order_amt_usd",
|
"fieldname": "purchase_order_amt_in_company_currency",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"width": 140
|
"width": 140
|
||||||
},
|
},
|
||||||
@@ -175,17 +177,17 @@ def get_data(filters):
|
|||||||
"requesting_site": po.warehouse,
|
"requesting_site": po.warehouse,
|
||||||
"requestor": po.owner,
|
"requestor": po.owner,
|
||||||
"material_request_no": po.material_request,
|
"material_request_no": po.material_request,
|
||||||
"description": po.description,
|
"item_code": po.item_code,
|
||||||
"quantity": po.qty,
|
"quantity": flt(po.qty),
|
||||||
"unit_of_measurement": po.stock_uom,
|
"unit_of_measurement": po.stock_uom,
|
||||||
"status": po.status,
|
"status": po.status,
|
||||||
"purchase_order_date": po.transaction_date,
|
"purchase_order_date": po.transaction_date,
|
||||||
"purchase_order": po.parent,
|
"purchase_order": po.parent,
|
||||||
"supplier": po.supplier,
|
"supplier": po.supplier,
|
||||||
"estimated_cost": mr_record.get('amount'),
|
"estimated_cost": flt(mr_record.get('amount')),
|
||||||
"actual_cost": pi_records.get(po.name),
|
"actual_cost": flt(pi_records.get(po.name)),
|
||||||
"purchase_order_amt": po.amount,
|
"purchase_order_amt": flt(po.amount),
|
||||||
"purchase_order_amt_in_company_currency": po.base_amount,
|
"purchase_order_amt_in_company_currency": flt(po.base_amount),
|
||||||
"expected_delivery_date": po.schedule_date,
|
"expected_delivery_date": po.schedule_date,
|
||||||
"actual_delivery_date": pr_records.get(po.name)
|
"actual_delivery_date": pr_records.get(po.name)
|
||||||
}
|
}
|
||||||
@@ -198,9 +200,14 @@ def get_mapped_mr_details(conditions):
|
|||||||
SELECT
|
SELECT
|
||||||
par.transaction_date,
|
par.transaction_date,
|
||||||
par.per_ordered,
|
par.per_ordered,
|
||||||
|
par.owner,
|
||||||
child.name,
|
child.name,
|
||||||
child.parent,
|
child.parent,
|
||||||
child.amount
|
child.amount,
|
||||||
|
child.qty,
|
||||||
|
child.item_code,
|
||||||
|
child.uom,
|
||||||
|
par.status
|
||||||
FROM `tabMaterial Request` par, `tabMaterial Request Item` child
|
FROM `tabMaterial Request` par, `tabMaterial Request Item` child
|
||||||
WHERE
|
WHERE
|
||||||
par.per_ordered>=0
|
par.per_ordered>=0
|
||||||
@@ -217,7 +224,15 @@ def get_mapped_mr_details(conditions):
|
|||||||
procurement_record_details = dict(
|
procurement_record_details = dict(
|
||||||
material_request_date=record.transaction_date,
|
material_request_date=record.transaction_date,
|
||||||
material_request_no=record.parent,
|
material_request_no=record.parent,
|
||||||
estimated_cost=record.amount
|
requestor=record.owner,
|
||||||
|
item_code=record.item_code,
|
||||||
|
estimated_cost=flt(record.amount),
|
||||||
|
quantity=flt(record.qty),
|
||||||
|
unit_of_measurement=record.uom,
|
||||||
|
status=record.status,
|
||||||
|
actual_cost=0,
|
||||||
|
purchase_order_amt=0,
|
||||||
|
purchase_order_amt_in_company_currency=0
|
||||||
)
|
)
|
||||||
procurement_record_against_mr.append(procurement_record_details)
|
procurement_record_against_mr.append(procurement_record_details)
|
||||||
return mr_records, procurement_record_against_mr
|
return mr_records, procurement_record_against_mr
|
||||||
@@ -259,7 +274,7 @@ def get_po_entries(conditions):
|
|||||||
child.warehouse,
|
child.warehouse,
|
||||||
child.material_request,
|
child.material_request,
|
||||||
child.material_request_item,
|
child.material_request_item,
|
||||||
child.description,
|
child.item_code,
|
||||||
child.stock_uom,
|
child.stock_uom,
|
||||||
child.qty,
|
child.qty,
|
||||||
child.amount,
|
child.amount,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class TestProcurementTracker(unittest.TestCase):
|
|||||||
def test_result_for_procurement_tracker(self):
|
def test_result_for_procurement_tracker(self):
|
||||||
filters = {
|
filters = {
|
||||||
'company': '_Test Procurement Company',
|
'company': '_Test Procurement Company',
|
||||||
'cost_center': '_Test Cost Center - _TC'
|
'cost_center': 'Main - _TPC'
|
||||||
}
|
}
|
||||||
expected_data = self.generate_expected_data()
|
expected_data = self.generate_expected_data()
|
||||||
report = execute(filters)
|
report = execute(filters)
|
||||||
@@ -33,24 +33,27 @@ class TestProcurementTracker(unittest.TestCase):
|
|||||||
country="Pakistan"
|
country="Pakistan"
|
||||||
)).insert()
|
)).insert()
|
||||||
warehouse = create_warehouse("_Test Procurement Warehouse", company="_Test Procurement Company")
|
warehouse = create_warehouse("_Test Procurement Warehouse", company="_Test Procurement Company")
|
||||||
mr = make_material_request(company="_Test Procurement Company", warehouse=warehouse)
|
mr = make_material_request(company="_Test Procurement Company", warehouse=warehouse, cost_center="Main - _TPC")
|
||||||
po = make_purchase_order(mr.name)
|
po = make_purchase_order(mr.name)
|
||||||
po.supplier = "_Test Supplier"
|
po.supplier = "_Test Supplier"
|
||||||
po.get("items")[0].cost_center = "_Test Cost Center - _TC"
|
po.get("items")[0].cost_center = "Main - _TPC"
|
||||||
po.submit()
|
po.submit()
|
||||||
pr = make_purchase_receipt(po.name)
|
pr = make_purchase_receipt(po.name)
|
||||||
|
pr.get("items")[0].cost_center = "Main - _TPC"
|
||||||
pr.submit()
|
pr.submit()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
date_obj = datetime.date(datetime.now())
|
date_obj = datetime.date(datetime.now())
|
||||||
|
|
||||||
|
po.load_from_db()
|
||||||
|
|
||||||
expected_data = {
|
expected_data = {
|
||||||
"material_request_date": date_obj,
|
"material_request_date": date_obj,
|
||||||
"cost_center": "_Test Cost Center - _TC",
|
"cost_center": "Main - _TPC",
|
||||||
"project": None,
|
"project": None,
|
||||||
"requesting_site": "_Test Procurement Warehouse - _TPC",
|
"requesting_site": "_Test Procurement Warehouse - _TPC",
|
||||||
"requestor": "Administrator",
|
"requestor": "Administrator",
|
||||||
"material_request_no": mr.name,
|
"material_request_no": mr.name,
|
||||||
"description": '_Test Item 1',
|
"item_code": '_Test Item',
|
||||||
"quantity": 10.0,
|
"quantity": 10.0,
|
||||||
"unit_of_measurement": "_Test UOM",
|
"unit_of_measurement": "_Test UOM",
|
||||||
"status": "To Bill",
|
"status": "To Bill",
|
||||||
@@ -58,9 +61,9 @@ class TestProcurementTracker(unittest.TestCase):
|
|||||||
"purchase_order": po.name,
|
"purchase_order": po.name,
|
||||||
"supplier": "_Test Supplier",
|
"supplier": "_Test Supplier",
|
||||||
"estimated_cost": 0.0,
|
"estimated_cost": 0.0,
|
||||||
"actual_cost": None,
|
"actual_cost": 0.0,
|
||||||
"purchase_order_amt": 5000.0,
|
"purchase_order_amt": po.net_total,
|
||||||
"purchase_order_amt_in_company_currency": 300000.0,
|
"purchase_order_amt_in_company_currency": po.base_net_total,
|
||||||
"expected_delivery_date": date_obj,
|
"expected_delivery_date": date_obj,
|
||||||
"actual_delivery_date": date_obj
|
"actual_delivery_date": date_obj
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
return [
|
config = [
|
||||||
{
|
{
|
||||||
"label": _("Purchasing"),
|
"label": _("Purchasing"),
|
||||||
"icon": "fa fa-star",
|
"icon": "fa fa-star",
|
||||||
@@ -243,3 +244,21 @@ def get_data():
|
|||||||
},
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
regional = {
|
||||||
|
"label": _("Regional"),
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Import Supplier Invoice",
|
||||||
|
"description": _("Import Italian Supplier Invoice."),
|
||||||
|
"onboard": 1,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
countries = frappe.get_all("Company", fields="country")
|
||||||
|
countries = [country["country"] for country in countries]
|
||||||
|
if "Italy" in countries:
|
||||||
|
config.append(regional)
|
||||||
|
return config
|
||||||
@@ -1137,8 +1137,8 @@ def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname,
|
|||||||
child_item.item_name = item.item_name
|
child_item.item_name = item.item_name
|
||||||
child_item.description = item.description
|
child_item.description = item.description
|
||||||
child_item.delivery_date = trans_item.get('delivery_date') or p_doc.delivery_date
|
child_item.delivery_date = trans_item.get('delivery_date') or p_doc.delivery_date
|
||||||
|
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
||||||
child_item.uom = item.stock_uom
|
child_item.uom = item.stock_uom
|
||||||
child_item.conversion_factor = get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
|
||||||
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.")
|
||||||
@@ -1157,8 +1157,8 @@ def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docna
|
|||||||
child_item.item_name = item.item_name
|
child_item.item_name = item.item_name
|
||||||
child_item.description = item.description
|
child_item.description = item.description
|
||||||
child_item.schedule_date = trans_item.get('schedule_date') or p_doc.schedule_date
|
child_item.schedule_date = trans_item.get('schedule_date') or p_doc.schedule_date
|
||||||
|
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
||||||
child_item.uom = item.stock_uom
|
child_item.uom = item.stock_uom
|
||||||
child_item.conversion_factor = get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
|
|
||||||
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
|
||||||
return child_item
|
return child_item
|
||||||
@@ -1190,6 +1190,26 @@ def check_and_delete_children(parent, data):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"):
|
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"):
|
||||||
|
def check_permissions(doc, perm_type='create'):
|
||||||
|
try:
|
||||||
|
doc.check_permission(perm_type)
|
||||||
|
except:
|
||||||
|
action = "add" if perm_type == 'create' else "update"
|
||||||
|
frappe.throw(_("You do not have permissions to {} items in a Sales Order.").format(action), title=_("Insufficient Permissions"))
|
||||||
|
|
||||||
|
def get_new_child_item(item_row):
|
||||||
|
if parent_doctype == "Sales Order":
|
||||||
|
return set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row)
|
||||||
|
if parent_doctype == "Purchase Order":
|
||||||
|
return set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row)
|
||||||
|
|
||||||
|
def validate_quantity(child_item, d):
|
||||||
|
if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty):
|
||||||
|
frappe.throw(_("Cannot set quantity less than delivered quantity"))
|
||||||
|
|
||||||
|
if parent_doctype == "Purchase Order" and flt(d.get("qty")) < flt(child_item.received_qty):
|
||||||
|
frappe.throw(_("Cannot set quantity less than received quantity"))
|
||||||
|
|
||||||
data = json.loads(trans_items)
|
data = json.loads(trans_items)
|
||||||
|
|
||||||
sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation']
|
sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation']
|
||||||
@@ -1201,20 +1221,29 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
new_child_flag = False
|
new_child_flag = False
|
||||||
if not d.get("docname"):
|
if not d.get("docname"):
|
||||||
new_child_flag = True
|
new_child_flag = True
|
||||||
if parent_doctype == "Sales Order":
|
check_permissions(parent, 'create')
|
||||||
child_item = set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
|
child_item = get_new_child_item(d)
|
||||||
if parent_doctype == "Purchase Order":
|
|
||||||
child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
|
|
||||||
else:
|
else:
|
||||||
|
check_permissions(parent, 'write')
|
||||||
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
||||||
if flt(child_item.get("rate")) == flt(d.get("rate")) and flt(child_item.get("qty")) == flt(d.get("qty")):
|
|
||||||
|
prev_rate, new_rate = flt(child_item.get("rate")), flt(d.get("rate"))
|
||||||
|
prev_qty, new_qty = flt(child_item.get("qty")), flt(d.get("qty"))
|
||||||
|
prev_con_fac, new_con_fac = flt(child_item.get("conversion_factor")), flt(d.get("conversion_factor"))
|
||||||
|
|
||||||
|
if parent_doctype == 'Sales Order':
|
||||||
|
prev_date, new_date = child_item.get("delivery_date"), d.get("delivery_date")
|
||||||
|
elif parent_doctype == 'Purchase Order':
|
||||||
|
prev_date, new_date = child_item.get("schedule_date"), d.get("schedule_date")
|
||||||
|
|
||||||
|
rate_unchanged = prev_rate == new_rate
|
||||||
|
qty_unchanged = prev_qty == new_qty
|
||||||
|
conversion_factor_unchanged = prev_con_fac == new_con_fac
|
||||||
|
date_unchanged = prev_date == new_date if prev_date and new_date else False # in case of delivery note etc
|
||||||
|
if rate_unchanged and qty_unchanged and conversion_factor_unchanged and date_unchanged:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty):
|
validate_quantity(child_item, d)
|
||||||
frappe.throw(_("Cannot set quantity less than delivered quantity"))
|
|
||||||
|
|
||||||
if parent_doctype == "Purchase Order" and flt(d.get("qty")) < flt(child_item.received_qty):
|
|
||||||
frappe.throw(_("Cannot set quantity less than received quantity"))
|
|
||||||
|
|
||||||
child_item.qty = flt(d.get("qty"))
|
child_item.qty = flt(d.get("qty"))
|
||||||
precision = child_item.precision("rate") or 2
|
precision = child_item.precision("rate") or 2
|
||||||
@@ -1225,6 +1254,18 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
else:
|
else:
|
||||||
child_item.rate = flt(d.get("rate"))
|
child_item.rate = flt(d.get("rate"))
|
||||||
|
|
||||||
|
if d.get("conversion_factor"):
|
||||||
|
if child_item.stock_uom == child_item.uom:
|
||||||
|
child_item.conversion_factor = 1
|
||||||
|
else:
|
||||||
|
child_item.conversion_factor = flt(d.get('conversion_factor'))
|
||||||
|
|
||||||
|
if d.get("delivery_date") and parent_doctype == 'Sales Order':
|
||||||
|
child_item.delivery_date = d.get('delivery_date')
|
||||||
|
|
||||||
|
if d.get("schedule_date") and parent_doctype == 'Purchase Order':
|
||||||
|
child_item.schedule_date = d.get('schedule_date')
|
||||||
|
|
||||||
if flt(child_item.price_list_rate):
|
if flt(child_item.price_list_rate):
|
||||||
if flt(child_item.rate) > flt(child_item.price_list_rate):
|
if flt(child_item.rate) > flt(child_item.price_list_rate):
|
||||||
# if rate is greater than price_list_rate, set margin
|
# if rate is greater than price_list_rate, set margin
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ class BuyingController(StockController):
|
|||||||
})
|
})
|
||||||
|
|
||||||
if not rm.rate:
|
if not rm.rate:
|
||||||
rm.rate = get_valuation_rate(raw_material_data.item_code, self.supplier_warehouse,
|
rm.rate = get_valuation_rate(raw_material_data.rm_item_code, self.supplier_warehouse,
|
||||||
self.doctype, self.name, currency=self.company_currency, company=self.company)
|
self.doctype, self.name, currency=self.company_currency, company=self.company)
|
||||||
|
|
||||||
rm.amount = qty * flt(rm.rate)
|
rm.amount = qty * flt(rm.rate)
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ def validate_item_variant_attributes(item, args=None):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
attributes_list = attribute_values.get(attribute.lower(), [])
|
attributes_list = attribute_values.get(attribute.lower(), [])
|
||||||
validate_item_attribute_value(attributes_list, attribute, value, item.name)
|
validate_item_attribute_value(attributes_list, attribute, value, item.name, from_variant=True)
|
||||||
|
|
||||||
def validate_is_incremental(numeric_attribute, attribute, value, item):
|
def validate_is_incremental(numeric_attribute, attribute, value, item):
|
||||||
from_range = numeric_attribute.from_range
|
from_range = numeric_attribute.from_range
|
||||||
@@ -93,13 +93,20 @@ def validate_is_incremental(numeric_attribute, attribute, value, item):
|
|||||||
.format(attribute, from_range, to_range, increment, item),
|
.format(attribute, from_range, to_range, increment, item),
|
||||||
InvalidItemAttributeValueError, title=_('Invalid Attribute'))
|
InvalidItemAttributeValueError, title=_('Invalid Attribute'))
|
||||||
|
|
||||||
def validate_item_attribute_value(attributes_list, attribute, attribute_value, item):
|
def validate_item_attribute_value(attributes_list, attribute, attribute_value, item, from_variant=True):
|
||||||
allow_rename_attribute_value = frappe.db.get_single_value('Item Variant Settings', 'allow_rename_attribute_value')
|
allow_rename_attribute_value = frappe.db.get_single_value('Item Variant Settings', 'allow_rename_attribute_value')
|
||||||
if allow_rename_attribute_value:
|
if allow_rename_attribute_value:
|
||||||
pass
|
pass
|
||||||
elif attribute_value not in attributes_list:
|
elif attribute_value not in attributes_list:
|
||||||
frappe.throw(_("The value {0} is already assigned to an exisiting Item {2}.").format(
|
if from_variant:
|
||||||
attribute_value, attribute, item), InvalidItemAttributeValueError, title=_('Rename Not Allowed'))
|
frappe.throw(_("{0} is not a valid Value for Attribute {1} of Item {2}.").format(
|
||||||
|
frappe.bold(attribute_value), frappe.bold(attribute), frappe.bold(item)), InvalidItemAttributeValueError, title=_("Invalid Value"))
|
||||||
|
else:
|
||||||
|
msg = _("The value {0} is already assigned to an existing Item {1}.").format(
|
||||||
|
frappe.bold(attribute_value), frappe.bold(item))
|
||||||
|
msg += "<br>" + _("To still proceed with editing this Attribute Value, enable {0} in Item Variant Settings.").format(frappe.bold("Allow Rename Attribute Value"))
|
||||||
|
|
||||||
|
frappe.throw(msg, InvalidItemAttributeValueError, title=_('Edit Not Allowed'))
|
||||||
|
|
||||||
def get_attribute_values(item):
|
def get_attribute_values(item):
|
||||||
if not frappe.flags.attribute_values:
|
if not frappe.flags.attribute_values:
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class QualityInspectionNotSubmittedError(frappe.ValidationError): pass
|
|||||||
class StockController(AccountsController):
|
class StockController(AccountsController):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
super(StockController, self).validate()
|
super(StockController, self).validate()
|
||||||
|
if not self.get('is_return'):
|
||||||
self.validate_inspection()
|
self.validate_inspection()
|
||||||
self.validate_serialized_batch()
|
self.validate_serialized_batch()
|
||||||
self.validate_customer_provided_item()
|
self.validate_customer_provided_item()
|
||||||
@@ -226,7 +227,9 @@ class StockController(AccountsController):
|
|||||||
|
|
||||||
def check_expense_account(self, item):
|
def check_expense_account(self, item):
|
||||||
if not item.get("expense_account"):
|
if not item.get("expense_account"):
|
||||||
frappe.throw(_("Expense Account not set for Item {0}. Please set an Expense Account for the item in the Items table").format(item.item_code))
|
frappe.throw(_("Row #{0}: Expense Account not set for Item {1}. Please set an Expense \
|
||||||
|
Account in the Items table").format(item.idx, frappe.bold(item.item_code)),
|
||||||
|
title=_("Expense Account Missing"))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
is_expense_account = frappe.db.get_value("Account",
|
is_expense_account = frappe.db.get_value("Account",
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ def get_dashboards():
|
|||||||
{ "chart": "Opportunity Trends", "width": "Full"},
|
{ "chart": "Opportunity Trends", "width": "Full"},
|
||||||
{ "chart": "Won Opportunities", "width": "Full" },
|
{ "chart": "Won Opportunities", "width": "Full" },
|
||||||
{ "chart": "Territory Wise Opportunity Count", "width": "Half"},
|
{ "chart": "Territory Wise Opportunity Count", "width": "Half"},
|
||||||
{ "chart": "Territory Wise Sales", "width": "Half"},
|
|
||||||
{ "chart": "Opportunities via Campaigns", "width": "Half" },
|
{ "chart": "Opportunities via Campaigns", "width": "Half" },
|
||||||
|
{ "chart": "Territory Wise Sales", "width": "Full"},
|
||||||
{ "chart": "Lead Source", "width": "Half"}
|
{ "chart": "Lead Source", "width": "Half"}
|
||||||
],
|
],
|
||||||
"cards": [
|
"cards": [
|
||||||
@@ -59,7 +59,7 @@ def get_charts():
|
|||||||
'is_public': 1,
|
'is_public': 1,
|
||||||
'timeseries': 1,
|
'timeseries': 1,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"filters_json": json.dumps([["Opportunity", "company", "=", company, False]]),
|
"filters_json": json.dumps([]),
|
||||||
"type": "Bar"
|
"type": "Bar"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -90,7 +90,11 @@ def get_charts():
|
|||||||
'timeseries': 1,
|
'timeseries': 1,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"filters_json": json.dumps([["Opportunity", "company", "=", company, False]]),
|
"filters_json": json.dumps([["Opportunity", "company", "=", company, False]]),
|
||||||
"type": "Pie"
|
"type": "Pie",
|
||||||
|
"custom_options": json.dumps({
|
||||||
|
"truncateLegends": 1,
|
||||||
|
"maxSlices": 8
|
||||||
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Won Opportunities",
|
"name": "Won Opportunities",
|
||||||
@@ -123,7 +127,11 @@ def get_charts():
|
|||||||
["Opportunity", "company", "=", company, False]
|
["Opportunity", "company", "=", company, False]
|
||||||
]),
|
]),
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"type": "Donut"
|
"type": "Donut",
|
||||||
|
"custom_options": json.dumps({
|
||||||
|
"truncateLegends": 1,
|
||||||
|
"maxSlices": 8
|
||||||
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Territory Wise Sales",
|
"name": "Territory Wise Sales",
|
||||||
@@ -140,7 +148,7 @@ def get_charts():
|
|||||||
["Opportunity", "company", "=", company, False],
|
["Opportunity", "company", "=", company, False],
|
||||||
["Opportunity", "status", "=", "Converted", False]
|
["Opportunity", "status", "=", "Converted", False]
|
||||||
]),
|
]),
|
||||||
"type": "Donut"
|
"type": "Bar"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Lead Source",
|
"name": "Lead Source",
|
||||||
@@ -152,7 +160,11 @@ def get_charts():
|
|||||||
"document_type": "Lead",
|
"document_type": "Lead",
|
||||||
'is_public': 1,
|
'is_public': 1,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"type": "Pie"
|
"type": "Pie",
|
||||||
|
"custom_options": json.dumps({
|
||||||
|
"truncateLegends": 1,
|
||||||
|
"maxSlices": 8
|
||||||
|
})
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def get_number_cards():
|
def get_number_cards():
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "CRM",
|
"label": "CRM",
|
||||||
"modified": "2020-05-20 12:11:36.250491",
|
"modified": "2020-05-28 13:33:52.906750",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "CRM",
|
"name": "CRM",
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
"pin_to_top": 0,
|
"pin_to_top": 0,
|
||||||
"shortcuts": [
|
"shortcuts": [
|
||||||
{
|
{
|
||||||
|
"color": "#ffe8cd",
|
||||||
"format": "{} Open",
|
"format": "{} Open",
|
||||||
"label": "Lead",
|
"label": "Lead",
|
||||||
"link_to": "Lead",
|
"link_to": "Lead",
|
||||||
@@ -59,6 +60,7 @@
|
|||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"color": "#cef6d1",
|
||||||
"format": "{} Assigned",
|
"format": "{} Assigned",
|
||||||
"label": "Opportunity",
|
"label": "Opportunity",
|
||||||
"link_to": "Opportunity",
|
"link_to": "Opportunity",
|
||||||
@@ -76,7 +78,7 @@
|
|||||||
"type": "Report"
|
"type": "Report"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "CRM Dashboard",
|
"label": "Dashboard",
|
||||||
"link_to": "CRM",
|
"link_to": "CRM",
|
||||||
"type": "Dashboard"
|
"type": "Dashboard"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"creation": "2013-04-10 11:45:37",
|
"creation": "2013-04-10 11:45:37",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "Document",
|
||||||
|
"email_append_to": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"organization_lead",
|
"organization_lead",
|
||||||
@@ -448,7 +449,7 @@
|
|||||||
"idx": 5,
|
"idx": 5,
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-05-11 20:27:45.868960",
|
"modified": "2020-06-18 14:39:41.835416",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Lead",
|
"name": "Lead",
|
||||||
@@ -508,8 +509,10 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"search_fields": "lead_name,lead_owner,status",
|
"search_fields": "lead_name,lead_owner,status",
|
||||||
|
"sender_field": "email_id",
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"subject_field": "title",
|
||||||
"title_field": "title"
|
"title_field": "title"
|
||||||
}
|
}
|
||||||
@@ -96,6 +96,7 @@ frappe.ui.form.on("Opportunity", {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
frm.add_custom_button(__("Reopen"), function() {
|
frm.add_custom_button(__("Reopen"), function() {
|
||||||
|
frm.set_value("lost_reasons",[])
|
||||||
frm.set_value("status", "Open");
|
frm.set_value("status", "Open");
|
||||||
frm.save();
|
frm.save();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,11 +3,7 @@ from frappe import _
|
|||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
return {
|
return {
|
||||||
'fieldname': 'prevdoc_docname',
|
'fieldname': 'opportunity',
|
||||||
'non_standard_fieldnames': {
|
|
||||||
'Supplier Quotation': 'opportunity',
|
|
||||||
'Quotation': 'opportunity'
|
|
||||||
},
|
|
||||||
'transactions': [
|
'transactions': [
|
||||||
{
|
{
|
||||||
'items': ['Quotation', 'Supplier Quotation']
|
'items': ['Quotation', 'Supplier Quotation']
|
||||||
|
|||||||
@@ -30,24 +30,32 @@
|
|||||||
"fieldname": "text",
|
"fieldname": "text",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Tweet",
|
"label": "Tweet",
|
||||||
"mandatory_depends_on": "eval:doc.twitter ==1"
|
"mandatory_depends_on": "eval:doc.twitter ==1",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "image",
|
"fieldname": "image",
|
||||||
"fieldtype": "Attach Image",
|
"fieldtype": "Attach Image",
|
||||||
"label": "Image"
|
"label": "Image",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "twitter",
|
"fieldname": "twitter",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Twitter"
|
"label": "Twitter",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "linkedin",
|
"fieldname": "linkedin",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "LinkedIn"
|
"label": "LinkedIn",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
@@ -56,13 +64,17 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Social Media Post",
|
"options": "Social Media Post",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.twitter ==1",
|
"depends_on": "eval:doc.twitter ==1",
|
||||||
"fieldname": "content",
|
"fieldname": "content",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Twitter"
|
"label": "Twitter",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
@@ -70,7 +82,9 @@
|
|||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Post Status",
|
"label": "Post Status",
|
||||||
"options": "\nScheduled\nPosted\nError",
|
"options": "\nScheduled\nPosted\nError",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
@@ -78,7 +92,9 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Twitter Post Id",
|
"label": "Twitter Post Id",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
@@ -86,68 +102,89 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "LinkedIn Post Id",
|
"label": "LinkedIn Post Id",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "campaign_name",
|
"fieldname": "campaign_name",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Campaign",
|
"label": "Campaign",
|
||||||
"options": "Campaign"
|
"options": "Campaign",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_6",
|
"fieldname": "column_break_6",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"label": "Share On"
|
"label": "Share On",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_14",
|
"fieldname": "column_break_14",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "tweet_preview",
|
"fieldname": "tweet_preview",
|
||||||
"fieldtype": "HTML"
|
"fieldtype": "HTML",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"depends_on": "eval:doc.linkedin==1",
|
"depends_on": "eval:doc.linkedin==1",
|
||||||
"fieldname": "linkedin_section",
|
"fieldname": "linkedin_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "LinkedIn"
|
"label": "LinkedIn",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "attachments_section",
|
"fieldname": "attachments_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Attachments"
|
"label": "Attachments",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "linkedin_post",
|
"fieldname": "linkedin_post",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Text",
|
||||||
"label": "Post",
|
"label": "Post",
|
||||||
"mandatory_depends_on": "eval:doc.linkedin ==1"
|
"mandatory_depends_on": "eval:doc.linkedin ==1",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_15",
|
"fieldname": "column_break_15",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"fieldname": "scheduled_time",
|
"fieldname": "scheduled_time",
|
||||||
"fieldtype": "Datetime",
|
"fieldtype": "Datetime",
|
||||||
"label": "Scheduled Time",
|
"label": "Scheduled Time",
|
||||||
"read_only_depends_on": "eval:doc.post_status == \"Posted\""
|
"read_only_depends_on": "eval:doc.post_status == \"Posted\"",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-21 15:10:04.953713",
|
"modified": "2020-06-14 10:31:33.961381",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Social Media Post",
|
"name": "Social Media Post",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
@@ -157,6 +194,35 @@
|
|||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "System Manager",
|
"role": "System Manager",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cancel": 1,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Sales User",
|
||||||
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cancel": 1,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Sales Manager",
|
||||||
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/CRM",
|
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/CRM",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_complete": 0,
|
"is_complete": 0,
|
||||||
"modified": "2020-05-27 11:33:09.941263",
|
"modified": "2020-05-28 21:07:41.278784",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "CRM",
|
"name": "CRM",
|
||||||
@@ -35,8 +35,8 @@
|
|||||||
"step": "Create and Send Quotation"
|
"step": "Create and Send Quotation"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"subtitle": "Lead, Opportunity, Customer and more",
|
"subtitle": "Lead, Opportunity, Customer and more.",
|
||||||
"success_message": "CRM Module is all setup!",
|
"success_message": "CRM Module is all Set Up!",
|
||||||
"title": "Let's Setup Your CRM",
|
"title": "Let's Set Up Your CRM.",
|
||||||
"user_can_dismiss": 1
|
"user_can_dismiss": 1
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
"is_mandatory": 0,
|
"is_mandatory": 0,
|
||||||
"is_single": 0,
|
"is_single": 0,
|
||||||
"is_skipped": 0,
|
"is_skipped": 0,
|
||||||
"modified": "2020-05-27 11:30:28.237263",
|
"modified": "2020-05-28 21:07:11.461172",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"name": "Create and Send Quotation",
|
"name": "Create and Send Quotation",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"is_mandatory": 0,
|
"is_mandatory": 0,
|
||||||
"is_single": 0,
|
"is_single": 0,
|
||||||
"is_skipped": 0,
|
"is_skipped": 0,
|
||||||
"modified": "2020-05-27 11:30:59.493720",
|
"modified": "2020-05-28 21:07:01.373403",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"name": "Create Lead",
|
"name": "Create Lead",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"is_mandatory": 0,
|
"is_mandatory": 0,
|
||||||
"is_single": 0,
|
"is_single": 0,
|
||||||
"is_skipped": 0,
|
"is_skipped": 0,
|
||||||
"modified": "2020-05-27 11:28:07.452857",
|
"modified": "2020-05-14 17:28:16.448676",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"name": "Introduction to CRM",
|
"name": "Introduction to CRM",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2017-07-18 15:21:21.527136",
|
"creation": "2017-07-18 15:21:21.527136",
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"fee_structure",
|
"fee_structure",
|
||||||
|
"posting_date",
|
||||||
"due_date",
|
"due_date",
|
||||||
"naming_series",
|
"naming_series",
|
||||||
"fee_creation_status",
|
"fee_creation_status",
|
||||||
@@ -259,10 +261,18 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "dimension_col_break",
|
"fieldname": "dimension_col_break",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Today",
|
||||||
|
"fieldname": "posting_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"label": "Posting Date",
|
||||||
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-05-26 09:10:34.522409",
|
"links": [],
|
||||||
|
"modified": "2020-05-15 08:39:20.682837",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Education",
|
"module": "Education",
|
||||||
"name": "Fee Schedule",
|
"name": "Fee Schedule",
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ def generate_fee(fee_schedule):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
fees_doc.posting_date = doc.posting_date
|
||||||
fees_doc.student = student.student
|
fees_doc.student = student.student
|
||||||
fees_doc.student_name = student.student_name
|
fees_doc.student_name = student.student_name
|
||||||
fees_doc.program = student.program
|
fees_doc.program = student.program
|
||||||
|
|||||||
@@ -9,6 +9,14 @@ frappe.ui.form.on('Fee Structure', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
|
frm.set_query("academic_term", function() {
|
||||||
|
return {
|
||||||
|
"filters": {
|
||||||
|
"academic_year": frm.doc.academic_year
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
frm.set_query("receivable_account", function(doc) {
|
frm.set_query("receivable_account", function(doc) {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
@@ -11,8 +12,8 @@
|
|||||||
"program",
|
"program",
|
||||||
"student_category",
|
"student_category",
|
||||||
"column_break_2",
|
"column_break_2",
|
||||||
"academic_term",
|
|
||||||
"academic_year",
|
"academic_year",
|
||||||
|
"academic_term",
|
||||||
"section_break_4",
|
"section_break_4",
|
||||||
"components",
|
"components",
|
||||||
"section_break_6",
|
"section_break_6",
|
||||||
@@ -157,7 +158,8 @@
|
|||||||
],
|
],
|
||||||
"icon": "fa fa-flag",
|
"icon": "fa fa-flag",
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-05-26 09:04:17.765758",
|
"links": [],
|
||||||
|
"modified": "2020-06-16 15:34:57.295010",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Education",
|
"module": "Education",
|
||||||
"name": "Fee Structure",
|
"name": "Fee Structure",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2015-09-07 14:37:01.886859",
|
"creation": "2015-09-07 14:37:01.886859",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
@@ -16,26 +17,33 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Course",
|
"label": "Course",
|
||||||
"options": "Course",
|
"options": "Course",
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"fetch_from": "course.course_name",
|
||||||
"fieldname": "course_name",
|
"fieldname": "course_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Course Name",
|
"label": "Course Name",
|
||||||
"fetch_from": "course.course_name",
|
"read_only": 1,
|
||||||
"read_only":1
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "required",
|
"fieldname": "required",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Mandatory"
|
"label": "Mandatory",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-06-12 12:42:12.845972",
|
"links": [],
|
||||||
|
"modified": "2020-06-09 18:56:10.213241",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Education",
|
"module": "Education",
|
||||||
"name": "Program Course",
|
"name": "Program Course",
|
||||||
|
|||||||
@@ -1,398 +1,119 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 1,
|
"allow_guest_to_view": 1,
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "",
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2016-09-13 03:05:27.154713",
|
"creation": "2016-09-13 03:05:27.154713",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "Document",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"title",
|
||||||
|
"route",
|
||||||
|
"column_break_3",
|
||||||
|
"academic_year",
|
||||||
|
"admission_start_date",
|
||||||
|
"admission_end_date",
|
||||||
|
"published",
|
||||||
|
"enable_admission_application",
|
||||||
|
"section_break_5",
|
||||||
|
"program_details",
|
||||||
|
"introduction"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "title",
|
"fieldname": "title",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"label": "Title"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Title",
|
|
||||||
"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,
|
|
||||||
"depends_on": "",
|
|
||||||
"fieldname": "route",
|
"fieldname": "route",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Route",
|
"label": "Route",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"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": 1
|
"unique": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "application_form_route",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Application Form Route",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_3",
|
"fieldname": "column_break_3",
|
||||||
"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": "academic_year",
|
"fieldname": "academic_year",
|
||||||
"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": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Academic Year",
|
"label": "Academic Year",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Academic Year",
|
"options": "Academic Year",
|
||||||
"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": "admission_start_date",
|
"fieldname": "admission_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": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Admission Start Date",
|
"label": "Admission Start Date",
|
||||||
"length": 0,
|
"no_copy": 1
|
||||||
"no_copy": 1,
|
|
||||||
"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": "admission_end_date",
|
"fieldname": "admission_end_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": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Admission End Date",
|
"label": "Admission End Date",
|
||||||
"length": 0,
|
"no_copy": 1
|
||||||
"no_copy": 1,
|
|
||||||
"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,
|
"default": "0",
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "published",
|
"fieldname": "published",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"label": "Publish on website"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Publish on website",
|
|
||||||
"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": "section_break_5",
|
"fieldname": "section_break_5",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Eligibility and Details"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Eligibility and Details",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "program_details",
|
"fieldname": "program_details",
|
||||||
"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": "Eligibility and Details",
|
"label": "Eligibility and Details",
|
||||||
"length": 0,
|
"options": "Student Admission Program"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Student Admission Program",
|
|
||||||
"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": "introduction",
|
"fieldname": "introduction",
|
||||||
"fieldtype": "Text Editor",
|
"fieldtype": "Text Editor",
|
||||||
"hidden": 0,
|
"label": "Introduction"
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
{
|
||||||
"in_filter": 0,
|
"default": "0",
|
||||||
"in_global_search": 0,
|
"fieldname": "enable_admission_application",
|
||||||
"in_list_view": 0,
|
"fieldtype": "Check",
|
||||||
"in_standard_filter": 0,
|
"label": "Enable Admission Application"
|
||||||
"label": "Introduction",
|
|
||||||
"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": 1,
|
"has_web_view": 1,
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_published_field": "published",
|
"is_published_field": "published",
|
||||||
"is_submittable": 0,
|
"links": [],
|
||||||
"issingle": 0,
|
"modified": "2020-06-15 20:18:38.591626",
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2017-11-10 18:57:34.570376",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Education",
|
"module": "Education",
|
||||||
"name": "Student Admission",
|
"name": "Student Admission",
|
||||||
"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": "Academics User",
|
"role": "Academics User",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"restrict_to_domain": "Education",
|
"restrict_to_domain": "Education",
|
||||||
"route": "admissions",
|
"route": "admissions",
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "title",
|
"title_field": "title"
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr class="active">
|
<tr class="active">
|
||||||
<th style="width: 90px">Program/Std.</th>
|
<th style="width: 90px">Program/Std.</th>
|
||||||
<th style="width: 170px">Minumum Age(DOB)</th>
|
<th style="width: 170px">Minumum Age</th>
|
||||||
<th style="width: 170px">Maximum Age(DOB)</th>
|
<th style="width: 170px">Maximum Age</th>
|
||||||
<th style="width: 100px">Application Fee</th>
|
<th style="width: 100px">Application Fee</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -52,8 +52,8 @@
|
|||||||
{% for row in program_details %}
|
{% for row in program_details %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ row.program }}</td>
|
<td>{{ row.program }}</td>
|
||||||
<td>{{ row.minimum_age }}</td>
|
<td>{{ row.min_age }}</td>
|
||||||
<td>{{ row.maximum_age }}</td>
|
<td>{{ row.max_age }}</td>
|
||||||
<td>{{ row.application_fee }}</td>
|
<td>{{ row.application_fee }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -61,12 +61,11 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{%- if doc.enable_admission_application -%}
|
||||||
{%- if application_form_route -%}
|
|
||||||
<br>
|
<br>
|
||||||
<p>
|
<p>
|
||||||
<a class='btn btn-primary'
|
<a class='btn btn-primary'
|
||||||
href='/{{ doc.application_form_route }}?new=1'>
|
href='/student-applicant?new=1&student_admission={{doc.name}}'>
|
||||||
{{ _("Apply Now") }}</a>
|
{{ _("Apply Now") }}</a>
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ QUnit.test('Test: Student Admission', function(assert) {
|
|||||||
{admission_start_date: '2016-04-20'},
|
{admission_start_date: '2016-04-20'},
|
||||||
{admission_end_date: '2016-05-31'},
|
{admission_end_date: '2016-05-31'},
|
||||||
{title: '2016-17 Admissions'},
|
{title: '2016-17 Admissions'},
|
||||||
{application_form_route: 'student-applicant'},
|
{enable_admission_application: 1},
|
||||||
{introduction: 'Test intro'},
|
{introduction: 'Test intro'},
|
||||||
{program_details: [
|
{program_details: [
|
||||||
[
|
[
|
||||||
@@ -28,7 +28,7 @@ QUnit.test('Test: Student Admission', function(assert) {
|
|||||||
assert.ok(cur_frm.doc.admission_start_date == '2016-04-20');
|
assert.ok(cur_frm.doc.admission_start_date == '2016-04-20');
|
||||||
assert.ok(cur_frm.doc.admission_end_date == '2016-05-31');
|
assert.ok(cur_frm.doc.admission_end_date == '2016-05-31');
|
||||||
assert.ok(cur_frm.doc.title == '2016-17 Admissions');
|
assert.ok(cur_frm.doc.title == '2016-17 Admissions');
|
||||||
assert.ok(cur_frm.doc.application_form_route == 'student-applicant');
|
assert.ok(cur_frm.doc.enable_admission_application == 1);
|
||||||
assert.ok(cur_frm.doc.introduction == 'Test intro');
|
assert.ok(cur_frm.doc.introduction == 'Test intro');
|
||||||
assert.ok(cur_frm.doc.program_details[0].program == 'Standard Test', 'Program correctly selected');
|
assert.ok(cur_frm.doc.program_details[0].program == 'Standard Test', 'Program correctly selected');
|
||||||
assert.ok(cur_frm.doc.program_details[0].application_fee == 1000);
|
assert.ok(cur_frm.doc.program_details[0].application_fee == 1000);
|
||||||
|
|||||||
@@ -1,237 +1,77 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"autoname": "",
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2017-09-15 12:59:43.207923",
|
"creation": "2017-09-15 12:59:43.207923",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"program",
|
||||||
|
"min_age",
|
||||||
|
"max_age",
|
||||||
|
"column_break_4",
|
||||||
|
"application_fee",
|
||||||
|
"applicant_naming_series"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "program",
|
"fieldname": "program",
|
||||||
"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": "Program",
|
"label": "Program",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Program",
|
"options": "Program",
|
||||||
"permlevel": 0,
|
"show_days": 1,
|
||||||
"precision": "",
|
"show_seconds": 1
|
||||||
"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": "minimum_age",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Minimum Age",
|
|
||||||
"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": "maximum_age",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Maximum Age",
|
|
||||||
"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_4",
|
"fieldname": "column_break_4",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"hidden": 0,
|
"show_days": 1,
|
||||||
"ignore_user_permissions": 0,
|
"show_seconds": 1
|
||||||
"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": "application_fee",
|
"fieldname": "application_fee",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"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": "Application Fee",
|
"label": "Application Fee",
|
||||||
"length": 0,
|
"show_days": 1,
|
||||||
"no_copy": 0,
|
"show_seconds": 1
|
||||||
"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": "applicant_naming_series",
|
"fieldname": "applicant_naming_series",
|
||||||
"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": "Naming Series (for Student Applicant)",
|
"label": "Naming Series (for Student Applicant)",
|
||||||
"length": 0,
|
"show_days": 1,
|
||||||
"no_copy": 0,
|
"show_seconds": 1
|
||||||
"permlevel": 0,
|
},
|
||||||
"precision": "",
|
{
|
||||||
"print_hide": 0,
|
"fieldname": "min_age",
|
||||||
"print_hide_if_no_value": 0,
|
"fieldtype": "Int",
|
||||||
"read_only": 0,
|
"in_list_view": 1,
|
||||||
"remember_last_selected_value": 0,
|
"label": "Minimum Age",
|
||||||
"report_hide": 0,
|
"show_days": 1,
|
||||||
"reqd": 0,
|
"show_seconds": 1
|
||||||
"search_index": 0,
|
},
|
||||||
"set_only_once": 0,
|
{
|
||||||
"translatable": 0,
|
"fieldname": "max_age",
|
||||||
"unique": 0
|
"fieldtype": "Int",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Maximum Age",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"links": [],
|
||||||
"modified": "2018-11-04 03:37:17.408427",
|
"modified": "2020-06-10 23:06:30.037404",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Education",
|
"module": "Education",
|
||||||
"name": "Student Admission Program",
|
"name": "Student Admission Program",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"restrict_to_domain": "Education",
|
"restrict_to_domain": "Education",
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ from __future__ import print_function, unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate, add_years, nowdate, date_diff
|
||||||
|
|
||||||
class StudentApplicant(Document):
|
class StudentApplicant(Document):
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
@@ -31,6 +31,7 @@ class StudentApplicant(Document):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_dates()
|
self.validate_dates()
|
||||||
self.title = " ".join(filter(None, [self.first_name, self.middle_name, self.last_name]))
|
self.title = " ".join(filter(None, [self.first_name, self.middle_name, self.last_name]))
|
||||||
|
|
||||||
if self.student_admission and self.program and self.date_of_birth:
|
if self.student_admission and self.program and self.date_of_birth:
|
||||||
self.validation_from_student_admission()
|
self.validation_from_student_admission()
|
||||||
|
|
||||||
@@ -48,16 +49,16 @@ class StudentApplicant(Document):
|
|||||||
frappe.throw(_("Please select Student Admission which is mandatory for the paid student applicant"))
|
frappe.throw(_("Please select Student Admission which is mandatory for the paid student applicant"))
|
||||||
|
|
||||||
def validation_from_student_admission(self):
|
def validation_from_student_admission(self):
|
||||||
|
|
||||||
student_admission = get_student_admission_data(self.student_admission, self.program)
|
student_admission = get_student_admission_data(self.student_admission, self.program)
|
||||||
|
|
||||||
# different validation for minimum and maximum age so that either min/max can also work independently.
|
if student_admission and student_admission.min_age and \
|
||||||
if student_admission and student_admission.minimum_age and \
|
date_diff(nowdate(), add_years(getdate(self.date_of_birth), student_admission.min_age)) < 0:
|
||||||
getdate(student_admission.minimum_age) < getdate(self.date_of_birth):
|
frappe.throw(_("Not eligible for the admission in this program as per Date Of Birth"))
|
||||||
frappe.throw(_("Not eligible for the admission in this program as per DOB"))
|
|
||||||
|
|
||||||
if student_admission and student_admission.maximum_age and \
|
if student_admission and student_admission.max_age and \
|
||||||
getdate(student_admission.maximum_age) > getdate(self.date_of_birth):
|
date_diff(nowdate(), add_years(getdate(self.date_of_birth), student_admission.max_age)) > 0:
|
||||||
frappe.throw(_("Not eligible for the admission in this program as per DOB"))
|
frappe.throw(_("Not eligible for the admission in this program as per Date Of Birth"))
|
||||||
|
|
||||||
|
|
||||||
def on_payment_authorized(self, *args, **kwargs):
|
def on_payment_authorized(self, *args, **kwargs):
|
||||||
@@ -65,10 +66,12 @@ class StudentApplicant(Document):
|
|||||||
|
|
||||||
|
|
||||||
def get_student_admission_data(student_admission, program):
|
def get_student_admission_data(student_admission, program):
|
||||||
|
|
||||||
student_admission = frappe.db.sql("""select sa.admission_start_date, sa.admission_end_date,
|
student_admission = frappe.db.sql("""select sa.admission_start_date, sa.admission_end_date,
|
||||||
sap.program, sap.minimum_age, sap.maximum_age, sap.applicant_naming_series
|
sap.program, sap.min_age, sap.max_age, sap.applicant_naming_series
|
||||||
from `tabStudent Admission` sa, `tabStudent Admission Program` sap
|
from `tabStudent Admission` sa, `tabStudent Admission Program` sap
|
||||||
where sa.name = sap.parent and sa.name = %s and sap.program = %s""", (student_admission, program), as_dict=1)
|
where sa.name = sap.parent and sa.name = %s and sap.program = %s""", (student_admission, program), as_dict=1)
|
||||||
|
|
||||||
if student_admission:
|
if student_admission:
|
||||||
return student_admission[0]
|
return student_admission[0]
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"login_required": 1,
|
"login_required": 1,
|
||||||
"max_attachment_size": 0,
|
"max_attachment_size": 0,
|
||||||
"modified": "2017-02-21 05:44:46.022738",
|
"modified": "2020-06-11 22:53:45.875310",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Education",
|
"module": "Education",
|
||||||
"name": "student-applicant",
|
"name": "student-applicant",
|
||||||
@@ -24,12 +24,16 @@
|
|||||||
"payment_button_label": "Buy Now",
|
"payment_button_label": "Buy Now",
|
||||||
"published": 1,
|
"published": 1,
|
||||||
"route": "student-applicant",
|
"route": "student-applicant",
|
||||||
|
"route_to_success_link": 0,
|
||||||
|
"show_attachments": 0,
|
||||||
|
"show_in_grid": 0,
|
||||||
"show_sidebar": 1,
|
"show_sidebar": 1,
|
||||||
"sidebar_items": [],
|
"sidebar_items": [],
|
||||||
"success_url": "/student-applicant",
|
"success_url": "/student-applicant",
|
||||||
"title": "Student Applicant",
|
"title": "Student Applicant",
|
||||||
"web_form_fields": [
|
"web_form_fields": [
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "first_name",
|
"fieldname": "first_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -37,9 +41,11 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "middle_name",
|
"fieldname": "middle_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -47,9 +53,11 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "last_name",
|
"fieldname": "last_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -57,9 +65,11 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "image",
|
"fieldname": "image",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -67,9 +77,11 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "program",
|
"fieldname": "program",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -78,9 +90,11 @@
|
|||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"options": "Program",
|
"options": "Program",
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "academic_year",
|
"fieldname": "academic_year",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -89,9 +103,11 @@
|
|||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"options": "Academic Year",
|
"options": "Academic Year",
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "date_of_birth",
|
"fieldname": "date_of_birth",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -99,9 +115,11 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "blood_group",
|
"fieldname": "blood_group",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -110,9 +128,11 @@
|
|||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"options": "\nA+\nA-\nB+\nB-\nO+\nO-\nAB+\nAB-",
|
"options": "\nA+\nA-\nB+\nB-\nO+\nO-\nAB+\nAB-",
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "student_email_id",
|
"fieldname": "student_email_id",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -120,9 +140,11 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "student_mobile_number",
|
"fieldname": "student_mobile_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -130,9 +152,11 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"default": "INDIAN",
|
"default": "INDIAN",
|
||||||
"fieldname": "nationality",
|
"fieldname": "nationality",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
@@ -142,9 +166,11 @@
|
|||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"options": "",
|
"options": "",
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "address_line_1",
|
"fieldname": "address_line_1",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -152,9 +178,11 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "address_line_2",
|
"fieldname": "address_line_2",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -162,9 +190,11 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "pincode",
|
"fieldname": "pincode",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -172,9 +202,11 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "guardians",
|
"fieldname": "guardians",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -183,9 +215,11 @@
|
|||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"options": "Student Guardian",
|
"options": "Student Guardian",
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
"fieldname": "siblings",
|
"fieldname": "siblings",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -194,7 +228,21 @@
|
|||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"options": "Student Sibling",
|
"options": "Student Sibling",
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
|
"fieldname": "student_admission",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"label": "Student Admission",
|
||||||
|
"max_length": 0,
|
||||||
|
"max_value": 0,
|
||||||
|
"options": "Student Admission",
|
||||||
|
"read_only": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -241,12 +241,15 @@ def get_order_taxes(shopify_order, shopify_settings):
|
|||||||
return taxes
|
return taxes
|
||||||
|
|
||||||
def update_taxes_with_shipping_lines(taxes, shipping_lines, shopify_settings):
|
def update_taxes_with_shipping_lines(taxes, shipping_lines, shopify_settings):
|
||||||
|
"""Shipping lines represents the shipping details,
|
||||||
|
each such shipping detail consists of a list of tax_lines"""
|
||||||
for shipping_charge in shipping_lines:
|
for shipping_charge in shipping_lines:
|
||||||
|
for tax in shipping_charge.get("tax_lines"):
|
||||||
taxes.append({
|
taxes.append({
|
||||||
"charge_type": _("Actual"),
|
"charge_type": _("Actual"),
|
||||||
"account_head": get_tax_account_head(shipping_charge),
|
"account_head": get_tax_account_head(tax),
|
||||||
"description": shipping_charge["title"],
|
"description": tax["title"],
|
||||||
"tax_amount": shipping_charge["price"],
|
"tax_amount": tax["price"],
|
||||||
"cost_center": shopify_settings.cost_center
|
"cost_center": shopify_settings.cost_center
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -73,10 +73,16 @@ def link_customer_and_address(raw_billing_data, raw_shipping_data, customer_name
|
|||||||
|
|
||||||
if customer_exists:
|
if customer_exists:
|
||||||
frappe.rename_doc("Customer", old_name, customer_name)
|
frappe.rename_doc("Customer", old_name, customer_name)
|
||||||
billing_address = frappe.get_doc("Address", {"woocommerce_email": customer_woo_com_email, "address_type": "Billing"})
|
for address_type in ("Billing", "Shipping",):
|
||||||
shipping_address = frappe.get_doc("Address", {"woocommerce_email": customer_woo_com_email, "address_type": "Shipping"})
|
try:
|
||||||
rename_address(billing_address, customer)
|
address = frappe.get_doc("Address", {"woocommerce_email": customer_woo_com_email, "address_type": address_type})
|
||||||
rename_address(shipping_address, customer)
|
rename_address(address, customer)
|
||||||
|
except (
|
||||||
|
frappe.DoesNotExistError,
|
||||||
|
frappe.DuplicateEntryError,
|
||||||
|
frappe.ValidationError,
|
||||||
|
):
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
create_address(raw_billing_data, customer, "Billing")
|
create_address(raw_billing_data, customer, "Billing")
|
||||||
create_address(raw_shipping_data, customer, "Shipping")
|
create_address(raw_shipping_data, customer, "Shipping")
|
||||||
|
|||||||
@@ -124,10 +124,11 @@ def add_account_subtype(account_subtype):
|
|||||||
|
|
||||||
@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
|
||||||
last_sync_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date")
|
add the transaction date of the oldest transaction as the last integration date'''
|
||||||
if last_sync_date:
|
last_transaction_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date")
|
||||||
start_date = formatdate(last_sync_date, "YYYY-MM-dd")
|
if last_transaction_date:
|
||||||
|
start_date = formatdate(last_transaction_date, "YYYY-MM-dd")
|
||||||
else:
|
else:
|
||||||
start_date = formatdate(add_months(today(), -12), "YYYY-MM-dd")
|
start_date = formatdate(add_months(today(), -12), "YYYY-MM-dd")
|
||||||
end_date = formatdate(today(), "YYYY-MM-dd")
|
end_date = formatdate(today(), "YYYY-MM-dd")
|
||||||
@@ -139,12 +140,14 @@ def sync_transactions(bank, bank_account):
|
|||||||
for transaction in reversed(transactions):
|
for transaction in reversed(transactions):
|
||||||
result += new_bank_transaction(transaction)
|
result += new_bank_transaction(transaction)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
last_transaction_date = frappe.db.get_value('Bank Transaction', result.pop(), 'date')
|
||||||
|
|
||||||
frappe.logger().info("Plaid added {} new Bank Transactions from '{}' between {} and {}".format(
|
frappe.logger().info("Plaid added {} new Bank Transactions from '{}' between {} and {}".format(
|
||||||
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", getdate(end_date))
|
frappe.db.set_value("Bank Account", bank_account, "last_integration_date", last_transaction_date)
|
||||||
|
|
||||||
return result
|
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
|
frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
|
||||||
|
|
||||||
|
|||||||
@@ -258,7 +258,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"modified": "2019-09-13 12:32:11.384757",
|
"modified": "2020-05-28 12:32:11.384757",
|
||||||
"modified_by": "umair@erpnext.com",
|
"modified_by": "umair@erpnext.com",
|
||||||
"module": "ERPNext Integrations",
|
"module": "ERPNext Integrations",
|
||||||
"name": "Shopify Settings",
|
"name": "Shopify Settings",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import json
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import get_request_session
|
from frappe.utils import get_request_session
|
||||||
|
from requests.exceptions import HTTPError
|
||||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||||
from erpnext.erpnext_integrations.utils import get_webhook_address
|
from erpnext.erpnext_integrations.utils import get_webhook_address
|
||||||
from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log
|
from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log
|
||||||
@@ -29,19 +30,24 @@ class ShopifySettings(Document):
|
|||||||
webhooks = ["orders/create", "orders/paid", "orders/fulfilled"]
|
webhooks = ["orders/create", "orders/paid", "orders/fulfilled"]
|
||||||
# url = get_shopify_url('admin/webhooks.json', self)
|
# url = get_shopify_url('admin/webhooks.json', self)
|
||||||
created_webhooks = [d.method for d in self.webhooks]
|
created_webhooks = [d.method for d in self.webhooks]
|
||||||
url = get_shopify_url('admin/api/2019-04/webhooks.json', self)
|
url = get_shopify_url('admin/api/2020-04/webhooks.json', self)
|
||||||
for method in webhooks:
|
for method in webhooks:
|
||||||
session = get_request_session()
|
session = get_request_session()
|
||||||
try:
|
try:
|
||||||
d = session.post(url, data=json.dumps({
|
res = session.post(url, data=json.dumps({
|
||||||
"webhook": {
|
"webhook": {
|
||||||
"topic": method,
|
"topic": method,
|
||||||
"address": get_webhook_address(connector_name='shopify_connection', method='store_request_data'),
|
"address": get_webhook_address(connector_name='shopify_connection', method='store_request_data'),
|
||||||
"format": "json"
|
"format": "json"
|
||||||
}
|
}
|
||||||
}), headers=get_header(self))
|
}), headers=get_header(self))
|
||||||
d.raise_for_status()
|
res.raise_for_status()
|
||||||
self.update_webhook_table(method, d.json())
|
self.update_webhook_table(method, res.json())
|
||||||
|
|
||||||
|
except HTTPError as e:
|
||||||
|
error_message = res.json().get('errors', e)
|
||||||
|
make_shopify_log(status="Warning", exception=error_message, rollback=True)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
make_shopify_log(status="Warning", exception=e, rollback=True)
|
make_shopify_log(status="Warning", exception=e, rollback=True)
|
||||||
|
|
||||||
@@ -50,13 +56,18 @@ class ShopifySettings(Document):
|
|||||||
deleted_webhooks = []
|
deleted_webhooks = []
|
||||||
|
|
||||||
for d in self.webhooks:
|
for d in self.webhooks:
|
||||||
url = get_shopify_url('admin/api/2019-04/webhooks/{0}.json'.format(d.webhook_id), self)
|
url = get_shopify_url('admin/api/2020-04/webhooks/{0}.json'.format(d.webhook_id), self)
|
||||||
try:
|
try:
|
||||||
res = session.delete(url, headers=get_header(self))
|
res = session.delete(url, headers=get_header(self))
|
||||||
res.raise_for_status()
|
res.raise_for_status()
|
||||||
deleted_webhooks.append(d)
|
deleted_webhooks.append(d)
|
||||||
|
|
||||||
|
except HTTPError as e:
|
||||||
|
error_message = res.json().get('errors', e)
|
||||||
|
make_shopify_log(status="Warning", exception=error_message, rollback=True)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
frappe.log_error(message=frappe.get_traceback(), title=e)
|
frappe.log_error(message=e, title='Shopify Webhooks Issue')
|
||||||
|
|
||||||
for d in deleted_webhooks:
|
for d in deleted_webhooks:
|
||||||
self.remove(d)
|
self.remove(d)
|
||||||
@@ -125,4 +136,3 @@ def setup_custom_fields():
|
|||||||
}
|
}
|
||||||
|
|
||||||
create_custom_fields(custom_fields)
|
create_custom_fields(custom_fields)
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings impo
|
|||||||
shopify_variants_attr_list = ["option1", "option2", "option3"]
|
shopify_variants_attr_list = ["option1", "option2", "option3"]
|
||||||
|
|
||||||
def sync_item_from_shopify(shopify_settings, item):
|
def sync_item_from_shopify(shopify_settings, item):
|
||||||
url = get_shopify_url("admin/api/2019-04/products/{0}.json".format(item.get("product_id")), shopify_settings)
|
url = get_shopify_url("admin/api/2020-04/products/{0}.json".format(item.get("product_id")), shopify_settings)
|
||||||
session = get_request_session()
|
session = get_request_session()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('Tally Migration', {
|
frappe.provide("erpnext.tally_migration");
|
||||||
|
|
||||||
|
frappe.ui.form.on("Tally Migration", {
|
||||||
onload: function (frm) {
|
onload: function (frm) {
|
||||||
let reload_status = true;
|
let reload_status = true;
|
||||||
frappe.realtime.on("tally_migration_progress_update", function (data) {
|
frappe.realtime.on("tally_migration_progress_update", function (data) {
|
||||||
@@ -35,7 +37,17 @@ frappe.ui.form.on('Tally Migration', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function (frm) {
|
refresh: function (frm) {
|
||||||
|
frm.trigger("show_logs_preview");
|
||||||
|
erpnext.tally_migration.failed_import_log = JSON.parse(frm.doc.failed_import_log);
|
||||||
|
erpnext.tally_migration.fixed_errors_log = JSON.parse(frm.doc.fixed_errors_log);
|
||||||
|
|
||||||
|
["default_round_off_account", "default_warehouse", "default_cost_center"].forEach(account => {
|
||||||
|
frm.toggle_reqd(account, frm.doc.is_master_data_imported === 1)
|
||||||
|
frm.toggle_enable(account, frm.doc.is_day_book_data_processed != 1)
|
||||||
|
})
|
||||||
|
|
||||||
if (frm.doc.master_data && !frm.doc.is_master_data_imported) {
|
if (frm.doc.master_data && !frm.doc.is_master_data_imported) {
|
||||||
if (frm.doc.is_master_data_processed) {
|
if (frm.doc.is_master_data_processed) {
|
||||||
if (frm.doc.status != "Importing Master Data") {
|
if (frm.doc.status != "Importing Master Data") {
|
||||||
@@ -47,6 +59,7 @@ frappe.ui.form.on('Tally Migration', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.day_book_data && !frm.doc.is_day_book_data_imported) {
|
if (frm.doc.day_book_data && !frm.doc.is_day_book_data_imported) {
|
||||||
if (frm.doc.is_day_book_data_processed) {
|
if (frm.doc.is_day_book_data_processed) {
|
||||||
if (frm.doc.status != "Importing Day Book Data") {
|
if (frm.doc.status != "Importing Day Book Data") {
|
||||||
@@ -59,6 +72,17 @@ frappe.ui.form.on('Tally Migration', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
erpnext_company: function (frm) {
|
||||||
|
frappe.db.exists("Company", frm.doc.erpnext_company).then(exists => {
|
||||||
|
if (exists) {
|
||||||
|
frappe.msgprint(
|
||||||
|
__("Company {0} already exists. Continuing will overwrite the Company and Chart of Accounts", [frm.doc.erpnext_company]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
add_button: function (frm, label, method) {
|
add_button: function (frm, label, method) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(
|
||||||
label,
|
label,
|
||||||
@@ -71,5 +95,255 @@ frappe.ui.form.on('Tally Migration', {
|
|||||||
frm.reload_doc();
|
frm.reload_doc();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
render_html_table(frm, shown_logs, hidden_logs, field) {
|
||||||
|
if (shown_logs && shown_logs.length > 0) {
|
||||||
|
frm.toggle_display(field, true);
|
||||||
|
} else {
|
||||||
|
frm.toggle_display(field, false);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let rows = erpnext.tally_migration.get_html_rows(shown_logs, field);
|
||||||
|
let rows_head, table_caption;
|
||||||
|
|
||||||
|
let table_footer = (hidden_logs && (hidden_logs.length > 0)) ? `<tr class="text-muted">
|
||||||
|
<td colspan="4">And ${hidden_logs.length} more others</td>
|
||||||
|
</tr>`: "";
|
||||||
|
|
||||||
|
if (field === "fixed_error_log_preview") {
|
||||||
|
rows_head = `<th width="75%">${__("Meta Data")}</th>
|
||||||
|
<th width="10%">${__("Unresolve")}</th>`
|
||||||
|
table_caption = "Resolved Issues"
|
||||||
|
} else {
|
||||||
|
rows_head = `<th width="75%">${__("Error Message")}</th>
|
||||||
|
<th width="10%">${__("Create")}</th>`
|
||||||
|
table_caption = "Error Log"
|
||||||
|
}
|
||||||
|
|
||||||
|
frm.get_field(field).$wrapper.html(`
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<caption>${table_caption}</caption>
|
||||||
|
<tr class="text-muted">
|
||||||
|
<th width="5%">${__("#")}</th>
|
||||||
|
<th width="10%">${__("DocType")}</th>
|
||||||
|
${rows_head}
|
||||||
|
</tr>
|
||||||
|
${rows}
|
||||||
|
${table_footer}
|
||||||
|
</table>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
|
||||||
|
show_error_summary(frm) {
|
||||||
|
let summary = erpnext.tally_migration.failed_import_log.reduce((summary, row) => {
|
||||||
|
if (row.doc) {
|
||||||
|
if (summary[row.doc.doctype]) {
|
||||||
|
summary[row.doc.doctype] += 1;
|
||||||
|
} else {
|
||||||
|
summary[row.doc.doctype] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return summary
|
||||||
|
}, {});
|
||||||
|
console.table(summary);
|
||||||
|
},
|
||||||
|
|
||||||
|
show_logs_preview(frm) {
|
||||||
|
let empty = "[]";
|
||||||
|
let import_log = frm.doc.failed_import_log || empty;
|
||||||
|
let completed_log = frm.doc.fixed_errors_log || empty;
|
||||||
|
let render_section = !(import_log === completed_log && import_log === empty);
|
||||||
|
|
||||||
|
frm.toggle_display("import_log_section", render_section);
|
||||||
|
if (render_section) {
|
||||||
|
frm.trigger("show_error_summary");
|
||||||
|
frm.trigger("show_errored_import_log");
|
||||||
|
frm.trigger("show_fixed_errors_log");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
show_errored_import_log(frm) {
|
||||||
|
let import_log = erpnext.tally_migration.failed_import_log;
|
||||||
|
let logs = import_log.slice(0, 20);
|
||||||
|
let hidden_logs = import_log.slice(20);
|
||||||
|
|
||||||
|
frm.events.render_html_table(frm, logs, hidden_logs, "failed_import_preview");
|
||||||
|
},
|
||||||
|
|
||||||
|
show_fixed_errors_log(frm) {
|
||||||
|
let completed_log = erpnext.tally_migration.fixed_errors_log;
|
||||||
|
let logs = completed_log.slice(0, 20);
|
||||||
|
let hidden_logs = completed_log.slice(20);
|
||||||
|
|
||||||
|
frm.events.render_html_table(frm, logs, hidden_logs, "fixed_error_log_preview");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
erpnext.tally_migration.getError = (traceback) => {
|
||||||
|
/* Extracts the Error Message from the Python Traceback or Solved error */
|
||||||
|
let is_multiline = traceback.trim().indexOf("\n") != -1;
|
||||||
|
let message;
|
||||||
|
|
||||||
|
if (is_multiline) {
|
||||||
|
let exc_error_idx = traceback.trim().lastIndexOf("\n") + 1
|
||||||
|
let error_line = traceback.substr(exc_error_idx)
|
||||||
|
let split_str_idx = (error_line.indexOf(':') > 0) ? error_line.indexOf(':') + 1 : 0;
|
||||||
|
message = error_line.slice(split_str_idx).trim();
|
||||||
|
} else {
|
||||||
|
message = traceback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return message
|
||||||
|
}
|
||||||
|
|
||||||
|
erpnext.tally_migration.cleanDoc = (obj) => {
|
||||||
|
/* Strips all null and empty values of your JSON object */
|
||||||
|
let temp = obj;
|
||||||
|
$.each(temp, function(key, value){
|
||||||
|
if (value === "" || value === null){
|
||||||
|
delete obj[key];
|
||||||
|
} else if (Object.prototype.toString.call(value) === '[object Object]') {
|
||||||
|
erpnext.tally_migration.cleanDoc(value);
|
||||||
|
} else if ($.isArray(value)) {
|
||||||
|
$.each(value, function (k,v) { erpnext.tally_migration.cleanDoc(v); });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
erpnext.tally_migration.unresolve = (document) => {
|
||||||
|
/* Mark document migration as unresolved ie. move to failed error log */
|
||||||
|
let frm = cur_frm;
|
||||||
|
let failed_log = erpnext.tally_migration.failed_import_log;
|
||||||
|
let fixed_log = erpnext.tally_migration.fixed_errors_log;
|
||||||
|
|
||||||
|
let modified_fixed_log = fixed_log.filter(row => {
|
||||||
|
if (!frappe.utils.deep_equal(erpnext.tally_migration.cleanDoc(row.doc), document)) {
|
||||||
|
return row
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
failed_log.push({ doc: document, exc: `Marked unresolved on ${Date()}` });
|
||||||
|
|
||||||
|
frm.doc.failed_import_log = JSON.stringify(failed_log);
|
||||||
|
frm.doc.fixed_errors_log = JSON.stringify(modified_fixed_log);
|
||||||
|
|
||||||
|
frm.dirty();
|
||||||
|
frm.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
erpnext.tally_migration.resolve = (document) => {
|
||||||
|
/* Mark document migration as resolved ie. move to fixed error log */
|
||||||
|
let frm = cur_frm;
|
||||||
|
let failed_log = erpnext.tally_migration.failed_import_log;
|
||||||
|
let fixed_log = erpnext.tally_migration.fixed_errors_log;
|
||||||
|
|
||||||
|
let modified_failed_log = failed_log.filter(row => {
|
||||||
|
if (!frappe.utils.deep_equal(erpnext.tally_migration.cleanDoc(row.doc), document)) {
|
||||||
|
return row
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fixed_log.push({ doc: document, exc: `Solved on ${Date()}` });
|
||||||
|
|
||||||
|
frm.doc.failed_import_log = JSON.stringify(modified_failed_log);
|
||||||
|
frm.doc.fixed_errors_log = JSON.stringify(fixed_log);
|
||||||
|
|
||||||
|
frm.dirty();
|
||||||
|
frm.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
erpnext.tally_migration.create_new_doc = (document) => {
|
||||||
|
/* Mark as resolved and create new document */
|
||||||
|
erpnext.tally_migration.resolve(document);
|
||||||
|
return frappe.call({
|
||||||
|
type: "POST",
|
||||||
|
method: 'erpnext.erpnext_integrations.doctype.tally_migration.tally_migration.new_doc',
|
||||||
|
args: {
|
||||||
|
document
|
||||||
|
},
|
||||||
|
freeze: true,
|
||||||
|
callback: function(r) {
|
||||||
|
if(!r.exc) {
|
||||||
|
frappe.model.sync(r.message);
|
||||||
|
frappe.get_doc(r.message.doctype, r.message.name).__run_link_triggers = true;
|
||||||
|
frappe.set_route("Form", r.message.doctype, r.message.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
erpnext.tally_migration.get_html_rows = (logs, field) => {
|
||||||
|
let index = 0;
|
||||||
|
let rows = logs
|
||||||
|
.map(({ doc, exc }) => {
|
||||||
|
let id = frappe.dom.get_unique_id();
|
||||||
|
let traceback = exc;
|
||||||
|
|
||||||
|
let error_message = erpnext.tally_migration.getError(traceback);
|
||||||
|
index++;
|
||||||
|
|
||||||
|
let show_traceback = `
|
||||||
|
<button class="btn btn-default btn-xs m-3" type="button" data-toggle="collapse" data-target="#${id}-traceback" aria-expanded="false" aria-controls="${id}-traceback">
|
||||||
|
${__("Show Traceback")}
|
||||||
|
</button>
|
||||||
|
<div class="collapse margin-top" id="${id}-traceback">
|
||||||
|
<div class="well">
|
||||||
|
<pre style="font-size: smaller;">${traceback}</pre>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
let show_doc = `
|
||||||
|
<button class='btn btn-default btn-xs m-3' type='button' data-toggle='collapse' data-target='#${id}-doc' aria-expanded='false' aria-controls='${id}-doc'>
|
||||||
|
${__("Show Document")}
|
||||||
|
</button>
|
||||||
|
<div class="collapse margin-top" id="${id}-doc">
|
||||||
|
<div class="well">
|
||||||
|
<pre style="font-size: smaller;">${JSON.stringify(erpnext.tally_migration.cleanDoc(doc), null, 1)}</pre>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
let create_button = `
|
||||||
|
<button class='btn btn-default btn-xs m-3' type='button' onclick='erpnext.tally_migration.create_new_doc(${JSON.stringify(doc)})'>
|
||||||
|
${__("Create Document")}
|
||||||
|
</button>`
|
||||||
|
|
||||||
|
let mark_as_unresolved = `
|
||||||
|
<button class='btn btn-default btn-xs m-3' type='button' onclick='erpnext.tally_migration.unresolve(${JSON.stringify(doc)})'>
|
||||||
|
${__("Mark as unresolved")}
|
||||||
|
</button>`
|
||||||
|
|
||||||
|
if (field === "fixed_error_log_preview") {
|
||||||
|
return `<tr>
|
||||||
|
<td>${index}</td>
|
||||||
|
<td>
|
||||||
|
<div>${doc.doctype}</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>${error_message}</div>
|
||||||
|
<div>${show_doc}</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>${mark_as_unresolved}</div>
|
||||||
|
</td>
|
||||||
|
</tr>`;
|
||||||
|
} else {
|
||||||
|
return `<tr>
|
||||||
|
<td>${index}</td>
|
||||||
|
<td>
|
||||||
|
<div>${doc.doctype}</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>${error_message}</div>
|
||||||
|
<div>${show_traceback}</div>
|
||||||
|
<div>${show_doc}</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>${create_button}</div>
|
||||||
|
</td>
|
||||||
|
</tr>`;
|
||||||
|
}
|
||||||
|
}).join("");
|
||||||
|
|
||||||
|
return rows
|
||||||
|
}
|
||||||
@@ -28,14 +28,19 @@
|
|||||||
"vouchers",
|
"vouchers",
|
||||||
"accounts_section",
|
"accounts_section",
|
||||||
"default_warehouse",
|
"default_warehouse",
|
||||||
"round_off_account",
|
"default_round_off_account",
|
||||||
"column_break_21",
|
"column_break_21",
|
||||||
"default_cost_center",
|
"default_cost_center",
|
||||||
"day_book_section",
|
"day_book_section",
|
||||||
"day_book_data",
|
"day_book_data",
|
||||||
"column_break_27",
|
"column_break_27",
|
||||||
"is_day_book_data_processed",
|
"is_day_book_data_processed",
|
||||||
"is_day_book_data_imported"
|
"is_day_book_data_imported",
|
||||||
|
"import_log_section",
|
||||||
|
"failed_import_log",
|
||||||
|
"fixed_errors_log",
|
||||||
|
"failed_import_preview",
|
||||||
|
"fixed_error_log_preview"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -57,6 +62,7 @@
|
|||||||
"fieldname": "tally_creditors_account",
|
"fieldname": "tally_creditors_account",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Tally Creditors Account",
|
"label": "Tally Creditors Account",
|
||||||
|
"read_only_depends_on": "eval:doc.is_master_data_processed==1",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -69,6 +75,7 @@
|
|||||||
"fieldname": "tally_debtors_account",
|
"fieldname": "tally_debtors_account",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Tally Debtors Account",
|
"label": "Tally Debtors Account",
|
||||||
|
"read_only_depends_on": "eval:doc.is_master_data_processed==1",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -136,6 +143,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "is_master_data_imported",
|
"depends_on": "is_master_data_imported",
|
||||||
|
"description": "The accounts are set by the system automatically but do confirm these defaults",
|
||||||
"fieldname": "accounts_section",
|
"fieldname": "accounts_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Accounts"
|
"label": "Accounts"
|
||||||
@@ -146,12 +154,6 @@
|
|||||||
"label": "Default Warehouse",
|
"label": "Default Warehouse",
|
||||||
"options": "Warehouse"
|
"options": "Warehouse"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "round_off_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Round Off Account",
|
|
||||||
"options": "Account"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_21",
|
"fieldname": "column_break_21",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
@@ -212,11 +214,47 @@
|
|||||||
"fieldname": "default_uom",
|
"fieldname": "default_uom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Default UOM",
|
"label": "Default UOM",
|
||||||
"options": "UOM"
|
"options": "UOM",
|
||||||
|
"read_only_depends_on": "eval:doc.is_master_data_imported==1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "[]",
|
||||||
|
"fieldname": "failed_import_log",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"hidden": 1,
|
||||||
|
"options": "JSON"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "failed_import_preview",
|
||||||
|
"fieldtype": "HTML",
|
||||||
|
"label": "Failed Import Log"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "import_log_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Import Log"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "default_round_off_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Default Round Off Account",
|
||||||
|
"options": "Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "[]",
|
||||||
|
"fieldname": "fixed_errors_log",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"hidden": 1,
|
||||||
|
"options": "JSON"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "fixed_error_log_preview",
|
||||||
|
"fieldtype": "HTML",
|
||||||
|
"label": "Fixed Error Log"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-16 13:03:28.894919",
|
"modified": "2020-04-28 00:29:18.039826",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "ERPNext Integrations",
|
"module": "ERPNext Integrations",
|
||||||
"name": "Tally Migration",
|
"name": "Tally Migration",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
import zipfile
|
import zipfile
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
@@ -15,18 +16,34 @@ from bs4 import BeautifulSoup as bs
|
|||||||
import frappe
|
import frappe
|
||||||
from erpnext import encode_company_abbr
|
from erpnext import encode_company_abbr
|
||||||
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts
|
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts
|
||||||
|
from erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer import unset_existing_data
|
||||||
|
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.model.naming import getseries, revert_series_if_last
|
from frappe.model.naming import getseries, revert_series_if_last
|
||||||
from frappe.utils.data import format_datetime
|
from frappe.utils.data import format_datetime
|
||||||
|
|
||||||
|
|
||||||
PRIMARY_ACCOUNT = "Primary"
|
PRIMARY_ACCOUNT = "Primary"
|
||||||
VOUCHER_CHUNK_SIZE = 500
|
VOUCHER_CHUNK_SIZE = 500
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def new_doc(document):
|
||||||
|
document = json.loads(document)
|
||||||
|
doctype = document.pop("doctype")
|
||||||
|
document.pop("name", None)
|
||||||
|
doc = frappe.new_doc(doctype)
|
||||||
|
doc.update(document)
|
||||||
|
|
||||||
|
return doc
|
||||||
|
|
||||||
class TallyMigration(Document):
|
class TallyMigration(Document):
|
||||||
|
def validate(self):
|
||||||
|
failed_import_log = json.loads(self.failed_import_log)
|
||||||
|
sorted_failed_import_log = sorted(failed_import_log, key=lambda row: row["doc"]["creation"])
|
||||||
|
self.failed_import_log = json.dumps(sorted_failed_import_log)
|
||||||
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
if not self.name:
|
if not self.name:
|
||||||
self.name = "Tally Migration on " + format_datetime(self.creation)
|
self.name = "Tally Migration on " + format_datetime(self.creation)
|
||||||
@@ -65,9 +82,17 @@ class TallyMigration(Document):
|
|||||||
"attached_to_name": self.name,
|
"attached_to_name": self.name,
|
||||||
"content": json.dumps(value),
|
"content": json.dumps(value),
|
||||||
"is_private": True
|
"is_private": True
|
||||||
}).insert()
|
})
|
||||||
|
try:
|
||||||
|
f.insert()
|
||||||
|
except frappe.DuplicateEntryError:
|
||||||
|
pass
|
||||||
setattr(self, key, f.file_url)
|
setattr(self, key, f.file_url)
|
||||||
|
|
||||||
|
def set_account_defaults(self):
|
||||||
|
self.default_cost_center, self.default_round_off_account = frappe.db.get_value("Company", self.erpnext_company, ["cost_center", "round_off_account"])
|
||||||
|
self.default_warehouse = frappe.db.get_value("Stock Settings", "Stock Settings", "default_warehouse")
|
||||||
|
|
||||||
def _process_master_data(self):
|
def _process_master_data(self):
|
||||||
def get_company_name(collection):
|
def get_company_name(collection):
|
||||||
return collection.find_all("REMOTECMPINFO.LIST")[0].REMOTECMPNAME.string.strip()
|
return collection.find_all("REMOTECMPINFO.LIST")[0].REMOTECMPNAME.string.strip()
|
||||||
@@ -84,7 +109,11 @@ class TallyMigration(Document):
|
|||||||
children, parents = get_children_and_parent_dict(accounts)
|
children, parents = get_children_and_parent_dict(accounts)
|
||||||
group_set = [acc[1] for acc in accounts if acc[2]]
|
group_set = [acc[1] for acc in accounts if acc[2]]
|
||||||
children, customers, suppliers = remove_parties(parents, children, group_set)
|
children, customers, suppliers = remove_parties(parents, children, group_set)
|
||||||
|
|
||||||
|
try:
|
||||||
coa = traverse({}, children, roots, roots, group_set)
|
coa = traverse({}, children, roots, roots, group_set)
|
||||||
|
except RecursionError:
|
||||||
|
self.log(_("Error occured while parsing Chart of Accounts: Please make sure that no two accounts have the same name"))
|
||||||
|
|
||||||
for account in coa:
|
for account in coa:
|
||||||
coa[account]["root_type"] = root_type_map[account]
|
coa[account]["root_type"] = root_type_map[account]
|
||||||
@@ -126,14 +155,18 @@ class TallyMigration(Document):
|
|||||||
def remove_parties(parents, children, group_set):
|
def remove_parties(parents, children, group_set):
|
||||||
customers, suppliers = set(), set()
|
customers, suppliers = set(), set()
|
||||||
for account in parents:
|
for account in parents:
|
||||||
|
found = False
|
||||||
if self.tally_creditors_account in parents[account]:
|
if self.tally_creditors_account in parents[account]:
|
||||||
children.pop(account, None)
|
found = True
|
||||||
if account not in group_set:
|
if account not in group_set:
|
||||||
suppliers.add(account)
|
suppliers.add(account)
|
||||||
elif self.tally_debtors_account in parents[account]:
|
if self.tally_debtors_account in parents[account]:
|
||||||
children.pop(account, None)
|
found = True
|
||||||
if account not in group_set:
|
if account not in group_set:
|
||||||
customers.add(account)
|
customers.add(account)
|
||||||
|
if found:
|
||||||
|
children.pop(account, None)
|
||||||
|
|
||||||
return children, customers, suppliers
|
return children, customers, suppliers
|
||||||
|
|
||||||
def traverse(tree, children, accounts, roots, group_set):
|
def traverse(tree, children, accounts, roots, group_set):
|
||||||
@@ -151,6 +184,7 @@ class TallyMigration(Document):
|
|||||||
parties, addresses = [], []
|
parties, addresses = [], []
|
||||||
for account in collection.find_all("LEDGER"):
|
for account in collection.find_all("LEDGER"):
|
||||||
party_type = None
|
party_type = None
|
||||||
|
links = []
|
||||||
if account.NAME.string.strip() in customers:
|
if account.NAME.string.strip() in customers:
|
||||||
party_type = "Customer"
|
party_type = "Customer"
|
||||||
parties.append({
|
parties.append({
|
||||||
@@ -161,7 +195,9 @@ class TallyMigration(Document):
|
|||||||
"territory": "All Territories",
|
"territory": "All Territories",
|
||||||
"customer_type": "Individual",
|
"customer_type": "Individual",
|
||||||
})
|
})
|
||||||
elif account.NAME.string.strip() in suppliers:
|
links.append({"link_doctype": party_type, "link_name": account["NAME"]})
|
||||||
|
|
||||||
|
if account.NAME.string.strip() in suppliers:
|
||||||
party_type = "Supplier"
|
party_type = "Supplier"
|
||||||
parties.append({
|
parties.append({
|
||||||
"doctype": party_type,
|
"doctype": party_type,
|
||||||
@@ -170,6 +206,8 @@ class TallyMigration(Document):
|
|||||||
"supplier_group": "All Supplier Groups",
|
"supplier_group": "All Supplier Groups",
|
||||||
"supplier_type": "Individual",
|
"supplier_type": "Individual",
|
||||||
})
|
})
|
||||||
|
links.append({"link_doctype": party_type, "link_name": account["NAME"]})
|
||||||
|
|
||||||
if party_type:
|
if party_type:
|
||||||
address = "\n".join([a.string.strip() for a in account.find_all("ADDRESS")])
|
address = "\n".join([a.string.strip() for a in account.find_all("ADDRESS")])
|
||||||
addresses.append({
|
addresses.append({
|
||||||
@@ -183,7 +221,7 @@ class TallyMigration(Document):
|
|||||||
"mobile": account.LEDGERPHONE.string.strip() if account.LEDGERPHONE else None,
|
"mobile": account.LEDGERPHONE.string.strip() if account.LEDGERPHONE else None,
|
||||||
"phone": account.LEDGERPHONE.string.strip() if account.LEDGERPHONE else None,
|
"phone": account.LEDGERPHONE.string.strip() if account.LEDGERPHONE else None,
|
||||||
"gstin": account.PARTYGSTIN.string.strip() if account.PARTYGSTIN else None,
|
"gstin": account.PARTYGSTIN.string.strip() if account.PARTYGSTIN else None,
|
||||||
"links": [{"link_doctype": party_type, "link_name": account["NAME"]}],
|
"links": links
|
||||||
})
|
})
|
||||||
return parties, addresses
|
return parties, addresses
|
||||||
|
|
||||||
@@ -242,12 +280,18 @@ class TallyMigration(Document):
|
|||||||
def create_company_and_coa(coa_file_url):
|
def create_company_and_coa(coa_file_url):
|
||||||
coa_file = frappe.get_doc("File", {"file_url": coa_file_url})
|
coa_file = frappe.get_doc("File", {"file_url": coa_file_url})
|
||||||
frappe.local.flags.ignore_chart_of_accounts = True
|
frappe.local.flags.ignore_chart_of_accounts = True
|
||||||
|
|
||||||
|
try:
|
||||||
company = frappe.get_doc({
|
company = frappe.get_doc({
|
||||||
"doctype": "Company",
|
"doctype": "Company",
|
||||||
"company_name": self.erpnext_company,
|
"company_name": self.erpnext_company,
|
||||||
"default_currency": "INR",
|
"default_currency": "INR",
|
||||||
"enable_perpetual_inventory": 0,
|
"enable_perpetual_inventory": 0,
|
||||||
}).insert()
|
}).insert()
|
||||||
|
except frappe.DuplicateEntryError:
|
||||||
|
company = frappe.get_doc("Company", self.erpnext_company)
|
||||||
|
unset_existing_data(self.erpnext_company)
|
||||||
|
|
||||||
frappe.local.flags.ignore_chart_of_accounts = False
|
frappe.local.flags.ignore_chart_of_accounts = False
|
||||||
create_charts(company.name, custom_chart=json.loads(coa_file.get_content()))
|
create_charts(company.name, custom_chart=json.loads(coa_file.get_content()))
|
||||||
company.create_default_warehouses()
|
company.create_default_warehouses()
|
||||||
@@ -256,36 +300,35 @@ class TallyMigration(Document):
|
|||||||
parties_file = frappe.get_doc("File", {"file_url": parties_file_url})
|
parties_file = frappe.get_doc("File", {"file_url": parties_file_url})
|
||||||
for party in json.loads(parties_file.get_content()):
|
for party in json.loads(parties_file.get_content()):
|
||||||
try:
|
try:
|
||||||
frappe.get_doc(party).insert()
|
party_doc = frappe.get_doc(party)
|
||||||
|
party_doc.insert()
|
||||||
except:
|
except:
|
||||||
self.log(party)
|
self.log(party_doc)
|
||||||
addresses_file = frappe.get_doc("File", {"file_url": addresses_file_url})
|
addresses_file = frappe.get_doc("File", {"file_url": addresses_file_url})
|
||||||
for address in json.loads(addresses_file.get_content()):
|
for address in json.loads(addresses_file.get_content()):
|
||||||
try:
|
try:
|
||||||
frappe.get_doc(address).insert(ignore_mandatory=True)
|
address_doc = frappe.get_doc(address)
|
||||||
|
address_doc.insert(ignore_mandatory=True)
|
||||||
except:
|
except:
|
||||||
try:
|
self.log(address_doc)
|
||||||
gstin = address.pop("gstin", None)
|
|
||||||
frappe.get_doc(address).insert(ignore_mandatory=True)
|
|
||||||
self.log({"address": address, "message": "Invalid GSTIN: {}. Address was created without GSTIN".format(gstin)})
|
|
||||||
except:
|
|
||||||
self.log(address)
|
|
||||||
|
|
||||||
def create_items_uoms(items_file_url, uoms_file_url):
|
def create_items_uoms(items_file_url, uoms_file_url):
|
||||||
uoms_file = frappe.get_doc("File", {"file_url": uoms_file_url})
|
uoms_file = frappe.get_doc("File", {"file_url": uoms_file_url})
|
||||||
for uom in json.loads(uoms_file.get_content()):
|
for uom in json.loads(uoms_file.get_content()):
|
||||||
if not frappe.db.exists(uom):
|
if not frappe.db.exists(uom):
|
||||||
try:
|
try:
|
||||||
frappe.get_doc(uom).insert()
|
uom_doc = frappe.get_doc(uom)
|
||||||
|
uom_doc.insert()
|
||||||
except:
|
except:
|
||||||
self.log(uom)
|
self.log(uom_doc)
|
||||||
|
|
||||||
items_file = frappe.get_doc("File", {"file_url": items_file_url})
|
items_file = frappe.get_doc("File", {"file_url": items_file_url})
|
||||||
for item in json.loads(items_file.get_content()):
|
for item in json.loads(items_file.get_content()):
|
||||||
try:
|
try:
|
||||||
frappe.get_doc(item).insert()
|
item_doc = frappe.get_doc(item)
|
||||||
|
item_doc.insert()
|
||||||
except:
|
except:
|
||||||
self.log(item)
|
self.log(item_doc)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.publish("Import Master Data", _("Creating Company and Importing Chart of Accounts"), 1, 4)
|
self.publish("Import Master Data", _("Creating Company and Importing Chart of Accounts"), 1, 4)
|
||||||
@@ -299,10 +342,13 @@ class TallyMigration(Document):
|
|||||||
|
|
||||||
self.publish("Import Master Data", _("Done"), 4, 4)
|
self.publish("Import Master Data", _("Done"), 4, 4)
|
||||||
|
|
||||||
|
self.set_account_defaults()
|
||||||
self.is_master_data_imported = 1
|
self.is_master_data_imported = 1
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
except:
|
except:
|
||||||
self.publish("Import Master Data", _("Process Failed"), -1, 5)
|
self.publish("Import Master Data", _("Process Failed"), -1, 5)
|
||||||
|
frappe.db.rollback()
|
||||||
self.log()
|
self.log()
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@@ -323,7 +369,9 @@ class TallyMigration(Document):
|
|||||||
processed_voucher = function(voucher)
|
processed_voucher = function(voucher)
|
||||||
if processed_voucher:
|
if processed_voucher:
|
||||||
vouchers.append(processed_voucher)
|
vouchers.append(processed_voucher)
|
||||||
|
frappe.db.commit()
|
||||||
except:
|
except:
|
||||||
|
frappe.db.rollback()
|
||||||
self.log(voucher)
|
self.log(voucher)
|
||||||
return vouchers
|
return vouchers
|
||||||
|
|
||||||
@@ -349,6 +397,7 @@ class TallyMigration(Document):
|
|||||||
journal_entry = {
|
journal_entry = {
|
||||||
"doctype": "Journal Entry",
|
"doctype": "Journal Entry",
|
||||||
"tally_guid": voucher.GUID.string.strip(),
|
"tally_guid": voucher.GUID.string.strip(),
|
||||||
|
"tally_voucher_no": voucher.VOUCHERNUMBER.string.strip() if voucher.VOUCHERNUMBER else "",
|
||||||
"posting_date": voucher.DATE.string.strip(),
|
"posting_date": voucher.DATE.string.strip(),
|
||||||
"company": self.erpnext_company,
|
"company": self.erpnext_company,
|
||||||
"accounts": accounts,
|
"accounts": accounts,
|
||||||
@@ -377,6 +426,7 @@ class TallyMigration(Document):
|
|||||||
"doctype": doctype,
|
"doctype": doctype,
|
||||||
party_field: voucher.PARTYNAME.string.strip(),
|
party_field: voucher.PARTYNAME.string.strip(),
|
||||||
"tally_guid": voucher.GUID.string.strip(),
|
"tally_guid": voucher.GUID.string.strip(),
|
||||||
|
"tally_voucher_no": voucher.VOUCHERNUMBER.string.strip() if voucher.VOUCHERNUMBER else "",
|
||||||
"posting_date": voucher.DATE.string.strip(),
|
"posting_date": voucher.DATE.string.strip(),
|
||||||
"due_date": voucher.DATE.string.strip(),
|
"due_date": voucher.DATE.string.strip(),
|
||||||
"items": get_voucher_items(voucher, doctype),
|
"items": get_voucher_items(voucher, doctype),
|
||||||
@@ -468,13 +518,20 @@ class TallyMigration(Document):
|
|||||||
oldest_year = new_year
|
oldest_year = new_year
|
||||||
|
|
||||||
def create_custom_fields(doctypes):
|
def create_custom_fields(doctypes):
|
||||||
for doctype in doctypes:
|
tally_guid_df = {
|
||||||
df = {
|
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"fieldname": "tally_guid",
|
"fieldname": "tally_guid",
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"label": "Tally GUID"
|
"label": "Tally GUID"
|
||||||
}
|
}
|
||||||
|
tally_voucher_no_df = {
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"fieldname": "tally_voucher_no",
|
||||||
|
"read_only": 1,
|
||||||
|
"label": "Tally Voucher Number"
|
||||||
|
}
|
||||||
|
for df in [tally_guid_df, tally_voucher_no_df]:
|
||||||
|
for doctype in doctypes:
|
||||||
create_custom_field(doctype, df)
|
create_custom_field(doctype, df)
|
||||||
|
|
||||||
def create_price_list():
|
def create_price_list():
|
||||||
@@ -490,7 +547,7 @@ class TallyMigration(Document):
|
|||||||
try:
|
try:
|
||||||
frappe.db.set_value("Account", encode_company_abbr(self.tally_creditors_account, self.erpnext_company), "account_type", "Payable")
|
frappe.db.set_value("Account", encode_company_abbr(self.tally_creditors_account, self.erpnext_company), "account_type", "Payable")
|
||||||
frappe.db.set_value("Account", encode_company_abbr(self.tally_debtors_account, self.erpnext_company), "account_type", "Receivable")
|
frappe.db.set_value("Account", encode_company_abbr(self.tally_debtors_account, self.erpnext_company), "account_type", "Receivable")
|
||||||
frappe.db.set_value("Company", self.erpnext_company, "round_off_account", self.round_off_account)
|
frappe.db.set_value("Company", self.erpnext_company, "round_off_account", self.default_round_off_account)
|
||||||
|
|
||||||
vouchers_file = frappe.get_doc("File", {"file_url": self.vouchers})
|
vouchers_file = frappe.get_doc("File", {"file_url": self.vouchers})
|
||||||
vouchers = json.loads(vouchers_file.get_content())
|
vouchers = json.loads(vouchers_file.get_content())
|
||||||
@@ -521,11 +578,14 @@ class TallyMigration(Document):
|
|||||||
|
|
||||||
for index, voucher in enumerate(chunk, start=start):
|
for index, voucher in enumerate(chunk, start=start):
|
||||||
try:
|
try:
|
||||||
doc = frappe.get_doc(voucher).insert()
|
voucher_doc = frappe.get_doc(voucher)
|
||||||
doc.submit()
|
voucher_doc.insert()
|
||||||
|
voucher_doc.submit()
|
||||||
self.publish("Importing Vouchers", _("{} of {}").format(index, total), index, total)
|
self.publish("Importing Vouchers", _("{} of {}").format(index, total), index, total)
|
||||||
|
frappe.db.commit()
|
||||||
except:
|
except:
|
||||||
self.log(voucher)
|
frappe.db.rollback()
|
||||||
|
self.log(voucher_doc)
|
||||||
|
|
||||||
if is_last:
|
if is_last:
|
||||||
self.status = ""
|
self.status = ""
|
||||||
@@ -551,6 +611,19 @@ class TallyMigration(Document):
|
|||||||
frappe.enqueue_doc(self.doctype, self.name, "_import_day_book_data", queue="long", timeout=3600)
|
frappe.enqueue_doc(self.doctype, self.name, "_import_day_book_data", queue="long", timeout=3600)
|
||||||
|
|
||||||
def log(self, data=None):
|
def log(self, data=None):
|
||||||
|
if isinstance(data, frappe.model.document.Document):
|
||||||
|
if sys.exc_info()[1].__class__ != frappe.DuplicateEntryError:
|
||||||
|
failed_import_log = json.loads(self.failed_import_log)
|
||||||
|
doc = data.as_dict()
|
||||||
|
failed_import_log.append({
|
||||||
|
"doc": doc,
|
||||||
|
"exc": traceback.format_exc()
|
||||||
|
})
|
||||||
|
self.failed_import_log = json.dumps(failed_import_log, separators=(',', ':'))
|
||||||
|
self.save()
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
else:
|
||||||
data = data or self.status
|
data = data or self.status
|
||||||
message = "\n".join(["Data:", json.dumps(data, default=str, indent=4), "--" * 50, "\nException:", traceback.format_exc()])
|
message = "\n".join(["Data:", json.dumps(data, default=str, indent=4), "--" * 50, "\nException:", traceback.format_exc()])
|
||||||
return frappe.log_error(title="Tally Migration Error", message=message)
|
return frappe.log_error(title="Tally Migration Error", message=message)
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ def get_charts():
|
|||||||
"chart_name": _("Department wise Patient Appointments"),
|
"chart_name": _("Department wise Patient Appointments"),
|
||||||
"chart_type": "Custom",
|
"chart_type": "Custom",
|
||||||
"source": "Department wise Patient Appointments",
|
"source": "Department wise Patient Appointments",
|
||||||
"filters_json": json.dumps({}),
|
"filters_json": json.dumps([]),
|
||||||
'is_public': 1,
|
'is_public': 1,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"type": "Bar",
|
"type": "Bar",
|
||||||
@@ -159,7 +159,7 @@ def get_charts():
|
|||||||
"document_type": "Patient Encounter Symptom",
|
"document_type": "Patient Encounter Symptom",
|
||||||
"group_by_type": "Count",
|
"group_by_type": "Count",
|
||||||
"group_by_based_on": "complaint",
|
"group_by_based_on": "complaint",
|
||||||
"filters_json": json.dumps({}),
|
"filters_json": json.dumps([]),
|
||||||
'is_public': 1,
|
'is_public': 1,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"type": "Percentage",
|
"type": "Percentage",
|
||||||
@@ -173,7 +173,7 @@ def get_charts():
|
|||||||
"document_type": "Patient Encounter Diagnosis",
|
"document_type": "Patient Encounter Diagnosis",
|
||||||
"group_by_type": "Count",
|
"group_by_type": "Count",
|
||||||
"group_by_based_on": "diagnosis",
|
"group_by_based_on": "diagnosis",
|
||||||
"filters_json": json.dumps({}),
|
"filters_json": json.dumps([]),
|
||||||
'is_public': 1,
|
'is_public': 1,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"type": "Percentage",
|
"type": "Percentage",
|
||||||
@@ -229,7 +229,7 @@ def get_number_cards():
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Appointments to Bill",
|
"name": "Appointments to Bill",
|
||||||
"label": _("Appointments to Bill"),
|
"label": _("Appointments To Bill"),
|
||||||
"function": "Count",
|
"function": "Count",
|
||||||
"doctype": "Number Card",
|
"doctype": "Number Card",
|
||||||
"document_type": "Patient Appointment",
|
"document_type": "Patient Appointment",
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Healthcare",
|
"label": "Healthcare",
|
||||||
"modified": "2020-05-19 20:57:22.797267",
|
"modified": "2020-05-28 19:02:28.824995",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Healthcare",
|
"module": "Healthcare",
|
||||||
"name": "Healthcare",
|
"name": "Healthcare",
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
"type": "Page"
|
"type": "Page"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Healthcare Dashboard",
|
"label": "Dashboard",
|
||||||
"link_to": "Healthcare",
|
"link_to": "Healthcare",
|
||||||
"type": "Dashboard"
|
"type": "Dashboard"
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user