Merge pull request #156 from anandpdoshi/master
Email Digest and patch to remove duplicate entries created in Table Mapper Detail
This commit is contained in:
commit
dcac0e7565
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -124,7 +124,7 @@ pscript.make_ac_tree = function() {
|
||||
var imgsrc=null;
|
||||
var has_children = true;
|
||||
if(cl[i].group_or_ledger=='Ledger') {
|
||||
var imgsrc = 'images/icons/page.gif';
|
||||
var imgsrc = 'lib/images/icons/page.gif';
|
||||
has_children = false;
|
||||
}
|
||||
var t = tree.addNode(n, cl[i].account_name, imgsrc,tree.std_onclick, has_children ? tree.std_onexp : null);
|
||||
@ -137,7 +137,7 @@ pscript.make_ac_tree = function() {
|
||||
var imgsrc=null;
|
||||
var has_children = true;
|
||||
if(cl[i].group_or_ledger=='Ledger') {
|
||||
var imgsrc = 'images/icons/page.gif';
|
||||
var imgsrc = 'lib/images/icons/page.gif';
|
||||
has_children = false;
|
||||
}
|
||||
var t = tree.addNode(n, cl[i].cost_center_name, imgsrc,tree.std_onclick, has_children ? tree.std_onexp : null);
|
||||
@ -254,7 +254,7 @@ pscript.make_group_area = function(type) {
|
||||
|
||||
// refresh
|
||||
ref_btn = $a(pscript.group_area, 'div', '', {fontSize: '14px',marginBottom: '8px', marginTop: '24px', fontWeight: 'bold'});
|
||||
ref_btn.innerHTML = '<img src="images/icons/page_refresh.gif" style="margin-right: 8px"><span class="link_type">Refresh Tree</span>';
|
||||
ref_btn.innerHTML = '<img src="lib/images/icons/page_refresh.gif" style="margin-right: 8px"><span class="link_type">Refresh Tree</span>';
|
||||
ref_btn.onclick= function() {
|
||||
pscript.cur_node.clear_child_nodes();
|
||||
pscript.cur_node.expand();
|
||||
@ -312,7 +312,7 @@ pscript.make_ledger_area = function() {
|
||||
|
||||
//General ledger report link
|
||||
pscript.gl_rep = $a(pscript.ledger_area, 'div','', {fontSize: '14px',marginBottom: '8px', fontWeight: 'bold'});
|
||||
pscript.gl_rep.innerHTML = '<img src="images/icons/report.png" style="margin-right: 8px"><span class="link_type">Open Ledger</span>';
|
||||
pscript.gl_rep.innerHTML = '<img src="lib/images/icons/report.png" style="margin-right: 8px"><span class="link_type">Open Ledger</span>';
|
||||
pscript.gl_rep.onclick = function(){ pscript.make_report('gl'); }
|
||||
|
||||
//Budget report link
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -10,8 +10,20 @@ pscript.onload_dashboard = function() {
|
||||
|
||||
pscript.dashboard_settings = {
|
||||
company: sys_defaults.company,
|
||||
start: dateutil.obj_to_str(dateutil.add_days(new Date(), -180)),
|
||||
end: dateutil.obj_to_str(new Date()),
|
||||
start: (function() {
|
||||
var start_date = dateutil.add_days(new Date(), -180);
|
||||
var year_start_date = dateutil.str_to_obj(sys_defaults.year_start_date);
|
||||
if (start_date < year_start_date) { start_date = year_start_date; }
|
||||
console.log(start_date);
|
||||
return dateutil.obj_to_str(start_date);
|
||||
})(),
|
||||
end: (function() {
|
||||
var end_date = new Date();
|
||||
var year_end_date = dateutil.str_to_obj(sys_defaults.year_end_date);
|
||||
if (end_date > year_end_date) { end_date = year_end_date; }
|
||||
console.log(end_date);
|
||||
return dateutil.obj_to_str(end_date);
|
||||
})(),
|
||||
interval: 30
|
||||
}
|
||||
|
||||
|
@ -133,19 +133,27 @@ class DashboardWidget:
|
||||
webnotes.msgprint('Wrongly defined account: ' + acc)
|
||||
print acc
|
||||
raise e
|
||||
|
||||
return self.glc.get_as_on_balance(acc, self.get_fiscal_year(start), start, debit_or_credit, lft, rgt)
|
||||
|
||||
fiscal_year = self.get_fiscal_year(start)
|
||||
if fiscal_year:
|
||||
return self.glc.get_as_on_balance(acc, fiscal_year, start, debit_or_credit, lft, rgt)
|
||||
else:
|
||||
webnotes.msgprint('Please select the START DATE and END DATE such that\
|
||||
they fall within <b>fiscal year(s)</b> as defined in\
|
||||
Setup > System > Fiscal Year.', raise_exception=1)
|
||||
|
||||
|
||||
def get_fiscal_year(self, dt):
|
||||
"""
|
||||
get fiscal year from date
|
||||
"""
|
||||
import webnotes
|
||||
return webnotes.conn.sql("""
|
||||
fiscal_year = webnotes.conn.sql("""
|
||||
select name from `tabFiscal Year`
|
||||
where year_start_date <= %s and
|
||||
DATE_ADD(year_start_date, INTERVAL 1 YEAR) >= %s
|
||||
""", (dt, dt))[0][0]
|
||||
""", (dt, dt))
|
||||
return fiscal_year and (fiscal_year[0] and fiscal_year[0][0]) or None
|
||||
|
||||
def get_creation_trend(self, doctype, start, end):
|
||||
"""
|
||||
@ -257,4 +265,4 @@ if __name__=='__main__':
|
||||
"start": "2011-05-01",
|
||||
"end": "2011-08-01",
|
||||
"interval": "7"
|
||||
}""")
|
||||
}""")
|
||||
|
75
erpnext/patches/deploy_email_digest.py
Normal file
75
erpnext/patches/deploy_email_digest.py
Normal file
@ -0,0 +1,75 @@
|
||||
import webnotes
|
||||
|
||||
def execute():
|
||||
"""
|
||||
* Reload email_digest doctype
|
||||
* Create default email digest
|
||||
"""
|
||||
from webnotes.modules.module_manager import reload_doc
|
||||
|
||||
# Minor fix in print_format doctype
|
||||
#reload_doc('core', 'doctype', 'print_format')
|
||||
|
||||
reload_doc('setup', 'doctype', 'email_digest')
|
||||
|
||||
global create_default_email_digest
|
||||
create_default_email_digest()
|
||||
|
||||
|
||||
def create_default_email_digest():
|
||||
"""
|
||||
* Weekly Digest
|
||||
* For all companies
|
||||
* Recipients: System Managers
|
||||
* Full content
|
||||
* Disabled by default
|
||||
"""
|
||||
from webnotes.model.doc import Document
|
||||
companies_list = webnotes.conn.sql("SELECT company_name FROM `tabCompany`", as_list=1)
|
||||
global get_system_managers
|
||||
system_managers = get_system_managers()
|
||||
for company in companies_list:
|
||||
if company and company[0]:
|
||||
edigest = Document('Email Digest')
|
||||
edigest.name = "Default Weekly Digest - " + company[0]
|
||||
edigest.company = company[0]
|
||||
edigest.frequency = 'Weekly'
|
||||
edigest.recipient_list = system_managers
|
||||
edigest.new_leads = 1
|
||||
edigest.new_enquiries = 1
|
||||
edigest.new_quotations = 1
|
||||
edigest.new_sales_orders = 1
|
||||
edigest.new_purchase_orders = 1
|
||||
edigest.new_transactions = 1
|
||||
edigest.payables = 1
|
||||
edigest.payments = 1
|
||||
edigest.expenses_booked = 1
|
||||
edigest.invoiced_amount = 1
|
||||
edigest.collections = 1
|
||||
edigest.income = 1
|
||||
edigest.bank_balance = 1
|
||||
exists = webnotes.conn.sql("""\
|
||||
SELECT name FROM `tabEmail Digest`
|
||||
WHERE name = %s""", edigest.name)
|
||||
if (exists and exists[0]) and exists[0][0]:
|
||||
continue
|
||||
else:
|
||||
edigest.save(1)
|
||||
|
||||
|
||||
def get_system_managers():
|
||||
"""
|
||||
Returns a string of system managers' email addresses separated by \n
|
||||
"""
|
||||
system_managers_list = webnotes.conn.sql("""\
|
||||
SELECT DISTINCT p.name
|
||||
FROM tabUserRole ur, tabProfile p
|
||||
WHERE
|
||||
ur.parent = p.name AND
|
||||
ur.role='System Manager' AND
|
||||
p.docstatus<2 AND
|
||||
p.enabled=1 AND
|
||||
p.name not in ('Administrator', 'Guest')""", as_list=1)
|
||||
|
||||
return "\n".join([sysman[0] for sysman in system_managers_list])
|
||||
|
@ -53,7 +53,7 @@ def execute():
|
||||
Install print formats
|
||||
"""
|
||||
from webnotes.modules.module_manager import reload_doc
|
||||
#reload_doc('core', 'doctype', 'print_format')
|
||||
reload_doc('core', 'doctype', 'print_format')
|
||||
|
||||
#copy_doctype_to_pfs()
|
||||
global pf_to_install
|
||||
|
@ -112,16 +112,25 @@
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.serial_no) {
|
||||
return (
|
||||
data_row.description +
|
||||
'<div style="padding-left: 15px;"><i>Serial No.:' +
|
||||
((data_row.serial_no.indexOf('\n')>-1)?'<br />':' ') +
|
||||
data_row.serial_no + '</i></div>'
|
||||
);
|
||||
} else {
|
||||
return data_row.description;
|
||||
var to_append = ''
|
||||
if(data_row.adj_rate){
|
||||
to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
data_row.description = data_row.description + to_append;
|
||||
}
|
||||
}
|
||||
|
||||
if(data_row.serial_no) {
|
||||
to_append = '<div style="padding-left: 15px;"><i>Serial No.:' +
|
||||
((data_row.serial_no.indexOf('\n')>-1)?'<br />':' ') +
|
||||
data_row.serial_no + '</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
data_row.description = data_row.description + to_append;
|
||||
}
|
||||
}
|
||||
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -176,7 +185,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td><h1>Delivery Note</h1></td></tr>
|
||||
<tr><td><script>'<h1>' + (doc.select_print_heading || 'Delivery Note') + '</h1>'</script></td></tr>
|
||||
<tr><td><h3><script>cur_frm.docname</script></h3></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -135,16 +135,25 @@
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.serial_no) {
|
||||
return (
|
||||
data_row.description +
|
||||
'<div style="padding-left: 15px;"><i>Serial No.:' +
|
||||
((data_row.serial_no.indexOf('\n')>-1)?'<br />':' ') +
|
||||
data_row.serial_no + '</i></div>'
|
||||
);
|
||||
} else {
|
||||
return data_row.description;
|
||||
var to_append = ''
|
||||
if(data_row.adj_rate){
|
||||
to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
data_row.description = data_row.description + to_append;
|
||||
}
|
||||
}
|
||||
|
||||
if(data_row.serial_no) {
|
||||
to_append = '<div style="padding-left: 15px;"><i>Serial No.:' +
|
||||
((data_row.serial_no.indexOf('\n')>-1)?'<br />':' ') +
|
||||
data_row.serial_no + '</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
data_row.description = data_row.description + to_append;
|
||||
}
|
||||
}
|
||||
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -199,7 +208,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td colspan=2><div><h1>Delivery Note</h1></div></td></tr>
|
||||
<tr><td colspan=2><div><script>'<h1>' + (doc.select_print_heading || 'Delivery Note') + '</h1>'</script></div></td></tr>
|
||||
<tr><td colspan=2><div style="height:15px"></div></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -303,4 +312,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
@ -134,16 +134,25 @@
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.serial_no) {
|
||||
return (
|
||||
data_row.description +
|
||||
'<div style="padding-left: 15px;"><i>Serial No.:' +
|
||||
((data_row.serial_no.indexOf('\n')>-1)?'<br />':' ') +
|
||||
data_row.serial_no + '</i></div>'
|
||||
);
|
||||
} else {
|
||||
return data_row.description;
|
||||
var to_append = ''
|
||||
if(data_row.adj_rate){
|
||||
to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
data_row.description = data_row.description + to_append;
|
||||
}
|
||||
}
|
||||
|
||||
if(data_row.serial_no) {
|
||||
to_append = '<div style="padding-left: 15px;"><i>Serial No.:' +
|
||||
((data_row.serial_no.indexOf('\n')>-1)?'<br />':' ') +
|
||||
data_row.serial_no + '</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
data_row.description = data_row.description + to_append;
|
||||
}
|
||||
}
|
||||
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -198,7 +207,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td colspan=2><h1>Delivery Note</h1></td></tr>
|
||||
<tr><td colspan=2><script>'<h1>' + (doc.select_print_heading || 'Delivery Note') + '</h1>'</script></td></tr>
|
||||
<tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -298,5 +307,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -160,7 +160,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td><h1>Purchase Order</h1></td></tr>
|
||||
<tr><td><script>'<h1>' + (doc.select_print_heading || 'Purchase Order') + '</h1>'</script></td></tr>
|
||||
<tr><td><h3><script>cur_frm.docname</script></h3></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -246,4 +246,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
@ -183,7 +183,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td colspan=2><div><h1>Purchase Order</h1></div></td></tr>
|
||||
<tr><td colspan=2><div><script>'<h1>' + (doc.select_print_heading || 'Purchase Order') + '</h1>'</script></div></td></tr>
|
||||
<tr><td colspan=2><div style="height:15px"></div></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -273,4 +273,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
@ -182,7 +182,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td colspan=2><h1>Purchase Order</h1></td></tr>
|
||||
<tr><td colspan=2><script>'<h1>' + (doc.select_print_heading || 'Purchase Order') + '</h1>'</script></td></tr>
|
||||
<tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -268,5 +268,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -107,7 +107,22 @@
|
||||
[// Here specify the column widths
|
||||
'3%', '10%', '15%', '32%', '5%',
|
||||
'5%', '15%', '15%'
|
||||
]
|
||||
],
|
||||
null,
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.adj_rate) {
|
||||
var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
return data_row.description + to_append;
|
||||
} else { return data_row.description; }
|
||||
} else {
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// This code takes care of page breaks
|
||||
@ -160,7 +175,9 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td><h1>Quotation</h1></td></tr>
|
||||
<tr><td>
|
||||
<script>'<h1>' + (doc.select_print_heading || 'Quotation') + '</h1>'</script>
|
||||
</td></tr>
|
||||
<tr><td><h3><script>cur_frm.docname</script></h3></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -253,4 +270,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
@ -130,7 +130,22 @@
|
||||
[// Here specify the column widths
|
||||
'3%', '10%', '15%', '32%', '5%',
|
||||
'5%', '15%', '15%'
|
||||
]
|
||||
],
|
||||
null,
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.adj_rate) {
|
||||
var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
return data_row.description + to_append;
|
||||
} else { return data_row.description; }
|
||||
} else {
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// This code takes care of page breaks
|
||||
@ -183,7 +198,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td colspan=2><div><h1>Quotation</h1></div></td></tr>
|
||||
<tr><td colspan=2><div><script>'<h1>' + (doc.select_print_heading || 'Quotation') + '</h1>'</script></div></td></tr>
|
||||
<tr><td colspan=2><div style="height:15px"></div></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -280,4 +295,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
@ -129,7 +129,22 @@
|
||||
[// Here specify the column widths
|
||||
'3%', '10%', '15%', '32%', '5%',
|
||||
'5%', '15%', '15%'
|
||||
]
|
||||
],
|
||||
null,
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.adj_rate) {
|
||||
var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
return data_row.description + to_append;
|
||||
} else { return data_row.description; }
|
||||
} else {
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// This code takes care of page breaks
|
||||
@ -182,7 +197,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td colspan=2><h1>Quotation</h1></td></tr>
|
||||
<tr><td colspan=2><script>'<h1>' + (doc.select_print_heading || 'Quotation') + '</h1>'</script></td></tr>
|
||||
<tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -275,5 +290,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -107,7 +107,22 @@
|
||||
[// Here specify the column widths
|
||||
'3%', '20%', '37%', '5%',
|
||||
'5%', '15%', '15%'
|
||||
]
|
||||
],
|
||||
null,
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.adj_rate) {
|
||||
var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
return data_row.description + to_append;
|
||||
} else { return data_row.description; }
|
||||
} else {
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// This code takes care of page breaks
|
||||
@ -128,7 +143,6 @@
|
||||
|
||||
|
||||
print_other_charges: function(parent) {
|
||||
console.log(parent);
|
||||
var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
|
||||
var rows = '<table width=100%>\n';
|
||||
for(var i=0; i<oc.length; i++) {
|
||||
@ -161,7 +175,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td><h1>Invoice</h1></td></tr>
|
||||
<tr><td><script>'<h1>' + (doc.select_print_heading || 'Invoice') + '</h1>'</script></td></tr>
|
||||
<tr><td><h3><script>cur_frm.docname</script></h3></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -258,4 +272,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
@ -130,7 +130,22 @@
|
||||
[// Here specify the column widths
|
||||
'3%', '20%', '37%', '5%',
|
||||
'5%', '15%', '15%'
|
||||
]
|
||||
],
|
||||
null,
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.adj_rate) {
|
||||
var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
return data_row.description + to_append;
|
||||
} else { return data_row.description; }
|
||||
} else {
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// This code takes care of page breaks
|
||||
@ -151,7 +166,6 @@
|
||||
|
||||
|
||||
print_other_charges: function(parent) {
|
||||
console.log(parent);
|
||||
var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
|
||||
var rows = '<table width=100%>\n';
|
||||
for(var i=0; i<oc.length; i++) {
|
||||
@ -184,7 +198,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td colspan=2><div><h1>Invoice</h1></div></td></tr>
|
||||
<tr><td colspan=2><div><script>'<h1>' + (doc.select_print_heading || 'Invoice') + '</h1>'</script></div></td></tr>
|
||||
<tr><td colspan=2><div style="height:15px"></div></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -285,4 +299,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
@ -129,7 +129,22 @@
|
||||
[// Here specify the column widths
|
||||
'3%', '20%', '37%', '5%',
|
||||
'5%', '15%', '15%'
|
||||
]
|
||||
],
|
||||
null,
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.adj_rate) {
|
||||
var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
return data_row.description + to_append;
|
||||
} else { return data_row.description; }
|
||||
} else {
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// This code takes care of page breaks
|
||||
@ -150,7 +165,6 @@
|
||||
|
||||
|
||||
print_other_charges: function(parent) {
|
||||
console.log(parent);
|
||||
var oc = getchildren('RV Tax Detail', doc.name, 'other_charges');
|
||||
var rows = '<table width=100%>\n';
|
||||
for(var i=0; i<oc.length; i++) {
|
||||
@ -183,7 +197,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td colspan=2><h1>Invoice</h1></td></tr>
|
||||
<tr><td colspan=2><script>'<h1>' + (doc.select_print_heading || 'Invoice') + '</h1>'</script></td></tr>
|
||||
<tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -280,5 +294,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -107,7 +107,22 @@
|
||||
[// Here specify the column widths
|
||||
'3%', '20%', '37%', '5%',
|
||||
'5%', '15%', '15%'
|
||||
]
|
||||
],
|
||||
null,
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.adj_rate) {
|
||||
var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
return data_row.description + to_append;
|
||||
} else { return data_row.description; }
|
||||
} else {
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// This code takes care of page breaks
|
||||
@ -160,7 +175,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td><h1>Sales Order</h1></td></tr>
|
||||
<tr><td><script>'<h1>' + (doc.select_print_heading || 'Sales Order') + '</h1>'</script></td></tr>
|
||||
<tr><td><h3><script>cur_frm.docname</script></h3></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -257,4 +272,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
@ -130,7 +130,22 @@
|
||||
[// Here specify the column widths
|
||||
'3%', '20%', '37%', '5%',
|
||||
'5%', '15%', '15%'
|
||||
]
|
||||
],
|
||||
null,
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.adj_rate) {
|
||||
var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
return data_row.description + to_append;
|
||||
} else { return data_row.description; }
|
||||
} else {
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// This code takes care of page breaks
|
||||
@ -183,7 +198,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td colspan=2><div><h1>Sales Order</h1></div></td></tr>
|
||||
<tr><td colspan=2><div><script>'<h1>' + (doc.select_print_heading || 'Sales Order') + '</h1>'</script></div></td></tr>
|
||||
<tr><td colspan=2><div style="height:15px"></div></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -284,4 +299,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
@ -129,7 +129,22 @@
|
||||
[// Here specify the column widths
|
||||
'3%', '20%', '37%', '5%',
|
||||
'5%', '15%', '15%'
|
||||
]
|
||||
],
|
||||
null,
|
||||
null,
|
||||
{
|
||||
'description' : function(data_row) {
|
||||
if(data_row.adj_rate) {
|
||||
var to_append = '<div style="padding-left: 15px;"><i>Discount: ' +
|
||||
data_row.adj_rate + '%</i></div>';
|
||||
if(data_row.description.indexOf(to_append)==-1) {
|
||||
return data_row.description + to_append;
|
||||
} else { return data_row.description; }
|
||||
} else {
|
||||
return data_row.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// This code takes care of page breaks
|
||||
@ -182,7 +197,7 @@
|
||||
-->
|
||||
<table class='header-table' cellspacing=0>
|
||||
<thead>
|
||||
<tr><td colspan=2><h1>Sales Order</h1></td></tr>
|
||||
<tr><td colspan=2><script>'<h1>' + (doc.select_print_heading || 'Sales Order') + '</h1>'</script></td></tr>
|
||||
<tr><td colspan=2><h3><script>cur_frm.docname</script></h3></td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -279,5 +294,3 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
7
erpnext/patches/reload_project_task.py
Normal file
7
erpnext/patches/reload_project_task.py
Normal file
@ -0,0 +1,7 @@
|
||||
"""
|
||||
Reload Task Doctype of Project Module
|
||||
"""
|
||||
def execute():
|
||||
from webnotes.modules.module_manager import reload_doc
|
||||
reload_doc('Projects', 'DocType', 'Ticket')
|
||||
|
22
erpnext/patches/remove_duplicate_table_mapper_detail.py
Normal file
22
erpnext/patches/remove_duplicate_table_mapper_detail.py
Normal file
@ -0,0 +1,22 @@
|
||||
"""
|
||||
Removes duplicate entries created in
|
||||
"""
|
||||
import webnotes
|
||||
def execute():
|
||||
res = webnotes.conn.sql("""\
|
||||
SELECT a.name
|
||||
FROM
|
||||
`tabTable Mapper Detail` a,
|
||||
`tabTable Mapper Detail` b
|
||||
WHERE
|
||||
a.parent = b.parent AND
|
||||
a.from_table = b.from_table AND
|
||||
a.to_table = b.to_table AND
|
||||
a.from_field = b.from_field AND
|
||||
a.to_field = b.to_field AND
|
||||
a.name < b.name""")
|
||||
if res and len(res)>0:
|
||||
name_string = ", ".join(["'" + str(r[0]) + "'" for r in res])
|
||||
res = webnotes.conn.sql("""\
|
||||
DELETE FROM `tabTable Mapper Detail`
|
||||
WHERE name IN (%s)""" % name_string)
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -139,7 +139,7 @@ SalesBrowser.prototype.make_tree = function() {
|
||||
var has_children = true;
|
||||
|
||||
if(cl[i].is_group=='No') {
|
||||
var imgsrc = 'images/icons/page.gif';
|
||||
var imgsrc = 'lib/images/icons/page.gif';
|
||||
has_children = false;
|
||||
}
|
||||
var t = me.tree.addNode(n, cl[i].name, imgsrc,me.tree.std_onclick, has_children ? me.tree.std_onexp : null);
|
||||
@ -219,7 +219,7 @@ SalesBrowser.prototype.first_level_node = function(){
|
||||
var has_children = true;
|
||||
|
||||
if(cl[i].is_group=='No') {
|
||||
var imgsrc = 'images/icons/page.gif';
|
||||
var imgsrc = 'lib/images/icons/page.gif';
|
||||
has_children = false;
|
||||
}
|
||||
me.tree_area.innerHTML = '';
|
||||
@ -418,4 +418,4 @@ MakeDialog.prototype.make_args = function(){
|
||||
else if(this.cls_obj.sel == 'Sales Person')
|
||||
return {'node_title':nt,'sales_person_name':nm,'parent_sales_person':pnm,'is_group':grp,'old_parent':old_prt}
|
||||
|
||||
}
|
||||
}
|
||||
|
10
erpnext/setup/doctype/email_digest/email_digest.css
Normal file
10
erpnext/setup/doctype/email_digest/email_digest.css
Normal file
@ -0,0 +1,10 @@
|
||||
table.profile-list {
|
||||
text-align: left;
|
||||
margin: auto;
|
||||
line-height: 250%;
|
||||
}
|
||||
|
||||
div.dialog-div {
|
||||
text-align: 'center';
|
||||
width: 100%;
|
||||
}
|
90
erpnext/setup/doctype/email_digest/email_digest.js
Normal file
90
erpnext/setup/doctype/email_digest/email_digest.js
Normal file
@ -0,0 +1,90 @@
|
||||
cur_frm.cscript.refresh = function(doc, dt, dn) {
|
||||
cur_frm.add_custom_button('View Now', function() {
|
||||
$c_obj(make_doclist(dt, dn), 'get', '', function(r, rt) {
|
||||
if(r.exc) {
|
||||
msgprint(r.exc);
|
||||
} else {
|
||||
//console.log(arguments);
|
||||
var d = new wn.widgets.Dialog({
|
||||
title: 'Email Digest: ' + dn,
|
||||
width: 800
|
||||
});
|
||||
|
||||
$a(d.body, 'div', '', '', r['message'][1]);
|
||||
|
||||
d.show();
|
||||
}
|
||||
});
|
||||
}, 1);
|
||||
cur_frm.add_custom_button('Send Now', function() {
|
||||
$c_obj(make_doclist(dt, dn), 'send', '', function(r, rt) {
|
||||
if(r.exc) {
|
||||
msgprint(r.exc);
|
||||
} else {
|
||||
//console.log(arguments);
|
||||
msgprint('Message Sent');
|
||||
}
|
||||
});
|
||||
}, 1);
|
||||
}
|
||||
|
||||
cur_frm.cscript['Add Recipients'] = function(doc, dt, dn) {
|
||||
// Get profile list
|
||||
$c_obj(make_doclist(dt, dn), 'get_profiles', '', function(r, rt) {
|
||||
if(r.exc) {
|
||||
msgprint(r.exc);
|
||||
} else {
|
||||
// Open a dialog and display checkboxes against email addresses
|
||||
doc = locals[dt][dn];
|
||||
var d = new wn.widgets.Dialog({
|
||||
title: 'Add Recipients',
|
||||
width: 400
|
||||
});
|
||||
var dialog_div = $a(d.body, 'div', 'dialog-div', '', '');
|
||||
var tab = make_table(dialog_div, r.profile_list.length+2, 2, '', ['15%', '85%']);
|
||||
tab.className = 'profile-list';
|
||||
var add_or_update = 'Add';
|
||||
$.each(r.profile_list, function(i, v) {
|
||||
var check = $a_input($td(tab, i+1, 0), 'checkbox');
|
||||
check.value = v.name;
|
||||
if(v.checked==1) {
|
||||
check.checked = 1;
|
||||
add_or_update = 'Update';
|
||||
}
|
||||
if(v.enabled==0) {
|
||||
v.name = "<span style='color: red'>" + v.name + " (disabled user)</span>"
|
||||
}
|
||||
var profile = $a($td(tab, i+1, 1), 'span', '', '', v.name);
|
||||
//profile.onclick = function() { check.checked = !check.checked; }
|
||||
});
|
||||
|
||||
// Display add recipients button
|
||||
if(r.profile_list.length>15) {
|
||||
$btn($td(tab, 0, 1), add_or_update + ' Recipients', function() {
|
||||
cur_frm.cscript.add_to_rec_list(doc, tab, r.profile_list.length);
|
||||
});
|
||||
}
|
||||
$btn($td(tab, r.profile_list.length+1, 1), add_or_update + ' Recipients', function() {
|
||||
cur_frm.cscript.add_to_rec_list(doc, tab, r.profile_list.length);
|
||||
});
|
||||
|
||||
cur_frm.rec_dialog = d;
|
||||
d.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
cur_frm.cscript.add_to_rec_list = function(doc, tab, length) {
|
||||
// add checked profiles to list of recipients
|
||||
var rec_list = [];
|
||||
for(var i = 1; i <= length; i++) {
|
||||
var input = $($td(tab, i, 0)).find('input');
|
||||
if(input.is(':checked')) {
|
||||
rec_list.push(input.attr('value'));
|
||||
}
|
||||
}
|
||||
doc.recipient_list = rec_list.join('\n');
|
||||
//console.log(doc.recipient_list);
|
||||
cur_frm.rec_dialog.hide();
|
||||
cur_frm.refresh_fields();
|
||||
}
|
734
erpnext/setup/doctype/email_digest/email_digest.py
Normal file
734
erpnext/setup/doctype/email_digest/email_digest.py
Normal file
@ -0,0 +1,734 @@
|
||||
import webnotes
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc, self.doclist = doc, doclist
|
||||
self.sending = False
|
||||
|
||||
|
||||
def get_profiles(self):
|
||||
"""
|
||||
Get a list of profiles
|
||||
"""
|
||||
import webnotes
|
||||
profile_list = webnotes.conn.sql("""
|
||||
SELECT name, enabled FROM tabProfile
|
||||
WHERE docstatus=0 AND name NOT IN ('Administrator', 'Guest')
|
||||
ORDER BY enabled DESC, name ASC""", as_dict=1)
|
||||
if self.doc.recipient_list:
|
||||
recipient_list = self.doc.recipient_list.split("\n")
|
||||
else:
|
||||
recipient_list = []
|
||||
for p in profile_list:
|
||||
if p['name'] in recipient_list: p['checked'] = 1
|
||||
else: p['checked'] = 0
|
||||
webnotes.response['profile_list'] = profile_list
|
||||
|
||||
|
||||
def get_standard_data(self):
|
||||
"""
|
||||
Executes standard queries
|
||||
"""
|
||||
res = {}
|
||||
query_dict = {
|
||||
|
||||
'invoiced_amount': self.generate_gle_query({
|
||||
'type': 'invoiced_amount',
|
||||
'field': 'debit',
|
||||
'master_type': 'Customer',
|
||||
}),
|
||||
|
||||
'payables': self.generate_gle_query({
|
||||
'type': 'payables',
|
||||
'field': 'credit',
|
||||
'master_type': 'Supplier',
|
||||
}),
|
||||
|
||||
'collections': self.generate_gle_query({
|
||||
'type': 'collections',
|
||||
'field': 'credit',
|
||||
'master_type': 'Customer',
|
||||
}),
|
||||
|
||||
'payments': self.generate_gle_query({
|
||||
'type': 'payments',
|
||||
'field': 'debit',
|
||||
'master_type': 'Supplier',
|
||||
}),
|
||||
|
||||
'income': self.generate_gle_query({
|
||||
'type': 'income',
|
||||
'debit_or_credit': 'Credit'
|
||||
}),
|
||||
|
||||
'expenses_booked': self.generate_gle_query({
|
||||
'type': 'expenses_booked',
|
||||
'debit_or_credit': 'Debit'
|
||||
}),
|
||||
|
||||
'bank_balance': self.generate_gle_query({
|
||||
'type': 'bank_balance'
|
||||
}),
|
||||
|
||||
'new_leads': self.generate_new_type_query({
|
||||
'type': 'new_leads',
|
||||
'doctype': 'Lead'
|
||||
}),
|
||||
|
||||
'new_enquiries': self.generate_new_type_query({
|
||||
'type': 'new_enquiries',
|
||||
'doctype': 'Enquiry'
|
||||
}),
|
||||
|
||||
'new_quotations': self.generate_new_type_query({
|
||||
'type': 'new_quotations',
|
||||
'doctype': 'Quotation',
|
||||
'sum_col': 'grand_total'
|
||||
}),
|
||||
|
||||
'new_sales_orders': self.generate_new_type_query({
|
||||
'type': 'new_sales_orders',
|
||||
'doctype': 'Receivable Voucher',
|
||||
'sum_col': 'grand_total'
|
||||
}),
|
||||
|
||||
'new_purchase_orders': self.generate_new_type_query({
|
||||
'type': 'new_purchase_orders',
|
||||
'doctype': 'Purchase Order',
|
||||
'sum_col': 'grand_total'
|
||||
}),
|
||||
|
||||
'new_transactions': self.generate_new_type_query({
|
||||
'type': 'new_transactions',
|
||||
'doctype': 'Feed'
|
||||
}),
|
||||
|
||||
'stock_below_rl': ""
|
||||
}
|
||||
|
||||
result = {}
|
||||
|
||||
for query in query_dict.keys():
|
||||
if self.doc.fields[query]:
|
||||
#webnotes.msgprint(query)
|
||||
res = webnotes.conn.sql(query_dict[query], as_dict=1)
|
||||
if query == 'income':
|
||||
for r in res:
|
||||
r['value'] = float(r['credit'] - r['debit'])
|
||||
elif query in ['expenses_booked', 'bank_balance']:
|
||||
for r in res:
|
||||
r['value'] = float(r['debit'] - r['credit'])
|
||||
#webnotes.msgprint(query)
|
||||
#webnotes.msgprint(res)
|
||||
result[query] = (res and len(res)==1) and res[0] or (res and res or None)
|
||||
|
||||
#webnotes.msgprint(result)
|
||||
return result
|
||||
|
||||
|
||||
def generate_gle_query(self, args):
|
||||
"""
|
||||
Returns generated query string based 'tabGL Entry' and 'tabAccount'
|
||||
"""
|
||||
self.process_args(args)
|
||||
|
||||
query = None
|
||||
|
||||
if args['type'] in ['invoiced_amount', 'payables']:
|
||||
query = """
|
||||
SELECT
|
||||
IFNULL(SUM(IFNULL(gle.%(field)s, 0)), 0) AS '%(field)s',
|
||||
%(common_select)s
|
||||
FROM
|
||||
%(common_from)s
|
||||
WHERE
|
||||
%(common_where)s AND
|
||||
ac.master_type = '%(master_type)s' AND
|
||||
%(start_date_condition)s AND
|
||||
%(end_date_condition)s""" % args
|
||||
|
||||
elif args['type'] in ['collections', 'payments']:
|
||||
args['bc_accounts_regex'] = self.get_bc_accounts_regex()
|
||||
query = """
|
||||
SELECT
|
||||
IFNULL(SUM(IFNULL(gle.%(field)s, 0)), 0) AS '%(field)s',
|
||||
%(common_select)s
|
||||
FROM
|
||||
%(common_from)s
|
||||
WHERE
|
||||
%(common_where)s AND
|
||||
ac.master_type = '%(master_type)s' AND
|
||||
gle.against REGEXP '%(bc_accounts_regex)s' AND
|
||||
%(start_date_condition)s AND
|
||||
%(end_date_condition)s""" % args
|
||||
|
||||
elif args['type'] in ['income', 'expenses_booked']:
|
||||
query = """
|
||||
SELECT
|
||||
IFNULL(SUM(IFNULL(gle.debit, 0)), 0) AS 'debit',
|
||||
IFNULL(SUM(IFNULL(gle.credit, 0)), 0) AS 'credit',
|
||||
%(common_select)s
|
||||
FROM
|
||||
%(common_from)s
|
||||
WHERE
|
||||
%(common_where)s AND
|
||||
ac.is_pl_account = 'Yes' AND
|
||||
ac.debit_or_credit = '%(debit_or_credit)s' AND
|
||||
%(start_date_condition)s AND
|
||||
%(end_date_condition)s""" % args
|
||||
|
||||
elif args['type'] == 'bank_balance':
|
||||
query = """
|
||||
SELECT
|
||||
ac.account_name AS 'name',
|
||||
IFNULL(SUM(IFNULL(gle.debit, 0)), 0) AS 'debit',
|
||||
IFNULL(SUM(IFNULL(gle.credit, 0)), 0) AS 'credit',
|
||||
%(common_select)s
|
||||
FROM
|
||||
%(common_from)s
|
||||
WHERE
|
||||
%(common_where)s AND
|
||||
ac.account_type = 'Bank or Cash' AND
|
||||
%(end_date_condition)s
|
||||
GROUP BY
|
||||
ac.account_name""" % args
|
||||
|
||||
return query
|
||||
|
||||
|
||||
def process_args(self, args):
|
||||
"""
|
||||
Adds common conditions in dictionary "args"
|
||||
"""
|
||||
start_date, end_date = self.get_start_end_dates()
|
||||
|
||||
if 'new' in args['type']:
|
||||
args.update({
|
||||
'company': self.doc.company,
|
||||
'start_date': start_date,
|
||||
'end_date': end_date,
|
||||
'sum_if_reqd': ''
|
||||
})
|
||||
if args['type'] in ['new_quotations', 'new_sales_orders', 'new_purchase_orders']:
|
||||
args['sum_if_reqd'] = "IFNULL(SUM(IFNULL(%(sum_col)s, 0)), 0) AS '%(sum_col)s'," % args
|
||||
|
||||
if args['type'] == 'new_transactions':
|
||||
args['company_condition'] = ''
|
||||
else:
|
||||
args['company_condition'] = "company = '%(company)s' AND" % args
|
||||
|
||||
else:
|
||||
args.update({
|
||||
'common_select': "COUNT(*) AS 'count'",
|
||||
|
||||
'common_from': "`tabGL Entry` gle, `tabAccount` ac",
|
||||
|
||||
'common_where': """
|
||||
gle.company = '%s' AND
|
||||
gle.account = ac.name AND
|
||||
ac.docstatus < 2 AND
|
||||
IFNULL(gle.is_cancelled, 'No') = 'No'""" % self.doc.company,
|
||||
|
||||
'start_date_condition': "gle.posting_date >= '%s'" % start_date,
|
||||
|
||||
'end_date_condition': "gle.posting_date <= '%s'" % end_date
|
||||
})
|
||||
|
||||
|
||||
def get_start_end_dates(self):
|
||||
"""
|
||||
Returns start and end date depending on the frequency of email digest
|
||||
"""
|
||||
from datetime import datetime, date, timedelta
|
||||
today = datetime.now().date()
|
||||
year, month, day = today.year, today.month, today.day
|
||||
|
||||
if self.doc.frequency == 'Daily':
|
||||
if self.sending:
|
||||
start_date = end_date = today - timedelta(days=1)
|
||||
else:
|
||||
start_date = end_date = today
|
||||
|
||||
elif self.doc.frequency == 'Weekly':
|
||||
if self.sending:
|
||||
start_date = today - timedelta(days=today.weekday(), weeks=1)
|
||||
end_date = start_date + timedelta(days=6)
|
||||
else:
|
||||
start_date = today - timedelta(days=today.weekday())
|
||||
end_date = start_date + timedelta(days=6)
|
||||
|
||||
else:
|
||||
import calendar
|
||||
|
||||
if self.sending:
|
||||
if month == 1:
|
||||
year = year - 1
|
||||
prev_month = 12
|
||||
else:
|
||||
prev_month = month - 1
|
||||
start_date = date(year, prev_month, 1)
|
||||
last_day = calendar.monthrange(year, prev_month)[1]
|
||||
end_date = date(year, prev_month, last_day)
|
||||
else:
|
||||
start_date = date(year, month, 1)
|
||||
last_day = calendar.monthrange(year, month)[1]
|
||||
end_date = date(year, month, last_day)
|
||||
|
||||
return start_date, end_date
|
||||
|
||||
|
||||
def generate_new_type_query(self, args):
|
||||
"""
|
||||
Returns generated query string for calculating new transactions created
|
||||
"""
|
||||
self.process_args(args)
|
||||
|
||||
query = """
|
||||
SELECT
|
||||
%(sum_if_reqd)s
|
||||
COUNT(*) AS 'count'
|
||||
FROM
|
||||
`tab%(doctype)s`
|
||||
WHERE
|
||||
docstatus < 2 AND
|
||||
%(company_condition)s
|
||||
creation >= '%(start_date)s' AND
|
||||
creation <= '%(end_date)s'""" % args
|
||||
|
||||
return query
|
||||
|
||||
|
||||
def get_bc_accounts_regex(self):
|
||||
"""
|
||||
Returns a regular expression of 'Bank or Cash' type account list
|
||||
"""
|
||||
bc_account_list = webnotes.conn.sql("""
|
||||
SELECT name
|
||||
FROM `tabAccount`
|
||||
WHERE account_type = 'Bank or Cash'""", as_list=1)
|
||||
|
||||
return '(' + '|'.join([ac[0] for ac in bc_account_list]) + ')'
|
||||
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
* Execute Query
|
||||
* Prepare Email Body from Print Format
|
||||
"""
|
||||
result, email_body = self.execute_queries()
|
||||
#webnotes.msgprint(result)
|
||||
#webnotes.msgprint(email_body)
|
||||
return result, email_body
|
||||
|
||||
|
||||
def execute_queries(self):
|
||||
"""
|
||||
* If standard==1, execute get_standard_data
|
||||
* If standard==0, execute python code in custom_code field
|
||||
"""
|
||||
result = {}
|
||||
if int(self.doc.use_standard)==1:
|
||||
result = self.get_standard_data()
|
||||
email_body = self.get_standard_body(result)
|
||||
else:
|
||||
result, email_body = self.execute_custom_code(self.doc)
|
||||
|
||||
#webnotes.msgprint(result)
|
||||
|
||||
return result, email_body
|
||||
|
||||
|
||||
def execute_custom_code(self, doc):
|
||||
"""
|
||||
Execute custom python code
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def send(self):
|
||||
"""
|
||||
* Execute get method
|
||||
* Send email to recipients
|
||||
"""
|
||||
self.sending = True
|
||||
result, email_body = self.get()
|
||||
recipient_list = self.doc.recipient_list.split("\n")
|
||||
|
||||
# before sending, check if user is disabled or not
|
||||
# do not send if disabled
|
||||
profile_list = webnotes.conn.sql("SELECT name, enabled FROM tabProfile", as_dict=1)
|
||||
for profile in profile_list:
|
||||
if profile['name'] in recipient_list and profile['enabled'] == 0:
|
||||
del recipient_list[recipient_list.index(profile['name'])]
|
||||
|
||||
from webnotes.utils.email_lib import sendmail
|
||||
try:
|
||||
sendmail(
|
||||
recipients=recipient_list,
|
||||
sender='notifications+email_digest@erpnext.com',
|
||||
reply_to='support@erpnext.com',
|
||||
subject=self.doc.frequency + ' Digest',
|
||||
msg=email_body,
|
||||
from_defs=1
|
||||
)
|
||||
except Exception, e:
|
||||
webnotes.msgprint('There was a problem in sending your email. Please contact support@erpnext.com')
|
||||
#webnotes.errprint(webnotes.getTraceback())
|
||||
|
||||
|
||||
def on_update(self):
|
||||
"""
|
||||
|
||||
"""
|
||||
import webnotes
|
||||
args = {
|
||||
'db_name': webnotes.conn.get_value('Control Panel', '', 'account_id'),
|
||||
'event': 'setup.doctype.email_digest.email_digest.send'
|
||||
}
|
||||
from webnotes.utils.scheduler import Scheduler
|
||||
print "before scheduler"
|
||||
sch = Scheduler()
|
||||
sch.connect()
|
||||
|
||||
|
||||
if self.doc.enabled == 1:
|
||||
# Create scheduler entry
|
||||
res = sch.conn.sql("""
|
||||
SELECT * FROM Event
|
||||
WHERE
|
||||
db_name = %(db_name)s AND
|
||||
event = %(event)s
|
||||
""", args)
|
||||
|
||||
if not (res and res[0]):
|
||||
args['next_execution'] = self.get_next_execution()
|
||||
|
||||
sch.conn.sql("""
|
||||
INSERT INTO Event (db_name, event, `interval`, next_execution, recurring)
|
||||
VALUES (%(db_name)s, %(event)s, 86400, %(next_execution)s, 1)
|
||||
""", args)
|
||||
|
||||
else:
|
||||
# delete scheduler entry
|
||||
sch.clear(args['db_name'], args['event'])
|
||||
print "after on update"
|
||||
|
||||
|
||||
def get_next_sending(self):
|
||||
"""
|
||||
|
||||
"""
|
||||
# Get TimeZone
|
||||
# Get System TimeZone
|
||||
import time
|
||||
from pytz import timezone
|
||||
import datetime
|
||||
import webnotes.defs
|
||||
cp = webnotes.model.doc.Document('Control Panel','Control Panel')
|
||||
app_tz = timezone(cp.time_zone)
|
||||
server_tz = timezone(getattr(webnotes.defs, 'system_timezone'))
|
||||
|
||||
start_date, end_date = self.get_start_end_dates()
|
||||
|
||||
new_date = end_date + datetime.timedelta(days=1)
|
||||
new_time = datetime.time(hour=6)
|
||||
|
||||
naive_dt = datetime.datetime.combine(new_date, new_time)
|
||||
app_dt = app_tz.localize(naive_dt)
|
||||
server_dt = server_tz.normalize(app_dt.astimezone(server_tz))
|
||||
|
||||
res = {
|
||||
'app_dt': app_dt.replace(tzinfo=None),
|
||||
'app_tz': app_tz,
|
||||
'server_dt': server_dt.replace(tzinfo=None),
|
||||
'server_tz': server_tz
|
||||
}
|
||||
|
||||
from webnotes.utils import formatdate
|
||||
str_date = formatdate(str(res['app_dt'].date()))
|
||||
str_time = res['app_dt'].time().strftime('%I:%M')
|
||||
|
||||
self.doc.next_send = str_date + " at about " + str_time
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def get_next_execution(self):
|
||||
"""
|
||||
|
||||
"""
|
||||
from datetime import datetime, timedelta
|
||||
dt_args = self.get_next_sending()
|
||||
server_dt = dt_args['server_dt']
|
||||
now_dt = datetime.now(dt_args['server_tz'])
|
||||
if now_dt.time() <= server_dt.time():
|
||||
next_date = now_dt.date()
|
||||
else:
|
||||
next_date = now_dt.date() + timedelta(days=1)
|
||||
|
||||
next_time = server_dt.time()
|
||||
|
||||
return datetime.combine(next_date, next_time)
|
||||
|
||||
|
||||
def onload(self):
|
||||
"""
|
||||
|
||||
"""
|
||||
self.get_next_sending()
|
||||
|
||||
|
||||
def get_standard_body(self, result):
|
||||
"""
|
||||
Generate email body depending on the result
|
||||
"""
|
||||
from webnotes.utils import fmt_money
|
||||
from webnotes.model.doc import Document
|
||||
company = Document('Company', self.doc.company)
|
||||
currency = company.default_currency
|
||||
|
||||
def table(args):
|
||||
if type(args['body']) == type(''):
|
||||
table_body = """\
|
||||
<tbody><tr>
|
||||
<td style='padding: 5px; font-size: 24px; \
|
||||
font-weight: bold; background: #F7F7F5'>""" + \
|
||||
args['body'] + \
|
||||
"""\
|
||||
</td>
|
||||
</tr></tbody>"""
|
||||
|
||||
elif type(args['body'] == type([])):
|
||||
body_rows = []
|
||||
for rows in args['body']:
|
||||
for r in rows:
|
||||
body_rows.append("""\
|
||||
<tr>
|
||||
<td style='padding: 5px; font-size: 24px; \
|
||||
font-weight: bold; background: #F7F7F5'>""" \
|
||||
+ r + """\
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
body_rows.append("<tr><td style='background: #F7F7F5'><br></td></tr>")
|
||||
|
||||
table_body = "<tbody>" + "".join(body_rows) + "</tbody>"
|
||||
|
||||
table_head = """\
|
||||
<thead><tr>
|
||||
<td style='padding: 5px; background: #D8D8D4; font-size: 16px; font-weight: bold'>""" \
|
||||
+ args['head'] + """\
|
||||
</td>
|
||||
</tr></thead>"""
|
||||
|
||||
return "<table style='border-collapse: collapse; width: 100%;'>" \
|
||||
+ table_head \
|
||||
+ table_body \
|
||||
+ "</table>"
|
||||
|
||||
currency_amount_str = "<span style='color: grey; font-size: 12px'>%s</span> %s"
|
||||
|
||||
body_dict = {
|
||||
|
||||
'invoiced_amount': {
|
||||
'table': 'invoiced_amount' in result and table({
|
||||
'head': 'Invoiced Amount',
|
||||
'body': currency_amount_str \
|
||||
% (currency, fmt_money(result['invoiced_amount']['debit']))
|
||||
}),
|
||||
'idx': 300
|
||||
},
|
||||
|
||||
'payables': {
|
||||
'table': 'payables' in result and table({
|
||||
'head': 'Payables',
|
||||
'body': currency_amount_str \
|
||||
% (currency, fmt_money(result['payables']['credit']))
|
||||
}),
|
||||
'idx': 200
|
||||
},
|
||||
|
||||
'collections': {
|
||||
'table': 'collections' in result and table({
|
||||
'head': 'Collections',
|
||||
'body': currency_amount_str \
|
||||
% (currency, fmt_money(result['collections']['credit']))
|
||||
}),
|
||||
'idx': 301
|
||||
},
|
||||
|
||||
'payments': {
|
||||
'table': 'payments' in result and table({
|
||||
'head': 'Payments',
|
||||
'body': currency_amount_str \
|
||||
% (currency, fmt_money(result['payments']['debit']))
|
||||
}),
|
||||
'idx': 201
|
||||
},
|
||||
|
||||
'income': {
|
||||
'table': 'income' in result and table({
|
||||
'head': 'Income',
|
||||
'body': currency_amount_str \
|
||||
% (currency, fmt_money(result['income']['value']))
|
||||
}),
|
||||
'idx': 302
|
||||
},
|
||||
|
||||
'expenses_booked': {
|
||||
'table': 'expenses_booked' in result and table({
|
||||
'head': 'Expenses Booked',
|
||||
'body': currency_amount_str \
|
||||
% (currency, fmt_money(result['expenses_booked']['value']))
|
||||
}),
|
||||
'idx': 202
|
||||
},
|
||||
|
||||
'bank_balance': {
|
||||
'table': 'bank_balance' in result and table({
|
||||
'head': 'Bank Balance',
|
||||
'body': [
|
||||
[
|
||||
"<span style='font-size: 16px; font-weight: normal'>%s</span>" % bank['name'],
|
||||
currency_amount_str % (currency, fmt_money(bank['value']))
|
||||
] for bank in result['bank_balance']
|
||||
]
|
||||
}),
|
||||
'idx': 400
|
||||
},
|
||||
|
||||
'new_leads': {
|
||||
'table': 'new_leads' in result and table({
|
||||
'head': 'New Leads',
|
||||
'body': '%s' % result['new_leads']['count']
|
||||
}),
|
||||
'idx': 100
|
||||
},
|
||||
|
||||
'new_enquiries': {
|
||||
'table': 'new_enquiries' in result and table({
|
||||
'head': 'New Enquiries',
|
||||
'body': '%s' % result['new_enquiries']['count']
|
||||
}),
|
||||
'idx': 101
|
||||
},
|
||||
|
||||
'new_quotations': {
|
||||
'table': 'new_quotations' in result and table({
|
||||
'head': 'New Quotations',
|
||||
'body': '%s' % result['new_quotations']['count']
|
||||
}),
|
||||
'idx': 102
|
||||
},
|
||||
|
||||
'new_sales_orders': {
|
||||
'table': 'new_sales_orders' in result and table({
|
||||
'head': 'New Sales Orders',
|
||||
'body': '%s' % result['new_sales_orders']['count']
|
||||
}),
|
||||
'idx': 103
|
||||
},
|
||||
|
||||
'new_purchase_orders': {
|
||||
'table': 'new_purchase_orders' in result and table({
|
||||
'head': 'New Purchase Orders',
|
||||
'body': '%s' % result['new_purchase_orders']['count']
|
||||
}),
|
||||
'idx': 104
|
||||
},
|
||||
|
||||
'new_transactions': {
|
||||
'table': 'new_transactions' in result and table({
|
||||
'head': 'New Transactions',
|
||||
'body': '%s' % result['new_transactions']['count']
|
||||
}),
|
||||
'idx': 105
|
||||
}
|
||||
|
||||
#'stock_below_rl':
|
||||
}
|
||||
|
||||
table_list = []
|
||||
|
||||
# Sort these keys depending on idx value
|
||||
bd_keys = sorted(body_dict, key=lambda x: body_dict[x]['idx'])
|
||||
|
||||
|
||||
for k in bd_keys:
|
||||
if self.doc.fields[k]:
|
||||
table_list.append(body_dict[k]['table'])
|
||||
|
||||
result = []
|
||||
|
||||
i = 0
|
||||
result = []
|
||||
op_len = len(table_list)
|
||||
while(True):
|
||||
if i>=op_len:
|
||||
break
|
||||
elif (op_len - i) == 1:
|
||||
result.append("""\
|
||||
<tr>
|
||||
<td style='width: 50%%; vertical-align: top;'>%s</td>
|
||||
<td></td>
|
||||
</tr>""" % (table_list[i]))
|
||||
else:
|
||||
result.append("""\
|
||||
<tr>
|
||||
<td style='width: 50%%; vertical-align: top;'>%s</td>
|
||||
<td>%s</td>
|
||||
</tr>""" % (table_list[i], table_list[i+1]))
|
||||
|
||||
i = i + 2
|
||||
|
||||
from webnotes.utils import formatdate
|
||||
start_date, end_date = self.get_start_end_dates()
|
||||
digest_daterange = self.doc.frequency=='Daily' \
|
||||
and formatdate(str(start_date)) \
|
||||
or (formatdate(str(start_date)) + " to " + (formatdate(str(end_date))))
|
||||
|
||||
email_body = """
|
||||
<div style='width: 100%%'>
|
||||
<div style='padding: 10px; margin: auto; text-align: center; line-height: 80%%'>
|
||||
<p style='font-weight: bold; font-size: 24px'>%s</p>
|
||||
<p style='font-size: 16px; color: grey'>%s</p>
|
||||
<p style='font-size: 20px; font-weight: bold'>%s</p>
|
||||
</div>
|
||||
<table cellspacing=15 style='width: 100%%'>""" \
|
||||
% ((self.doc.frequency + " Digest"), \
|
||||
digest_daterange, self.doc.company) \
|
||||
+ "".join(result) + """\
|
||||
</table><br><p></p>
|
||||
</div>"""
|
||||
|
||||
return email_body
|
||||
|
||||
|
||||
def send():
|
||||
"""
|
||||
|
||||
"""
|
||||
edigest_list = webnotes.conn.sql("""
|
||||
SELECT name FROM `tabEmail Digest`
|
||||
WHERE enabled=1
|
||||
""", as_list=1)
|
||||
|
||||
from webnotes.model.code import get_obj
|
||||
from datetime import datetime, timedelta
|
||||
now = datetime.now()
|
||||
now_date = now.date()
|
||||
now_time = (now + timedelta(hours=2)).time()
|
||||
|
||||
for ed in edigest_list:
|
||||
if ed[0]:
|
||||
ed_obj = get_obj('Email Digest', ed[0])
|
||||
ed_obj.sending = True
|
||||
dt_dict = ed_obj.get_next_sending()
|
||||
send_date = dt_dict['server_dt'].date()
|
||||
send_time = dt_dict['server_dt'].time()
|
||||
|
||||
if (now_date == send_date) and (send_time <= now_time):
|
||||
#webnotes.msgprint('sending ' + ed_obj.doc.name)
|
||||
ed_obj.send()
|
||||
#else:
|
||||
# webnotes.msgprint('not sending ' + ed_obj.doc.name)
|
@ -3,24 +3,25 @@
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2011-07-27 14:23:09',
|
||||
'creation': '2011-11-28 13:11:56',
|
||||
'docstatus': 0,
|
||||
'modified': '2011-07-27 17:32:27',
|
||||
'modified': '2011-12-08 19:21:26',
|
||||
'modified_by': 'Administrator',
|
||||
'owner': 'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': '1311760331',
|
||||
'_last_update': '1323352149',
|
||||
'autoname': 'Prompt',
|
||||
'colour': 'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'issingle': 1,
|
||||
'document_type': 'System',
|
||||
'module': 'Setup',
|
||||
'name': '__common__',
|
||||
'section_style': 'Simple',
|
||||
'show_in_menu': 0,
|
||||
'version': 4
|
||||
'version': 78
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
@ -29,23 +30,18 @@
|
||||
'name': '__common__',
|
||||
'parent': 'Email Digest',
|
||||
'parentfield': 'fields',
|
||||
'parenttype': 'DocType',
|
||||
'permlevel': 0
|
||||
'parenttype': 'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
'doctype': 'DocPerm',
|
||||
'idx': 1,
|
||||
'name': '__common__',
|
||||
'parent': 'Email Digest',
|
||||
'parentfield': 'permissions',
|
||||
'parenttype': 'DocType',
|
||||
'permlevel': 0,
|
||||
'read': 1,
|
||||
'role': 'Administrator',
|
||||
'write': 1
|
||||
'role': 'System Manager'
|
||||
},
|
||||
|
||||
# DocType, Email Digest
|
||||
@ -56,34 +52,290 @@
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': 'DocPerm'
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': 'DocPerm',
|
||||
'permlevel': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': 'DocPerm',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'HTML',
|
||||
'idx': 1,
|
||||
'label': 'Body'
|
||||
'fieldtype': 'Section Break',
|
||||
'label': 'Settings',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'content_config',
|
||||
'fieldtype': 'Text',
|
||||
'fieldtype': 'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'enabled',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'Enabled',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'company',
|
||||
'fieldtype': 'Select',
|
||||
'label': 'For Company',
|
||||
'options': 'link:Company',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'frequency',
|
||||
'fieldtype': 'Select',
|
||||
'label': 'How frequently?',
|
||||
'options': '\nDaily\nWeekly\nMonthly',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.enabled',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'next_send',
|
||||
'fieldtype': 'Data',
|
||||
'label': 'Next email will be sent on:',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': '1',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'use_standard',
|
||||
'fieldtype': 'Check',
|
||||
'hidden': 1,
|
||||
'idx': 2,
|
||||
'label': 'Content Config'
|
||||
'label': 'Use standard?',
|
||||
'permlevel': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'email_config',
|
||||
'fieldtype': 'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Button',
|
||||
'label': 'Add Recipients',
|
||||
'permlevel': 0,
|
||||
'trigger': 'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'description': 'Note: Email will not be sent to disabled users',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'recipient_list',
|
||||
'fieldtype': 'Text',
|
||||
'label': 'Recipients',
|
||||
'permlevel': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'label': 'Select Digest Content',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'new_leads',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'New Leads',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'new_enquiries',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'New Enquiries',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'new_quotations',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'New Quotations',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'new_sales_orders',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'New Sales Orders',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'new_purchase_orders',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'New Purchase Orders',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'new_transactions',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'New Transactions',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'payables',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'Payables',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'payments',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'Payments',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'expenses_booked',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'Expenses Booked',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'invoiced_amount',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'Invoiced Amount (Receivables)',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'collections',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'Collections',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'income',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'Income',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'bank_balance',
|
||||
'fieldtype': 'Check',
|
||||
'label': 'Bank Balance',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'stock_below_rl',
|
||||
'fieldtype': 'Check',
|
||||
'hidden': 1,
|
||||
'idx': 3,
|
||||
'label': 'Email Config'
|
||||
'label': 'Stock Items below re-order level',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:!doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldtype': 'Section Break',
|
||||
'label': 'Enter Custom Code',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:!doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'custom_code',
|
||||
'fieldtype': 'Code',
|
||||
'label': 'Custom Python Code',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'depends_on': 'eval:!doc.use_standard',
|
||||
'doctype': 'DocField',
|
||||
'fieldname': 'email_template',
|
||||
'fieldtype': 'Code',
|
||||
'label': 'Email Template',
|
||||
'permlevel': 0
|
||||
}
|
||||
]
|
@ -161,6 +161,7 @@ SetupData = function(cnty){
|
||||
['Custom Field',1,'Custom Field','dt'+NEWLINE+'label'+NEWLINE+'fieldtype'+NEWLINE+'options','Add and manage custom fields on forms'],
|
||||
['Email Settings',3,'Email Settings','','Outgoing email server and address'],
|
||||
['Notification Settings',3,'Notification Control','','Automatic emails set at selected events'],
|
||||
['Email Digest', 1, 'Email Digest', '', 'Schedule Daily / Weekly / Monthly Summary e-mails'],
|
||||
['Company',1,'Company','id'+NEWLINE+'is_active'+NEWLINE+'email','Manage list of companies'],
|
||||
['Fiscal Year',1,'Fiscal Year','id'+NEWLINE+'company'+NEWLINE+'is_active'+NEWLINE+'year','Manage list of fiscal years'],
|
||||
['Personalize',3,'Personalize','','Set your banner'],
|
||||
@ -168,7 +169,7 @@ SetupData = function(cnty){
|
||||
['Import Data',2,'Import Data','','Import data from CSV files'],
|
||||
['Manage Users',2,'My Company','','Add / remove users and manage their roles'],
|
||||
['Web Forms',2,'Webforms','', 'Code to embed forms in yor website'],
|
||||
['Permissions Manager',2,'Permission Engine','', 'Manage all permissions from one tool (beta)'],
|
||||
['Permissions Manager',2,'Permission Engine','', 'Manage all permissions from one tool'],
|
||||
//['Property Setter',1,'Property Setter','', 'Customize properties of a Form (DocType) or Field'],
|
||||
['Customize Form View',3,'DocLayer','', 'Customize properties of a Form (DocType) or Field'],
|
||||
['Print Formats', 1, 'Print Format', '', 'Manage Print Formats'],
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user