Hey all,
Been using from frappe.core.doctype.communication.email import make
since v10 days and during migration to v12 have noticed I’m getting an error relating to sending emails and attaching the communication to a Sales Order. The errors I’m getting when using console
are:
from frappe.core.doctype.communication.email import make as send_email
send_email(doctype='Sales Order', name='SO-2019-00001', content='test message', recipients='myemailaddress@mydomain.com', send_email=True)
call stack:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/home/frappe/frappe-bench/apps/frappe/frappe/commands/utils.py in <module>()
----> 1 send_email(doctype='Sales Order', name='SO-2019-00001', content='test message', recipients='myemailaddress@mydomain.com', send_email=True)
/home/frappe/frappe-bench/apps/frappe/frappe/core/doctype/communication/email.py in make(doctype, name, content, subject, sent_or_received, sender, sender_full_name, recipients, communication_medium, send_email, print_html, print_format, attachments, send_me_a_copy, cc, bcc, flags, read_receipt, print_letterhead, email_template)
71 "read_receipt":read_receipt,
72 "has_attachment": 1 if attachments else 0
---> 73 }).insert(ignore_permissions=True)
74
75 comm.save(ignore_permissions=True)
/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py in insert(self, ignore_permissions, ignore_links, ignore_if_duplicate, ignore_mandatory)
226
227 self.flags.in_insert = True
--> 228 self.run_before_save_methods()
229 self._validate()
230 self.set_docstatus()
/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py in run_before_save_methods(self)
884 if self._action=="save":
885 self.run_method("before_validate")
--> 886 self.run_method("validate")
887 self.run_method("before_save")
888 elif self._action=="submit":
/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py in run_method(self, method, *args, **kwargs)
784
785 fn.__name__ = str(method)
--> 786 out = Document.hook(fn)(self, *args, **kwargs)
787
788 self.run_notifications(method)
/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py in composer(self, *args, **kwargs)
1054
1055 composed = compose(f, *hooks)
-> 1056 return composed(self, method, *args, **kwargs)
1057
1058 return composer
/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py in runner(self, method, *args, **kwargs)
1037 def compose(fn, *hooks):
1038 def runner(self, method, *args, **kwargs):
-> 1039 add_to_return_value(self, fn(self, *args, **kwargs))
1040 for f in hooks:
1041 add_to_return_value(self, f(self, method, *args, **kwargs))
/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py in <lambda>(self, *args, **kwargs)
778
779 if hasattr(self, method) and hasattr(getattr(self, method), "__call__"):
--> 780 fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
781 else:
782 # hack! to run hooks even if method does not exist
/home/frappe/frappe-bench/apps/frappe/frappe/core/doctype/communication/communication.py in validate(self)
63 if self.communication_medium == "Email":
64 self.parse_email_for_timeline_links()
---> 65 self.set_timeline_links()
66 self.deduplicate_timeline_links()
67
/home/frappe/frappe-bench/apps/frappe/frappe/core/doctype/communication/communication.py in set_timeline_links(self)
261 contacts = get_contacts([self.sender, self.recipients, self.cc, self.bcc])
262 for contact_name in contacts:
--> 263 self.add_link('Contact', contact_name)
264
265 #link contact's dynamic links to communication
/home/frappe/frappe-bench/apps/frappe/frappe/core/doctype/communication/communication.py in add_link(self, link_doctype, link_name, autosave)
286 {
287 "link_doctype": link_doctype,
--> 288 "link_name": link_name
289 }
290 )
/home/frappe/frappe-bench/apps/frappe/frappe/model/base_document.py in append(self, key, value)
147 if not self.__dict__.get(key):
148 self.__dict__[key] = []
--> 149 value = self._init_child(value, key)
150 self.__dict__[key].append(value)
151
/home/frappe/frappe-bench/apps/frappe/frappe/model/base_document.py in _init_child(self, value, key)
182 if not isinstance(value, BaseDocument):
183 if "doctype" not in value or value['doctype'] is None:
--> 184 value["doctype"] = self.get_table_field_doctype(key)
185 if not value["doctype"]:
186 raise AttributeError(key)
/home/frappe/frappe-bench/apps/frappe/frappe/model/base_document.py in get_table_field_doctype(self, fieldname)
296
297 def get_table_field_doctype(self, fieldname):
--> 298 return self.meta.get_field(fieldname).options
299
300 def get_parentfield_of_doctype(self, doctype):
AttributeError: 'NoneType' object has no attribute 'options'
It would seem its trying to access the timeline_links
property of the Communication
doctype, and not getting the options
.
can you help?