Merge pull request #2203 from rmehta/mailbox

Mailbox
This commit is contained in:
Rushabh Mehta 2014-09-29 14:18:10 +05:30
commit 86211cd219
131 changed files with 1625 additions and 3166 deletions

View File

@ -16,7 +16,7 @@ install:
- sudo apt-get install mariadb-server mariadb-common libmariadbclient-dev
- wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/wkhtmltox-0.12.1_linux-precise-amd64.deb
- sudo dpkg -i wkhtmltox-0.12.1_linux-precise-amd64.deb
- CFLAGS=-O0 pip install git+https://github.com/frappe/frappe.git@develop
- CFLAGS=-O0 pip install git+https://github.com/frappe/frappe.git@v5.0
- CFLAGS=-O0 pip install --editable .
before_script:

View File

@ -1 +1 @@
__version__ = '4.3.0'
__version__ = '5.0.0-alpha'

View File

@ -18,6 +18,9 @@ class JournalVoucher(AccountsController):
self.credit_days_global = -1
self.is_approving_authority = -1
def get_feed(self):
return self.voucher_type
def validate(self):
if not self.is_opening:
self.is_opening='No'

View File

@ -78,7 +78,7 @@ def get_conditions(filters):
conditions.append("voucher_no=%(voucher_no)s")
from frappe.widgets.reportview import build_match_conditions
from frappe.desk.reportview import build_match_conditions
match_conditions = build_match_conditions("GL Entry")
if match_conditions: conditions.append(match_conditions)

View File

@ -7,7 +7,7 @@ import frappe
from frappe.utils import nowdate, cstr, flt, now, getdate, add_months
from frappe import throw, _
from frappe.utils import formatdate
import frappe.widgets.reportview
import frappe.desk.reportview
class FiscalYearError(frappe.ValidationError): pass
class BudgetError(frappe.ValidationError): pass

View File

@ -10,6 +10,8 @@ frappe.provide("erpnext.buying");
frappe.require("assets/erpnext/js/transaction.js");
{% include "public/js/controllers/accounts.js" %}
cur_frm.email_field = "contact_email";
erpnext.buying.BuyingController = erpnext.TransactionController.extend({
onload: function() {
this.setup_queries();

View File

@ -38,7 +38,7 @@ class QualityInspection(Document):
def item_query(doctype, txt, searchfield, start, page_len, filters):
if filters.get("from"):
from frappe.widgets.reportview import get_match_cond
from frappe.desk.reportview import get_match_cond
filters.update({
"txt": txt,
"mcond": get_match_cond(filters["from"]),

View File

@ -20,12 +20,6 @@ cur_frm.cscript.refresh = function(doc, dt, dn) {
// make lists
cur_frm.cscript.make_address(doc,dt,dn);
cur_frm.cscript.make_contact(doc,dt,dn);
cur_frm.communication_view = new frappe.views.CommunicationList({
list: frappe.get_list("Communication", {"supplier": doc.name}),
parent: cur_frm.fields_dict.communication_html.wrapper,
doc: doc
})
}
}

View File

@ -83,22 +83,6 @@
"permlevel": 0,
"read_only": 1
},
{
"depends_on": "eval:!doc.__islocal",
"fieldname": "communication_history",
"fieldtype": "Section Break",
"label": "Communication History",
"options": "icon-comments",
"permlevel": 0,
"print_hide": 1
},
{
"fieldname": "communication_html",
"fieldtype": "HTML",
"label": "Communication HTML",
"permlevel": 0,
"print_hide": 1
},
{
"fieldname": "more_info",
"fieldtype": "Section Break",
@ -186,7 +170,7 @@
],
"icon": "icon-user",
"idx": 1,
"modified": "2014-09-10 17:53:09.286715",
"modified": "2014-09-12 12:26:37.606976",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier",

View File

@ -13,6 +13,8 @@ from erpnext.accounts.party import create_party_account
from erpnext.utilities.transaction_base import TransactionBase
class Supplier(TransactionBase):
def get_feed(self):
return self.supplier_name
def autoname(self):
supp_master_name = frappe.defaults.get_global_default('supp_master_name')

View File

@ -7,13 +7,6 @@ def get_data():
"icon": "icon-money",
"type": "module"
},
"Activity": {
"color": "#e67e22",
"icon": "icon-play",
"label": _("Activity"),
"link": "activity",
"type": "page"
},
"Buying": {
"color": "#c0392b",
"icon": "icon-shopping-cart",
@ -30,14 +23,6 @@ def get_data():
"icon": "icon-cogs",
"type": "module"
},
"Notes": {
"color": "#95a5a6",
"doctype": "Note",
"icon": "icon-file-alt",
"label": _("Notes"),
"link": "List/Note",
"type": "list"
},
"POS": {
"color": "#589494",
"icon": "icon-th",

View File

@ -155,7 +155,7 @@ def get_data():
},
{
"type": "doctype",
"name": "Jobs Email Settings",
"name": "Email Account",
"description": _("Setup incoming server for jobs email id. (e.g. jobs@example.com)")
},
]

View File

@ -158,7 +158,7 @@ def get_data():
},
{
"type": "doctype",
"name": "Sales Email Settings",
"name": "Email Account",
"description": _("Setup incoming server for sales email id. (e.g. sales@example.com)")
},
{

View File

@ -1,5 +1,5 @@
from frappe import _
from frappe.widgets.moduleview import add_setup_section
from frappe.desk.moduleview import add_setup_section
def get_data():
data = [
@ -73,21 +73,6 @@ def get_data():
"name": "Email Digest",
"description": _("Create and manage daily, weekly and monthly email digests.")
},
{
"type": "doctype",
"name": "Support Email Settings",
"description": _("Setup incoming server for support email id. (e.g. support@example.com)")
},
{
"type": "doctype",
"name": "Sales Email Settings",
"description": _("Setup incoming server for sales email id. (e.g. sales@example.com)")
},
{
"type": "doctype",
"name": "Jobs Email Settings",
"description": _("Setup incoming server for jobs email id. (e.g. jobs@example.com)")
},
{
"type": "doctype",
"name": "SMS Settings",

View File

@ -49,7 +49,7 @@ def get_data():
"items": [
{
"type": "doctype",
"name": "Support Email Settings",
"name": "Email Account",
"description": _("Setup incoming server for support email id. (e.g. support@example.com)")
},
]

View File

@ -146,7 +146,6 @@ class AccountsController(TransactionBase):
self.currency = company_currency
self.conversion_rate = 1.0
else:
from erpnext.setup.doctype.currency.currency import validate_conversion_rate
validate_conversion_rate(self.currency, self.conversion_rate,
self.meta.get_label("conversion_rate"), self.company)
@ -500,3 +499,12 @@ def get_taxes_and_charges(master_doctype, master_name, tax_parentfield):
taxes_and_charges.append(tax)
return taxes_and_charges
def validate_conversion_rate(currency, conversion_rate, conversion_rate_label, company):
"""common validation for currency and price list currency"""
company_currency = frappe.db.get_value("Company", company, "default_currency")
if not conversion_rate:
throw(_("{0} is mandatory. Maybe Currency Exchange record is not created for {1} to {2}.").format(
conversion_rate_label, currency, company_currency))

View File

@ -18,6 +18,10 @@ class BuyingController(StockController):
"other_charges": "templates/print_formats/includes/taxes.html",
}
def get_feed(self):
return _("From {0} | {1} {2}").format(self.supplier_name, self.currency,
self.grand_total_import)
def validate(self):
super(BuyingController, self).validate()
if getattr(self, "supplier", None) and not self.supplier_name:

View File

@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
from frappe.widgets.reportview import get_match_cond
from frappe.desk.reportview import get_match_cond
from frappe.model.db_query import DatabaseQuery
def get_filters_cond(doctype, filters, conditions):
@ -276,7 +276,7 @@ def get_account_list(doctype, txt, searchfield, start, page_len, filters):
if searchfield and txt:
filter_list.append([doctype, searchfield, "like", "%%%s%%" % txt])
return frappe.widgets.reportview.execute("Account", filters = filter_list,
return frappe.desk.reportview.execute("Account", filters = filter_list,
fields = ["name", "parent_account"],
limit_start=start, limit_page_length=page_len, as_list=True)

View File

@ -134,7 +134,7 @@ def notify_errors(doc, doctype, customer, owner):
def assign_task_to_owner(doc, doctype, msg, users):
for d in users:
from frappe.widgets.form import assign_to
from frappe.desk.form import assign_to
args = {
'assign_to' : d,
'doctype' : doctype,

View File

@ -18,6 +18,10 @@ class SellingController(StockController):
"other_charges": "templates/print_formats/includes/taxes.html",
}
def get_feed(self):
return _("To {0} | {1} {2}").format(self.customer_name, self.currency,
self.grand_total_export)
def onload(self):
if self.doctype in ("Sales Order", "Delivery Note", "Sales Invoice"):
for item in self.get(self.fname):
@ -29,13 +33,6 @@ class SellingController(StockController):
self.validate_max_discount()
check_active_sales_items(self)
def get_sender(self, comm):
sender = None
if cint(frappe.db.get_value('Sales Email Settings', None, 'extract_emails')):
sender = frappe.db.get_value('Sales Email Settings', None, 'email_id')
return sender or comm.sender or frappe.session.user
def set_missing_values(self, for_validate=False):
super(SellingController, self).set_missing_values(for_validate)

View File

@ -8,37 +8,23 @@ from frappe import msgprint, _, throw
from frappe.model.document import Document
status_map = {
"Contact": [
["Replied", "communication_sent"],
["Open", "communication_received"]
],
"Job Applicant": [
["Replied", "communication_sent"],
["Open", "communication_received"]
],
"Lead": [
["Replied", "communication_sent"],
["Converted", "has_customer"],
["Opportunity", "has_opportunity"],
["Open", "communication_received"],
],
"Opportunity": [
["Draft", None],
["Submitted", "eval:self.docstatus==1"],
["Lost", "eval:self.status=='Lost'"],
["Quotation", "has_quotation"],
["Replied", "communication_sent"],
["Cancelled", "eval:self.docstatus==2"],
["Open", "communication_received"],
],
"Quotation": [
["Draft", None],
["Submitted", "eval:self.docstatus==1"],
["Lost", "eval:self.status=='Lost'"],
["Ordered", "has_sales_order"],
["Replied", "communication_sent"],
["Cancelled", "eval:self.docstatus==2"],
["Open", "communication_received"],
],
"Sales Order": [
["Draft", None],
@ -46,10 +32,6 @@ status_map = {
["Stopped", "eval:self.status=='Stopped'"],
["Cancelled", "eval:self.docstatus==2"],
],
"Support Ticket": [
["Replied", "communication_sent"],
["Open", "communication_received"]
],
}
class StatusUpdater(Document):
@ -90,25 +72,6 @@ class StatusUpdater(Document):
if update:
frappe.db.set_value(self.doctype, self.name, "status", self.status)
def on_communication(self):
if not self.get("communications"): return
self.communication_set = True
self.get("communications").sort(key=lambda d: d.creation)
self.set_status(update=True)
del self.communication_set
def communication_received(self):
if getattr(self, "communication_set", False):
last_comm = self.get("communications")
if last_comm:
return last_comm[-1].sent_or_received == "Received"
def communication_sent(self):
if getattr(self, "communication_set", False):
last_comm = self.get("communications")
if last_comm:
return last_comm[-1].sent_or_received == "Sent"
def validate_qty(self):
"""
Validates qty at row level

View File

@ -1,102 +0,0 @@
# ERPNext - web based ERP (http://erpnext.com)
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import frappe
from frappe import msgprint
feed_dict = {
# Project
'Project': ['[%(status)s]', '#000080'],
'Task': ['[%(status)s] %(subject)s', '#000080'],
# Sales
'Lead': ['%(lead_name)s', '#000080'],
'Quotation': ['[%(status)s] To %(customer_name)s worth %(currency)s %(grand_total_export)s', '#4169E1'],
'Sales Order': ['[%(status)s] To %(customer_name)s worth %(currency)s %(grand_total_export)s', '#4169E1'],
# Purchase
'Supplier': ['%(supplier_name)s, %(supplier_type)s', '#6495ED'],
'Purchase Order': ['[%(status)s] %(name)s To %(supplier_name)s for %(currency)s %(grand_total_import)s', '#4169E1'],
# Stock
'Delivery Note': ['[%(status)s] To %(customer_name)s', '#4169E1'],
'Purchase Receipt': ['[%(status)s] From %(supplier)s', '#4169E1'],
# Accounts
'Journal Voucher': ['[%(voucher_type)s] %(name)s', '#4169E1'],
'Purchase Invoice': ['To %(supplier_name)s for %(currency)s %(grand_total_import)s', '#4169E1'],
'Sales Invoice': ['To %(customer_name)s for %(currency)s %(grand_total_export)s', '#4169E1'],
# HR
'Expense Claim': ['[%(approval_status)s] %(name)s by %(employee_name)s', '#4169E1'],
'Salary Slip': ['%(employee_name)s for %(month)s %(fiscal_year)s', '#4169E1'],
'Leave Transaction': ['%(leave_type)s for %(employee)s', '#4169E1'],
# Support
'Customer Issue': ['[%(status)s] %(description)s by %(customer_name)s', '#000080'],
'Maintenance Visit': ['To %(customer_name)s', '#4169E1'],
'Support Ticket': ["[%(status)s] %(subject)s", '#000080'],
# Website
'Web Page': ['%(title)s', '#000080'],
'Blog': ['%(title)s', '#000080']
}
def make_feed(feedtype, doctype, name, owner, subject, color):
"makes a new Feed record"
#msgprint(subject)
from frappe.utils import get_fullname
if feedtype in ('Login', 'Comment', 'Assignment'):
# delete old login, comment feed
frappe.db.sql("""delete from tabFeed where
datediff(curdate(), creation) > 7 and doc_type in ('Comment', 'Login', 'Assignment')""")
else:
# one feed per item
frappe.db.sql("""delete from tabFeed
where doc_type=%s and doc_name=%s
and ifnull(feed_type,'') != 'Comment'""", (doctype, name))
f = frappe.new_doc('Feed')
f.owner = owner
f.feed_type = feedtype
f.doc_type = doctype
f.doc_name = name
f.subject = subject
f.color = color
f.full_name = get_fullname(owner)
f.save(ignore_permissions=True)
def update_feed(doc, method=None):
"adds a new feed"
if frappe.flags.in_patch:
return
if method in ['on_update', 'on_submit']:
subject, color = feed_dict.get(doc.doctype, [None, None])
if subject:
make_feed('', doc.doctype, doc.name, doc.owner, subject % doc.as_dict(), color)
def make_comment_feed(doc, method):
"""add comment to feed"""
comment = doc.comment
if len(comment) > 240:
comment = comment[:240] + "..."
make_feed('Comment', doc.comment_doctype, doc.comment_docname, doc.comment_by,
'<i>"' + comment + '"</i>', '#6B24B3')

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1 +0,0 @@
Activity Feed.

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1,73 +0,0 @@
{
"autoname": "hash",
"creation": "2012-07-03 13:29:42",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "feed_type",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Feed Type",
"options": "\nComment\nLogin",
"permlevel": 0
},
{
"fieldname": "doc_type",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Doc Type",
"permlevel": 0
},
{
"fieldname": "doc_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Doc Name",
"permlevel": 0
},
{
"fieldname": "subject",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Subject",
"permlevel": 0
},
{
"fieldname": "color",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Color",
"permlevel": 0
},
{
"fieldname": "full_name",
"fieldtype": "Data",
"label": "Full Name",
"permlevel": 0
}
],
"icon": "icon-rss",
"idx": 1,
"modified": "2014-06-18 03:49:10.882587",
"modified_by": "Administrator",
"module": "Home",
"name": "Feed",
"owner": "Administrator",
"permissions": [
{
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager"
},
{
"apply_user_permissions": 1,
"permlevel": 0,
"read": 1,
"role": "All"
}
]
}

View File

@ -1,50 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
import frappe.defaults
import frappe.permissions
from frappe.model.document import Document
class Feed(Document):
pass
def on_doctype_update():
if not frappe.db.sql("""show index from `tabFeed`
where Key_name="feed_doctype_docname_index" """):
frappe.db.commit()
frappe.db.sql("""alter table `tabFeed`
add index feed_doctype_docname_index(doc_type, doc_name)""")
def get_permission_query_conditions(user):
if not user: user = frappe.session.user
if not frappe.permissions.apply_user_permissions("Feed", "read", user):
return ""
user_permissions = frappe.defaults.get_user_permissions(user)
can_read = frappe.get_user(user).get_can_read()
can_read_doctypes = ['"{}"'.format(doctype) for doctype in
list(set(can_read) - set(user_permissions.keys()))]
if not can_read_doctypes:
return ""
conditions = ["tabFeed.doc_type in ({})".format(", ".join(can_read_doctypes))]
if user_permissions:
can_read_docs = []
for doctype, names in user_permissions.items():
for n in names:
can_read_docs.append('"{}|{}"'.format(doctype, n))
if can_read_docs:
conditions.append("concat_ws('|', tabFeed.doc_type, tabFeed.doc_name) in ({})".format(
", ".join(can_read_docs)))
return "(" + " or ".join(conditions) + ")"
def has_permission(doc, user):
return frappe.has_permission(doc.doc_type, "read", doc.doc_name, user=user)

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1 +0,0 @@
List of latest activities based on Feed.

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1,23 +0,0 @@
#page-activity .label {
display: inline-block;
width: 100px;
margin-right: 7px;
}
#page-activity .label-info {
cursor: pointer;
}
#page-activity .user-info {
float: right;
color: #777;
font-size: 10px;
}
#page-activity .date-sep {
margin: 0px -15px 11px -15px;
padding: 5px 0px;
border-bottom: 2px solid #aaa;
color: #555;
font-size: 10px;
}

View File

@ -1,88 +0,0 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
frappe.pages['activity'].onload = function(wrapper) {
frappe.ui.make_app_page({
parent: wrapper,
title: __("Activity"),
single_column: true
})
wrapper.appframe.add_module_icon("Activity");
var list = new frappe.ui.Listing({
hide_refresh: true,
appframe: wrapper.appframe,
method: 'erpnext.home.page.activity.activity.get_feed',
parent: $(wrapper).find(".layout-main"),
render_row: function(row, data) {
new erpnext.ActivityFeed(row, data);
}
});
list.run();
wrapper.appframe.set_title_right(__("Refresh"), function() { list.run(); });
// Build Report Button
if(frappe.boot.user.can_get_report.indexOf("Feed")!=-1) {
wrapper.appframe.add_button(__('Build Report'), function() {
frappe.set_route('Report', "Feed");
}, 'icon-th');
}
}
erpnext.last_feed_date = false;
erpnext.ActivityFeed = Class.extend({
init: function(row, data) {
this.scrub_data(data);
this.add_date_separator(row, data);
if(!data.add_class) data.add_class = "label-default";
$(row).append(repl('<div style="margin: 0px">\
<span class="avatar avatar-small"><img src="%(imgsrc)s" /></span> \
<span %(onclick)s class="label %(add_class)s">%(feed_type)s</span>\
%(link)s %(subject)s <span class="user-info">%(by)s</span></div>', data));
},
scrub_data: function(data) {
data.by = frappe.user_info(data.owner).fullname;
data.imgsrc = frappe.utils.get_file_link(frappe.user_info(data.owner).image);
// feedtype
if(!data.feed_type) {
data.feed_type = __(data.doc_type);
data.add_class = "label-info";
data.onclick = repl('onclick="window.location.href=\'#!List/%(feed_type)s\';"', data)
}
// color for comment
if(data.feed_type=='Comment') {
data.add_class = "label-danger";
}
if(data.feed_type=='Assignment') {
data.add_class = "label-warning";
}
// link
if(data.doc_name && data.feed_type!='Login') {
data.link = frappe.format(data.doc_name, {"fieldtype":"Link", "options":data.doc_type})
} else {
data.link = "";
}
},
add_date_separator: function(row, data) {
var date = dateutil.str_to_obj(data.modified);
var last = erpnext.last_feed_date;
if((last && dateutil.obj_to_str(last) != dateutil.obj_to_str(date)) || (!last)) {
var diff = dateutil.get_day_diff(dateutil.get_today(), dateutil.obj_to_str(date));
if(diff < 1) {
pdate = 'Today';
} else if(diff < 2) {
pdate = 'Yesterday';
} else {
pdate = dateutil.global_date_format(date);
}
$(row).html(repl('<div class="date-sep" style="padding-left: 15px;">%(date)s</div>', {date: pdate}));
}
erpnext.last_feed_date = date;
}
})

View File

@ -1,20 +0,0 @@
{
"creation": "2013-04-09 11:45:31.000000",
"docstatus": 0,
"doctype": "Page",
"icon": "icon-play",
"idx": 1,
"modified": "2013-07-11 14:40:20.000000",
"modified_by": "Administrator",
"module": "Home",
"name": "activity",
"owner": "Administrator",
"page_name": "activity",
"roles": [
{
"role": "All"
}
],
"standard": "Yes",
"title": "Activity"
}

View File

@ -1,12 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.utils import cint
@frappe.whitelist()
def get_feed(limit_start, limit_page_length):
"""get feed"""
return frappe.get_list("Feed", fields=["name", "feed_type", "doc_type", "subject", "owner", "modified"],
limit_start = limit_start, limit_page_length = limit_page_length)

View File

@ -4,7 +4,7 @@ app_publisher = "Web Notes Technologies Pvt. Ltd. and Contributors"
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
app_icon = "icon-th"
app_color = "#e74c3c"
app_version = "4.3.0"
app_version = "5.0.0-alpha"
error_report_email = "support@erpnext.com"
@ -20,32 +20,15 @@ notification_config = "erpnext.startup.notifications.get_notification_config"
dump_report_map = "erpnext.startup.report_data_map.data_map"
update_website_context = "erpnext.startup.webutils.update_website_context"
on_session_creation = "erpnext.startup.event_handlers.on_session_creation"
before_tests = "erpnext.setup.utils.before_tests"
website_generators = ["Item Group", "Item", "Sales Partner"]
standard_queries = "Customer:erpnext.selling.doctype.customer.customer.get_customer_list"
permission_query_conditions = {
"Feed": "erpnext.home.doctype.feed.feed.get_permission_query_conditions",
"Note": "erpnext.utilities.doctype.note.note.get_permission_query_conditions"
}
has_permission = {
"Feed": "erpnext.home.doctype.feed.feed.has_permission",
"Note": "erpnext.utilities.doctype.note.note.has_permission"
}
communication_covert_to = ["Lead", "Support Ticket", "Job Application"]
doc_events = {
"*": {
"on_update": "erpnext.home.update_feed",
"on_submit": "erpnext.home.update_feed"
},
"Comment": {
"on_update": "erpnext.home.make_comment_feed"
},
"Stock Entry": {
"on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_qty",
"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_qty"
@ -57,11 +40,6 @@ doc_events = {
}
scheduler_events = {
"all": [
"erpnext.support.doctype.support_ticket.get_support_mails.get_support_mails",
"erpnext.hr.doctype.job_applicant.get_job_applications.get_job_applications",
"erpnext.selling.doctype.lead.get_leads.get_leads"
],
"daily": [
"erpnext.controllers.recurring_document.create_recurring_documents",
"erpnext.stock.utils.reorder_item",
@ -76,3 +54,6 @@ scheduler_events = {
]
}
default_mail_footer = """<div style="padding: 7px; text-align: right; color: #888"><small>
<a style="color: #888" href="https://erpnext.com">Sent via ERPNext</a></div>"""

View File

@ -11,6 +11,10 @@ from erpnext.hr.utils import set_employee_name
class InvalidExpenseApproverError(frappe.ValidationError): pass
class ExpenseClaim(Document):
def get_feed(self):
return _("{0}: From {0} for {1}").format(self.approval_status,
self.employee_name, self.total_claimed_amount)
def validate(self):
self.validate_fiscal_year()
self.validate_exp_details()

View File

@ -1,47 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.utils import cstr, cint
from frappe.utils.email_lib.receive import POP3Mailbox
from frappe.core.doctype.communication.communication import _make
class JobsMailbox(POP3Mailbox):
def setup(self, args=None):
self.settings = args or frappe.get_doc("Jobs Email Settings", "Jobs Email Settings")
def process_message(self, mail):
if mail.from_email == self.settings.email_id:
return
name = frappe.db.get_value("Job Applicant", {"email_id": mail.from_email},
"name")
if name:
applicant = frappe.get_doc("Job Applicant", name)
if applicant.status!="Rejected":
applicant.status = "Open"
applicant.ignore_permissions = True
applicant.save()
else:
name = (mail.from_real_name and (mail.from_real_name + " - ") or "") \
+ mail.from_email
applicant = frappe.get_doc({
"creation": mail.date,
"doctype":"Job Applicant",
"applicant_name": name,
"email_id": mail.from_email,
"status": "Open"
})
applicant.ignore_permissions = True
applicant.ignore_mandatory = True
applicant.insert()
mail.save_attachments_in_doc(applicant)
_make(content=mail.content, sender=mail.from_email, subject=mail.subject or "No Subject",
doctype="Job Applicant", name=applicant.name, sent_or_received="Received")
def get_job_applications():
if cint(frappe.db.get_value('Jobs Email Settings', None, 'extract_emails')):
JobsMailbox()

View File

@ -3,16 +3,9 @@
// For license information, please see license.txt
// for communication
cur_frm.email_field = "email_id";
cur_frm.cscript = {
refresh: function(doc) {
cur_frm.cscript.make_listing(doc);
},
make_listing: function(doc) {
cur_frm.communication_view = new frappe.views.CommunicationList({
list: frappe.get_list("Communication", {"parent": doc.name, "parenttype": "Job Applicant"}),
parent: cur_frm.fields_dict['thread_html'].wrapper,
doc: doc,
recipients: doc.email_id
})
},
}

View File

@ -5,13 +5,9 @@
from __future__ import unicode_literals
import frappe
from erpnext.utilities.transaction_base import TransactionBase
from frappe.model.document import Document
from frappe.utils import extract_email_id
class JobApplicant(TransactionBase):
def get_sender(self, comm):
return frappe.db.get_value('Jobs Email Settings',None,'email_id') or comm.sender or frappe.session.user
class JobApplicant(Document):
def validate(self):
self.set_status()

View File

@ -17,6 +17,10 @@ class LeaveApproverIdentityError(frappe.ValidationError): pass
from frappe.model.document import Document
class LeaveApplication(Document):
def get_feed(self):
return _("{0}: From {0} of type {1}").format(self.status,
self.employee_name, self.leave_type)
def validate(self):
if not getattr(self, "__islocal", None) and frappe.db.exists(self.doctype, self.name):
self.previous_doc = frappe.db.get_value(self.doctype, self.name, "*", as_dict=True)
@ -212,7 +216,7 @@ class LeaveApplication(Document):
def notify(self, args):
args = frappe._dict(args)
from frappe.core.page.messages.messages import post
from frappe.desk.page.messages.messages import post
post(**{"txt": args.message, "contact": args.message_to, "subject": args.subject,
"notify": cint(self.follow_via_email)})
@ -249,7 +253,7 @@ def get_events(start, end):
employee, company = employee.name, employee.company
from frappe.widgets.reportview import build_match_conditions
from frappe.desk.reportview import build_match_conditions
match_conditions = build_match_conditions("Leave Application")
# show department leaves for employee

View File

@ -185,12 +185,10 @@ class SalarySlip(TransactionBase):
def send_mail_funct(self):
from frappe.utils.email_lib import sendmail
receiver = frappe.db.get_value("Employee", self.employee, "company_email")
if receiver:
subj = 'Salary Slip - ' + cstr(self.month) +'/'+cstr(self.fiscal_year)
sendmail([receiver], subject=subj, msg = _("Please see attachment"),
frappe.sendmail([receiver], subject=subj, msg = _("Please see attachment"),
attachments=[{
"fname": self.name + ".pdf",
"fcontent": frappe.get_print_format(self.doctype, self.name, as_pdf = True)

View File

@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.widgets.reportview import execute as runreport
from frappe.desk.reportview import execute as runreport
def execute(filters=None):
if not filters: filters = {}

View File

@ -1,6 +1,5 @@
Accounts
Buying
Home
HR
Manufacturing
Projects

View File

@ -7,7 +7,7 @@ import json
import re
from frappe.model.naming import make_autoname
from frappe.utils import cint
from frappe.utils.email_lib import sendmail_to_system_managers
from frappe.email import sendmail_to_system_managers
doctype_series_map = {
'Attendance': 'ATT-',

View File

@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
from frappe.core.doctype.custom_field.custom_field import create_custom_field_if_values_exist
from frappe.custom.doctype.custom_field.custom_field import create_custom_field_if_values_exist
def execute():
frappe.reload_doc("stock", "doctype", "purchase_receipt")

View File

@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
from frappe.country_info import get_all
from frappe.geo.country_info import get_all
from erpnext.setup.install import import_country_and_currency
def execute():

View File

@ -10,9 +10,9 @@ def execute():
"Comment", "Communication", "Company", "Contact Us Settings",
"Country", "Currency", "Currency Exchange", "Deduction Type", "Department",
"Designation", "Earning Type", "Event", "Feed", "File Data", "Fiscal Year",
"HR Settings", "Industry Type", "Jobs Email Settings", "Leave Type", "Letter Head",
"HR Settings", "Industry Type", "Leave Type", "Letter Head",
"Mode of Payment", "Module Def", "Naming Series", "POS Setting", "Print Heading",
"Report", "Role", "Sales Email Settings", "Selling Settings", "Stock Settings", "Supplier Type", "UOM"):
"Report", "Role", "Selling Settings", "Stock Settings", "Supplier Type", "UOM"):
try:
frappe.reset_perms(doctype)
except:

View File

@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe.core.doctype.property_setter.property_setter import make_property_setter
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
doctype_series_map = {
'Attendance': 'ATT-',

View File

@ -5,6 +5,16 @@ from __future__ import unicode_literals
import frappe
def execute():
print "WARNING!!!! Email Settings not migrated. Please setup your email again."
# this will happen if you are migrating very old accounts
# comment out this line below and remember to create new Email Accounts
# for incoming and outgoing mails
raise Exception
return
frappe.reload_doc("core", "doctype", "outgoing_email_settings")
frappe.reload_doc("support", "doctype", "support_email_settings")
@ -12,7 +22,6 @@ def execute():
map_outgoing_email_settings(email_settings)
map_support_email_settings(email_settings)
frappe.delete_doc("DocType", "Email Settings")
def map_outgoing_email_settings(email_settings):
outgoing_email_settings = frappe.get_doc("Outgoing Email Settings")

View File

@ -6,6 +6,7 @@ import frappe
from erpnext.setup.install import default_mail_footer
def execute():
return
mail_footer = frappe.db.get_default('mail_footer') or ''
mail_footer += default_mail_footer
frappe.db.set_value("Outgoing Email Settings", "Outgoing Email Settings", "footer", mail_footer)

View File

@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
from frappe.country_info import get_country_info
from frappe.geo.country_info import get_country_info
from erpnext.setup.install import add_country_and_currency
def execute():

View File

@ -0,0 +1,73 @@
import frappe
def execute():
frappe.reload_doc("email", "doctype", "email_account")
# outgoing
outgoing = frappe.get_doc("Outgoing Email Settings")
account = frappe.new_doc("Email Account")
mapping = {
"email_id": "mail_login",
"password": "mail_password",
"footer": "footer",
"smtp_server": "mail_server",
"smtp_port": "mail_port",
"use_tls": "use_ssl"
}
for target_fieldname, source_fieldname in mapping.iteritems():
account.set(target_fieldname, outgoing.get(source_fieldname))
account.enable_outgoing = 1
account.enable_incoming = 0
account.is_global = 1
account.insert()
# support
support = frappe.get_doc("Support Email Settings")
account = frappe.new_doc("Email Account")
mapping = {
"enable_incoming": "sync_support_mails",
"email_id": "mail_login",
"password": "mail_password",
"pop3_server": "mail_server",
"use_ssl": "use_ssl",
"signature": "support_signature",
"enable_auto_reply": "send_autoreply",
"auto_reply_message": "support_autoreply"
}
for target_fieldname, source_fieldname in mapping.iteritems():
account.set(target_fieldname, support.get(source_fieldname))
account.enable_outgoing = 0
account.is_global = 1
account.insert()
# sales, jobs
for doctype in ("Sales Email Settings", "Jobs Email Settings"):
source = frappe.get_doc(doctype)
account = frappe.new_doc("Email Account")
mapping = {
"enable_incoming": "extract_emails",
"email_id": "username",
"password": "password",
"pop3_server": "host",
"use_ssl": "use_ssl",
}
for target_fieldname, source_fieldname in mapping.iteritems():
account.set(target_fieldname, source.get(source_fieldname))
account.enable_outgoing = 0
account.is_global = 1
account.append_to = "Lead" if doctype=="Sales Email Settings" else "Job Applicant"
account.insert()
for doctype in ("Outgoing Email Settings", "Support Email Settings",
"Sales Email Settings", "Jobs Email Settings"):
frappe.delete_doc("DocType", doctype)

View File

@ -11,6 +11,8 @@ from erpnext.utilities.transaction_base import delete_events
from frappe.model.document import Document
class Project(Document):
def get_feed(self):
return self.status
def get_gross_profit(self):
pft, per_pft =0, 0

View File

@ -11,6 +11,9 @@ from frappe import _
from frappe.model.document import Document
class Task(Document):
def get_feed(self):
return '{0}: {1}'.format(_(self.status), self.subject)
def get_project_details(self):
return {
"project": self.project
@ -47,7 +50,7 @@ class Task(Document):
@frappe.whitelist()
def get_events(start, end, filters=None):
from frappe.widgets.reportview import build_match_conditions
from frappe.desk.reportview import build_match_conditions
if not frappe.has_permission("Task"):
frappe.msgprint(_("No Permission"), raise_exception=1)

View File

@ -61,7 +61,7 @@ class TimeLog(Document):
@frappe.whitelist()
def get_events(start, end):
from frappe.widgets.reportview import build_match_conditions
from frappe.desk.reportview import build_match_conditions
if not frappe.has_permission("Time Log"):
frappe.msgprint(_("No Permission"), raise_exception=1)

View File

@ -75,7 +75,7 @@ def build_conditions(filters):
if filters.get("to_date"):
conditions += " and to_time <= timestamp(%(to_date)s, %(to_time)s)"
from frappe.widgets.reportview import build_match_conditions
from frappe.desk.reportview import build_match_conditions
match_conditions = build_match_conditions("Time Log")
if match_conditions:
conditions += " and %s" % match_conditions

View File

@ -12,7 +12,7 @@ def get_time_log_list(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
def query_task(doctype, txt, searchfield, start, page_len, filters):
from frappe.widgets.reportview import build_match_conditions
from frappe.desk.reportview import build_match_conditions
search_string = "%%%s%%" % txt
order_by_string = "%s%%" % txt

View File

@ -34,11 +34,6 @@ cur_frm.cscript.refresh = function(doc, dt, dn) {
// make lists
cur_frm.cscript.make_address(doc, dt, dn);
cur_frm.cscript.make_contact(doc, dt, dn);
cur_frm.communication_view = new frappe.views.CommunicationList({
parent: cur_frm.fields_dict.communication_html.wrapper,
doc: doc,
});
}
}

View File

@ -129,22 +129,6 @@
"permlevel": 0,
"read_only": 1
},
{
"depends_on": "eval:!doc.__islocal",
"fieldname": "communication_history",
"fieldtype": "Section Break",
"label": "Communication History",
"options": "icon-comments",
"permlevel": 0,
"print_hide": 1
},
{
"fieldname": "communication_html",
"fieldtype": "HTML",
"label": "Communication HTML",
"permlevel": 0,
"print_hide": 1
},
{
"fieldname": "more_info",
"fieldtype": "Section Break",
@ -282,7 +266,7 @@
],
"icon": "icon-user",
"idx": 1,
"modified": "2014-09-10 16:41:07.553182",
"modified": "2014-09-12 12:26:47.480965",
"modified_by": "Administrator",
"module": "Selling",
"name": "Customer",

View File

@ -12,6 +12,8 @@ from erpnext.utilities.transaction_base import TransactionBase
from erpnext.accounts.party import create_party_account
class Customer(TransactionBase):
def get_feed(self):
return self.customer_name
def autoname(self):
cust_master_name = frappe.defaults.get_global_default('cust_master_name')

View File

@ -1,53 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.utils import cstr, cint
from frappe.utils.email_lib.receive import POP3Mailbox
from frappe.core.doctype.communication.communication import _make
def add_sales_communication(subject, content, sender, real_name, mail=None,
status="Open", date=None):
lead_name = frappe.db.get_value("Lead", {"email_id": sender})
contact_name = frappe.db.get_value("Contact", {"email_id": sender})
if not (lead_name or contact_name):
# none, create a new Lead
lead = frappe.get_doc({
"doctype":"Lead",
"lead_name": real_name or sender,
"email_id": sender,
"status": status,
"source": "Email"
})
lead.ignore_permissions = True
lead.ignore_mandatory = True
lead.insert()
lead_name = lead.name
parent_doctype = "Contact" if contact_name else "Lead"
parent_name = contact_name or lead_name
message = _make(content=content, sender=sender, subject=subject,
doctype = parent_doctype, name = parent_name, date=date, sent_or_received="Received")
if mail:
# save attachments to parent if from mail
doc = frappe.get_doc(parent_doctype, parent_name)
mail.save_attachments_in_doc(doc)
class SalesMailbox(POP3Mailbox):
def setup(self, args=None):
self.settings = args or frappe.get_doc("Sales Email Settings", "Sales Email Settings")
def process_message(self, mail):
if mail.from_email == self.settings.email_id:
return
add_sales_communication(mail.subject, mail.content, mail.from_email,
mail.from_real_name, mail=mail, date=mail.date)
def get_leads():
if cint(frappe.db.get_value('Sales Email Settings', None, 'extract_emails')):
SalesMailbox()

View File

@ -4,6 +4,8 @@
{% include 'setup/doctype/contact_control/contact_control.js' %};
frappe.provide("erpnext");
cur_frm.email_field = "email_id";
erpnext.LeadController = frappe.ui.form.Controller.extend({
setup: function() {
this.frm.fields_dict.customer.get_query = function(doc, cdt, cdn) {
@ -34,13 +36,6 @@ erpnext.LeadController = frappe.ui.form.Controller.extend({
this.frm.appframe.add_button(__("Send SMS"), this.frm.cscript.send_sms, "icon-mobile-phone");
}
cur_frm.communication_view = new frappe.views.CommunicationList({
list: frappe.get_list("Communication", {"parenttype": "Lead", "parent":this.frm.doc.name}),
parent: this.frm.fields_dict.communication_html.wrapper,
doc: this.frm.doc,
recipients: this.frm.doc.email_id
});
if(!this.frm.doc.__islocal) {
this.make_address_list();
}

View File

@ -58,11 +58,6 @@
"reqd": 0,
"search_index": 1
},
{
"fieldname": "cb6",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"default": "Lead",
"fieldname": "status",
@ -92,6 +87,12 @@
"reqd": 0,
"search_index": 0
},
{
"fieldname": "col_break123",
"fieldtype": "Column Break",
"permlevel": 0,
"width": "50%"
},
{
"depends_on": "eval:doc.source == 'Customer'",
"fieldname": "customer",
@ -115,14 +116,6 @@
"options": "Campaign",
"permlevel": 0
},
{
"fieldname": "communication_history",
"fieldtype": "Section Break",
"label": "Communication",
"options": "icon-comments",
"permlevel": 0,
"print_hide": 1
},
{
"default": "__user",
"fieldname": "lead_owner",
@ -135,12 +128,6 @@
"permlevel": 0,
"search_index": 1
},
{
"fieldname": "col_break123",
"fieldtype": "Column Break",
"permlevel": 0,
"width": "50%"
},
{
"allow_on_submit": 0,
"fieldname": "contact_by",
@ -170,21 +157,6 @@
"reqd": 0,
"width": "100px"
},
{
"fieldname": "sec_break123",
"fieldtype": "Section Break",
"options": "Simple",
"permlevel": 0
},
{
"allow_on_submit": 0,
"fieldname": "communication_html",
"fieldtype": "HTML",
"label": "Communication HTML",
"oldfieldname": "follow_up",
"oldfieldtype": "Table",
"permlevel": 0
},
{
"fieldname": "fold",
"fieldtype": "Fold",
@ -355,20 +327,11 @@
"fieldtype": "Check",
"label": "Blog Subscriber",
"permlevel": 0
},
{
"fieldname": "communications",
"fieldtype": "Table",
"hidden": 1,
"label": "Communications",
"options": "Communication",
"permlevel": 0,
"print_hide": 1
}
],
"icon": "icon-user",
"idx": 1,
"modified": "2014-08-12 05:22:18.801092",
"modified": "2014-09-11 18:52:50.397563",
"modified_by": "Administrator",
"module": "Selling",
"name": "Lead",
@ -376,6 +339,34 @@
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"match": "",
"permlevel": 1,
"read": 1,
"report": 1,
"role": "All",
"submit": 0,
"write": 0
},
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"submit": 0,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
@ -389,7 +380,7 @@
},
{
"amend": 0,
"apply_user_permissions": 1,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 1,
@ -397,9 +388,35 @@
"print": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"role": "System Manager",
"submit": 0,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"match": "",
"permlevel": 1,
"read": 1,
"report": 1,
"role": "Sales Manager",
"submit": 0,
"write": 0
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"match": "",
"permlevel": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"submit": 0,
"write": 0
}
],
"search_fields": "lead_name,lead_owner,status",

View File

@ -11,6 +11,9 @@ from frappe.model.mapper import get_mapped_doc
from erpnext.controllers.selling_controller import SellingController
class Lead(SellingController):
def get_feed(self):
return '{0}: {1}'.format(_(self.status), self.lead_name)
def onload(self):
customer = frappe.db.get_value("Customer", {"lead_name": self.name})
self.get("__onload").is_customer = customer

View File

@ -8,6 +8,8 @@ frappe.ui.form.on_change("Opportunity", "contact_person", erpnext.utils.get_cont
frappe.provide("erpnext.selling");
cur_frm.email_field = "contact_email";
// TODO commonify this code
erpnext.selling.Opportunity = frappe.ui.form.Controller.extend({
onload: function() {
@ -26,15 +28,6 @@ erpnext.selling.Opportunity = frappe.ui.form.Controller.extend({
set_multiple(cdt, cdn, { fiscal_year:sys_defaults.fiscal_year });
if(!this.frm.doc.__islocal) {
cur_frm.communication_view = new frappe.views.CommunicationList({
list: frappe.get_list("Communication", {"parent": this.frm.doc.name, "parenttype": "Opportunity"}),
parent: cur_frm.fields_dict.communication_html.wrapper,
doc: this.frm.doc,
recipients: this.frm.doc.contact_email
});
}
if(this.frm.doc.customer && !this.frm.doc.customer_name) cur_frm.cscript.customer(this.frm.doc);
this.setup_queries();

View File

@ -134,26 +134,6 @@
"permlevel": 0,
"read_only": 0
},
{
"description": "Keep a track of communication related to this enquiry which will help for future reference.",
"fieldname": "communication_history",
"fieldtype": "Section Break",
"label": "Communication History",
"oldfieldtype": "Section Break",
"options": "icon-comments",
"permlevel": 0,
"read_only": 0
},
{
"allow_on_submit": 1,
"fieldname": "communication_html",
"fieldtype": "HTML",
"label": "Communication HTML",
"oldfieldname": "follow_up",
"oldfieldtype": "Table",
"permlevel": 0,
"read_only": 0
},
{
"fieldname": "fold",
"fieldtype": "Fold",
@ -402,21 +382,12 @@
"print_hide": 1,
"read_only": 1,
"width": "150px"
},
{
"fieldname": "communications",
"fieldtype": "Table",
"hidden": 1,
"label": "Communications",
"options": "Communication",
"permlevel": 0,
"print_hide": 1
}
],
"icon": "icon-info-sign",
"idx": 1,
"is_submittable": 1,
"modified": "2014-08-12 05:21:51.282397",
"modified": "2014-09-11 18:53:14.037512",
"modified_by": "Administrator",
"module": "Selling",
"name": "Opportunity",
@ -424,7 +395,6 @@
"permissions": [
{
"amend": 1,
"apply_user_permissions": 1,
"cancel": 1,
"create": 1,
"delete": 1,

View File

@ -53,15 +53,6 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
}, "icon-download", "btn-default");
}
if (!doc.__islocal) {
cur_frm.communication_view = new frappe.views.CommunicationList({
list: frappe.get_list("Communication", {"parent": doc.name, "parenttype": "Quotation"}),
parent: cur_frm.fields_dict.communication_html.wrapper,
doc: doc,
recipients: doc.contact_email
});
}
this.toggle_reqd_lead_customer();
},

View File

@ -793,38 +793,6 @@
"print_hide": 1,
"read_only": 1,
"report_hide": 0
},
{
"fieldname": "communication_history",
"fieldtype": "Section Break",
"label": "Communication History",
"oldfieldtype": "Section Break",
"options": "icon-comments",
"permlevel": 0,
"print_hide": 1,
"read_only": 0
},
{
"allow_on_submit": 1,
"depends_on": "eval:!doc.__islocal",
"fieldname": "communication_html",
"fieldtype": "HTML",
"label": "Communication HTML",
"oldfieldname": "follow_up",
"oldfieldtype": "Table",
"permlevel": 0,
"print_hide": 1,
"read_only": 0,
"width": "40px"
},
{
"fieldname": "communications",
"fieldtype": "Table",
"hidden": 1,
"label": "Communications",
"options": "Communication",
"permlevel": 0,
"print_hide": 1
}
],
"hide_toolbar": 0,
@ -832,7 +800,7 @@
"idx": 1,
"is_submittable": 1,
"max_attachments": 1,
"modified": "2014-09-09 05:35:33.413559",
"modified": "2014-09-11 18:53:08.594908",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation",
@ -848,13 +816,49 @@
"print": 1,
"read": 1,
"report": 1,
"role": "Sales Manager",
"role": "Sales User",
"submit": 1,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"match": "",
"permlevel": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"submit": 0,
"write": 0
},
{
"cancel": 0,
"delete": 0,
"email": 1,
"match": "",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Customer"
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"match": "",
"permlevel": 1,
"read": 1,
"report": 1,
"role": "Sales Manager",
"submit": 0,
"write": 0
},
{
"amend": 1,
"apply_user_permissions": 1,
"cancel": 1,
"create": 1,
"delete": 1,
@ -863,25 +867,10 @@
"print": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"role": "Sales Manager",
"submit": 1,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Customer",
"submit": 0,
"write": 0
},
{
"amend": 1,
"cancel": 1,
@ -896,9 +885,20 @@
"submit": 1,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"match": "",
"permlevel": 1,
"read": 1,
"report": 1,
"role": "Maintenance Manager",
"submit": 0
},
{
"amend": 1,
"apply_user_permissions": 1,
"cancel": 1,
"create": 1,
"delete": 1,
@ -912,10 +912,16 @@
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"match": "",
"permlevel": 1,
"read": 1,
"role": "Sales Manager",
"write": 1
"report": 1,
"role": "Maintenance User",
"submit": 0
}
],
"read_only_onload": 1,

View File

@ -13,6 +13,8 @@ frappe.require("assets/erpnext/js/transaction.js");
{% include "public/js/controllers/accounts.js" %}
cur_frm.email_field = "contact_email";
erpnext.selling.SellingController = erpnext.TransactionController.extend({
onload: function() {
this._super();

View File

@ -10,8 +10,8 @@ $.extend(cur_frm.cscript, {
cur_frm.set_intro(__("You can start by selecting backup frequency and granting access for sync"));
} else {
var services = {
"dropbox": __("Dropbox"),
"gdrive": __("Google Drive")
"dropbox": __("Dropbox")
// "gdrive": __("Google Drive")
}
var active_services = [];

View File

@ -57,7 +57,6 @@ def take_backups_gdrive():
send_email(False, "Google Drive", error_message)
def send_email(success, service_name, error_status=None):
from frappe.utils.email_lib import sendmail
if success:
subject = "Backup Upload Successful"
message ="""<h3>Backup Uploaded Successfully</h3><p>Hi there, this is just to inform you
@ -76,4 +75,4 @@ def send_email(success, service_name, error_status=None):
frappe.connect()
recipients = frappe.db.get_value("Backup Manager", None, "send_notifications_to").split(",")
sendmail(recipients, subject=subject, msg=message)
frappe.sendmail(recipients=recipients, subject=subject, msg=message)

View File

@ -1 +0,0 @@
Country Master.

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1,107 +0,0 @@
{
"allow_import": 1,
"autoname": "field:country_name",
"creation": "2013-01-19 10:23:30",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Master",
"fields": [
{
"fieldname": "country_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Country Name",
"oldfieldname": "country_name",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 1
},
{
"fieldname": "date_format",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Date Format",
"permlevel": 0
},
{
"fieldname": "time_zones",
"fieldtype": "Text",
"in_list_view": 1,
"label": "Time Zones",
"permlevel": 0
},
{
"fieldname": "code",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Code",
"permlevel": 0
}
],
"icon": "icon-globe",
"idx": 1,
"in_create": 0,
"modified": "2014-05-27 03:49:08.984710",
"modified_by": "Administrator",
"module": "Setup",
"name": "Country",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"create": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales Master Manager",
"submit": 0,
"write": 1
},
{
"create": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Purchase Master Manager",
"submit": 0,
"write": 1
},
{
"apply_user_permissions": 1,
"create": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "HR User",
"submit": 0,
"write": 1
},
{
"create": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "HR Manager",
"submit": 0,
"write": 1
},
{
"apply_user_permissions": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "All"
}
],
"read_only": 0
}

View File

@ -1,10 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class Country(Document):
pass

View File

@ -1,6 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import frappe
test_records = frappe.get_test_records('Country')

View File

@ -1,6 +0,0 @@
[
{
"country_name": "_Test Country",
"doctype": "Country"
}
]

View File

@ -1 +0,0 @@
Currency Master with details about abbreviation, symbol etc.

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1,9 +0,0 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
cur_frm.cscript.refresh = function(doc) {
cur_frm.set_intro("");
if(!cur_frm.doc.enabled) {
cur_frm.set_intro(__("This Currency is disabled. Enable to use in transactions"))
}
}

View File

@ -1,117 +0,0 @@
{
"autoname": "field:currency_name",
"creation": "2013-01-28 10:06:02",
"description": "**Currency** Master",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "currency_name",
"fieldtype": "Data",
"label": "Currency Name",
"oldfieldname": "currency_name",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 1
},
{
"fieldname": "enabled",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Enabled",
"permlevel": 0
},
{
"description": "Sub-currency. For e.g. \"Cent\"",
"fieldname": "fraction",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Fraction",
"permlevel": 0
},
{
"description": "1 Currency = [?] Fraction\nFor e.g. 1 USD = 100 Cent",
"fieldname": "fraction_units",
"fieldtype": "Int",
"in_list_view": 1,
"label": "Fraction Units",
"permlevel": 0
},
{
"description": "A symbol for this currency. For e.g. $",
"fieldname": "symbol",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Symbol",
"permlevel": 0
},
{
"description": "How should this currency be formatted? If not set, will use system defaults",
"fieldname": "number_format",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Number Format",
"options": "\n#,###.##\n#.###,##\n# ###.##\n# ###,##\n#'###.##\n#, ###.##\n#,##,###.##\n#,###.###\n#.###\n#,###",
"permlevel": 0
}
],
"icon": "icon-bitcoin",
"idx": 1,
"in_create": 0,
"modified": "2014-06-18 03:49:09.038451",
"modified_by": "Administrator",
"module": "Setup",
"name": "Currency",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"submit": 0,
"write": 1
},
{
"amend": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales Master Manager",
"submit": 0,
"write": 1
},
{
"amend": 0,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Purchase Master Manager",
"submit": 0,
"write": 1
},
{
"apply_user_permissions": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "All"
}
],
"read_only": 0
}

View File

@ -1,21 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe import throw, _
from frappe.model.document import Document
class Currency(Document):
def validate(self):
frappe.clear_cache()
def validate_conversion_rate(currency, conversion_rate, conversion_rate_label, company):
"""common validation for currency and price list currency"""
company_currency = frappe.db.get_value("Company", company, "default_currency")
if not conversion_rate:
throw(_("{0} is mandatory. Maybe Currency Exchange record is not created for {1} to {2}.").format(
conversion_rate_label, currency, company_currency))

View File

@ -1,7 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
# pre loaded
import frappe
test_records = frappe.get_test_records('Currency')

View File

@ -9,7 +9,6 @@ from frappe.utils import fmt_money, formatdate, now_datetime, cstr, esc, \
from frappe.utils.dateutils import datetime_in_user_format
from datetime import timedelta
from dateutil.relativedelta import relativedelta
from frappe.utils.email_lib import sendmail
from frappe.core.doctype.user.user import STANDARD_USERS
content_sequence = [
@ -83,10 +82,10 @@ class EmailDigest(Document):
msg_for_this_receipient = self.get_msg_html(self.get_user_specific_content(user_id) + \
common_msg)
if msg_for_this_receipient:
sendmail(recipients=user_id,
frappe.sendmail(recipients=user_id,
subject="[ERPNext] [{frequency} Digest] {name}".format(
frequency=self.frequency, name=self.name),
msg=msg_for_this_receipient)
msg=msg_for_this_receipient, bulk=True)
def get_digest_msg(self):
return self.get_msg_html(self.get_user_specific_content(frappe.session.user) + \
@ -295,7 +294,7 @@ class EmailDigest(Document):
filter_by_company=False)
def get_calendar_events(self, user_id):
from frappe.core.doctype.event.event import get_events
from frappe.desk.doctype.event.event import get_events
events = get_events(self.future_from_date.strftime("%Y-%m-%d"), self.future_to_date.strftime("%Y-%m-%d"))
html = ""

View File

@ -6,7 +6,7 @@ from __future__ import unicode_literals
import frappe
import frappe.defaults
from frappe.utils import cint
from frappe.core.doctype.property_setter.property_setter import make_property_setter
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
keydict = {
# "key in defaults": "key in Global Defaults"

View File

@ -1 +0,0 @@
Settings to extract job applications via email (POP).

View File

@ -1,15 +0,0 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
// For license information, please see license.txt
cur_frm.cscript = {
refresh: function(doc) {
cur_frm.set_intro("");
if(doc.extract_emails) {
cur_frm.set_intro(__("Active: Will extract emails from ") + doc.email_id);
} else {
cur_frm.set_intro(__("Not Active"));
}
}
}

View File

@ -1,73 +0,0 @@
{
"creation": "2013-01-15 16:50:01.000000",
"description": "Email settings for jobs email id \"jobs@example.com\"",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"description": "Settings to extract Job Applicants from a mailbox e.g. \"jobs@example.com\"",
"fieldname": "pop3_mail_settings",
"fieldtype": "Section Break",
"label": "POP3 Mail Settings",
"permlevel": 0
},
{
"description": "Check to activate",
"fieldname": "extract_emails",
"fieldtype": "Check",
"label": "Extract Emails",
"permlevel": 0
},
{
"description": "Email Id where a job applicant will email e.g. \"jobs@example.com\"",
"fieldname": "email_id",
"fieldtype": "Data",
"label": "Email Id",
"permlevel": 0
},
{
"description": "POP3 server e.g. (pop.gmail.com)",
"fieldname": "host",
"fieldtype": "Data",
"label": "Host",
"permlevel": 0
},
{
"fieldname": "use_ssl",
"fieldtype": "Check",
"label": "Use SSL",
"permlevel": 0
},
{
"fieldname": "username",
"fieldtype": "Data",
"label": "Username",
"permlevel": 0
},
{
"fieldname": "password",
"fieldtype": "Password",
"label": "Password",
"permlevel": 0
}
],
"icon": "icon-cog",
"idx": 1,
"issingle": 1,
"modified": "2013-12-20 19:23:16.000000",
"modified_by": "Administrator",
"module": "Setup",
"name": "Jobs Email Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"role": "System Manager",
"write": 1
}
]
}

View File

@ -1,19 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import cint
from frappe.model.document import Document
class JobsEmailSettings(Document):
def validate(self):
if cint(self.extract_emails) and not (self.email_id and self.host and \
self.username and self.password):
frappe.throw(_("""Host, Email and Password required if emails are to be pulled"""))

View File

@ -12,15 +12,27 @@ from frappe.model.document import Document
class NamingSeries(Document):
def get_transactions(self, arg=None):
return {
"transactions": "\n".join([''] + sorted(list(set(
frappe.db.sql_list("""select parent
doctypes = list(set(frappe.db.sql_list("""select parent
from `tabDocField` where fieldname='naming_series'""")
+ frappe.db.sql_list("""select dt from `tabCustom Field`
where fieldname='naming_series'""")
)))),
"prefixes": "\n".join([''] + [i[0] for i in
frappe.db.sql("""select name from tabSeries order by name""")])
where fieldname='naming_series'""")))
prefixes = ""
for d in doctypes:
print d
try:
options = self.get_options(d)
except frappe.DoesNotExistError:
continue
prefixes = prefixes + "\n" + options
prefixes.replace("\n\n", "\n")
prefixes = "\n".join(sorted(prefixes.split()))
return {
"transactions": "\n".join([''] + sorted(doctypes)),
"prefixes": prefixes
}
def scrub_options_list(self, ol):
@ -110,8 +122,8 @@ class NamingSeries(Document):
if not re.match("^[a-zA-Z0-9- /.#]*$", n):
throw(_('Special Characters except "-" and "/" not allowed in naming series'))
def get_options(self, arg=''):
return frappe.get_meta(self.select_doc_for_series).get_field("naming_series").options
def get_options(self, arg=None):
return frappe.get_meta(arg or self.select_doc_for_series).get_field("naming_series").options
def get_current(self, arg=None):
"""get series current"""
@ -135,7 +147,7 @@ class NamingSeries(Document):
msgprint(_("Please select prefix first"))
def set_by_naming_series(doctype, fieldname, naming_series, hide_name_field=True):
from frappe.core.doctype.property_setter.property_setter import make_property_setter
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
if naming_series:
make_property_setter(doctype, "naming_series", "hidden", 0, "Check")
make_property_setter(doctype, "naming_series", "reqd", 1, "Check")

View File

@ -1 +0,0 @@
Settings for creating new Communication, Leads from sales inbox like "sales@example.com" via POP3.

View File

@ -1,15 +0,0 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
// For license information, please see license.txt
cur_frm.cscript = {
refresh: function(doc) {
cur_frm.set_intro("");
if(doc.extract_emails) {
cur_frm.set_intro(__("Active: Will extract emails from ") + doc.email_id);
} else {
cur_frm.set_intro(__("Not Active"));
}
}
}

View File

@ -1,73 +0,0 @@
{
"creation": "2013-01-16 10:25:26.000000",
"description": "Email settings to extract Leads from sales email id e.g. \"sales@example.com\"",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"description": "Email settings to extract Leads from sales email id e.g. \"sales@example.com\"",
"fieldname": "pop3_mail_settings",
"fieldtype": "Section Break",
"label": "POP3 Mail Settings",
"permlevel": 0
},
{
"description": "Check to activate",
"fieldname": "extract_emails",
"fieldtype": "Check",
"label": "Extract Emails",
"permlevel": 0
},
{
"description": "Email Id where a job applicant will email e.g. \"jobs@example.com\"",
"fieldname": "email_id",
"fieldtype": "Data",
"label": "Email Id",
"permlevel": 0
},
{
"description": "POP3 server e.g. (pop.gmail.com)",
"fieldname": "host",
"fieldtype": "Data",
"label": "Host",
"permlevel": 0
},
{
"fieldname": "use_ssl",
"fieldtype": "Check",
"label": "Use SSL",
"permlevel": 0
},
{
"fieldname": "username",
"fieldtype": "Data",
"label": "Username",
"permlevel": 0
},
{
"fieldname": "password",
"fieldtype": "Password",
"label": "Password",
"permlevel": 0
}
],
"icon": "icon-cog",
"idx": 1,
"issingle": 1,
"modified": "2013-12-20 19:21:38.000000",
"modified_by": "Administrator",
"module": "Setup",
"name": "Sales Email Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"role": "System Manager",
"write": 1
}
]
}

View File

@ -1,20 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import cint
from frappe.model.document import Document
class SalesEmailSettings(Document):
def validate(self):
if cint(self.extract_emails) and not (self.email_id and self.host and \
self.username and self.password):
frappe.msgprint(_("""Host, Email and Password required if emails are to be pulled"""),
raise_exception=True)

View File

@ -13,7 +13,6 @@ default_mail_footer = """<div style="padding: 7px; text-align: right; color: #88
def after_install():
frappe.get_doc({'doctype': "Role", "role_name": "Analytics"}).insert()
set_single_defaults()
import_country_and_currency()
from erpnext.accounts.doctype.chart_of_accounts.import_charts import import_charts
import_charts()
frappe.db.set_default('desktop:home_page', 'setup-wizard')
@ -22,38 +21,6 @@ def after_install():
add_all_roles_to("Administrator")
frappe.db.commit()
def import_country_and_currency():
from frappe.country_info import get_all
data = get_all()
for name in data:
country = frappe._dict(data[name])
add_country_and_currency(name, country)
# enable frequently used currencies
for currency in ("INR", "USD", "GBP", "EUR", "AED", "AUD", "JPY", "CNY", "CHF"):
frappe.db.set_value("Currency", currency, "enabled", 1)
def add_country_and_currency(name, country):
if not frappe.db.exists("Country", name):
frappe.get_doc({
"doctype": "Country",
"country_name": name,
"code": country.code,
"date_format": country.date_format or "dd-mm-yyyy",
"time_zones": "\n".join(country.timezones or [])
}).insert()
if country.currency and not frappe.db.exists("Currency", country.currency):
frappe.get_doc({
"doctype": "Currency",
"currency_name": country.currency,
"fraction": country.currency_fraction,
"symbol": country.currency_symbol,
"fraction_units": country.currency_fraction_units,
"number_format": country.number_format
}).insert()
def feature_setup():
"""save global defaults and features setup"""
doc = frappe.get_doc("Features Setup", "Features Setup")
@ -85,6 +52,3 @@ def set_single_defaults():
pass
frappe.db.set_default("date_format", "dd-mm-yyyy")
frappe.db.set_value("Outgoing Email Settings", "Outgoing Email Settings", "footer",
default_mail_footer)

View File

@ -8,7 +8,7 @@ from frappe.utils import cstr, flt, getdate
from frappe import _
from frappe.utils.file_manager import save_file
from frappe.translate import set_default_language, get_dict, get_lang_dict, send_translations
from frappe.country_info import get_country_info
from frappe.geo.country_info import get_country_info
from frappe.utils.nestedset import get_root_of
from default_website import website_maker
import install_fixtures
@ -227,9 +227,11 @@ def set_defaults(args):
def create_feed_and_todo():
"""update activty feed and create todo for creation of item, customer, vendor"""
from erpnext.home import make_feed
make_feed('Comment', 'ToDo', '', frappe.session['user'],
'ERNext Setup Complete!', '#6B24B3')
frappe.get_doc({
"doctype": "Feed",
"feedtype": "Comment",
"subject": "ERPNext Setup Complete!"
}).insert(ignore_permissions=True)
def create_email_digest():
from frappe.utils.user import get_system_managers

View File

@ -1,17 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt"
from __future__ import unicode_literals
import frappe
from frappe.utils import nowtime
from frappe.utils.user import get_user_fullname
from erpnext.home import make_feed
def on_session_creation(login_manager):
"""make feed"""
if frappe.session['user'] != 'Guest':
# create feed
make_feed('Login', 'User', login_manager.user, login_manager.user,
'%s logged in at %s' % (get_user_fullname(login_manager.user), nowtime()),
login_manager.user=='Administrator' and '#8CA2B3' or '#1B750D')

Some files were not shown because too many files have changed in this diff Show More