Removed controller.py
This commit is contained in:
parent
424c033395
commit
21ae930b4c
@ -6,9 +6,9 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.controller import DocListController
|
||||
from frappe.model.document import Document
|
||||
|
||||
class CurrencyExchange(DocListController):
|
||||
class CurrencyExchange(Document):
|
||||
|
||||
def autoname(self):
|
||||
self.name = self.from_currency + "-" + self.to_currency
|
||||
|
@ -18,9 +18,9 @@ content_sequence = [
|
||||
["Receivables / Payables", ["collections", "payments",
|
||||
"invoiced_amount", "payables"]],
|
||||
["Buying", ["new_purchase_requests", "new_supplier_quotations", "new_purchase_orders"]],
|
||||
["Selling", ["new_leads", "new_enquiries", "new_quotations", "new_sales_orders"]],
|
||||
["Stock", ["new_delivery_notes", "new_purchase_receipts", "new_stock_entries"]],
|
||||
["Support", ["new_communications", "new_support_tickets", "open_tickets"]],
|
||||
["Selling", ["new_leads", "new_enquiries", "new_quotations", "new_sales_orders"]],
|
||||
["Stock", ["new_delivery_notes", "new_purchase_receipts", "new_stock_entries"]],
|
||||
["Support", ["new_communications", "new_support_tickets", "open_tickets"]],
|
||||
["Projects", ["new_projects"]],
|
||||
["System", ["scheduler_errors"]],
|
||||
]
|
||||
@ -35,17 +35,17 @@ digest_template = """<style>p.ed-indent { margin-right: 17px; }</style>
|
||||
%(with_value)s
|
||||
%(no_value)s
|
||||
<hr>
|
||||
<p style="color: #888; font-size: 90%%">To change what you see here,
|
||||
<p style="color: #888; font-size: 90%%">To change what you see here,
|
||||
create more digests, go to Setup > Email Digest</p>"""
|
||||
|
||||
row_template = """<p style="%(style)s">
|
||||
<span>%(label)s</span>:
|
||||
<span>%(label)s</span>:
|
||||
<span style="font-weight: bold; font-size: 110%%">
|
||||
<span style="color: grey">%(currency)s</span>%(value)s
|
||||
</span></p>"""
|
||||
|
||||
from frappe.model.controller import DocListController
|
||||
class EmailDigest(DocListController):
|
||||
from frappe.model.document import Document
|
||||
class EmailDigest(Document):
|
||||
def __init__(self, arg1, arg2=None):
|
||||
super(EmailDigest, self).__init__(arg1, arg2)
|
||||
self.from_date, self.to_date = self.get_from_to_date()
|
||||
@ -69,29 +69,29 @@ class EmailDigest(DocListController):
|
||||
p["checked"] = p["name"] in recipient_list and 1 or 0
|
||||
|
||||
frappe.response['user_list'] = user_list
|
||||
|
||||
|
||||
def send(self):
|
||||
# send email only to enabled users
|
||||
valid_users = [p[0] for p in frappe.db.sql("""select name from `tabUser`
|
||||
where enabled=1""")]
|
||||
recipients = filter(lambda r: r in valid_users,
|
||||
self.recipient_list.split("\n"))
|
||||
|
||||
|
||||
common_msg = self.get_common_content()
|
||||
if recipients:
|
||||
for user_id in recipients:
|
||||
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,
|
||||
sendmail(recipients=user_id,
|
||||
subject="[ERPNext] [{frequency} Digest] {name}".format(
|
||||
frequency=self.frequency, name=self.name),
|
||||
frequency=self.frequency, name=self.name),
|
||||
msg=msg_for_this_receipient)
|
||||
|
||||
|
||||
def get_digest_msg(self):
|
||||
return self.get_msg_html(self.get_user_specific_content(frappe.session.user) + \
|
||||
self.get_common_content(), send_only_if_updates=False)
|
||||
|
||||
|
||||
def get_common_content(self):
|
||||
out = []
|
||||
for module, content in content_sequence:
|
||||
@ -103,45 +103,45 @@ class EmailDigest(DocListController):
|
||||
out += [[1, "<h4>" + _(module) + "</h4>"]] + module_out + [[1, "<hr>"]]
|
||||
else:
|
||||
out += module_out
|
||||
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def get_user_specific_content(self, user_id):
|
||||
original_session_user = frappe.session.user
|
||||
|
||||
|
||||
# setting session user for role base event fetching
|
||||
frappe.session.user = user_id
|
||||
|
||||
|
||||
out = []
|
||||
for ctype in user_specific_content:
|
||||
if self.get(ctype) and hasattr(self, "get_"+ctype):
|
||||
out.append(getattr(self, "get_"+ctype)(user_id))
|
||||
|
||||
|
||||
frappe.session.user = original_session_user
|
||||
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def get_msg_html(self, out, send_only_if_updates=True):
|
||||
with_value = [o[1] for o in out if o[0]]
|
||||
|
||||
|
||||
if with_value:
|
||||
has_updates = True
|
||||
with_value = "\n".join(with_value)
|
||||
else:
|
||||
has_updates = False
|
||||
with_value = "<p>There were no updates in the items selected for this digest.</p><hr>"
|
||||
|
||||
|
||||
if not has_updates and send_only_if_updates:
|
||||
return
|
||||
|
||||
|
||||
# seperate out no value items
|
||||
no_value = [o[1] for o in out if not o[0]]
|
||||
if no_value:
|
||||
no_value = """<h4>No Updates For:</h4>""" + "\n".join(no_value)
|
||||
|
||||
|
||||
date = self.frequency == "Daily" and formatdate(self.from_date) or \
|
||||
"%s to %s" % (formatdate(self.from_date), formatdate(self.to_date))
|
||||
|
||||
|
||||
msg = digest_template % {
|
||||
"digest": self.frequency + " Digest",
|
||||
"date": date,
|
||||
@ -150,23 +150,23 @@ class EmailDigest(DocListController):
|
||||
"no_value": no_value or "",
|
||||
"name": self.name
|
||||
}
|
||||
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
def get_income_year_to_date(self):
|
||||
return self.get_income(frappe.db.get_defaults("year_start_date"),
|
||||
return self.get_income(frappe.db.get_defaults("year_start_date"),
|
||||
self.meta.get_label("income_year_to_date"))
|
||||
|
||||
|
||||
def get_bank_balance(self):
|
||||
# account is of type "Bank" or "Cash"
|
||||
accounts = dict([[a["name"], [a["account_name"], 0]] for a in self.get_accounts()
|
||||
if a["account_type"] in ["Bank", "Cash"]])
|
||||
ackeys = accounts.keys()
|
||||
|
||||
|
||||
for gle in self.get_gl_entries(None, self.to_date):
|
||||
if gle["account"] in ackeys:
|
||||
accounts[gle["account"]][1] += gle["debit"] - gle["credit"]
|
||||
|
||||
|
||||
# build html
|
||||
out = self.get_html("Bank/Cash Balance", "", "")
|
||||
for ac in ackeys:
|
||||
@ -174,37 +174,37 @@ class EmailDigest(DocListController):
|
||||
out += "\n" + self.get_html(accounts[ac][0], self.currency,
|
||||
fmt_money(accounts[ac][1]), style="margin-left: 17px")
|
||||
return sum((accounts[ac][1] for ac in ackeys)), out
|
||||
|
||||
|
||||
def get_income(self, from_date=None, label=None):
|
||||
# account is PL Account and Credit type account
|
||||
accounts = [a["name"] for a in self.get_accounts() if a["root_type"]=="Income"]
|
||||
|
||||
|
||||
income = 0
|
||||
for gle in self.get_gl_entries(from_date or self.from_date, self.to_date):
|
||||
if gle["account"] in accounts:
|
||||
income += gle["credit"] - gle["debit"]
|
||||
|
||||
|
||||
return income, self.get_html(label or self.meta.get_label("income"), self.currency,
|
||||
fmt_money(income))
|
||||
|
||||
|
||||
def get_expenses_booked(self):
|
||||
# account is PL Account and Debit type account
|
||||
accounts = [a["name"] for a in self.get_accounts() if a["root_type"]=="Expense"]
|
||||
|
||||
|
||||
expense = 0
|
||||
for gle in self.get_gl_entries(self.from_date, self.to_date):
|
||||
if gle["account"] in accounts:
|
||||
expense += gle["debit"] - gle["credit"]
|
||||
|
||||
|
||||
return expense, self.get_html(self.meta.get_label("expenses_booked"), self.currency,
|
||||
fmt_money(expense))
|
||||
|
||||
|
||||
def get_collections(self):
|
||||
return self.get_party_total("Customer", "credit", self.meta.get_label("collections"))
|
||||
|
||||
|
||||
def get_payments(self):
|
||||
return self.get_party_total("Supplier", "debit", self.meta.get_label("payments"))
|
||||
|
||||
|
||||
def get_party_total(self, party_type, gle_field, label):
|
||||
import re
|
||||
# account is of master_type Customer or Supplier
|
||||
@ -212,10 +212,10 @@ class EmailDigest(DocListController):
|
||||
if a["master_type"]==party_type]
|
||||
|
||||
# account is "Bank" or "Cash"
|
||||
bc_accounts = [esc(a["name"], "()|") for a in self.get_accounts()
|
||||
bc_accounts = [esc(a["name"], "()|") for a in self.get_accounts()
|
||||
if a["account_type"] in ["Bank", "Cash"]]
|
||||
bc_regex = re.compile("""(%s)""" % "|".join(bc_accounts))
|
||||
|
||||
|
||||
total = 0
|
||||
for gle in self.get_gl_entries(self.from_date, self.to_date):
|
||||
# check that its made against a bank or cash account
|
||||
@ -223,78 +223,78 @@ class EmailDigest(DocListController):
|
||||
bc_regex.findall(gle["against"]):
|
||||
val = gle["debit"] - gle["credit"]
|
||||
total += (gle_field=="debit" and 1 or -1) * val
|
||||
|
||||
|
||||
return total, self.get_html(label, self.currency, fmt_money(total))
|
||||
|
||||
|
||||
def get_invoiced_amount(self):
|
||||
# aka receivables
|
||||
return self.get_booked_total("Customer", "debit", self.meta.get_label("invoiced_amount"))
|
||||
|
||||
def get_payables(self):
|
||||
return self.get_booked_total("Supplier", "credit", self.meta.get_label("payables"))
|
||||
|
||||
|
||||
def get_booked_total(self, party_type, gle_field, label):
|
||||
# account is of master_type Customer or Supplier
|
||||
accounts = [a["name"] for a in self.get_accounts()
|
||||
if a["master_type"]==party_type]
|
||||
|
||||
|
||||
total = 0
|
||||
for gle in self.get_gl_entries(self.from_date, self.to_date):
|
||||
if gle["account"] in accounts:
|
||||
total += gle[gle_field]
|
||||
|
||||
return total, self.get_html(label, self.currency, fmt_money(total))
|
||||
|
||||
|
||||
def get_new_leads(self):
|
||||
return self.get_new_count("Lead", self.meta.get_label("new_leads"))
|
||||
|
||||
|
||||
def get_new_enquiries(self):
|
||||
return self.get_new_count("Opportunity", self.meta.get_label("new_enquiries"), docstatus=1)
|
||||
|
||||
|
||||
def get_new_quotations(self):
|
||||
return self.get_new_sum("Quotation", self.meta.get_label("new_quotations"), "grand_total")
|
||||
|
||||
|
||||
def get_new_sales_orders(self):
|
||||
return self.get_new_sum("Sales Order", self.meta.get_label("new_sales_orders"), "grand_total")
|
||||
|
||||
|
||||
def get_new_delivery_notes(self):
|
||||
return self.get_new_sum("Delivery Note", self.meta.get_label("new_delivery_notes"), "grand_total")
|
||||
|
||||
|
||||
def get_new_purchase_requests(self):
|
||||
return self.get_new_count("Material Request",
|
||||
self.meta.get_label("new_purchase_requests"), docstatus=1)
|
||||
|
||||
|
||||
def get_new_supplier_quotations(self):
|
||||
return self.get_new_sum("Supplier Quotation", self.meta.get_label("new_supplier_quotations"),
|
||||
"grand_total")
|
||||
|
||||
|
||||
def get_new_purchase_orders(self):
|
||||
return self.get_new_sum("Purchase Order", self.meta.get_label("new_purchase_orders"),
|
||||
"grand_total")
|
||||
|
||||
|
||||
def get_new_purchase_receipts(self):
|
||||
return self.get_new_sum("Purchase Receipt", self.meta.get_label("new_purchase_receipts"),
|
||||
"grand_total")
|
||||
|
||||
|
||||
def get_new_stock_entries(self):
|
||||
return self.get_new_sum("Stock Entry", self.meta.get_label("new_stock_entries"), "total_amount")
|
||||
|
||||
|
||||
def get_new_support_tickets(self):
|
||||
return self.get_new_count("Support Ticket", self.meta.get_label("new_support_tickets"),
|
||||
return self.get_new_count("Support Ticket", self.meta.get_label("new_support_tickets"),
|
||||
filter_by_company=False)
|
||||
|
||||
|
||||
def get_new_communications(self):
|
||||
return self.get_new_count("Communication", self.meta.get_label("new_communications"),
|
||||
return self.get_new_count("Communication", self.meta.get_label("new_communications"),
|
||||
filter_by_company=False)
|
||||
|
||||
|
||||
def get_new_projects(self):
|
||||
return self.get_new_count("Project", self.meta.get_label("new_projects"),
|
||||
return self.get_new_count("Project", self.meta.get_label("new_projects"),
|
||||
filter_by_company=False)
|
||||
|
||||
|
||||
def get_calendar_events(self, user_id):
|
||||
from frappe.core.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 = ""
|
||||
if events:
|
||||
for i, e in enumerate(events):
|
||||
@ -306,18 +306,18 @@ class EmailDigest(DocListController):
|
||||
else:
|
||||
html += "<li style='line-height: 200%%'>%s [%s - %s]</li>" % \
|
||||
(e.subject, datetime_in_user_format(e.starts_on), datetime_in_user_format(e.ends_on))
|
||||
|
||||
|
||||
if html:
|
||||
return 1, "<h4>Upcoming Calendar Events (max 10):</h4><ul>" + html + "</ul><hr>"
|
||||
else:
|
||||
return 0, "<p>Calendar Events</p>"
|
||||
|
||||
|
||||
def get_todo_list(self, user_id):
|
||||
todo_list = frappe.db.sql("""select *
|
||||
from `tabToDo` where (owner=%s or assigned_by=%s)
|
||||
order by field(priority, 'High', 'Medium', 'Low') asc, date asc""",
|
||||
(user_id, user_id), as_dict=True)
|
||||
|
||||
|
||||
html = ""
|
||||
if todo_list:
|
||||
for i, todo in enumerate([todo for todo in todo_list if not todo.checked]):
|
||||
@ -327,14 +327,14 @@ class EmailDigest(DocListController):
|
||||
todo.description = "%s: %s - %s %s" % \
|
||||
(todo.reference_type, get_url_to_form(todo.reference_type, todo.reference_name),
|
||||
_("assigned by"), get_fullname(todo.assigned_by))
|
||||
|
||||
|
||||
html += "<li style='line-height: 200%%'>%s [%s]</li>" % (todo.description, todo.priority)
|
||||
|
||||
|
||||
if html:
|
||||
return 1, "<h4>To Do (max 10):</h4><ul>" + html + "</ul><hr>"
|
||||
else:
|
||||
return 0, "<p>To Do</p>"
|
||||
|
||||
|
||||
def get_new_count(self, doctype, label, docstatus=0, filter_by_company=True):
|
||||
if filter_by_company:
|
||||
company = """and company="%s" """ % self.company.replace('"', '\"')
|
||||
@ -342,22 +342,22 @@ class EmailDigest(DocListController):
|
||||
company = ""
|
||||
count = frappe.db.sql("""select count(*) from `tab%s`
|
||||
where docstatus=%s %s and
|
||||
date(creation)>=%s and date(creation)<=%s""" %
|
||||
date(creation)>=%s and date(creation)<=%s""" %
|
||||
(doctype, docstatus, company, "%s", "%s"), (self.from_date, self.to_date))
|
||||
count = count and count[0][0] or 0
|
||||
|
||||
|
||||
return count, self.get_html(label, None, count)
|
||||
|
||||
|
||||
def get_new_sum(self, doctype, label, sum_field):
|
||||
count_sum = frappe.db.sql("""select count(*), sum(ifnull(`%s`, 0))
|
||||
from `tab%s` where docstatus=1 and company = %s and
|
||||
date(creation)>=%s and date(creation)<=%s""" % (sum_field, doctype, "%s",
|
||||
"%s", "%s"), (self.company, self.from_date, self.to_date))
|
||||
count, total = count_sum and count_sum[0] or (0, 0)
|
||||
|
||||
return count, self.get_html(label, self.currency,
|
||||
|
||||
return count, self.get_html(label, self.currency,
|
||||
"%s - (%s)" % (fmt_money(total), cstr(count)))
|
||||
|
||||
|
||||
def get_html(self, label, currency, value, style=None):
|
||||
"""get html output"""
|
||||
return row_template % {
|
||||
@ -366,27 +366,27 @@ class EmailDigest(DocListController):
|
||||
"currency": currency and (currency+" ") or "",
|
||||
"value": value
|
||||
}
|
||||
|
||||
|
||||
def get_gl_entries(self, from_date=None, to_date=None):
|
||||
"""get valid GL Entries filtered by company and posting date"""
|
||||
if from_date==self.from_date and to_date==self.to_date and \
|
||||
hasattr(self, "gl_entries"):
|
||||
return self.gl_entries
|
||||
|
||||
gl_entries = frappe.db.sql("""select `account`,
|
||||
|
||||
gl_entries = frappe.db.sql("""select `account`,
|
||||
ifnull(credit, 0) as credit, ifnull(debit, 0) as debit, `against`
|
||||
from `tabGL Entry`
|
||||
where company=%s
|
||||
and posting_date <= %s %s""" % ("%s", "%s",
|
||||
where company=%s
|
||||
and posting_date <= %s %s""" % ("%s", "%s",
|
||||
from_date and "and posting_date>='%s'" % from_date or ""),
|
||||
(self.company, to_date or self.to_date), as_dict=1)
|
||||
|
||||
|
||||
# cache if it is the normal cases
|
||||
if from_date==self.from_date and to_date==self.to_date:
|
||||
self.gl_entries = gl_entries
|
||||
|
||||
|
||||
return gl_entries
|
||||
|
||||
|
||||
def get_accounts(self):
|
||||
if not hasattr(self, "accounts"):
|
||||
self.accounts = frappe.db.sql("""select name, is_pl_account,
|
||||
@ -395,10 +395,10 @@ class EmailDigest(DocListController):
|
||||
and group_or_ledger = "Ledger" order by lft""",
|
||||
(self.company,), as_dict=1)
|
||||
return self.accounts
|
||||
|
||||
|
||||
def get_from_to_date(self):
|
||||
today = now_datetime().date()
|
||||
|
||||
|
||||
# decide from date based on email digest frequency
|
||||
if self.frequency == "Daily":
|
||||
# from date, to_date is yesterday
|
||||
@ -415,10 +415,10 @@ class EmailDigest(DocListController):
|
||||
to_date = today - relativedelta(days=today.day)
|
||||
|
||||
return from_date, to_date
|
||||
|
||||
|
||||
def get_future_from_to_date(self):
|
||||
today = now_datetime().date()
|
||||
|
||||
|
||||
# decide from date based on email digest frequency
|
||||
if self.frequency == "Daily":
|
||||
# from date, to_date is today
|
||||
@ -433,14 +433,14 @@ class EmailDigest(DocListController):
|
||||
from_date = today - relativedelta(days=today.day-1)
|
||||
# to date is the last day of the current month
|
||||
to_date = from_date + relativedelta(days=-1, months=1)
|
||||
|
||||
|
||||
return from_date, to_date
|
||||
|
||||
def get_next_sending(self):
|
||||
from_date, to_date = self.get_from_to_date()
|
||||
|
||||
send_date = to_date + timedelta(days=1)
|
||||
|
||||
|
||||
if self.frequency == "Daily":
|
||||
next_send_date = send_date + timedelta(days=1)
|
||||
elif self.frequency == "Weekly":
|
||||
@ -448,31 +448,31 @@ class EmailDigest(DocListController):
|
||||
else:
|
||||
next_send_date = send_date + relativedelta(months=1)
|
||||
self.next_send = formatdate(next_send_date) + " at midnight"
|
||||
|
||||
|
||||
return send_date
|
||||
|
||||
|
||||
def get_open_tickets(self):
|
||||
open_tickets = frappe.db.sql("""select name, subject, modified, raised_by
|
||||
from `tabSupport Ticket` where status='Open'
|
||||
order by modified desc limit 10""", as_dict=True)
|
||||
|
||||
|
||||
if open_tickets:
|
||||
return 1, """<hr><h4>Latest Open Tickets (max 10):</h4>%s""" % \
|
||||
"".join(["<p>%(name)s: %(subject)s <br>by %(raised_by)s on %(modified)s</p>" % \
|
||||
t for t in open_tickets])
|
||||
else:
|
||||
return 0, "No Open Tickets!"
|
||||
|
||||
|
||||
def get_scheduler_errors(self):
|
||||
import frappe.utils.scheduler
|
||||
return frappe.utils.scheduler.get_error_report(self.from_date, self.to_date)
|
||||
|
||||
|
||||
def onload(self):
|
||||
self.get_next_sending()
|
||||
|
||||
|
||||
def send():
|
||||
now_date = now_datetime().date()
|
||||
|
||||
|
||||
for ed in frappe.db.sql("""select name from `tabEmail Digest`
|
||||
where enabled=1 and docstatus<2""", as_list=1):
|
||||
ed_obj = frappe.get_doc('Email Digest', ed[0])
|
||||
|
@ -5,10 +5,10 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _, throw
|
||||
from frappe.utils import cint
|
||||
from frappe.model.controller import DocListController
|
||||
from frappe.model.document import Document
|
||||
import frappe.defaults
|
||||
|
||||
class PriceList(DocListController):
|
||||
class PriceList(Document):
|
||||
def validate(self):
|
||||
if not cint(self.buying) and not cint(self.selling):
|
||||
throw(_("Price List must be applicable for Buying or Selling"))
|
||||
|
@ -6,12 +6,12 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt, getdate, add_days, formatdate
|
||||
from frappe.model.controller import DocListController
|
||||
from frappe.model.document import Document
|
||||
from datetime import date
|
||||
|
||||
class StockFreezeError(frappe.ValidationError): pass
|
||||
|
||||
class StockLedgerEntry(DocListController):
|
||||
class StockLedgerEntry(Document):
|
||||
def validate(self):
|
||||
from erpnext.stock.utils import validate_warehouse_company
|
||||
self.validate_mandatory()
|
||||
|
Loading…
x
Reference in New Issue
Block a user