[fixes] address and contact

This commit is contained in:
Rushabh Mehta 2017-01-14 00:25:22 +05:30
parent c0bfb0ba56
commit 95439db53f
10 changed files with 113 additions and 146 deletions

View File

@ -7,6 +7,7 @@ import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import cstr, cint
from frappe.geo.doctype.address.address import get_default_address
class IncorrectCustomerGroup(frappe.ValidationError): pass
class IncorrectSupplierType(frappe.ValidationError): pass
@ -96,27 +97,31 @@ class TaxRule(Document):
@frappe.whitelist()
def get_party_details(party, party_type, args=None):
out = {}
billing_address, shipping_address = None, None
if args:
billing_filters= {"name": args.get("billing_address")}
shipping_filters= {"name": args.get("shipping_address")}
if args.get('billing_address'):
billing_address = frappe.get_doc('Address', args.get('billing_address'))
if args.get('shipping_address'):
shipping_address = frappe.get_doc('Address', args.get('shipping_address'))
else:
billing_filters= {party_type: party, "is_primary_address": 1}
shipping_filters= {party_type:party, "is_shipping_address": 1}
billing_address= frappe.get_all("Address", fields=["city", "county", "state", "country"], filters= billing_filters)
shipping_address= frappe.get_all("Address", fields=["city", "county", "state", "country"], filters= shipping_filters)
billing_address_name = get_default_address(party_type, party)
shipping_address_name = get_default_address(party_type, party, 'is_shipping_address')
if billing_address_name:
billing_address = frappe.get_doc('Address', billing_address_name)
if shipping_address_name:
shipping_address = frappe.get_doc('Address', shipping_address_name)
if billing_address:
out["billing_city"]= billing_address[0].city
out["billing_county"]= billing_address[0].county
out["billing_state"]= billing_address[0].state
out["billing_country"]= billing_address[0].country
out["billing_city"]= billing_address.city
out["billing_county"]= billing_address.county
out["billing_state"]= billing_address.state
out["billing_country"]= billing_address.country
if shipping_address:
out["shipping_city"]= shipping_address[0].city
out["shipping_county"]= shipping_address[0].county
out["shipping_state"]= shipping_address[0].state
out["shipping_country"]= shipping_address[0].country
out["shipping_city"]= shipping_address.city
out["shipping_county"]= shipping_address.county
out["shipping_state"]= shipping_address.state
out["shipping_country"]= shipping_address.country
return out

View File

@ -6,7 +6,9 @@ import frappe
import frappe.defaults
from frappe import msgprint, _
from frappe.model.naming import make_autoname
from erpnext.utilities.address_and_contact import load_address_and_contact
from erpnext.utilities.address_and_contact import (load_address_and_contact,
delete_contact_and_address)
from erpnext.utilities.transaction_base import TransactionBase
from erpnext.accounts.party import validate_party_accounts, get_timeline_data # keep this
from erpnext.accounts.party_status import get_party_status
@ -46,21 +48,10 @@ class Supplier(TransactionBase):
else:
self.name = make_autoname(self.naming_series + '.#####')
def update_address(self):
frappe.db.sql("""update `tabAddress` set supplier_name=%s, modified=NOW()
where supplier=%s""", (self.supplier_name, self.name))
def update_contact(self):
frappe.db.sql("""update `tabContact` set supplier_name=%s, modified=NOW()
where supplier=%s""", (self.supplier_name, self.name))
def on_update(self):
if not self.naming_series:
self.naming_series = ''
self.update_address()
self.update_contact()
def validate(self):
#validation for Naming Series mandatory field...
if frappe.defaults.get_global_default('supp_master_name') == 'Naming Series':
@ -78,28 +69,9 @@ class Supplier(TransactionBase):
else:
return ''
def delete_supplier_address(self):
for rec in frappe.db.sql("select * from `tabAddress` where supplier=%s", (self.name,), as_dict=1):
frappe.db.sql("delete from `tabAddress` where name=%s",(rec['name']))
def delete_supplier_contact(self):
for contact in frappe.db.sql_list("""select name from `tabContact`
where supplier=%s""", self.name):
frappe.delete_doc("Contact", contact)
def on_trash(self):
self.delete_supplier_address()
self.delete_supplier_contact()
delete_contact_and_address('Supplier', self.name)
def after_rename(self, olddn, newdn, merge=False):
set_field = ''
if frappe.defaults.get_global_default('supp_master_name') == 'Supplier Name':
frappe.db.set(self, "supplier_name", newdn)
self.update_contact()
set_field = ", supplier_name=%(newdn)s"
self.update_supplier_address(newdn, set_field)
def update_supplier_address(self, newdn, set_field):
frappe.db.sql("""update `tabAddress` set address_title=%(newdn)s
{set_field} where supplier=%(newdn)s"""\
.format(set_field=set_field), ({"newdn": newdn}))

View File

@ -5,7 +5,7 @@
"city": "Larnaka",
"country": "Cyprus",
"links": [{"link_doctype": "Customer", "link_name": "Adaptas"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "R Patr\u00e3o Caramelho 116",
@ -13,7 +13,7 @@
"city": "Fajozes",
"country": "Portugal",
"links": [{"link_doctype": "Customer", "link_name": "Asian Fusion"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "30 Fulford Road",
@ -21,7 +21,7 @@
"city": "PENTRE-PIOD",
"country": "United Kingdom",
"links": [{"link_doctype": "Customer", "link_name": "Asian Junction"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "Schoenebergerstrasse 13",
@ -29,7 +29,7 @@
"city": "Raschau",
"country": "Germany",
"links": [{"link_doctype": "Customer", "link_name": "Big D Supermarkets"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "Hoheluftchaussee 43",
@ -37,7 +37,7 @@
"city": "Kieritzsch",
"country": "Germany",
"links": [{"link_doctype": "Customer", "link_name": "Buttrey Food & Drug"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "R Cimo Vila 6",
@ -45,7 +45,7 @@
"city": "Rebordosa",
"country": "Portugal",
"links": [{"link_doctype": "Customer", "link_name": "Chi-Chis"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "R 5 Outubro 9",
@ -53,7 +53,7 @@
"city": "Quinta Nova S\u00e3o Domingos",
"country": "Portugal",
"links": [{"link_doctype": "Customer", "link_name": "Choices"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "Avenida Macambira 953",
@ -61,7 +61,7 @@
"city": "Goi\u00e2nia",
"country": "Brazil",
"links": [{"link_doctype": "Customer", "link_name": "Consumers and Consumers Express"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "2342 Goyeau Ave",
@ -69,7 +69,7 @@
"city": "Windsor",
"country": "Canada",
"links": [{"link_doctype": "Customer", "link_name": "Crafts Canada"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "Laukaantie 82",
@ -77,7 +77,7 @@
"city": "KOKKOLA",
"country": "Finland",
"links": [{"link_doctype": "Customer", "link_name": "Endicott Shoes"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "9 Brown Street",
@ -85,7 +85,7 @@
"city": "PETERSHAM",
"country": "Australia",
"links": [{"link_doctype": "Customer", "link_name": "Fayva"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "Via Donnalbina 41",
@ -93,7 +93,7 @@
"city": "Cala Gonone",
"country": "Italy",
"links": [{"link_doctype": "Customer", "link_name": "Intelacard"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "Liljerum Grenadj\u00e4rtorpet 69",
@ -101,7 +101,7 @@
"city": "TOMTEBODA",
"country": "Sweden",
"links": [{"link_doctype": "Customer", "link_name": "Landskip Yard Care"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "72 Bishopgate Street",
@ -109,7 +109,7 @@
"city": "SEAHAM",
"country": "United Kingdom",
"links": [{"link_doctype": "Customer", "link_name": "Life Plan Counselling"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "\u03a3\u03ba\u03b1\u03c6\u03af\u03b4\u03b9\u03b1 105",
@ -117,7 +117,7 @@
"city": "\u03a0\u0391\u03a1\u0395\u039a\u039a\u039b\u0397\u03a3\u0399\u0391",
"country": "Cyprus",
"links": [{"link_doctype": "Customer", "link_name": "Mr Fables"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "Mellemvej 7",
@ -125,7 +125,7 @@
"city": "Aabybro",
"country": "Denmark",
"links": [{"link_doctype": "Customer", "link_name": "Nelson Brothers"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "Plougg\u00e5rdsvej 98",
@ -133,7 +133,7 @@
"city": "Karby",
"country": "Denmark",
"links": [{"link_doctype": "Customer", "link_name": "Netobill"}],
"phone": "23566775757",
"phone": "23566775757"
},
{
"address_line1": "176 Michalakopoulou Street",
@ -141,7 +141,7 @@
"city": "Agio Georgoudi",
"country": "Cyprus",
"phone": "23566775757",
"links": [{"link_doctype": "Supplier", "link_name": "Helios Air"}],
"links": [{"link_doctype": "Supplier", "link_name": "Helios Air"}]
},
{
"address_line1": "Fibichova 1102",
@ -149,7 +149,7 @@
"city": "Kokor\u00edn",
"country": "Czech Republic",
"phone": "23566775757",
"links": [{"link_doctype": "Supplier", "link_name": "Ks Merchandise"}],
"links": [{"link_doctype": "Supplier", "link_name": "Ks Merchandise"}]
},
{
"address_line1": "Zahradn\u00ed 888",
@ -157,7 +157,7 @@
"city": "Cecht\u00edn",
"country": "Czech Republic",
"phone": "23566775757",
"links": [{"link_doctype": "Supplier", "link_name": "HomeBase"}],
"links": [{"link_doctype": "Supplier", "link_name": "HomeBase"}]
},
{
"address_line1": "ul. Grochowska 94",
@ -165,7 +165,7 @@
"city": "Warszawa",
"country": "Poland",
"phone": "23566775757",
"links": [{"link_doctype": "Supplier", "link_name": "Scott Ties"}],
"links": [{"link_doctype": "Supplier", "link_name": "Scott Ties"}]
},
{
"address_line1": "Norra Esplanaden 87",
@ -173,7 +173,7 @@
"city": "HELSINKI",
"country": "Finland",
"phone": "23566775757",
"links": [{"link_doctype": "Supplier", "link_name": "Reliable Investments"}],
"links": [{"link_doctype": "Supplier", "link_name": "Reliable Investments"}]
},
{
"address_line1": "2038 Fallon Drive",
@ -181,7 +181,7 @@
"city": "Dresden",
"country": "Canada",
"phone": "23566775757",
"links": [{"link_doctype": "Supplier", "link_name": "Nan Duskin"}],
"links": [{"link_doctype": "Supplier", "link_name": "Nan Duskin"}]
},
{
"address_line1": "77 cours Franklin Roosevelt",
@ -189,7 +189,7 @@
"city": "MARSEILLE",
"country": "France",
"phone": "23566775757",
"links": [{"link_doctype": "Supplier", "link_name": "Rainbow Records"}],
"links": [{"link_doctype": "Supplier", "link_name": "Rainbow Records"}]
},
{
"address_line1": "ul. Tuwima Juliana 85",
@ -197,7 +197,7 @@
"city": "\u0141\u00f3d\u017a",
"country": "Poland",
"phone": "23566775757",
"links": [{"link_doctype": "Supplier", "link_name": "New World Realty"}],
"links": [{"link_doctype": "Supplier", "link_name": "New World Realty"}]
},
{
"address_line1": "Gl. Sygehusvej 41",
@ -205,7 +205,7 @@
"city": "Narsaq",
"country": "Greenland",
"phone": "23566775757",
"links": [{"link_doctype": "Supplier", "link_name": "Asiatic Solutions"}],
"links": [{"link_doctype": "Supplier", "link_name": "Asiatic Solutions"}]
},
{
"address_line1": "Gosposka ulica 50",
@ -213,6 +213,6 @@
"city": "Nova Gorica",
"country": "Slovenia",
"phone": "23566775757",
"links": [{"link_doctype": "Supplier", "link_name": "Eagle Hardware"}],
"links": [{"link_doctype": "Supplier", "link_name": "Eagle Hardware"}]
}
]

View File

@ -105,60 +105,60 @@
"links": [{"link_doctype": "Supplier", "link_name": "Helios Air"}],
"email_id": "TewoldeAbaalom@example.com",
"first_name": "Tewolde",
"last_name": "Abaalom",
"last_name": "Abaalom"
},
{
"links": [{"link_doctype": "Supplier", "link_name": "Ks Merchandise"}],
"email_id": "LeilaFernandesRodrigues@example.com",
"first_name": "Leila",
"last_name": "Rodrigues",
"last_name": "Rodrigues"
},
{
"links": [{"link_doctype": "Supplier", "link_name": "HomeBase"}],
"email_id": "DmitryBulgakov@example.com",
"first_name": "Dmitry",
"last_name": "Bulgakov",
"last_name": "Bulgakov"
},
{
"links": [{"link_doctype": "Supplier", "link_name": "Scott Ties"}],
"email_id": "HaiducWhitfoot@example.com",
"first_name": "Haiduc",
"last_name": "Whitfoot",
"last_name": "Whitfoot"
},
{
"links": [{"link_doctype": "Supplier", "link_name": "Reliable Investments"}],
"email_id": "SesseljaPetursdottir@example.com",
"first_name": "Sesselja",
"last_name": "P\u00e9tursd\u00f3ttir",
"last_name": "P\u00e9tursd\u00f3ttir"
},
{
"links": [{"link_doctype": "Supplier", "link_name": "Nan Duskin"}],
"email_id": "HajdarPignar@example.com",
"first_name": "Hajdar",
"last_name": "Pignar",
"last_name": "Pignar"
},
{
"links": [{"link_doctype": "Supplier", "link_name": "Rainbow Records"}],
"email_id": "GustavaLorenzo@example.com",
"first_name": "Gustava",
"last_name": "Lorenzo",
"last_name": "Lorenzo"
},
{
"links": [{"link_doctype": "Supplier", "link_name": "New World Realty"}],
"email_id": "BethanyWood@example.com",
"first_name": "Bethany",
"last_name": "Wood",
"last_name": "Wood"
},
{
"links": [{"link_doctype": "Supplier", "link_name": "Asiatic Solutions"}],
"email_id": "GlorianaBrownlock@example.com",
"first_name": "Gloriana",
"last_name": "Brownlock",
"last_name": "Brownlock"
},
{
"links": [{"link_doctype": "Supplier", "link_name": "Eagle Hardware"}],
"email_id": "JensonFraser@gustr.com",
"first_name": "Jenson",
"last_name": "Fraser",
"last_name": "Fraser"
}
]

View File

@ -32,7 +32,7 @@ def setup(domain):
import_json('Contact')
import_json('Lead')
setup_currency_exchange()
setup_mode_of_payment()
#setup_mode_of_payment()
setup_account_to_expense_type()
setup_budget()
setup_pos_profile()

View File

@ -114,10 +114,8 @@ portal_menu_items = [
]
default_roles = [
{'role': 'Customer', 'doctype':'Contact', 'email_field': 'email_id',
'filters': {'ifnull(customer, "")': ('!=', '')}},
{'role': 'Supplier', 'doctype':'Contact', 'email_field': 'email_id',
'filters': {'ifnull(supplier, "")': ('!=', '')}},
{'role': 'Customer', 'doctype':'Contact', 'email_field': 'email_id'},
{'role': 'Supplier', 'doctype':'Contact', 'email_field': 'email_id'},
{'role': 'Student', 'doctype':'Student', 'email_field': 'student_email_id'}
]
@ -154,9 +152,10 @@ doc_events = {
"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty"
},
"User": {
"after_insert": "frappe.email.doctype.contact.contact.update_contact",
"validate": "erpnext.hr.doctype.employee.employee.validate_employee_role",
"on_update": "erpnext.hr.doctype.employee.employee.update_user_permissions",
"on_update": "frappe.email.doctype.contact.contact.update_contact"
"on_update": "erpnext.utilities.address_and_contact.set_default_role"
},
("Sales Taxes and Charges Template", 'Price List'): {
"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"

View File

@ -9,7 +9,7 @@ import frappe.defaults
from frappe.utils import flt, cint, cstr
from frappe.desk.reportview import build_match_conditions
from erpnext.utilities.transaction_base import TransactionBase
from erpnext.utilities.address_and_contact import load_address_and_contact
from erpnext.utilities.address_and_contact import load_address_and_contact, delete_contact_and_address
from erpnext.accounts.party import validate_party_accounts, get_timeline_data # keep this
from erpnext.accounts.party_status import get_party_status
from erpnext import get_default_currency
@ -79,9 +79,6 @@ class Customer(TransactionBase):
if self.flags.old_lead != self.lead_name:
self.update_lead_status()
self.update_address()
self.update_contact()
if self.flags.is_new_doc:
self.create_lead_address_contact()
@ -95,30 +92,26 @@ class Customer(TransactionBase):
for d in frappe.get_all(doctype, {'lead': self.lead_name}):
frappe.db.set_value(doctype, d.name, 'customer', self.name, update_modified=False)
def update_address(self):
frappe.db.sql("""update `tabAddress` set customer_name=%s, modified=NOW()
where customer=%s""", (self.customer_name, self.name))
def update_contact(self):
frappe.db.sql("""update `tabContact` set customer_name=%s, modified=NOW()
where customer=%s""", (self.customer_name, self.name))
def create_lead_address_contact(self):
if self.lead_name:
if not frappe.db.get_value("Address", {"lead": self.lead_name, "customer": self.name}):
frappe.db.sql("""update `tabAddress` set customer=%s, customer_name=%s where lead=%s""",
(self.name, self.customer_name, self.lead_name))
# assign lead address to customer (if already not set)
address_name = frappe.get_value('Dynamic Link', dict(parenttype='Address', link_doctype='Lead', link_name=self.name))
if address_name:
address = frappe.get_doc('Address', address_name)
if not address.has_link('Customer', self.name):
address.append('links', dict(link_doctype='Customer', link_name=self.name))
address.save()
lead = frappe.db.get_value("Lead", self.lead_name, ["lead_name", "email_id", "phone", "mobile_no"], as_dict=True)
# create contact from lead
c = frappe.new_doc('Contact')
c.first_name = lead.lead_name
c.email_id = lead.email_id
c.phone = lead.phone
c.mobile_no = lead.mobile_no
c.customer = self.name
c.customer_name = self.customer_name
c.is_primary_contact = 1
c.append('links', dict(link_doctype='Customer', link_name=self.name))
c.flags.ignore_permissions = self.flags.ignore_permissions
c.autoname()
if not frappe.db.exists("Contact", c.name):
@ -137,40 +130,14 @@ class Customer(TransactionBase):
if flt(self.credit_limit) < outstanding_amt:
frappe.throw(_("""New credit limit is less than current outstanding amount for the customer. Credit limit has to be atleast {0}""").format(outstanding_amt))
def delete_customer_address(self):
addresses = frappe.db.sql("""select name, lead from `tabAddress`
where customer=%s""", (self.name,))
for name, lead in addresses:
if lead:
frappe.db.sql("""update `tabAddress` set customer=null, customer_name=null
where name=%s""", name)
else:
frappe.db.sql("""delete from `tabAddress` where name=%s""", name)
def delete_customer_contact(self):
for contact in frappe.db.sql_list("""select name from `tabContact`
where customer=%s""", self.name):
frappe.delete_doc("Contact", contact)
def on_trash(self):
self.delete_customer_address()
self.delete_customer_contact()
delete_contact_and_address('Customer', self.name)
if self.lead_name:
frappe.db.sql("update `tabLead` set status='Interested' where name=%s",self.lead_name)
def after_rename(self, olddn, newdn, merge=False):
set_field = ''
if frappe.defaults.get_global_default('cust_master_name') == 'Customer Name':
frappe.db.set(self, "customer_name", newdn)
self.update_contact()
set_field = ", customer_name=%(newdn)s"
self.update_customer_address(newdn, set_field)
def update_customer_address(self, newdn, set_field):
frappe.db.sql("""update `tabAddress` set address_title=%(newdn)s
{set_field} where customer=%(newdn)s"""\
.format(set_field=set_field), ({"newdn": newdn}))
def get_customer_list(doctype, txt, searchfield, start, page_len, filters):

View File

@ -407,7 +407,7 @@ def create_customers(args):
if args.get("customer_contact_" + str(i)):
create_contact(args.get("customer_contact_" + str(i)),
"customer", doc.name)
"Customer", doc.name)
except frappe.NameError:
pass
@ -425,7 +425,7 @@ def create_suppliers(args):
if args.get("supplier_contact_" + str(i)):
create_contact(args.get("supplier_contact_" + str(i)),
"supplier", doc.name)
"Supplier", doc.name)
except frappe.NameError:
pass
@ -433,12 +433,13 @@ def create_contact(contact, party_type, party):
"""Create contact based on given contact name"""
contact = contact.strip().split(" ")
frappe.get_doc({
contact = frappe.get_doc({
"doctype":"Contact",
party_type: party,
"first_name":contact[0],
"last_name": len(contact) > 1 and contact[1] or ""
}).insert()
})
contact.append('links', dict(link_doctype=party_type, link_name=party))
contact.insert()
def create_letter_head(args):
if args.get("attach_letterhead"):

View File

@ -31,12 +31,11 @@ def update_website_context(context):
def check_customer_or_supplier():
if frappe.session.user:
contacts = frappe.get_all("Contact", fields=["customer", "supplier", "email_id"],
filters={"email_id": frappe.session.user})
contact_name = frappe.get_value("Contact", {"email_id": frappe.session.user})
if contact_name:
contact = frappe.get_doc('Contact', contact_name)
for link in contact.links:
if link.link_doctype in ('Customer', 'Supplier'):
return link.link_doctype, link.link_name
customer = [d.customer for d in contacts if d.customer] or None
supplier = [d.supplier for d in contacts if d.supplier] or None
if customer: return 'Customer', customer
if supplier : return 'Supplier', supplier
return 'Customer', None

View File

@ -34,6 +34,19 @@ def load_address_and_contact(doc, key):
doc.set_onload('contact_list', contact_list)
def set_default_role(doc, method):
'''Set customer, supplier, student based on email'''
contact_name = frappe.get_value('Contact', dict(email_id=doc.email))
if contact_name:
contact = frappe.get_doc('Contact', contact_name)
for link in contact.links:
if link.link_doctype=='Customer':
doc.add_roles('Customer')
elif link.link_doctype=='Supplier':
doc.add_roles('Supplier')
elif frappe.get_value('Student', dict(student_email_id=doc.email)):
doc.add_roles('Student')
def has_permission(doc, ptype, user):
links = get_permitted_and_not_permitted_links(doc.doctype)
if not links.get("not_permitted_links"):
@ -105,3 +118,14 @@ def get_permitted_and_not_permitted_links(doctype):
"permitted_links": permitted_links,
"not_permitted_links": not_permitted_links
}
def delete_contact_and_address(doctype, name):
for parenttype in ('Contact', 'Address'):
items = frappe.db.sql("""select parent from `tabDynamic Link`
where parenttype=%s and link_type=%s and link_name=%s""",
(parenttype, doctype, name))
for name in items:
doc = frappe.get_doc(parenttype, name)
if len(doc.links)==1:
doc.delete()