Merge pull request #26771 from barredterra/contact-vcard
feat: download Contact as vCard
This commit is contained in:
commit
9d73477e60
4 changed files with 103 additions and 0 deletions
|
|
@ -88,6 +88,17 @@ frappe.ui.form.on("Contact", {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!frm.is_dirty()) {
|
||||
frm.page.add_menu_item(__("Download vCard"), function () {
|
||||
window.open(
|
||||
`/api/method/frappe.contacts.doctype.contact.contact.download_vcard?contact=${encodeURIComponent(
|
||||
frm.doc.name
|
||||
)}`,
|
||||
"_blank"
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
validate: function (frm) {
|
||||
// clear linked customer / supplier / sales partner on saving...
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
import frappe
|
||||
from frappe import _
|
||||
from frappe.contacts.address_and_contact import set_link_title
|
||||
from frappe.core.doctype.access_log.access_log import make_access_log
|
||||
from frappe.core.doctype.dynamic_link.dynamic_link import deduplicate_dynamic_links
|
||||
from frappe.model.document import Document
|
||||
from frappe.model.naming import append_number_if_name_exists
|
||||
|
|
@ -170,6 +171,88 @@ class Contact(Document):
|
|||
def _get_full_name(self) -> str:
|
||||
return get_full_name(self.first_name, self.middle_name, self.last_name, self.company_name)
|
||||
|
||||
def get_vcard(self):
|
||||
from vobject import vCard
|
||||
from vobject.vcard import Name
|
||||
|
||||
vcard = vCard()
|
||||
vcard.add("fn").value = self.full_name
|
||||
|
||||
name = Name()
|
||||
if self.first_name:
|
||||
name.given = self.first_name
|
||||
|
||||
if self.last_name:
|
||||
name.family = self.last_name
|
||||
|
||||
if self.middle_name:
|
||||
name.additional = self.middle_name
|
||||
|
||||
vcard.add("n").value = name
|
||||
|
||||
if self.designation:
|
||||
vcard.add("title").value = self.designation
|
||||
|
||||
for row in self.email_ids:
|
||||
email = vcard.add("email")
|
||||
email.value = row.email_id
|
||||
if row.is_primary:
|
||||
email.type_param = "pref"
|
||||
|
||||
for row in self.phone_nos:
|
||||
tel = vcard.add("tel")
|
||||
tel.value = row.phone
|
||||
if row.is_primary_phone:
|
||||
tel.type_param = "home"
|
||||
|
||||
if row.is_primary_mobile_no:
|
||||
tel.type_param = "cell"
|
||||
|
||||
return vcard
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def download_vcard(contact: str):
|
||||
"""Download vCard for the contact"""
|
||||
contact = frappe.get_doc("Contact", contact)
|
||||
contact.check_permission()
|
||||
|
||||
vcard = contact.get_vcard()
|
||||
make_access_log(doctype="Contact", document=contact.name, file_type="vcf")
|
||||
|
||||
frappe.response["filename"] = f"{contact.name}.vcf"
|
||||
frappe.response["filecontent"] = vcard.serialize().encode("utf-8")
|
||||
frappe.response["type"] = "binary"
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def download_vcards(contacts: str):
|
||||
"""Download vCard for the contact"""
|
||||
import json
|
||||
|
||||
from frappe.utils.data import now
|
||||
|
||||
contact_ids = frappe.parse_json(contacts)
|
||||
|
||||
vcards = []
|
||||
for contact_id in contact_ids:
|
||||
contact = frappe.get_doc("Contact", contact_id)
|
||||
contact.check_permission()
|
||||
vcard = contact.get_vcard()
|
||||
vcards.append(vcard.serialize())
|
||||
|
||||
make_access_log(
|
||||
doctype="Contact",
|
||||
filters=json.dumps([["name", "in", contact_ids]], ensure_ascii=False, indent="\t"),
|
||||
file_type="vcf",
|
||||
)
|
||||
|
||||
timestamp = now()[:19] # remove milliseconds
|
||||
|
||||
frappe.response["filename"] = f"{timestamp} Contacts.vcf"
|
||||
frappe.response["filecontent"] = "\n".join(vcards).encode("utf-8")
|
||||
frappe.response["type"] = "binary"
|
||||
|
||||
|
||||
def get_default_contact(doctype, name):
|
||||
"""Return default contact for the given doctype, name."""
|
||||
|
|
|
|||
|
|
@ -1,3 +1,11 @@
|
|||
frappe.listview_settings["Contact"] = {
|
||||
add_fields: ["image"],
|
||||
onload: function (listview) {
|
||||
listview.page.add_action_item(__("Download vCards"), function () {
|
||||
const contacts = listview.get_checked_items();
|
||||
open_url_post("/api/method/frappe.contacts.doctype.contact.contact.download_vcards", {
|
||||
contacts: contacts.map((c) => c.name),
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ dependencies = [
|
|||
"google-auth-oauthlib~=0.4.4",
|
||||
"google-auth~=1.29.0",
|
||||
"posthog~=3.0.1",
|
||||
"vobject~=0.9.7",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue